diff --git a/.gitignore b/.gitignore index 8d9e780..9be89b1 100644 --- a/.gitignore +++ b/.gitignore @@ -12,4 +12,8 @@ stable-download/java/spigot_command/world_nether/* stable-download/java/spigot_command/world_the_end/* stable-download/java/spigot_command/server.log stable-download/java/bungee_command/proxy* -lwjgl-rundir/_eagstorage* \ No newline at end of file +lwjgl-rundir/_eagstorage* +sp-server/.gradle +sp-server/.settings +sp-server/build +sp-server/bin \ No newline at end of file diff --git a/javascript/classes_server.js b/javascript/classes_server.js new file mode 100644 index 0000000..5817e36 --- /dev/null +++ b/javascript/classes_server.js @@ -0,0 +1,15666 @@ +"use strict"; +var main; +(function() { +var $rt_seed = 2463534242; +function $rt_nextId() { + var x = $rt_seed; + x ^= x << 13; + x ^= x >> 17; + x ^= x << 5; + $rt_seed = x; + return x; +} +function $rt_compare(a, b) { + return a > b ? 1 : a < b ? -1 : a === b ? 0 : 1; +} +function $rt_isInstance(obj, cls) { + return obj !== null && !!obj.constructor.$meta && $rt_isAssignable(obj.constructor, cls); +} +function $rt_isAssignable(from, to) { + if (from === to) { + return true; + } + if (to.$meta.item !== null) { + return from.$meta.item !== null && $rt_isAssignable(from.$meta.item, to.$meta.item); + } + var supertypes = from.$meta.supertypes; + for (var i = 0;i < supertypes.length;i = i + 1 | 0) { + if ($rt_isAssignable(supertypes[i], to)) { + return true; + } + } + return false; +} +function $rt_castToInterface(obj, cls) { + if (obj !== null && !$rt_isInstance(obj, cls)) { + $rt_throwCCE(); + } + return obj; +} +function $rt_castToClass(obj, cls) { + if (obj !== null && !(obj instanceof cls)) { + $rt_throwCCE(); + } + return obj; +} +Array.prototype.fill = Array.prototype.fill || function(value, start, end) { + var len = this.length; + if (!len) return this; + start = start | 0; + var i = start < 0 ? Math.max(len + start, 0) : Math.min(start, len); + end = end === undefined ? len : end | 0; + end = end < 0 ? Math.max(len + end, 0) : Math.min(end, len); + for (;i < end;i++) { + this[i] = value; + } + return this; +}; +function $rt_createArray(cls, sz) { + var data = new Array(sz); + data.fill(null); + return new $rt_array(cls, data); +} +function $rt_createArrayFromData(cls, init) { + return $rt_wrapArray(cls, init); +} +function $rt_wrapArray(cls, data) { + return new $rt_array(cls, data); +} +function $rt_createUnfilledArray(cls, sz) { + return new $rt_array(cls, new Array(sz)); +} +function $rt_createNumericArray(cls, nativeArray) { + return new $rt_array(cls, nativeArray); +} +var $rt_createLongArray; +var $rt_createLongArrayFromData; +if (typeof BigInt64Array !== 'function') { + $rt_createLongArray = function(sz) { + var data = new Array(sz); + var arr = new $rt_array($rt_longcls(), data); + data.fill(Long_ZERO); + return arr; + }; + $rt_createLongArrayFromData = function(init) { + return new $rt_array($rt_longcls(), init); + }; +} else { + $rt_createLongArray = function(sz) { + return $rt_createNumericArray($rt_longcls(), new BigInt64Array(sz)); + }; + $rt_createLongArrayFromData = function(data) { + var buffer = new BigInt64Array(data.length); + buffer.set(data); + return $rt_createNumericArray($rt_longcls(), buffer); + }; +} +function $rt_createCharArray(sz) { + return $rt_createNumericArray($rt_charcls(), new Uint16Array(sz)); +} +function $rt_createCharArrayFromData(data) { + var buffer = new Uint16Array(data.length); + buffer.set(data); + return $rt_createNumericArray($rt_charcls(), buffer); +} +function $rt_createByteArray(sz) { + return $rt_createNumericArray($rt_bytecls(), new Int8Array(sz)); +} +function $rt_createByteArrayFromData(data) { + var buffer = new Int8Array(data.length); + buffer.set(data); + return $rt_createNumericArray($rt_bytecls(), buffer); +} +function $rt_createShortArray(sz) { + return $rt_createNumericArray($rt_shortcls(), new Int16Array(sz)); +} +function $rt_createShortArrayFromData(data) { + var buffer = new Int16Array(data.length); + buffer.set(data); + return $rt_createNumericArray($rt_shortcls(), buffer); +} +function $rt_createIntArray(sz) { + return $rt_createNumericArray($rt_intcls(), new Int32Array(sz)); +} +function $rt_createIntArrayFromData(data) { + var buffer = new Int32Array(data.length); + buffer.set(data); + return $rt_createNumericArray($rt_intcls(), buffer); +} +function $rt_createBooleanArray(sz) { + return $rt_createNumericArray($rt_booleancls(), new Int8Array(sz)); +} +function $rt_createBooleanArrayFromData(data) { + var buffer = new Int8Array(data.length); + buffer.set(data); + return $rt_createNumericArray($rt_booleancls(), buffer); +} +function $rt_createFloatArray(sz) { + return $rt_createNumericArray($rt_floatcls(), new Float32Array(sz)); +} +function $rt_createFloatArrayFromData(data) { + var buffer = new Float32Array(data.length); + buffer.set(data); + return $rt_createNumericArray($rt_floatcls(), buffer); +} +function $rt_createDoubleArray(sz) { + return $rt_createNumericArray($rt_doublecls(), new Float64Array(sz)); +} +function $rt_createDoubleArrayFromData(data) { + var buffer = new Float64Array(data.length); + buffer.set(data); + return $rt_createNumericArray($rt_doublecls(), buffer); +} +function $rt_arraycls(cls) { + var result = cls.$array; + if (result === null) { + var arraycls = { }; + var name = "[" + cls.$meta.binaryName; + arraycls.$meta = { item : cls, supertypes : [$rt_objcls()], primitive : false, superclass : $rt_objcls(), name : name, binaryName : name, enum : false, simpleName : null, declaringClass : null, enclosingClass : null }; + arraycls.classObject = null; + arraycls.$array = null; + result = arraycls; + cls.$array = arraycls; + } + return result; +} +function $rt_createcls() { + return { $array : null, classObject : null, $meta : { supertypes : [], superclass : null } }; +} +function $rt_createPrimitiveCls(name, binaryName) { + var cls = $rt_createcls(); + cls.$meta.primitive = true; + cls.$meta.name = name; + cls.$meta.binaryName = binaryName; + cls.$meta.enum = false; + cls.$meta.item = null; + cls.$meta.simpleName = null; + cls.$meta.declaringClass = null; + cls.$meta.enclosingClass = null; + return cls; +} +var $rt_booleanclsCache = null; +function $rt_booleancls() { + if ($rt_booleanclsCache === null) { + $rt_booleanclsCache = $rt_createPrimitiveCls("boolean", "Z"); + } + return $rt_booleanclsCache; +} +var $rt_charclsCache = null; +function $rt_charcls() { + if ($rt_charclsCache === null) { + $rt_charclsCache = $rt_createPrimitiveCls("char", "C"); + } + return $rt_charclsCache; +} +var $rt_byteclsCache = null; +function $rt_bytecls() { + if ($rt_byteclsCache === null) { + $rt_byteclsCache = $rt_createPrimitiveCls("byte", "B"); + } + return $rt_byteclsCache; +} +var $rt_shortclsCache = null; +function $rt_shortcls() { + if ($rt_shortclsCache === null) { + $rt_shortclsCache = $rt_createPrimitiveCls("short", "S"); + } + return $rt_shortclsCache; +} +var $rt_intclsCache = null; +function $rt_intcls() { + if ($rt_intclsCache === null) { + $rt_intclsCache = $rt_createPrimitiveCls("int", "I"); + } + return $rt_intclsCache; +} +var $rt_longclsCache = null; +function $rt_longcls() { + if ($rt_longclsCache === null) { + $rt_longclsCache = $rt_createPrimitiveCls("long", "J"); + } + return $rt_longclsCache; +} +var $rt_floatclsCache = null; +function $rt_floatcls() { + if ($rt_floatclsCache === null) { + $rt_floatclsCache = $rt_createPrimitiveCls("float", "F"); + } + return $rt_floatclsCache; +} +var $rt_doubleclsCache = null; +function $rt_doublecls() { + if ($rt_doubleclsCache === null) { + $rt_doubleclsCache = $rt_createPrimitiveCls("double", "D"); + } + return $rt_doubleclsCache; +} +var $rt_voidclsCache = null; +function $rt_voidcls() { + if ($rt_voidclsCache === null) { + $rt_voidclsCache = $rt_createPrimitiveCls("void", "V"); + } + return $rt_voidclsCache; +} +function $rt_throw(ex) { + throw $rt_exception(ex); +} +var $rt_javaExceptionProp = Symbol("javaException"); +function $rt_exception(ex) { + var err = ex.$jsException; + if (!err) { + err = new Error("Java exception thrown"); + if (typeof Error.captureStackTrace === "function") { + Error.captureStackTrace(err); + } + err[$rt_javaExceptionProp] = ex; + ex.$jsException = err; + $rt_fillStack(err, ex); + } + return err; +} +function $rt_fillStack(err, ex) { + if (typeof $rt_decodeStack === "function" && err.stack) { + var stack = $rt_decodeStack(err.stack); + var javaStack = $rt_createArray($rt_stecls(), stack.length); + var elem; + var noStack = false; + for (var i = 0;i < stack.length;++i) { + var element = stack[i]; + elem = $rt_createStackElement($rt_str(element.className), $rt_str(element.methodName), $rt_str(element.fileName), element.lineNumber); + if (elem == null) { + noStack = true; + break; + } + javaStack.data[i] = elem; + } + if (!noStack) { + $rt_setStack(ex, javaStack); + } + } +} +function $rt_createMultiArray(cls, dimensions) { + var first = 0; + for (var i = dimensions.length - 1;i >= 0;i = i - 1 | 0) { + if (dimensions[i] === 0) { + first = i; + break; + } + } + if (first > 0) { + for (i = 0;i < first;i = i + 1 | 0) { + cls = $rt_arraycls(cls); + } + if (first === dimensions.length - 1) { + return $rt_createArray(cls, dimensions[first]); + } + } + var arrays = new Array($rt_primitiveArrayCount(dimensions, first)); + var firstDim = dimensions[first] | 0; + for (i = 0;i < arrays.length;i = i + 1 | 0) { + arrays[i] = $rt_createArray(cls, firstDim); + } + return $rt_createMultiArrayImpl(cls, arrays, dimensions, first); +} +function $rt_createByteMultiArray(dimensions) { + var arrays = new Array($rt_primitiveArrayCount(dimensions, 0)); + if (arrays.length === 0) { + return $rt_createMultiArray($rt_bytecls(), dimensions); + } + var firstDim = dimensions[0] | 0; + for (var i = 0;i < arrays.length;i = i + 1 | 0) { + arrays[i] = $rt_createByteArray(firstDim); + } + return $rt_createMultiArrayImpl($rt_bytecls(), arrays, dimensions); +} +function $rt_createCharMultiArray(dimensions) { + var arrays = new Array($rt_primitiveArrayCount(dimensions, 0)); + if (arrays.length === 0) { + return $rt_createMultiArray($rt_charcls(), dimensions); + } + var firstDim = dimensions[0] | 0; + for (var i = 0;i < arrays.length;i = i + 1 | 0) { + arrays[i] = $rt_createCharArray(firstDim); + } + return $rt_createMultiArrayImpl($rt_charcls(), arrays, dimensions, 0); +} +function $rt_createBooleanMultiArray(dimensions) { + var arrays = new Array($rt_primitiveArrayCount(dimensions, 0)); + if (arrays.length === 0) { + return $rt_createMultiArray($rt_booleancls(), dimensions); + } + var firstDim = dimensions[0] | 0; + for (var i = 0;i < arrays.length;i = i + 1 | 0) { + arrays[i] = $rt_createBooleanArray(firstDim); + } + return $rt_createMultiArrayImpl($rt_booleancls(), arrays, dimensions, 0); +} +function $rt_createShortMultiArray(dimensions) { + var arrays = new Array($rt_primitiveArrayCount(dimensions, 0)); + if (arrays.length === 0) { + return $rt_createMultiArray($rt_shortcls(), dimensions); + } + var firstDim = dimensions[0] | 0; + for (var i = 0;i < arrays.length;i = i + 1 | 0) { + arrays[i] = $rt_createShortArray(firstDim); + } + return $rt_createMultiArrayImpl($rt_shortcls(), arrays, dimensions, 0); +} +function $rt_createIntMultiArray(dimensions) { + var arrays = new Array($rt_primitiveArrayCount(dimensions, 0)); + if (arrays.length === 0) { + return $rt_createMultiArray($rt_intcls(), dimensions); + } + var firstDim = dimensions[0] | 0; + for (var i = 0;i < arrays.length;i = i + 1 | 0) { + arrays[i] = $rt_createIntArray(firstDim); + } + return $rt_createMultiArrayImpl($rt_intcls(), arrays, dimensions, 0); +} +function $rt_createLongMultiArray(dimensions) { + var arrays = new Array($rt_primitiveArrayCount(dimensions, 0)); + if (arrays.length === 0) { + return $rt_createMultiArray($rt_longcls(), dimensions); + } + var firstDim = dimensions[0] | 0; + for (var i = 0;i < arrays.length;i = i + 1 | 0) { + arrays[i] = $rt_createLongArray(firstDim); + } + return $rt_createMultiArrayImpl($rt_longcls(), arrays, dimensions, 0); +} +function $rt_createFloatMultiArray(dimensions) { + var arrays = new Array($rt_primitiveArrayCount(dimensions, 0)); + if (arrays.length === 0) { + return $rt_createMultiArray($rt_floatcls(), dimensions); + } + var firstDim = dimensions[0] | 0; + for (var i = 0;i < arrays.length;i = i + 1 | 0) { + arrays[i] = $rt_createFloatArray(firstDim); + } + return $rt_createMultiArrayImpl($rt_floatcls(), arrays, dimensions, 0); +} +function $rt_createDoubleMultiArray(dimensions) { + var arrays = new Array($rt_primitiveArrayCount(dimensions, 0)); + if (arrays.length === 0) { + return $rt_createMultiArray($rt_doublecls(), dimensions); + } + var firstDim = dimensions[0] | 0; + for (var i = 0;i < arrays.length;i = i + 1 | 0) { + arrays[i] = $rt_createDoubleArray(firstDim); + } + return $rt_createMultiArrayImpl($rt_doublecls(), arrays, dimensions, 0); +} +function $rt_primitiveArrayCount(dimensions, start) { + var val = dimensions[start + 1] | 0; + for (var i = start + 2;i < dimensions.length;i = i + 1 | 0) { + val = val * (dimensions[i] | 0) | 0; + if (val === 0) { + break; + } + } + return val; +} +function $rt_createMultiArrayImpl(cls, arrays, dimensions, start) { + var limit = arrays.length; + for (var i = start + 1 | 0;i < dimensions.length;i = i + 1 | 0) { + cls = $rt_arraycls(cls); + var dim = dimensions[i]; + var index = 0; + var packedIndex = 0; + while (index < limit) { + var arr = $rt_createUnfilledArray(cls, dim); + for (var j = 0;j < dim;j = j + 1 | 0) { + arr.data[j] = arrays[index]; + index = index + 1 | 0; + } + arrays[packedIndex] = arr; + packedIndex = packedIndex + 1 | 0; + } + limit = packedIndex; + } + return arrays[0]; +} +function $rt_assertNotNaN(value) { + if (typeof value === 'number' && isNaN(value)) { + throw "NaN"; + } + return value; +} +function $rt_createOutputFunction(printFunction) { + var buffer = ""; + var utf8Buffer = 0; + var utf8Remaining = 0; + function putCodePoint(ch) { + if (ch === 0xA) { + printFunction(buffer); + buffer = ""; + } else if (ch < 0x10000) { + buffer += String.fromCharCode(ch); + } else { + ch = ch - 0x10000 | 0; + var hi = (ch >> 10) + 0xD800; + var lo = (ch & 0x3FF) + 0xDC00; + buffer += String.fromCharCode(hi, lo); + } + } + return function(ch) { + if ((ch & 0x80) === 0) { + putCodePoint(ch); + } else if ((ch & 0xC0) === 0x80) { + if (utf8Buffer > 0) { + utf8Remaining <<= 6; + utf8Remaining |= ch & 0x3F; + if ( --utf8Buffer === 0) { + putCodePoint(utf8Remaining); + } + } + } else if ((ch & 0xE0) === 0xC0) { + utf8Remaining = ch & 0x1F; + utf8Buffer = 1; + } else if ((ch & 0xF0) === 0xE0) { + utf8Remaining = ch & 0x0F; + utf8Buffer = 2; + } else if ((ch & 0xF8) === 0xF0) { + utf8Remaining = ch & 0x07; + utf8Buffer = 3; + } + }; +} +var $rt_putStdout = typeof $rt_putStdoutCustom === "function" ? $rt_putStdoutCustom : typeof console === "object" ? $rt_createOutputFunction(function(msg) { + console.info(msg); +}) : function() { +}; +var $rt_putStderr = typeof $rt_putStderrCustom === "function" ? $rt_putStderrCustom : typeof console === "object" ? $rt_createOutputFunction(function(msg) { + console.error(msg); +}) : function() { +}; +var $rt_packageData = null; +function $rt_packages(data) { + var i = 0; + var packages = new Array(data.length); + for (var j = 0;j < data.length;++j) { + var prefixIndex = data[i++]; + var prefix = prefixIndex >= 0 ? packages[prefixIndex] : ""; + packages[j] = prefix + data[i++] + "."; + } + $rt_packageData = packages; +} +function $rt_metadata(data) { + var packages = $rt_packageData; + var i = 0; + while (i < data.length) { + var cls = data[i++]; + cls.$meta = { }; + var m = cls.$meta; + var className = data[i++]; + m.name = className !== 0 ? className : null; + if (m.name !== null) { + var packageIndex = data[i++]; + if (packageIndex >= 0) { + m.name = packages[packageIndex] + m.name; + } + } + m.binaryName = "L" + m.name + ";"; + var superclass = data[i++]; + m.superclass = superclass !== 0 ? superclass : null; + m.supertypes = data[i++]; + if (m.superclass) { + m.supertypes.push(m.superclass); + cls.prototype = Object.create(m.superclass.prototype); + } else { + cls.prototype = { }; + } + var flags = data[i++]; + m.enum = (flags & 8) !== 0; + m.flags = flags; + m.primitive = false; + m.item = null; + cls.prototype.constructor = cls; + cls.classObject = null; + m.accessLevel = data[i++]; + var innerClassInfo = data[i++]; + if (innerClassInfo === 0) { + m.simpleName = null; + m.declaringClass = null; + m.enclosingClass = null; + } else { + var enclosingClass = innerClassInfo[0]; + m.enclosingClass = enclosingClass !== 0 ? enclosingClass : null; + var declaringClass = innerClassInfo[1]; + m.declaringClass = declaringClass !== 0 ? declaringClass : null; + var simpleName = innerClassInfo[2]; + m.simpleName = simpleName !== 0 ? simpleName : null; + } + var clinit = data[i++]; + cls.$clinit = clinit !== 0 ? clinit : function() { + }; + var virtualMethods = data[i++]; + if (virtualMethods !== 0) { + for (var j = 0;j < virtualMethods.length;j += 2) { + var name = virtualMethods[j]; + var func = virtualMethods[j + 1]; + if (typeof name === 'string') { + name = [name]; + } + for (var k = 0;k < name.length;++k) { + cls.prototype[name[k]] = func; + } + } + } + cls.$array = null; + } +} +function $rt_wrapFunction0(f) { + return function() { + return f(this); + }; +} +function $rt_wrapFunction1(f) { + return function(p1) { + return f(this, p1); + }; +} +function $rt_wrapFunction2(f) { + return function(p1, p2) { + return f(this, p1, p2); + }; +} +function $rt_wrapFunction3(f) { + return function(p1, p2, p3) { + return f(this, p1, p2, p3, p3); + }; +} +function $rt_wrapFunction4(f) { + return function(p1, p2, p3, p4) { + return f(this, p1, p2, p3, p4); + }; +} +function $rt_threadStarter(f) { + return function() { + var args = Array.prototype.slice.apply(arguments); + $rt_startThread(function() { + f.apply(this, args); + }); + }; +} +function $rt_mainStarter(f) { + return function(args, callback) { + if (!args) { + args = []; + } + var javaArgs = $rt_createArray($rt_objcls(), args.length); + for (var i = 0;i < args.length;++i) { + javaArgs.data[i] = $rt_str(args[i]); + } + $rt_startThread(function() { + f.call(null, javaArgs); + }, callback); + }; +} +var $rt_stringPool_instance; +function $rt_stringPool(strings) { + $rt_stringPool_instance = new Array(strings.length); + for (var i = 0;i < strings.length;++i) { + $rt_stringPool_instance[i] = $rt_intern($rt_str(strings[i])); + } +} +function $rt_s(index) { + return $rt_stringPool_instance[index]; +} +function $rt_eraseClinit(target) { + return target.$clinit = function() { + }; +} +var $rt_numberConversionView = new DataView(new ArrayBuffer(8)); +var $rt_doubleToLongBits; +var $rt_longBitsToDouble; +if (typeof BigInt !== 'function') { + $rt_doubleToLongBits = function(n) { + $rt_numberConversionView.setFloat64(0, n, true); + return new Long($rt_numberConversionView.getInt32(0, true), $rt_numberConversionView.getInt32(4, true)); + }; + $rt_longBitsToDouble = function(n) { + $rt_numberConversionView.setInt32(0, n.lo, true); + $rt_numberConversionView.setInt32(4, n.hi, true); + return $rt_numberConversionView.getFloat64(0, true); + }; +} else { + $rt_doubleToLongBits = function(n) { + $rt_numberConversionView.setFloat64(0, n, true); + var lo = $rt_numberConversionView.getInt32(0, true); + var hi = $rt_numberConversionView.getInt32(4, true); + return BigInt.asIntN(64, BigInt.asUintN(32, BigInt(lo)) | BigInt(hi) << BigInt(32)); + }; + $rt_longBitsToDouble = function(n) { + var hi = Number(BigInt.asIntN(32, n >> BigInt(32))); + var lo = Number(BigInt.asIntN(32, n & BigInt(0xFFFFFFFF))); + $rt_numberConversionView.setInt32(0, lo, true); + $rt_numberConversionView.setInt32(4, hi, true); + return $rt_numberConversionView.getFloat64(0, true); + }; +} +function $rt_floatToIntBits(n) { + $rt_numberConversionView.setFloat32(0, n); + return $rt_numberConversionView.getInt32(0); +} +function $rt_intBitsToFloat(n) { + $rt_numberConversionView.setInt32(0, n); + return $rt_numberConversionView.getFloat32(0); +} +function $rt_javaException(e) { + return e instanceof Error && typeof e[$rt_javaExceptionProp] === 'object' ? e[$rt_javaExceptionProp] : null; +} +function $rt_jsException(e) { + return typeof e.$jsException === 'object' ? e.$jsException : null; +} +function $rt_wrapException(err) { + var ex = err[$rt_javaExceptionProp]; + if (!ex) { + ex = $rt_createException($rt_str("(JavaScript) " + err.toString())); + err[$rt_javaExceptionProp] = ex; + ex.$jsException = err; + $rt_fillStack(err, ex); + } + return ex; +} +function $dbg_class(obj) { + var cls = obj.constructor; + var arrayDegree = 0; + while (cls.$meta && cls.$meta.item) { + ++arrayDegree; + cls = cls.$meta.item; + } + var clsName = ""; + if (cls === $rt_booleancls()) { + clsName = "boolean"; + } else if (cls === $rt_bytecls()) { + clsName = "byte"; + } else if (cls === $rt_shortcls()) { + clsName = "short"; + } else if (cls === $rt_charcls()) { + clsName = "char"; + } else if (cls === $rt_intcls()) { + clsName = "int"; + } else if (cls === $rt_longcls()) { + clsName = "long"; + } else if (cls === $rt_floatcls()) { + clsName = "float"; + } else if (cls === $rt_doublecls()) { + clsName = "double"; + } else { + clsName = cls.$meta ? cls.$meta.name || "a/" + cls.name : "@" + cls.name; + } + while (arrayDegree-- > 0) { + clsName += "[]"; + } + return clsName; +} +function Long(lo, hi) { + this.lo = lo | 0; + this.hi = hi | 0; +} +Long.prototype.__teavm_class__ = function() { + return "long"; +}; +function Long_isPositive(a) { + return (a.hi & 0x80000000) === 0; +} +function Long_isNegative(a) { + return (a.hi & 0x80000000) !== 0; +} +var Long_MAX_NORMAL = 1 << 18; +var Long_ZERO; +var Long_create; +var Long_fromInt; +var Long_fromNumber; +var Long_toNumber; +var Long_hi; +var Long_lo; +if (typeof BigInt !== "function") { + Long.prototype.toString = function() { + var result = []; + var n = this; + var positive = Long_isPositive(n); + if (!positive) { + n = Long_neg(n); + } + var radix = new Long(10, 0); + do { + var divRem = Long_divRem(n, radix); + result.push(String.fromCharCode(48 + divRem[1].lo)); + n = divRem[0]; + }while (n.lo !== 0 || n.hi !== 0); + result = (result.reverse()).join(''); + return positive ? result : "-" + result; + }; + Long.prototype.valueOf = function() { + return Long_toNumber(this); + }; + Long_ZERO = new Long(0, 0); + Long_fromInt = function(val) { + return new Long(val, -(val < 0) | 0); + }; + Long_fromNumber = function(val) { + if (val >= 0) { + return new Long(val | 0, val / 0x100000000 | 0); + } else { + return Long_neg(new Long( -val | 0, -val / 0x100000000 | 0)); + } + }; + Long_create = function(lo, hi) { + return new Long(lo, hi); + }; + Long_toNumber = function(val) { + return 0x100000000 * val.hi + (val.lo >>> 0); + }; + Long_hi = function(val) { + return val.hi; + }; + Long_lo = function(val) { + return val.lo; + }; +} else { + Long_ZERO = BigInt(0); + Long_create = function(lo, hi) { + return BigInt.asIntN(64, BigInt.asUintN(32, BigInt(lo)) | BigInt(hi) << BigInt(32)); + }; + Long_fromInt = function(val) { + return BigInt(val); + }; + Long_fromNumber = function(val) { + return BigInt(val >= 0 ? Math.floor(val) : Math.ceil(val)); + }; + Long_toNumber = function(val) { + return Number(val); + }; + Long_hi = function(val) { + return Number(BigInt.asIntN(64, val >> BigInt(32))) | 0; + }; + Long_lo = function(val) { + return Number(BigInt.asIntN(32, val)) | 0; + }; +} +var $rt_imul = Math.imul || function(a, b) { + var ah = a >>> 16 & 0xFFFF; + var al = a & 0xFFFF; + var bh = b >>> 16 & 0xFFFF; + var bl = b & 0xFFFF; + return al * bl + (ah * bl + al * bh << 16 >>> 0) | 0; +}; +var $rt_udiv = function(a, b) { + return (a >>> 0) / (b >>> 0) >>> 0; +}; +var $rt_umod = function(a, b) { + return (a >>> 0) % (b >>> 0) >>> 0; +}; +function $rt_checkBounds(index, array) { + if (index < 0 || index >= array.length) { + $rt_throwAIOOBE(); + } + return index; +} +function $rt_checkUpperBound(index, array) { + if (index >= array.length) { + $rt_throwAIOOBE(); + } + return index; +} +function $rt_checkLowerBound(index) { + if (index < 0) { + $rt_throwAIOOBE(); + } + return index; +} +function $rt_classWithoutFields(superclass) { + if (superclass === 0) { + return function() { + }; + } + if (superclass === void 0) { + superclass = $rt_objcls(); + } + return function() { + superclass.call(this); + }; +} +function $rt_setCloneMethod(target, f) { + target.$clone = f; +} +function $rt_cls(cls) { + return jl_Class_getClass(cls); +} +function $rt_str(str) { + if (str === null) { + return null; + } + var characters = $rt_createCharArray(str.length); + var charsBuffer = characters.data; + for (var i = 0; i < str.length; i = (i + 1) | 0) { + charsBuffer[i] = str.charCodeAt(i) & 0xFFFF; + } + return jl_String__init_(characters); +} +function $rt_ustr(str) { + if (str === null) { + return null; + } + var data = str.$characters.data; + var result = ""; + for (var i = 0; i < data.length; i = (i + 1) | 0) { + result += String.fromCharCode(data[i]); + } + return result; +} +function $rt_objcls() { return jl_Object; } +function $rt_stecls() { + return jl_Object; +} +function $rt_nullCheck(val) { + if (val === null) { + $rt_throw(jl_NullPointerException__init_()); + } + return val; +} +function $rt_intern(str) { + return str; +} +function $rt_getThread() { + return null; +} +function $rt_setThread(t) { +} +function $rt_createException(message) { + return jl_RuntimeException__init_(message); +} +function $rt_createStackElement(className, methodName, fileName, lineNumber) { + return null; +} +function $rt_setStack(e, stack) { +} +function $rt_throwAIOOBE() { +} +function $rt_throwCCE() { +} +var $java = Object.create(null); +function jl_Object() { + this.$id$ = 0; +} +function jl_Object__init_() { + var var_0 = new jl_Object(); + jl_Object__init_0(var_0); + return var_0; +} +function jl_Object__init_0($this) {} +function jl_Object_getClass($this) { + var var$1, var$2, var$3; + var$1 = $this.constructor; + if (var$1 === null) + var$2 = null; + else { + var$2 = var$1.classObject; + if (var$2 === null) { + var$2 = new jl_Class; + var$2.$platformClass = var$1; + var$3 = var$2; + var$1.classObject = var$3; + } + } + return var$2; +} +function jl_Object_toString($this) { + var var$1, var$2, var$3, var$4, var$5, var$6, var$7, var$8, var$9; + var$1 = new jl_StringBuilder; + var$1.$buffer = $rt_createCharArray(16); + var$2 = $this.constructor; + if (var$2 === null) + var$3 = null; + else { + var$3 = var$2.classObject; + if (var$3 === null) { + var$3 = new jl_Class; + var$3.$platformClass = var$2; + var$4 = var$3; + var$2.classObject = var$4; + } + } + if (var$3.$name === null) + var$3.$name = $rt_str(var$3.$platformClass.$meta.name); + var$2 = var$3.$name; + jl_AbstractStringBuilder_insert(var$1, var$1.$length, var$2); + jl_AbstractStringBuilder_insert(var$1, var$1.$length, $rt_s(0)); + var$2 = $this; + if (!var$2.$id$) { + var$4 = $rt_nextId(); + var$2.$id$ = var$4; + } + var$2 = otci_IntegerUtil_toUnsignedLogRadixString($this.$id$, 4); + jl_AbstractStringBuilder_insert(var$1, var$1.$length, var$2); + var$2 = new jl_String; + var$5 = var$1.$buffer; + var$6 = var$1.$length; + var$7 = $rt_createCharArray(var$6); + var$8 = var$7.data; + var$2.$characters = var$7; + var$9 = 0; + while (var$9 < var$6) { + var$8[var$9] = var$5.data[var$9 + 0 | 0]; + var$9 = var$9 + 1 | 0; + } + return var$2; +} +function jl_Object_identity($this) { + var $platformThis, var$2; + $platformThis = $this; + if (!$platformThis.$id$) { + var$2 = $rt_nextId(); + $platformThis.$id$ = var$2; + } + return $this.$id$; +} +function jl_Object_clone($this) { + var $result, var$2, var$3; + if (!$rt_isInstance($this, jl_Cloneable) && $this.constructor.$meta.item === null) { + $result = new jl_CloneNotSupportedException; + $result.$suppressionEnabled = 1; + $result.$writableStackTrace = 1; + $rt_throw($result); + } + $result = otp_Platform_clone($this); + var$2 = $result; + var$3 = $rt_nextId(); + var$2.$id$ = var$3; + return $result; +} +var nles_IntegratedServer = $rt_classWithoutFields(); +function nles_IntegratedServer_main($args) { + var var$2, var$3, var$4, var$5, $ptr, $tmp; + $ptr = 0; + if ($rt_resuming()) { + var $thread = $rt_nativeThread(); + $ptr = $thread.pop();var$5 = $thread.pop();var$4 = $thread.pop();var$3 = $thread.pop();var$2 = $thread.pop();$args = $thread.pop(); + } + main: while (true) { switch ($ptr) { + case 0: + jl_String_CASE_INSENSITIVE_ORDER = new jl_String$_clinit_$lambda$_84_0; + jl_Integer_TYPE = $rt_cls($rt_intcls()); + $args = $rt_createArray(jl_String, 1); + $args.data[0] = $rt_s(1); + nles_VFile_altPathSeperator = $args; + jl_Character_TYPE = $rt_cls($rt_charcls()); + jl_Character_characterCache = $rt_createArray(jl_Character, 128); + var$2 = new nles_BooleanResult; + var$2.$bool = 1; + nles_BooleanResult_TRUE = var$2; + var$2 = new nles_BooleanResult; + var$2.$bool = 0; + nles_BooleanResult_FALSE = var$2; + otcic_StdoutOutputStream_INSTANCE = new otcic_StdoutOutputStream; + var$2 = new jnci_UTF8Charset; + $args = $rt_createArray(jl_String, 0); + var$3 = $args.data; + jnc_Charset_checkCanonicalName($rt_s(2)); + var$4 = var$3.length; + var$5 = 0; + while (var$5 < var$4) { + jnc_Charset_checkCanonicalName(var$3[var$5]); + var$5 = var$5 + 1 | 0; + } + var$2.$canonicalName = $rt_s(2); + var$2.$aliases = $args.$clone(); + jnci_UTF8Charset_INSTANCE = var$2; + var$2 = new jnc_CodingErrorAction; + var$2.$name0 = $rt_s(3); + jnc_CodingErrorAction_IGNORE = var$2; + var$2 = new jnc_CodingErrorAction; + var$2.$name0 = $rt_s(4); + jnc_CodingErrorAction_REPLACE = var$2; + var$2 = new jnc_CodingErrorAction; + var$2.$name0 = $rt_s(5); + jnc_CodingErrorAction_REPORT = var$2; + var$2 = new jnc_CoderResult; + var$2.$kind = 0; + var$2.$length0 = 0; + jnc_CoderResult_UNDERFLOW = var$2; + var$2 = new jnc_CoderResult; + var$2.$kind = 1; + var$2.$length0 = 0; + jnc_CoderResult_OVERFLOW = var$2; + var$2 = new jn_ByteOrder; + var$2.$name1 = $rt_s(6); + jn_ByteOrder_BIG_ENDIAN = var$2; + var$2 = new jn_ByteOrder; + var$2.$name1 = $rt_s(7); + jn_ByteOrder_LITTLE_ENDIAN = var$2; + jur_AbstractSet_counter = 1; + jur_AbstractCharClass$PredefinedCharacterClasses__clinit_(); + jur_AbstractCharClass_charClasses = new jur_AbstractCharClass$PredefinedCharacterClasses; + $ptr = 1; + case 1: + nles_SYS_$callClinit(); + if ($rt_suspending()) { + break main; + } + nles_VFSTestClass_test(nles_SYS_VFS); + return; + default: $rt_invalidPointer(); + }} + $rt_nativeThread().push($args, var$2, var$3, var$4, var$5, $ptr); +} +var jlr_AnnotatedElement = $rt_classWithoutFields(0); +var jlr_Type = $rt_classWithoutFields(0); +function jl_Class() { + var a = this; jl_Object.call(a); + a.$name = null; + a.$platformClass = null; +} +function jl_Class_getClass($cls) { + var $result, var$3; + if ($cls === null) + return null; + $result = $cls.classObject; + if ($result === null) { + $result = new jl_Class; + $result.$platformClass = $cls; + var$3 = $result; + $cls.classObject = var$3; + } + return $result; +} +function jl_Class_getComponentType($this) { + var var$1, var$2, var$3; + var$1 = $this.$platformClass.$meta.item; + if (var$1 === null) + var$2 = null; + else { + var$2 = var$1.classObject; + if (var$2 === null) { + var$2 = new jl_Class; + var$2.$platformClass = var$1; + var$3 = var$2; + var$1.classObject = var$3; + } + } + return var$2; +} +var otji_JS = $rt_classWithoutFields(); +function otji_JS_function(var$1, var$2) { + var name = 'jso$functor$' + var$2; + if (!var$1[name]) { + var fn = function() { + return var$1[var$2].apply(var$1, arguments); + }; + var$1[name] = function() { + return fn; + }; + } + return var$1[name](); +} +function otji_JS_functionAsObject(var$1, var$2) { + if (typeof var$1 !== "function") return var$1; + var result = {}; + result[var$2] = var$1; + return result; +} +var otp_Platform = $rt_classWithoutFields(); +function otp_Platform_clone(var$1) { + var copy = new var$1.constructor(); + for (var field in var$1) { + if (!var$1.hasOwnProperty(field)) { + continue; + } + copy[field] = var$1[field]; + } + return copy; +} +function otp_Platform_isAssignable($from, $to) { + var $supertypes, $i; + if ($from === $to) + return 1; + $supertypes = $from.$meta.supertypes; + $i = 0; + while ($i < $supertypes.length) { + if (otp_Platform_isAssignable($supertypes[$i], $to)) + return 1; + $i = $i + 1 | 0; + } + return 0; +} +function otp_Platform_stringFromCharCode($charCode) { + return String.fromCharCode($charCode); +} +var ji_Serializable = $rt_classWithoutFields(0); +var jl_Comparable = $rt_classWithoutFields(0); +var jl_CharSequence = $rt_classWithoutFields(0); +function jl_String() { + var a = this; jl_Object.call(a); + a.$characters = null; + a.$hashCode = 0; +} +var jl_String_CASE_INSENSITIVE_ORDER = null; +function jl_String__init_(var_0) { + var var_1 = new jl_String(); + jl_String__init_0(var_1, var_0); + return var_1; +} +function jl_String__init_1(var_0, var_1, var_2) { + var var_3 = new jl_String(); + jl_String__init_2(var_3, var_0, var_1, var_2); + return var_3; +} +function jl_String__init_0($this, $characters) { + var var$2, var$3, var$4, $i; + $characters = $characters.data; + var$2 = $characters.length; + var$3 = $rt_createCharArray(var$2); + var$4 = var$3.data; + $this.$characters = var$3; + $i = 0; + while ($i < var$2) { + var$4[$i] = $characters[$i]; + $i = $i + 1 | 0; + } +} +function jl_String__init_2($this, $value, $offset, $count) { + var var$4, var$5, $i; + var$4 = $rt_createCharArray($count); + var$5 = var$4.data; + $this.$characters = var$4; + $i = 0; + while ($i < $count) { + var$5[$i] = $value.data[$i + $offset | 0]; + $i = $i + 1 | 0; + } +} +function jl_String_charAt($this, $index) { + var var$2, var$3; + if ($index >= 0) { + var$2 = $this.$characters.data; + if ($index < var$2.length) + return var$2[$index]; + } + var$3 = new jl_StringIndexOutOfBoundsException; + var$3.$suppressionEnabled = 1; + var$3.$writableStackTrace = 1; + $rt_throw(var$3); +} +function jl_String_length($this) { + return $this.$characters.data.length; +} +function jl_String_startsWith($this, $prefix, $toffset) { + var var$3, var$4, var$5, var$6, var$7, $i, var$9; + var$3 = $prefix.$characters.data; + var$4 = var$3.length; + var$5 = $toffset + var$4 | 0; + var$6 = $this.$characters.data; + var$7 = var$6.length; + if (var$5 > var$7) + return 0; + $i = 0; + a: { + b: { + while (true) { + var$5 = $rt_compare($i, var$4); + if (var$5 >= 0) + break; + if ($i < 0) + break a; + if (var$5 >= 0) + break a; + var$9 = var$3[$i]; + var$5 = $toffset + 1 | 0; + if ($toffset < 0) + break b; + if ($toffset >= var$7) + break b; + if (var$9 != var$6[$toffset]) + return 0; + $i = $i + 1 | 0; + $toffset = var$5; + } + return 1; + } + $prefix = new jl_StringIndexOutOfBoundsException; + $prefix.$suppressionEnabled = 1; + $prefix.$writableStackTrace = 1; + $rt_throw($prefix); + } + $prefix = new jl_StringIndexOutOfBoundsException; + $prefix.$suppressionEnabled = 1; + $prefix.$writableStackTrace = 1; + $rt_throw($prefix); +} +function jl_String_startsWith0($this, $prefix) { + if ($this === $prefix) + return 1; + return jl_String_startsWith($this, $prefix, 0); +} +function jl_String_endsWith($this, $suffix) { + var var$2, var$3, var$4, var$5, $j, $i, var$8, var$9; + if ($this === $suffix) + return 1; + var$2 = $suffix.$characters.data; + var$3 = var$2.length; + var$4 = $this.$characters.data; + var$5 = var$4.length; + if (var$3 > var$5) + return 0; + $j = 0; + $i = var$5 - var$3 | 0; + a: { + b: { + while (true) { + var$8 = $rt_compare($i, var$5); + if (var$8 >= 0) + break; + if ($i < 0) + break a; + if (var$8 >= 0) + break a; + var$9 = var$4[$i]; + var$8 = $j + 1 | 0; + if ($j < 0) + break b; + if ($j >= var$3) + break b; + if (var$9 != var$2[$j]) + return 0; + $i = $i + 1 | 0; + $j = var$8; + } + return 1; + } + $suffix = new jl_StringIndexOutOfBoundsException; + $suffix.$suppressionEnabled = 1; + $suffix.$writableStackTrace = 1; + $rt_throw($suffix); + } + $suffix = new jl_StringIndexOutOfBoundsException; + $suffix.$suppressionEnabled = 1; + $suffix.$writableStackTrace = 1; + $rt_throw($suffix); +} +function jl_String_indexOf($this, $ch, $i) { + var $bmpChar, var$4, $hi, $lo; + if (0 > $i) + $i = 0; + if ($ch < 65536) { + $bmpChar = $ch & 65535; + while (true) { + var$4 = $this.$characters.data; + if ($i >= var$4.length) + return (-1); + if (var$4[$i] == $bmpChar) + break; + $i = $i + 1 | 0; + } + return $i; + } + $hi = (55296 | ($ch - 65536 | 0) >> 10 & 1023) & 65535; + $lo = (56320 | $ch & 1023) & 65535; + while (true) { + var$4 = $this.$characters.data; + if ($i >= (var$4.length - 1 | 0)) + return (-1); + if (var$4[$i] == $hi && var$4[$i + 1 | 0] == $lo) + break; + $i = $i + 1 | 0; + } + return $i; +} +function jl_String_lastIndexOf($this, $ch, $fromIndex) { + var var$3, $i, $bmpChar, $hi, $lo; + var$3 = $this.$characters.data; + $i = var$3.length - 1 | 0; + if ($fromIndex < $i) + $i = $fromIndex; + if ($ch < 65536) { + $bmpChar = $ch & 65535; + while (true) { + if ($i < 0) + return (-1); + if (var$3[$i] == $bmpChar) + break; + $i = $i + (-1) | 0; + } + return $i; + } + $hi = (55296 | ($ch - 65536 | 0) >> 10 & 1023) & 65535; + $lo = (56320 | $ch & 1023) & 65535; + while (true) { + if ($i < 1) + return (-1); + if (var$3[$i] == $lo) { + $ch = $i - 1 | 0; + if (var$3[$ch] == $hi) + break; + } + $i = $i + (-1) | 0; + } + return $ch; +} +function jl_String_indexOf0($this, $str, $i) { + var var$3, var$4, var$5, var$6, $toIndex, $j, var$9, var$10, var$11; + if (0 > $i) + $i = 0; + var$3 = $this.$characters.data; + var$4 = var$3.length; + var$5 = $str.$characters.data; + var$6 = var$5.length; + $toIndex = var$4 - var$6 | 0; + a: { + b: { + c: while (true) { + if ($i > $toIndex) + return (-1); + $j = 0; + while (true) { + var$9 = $rt_compare($j, var$6); + if (var$9 >= 0) + break c; + var$10 = $i + $j | 0; + if (var$10 < 0) + break a; + if (var$10 >= var$4) + break a; + var$11 = var$3[var$10]; + if ($j < 0) + break b; + if (var$9 >= 0) + break b; + if (var$11 != var$5[$j]) + break; + $j = $j + 1 | 0; + } + $i = $i + 1 | 0; + } + return $i; + } + $str = new jl_StringIndexOutOfBoundsException; + $str.$suppressionEnabled = 1; + $str.$writableStackTrace = 1; + $rt_throw($str); + } + $str = new jl_StringIndexOutOfBoundsException; + $str.$suppressionEnabled = 1; + $str.$writableStackTrace = 1; + $rt_throw($str); +} +function jl_String_lastIndexOf0($this, $str, $fromIndex) { + var var$3, var$4, var$5, var$6, $i, $j, var$9, var$10; + var$3 = $this.$characters.data; + var$4 = var$3.length; + var$5 = $str.$characters.data; + var$6 = var$5.length; + $i = var$4 - var$6 | 0; + if ($fromIndex < $i) + $i = $fromIndex; + a: { + b: { + c: while (true) { + if ($i < 0) + return (-1); + $j = 0; + while (true) { + var$9 = $rt_compare($j, var$6); + if (var$9 >= 0) + break c; + var$10 = $i + $j | 0; + if (var$10 < 0) + break a; + if (var$10 >= var$4) + break a; + var$10 = var$3[var$10]; + if ($j < 0) + break b; + if (var$9 >= 0) + break b; + if (var$10 != var$5[$j]) + break; + $j = $j + 1 | 0; + } + $i = $i + (-1) | 0; + } + return $i; + } + $str = new jl_StringIndexOutOfBoundsException; + $str.$suppressionEnabled = 1; + $str.$writableStackTrace = 1; + $rt_throw($str); + } + $str = new jl_StringIndexOutOfBoundsException; + $str.$suppressionEnabled = 1; + $str.$writableStackTrace = 1; + $rt_throw($str); +} +function jl_String_substring($this, $beginIndex, $endIndex) { + var var$3, var$4, var$5, var$6, var$7; + if ($beginIndex > $endIndex) { + var$3 = new jl_IndexOutOfBoundsException; + var$3.$suppressionEnabled = 1; + var$3.$writableStackTrace = 1; + $rt_throw(var$3); + } + var$3 = new jl_String; + var$4 = $this.$characters; + $endIndex = $endIndex - $beginIndex | 0; + var$5 = $rt_createCharArray($endIndex); + var$6 = var$5.data; + var$3.$characters = var$5; + var$7 = 0; + while (var$7 < $endIndex) { + var$6[var$7] = var$4.data[var$7 + $beginIndex | 0]; + var$7 = var$7 + 1 | 0; + } + return var$3; +} +function jl_String_replace($this, $target, $replacement) { + var $sb, $sz, $i, var$6, $j, var$8, var$9, var$10, var$11, var$12; + $sb = new jl_StringBuilder; + $sb.$buffer = $rt_createCharArray(16); + $sz = $this.$characters.data.length - $target.$characters.data.length | 0; + $i = 0; + a: { + b: { + c: while (true) { + if ($i > $sz) { + var$6 = $this.$characters.data; + $j = var$6.length; + if ($i > $j) { + $target = new jl_IndexOutOfBoundsException; + $target.$suppressionEnabled = 1; + $target.$writableStackTrace = 1; + $rt_throw($target); + } + $target = new jl_String; + $sz = $j - $i | 0; + var$8 = $rt_createCharArray($sz); + var$9 = var$8.data; + $target.$characters = var$8; + var$10 = 0; + while (var$10 < $sz) { + var$9[var$10] = var$6[var$10 + $i | 0]; + var$10 = var$10 + 1 | 0; + } + jl_AbstractStringBuilder_insert($sb, $sb.$length, $target); + $target = new jl_String; + var$9 = $sb.$buffer; + $i = $sb.$length; + var$6 = $rt_createCharArray($i); + var$8 = var$6.data; + $target.$characters = var$6; + $sz = 0; + while ($sz < $i) { + var$8[$sz] = var$9.data[$sz + 0 | 0]; + $sz = $sz + 1 | 0; + } + return $target; + } + $j = 0; + d: { + while (true) { + var$9 = $target.$characters.data; + var$10 = $rt_compare($j, var$9.length); + if (var$10 >= 0) + break; + var$11 = $i + $j | 0; + if (var$11 < 0) + break b; + var$6 = $this.$characters.data; + var$12 = var$6.length; + if (var$11 >= var$12) + break b; + var$11 = var$6[var$11]; + if ($j < 0) + break c; + if (var$10 >= 0) + break c; + if (var$11 != var$9[$j]) { + if ($i < 0) + break a; + if ($i >= var$12) + break a; + var$11 = var$6[$i]; + var$10 = $sb.$length; + jl_AbstractStringBuilder_insertSpace($sb, var$10, var$10 + 1 | 0); + $sb.$buffer.data[var$10] = var$11; + break d; + } + $j = $j + 1 | 0; + } + jl_AbstractStringBuilder_insert($sb, $sb.$length, $replacement === null ? $rt_s(8) : $replacement); + $i = $i + ($target.$characters.data.length - 1 | 0) | 0; + } + $i = $i + 1 | 0; + } + $target = new jl_StringIndexOutOfBoundsException; + $target.$suppressionEnabled = 1; + $target.$writableStackTrace = 1; + $rt_throw($target); + } + $target = new jl_StringIndexOutOfBoundsException; + $target.$suppressionEnabled = 1; + $target.$writableStackTrace = 1; + $rt_throw($target); + } + $target = new jl_StringIndexOutOfBoundsException; + $target.$suppressionEnabled = 1; + $target.$writableStackTrace = 1; + $rt_throw($target); +} +function jl_String_trim($this) { + var $lower, var$2, var$3, $upper, var$5, var$6, var$7, var$8; + $lower = 0; + var$2 = $this.$characters.data; + var$3 = var$2.length; + $upper = var$3 - 1 | 0; + a: { + while (true) { + if ($lower > $upper) + break a; + if ($lower < 0) + break; + if ($lower >= var$3) + break; + if (var$2[$lower] > 32) + break a; + $lower = $lower + 1 | 0; + } + var$5 = new jl_StringIndexOutOfBoundsException; + var$5.$suppressionEnabled = 1; + var$5.$writableStackTrace = 1; + $rt_throw(var$5); + } + b: { + while (true) { + if ($lower > $upper) + break b; + if ($upper < 0) + break; + if ($upper >= var$3) + break; + if (var$2[$upper] > 32) + break b; + $upper = $upper + (-1) | 0; + } + var$5 = new jl_StringIndexOutOfBoundsException; + var$5.$suppressionEnabled = 1; + var$5.$writableStackTrace = 1; + $rt_throw(var$5); + } + var$6 = $upper + 1 | 0; + if ($lower > var$6) { + var$5 = new jl_IndexOutOfBoundsException; + var$5.$suppressionEnabled = 1; + var$5.$writableStackTrace = 1; + $rt_throw(var$5); + } + var$5 = new jl_String; + var$6 = var$6 - $lower | 0; + var$7 = $rt_createCharArray(var$6); + var$8 = var$7.data; + var$5.$characters = var$7; + $upper = 0; + while ($upper < var$6) { + var$8[$upper] = var$2[$upper + $lower | 0]; + $upper = $upper + 1 | 0; + } + return var$5; +} +function jl_String_toString($this) { + return $this; +} +function jl_String_equals($this, $other) { + var var$2, var$3, var$4, var$5, $i, var$7, var$8; + if ($this === $other) + return 1; + if (!($other instanceof jl_String)) + return 0; + var$2 = $other.$characters.data; + var$3 = var$2.length; + var$4 = $this.$characters.data; + var$5 = var$4.length; + if (var$3 != var$5) + return 0; + $i = 0; + a: { + b: { + while (true) { + var$7 = $rt_compare($i, var$3); + if (var$7 >= 0) + break; + if ($i < 0) + break a; + if ($i >= var$5) + break a; + var$8 = var$4[$i]; + if ($i < 0) + break b; + if (var$7 >= 0) + break b; + if (var$8 != var$2[$i]) + return 0; + $i = $i + 1 | 0; + } + return 1; + } + $other = new jl_StringIndexOutOfBoundsException; + $other.$suppressionEnabled = 1; + $other.$writableStackTrace = 1; + $rt_throw($other); + } + $other = new jl_StringIndexOutOfBoundsException; + $other.$suppressionEnabled = 1; + $other.$writableStackTrace = 1; + $rt_throw($other); +} +function jl_String_hashCode($this) { + var var$1, var$2, var$3, $c; + a: { + if (!$this.$hashCode) { + var$1 = $this.$characters.data; + var$2 = var$1.length; + var$3 = 0; + while (true) { + if (var$3 >= var$2) + break a; + $c = var$1[var$3]; + $this.$hashCode = (31 * $this.$hashCode | 0) + $c | 0; + var$3 = var$3 + 1 | 0; + } + } + } + return $this.$hashCode; +} +function jl_String__clinit_() { + jl_String_CASE_INSENSITIVE_ORDER = new jl_String$_clinit_$lambda$_84_0; +} +function jl_Throwable() { + var a = this; jl_Object.call(a); + a.$message = null; + a.$cause = null; + a.$suppressionEnabled = 0; + a.$writableStackTrace = 0; +} +function jl_Throwable__init_() { + var var_0 = new jl_Throwable(); + jl_Throwable__init_0(var_0); + return var_0; +} +function jl_Throwable__init_0($this) { + $this.$suppressionEnabled = 1; + $this.$writableStackTrace = 1; +} +function jl_Throwable_fillInStackTrace($this) { + return $this; +} +var jl_Error = $rt_classWithoutFields(jl_Throwable); +var jl_LinkageError = $rt_classWithoutFields(jl_Error); +var jl_NoClassDefFoundError = $rt_classWithoutFields(jl_LinkageError); +function jl_AbstractStringBuilder() { + var a = this; jl_Object.call(a); + a.$buffer = null; + a.$length = 0; +} +function jl_AbstractStringBuilder__init_() { + var var_0 = new jl_AbstractStringBuilder(); + jl_AbstractStringBuilder__init_0(var_0); + return var_0; +} +function jl_AbstractStringBuilder__init_1(var_0) { + var var_1 = new jl_AbstractStringBuilder(); + jl_AbstractStringBuilder__init_2(var_1, var_0); + return var_1; +} +function jl_AbstractStringBuilder__init_0($this) { + $this.$buffer = $rt_createCharArray(16); +} +function jl_AbstractStringBuilder__init_2($this, $capacity) { + $this.$buffer = $rt_createCharArray($capacity); +} +function jl_AbstractStringBuilder_append($this, $string) { + jl_AbstractStringBuilder_insert($this, $this.$length, $string); + return $this; +} +function jl_AbstractStringBuilder_insert($this, $index, $string) { + var $i, $i_0, var$5, var$6, var$7, var$8; + if ($index >= 0) { + $i = $this.$length; + if ($index <= $i) { + if ($string === null) + $string = $rt_s(8); + else if ($string.$characters.data.length ? 0 : 1) + return $this; + jl_AbstractStringBuilder_ensureCapacity($this, $i + $string.$characters.data.length | 0); + $i = $this.$length; + $i_0 = $i - 1 | 0; + while ($i_0 >= $index) { + var$5 = $this.$buffer.data; + var$5[$i_0 + $string.$characters.data.length | 0] = var$5[$i_0]; + $i_0 = $i_0 + (-1) | 0; + } + var$5 = $string.$characters.data; + var$6 = var$5.length; + $this.$length = $i + var$6 | 0; + $i = 0; + a: { + while (true) { + $i_0 = $rt_compare($i, var$6); + if ($i_0 >= 0) + break; + var$7 = $this.$buffer; + var$8 = $index + 1 | 0; + if ($i < 0) + break a; + if ($i_0 >= 0) + break a; + var$7.data[$index] = var$5[$i]; + $i = $i + 1 | 0; + $index = var$8; + } + return $this; + } + $string = new jl_StringIndexOutOfBoundsException; + $string.$suppressionEnabled = 1; + $string.$writableStackTrace = 1; + $rt_throw($string); + } + } + $string = new jl_StringIndexOutOfBoundsException; + $string.$suppressionEnabled = 1; + $string.$writableStackTrace = 1; + $rt_throw($string); +} +function jl_AbstractStringBuilder_append0($this, $value, $radix) { + return jl_AbstractStringBuilder_insert0($this, $this.$length, $value, $radix); +} +function jl_AbstractStringBuilder_insert0($this, $target, $value, $radix) { + var $positive, var$5, var$6, $pos, $sz, $posLimit, var$10; + $positive = 1; + if ($value < 0) { + $positive = 0; + $value = -$value | 0; + } + a: { + if ($value < $radix) { + if ($positive) + jl_AbstractStringBuilder_insertSpace($this, $target, $target + 1 | 0); + else { + jl_AbstractStringBuilder_insertSpace($this, $target, $target + 2 | 0); + var$5 = $this.$buffer.data; + var$6 = $target + 1 | 0; + var$5[$target] = 45; + $target = var$6; + } + $this.$buffer.data[$target] = jl_Character_forDigit($value, $radix); + } else { + $pos = 1; + $sz = 1; + $posLimit = 2147483647 / $radix | 0; + b: { + while (true) { + var$10 = $rt_imul($pos, $radix); + if (var$10 > $value) { + var$10 = $pos; + break b; + } + $sz = $sz + 1 | 0; + if (var$10 > $posLimit) + break; + $pos = var$10; + } + } + if (!$positive) + $sz = $sz + 1 | 0; + jl_AbstractStringBuilder_insertSpace($this, $target, $target + $sz | 0); + if ($positive) + $positive = $target; + else { + var$5 = $this.$buffer.data; + $positive = $target + 1 | 0; + var$5[$target] = 45; + } + while (true) { + if (var$10 <= 0) + break a; + var$5 = $this.$buffer.data; + $target = $positive + 1 | 0; + var$5[$positive] = jl_Character_forDigit($value / var$10 | 0, $radix); + $value = $value % var$10 | 0; + var$10 = var$10 / $radix | 0; + $positive = $target; + } + } + } + return $this; +} +function jl_AbstractStringBuilder_ensureCapacity($this, $capacity) { + var var$2, var$3, $newLength, var$5, var$6, var$7; + var$2 = $this.$buffer.data; + var$3 = var$2.length; + if (var$3 >= $capacity) + return; + if (var$3 >= 1073741823) + $newLength = 2147483647; + else { + var$5 = var$3 * 2 | 0; + $newLength = 5; + if (var$5 > $newLength) + $newLength = var$5; + if ($capacity > $newLength) + $newLength = $capacity; + } + var$6 = $rt_createCharArray($newLength); + if ($newLength < var$3) + var$3 = $newLength; + var$7 = var$6.data; + $capacity = 0; + while ($capacity < var$3) { + var$7[$capacity] = var$2[$capacity]; + $capacity = $capacity + 1 | 0; + } + $this.$buffer = var$6; +} +function jl_AbstractStringBuilder_toString($this) { + var var$1, var$2, var$3, var$4, var$5, var$6; + var$1 = new jl_String; + var$2 = $this.$buffer; + var$3 = $this.$length; + var$4 = $rt_createCharArray(var$3); + var$5 = var$4.data; + var$1.$characters = var$4; + var$6 = 0; + while (var$6 < var$3) { + var$5[var$6] = var$2.data[var$6 + 0 | 0]; + var$6 = var$6 + 1 | 0; + } + return var$1; +} +function jl_AbstractStringBuilder_insert1($this, $index, $chars, $offset, $len) { + var var$5, var$6, var$7, var$8; + jl_AbstractStringBuilder_insertSpace($this, $index, $index + $len | 0); + var$5 = $len + $offset | 0; + while ($offset < var$5) { + var$6 = $chars.data; + var$7 = $this.$buffer.data; + $len = $index + 1 | 0; + var$8 = $offset + 1 | 0; + var$7[$index] = var$6[$offset]; + $index = $len; + $offset = var$8; + } + return $this; +} +function jl_AbstractStringBuilder_deleteCharAt($this, $i) { + var var$2, var$3, $i_0, var$5; + if ($i >= 0) { + var$2 = $this.$length; + if ($i < var$2) { + var$2 = var$2 - 1 | 0; + $this.$length = var$2; + while ($i < var$2) { + var$3 = $this.$buffer.data; + $i_0 = $i + 1 | 0; + var$3[$i] = var$3[$i_0]; + $i = $i_0; + } + return $this; + } + } + var$5 = new jl_StringIndexOutOfBoundsException; + var$5.$suppressionEnabled = 1; + var$5.$writableStackTrace = 1; + $rt_throw(var$5); +} +function jl_AbstractStringBuilder_delete($this, $start, $end) { + var $sz, var$4, $i, var$6, var$7, var$8; + $sz = $rt_compare($start, $end); + if ($sz <= 0) { + var$4 = $this.$length; + if ($start <= var$4) { + if (!$sz) + return $this; + $sz = var$4 - $end | 0; + $this.$length = var$4 - ($end - $start | 0) | 0; + $i = 0; + while ($i < $sz) { + var$6 = $this.$buffer.data; + var$7 = $start + 1 | 0; + var$4 = $end + 1 | 0; + var$6[$start] = var$6[$end]; + $i = $i + 1 | 0; + $start = var$7; + $end = var$4; + } + return $this; + } + } + var$8 = new jl_StringIndexOutOfBoundsException; + var$8.$suppressionEnabled = 1; + var$8.$writableStackTrace = 1; + $rt_throw(var$8); +} +function jl_AbstractStringBuilder_insertSpace($this, $start, $end) { + var var$3, $sz, $i, var$6; + var$3 = $this.$length; + $sz = var$3 - $start | 0; + $this.$ensureCapacity((var$3 + $end | 0) - $start | 0); + $i = $sz - 1 | 0; + while ($i >= 0) { + var$6 = $this.$buffer.data; + var$6[$end + $i | 0] = var$6[$start + $i | 0]; + $i = $i + (-1) | 0; + } + $this.$length = $this.$length + ($end - $start | 0) | 0; +} +var jl_Appendable = $rt_classWithoutFields(0); +var jl_StringBuilder = $rt_classWithoutFields(jl_AbstractStringBuilder); +function jl_StringBuilder_append($this, $c) { + var var$2; + var$2 = $this.$length; + jl_AbstractStringBuilder_insertSpace($this, var$2, var$2 + 1 | 0); + $this.$buffer.data[var$2] = $c; + return $this; +} +function jl_StringBuilder_delete($this, $start, $end) { + jl_AbstractStringBuilder_delete($this, $start, $end); + return $this; +} +function jl_StringBuilder_insert($this, var$1, var$2, var$3, var$4) { + var var$5, var$6, var$7, var$8; + jl_AbstractStringBuilder_insertSpace($this, var$1, var$1 + var$4 | 0); + var$5 = var$4 + var$3 | 0; + while (var$3 < var$5) { + var$6 = var$2.data; + var$7 = $this.$buffer.data; + var$4 = var$1 + 1 | 0; + var$8 = var$3 + 1 | 0; + var$7[var$1] = var$6[var$3]; + var$1 = var$4; + var$3 = var$8; + } + return $this; +} +function jl_StringBuilder_append0($this, var$1, var$2, var$3) { + var var$4, var$5, var$6, var$7, var$8; + var$4 = $this.$length; + jl_AbstractStringBuilder_insertSpace($this, var$4, var$4 + var$3 | 0); + var$5 = var$3 + var$2 | 0; + while (var$2 < var$5) { + var$6 = var$1.data; + var$7 = $this.$buffer.data; + var$3 = var$4 + 1 | 0; + var$8 = var$2 + 1 | 0; + var$7[var$4] = var$6[var$2]; + var$4 = var$3; + var$2 = var$8; + } + return $this; +} +function jl_StringBuilder_length($this) { + return $this.$length; +} +function jl_StringBuilder_toString($this) { + var var$1, var$2, var$3, var$4, var$5, var$6; + var$1 = new jl_String; + var$2 = $this.$buffer; + var$3 = $this.$length; + var$4 = $rt_createCharArray(var$3); + var$5 = var$4.data; + var$1.$characters = var$4; + var$6 = 0; + while (var$6 < var$3) { + var$5[var$6] = var$2.data[var$6 + 0 | 0]; + var$6 = var$6 + 1 | 0; + } + return var$1; +} +function jl_StringBuilder_ensureCapacity($this, var$1) { + jl_AbstractStringBuilder_ensureCapacity($this, var$1); +} +function jl_StringBuilder_insert0($this, var$1, var$2) { + jl_AbstractStringBuilder_insertSpace($this, var$1, var$1 + 1 | 0); + $this.$buffer.data[var$1] = var$2; + return $this; +} +var jl_Number = $rt_classWithoutFields(); +function jl_Integer() { + jl_Number.call(this); + this.$value = 0; +} +var jl_Integer_TYPE = null; +function jl_Integer_toString($i, $radix) { + var var$3; + if (!($radix >= 2 && $radix <= 36)) + $radix = 10; + var$3 = new jl_AbstractStringBuilder; + var$3.$buffer = $rt_createCharArray(20); + return (jl_AbstractStringBuilder_insert0(var$3, var$3.$length, $i, $radix)).$toString(); +} +function jl_Integer_toString0($i) { + var var$2; + var$2 = new jl_AbstractStringBuilder; + var$2.$buffer = $rt_createCharArray(20); + return (jl_AbstractStringBuilder_insert0(var$2, var$2.$length, $i, 10)).$toString(); +} +function jl_Integer_parseInt($s, $radix) { + var var$3, var$4, $negative, $index, $value, $digit, var$9, var$10, var$11, var$12; + if ($radix >= 2 && $radix <= 36) { + if ($s !== null) { + var$3 = $s.$characters.data; + var$4 = var$3.length; + if (!(var$4 ? 0 : 1)) { + $negative = 0; + $index = 0; + if (0 >= var$4) { + $s = new jl_StringIndexOutOfBoundsException; + $s.$suppressionEnabled = 1; + $s.$writableStackTrace = 1; + $rt_throw($s); + } + a: { + switch (var$3[0]) { + case 43: + $index = 1; + break a; + case 45: + $negative = 1; + $index = 1; + break a; + default: + } + } + $value = 0; + if ($index == var$4) { + $s = new jl_NumberFormatException; + $s.$suppressionEnabled = 1; + $s.$writableStackTrace = 1; + $rt_throw($s); + } + b: { + while (true) { + var$3 = $s.$characters.data; + $digit = $rt_compare($index, var$3.length); + if ($digit >= 0) + break; + var$4 = $index + 1 | 0; + if ($index < 0) + break b; + if ($digit >= 0) + break b; + $digit = jl_Character_getNumericValue(var$3[$index]); + if ($digit < 0) { + var$9 = new jl_NumberFormatException; + var$10 = new jl_StringBuilder; + var$10.$buffer = $rt_createCharArray(16); + jl_AbstractStringBuilder_insert(var$10, var$10.$length, $rt_s(9)); + jl_AbstractStringBuilder_insert(var$10, var$10.$length, $s); + $s = new jl_String; + var$3 = var$10.$buffer; + $negative = var$10.$length; + var$11 = $rt_createCharArray($negative); + var$12 = var$11.data; + $s.$characters = var$11; + $index = 0; + while ($index < $negative) { + var$12[$index] = var$3.data[$index + 0 | 0]; + $index = $index + 1 | 0; + } + var$9.$suppressionEnabled = 1; + var$9.$writableStackTrace = 1; + var$9.$message = $s; + $rt_throw(var$9); + } + if ($digit >= $radix) { + var$9 = new jl_NumberFormatException; + var$10 = new jl_StringBuilder; + var$10.$buffer = $rt_createCharArray(16); + jl_AbstractStringBuilder_insert(var$10, var$10.$length, $rt_s(10)); + jl_AbstractStringBuilder_insert0(var$10, var$10.$length, $radix, 10); + jl_AbstractStringBuilder_insert(var$10, var$10.$length, $rt_s(11)); + jl_AbstractStringBuilder_insert(var$10, var$10.$length, $s); + $s = jl_StringBuilder_toString(var$10); + var$9.$suppressionEnabled = 1; + var$9.$writableStackTrace = 1; + var$9.$message = $s; + $rt_throw(var$9); + } + $value = $rt_imul($radix, $value) + $digit | 0; + if ($value < 0) { + if (var$4 == $s.$characters.data.length && $value == (-2147483648) && $negative) + return (-2147483648); + var$9 = new jl_NumberFormatException; + var$10 = new jl_StringBuilder; + jl_AbstractStringBuilder__init_2(var$10, 16); + jl_AbstractStringBuilder_append(var$10, $rt_s(12)); + jl_AbstractStringBuilder_append(var$10, $s); + jl_NumberFormatException__init_(var$9, jl_StringBuilder_toString(var$10)); + $rt_throw(var$9); + } + $index = var$4; + } + if ($negative) + $value = -$value | 0; + return $value; + } + $s = new jl_StringIndexOutOfBoundsException; + $s.$suppressionEnabled = 1; + $s.$writableStackTrace = 1; + $rt_throw($s); + } + } + $s = new jl_NumberFormatException; + $s.$suppressionEnabled = 1; + $s.$writableStackTrace = 1; + $s.$message = $rt_s(13); + $rt_throw($s); + } + var$9 = new jl_NumberFormatException; + $s = new jl_StringBuilder; + $s.$buffer = $rt_createCharArray(16); + jl_AbstractStringBuilder_insert($s, $s.$length, $rt_s(14)); + jl_AbstractStringBuilder_insert0($s, $s.$length, $radix, 10); + var$10 = new jl_String; + var$3 = $s.$buffer; + $negative = $s.$length; + var$11 = $rt_createCharArray($negative); + var$12 = var$11.data; + var$10.$characters = var$11; + $index = 0; + while ($index < $negative) { + var$12[$index] = var$3.data[$index + 0 | 0]; + $index = $index + 1 | 0; + } + var$9.$suppressionEnabled = 1; + var$9.$writableStackTrace = 1; + var$9.$message = var$10; + $rt_throw(var$9); +} +function jl_Integer_numberOfLeadingZeros($i) { + var $n, var$3; + if (!$i) + return 32; + $n = 0; + var$3 = $i >>> 16; + if (var$3) + $n = 16; + else + var$3 = $i; + $i = var$3 >>> 8; + if (!$i) + $i = var$3; + else + $n = $n | 8; + var$3 = $i >>> 4; + if (!var$3) + var$3 = $i; + else + $n = $n | 4; + $i = var$3 >>> 2; + if (!$i) + $i = var$3; + else + $n = $n | 2; + if ($i >>> 1) + $n = $n | 1; + return (32 - $n | 0) - 1 | 0; +} +function jl_Integer_numberOfTrailingZeros($i) { + var $n, var$3; + if (!$i) + return 32; + $n = 0; + var$3 = $i << 16; + if (var$3) + $n = 16; + else + var$3 = $i; + $i = var$3 << 8; + if (!$i) + $i = var$3; + else + $n = $n | 8; + var$3 = $i << 4; + if (!var$3) + var$3 = $i; + else + $n = $n | 4; + $i = var$3 << 2; + if (!$i) + $i = var$3; + else + $n = $n | 2; + if ($i << 1) + $n = $n | 1; + return (32 - $n | 0) - 1 | 0; +} +function jl_Integer__clinit_() { + jl_Integer_TYPE = $rt_cls($rt_intcls()); +} +var jl_IncompatibleClassChangeError = $rt_classWithoutFields(jl_LinkageError); +var jl_NoSuchFieldError = $rt_classWithoutFields(jl_IncompatibleClassChangeError); +function jl_NoSuchFieldError__init_(var_0) { + var var_1 = new jl_NoSuchFieldError(); + jl_NoSuchFieldError__init_0(var_1, var_0); + return var_1; +} +function jl_NoSuchFieldError__init_0($this, $message) { + $this.$suppressionEnabled = 1; + $this.$writableStackTrace = 1; + $this.$message = $message; +} +var jl_NoSuchMethodError = $rt_classWithoutFields(jl_IncompatibleClassChangeError); +function jl_NoSuchMethodError__init_(var_0) { + var var_1 = new jl_NoSuchMethodError(); + jl_NoSuchMethodError__init_0(var_1, var_0); + return var_1; +} +function jl_NoSuchMethodError__init_0($this, $message) { + $this.$suppressionEnabled = 1; + $this.$writableStackTrace = 1; + $this.$message = $message; +} +var jl_Exception = $rt_classWithoutFields(jl_Throwable); +var jl_RuntimeException = $rt_classWithoutFields(jl_Exception); +function jl_RuntimeException__init_(var_0) { + var var_1 = new jl_RuntimeException(); + jl_RuntimeException__init_0(var_1, var_0); + return var_1; +} +function jl_RuntimeException__init_0($this, $message) { + $this.$suppressionEnabled = 1; + $this.$writableStackTrace = 1; + $this.$message = $message; +} +var nles_SYS = $rt_classWithoutFields(); +var nles_SYS_PERSIST = 0; +var nles_SYS_VFS = null; +var nles_SYS_$clinitCalled = false; +function nles_SYS_$callClinit() { + var $ptr = 0; + if ($rt_resuming()) { + $ptr = $rt_nativeThread().pop(); + } else if (nles_SYS_$clinitCalled) { + return; + } + main: while (true) { switch ($ptr) { + case 0: + nles_SYS_$clinitCalled = true; + $ptr = 1; + case 1: + nles_SYS__clinit_(); + if ($rt_suspending()) { + break main; + } + nles_SYS_$callClinit = $rt_eraseClinit(nles_SYS); + return; + default: $rt_invalidPointer(); + }} + $rt_nativeThread().push($ptr); +} +function nles_SYS_requestPersist() { + var thread = $rt_nativeThread(); + var javaThread = $rt_getThread(); + if (thread.isResuming()) { + thread.status = 0; + var result = thread.attribute; + if (result instanceof Error) { + throw result; + } + return result; + } + var callback = function() {}; + callback.$complete = function(val) { + thread.attribute = val; + $rt_setThread(javaThread); + thread.resume(); + }; + callback.$error = function(e) { + thread.attribute = $rt_exception(e); + $rt_setThread(javaThread); + thread.resume(); + }; + callback = otpp_AsyncCallbackWrapper_create(callback); + return thread.suspend(function() { + try { + nles_SYS_requestPersist0(callback); + } catch($e) { + callback.$error($rt_exception($e)); + } + }); +} +function nles_SYS_requestPersist0($callback) { + var var$2, $ptr, $tmp; + $ptr = 0; + if ($rt_resuming()) { + var $thread = $rt_nativeThread(); + $ptr = $thread.pop();var$2 = $thread.pop();$callback = $thread.pop(); + } + main: while (true) { switch ($ptr) { + case 0: + $ptr = 1; + case 1: + nles_SYS_$callClinit(); + if ($rt_suspending()) { + break main; + } + var$2 = new nles_SYS$requestPersist$lambda$_2_0; + var$2.$_0 = $callback; + $callback = otji_JS_function(var$2, "complete"); + $ptr = 2; + case 2: + nles_SYS_requestPersist0$js_body$_3($callback); + if ($rt_suspending()) { + break main; + } + return; + default: $rt_invalidPointer(); + }} + $rt_nativeThread().push($callback, var$2, $ptr); +} +function nles_SYS__clinit_() { + var $vh, var$2, var$3, var$4, var$5, var$6, var$7, var$8, var$9, $ptr, $tmp; + $ptr = 0; + if ($rt_resuming()) { + var $thread = $rt_nativeThread(); + $ptr = $thread.pop();var$9 = $thread.pop();var$8 = $thread.pop();var$7 = $thread.pop();var$6 = $thread.pop();var$5 = $thread.pop();var$4 = $thread.pop();var$3 = $thread.pop();var$2 = $thread.pop();$vh = $thread.pop(); + } + main: while (true) { switch ($ptr) { + case 0: + $ptr = 1; + case 1: + $tmp = nles_SYS_requestPersist(); + if ($rt_suspending()) { + break main; + } + $vh = $tmp; + var$2 = $vh.$bool; + nles_SYS_PERSIST = var$2; + if (!var$2) + alert("PERSISTENT STORAGE NOT AVAILABLE, YOUR BROWSER MAY DELETE YOUR WORLDS!"); + $vh = $rt_s(15); + $ptr = 2; + case 2: + $tmp = nles_VirtualFilesystem_openVFS($vh); + if ($rt_suspending()) { + break main; + } + $vh = $tmp; + if ($vh.$vfs === null) { + var$3 = new jl_StringBuilder; + var$3.$buffer = $rt_createCharArray(16); + jl_AbstractStringBuilder_insert(var$3, var$3.$length, $rt_s(16)); + var$4 = nles_VirtualFilesystem$VFSHandle_toString($vh); + jl_AbstractStringBuilder_insert(var$3, var$3.$length, var$4); + var$4 = new jl_String; + var$5 = var$3.$buffer; + var$6 = var$3.$length; + var$7 = $rt_createCharArray(var$6); + var$8 = var$7.data; + var$4.$characters = var$7; + var$9 = 0; + while (var$9 < var$6) { + var$8[var$9] = var$5.data[var$9 + 0 | 0]; + var$9 = var$9 + 1 | 0; + } + alert($rt_ustr(var$4)); + } + nles_SYS_VFS = $vh.$vfs; + return; + default: $rt_invalidPointer(); + }} + $rt_nativeThread().push($vh, var$2, var$3, var$4, var$5, var$6, var$7, var$8, var$9, $ptr); +} +function nles_SYS_requestPersist0$js_body$_3(var$1) { + if (navigator.storage && navigator.storage.persist) { + (navigator.storage.persist()).then(function(persistent) { + var$1(persistent ? { p : true } : null); + }); + } else { + var$1(null); + } +} +var nles_VFSTestClass = $rt_classWithoutFields(); +function nles_VFSTestClass_test($vfs) { + var $f, var$3, var$4, var$5, var$6; + $f = new nles_VFile; + var$3 = $rt_createArray(jl_Object, 1); + var$3.data[0] = $rt_s(17); + $f.$path = nles_VFile_createPath(var$3); + if (jl_System_outCache === null) { + var$4 = new ji_PrintStream; + var$4.$out = otcic_StdoutOutputStream_INSTANCE; + $vfs = new jl_StringBuilder; + $vfs.$buffer = $rt_createCharArray(16); + var$4.$sb = $vfs; + var$4.$buffer0 = $rt_createCharArray(32); + var$4.$autoFlush = 0; + var$4.$charset = jnci_UTF8Charset_INSTANCE; + jl_System_outCache = var$4; + } + ji_PrintStream_println(jl_System_outCache, $f); + $vfs = new nles_VFile; + var$3 = $rt_createArray(jl_Object, 1); + var$3.data[0] = $rt_s(18); + nles_VFile__init_($vfs, var$3); + ji_PrintStream_println(jl_System_out(), $vfs); + $vfs = new nles_VFile; + var$3 = $rt_createArray(jl_Object, 1); + var$3.data[0] = $rt_s(19); + nles_VFile__init_($vfs, var$3); + ji_PrintStream_println(jl_System_out(), $vfs); + $vfs = new nles_VFile; + var$3 = $rt_createArray(jl_Object, 1); + var$3.data[0] = $rt_s(20); + nles_VFile__init_($vfs, var$3); + ji_PrintStream_println(jl_System_out(), $vfs); + $vfs = new nles_VFile; + var$3 = $rt_createArray(jl_Object, 1); + var$3.data[0] = $rt_s(21); + nles_VFile__init_($vfs, var$3); + ji_PrintStream_println(jl_System_out(), $vfs); + $vfs = new nles_VFile; + var$3 = $rt_createArray(jl_Object, 1); + var$3.data[0] = $rt_s(22); + nles_VFile__init_($vfs, var$3); + ji_PrintStream_println(jl_System_out(), $vfs); + $vfs = new nles_VFile; + var$3 = $rt_createArray(jl_Object, 1); + var$3.data[0] = $rt_s(23); + nles_VFile__init_($vfs, var$3); + ji_PrintStream_println(jl_System_out(), $vfs); + $vfs = nles_VFile__init_0($rt_createArrayFromData(jl_Object, [$rt_s(24), $rt_s(25), $rt_s(26)])); + ji_PrintStream_println(jl_System_out(), $vfs); + $f = nles_VFile__init_0($rt_createArrayFromData(jl_Object, [$vfs, $rt_s(27), $rt_s(24), $rt_s(25), $rt_s(26)])); + ji_PrintStream_println(jl_System_out(), $f); + $vfs = nles_VFile__init_0($rt_createArrayFromData(jl_Object, [$f, $rt_s(28), $rt_s(24), $rt_s(29), $rt_s(26)])); + ji_PrintStream_println(jl_System_out(), $vfs); + $f = nles_VFile__init_0($rt_createArrayFromData(jl_Object, [$rt_s(30), $vfs])); + ji_PrintStream_println(jl_System_out(), $f); + $vfs = nles_VFile__init_0($rt_createArrayFromData(jl_Object, [$rt_s(31), $f])); + ji_PrintStream_println(jl_System_out(), $vfs); + $f = nles_VFile__init_0($rt_createArrayFromData(jl_Object, [$rt_s(32), $vfs])); + ji_PrintStream_println(jl_System_out(), $f); + $vfs = new nles_VFile; + var$3 = $rt_createArray(jl_Object, 4); + var$5 = var$3.data; + var$5[0] = $rt_s(32); + var$5[1] = $rt_s(33); + var$5[2] = $f; + $f = new nles_VFile; + var$6 = $rt_createArray(jl_Object, 1); + var$6.data[0] = $rt_s(34); + nles_VFile__init_($f, var$6); + var$5[3] = $f; + nles_VFile__init_($vfs, var$3); + ji_PrintStream_println(jl_System_out(), $vfs); + $f = new nles_VFile; + var$3 = $rt_createArray(jl_Object, 2); + var$5 = var$3.data; + var$5[0] = $vfs; + $vfs = new nles_VFile; + var$6 = $rt_createArray(jl_Object, 1); + var$6.data[0] = $rt_s(35); + nles_VFile__init_($vfs, var$6); + var$5[1] = $vfs; + nles_VFile__init_($f, var$3); + ji_PrintStream_println(jl_System_out(), $f); + $vfs = new nles_VFile; + var$3 = $rt_createArray(jl_Object, 2); + var$5 = var$3.data; + var$5[0] = $rt_s(36); + $f = new nles_VFile; + var$6 = $rt_createArray(jl_Object, 1); + var$6.data[0] = $rt_s(35); + nles_VFile__init_($f, var$6); + var$5[1] = $f; + nles_VFile__init_($vfs, var$3); + ji_PrintStream_println(jl_System_out(), $vfs); + $vfs = new nles_VFile; + var$3 = $rt_createArray(jl_Object, 2); + var$5 = var$3.data; + var$5[0] = $rt_s(37); + $f = new nles_VFile; + var$6 = $rt_createArray(jl_Object, 1); + var$6.data[0] = $rt_s(35); + nles_VFile__init_($f, var$6); + var$5[1] = $f; + nles_VFile__init_($vfs, var$3); + ji_PrintStream_println(jl_System_out(), $vfs); + $vfs = new nles_VFile; + var$3 = $rt_createArray(jl_Object, 2); + var$5 = var$3.data; + var$5[0] = $rt_s(38); + $f = new nles_VFile; + var$6 = $rt_createArray(jl_Object, 1); + var$6.data[0] = $rt_s(35); + nles_VFile__init_($f, var$6); + var$5[1] = $f; + nles_VFile__init_($vfs, var$3); + ji_PrintStream_println(jl_System_out(), $vfs); +} +var otci_IntegerUtil = $rt_classWithoutFields(); +function otci_IntegerUtil_toUnsignedLogRadixString($value, $radixLog2) { + var $radix, $mask, $sz, $chars, $pos, $target, $target_0, var$10, var$11, var$12; + if (!$value) + return $rt_s(39); + $radix = 1 << $radixLog2; + $mask = $radix - 1 | 0; + $sz = (((32 - jl_Integer_numberOfLeadingZeros($value) | 0) + $radixLog2 | 0) - 1 | 0) / $radixLog2 | 0; + $chars = $rt_createCharArray($sz).data; + $pos = $rt_imul($sz - 1 | 0, $radixLog2); + $target = 0; + while ($pos >= 0) { + $target_0 = $target + 1 | 0; + $chars[$target] = jl_Character_forDigit($value >>> $pos & $mask, $radix); + $pos = $pos - $radixLog2 | 0; + $target = $target_0; + } + var$10 = new jl_String; + $value = $chars.length; + var$11 = $rt_createCharArray($value); + var$12 = var$11.data; + var$10.$characters = var$11; + $radixLog2 = 0; + while ($radixLog2 < $value) { + var$12[$radixLog2] = $chars[$radixLog2]; + $radixLog2 = $radixLog2 + 1 | 0; + } + return var$10; +} +function nles_VFile() { + jl_Object.call(this); + this.$path = null; +} +var nles_VFile_altPathSeperator = null; +function nles_VFile__init_0(var_0) { + var var_1 = new nles_VFile(); + nles_VFile__init_(var_1, var_0); + return var_1; +} +function nles_VFile_normalizePath($p) { + var $i, var$3, var$4, var$5, var$6, var$7, var$8; + $i = 0; + while (true) { + var$3 = nles_VFile_altPathSeperator.data; + if ($i >= var$3.length) + break; + $p = jl_String_replace($p, var$3[$i], $rt_s(40)); + $i = $i + 1 | 0; + } + if ($p === $rt_s(40) ? 1 : jl_String_startsWith($p, $rt_s(40), 0)) { + var$4 = $rt_s(40).$characters.data.length; + var$5 = $p.$characters.data; + $i = var$5.length; + if (var$4 > $i) { + $p = new jl_IndexOutOfBoundsException; + $p.$suppressionEnabled = 1; + $p.$writableStackTrace = 1; + $rt_throw($p); + } + $p = new jl_String; + $i = $i - var$4 | 0; + var$3 = $rt_createCharArray($i); + var$6 = var$3.data; + $p.$characters = var$3; + var$7 = 0; + while (var$7 < $i) { + var$6[var$7] = var$5[var$7 + var$4 | 0]; + var$7 = var$7 + 1 | 0; + } + } + if (jl_String_endsWith($p, $rt_s(40))) { + var$5 = $p.$characters.data; + var$7 = var$5.length - $rt_s(40).$characters.data.length | 0; + if (0 > var$7) { + $p = new jl_IndexOutOfBoundsException; + $p.$suppressionEnabled = 1; + $p.$writableStackTrace = 1; + $rt_throw($p); + } + $p = new jl_String; + var$7 = var$7 - 0 | 0; + var$3 = $rt_createCharArray(var$7); + var$6 = var$3.data; + $p.$characters = var$3; + var$8 = 0; + while (var$8 < var$7) { + var$6[var$8] = var$5[var$8 + 0 | 0]; + var$8 = var$8 + 1 | 0; + } + } + return $p; +} +function nles_VFile_createPath($p) { + var $r, $i, var$4, $s, $j, var$7, var$8, $gg, var$10, $k; + $r = new ju_ArrayList; + $r.$array = $rt_createArray(jl_Object, 10); + $i = 0; + a: while (true) { + var$4 = $p.data; + if ($i >= var$4.length) { + if ($r.$size <= 0) + return null; + $s = new jl_StringBuilder; + $s.$buffer = $rt_createCharArray(16); + $i = 0; + while (true) { + if ($i >= $r.$size) { + $r = new jl_String; + $p = $s.$buffer; + $j = $s.$length; + var$4 = $rt_createCharArray($j); + var$7 = var$4.data; + $r.$characters = var$4; + var$8 = 0; + while (var$8 < $j) { + var$7[var$8] = $p.data[var$8 + 0 | 0]; + var$8 = var$8 + 1 | 0; + } + return $r; + } + if ($i > 0) + jl_AbstractStringBuilder_insert($s, $s.$length, $rt_s(40)); + if ($i < 0) + break; + if ($i >= $r.$size) + break; + $gg = $r.$array.data[$i]; + jl_AbstractStringBuilder_insert($s, $s.$length, $gg); + $i = $i + 1 | 0; + } + $r = new jl_IndexOutOfBoundsException; + $r.$suppressionEnabled = 1; + $r.$writableStackTrace = 1; + $rt_throw($r); + } + b: { + if (var$4[$i] !== null) { + $gg = var$4[$i].$toString(); + if ($gg !== null) { + $gg = nles_VFile_normalizePath($gg); + var$4 = jur_Pattern_split(jur_Pattern_compile($rt_s(40), 0), $gg, 0); + $j = 0; + while (true) { + var$7 = var$4.data; + var$8 = var$7.length; + if ($j >= var$8) + break; + var$7[$j] = jl_String_trim(var$7[$j]); + $j = $j + 1 | 0; + } + $j = 0; + while (true) { + if ($j >= var$8) + break b; + c: { + if (var$7[$j] !== null && !jl_String_equals(var$7[$j], $rt_s(29))) { + if (jl_String_equals(var$7[$j], $rt_s(41))) { + var$10 = $r.$size; + if (var$10 > 0) { + $k = var$10 - 1 | 0; + if ($k < 0) + break a; + if ($k >= var$10) + break a; + if (!jl_String_equals($r.$array.data[$k], $rt_s(41))) + ju_ArrayList_remove($r, $k); + else { + ju_ArrayList_ensureCapacity($r, $r.$size + 1 | 0); + var$4 = $r.$array.data; + var$10 = $r.$size; + $r.$size = var$10 + 1 | 0; + var$4[var$10] = $rt_s(41); + $r.$modCount = $r.$modCount + 1 | 0; + } + break c; + } + } + $s = var$7[$j]; + ju_ArrayList_ensureCapacity($r, $r.$size + 1 | 0); + var$4 = $r.$array.data; + var$10 = $r.$size; + $r.$size = var$10 + 1 | 0; + var$4[var$10] = $s; + $r.$modCount = $r.$modCount + 1 | 0; + } + } + $j = $j + 1 | 0; + } + } + } + } + $i = $i + 1 | 0; + } + $r = new jl_IndexOutOfBoundsException; + $r.$suppressionEnabled = 1; + $r.$writableStackTrace = 1; + $rt_throw($r); +} +function nles_VFile__init_($this, $p) { + $this.$path = nles_VFile_createPath($p); +} +function nles_VFile_toString($this) { + return $this.$path; +} +function nles_VFile__clinit_() { + var var$1; + var$1 = $rt_createArray(jl_String, 1); + var$1.data[0] = $rt_s(1); + nles_VFile_altPathSeperator = var$1; +} +var jl_System = $rt_classWithoutFields(); +var jl_System_outCache = null; +function jl_System_out() { + var var$1, var$2; + if (jl_System_outCache === null) { + var$1 = new ji_PrintStream; + var$1.$out = otcic_StdoutOutputStream_INSTANCE; + var$2 = new jl_StringBuilder; + var$2.$buffer = $rt_createCharArray(16); + var$1.$sb = var$2; + var$1.$buffer0 = $rt_createCharArray(32); + var$1.$autoFlush = 0; + var$1.$charset = jnci_UTF8Charset_INSTANCE; + jl_System_outCache = var$1; + } + return jl_System_outCache; +} +function jl_System_arraycopy($src, $srcPos, $dest, $destPos, $length) { + var var$6, $elem, $targetType, $srcType, $srcArray, $i, var$12, var$13, var$14, var$15; + if ($src !== null && $dest !== null) { + if ($srcPos >= 0 && $destPos >= 0 && $length >= 0 && ($srcPos + $length | 0) <= jlr_Array_getLength($src) && ($destPos + $length | 0) <= jlr_Array_getLength($dest)) { + a: { + b: { + if ($src !== $dest) { + var$6 = $src.constructor; + if (var$6 === null) + $elem = null; + else { + $elem = var$6.classObject; + if ($elem === null) { + $elem = new jl_Class; + $elem.$platformClass = var$6; + $targetType = $elem; + var$6.classObject = $targetType; + } + } + $srcType = jl_Class_getComponentType($elem); + var$6 = $dest.constructor; + if (var$6 === null) + $elem = null; + else { + $elem = var$6.classObject; + if ($elem === null) { + $elem = new jl_Class; + $elem.$platformClass = var$6; + $targetType = $elem; + var$6.classObject = $targetType; + } + } + $targetType = jl_Class_getComponentType($elem); + if ($srcType !== null && $targetType !== null) { + if ($srcType === $targetType) + break b; + if (!($srcType.$platformClass.$meta.primitive ? 1 : 0) && !($targetType.$platformClass.$meta.primitive ? 1 : 0)) { + $srcArray = $src; + $i = 0; + var$12 = $srcPos; + while ($i < $length) { + var$13 = $srcArray.data; + var$14 = var$12 + 1 | 0; + var$6 = var$13[var$12]; + var$15 = $targetType.$platformClass; + if (!(var$6 !== null && !(typeof var$6.constructor.$meta === 'undefined' ? 1 : 0) && otp_Platform_isAssignable(var$6.constructor, var$15) ? 1 : 0)) { + jl_System_doArrayCopy($src, $srcPos, $dest, $destPos, $i); + $src = new jl_ArrayStoreException; + $src.$suppressionEnabled = 1; + $src.$writableStackTrace = 1; + $rt_throw($src); + } + $i = $i + 1 | 0; + var$12 = var$14; + } + jl_System_doArrayCopy($src, $srcPos, $dest, $destPos, $length); + return; + } + if (!($srcType.$platformClass.$meta.primitive ? 1 : 0)) + break a; + if ($targetType.$platformClass.$meta.primitive ? 1 : 0) + break b; + else + break a; + } + $src = new jl_ArrayStoreException; + $src.$suppressionEnabled = 1; + $src.$writableStackTrace = 1; + $rt_throw($src); + } + } + jl_System_doArrayCopy($src, $srcPos, $dest, $destPos, $length); + return; + } + $src = new jl_ArrayStoreException; + $src.$suppressionEnabled = 1; + $src.$writableStackTrace = 1; + $rt_throw($src); + } + $src = new jl_IndexOutOfBoundsException; + $src.$suppressionEnabled = 1; + $src.$writableStackTrace = 1; + $rt_throw($src); + } + $dest = new jl_NullPointerException; + $dest.$suppressionEnabled = 1; + $dest.$writableStackTrace = 1; + $dest.$message = $rt_s(42); + $rt_throw($dest); +} +function jl_System_doArrayCopy(var$1, var$2, var$3, var$4, var$5) { + if (var$1 !== var$3 || var$4 < var$2) { + for (var i = 0; i < var$5; i = (i + 1) | 0) { + var$3.data[var$4++] = var$1.data[var$2++]; + } + } else { + var$2 = (var$2 + var$5) | 0; + var$4 = (var$4 + var$5) | 0; + for (var i = 0; i < var$5; i = (i + 1) | 0) { + var$3.data[--var$4] = var$1.data[--var$2]; + } + } +} +var ju_Comparator = $rt_classWithoutFields(0); +var jl_String$_clinit_$lambda$_84_0 = $rt_classWithoutFields(); +var jl_Character = $rt_classWithoutFields(); +var jl_Character_TYPE = null; +var jl_Character_digitMapping = null; +var jl_Character_classMapping = null; +var jl_Character_characterCache = null; +var jl_Character_$$metadata$$1 = null; +var jl_Character_$$metadata$$2 = null; +function jl_Character_toString($c) { + var var$2, var$3, var$4, var$5, var$6; + var$2 = new jl_String; + var$3 = $rt_createCharArray(1).data; + var$3[0] = $c; + $c = var$3.length; + var$4 = $rt_createCharArray($c); + var$5 = var$4.data; + var$2.$characters = var$4; + var$6 = 0; + while (var$6 < $c) { + var$5[var$6] = var$3[var$6]; + var$6 = var$6 + 1 | 0; + } + return var$2; +} +function jl_Character_toCodePoint($high, $low) { + return (($high & 1023) << 10 | $low & 1023) + 65536 | 0; +} +function jl_Character_codePointAt($a, $index, $limit) { + var var$4; + if ($index < ($limit - 1 | 0)) { + var$4 = $a.data; + if ((var$4[$index] & 64512) != 55296 ? 0 : 1) { + $limit = $index + 1 | 0; + if ((var$4[$limit] & 64512) != 56320 ? 0 : 1) + return ((var$4[$index] & 1023) << 10 | var$4[$limit] & 1023) + 65536 | 0; + } + } + return $a.data[$index]; +} +function jl_Character_toLowerCase($ch) { + return (String.fromCharCode($ch)).toLowerCase().charCodeAt(0) & 65535; +} +function jl_Character_toUpperCase($ch) { + return (String.fromCharCode($ch)).toUpperCase().charCodeAt(0) & 65535; +} +function jl_Character_getNumericValue($codePoint) { + var $digitMapping, $l, $u, $idx, var$6, $val; + if (jl_Character_digitMapping === null) { + if (jl_Character_$$metadata$$1 === null) + jl_Character_$$metadata$$1 = jl_Character_obtainDigitMapping$$create(); + jl_Character_digitMapping = otciu_UnicodeHelper_decodeIntPairsDiff((jl_Character_$$metadata$$1.value !== null ? $rt_str(jl_Character_$$metadata$$1.value) : null)); + } + $digitMapping = jl_Character_digitMapping.data; + $l = 0; + $u = ($digitMapping.length / 2 | 0) - 1 | 0; + while ($u >= $l) { + $idx = ($l + $u | 0) / 2 | 0; + var$6 = $idx * 2 | 0; + $val = $rt_compare($codePoint, $digitMapping[var$6]); + if ($val > 0) + $l = $idx + 1 | 0; + else { + if ($val >= 0) + return $digitMapping[var$6 + 1 | 0]; + $u = $idx - 1 | 0; + } + } + return (-1); +} +function jl_Character_forDigit($digit, $radix) { + if ($radix >= 2 && $radix <= 36 && $digit < $radix) + return $digit < 10 ? (48 + $digit | 0) & 65535 : ((97 + $digit | 0) - 10 | 0) & 65535; + return 0; +} +function jl_Character_getType($codePoint) { + var $l, $u, $classes, $i, $range; + if ($codePoint > 0 && $codePoint <= 65535 ? 1 : 0) { + $l = $codePoint & 65535 & 64512; + $u = $l != 55296 ? 0 : 1; + if (!$u && !($l != 56320 ? 0 : 1) ? 0 : 1) + return 19; + } + if (jl_Character_classMapping === null) { + if (jl_Character_$$metadata$$2 === null) + jl_Character_$$metadata$$2 = jl_Character_obtainClasses$$create(); + jl_Character_classMapping = otciu_UnicodeHelper_extractRle((jl_Character_$$metadata$$2.value !== null ? $rt_str(jl_Character_$$metadata$$2.value) : null)); + } + $classes = jl_Character_classMapping.data; + $l = 0; + $u = $classes.length - 1 | 0; + while ($l <= $u) { + $i = ($l + $u | 0) / 2 | 0; + $range = $classes[$i]; + if ($codePoint >= $range.$end) + $l = $i + 1 | 0; + else { + $u = $range.$start; + if ($codePoint >= $u) + return $range.$data.data[$codePoint - $u | 0]; + $u = $i - 1 | 0; + } + } + return 0; +} +function jl_Character_isIdentifierIgnorable($codePoint) { + a: { + if (!($codePoint >= 0 && $codePoint <= 8) && !($codePoint >= 14 && $codePoint <= 27)) { + if ($codePoint < 127) + break a; + if ($codePoint > 159) + break a; + } + return 1; + } + return jl_Character_getType($codePoint) != 16 ? 0 : 1; +} +function jl_Character__clinit_() { + jl_Character_TYPE = $rt_cls($rt_charcls()); + jl_Character_characterCache = $rt_createArray(jl_Character, 128); +} +function jl_Character_obtainDigitMapping$$create() { + return {"value" : "{?*% %%%%%%%%%%%%%%%%%%A%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%=,#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%_H#T#%%%%%%%%%%%%%%%%%%s+G%%%%%%%%%%%%%%%%%%_1G%%%%%%%%%%%%%%%%%%{CG%%%%%%%%%%%%%%%%%%2+G%%%%%%%%%%%%%%%%%%2+G%%%%%%%%%%%%%%%%%%2+G%%%%%%%%%%%%%%%%%%2+G%%%%%%%%%%%%%%%%%%2+G%%%%%%%%%%%%%%%%%%2+G%%%%%%%%%%%%%%%%%%2+G%%%%%%%%%%%%%%%%%%2+G%%%%%%%%%%%%%%%%%%2+G%%%%%%%%%%%%%%%%%%6)G%%%%%%%%%%%%%%%%%%2+G%%%%%%%%%%%%%%%%%%*\'G%%%%%%%%%%%%%%%%%%.9G%%%%%%%%%%%%%%%%%%*\'G%%%%%%%%%%%%%%%%%%!i#G" + + "%%%%%%%%%%%%%%%%%%c#G%%%%%%%%%%%%%%%%%%*;G%%%%%%%%%%%%%%%%%%Z+G%%%%%%%%%%%%%%%%%%:/G%%%%%%%%%%%%%%%%%%=G%%%%%%%%%%%%%%%%%%{/G%%%%%%%%%%%%%%%%%%k\'G%%%%%%%%%%%%%%%%%%s+G%%%%%%%%%%%%%%%%%%=G%%%%%%%%%%%%%%%%%%R@dG%%%%%%%%%%%%%%%%%%R[G%%%%%%%%%%%%%%%%%%c#G%%%%%%%%%%%%%%%%%%_1G%%%%%%%%%%%%%%%%%%!#G%%%%%%%%%%%%%%%%%%k\'G%%%%%%%%%%%%%%%%%%cCG%%%%%%%%%%%%%%%%%%o*IG%%%%%%%%%%%%%%%%%%A%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%=,#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%c:#T#%%%%%%%%%%%%%%%%%%w&%G%%%%%" + + "%%%%%%%%%%%%%BhG%%%%%%%%%%%%%%%%%%Z+G%%%%%%%%%%%%%%%%%%_%G%%%%%%%%%%%%%%%%%%>-G%%%%%%%%%%%%%%%%%%.9G%%%%%%%%%%%%%%%%%%w=G%%%%%%%%%%%%%%%%%%2+G%%%%%%%%%%%%%%%%%%>AG%%%%%%%%%%%%%%%%%%N)G%%%%%%%%%%%%%%%%%%N)G%%%%%%%%%%%%%%%%%%FEG%%%%%%%%%%%%%%%%%%slG%%%%%%%%%%%%%%%%%%g5G%%%%%%%%%%%%%%%%%%*\'G%%%%%%%%%%%%%%%%%%sTEG%%%%%%%%%%%%%%%%%%&5G%%%%%%%%%%%%%%%%%%28UG%%%%%%%%%%%%%%%%%%%G%%%%%%%%%%%%%%%%%%%G%%%%%%%%%%%%%%%%%%%G%%%%%%%%%%%%%%%%%%%G%%%%%%%%%%%%%%%%%%!8%G%%%%%%%%%%%%%%%%%%FEG%%%%%%%%%%%%%%%%%%VR#G%%%%%%%%%%%%%" + + "%%%%%"}; +} +function jl_Character_obtainClasses$$create() { + return {"value" : "PA-Y$;Y$679:95Y#J+Y#Z$Y#B;697<8:1=<=:L#<#Y#<,&?L$9B8:B(C9:C)!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!C#!#!#!#!#!#!#!#!C#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#B##!#!C$B##!#B##B$C#B%#B##B$C$B##B##!#!#B##!C#!#B##B$#!#B#C#&!C$F%!$#!$#!$#!#!#!#!#!#!#!#!C#!#!#!#!#!#!#!#!#!C#!$#!#B$#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!C(B##B#C#!#B%#!#!#!#!Cg&C?6_#?6>Y)./Q&-Y*>?Y%X#Y$:67Y,:98Y+-Q& Q+,%A#L\'Z$67%L+Z$67 E.A$[AA1G.H%\'H$G-A0^#" + + "!^%!^##B$C#B$#=!^#:B&^\'!=!=!=B%=#B%#F%#^#C#B#Z&!C%=:^##=L1KD!#K%,^#A%Z&^&Z#^%:^#:^#:^(:^@Z#^#:=:^@b:-% ^)6767^5Z#^(67b=2! :^?Z:^IZ\'^gA:^,A6L^^pL7b=X# :^*:^WZ)b=P! :b=Y$ 67676767676767L?^MZ&67Z@6767676767Z1b= % b:$# 6767676767676767676767Za6767ZA67b:#% ^QZ6^#Z\'^HA#^AA#b=I! BP CP !#B$C#!#!#!#B%#!C#!C\'E#B$#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!C#^\'!#!#G$!#A&Y%,Y#CG #A&#A#FYA(%9A/\'F8A*F( F( F( F( F( F( F( F( GAY#>?>?Y$>?9>?Y*5Y#59>?Y#>?67676767Y&%Y+U#Y%" + + "596Y.AQ^; b=:! A-b=7$ A;^-A%-Y$=%&+6767676767^#6767676756W#=K*G%I#5E&^#K$%&9^# b&7! A#G#]#E#&5b&;! 9E$&A&FL b&?! ^#L%^+FA$G$)FP\'I#G%I#G#I$Y. %J+A%Y#F&\'%F*J+F& FJG\'I#G#I#G#A*F$\'F)\')A#J+A#Y%F1%F\'^$&)\')FS\'&G$F#G#F&G#&\'&A9F#%Y#F,)G#I#Y#&E#)\'A+F\'A#F\'A#F\'A*F( F( CLA$FRA0\'LA#G$A%\'L*A(Y*A(F>L#9F>L$AAF)=F=G#A%L&Y(A*FWA$Y(F7A#L)F4A&L)F3A(Y%A-L(b 1! FkAXBTA.CTA(L\'FEG%A)J+b G% L@b !# F>L+&A)F7G,L%Y&b \'# F8A*)\')FVG0Y(A%L5J+A0G$)FNI$G%I#G#Y#1Y%A,1A#F:A(J+A\'G$FEG&)G) J+Y%&I#A*FD\'Y#&A*G#)FQI$G*I#F%Y%G%9A#J+&9&Y$ L5A,F3 F:I$G$I#\')G#Y\'\'AcF( & F% F0 F+" + + "9A\'FP\'I$G)A&J+A\'G#I# F)A#F#A#F7 F( F# F& G#&I#\'I%A#I#A#I$A#&A\')A&F&I#A#G(A$G&b ,# FVI$G)I#G$)\'F%Y&J+ 9 9\'&AAFQI$G\')\'I%G#)G#F#9&A)J+b G# FPI$G%A#I%G#)G#Y8F%G#ACFQI$G)I#\')G#Y$&A,J+A\'Y.A4FL\')\'I#G\')\'&A(J+AWFFZb (% F* FF)G( G\')\'&Y&A+J+L4A$Y#F?A#G7 )G()G#)G#AkF( F# FGG\'A$\' G# G(&\'A)J+A\'F\' F# FAI& G# I#\')\'&A(J+b W% F4G#I#Y#b ($ L6^)[%^2A.9b&;/ b G! b+P! Y&A,b&%$ b ^K b&P1 Q*b (a b&(* b Z\'#b&Z) A(F" + + "@ J+A%Y#b A! F?A#G&9A+FQG(Y&^%E%9=A+J+ L( F6A&F4b Q+ BACAL8Y%b F! FmA%\'&IXA(G%E.AbE#9%A=&b W@!&A)b&T, b .5#b&@% ARF$A2F%A)b&-\' b %E b&L! A&F.A$F*A(F+A#=G#9Q%b =.!b=W$ A+^HA#^^I#G$^$I\'Q)G)^#G(^?G%^]A8^dG$=b ;# L5A-b=8! A*L:b (# B;C;B;C( C3B;C;! B#A#!A#B#A#B% B)C% # C( C,B;C;B# B%A#B) B( C;B# B% B& !A$B( C;B;C;B;C;B;C;B;C;B;C;B;C=A#B::C::C\'B::C::C\'B::C::C\'B::C::C\'B::C::C\'!#A#JSb= ) GX^%GS^)\'^/\'^#Y&A0G& G0b 16 G( G2A#G( G# G&b 6$ FNA$G(E(A#J+A%&=b Q& FMG%J+A&;b 5 b&&$ A#L*G(AJBCCCG(%A%J+A%Y#b 2- L]=L$;L%AnLN=" + + "L0b #$ F% F< F# &A#& F+ F% & &A\'&A%& & & F$ F# &A#& & & & & F# &A#F% F( F% F% & F+ F2A&F$ F& F2AUZ#b /% ^MA%b=E! A-^0A#^0 ^0 ^FA+L.A$b=>! A$^_AZ^>A.^MA%^*A(^#A/^\'b ;# b=]$ ]&b=7, A+^.A$^,A&b=U! A-b=:! A(^-A5^-A%^YA)^+A\'^IA)^?b 3! ^- b=F! ^%A$^JA#^\'A$^>A#b=(# A-^/A#^%A%^$A&^$A.^\'b K6 &b %b %b 6<#&AJ&b T !&A,&b =$ &A#&b ;!&A/&b PU!&b @Q b&?) b %b %b %b %b %b %b %b %b %b %b %b %b %b %b %b %b %b %b %b %b %b %b %b %b %b %b %b %b %b %b %b %b " + + "%b %b %b %b %b %b %b %b %b %b %b %b D8 1A?b1A! b # b\'Q$ b %b %b %b 1Y$3b %b %b %b ^a$3A#3b %b %b %b ^a$3"}; +} +function nles_BooleanResult() { + jl_Object.call(this); + this.$bool = 0; +} +var nles_BooleanResult_TRUE = null; +var nles_BooleanResult_FALSE = null; +function nles_BooleanResult__clinit_() { + var var$1; + var$1 = new nles_BooleanResult; + var$1.$bool = 1; + nles_BooleanResult_TRUE = var$1; + var$1 = new nles_BooleanResult; + var$1.$bool = 0; + nles_BooleanResult_FALSE = var$1; +} +function nles_VirtualFilesystem() { + var a = this; jl_Object.call(a); + a.$fileMap = null; + a.$database = null; + a.$indexeddb = null; +} +function nles_VirtualFilesystem_openVFS($db) { + var $evt, var$3, var$4, var$5, var$6, var$7, var$8, var$9, $ptr, $tmp; + $ptr = 0; + if ($rt_resuming()) { + var $thread = $rt_nativeThread(); + $ptr = $thread.pop();var$9 = $thread.pop();var$8 = $thread.pop();var$7 = $thread.pop();var$6 = $thread.pop();var$5 = $thread.pop();var$4 = $thread.pop();var$3 = $thread.pop();$evt = $thread.pop();$db = $thread.pop(); + } + main: while (true) { switch ($ptr) { + case 0: + $ptr = 1; + case 1: + $tmp = nles_VirtualFilesystem$AsyncHandlers_openDB($db); + if ($rt_suspending()) { + break main; + } + $evt = $tmp; + if ($evt.$failedInit) { + $db = new nles_VirtualFilesystem$VFSHandle; + var$3 = $evt.$failedError; + var$4 = null; + $db.$failedInit0 = 1; + $db.$failedLocked = 0; + $db.$failedError0 = var$3; + $db.$vfs = var$4; + return $db; + } + if ($evt.$failedLocked0) { + $db = new nles_VirtualFilesystem$VFSHandle; + var$3 = null; + var$4 = null; + $db.$failedInit0 = 0; + $db.$failedLocked = 1; + $db.$failedError0 = var$3; + $db.$vfs = var$4; + return $db; + } + var$3 = $evt.$failedError; + if (var$3 !== null) { + $db = new nles_VirtualFilesystem$VFSHandle; + var$4 = null; + $db.$failedInit0 = 0; + $db.$failedLocked = 0; + $db.$failedError0 = var$3; + $db.$vfs = var$4; + return $db; + } + var$5 = new nles_VirtualFilesystem$VFSHandle; + var$3 = null; + var$4 = new nles_VirtualFilesystem; + $evt = $evt.$database0; + var$6 = new ju_HashMap; + var$7 = ju_HashMap_calculateCapacity(16); + var$6.$elementCount = 0; + var$8 = $rt_createArray(ju_HashMap$HashEntry, var$7); + var$9 = var$8.data; + var$6.$elementData = var$8; + var$6.$loadFactor = 0.75; + var$6.$threshold = var$9.length * 0.75 | 0; + var$4.$fileMap = var$6; + var$4.$database = $db; + var$4.$indexeddb = $evt; + var$5.$failedInit0 = 0; + var$5.$failedLocked = 0; + var$5.$failedError0 = var$3; + var$5.$vfs = var$4; + return var$5; + default: $rt_invalidPointer(); + }} + $rt_nativeThread().push($db, $evt, var$3, var$4, var$5, var$6, var$7, var$8, var$9, $ptr); +} +function nles_VirtualFilesystem$VFSHandle() { + var a = this; jl_Object.call(a); + a.$failedInit0 = 0; + a.$failedLocked = 0; + a.$failedError0 = null; + a.$vfs = null; +} +function nles_VirtualFilesystem$VFSHandle_toString($this) { + var var$1, var$2, var$3, var$4, var$5, var$6, var$7, var$8; + if (!$this.$failedInit0) { + if ($this.$failedLocked) + return $rt_s(43); + if ($this.$failedError0 !== null) { + var$1 = new jl_StringBuilder; + var$1.$buffer = $rt_createCharArray(16); + jl_AbstractStringBuilder_insert(var$1, var$1.$length, $rt_s(44)); + var$2 = $this.$failedError0; + jl_AbstractStringBuilder_insert(var$1, var$1.$length, var$2); + var$2 = new jl_String; + var$3 = var$1.$buffer; + var$4 = var$1.$length; + var$5 = $rt_createCharArray(var$4); + var$6 = var$5.data; + var$2.$characters = var$5; + var$7 = 0; + while (var$7 < var$4) { + var$6[var$7] = var$3.data[var$7 + 0 | 0]; + var$7 = var$7 + 1 | 0; + } + return var$2; + } + var$1 = new jl_StringBuilder; + var$1.$buffer = $rt_createCharArray(16); + jl_AbstractStringBuilder_insert(var$1, var$1.$length, $rt_s(45)); + var$2 = $this.$vfs.$database; + jl_AbstractStringBuilder_insert(var$1, var$1.$length, var$2); + var$2 = new jl_String; + var$3 = var$1.$buffer; + var$4 = var$1.$length; + var$5 = $rt_createCharArray(var$4); + var$6 = var$5.data; + var$2.$characters = var$5; + var$7 = 0; + while (var$7 < var$4) { + var$6[var$7] = var$3.data[var$7 + 0 | 0]; + var$7 = var$7 + 1 | 0; + } + return var$2; + } + var$1 = new jl_StringBuilder; + var$1.$buffer = $rt_createCharArray(16); + jl_AbstractStringBuilder_insert(var$1, var$1.$length, $rt_s(46)); + if ($this.$failedError0 === null) + var$8 = $rt_s(47); + else { + var$2 = new jl_StringBuilder; + var$2.$buffer = $rt_createCharArray(16); + jl_AbstractStringBuilder_insert(var$2, var$2.$length, $rt_s(48)); + var$8 = $this.$failedError0; + jl_AbstractStringBuilder_insert(var$2, var$2.$length, var$8); + var$8 = new jl_String; + var$3 = var$2.$buffer; + var$4 = var$2.$length; + var$5 = $rt_createCharArray(var$4); + var$6 = var$5.data; + var$8.$characters = var$5; + var$7 = 0; + while (var$7 < var$4) { + var$6[var$7] = var$3.data[var$7 + 0 | 0]; + var$7 = var$7 + 1 | 0; + } + } + jl_AbstractStringBuilder_insert(var$1, var$1.$length, var$8); + var$2 = new jl_String; + var$3 = var$1.$buffer; + var$7 = var$1.$length; + var$5 = $rt_createCharArray(var$7); + var$6 = var$5.data; + var$2.$characters = var$5; + var$4 = 0; + while (var$4 < var$7) { + var$6[var$4] = var$3.data[var$4 + 0 | 0]; + var$4 = var$4 + 1 | 0; + } + return var$2; +} +var otj_JSObject = $rt_classWithoutFields(0); +var otjde_EventTarget = $rt_classWithoutFields(0); +var otjde_FocusEventTarget = $rt_classWithoutFields(0); +var otjde_MouseEventTarget = $rt_classWithoutFields(0); +var otjde_KeyboardEventTarget = $rt_classWithoutFields(0); +var otjde_LoadEventTarget = $rt_classWithoutFields(0); +var otjde_GamepadEventTarget = $rt_classWithoutFields(0); +var otjb_WindowEventTarget = $rt_classWithoutFields(0); +var otjb_StorageProvider = $rt_classWithoutFields(0); +var otjc_JSArrayReader = $rt_classWithoutFields(0); +var otjb_Window = $rt_classWithoutFields(); +function otjb_Window_addEventListener$exported$0(var$0, var$1, var$2) { + var$0.$addEventListener($rt_str(var$1), otji_JS_functionAsObject(var$2, "handleEvent")); +} +function otjb_Window_removeEventListener$exported$1(var$0, var$1, var$2) { + var$0.$removeEventListener($rt_str(var$1), otji_JS_functionAsObject(var$2, "handleEvent")); +} +function otjb_Window_get$exported$2(var$0, var$1) { + return var$0.$get(var$1); +} +function otjb_Window_removeEventListener$exported$3(var$0, var$1, var$2, var$3) { + var$0.$removeEventListener0($rt_str(var$1), otji_JS_functionAsObject(var$2, "handleEvent"), var$3 ? 1 : 0); +} +function otjb_Window_dispatchEvent$exported$4(var$0, var$1) { + return !!var$0.$dispatchEvent(var$1); +} +function otjb_Window_getLength$exported$5(var$0) { + return var$0.$getLength0(); +} +function otjb_Window_addEventListener$exported$6(var$0, var$1, var$2, var$3) { + var$0.$addEventListener0($rt_str(var$1), otji_JS_functionAsObject(var$2, "handleEvent"), var$3 ? 1 : 0); +} +var jl_AutoCloseable = $rt_classWithoutFields(0); +var ji_Closeable = $rt_classWithoutFields(0); +var ji_Flushable = $rt_classWithoutFields(0); +var ji_OutputStream = $rt_classWithoutFields(); +function ji_OutputStream_write($this, $b, $off, $len) { + var $i, var$5, var$6; + $i = 0; + while ($i < $len) { + var$5 = $b.data; + var$6 = $off + 1 | 0; + $rt_putStdout(var$5[$off]); + $i = $i + 1 | 0; + $off = var$6; + } +} +function ji_FilterOutputStream() { + ji_OutputStream.call(this); + this.$out = null; +} +function ji_PrintStream() { + var a = this; ji_FilterOutputStream.call(a); + a.$autoFlush = 0; + a.$errorState = 0; + a.$sb = null; + a.$buffer0 = null; + a.$charset = null; +} +function ji_PrintStream_print($this, $s, $begin, $end) { + var $destBytes, $src, $overflow, var$7, var$8, var$9, var$10, var$11, var$12, var$13, $$je; + $destBytes = $s.data; + $end = $end - $begin | 0; + $src = new jn_CharBufferOverArray; + $overflow = $destBytes.length; + $end = $begin + $end | 0; + $src.$mark = (-1); + $src.$capacity = $overflow; + $src.$limit = $overflow; + $src.$position = $begin; + $src.$limit = $end; + $src.$start0 = 0; + $src.$readOnly = 0; + $src.$array0 = $s; + $end = 1024; + if ($overflow < $end) + $end = $overflow; + if (16 > $end) + $end = 16; + $destBytes = $rt_createByteArray($end); + $end = $destBytes.data.length; + var$7 = new jn_ByteBufferImpl; + var$8 = 0 + $end | 0; + var$7.$mark = (-1); + var$7.$capacity = $end; + var$7.$limit = $end; + var$7.$order = jn_ByteOrder_BIG_ENDIAN; + var$7.$start1 = 0; + var$7.$array1 = $destBytes; + var$7.$position = 0; + var$7.$limit = var$8; + var$7.$direct = 0; + var$7.$readOnly0 = 0; + var$9 = $this.$charset; + var$10 = new jnci_UTF8Encoder; + $s = $rt_createByteArray(1); + var$11 = $s.data; + var$11[0] = 63; + var$12 = jnc_CodingErrorAction_REPORT; + var$10.$malformedAction = var$12; + var$10.$unmappableAction = var$12; + $begin = var$11.length; + if ($begin && $begin >= var$10.$maxBytesPerChar) { + var$10.$charset0 = var$9; + var$10.$replacement = $s.$clone(); + var$10.$averageBytesPerChar = 2.0; + var$10.$maxBytesPerChar = 4.0; + var$10.$inArray = $rt_createCharArray(512); + var$10.$outArray = $rt_createByteArray(512); + var$9 = jnc_CodingErrorAction_REPLACE; + if (var$9 === null) { + var$7 = new jl_IllegalArgumentException; + var$7.$suppressionEnabled = 1; + var$7.$writableStackTrace = 1; + var$7.$message = $rt_s(49); + $rt_throw(var$7); + } + var$10.$malformedAction = var$9; + var$10.$unmappableAction = var$9; + while (true) { + $overflow = (jnc_CharsetEncoder_encode(var$10, $src, var$7, 1)).$kind != 1 ? 0 : 1; + var$13 = var$7.$position; + var$9 = $this.$out; + if (var$9 === null) + $this.$errorState = 1; + if ($this.$errorState ? 0 : 1) + a: { + try { + ji_OutputStream_write(var$9, $destBytes, 0, var$13); + break a; + } catch ($$e) { + $$je = $rt_wrapException($$e); + if ($$je instanceof ji_IOException) { + } else { + throw $$e; + } + } + $this.$errorState = 1; + } + var$7.$position = 0; + var$7.$limit = var$7.$capacity; + var$7.$mark = (-1); + if (!$overflow) + break; + } + while (true) { + $end = var$10.$status; + if ($end != 2 && $end != 4) { + var$9 = new jl_IllegalStateException; + var$9.$suppressionEnabled = 1; + var$9.$writableStackTrace = 1; + $rt_throw(var$9); + } + var$9 = jnc_CoderResult_UNDERFLOW; + if (var$9 === var$9) + var$10.$status = 3; + $overflow = var$9.$kind != 1 ? 0 : 1; + var$13 = var$7.$position; + var$9 = $this.$out; + if (var$9 === null) + $this.$errorState = 1; + if ($this.$errorState ? 0 : 1) + b: { + try { + ji_OutputStream_write(var$9, $destBytes, 0, var$13); + break b; + } catch ($$e) { + $$je = $rt_wrapException($$e); + if ($$je instanceof ji_IOException) { + } else { + throw $$e; + } + } + $this.$errorState = 1; + } + var$7.$position = 0; + var$7.$limit = var$7.$capacity; + var$7.$mark = (-1); + if (!$overflow) + break; + } + return; + } + var$7 = new jl_IllegalArgumentException; + var$7.$suppressionEnabled = 1; + var$7.$writableStackTrace = 1; + var$7.$message = $rt_s(50); + $rt_throw(var$7); +} +function ji_PrintStream_println($this, $s) { + var var$2, var$3; + var$2 = $this.$sb; + jl_AbstractStringBuilder_insert(var$2, var$2.$length, $s === null ? $rt_s(8) : $s.$path); + var$3 = var$2.$length; + jl_AbstractStringBuilder_insertSpace(var$2, var$3, var$3 + 1 | 0); + var$2.$buffer.data[var$3] = 10; + ji_PrintStream_printSB($this); +} +function ji_PrintStream_printSB($this) { + var var$1, var$2, $buffer, var$4, var$5, var$6, var$7, var$8, var$9; + var$1 = $this.$sb; + var$2 = var$1.$length; + $buffer = $this.$buffer0; + if (var$2 > $buffer.data.length) + $buffer = $rt_createCharArray(var$2); + var$4 = 0; + var$5 = 0; + if (var$4 > var$2) { + var$1 = new jl_IndexOutOfBoundsException; + var$1.$suppressionEnabled = 1; + var$1.$writableStackTrace = 1; + var$1.$message = $rt_s(51); + $rt_throw(var$1); + } + while (var$4 < var$2) { + var$6 = $buffer.data; + var$7 = var$5 + 1 | 0; + var$8 = var$1.$buffer.data; + var$9 = var$4 + 1 | 0; + var$6[var$5] = var$8[var$4]; + var$5 = var$7; + var$4 = var$9; + } + ji_PrintStream_print($this, $buffer, 0, var$2); + $this.$sb.$length = 0; +} +var otcic_StdoutOutputStream = $rt_classWithoutFields(ji_OutputStream); +var otcic_StdoutOutputStream_INSTANCE = null; +function otcic_StdoutOutputStream__clinit_() { + otcic_StdoutOutputStream_INSTANCE = new otcic_StdoutOutputStream; +} +var oti_AsyncCallback = $rt_classWithoutFields(0); +function otpp_AsyncCallbackWrapper() { + jl_Object.call(this); + this.$realAsyncCallback = null; +} +function otpp_AsyncCallbackWrapper_create($realAsyncCallback) { + var var$2; + var$2 = new otpp_AsyncCallbackWrapper; + var$2.$realAsyncCallback = $realAsyncCallback; + return var$2; +} +function otpp_AsyncCallbackWrapper_complete($this, $result) { + $this.$realAsyncCallback.$complete($result); +} +function otpp_AsyncCallbackWrapper_error($this, $e) { + $this.$realAsyncCallback.$error($e); +} +var nles_SYS$PromiseHandler = $rt_classWithoutFields(0); +function nles_SYS$requestPersist$lambda$_2_0() { + jl_Object.call(this); + this.$_0 = null; +} +function nles_SYS$requestPersist$lambda$_2_0_complete$exported$0(var$0, var$1) { + var var$2, var$3, $ptr, $tmp; + $ptr = 0; + if ($rt_resuming()) { + var $thread = $rt_nativeThread(); + $ptr = $thread.pop();var$3 = $thread.pop();var$2 = $thread.pop();var$1 = $thread.pop();var$0 = $thread.pop(); + } + main: while (true) { switch ($ptr) { + case 0: + var$2 = var$0.$_0; + $ptr = 1; + case 1: + nles_SYS_$callClinit(); + if ($rt_suspending()) { + break main; + } + var$3 = !(var$1 === null ? 0 : 1) ? nles_BooleanResult_FALSE : nles_BooleanResult_TRUE; + var$2.$realAsyncCallback.$complete(var$3); + return; + default: $rt_invalidPointer(); + }} + $rt_nativeThread().push(var$0, var$1, var$2, var$3, $ptr); +} +var nles_VirtualFilesystem$AsyncHandlers = $rt_classWithoutFields(); +function nles_VirtualFilesystem$AsyncHandlers_openDB(var$1) { + var thread = $rt_nativeThread(); + var javaThread = $rt_getThread(); + if (thread.isResuming()) { + thread.status = 0; + var result = thread.attribute; + if (result instanceof Error) { + throw result; + } + return result; + } + var callback = function() {}; + callback.$complete = function(val) { + thread.attribute = val; + $rt_setThread(javaThread); + thread.resume(); + }; + callback.$error = function(e) { + thread.attribute = $rt_exception(e); + $rt_setThread(javaThread); + thread.resume(); + }; + callback = otpp_AsyncCallbackWrapper_create(callback); + return thread.suspend(function() { + try { + nles_VirtualFilesystem$AsyncHandlers_openDB0(var$1, callback); + } catch($e) { + callback.$error($rt_exception($e)); + } + }); +} +function nles_VirtualFilesystem$AsyncHandlers_openDB0($name, $cb) { + var $i, $t, var$5, var$6, var$7, var$8, $f, var$10, var$11, var$12, var$13, var$14, var$15, $$je; + $i = null; + a: { + try { + $t = otji_IDBFactory_getInstance(); + $i = $t; + break a; + } catch ($$e) { + $$je = $rt_wrapException($$e); + if ($$je instanceof jl_Throwable) { + $t = $$je; + } else { + throw $$e; + } + } + var$5 = new nles_VirtualFilesystem$DatabaseOpen; + var$6 = $t.$message; + var$7 = new jl_StringBuilder; + var$7.$buffer = $rt_createCharArray(16); + $t = $t.constructor; + if ($t === null) + var$8 = null; + else { + var$8 = $t.classObject; + if (var$8 === null) { + var$8 = new jl_Class; + var$8.$platformClass = $t; + $f = var$8; + $t.classObject = $f; + } + } + if (var$8.$name === null) + var$8.$name = $rt_str(var$8.$platformClass.$meta.name); + $t = var$8.$name; + jl_AbstractStringBuilder_insert(var$7, var$7.$length, $t); + if (var$6 === null) + $t = $rt_s(47); + else { + $f = new jl_StringBuilder; + $f.$buffer = $rt_createCharArray(16); + jl_AbstractStringBuilder_insert($f, $f.$length, $rt_s(11)); + jl_AbstractStringBuilder_insert($f, $f.$length, var$6); + $t = new jl_String; + var$10 = $f.$buffer; + var$11 = $f.$length; + var$12 = $rt_createCharArray(var$11); + var$13 = var$12.data; + $t.$characters = var$12; + var$14 = 0; + while (var$14 < var$11) { + var$13[var$14] = var$10.data[var$14 + 0 | 0]; + var$14 = var$14 + 1 | 0; + } + } + jl_AbstractStringBuilder_insert(var$7, var$7.$length, $t); + $t = new jl_String; + var$13 = var$7.$buffer; + var$14 = var$7.$length; + var$10 = $rt_createCharArray(var$14); + var$12 = var$10.data; + $t.$characters = var$10; + var$15 = 0; + while (var$15 < var$14) { + var$12[var$15] = var$13.data[var$15 + 0 | 0]; + var$15 = var$15 + 1 | 0; + } + $f = null; + var$5.$failedInit = 1; + var$5.$failedLocked0 = 0; + var$5.$failedError = $t; + var$5.$database0 = $f; + $cb.$realAsyncCallback.$complete(var$5); + $t = $i; + } + $f = $t.open($rt_ustr($name), 1); + $name = new nles_VirtualFilesystem$AsyncHandlers$1; + $name.$val$cb = $cb; + $name = otji_JS_function($name, "handleEvent"); + $f.onBlocked = $name; + $name = new nles_VirtualFilesystem$AsyncHandlers$2; + $name.$val$cb0 = $cb; + $name.$val$f = $f; + $name = otji_JS_function($name, "handleEvent"); + $f.onsuccess = $name; + $name = new nles_VirtualFilesystem$AsyncHandlers$3; + $name.$val$cb1 = $cb; + $name = otji_JS_function($name, "handleEvent"); + $f.onerror = $name; + $name = new nles_VirtualFilesystem$AsyncHandlers$4; + $name.$val$f0 = $f; + $name = otji_JS_function($name, "handleEvent"); + $f.onupgradeneeded = $name; +} +function nles_VirtualFilesystem$DatabaseOpen() { + var a = this; jl_Object.call(a); + a.$failedInit = 0; + a.$failedLocked0 = 0; + a.$failedError = null; + a.$database0 = null; +} +var jl_Iterable = $rt_classWithoutFields(0); +var ju_Collection = $rt_classWithoutFields(0); +var ju_AbstractCollection = $rt_classWithoutFields(); +function ju_AbstractCollection_toArray($this, $a) { + var var$2, $i, $i_0, var$5, $iter$index, var$7, var$8, var$9, $iter$index_0; + var$2 = $a.data; + $i = $this.$size; + $i_0 = var$2.length; + if ($i_0 >= $i) + while ($i < $i_0) { + var$2[$i] = null; + $i = $i + 1 | 0; + } + else { + var$5 = $a.constructor; + if (var$5 === null) + $a = null; + else { + $a = var$5.classObject; + if ($a === null) { + $a = new jl_Class; + $a.$platformClass = var$5; + var$2 = $a; + var$5.classObject = var$2; + } + } + $a = jl_Class_getComponentType($a); + if ($a === null) { + $a = new jl_NullPointerException; + $a.$suppressionEnabled = 1; + $a.$writableStackTrace = 1; + $rt_throw($a); + } + if ($a === $rt_cls($rt_voidcls())) { + $a = new jl_IllegalArgumentException; + $a.$suppressionEnabled = 1; + $a.$writableStackTrace = 1; + $rt_throw($a); + } + if ($i < 0) { + $a = new jl_NegativeArraySizeException; + $a.$suppressionEnabled = 1; + $a.$writableStackTrace = 1; + $rt_throw($a); + } + $a = jlr_Array_newInstanceImpl($a.$platformClass, $i); + } + $i_0 = 0; + $iter$index = 0; + var$7 = $this.$modCount; + var$8 = $this.$size; + $i = $rt_compare(var$7, var$7); + a: { + while (true) { + var$9 = $rt_compare($iter$index, var$8); + if (!(var$9 >= 0 ? 0 : 1)) + break; + var$7 = $i_0 + 1 | 0; + if ($i < 0) { + $a = new ju_ConcurrentModificationException; + $a.$suppressionEnabled = 1; + $a.$writableStackTrace = 1; + $rt_throw($a); + } + $iter$index_0 = $iter$index + 1 | 0; + if ($iter$index < 0) + break a; + if (var$9 >= 0) + break a; + $a.data[$i_0] = $this.$array.data[$iter$index]; + $i_0 = var$7; + $iter$index = $iter$index_0; + } + return $a; + } + $a = new jl_IndexOutOfBoundsException; + $a.$suppressionEnabled = 1; + $a.$writableStackTrace = 1; + $rt_throw($a); +} +var ju_List = $rt_classWithoutFields(0); +function ju_AbstractList() { + ju_AbstractCollection.call(this); + this.$modCount = 0; +} +var jl_Cloneable = $rt_classWithoutFields(0); +var ju_RandomAccess = $rt_classWithoutFields(0); +function ju_ArrayList() { + var a = this; ju_AbstractList.call(a); + a.$array = null; + a.$size = 0; +} +function ju_ArrayList_ensureCapacity($this, $minCapacity) { + var var$2, var$3, var$4, $newLength, var$6, var$7, var$8, var$9; + var$2 = $this.$array; + var$3 = var$2.data; + var$4 = var$3.length; + if (var$4 < $minCapacity) { + if (var$4 >= 1073741823) + $newLength = 2147483647; + else { + var$6 = var$4 * 2 | 0; + $newLength = 5; + if (var$6 > $newLength) + $newLength = var$6; + if ($minCapacity > $newLength) + $newLength = $minCapacity; + } + var$7 = var$2.constructor; + if (var$7 === null) + var$8 = null; + else { + var$8 = var$7.classObject; + if (var$8 === null) { + var$8 = new jl_Class; + var$8.$platformClass = var$7; + var$9 = var$8; + var$7.classObject = var$9; + } + } + var$7 = jl_Class_getComponentType(var$8); + if (var$7 === null) { + var$8 = new jl_NullPointerException; + var$8.$suppressionEnabled = 1; + var$8.$writableStackTrace = 1; + $rt_throw(var$8); + } + if (var$7 === $rt_cls($rt_voidcls())) { + var$8 = new jl_IllegalArgumentException; + var$8.$suppressionEnabled = 1; + var$8.$writableStackTrace = 1; + $rt_throw(var$8); + } + if ($newLength < 0) { + var$8 = new jl_NegativeArraySizeException; + var$8.$suppressionEnabled = 1; + var$8.$writableStackTrace = 1; + $rt_throw(var$8); + } + var$9 = jlr_Array_newInstanceImpl(var$7.$platformClass, $newLength); + if ($newLength < var$4) + var$4 = $newLength; + $minCapacity = 0; + while ($minCapacity < var$4) { + var$9.data[$minCapacity] = var$3[$minCapacity]; + $minCapacity = $minCapacity + 1 | 0; + } + $this.$array = var$9; + } +} +function ju_ArrayList_get($this, $index) { + var var$2; + if ($index >= 0 && $index < $this.$size) + return $this.$array.data[$index]; + var$2 = new jl_IndexOutOfBoundsException; + var$2.$suppressionEnabled = 1; + var$2.$writableStackTrace = 1; + $rt_throw(var$2); +} +function ju_ArrayList_size($this) { + return $this.$size; +} +function ju_ArrayList_add($this, $element) { + var var$2, var$3; + ju_ArrayList_ensureCapacity($this, $this.$size + 1 | 0); + var$2 = $this.$array.data; + var$3 = $this.$size; + $this.$size = var$3 + 1 | 0; + var$2[var$3] = $element; + $this.$modCount = $this.$modCount + 1 | 0; + return 1; +} +function ju_ArrayList_add0($this, $index, $element) { + var var$3, $i, var$5; + if ($index >= 0) { + var$3 = $this.$size; + if ($index <= var$3) { + ju_ArrayList_ensureCapacity($this, var$3 + 1 | 0); + var$3 = $this.$size; + $i = var$3; + while ($i > $index) { + var$5 = $this.$array.data; + var$5[$i] = var$5[$i - 1 | 0]; + $i = $i + (-1) | 0; + } + $this.$array.data[$index] = $element; + $this.$size = var$3 + 1 | 0; + $this.$modCount = $this.$modCount + 1 | 0; + return; + } + } + $element = new jl_IndexOutOfBoundsException; + $element.$suppressionEnabled = 1; + $element.$writableStackTrace = 1; + $rt_throw($element); +} +function ju_ArrayList_remove($this, $i) { + var var$2, var$3, $old, $i_0; + if ($i >= 0) { + var$2 = $this.$size; + if ($i < var$2) { + var$3 = $this.$array.data; + $old = var$3[$i]; + var$2 = var$2 - 1 | 0; + $this.$size = var$2; + while ($i < var$2) { + $i_0 = $i + 1 | 0; + var$3[$i] = var$3[$i_0]; + $i = $i_0; + } + var$3[var$2] = null; + $this.$modCount = $this.$modCount + 1 | 0; + return $old; + } + } + $old = new jl_IndexOutOfBoundsException; + $old.$suppressionEnabled = 1; + $old.$writableStackTrace = 1; + $rt_throw($old); +} +function ju_ArrayList_checkIndex($this, $index) { + var var$2; + if ($index >= 0 && $index < $this.$size) + return; + var$2 = new jl_IndexOutOfBoundsException; + var$2.$suppressionEnabled = 1; + var$2.$writableStackTrace = 1; + $rt_throw(var$2); +} +function jnc_Charset() { + var a = this; jl_Object.call(a); + a.$canonicalName = null; + a.$aliases = null; +} +function jnc_Charset_checkCanonicalName($name) { + var var$2, $c, var$4, $i; + var$2 = $name.$characters.data; + $c = var$2.length; + if ($c ? 0 : 1) { + var$4 = new jnc_IllegalCharsetNameException; + var$4.$suppressionEnabled = 1; + var$4.$writableStackTrace = 1; + var$4.$charsetName = $name; + $rt_throw(var$4); + } + if (0 >= $c) { + $name = new jl_StringIndexOutOfBoundsException; + $name.$suppressionEnabled = 1; + $name.$writableStackTrace = 1; + $rt_throw($name); + } + if (!jnc_Charset_isValidCharsetStart(var$2[0])) { + var$4 = new jnc_IllegalCharsetNameException; + var$4.$suppressionEnabled = 1; + var$4.$writableStackTrace = 1; + var$4.$charsetName = $name; + $rt_throw(var$4); + } + $i = 1; + a: { + while (true) { + var$2 = $name.$characters.data; + $c = $rt_compare($i, var$2.length); + if ($c >= 0) + break; + if ($i < 0) + break a; + if ($c >= 0) + break a; + b: { + $c = var$2[$i]; + switch ($c) { + case 43: + case 45: + case 46: + case 58: + case 95: + break; + default: + if (jnc_Charset_isValidCharsetStart($c)) + break b; + else { + var$4 = new jnc_IllegalCharsetNameException; + var$4.$suppressionEnabled = 1; + var$4.$writableStackTrace = 1; + var$4.$charsetName = $name; + $rt_throw(var$4); + } + } + } + $i = $i + 1 | 0; + } + return; + } + $name = new jl_StringIndexOutOfBoundsException; + $name.$suppressionEnabled = 1; + $name.$writableStackTrace = 1; + $rt_throw($name); +} +function jnc_Charset_isValidCharsetStart($c) { + a: { + b: { + if (!($c >= 48 && $c <= 57) && !($c >= 97 && $c <= 122)) { + if ($c < 65) + break b; + if ($c > 90) + break b; + } + $c = 1; + break a; + } + $c = 0; + } + return $c; +} +var jnci_UTF8Charset = $rt_classWithoutFields(jnc_Charset); +var jnci_UTF8Charset_INSTANCE = null; +function jnci_UTF8Charset__clinit_() { + var var$1, var$2, var$3, var$4, var$5; + var$1 = new jnci_UTF8Charset; + var$2 = $rt_createArray(jl_String, 0); + var$3 = var$2.data; + jnc_Charset_checkCanonicalName($rt_s(2)); + var$4 = var$3.length; + var$5 = 0; + while (var$5 < var$4) { + jnc_Charset_checkCanonicalName(var$3[var$5]); + var$5 = var$5 + 1 | 0; + } + var$1.$canonicalName = $rt_s(2); + var$1.$aliases = var$2.$clone(); + jnci_UTF8Charset_INSTANCE = var$1; +} +var otji_EventHandler = $rt_classWithoutFields(0); +function nles_VirtualFilesystem$AsyncHandlers$1() { + jl_Object.call(this); + this.$val$cb = null; +} +function nles_VirtualFilesystem$AsyncHandlers$1_handleEvent$exported$0(var$0) { + var var$1, var$2, var$3, var$4; + var$1 = var$0.$val$cb; + var$2 = new nles_VirtualFilesystem$DatabaseOpen; + var$3 = null; + var$4 = null; + var$2.$failedInit = 0; + var$2.$failedLocked0 = 1; + var$2.$failedError = var$3; + var$2.$database0 = var$4; + var$1.$realAsyncCallback.$complete(var$2); +} +function nles_VirtualFilesystem$AsyncHandlers$2() { + var a = this; jl_Object.call(a); + a.$val$cb0 = null; + a.$val$f = null; +} +function nles_VirtualFilesystem$AsyncHandlers$2_handleEvent$exported$0(var$0) { + var var$1, var$2, var$3, var$4; + var$1 = var$0.$val$cb0; + var$2 = new nles_VirtualFilesystem$DatabaseOpen; + var$3 = null; + var$4 = var$0.$val$f.result; + var$2.$failedInit = 0; + var$2.$failedLocked0 = 0; + var$2.$failedError = var$3; + var$2.$database0 = var$4; + var$1.$realAsyncCallback.$complete(var$2); +} +function nles_VirtualFilesystem$AsyncHandlers$3() { + jl_Object.call(this); + this.$val$cb1 = null; +} +function nles_VirtualFilesystem$AsyncHandlers$3_handleEvent$exported$0(var$0) { + var var$1, var$2, var$3; + var$1 = var$0.$val$cb1; + var$2 = new nles_VirtualFilesystem$DatabaseOpen; + var$3 = null; + var$2.$failedInit = 0; + var$2.$failedLocked0 = 0; + var$2.$failedError = $rt_s(52); + var$2.$database0 = var$3; + var$1.$realAsyncCallback.$complete(var$2); +} +var otjde_EventListener = $rt_classWithoutFields(0); +function nles_VirtualFilesystem$AsyncHandlers$4() { + jl_Object.call(this); + this.$val$f0 = null; +} +function nles_VirtualFilesystem$AsyncHandlers$4_handleEvent$exported$0(var$0, var$1) { + var var$2, var$3, var$4, var$5, var$6, var$7, var$8; + var$2 = var$0.$val$f0.result; + var$3 = otji_IDBObjectStoreParameters_create$js_body$_1(); + var$4 = $rt_createArray(jl_String, 1).data; + var$4[0] = $rt_s(53); + var$5 = var$4.length; + var$6 = new Array(var$5); + var$7 = 0; + while (var$7 < var$5) { + var$8 = $rt_ustr(var$4[var$7]); + var$6[var$7] = var$8; + var$7 = var$7 + 1 | 0; + } + var$3.keyPath = var$6; + var$2.createObjectStore("filesystem", var$3); +} +var otji_IDBFactory = $rt_classWithoutFields(); +function otji_IDBFactory_getInstance() { + var $factory, var$2; + $factory = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB; + if (!(typeof $factory === 'undefined' ? 1 : 0)) + return $factory; + var$2 = new jl_IllegalStateException; + var$2.$suppressionEnabled = 1; + var$2.$writableStackTrace = 1; + var$2.$message = $rt_s(54); + $rt_throw(var$2); +} +var ju_Map = $rt_classWithoutFields(0); +var ju_AbstractMap = $rt_classWithoutFields(); +function ju_HashMap() { + var a = this; ju_AbstractMap.call(a); + a.$elementCount = 0; + a.$elementData = null; + a.$loadFactor = 0.0; + a.$threshold = 0; +} +function ju_HashMap_calculateCapacity($x) { + var var$2; + if ($x >= 1073741824) + return 1073741824; + if (!$x) + return 16; + var$2 = $x - 1 | 0; + $x = var$2 | var$2 >> 1; + $x = $x | $x >> 2; + $x = $x | $x >> 4; + $x = $x | $x >> 8; + return ($x | $x >> 16) + 1 | 0; +} +var jl_IllegalStateException = $rt_classWithoutFields(jl_Exception); +var jl_IllegalArgumentException = $rt_classWithoutFields(jl_RuntimeException); +function jnc_IllegalCharsetNameException() { + jl_IllegalArgumentException.call(this); + this.$charsetName = null; +} +var jl_CloneNotSupportedException = $rt_classWithoutFields(jl_Exception); +var jl_IndexOutOfBoundsException = $rt_classWithoutFields(jl_RuntimeException); +var jl_StringIndexOutOfBoundsException = $rt_classWithoutFields(jl_IndexOutOfBoundsException); +var ju_Map$Entry = $rt_classWithoutFields(0); +var ju_MapEntry = $rt_classWithoutFields(); +var ju_HashMap$HashEntry = $rt_classWithoutFields(ju_MapEntry); +function jn_Buffer() { + var a = this; jl_Object.call(a); + a.$capacity = 0; + a.$position = 0; + a.$limit = 0; + a.$mark = 0; +} +function jn_Buffer_position($this, $newPosition) { + var var$2, var$3, var$4, var$5, var$6, var$7, var$8, var$9; + if ($newPosition >= 0 && $newPosition <= $this.$limit) { + $this.$position = $newPosition; + if ($newPosition < $this.$mark) + $this.$mark = 0; + return $this; + } + var$2 = new jl_IllegalArgumentException; + var$3 = new jl_StringBuilder; + var$3.$buffer = $rt_createCharArray(16); + jl_AbstractStringBuilder_insert(var$3, var$3.$length, $rt_s(55)); + jl_AbstractStringBuilder_insert0(var$3, var$3.$length, $newPosition, 10); + jl_AbstractStringBuilder_insert(var$3, var$3.$length, $rt_s(56)); + $newPosition = $this.$limit; + jl_AbstractStringBuilder_insert0(var$3, var$3.$length, $newPosition, 10); + jl_AbstractStringBuilder_insert(var$3, var$3.$length, $rt_s(57)); + var$4 = new jl_String; + var$5 = var$3.$buffer; + var$6 = var$3.$length; + var$7 = $rt_createCharArray(var$6); + var$8 = var$7.data; + var$4.$characters = var$7; + var$9 = 0; + while (var$9 < var$6) { + var$8[var$9] = var$5.data[var$9 + 0 | 0]; + var$9 = var$9 + 1 | 0; + } + var$2.$suppressionEnabled = 1; + var$2.$writableStackTrace = 1; + var$2.$message = var$4; + $rt_throw(var$2); +} +var jl_Readable = $rt_classWithoutFields(0); +var jn_CharBuffer = $rt_classWithoutFields(jn_Buffer); +function jn_CharBuffer_get($this, $dst, $offset, $length) { + var var$4, var$5, $i, var$7, var$8, var$9, var$10, $pos, var$12, var$13; + if ($offset >= 0) { + var$4 = $dst.data; + var$5 = var$4.length; + if ($offset < var$5) { + $i = $offset + $length | 0; + if ($i > var$5) { + var$7 = new jl_IndexOutOfBoundsException; + var$8 = new jl_StringBuilder; + var$8.$buffer = $rt_createCharArray(16); + jl_AbstractStringBuilder_insert(var$8, var$8.$length, $rt_s(58)); + jl_AbstractStringBuilder_insert0(var$8, var$8.$length, $i, 10); + jl_AbstractStringBuilder_insert(var$8, var$8.$length, $rt_s(59)); + jl_AbstractStringBuilder_insert0(var$8, var$8.$length, var$5, 10); + var$9 = new jl_String; + $dst = var$8.$buffer; + $length = var$8.$length; + var$4 = $rt_createCharArray($length); + var$10 = var$4.data; + var$9.$characters = var$4; + var$5 = 0; + while (var$5 < $length) { + var$10[var$5] = $dst.data[var$5 + 0 | 0]; + var$5 = var$5 + 1 | 0; + } + var$7.$suppressionEnabled = 1; + var$7.$writableStackTrace = 1; + var$7.$message = var$9; + $rt_throw(var$7); + } + var$5 = $this.$limit; + $pos = $this.$position; + if ((var$5 - $pos | 0) < $length) { + var$7 = new jn_BufferUnderflowException; + var$7.$suppressionEnabled = 1; + var$7.$writableStackTrace = 1; + $rt_throw(var$7); + } + if ($length >= 0) { + $i = 0; + var$12 = $pos; + while ($i < $length) { + var$13 = $offset + 1 | 0; + var$5 = var$12 + 1 | 0; + var$4[$offset] = $this.$array0.data[var$12 + $this.$start0 | 0]; + $i = $i + 1 | 0; + $offset = var$13; + var$12 = var$5; + } + $this.$position = $pos + $length | 0; + return $this; + } + var$7 = new jl_IndexOutOfBoundsException; + var$8 = new jl_StringBuilder; + var$8.$buffer = $rt_createCharArray(16); + jl_AbstractStringBuilder_insert(var$8, var$8.$length, $rt_s(60)); + jl_AbstractStringBuilder_insert0(var$8, var$8.$length, $length, 10); + jl_AbstractStringBuilder_insert(var$8, var$8.$length, $rt_s(61)); + var$9 = new jl_String; + $dst = var$8.$buffer; + $length = var$8.$length; + var$4 = $rt_createCharArray($length); + var$10 = var$4.data; + var$9.$characters = var$4; + var$5 = 0; + while (var$5 < $length) { + var$10[var$5] = $dst.data[var$5 + 0 | 0]; + var$5 = var$5 + 1 | 0; + } + var$7.$suppressionEnabled = 1; + var$7.$writableStackTrace = 1; + var$7.$message = var$9; + $rt_throw(var$7); + } + } + $dst = $dst.data; + var$8 = new jl_IndexOutOfBoundsException; + var$7 = new jl_StringBuilder; + var$7.$buffer = $rt_createCharArray(16); + jl_AbstractStringBuilder_insert(var$7, var$7.$length, $rt_s(62)); + jl_AbstractStringBuilder_insert0(var$7, var$7.$length, $offset, 10); + jl_AbstractStringBuilder_insert(var$7, var$7.$length, $rt_s(56)); + $offset = $dst.length; + jl_AbstractStringBuilder_insert0(var$7, var$7.$length, $offset, 10); + jl_AbstractStringBuilder_insert(var$7, var$7.$length, $rt_s(63)); + var$9 = new jl_String; + $dst = var$7.$buffer; + $length = var$7.$length; + var$4 = $rt_createCharArray($length); + var$10 = var$4.data; + var$9.$characters = var$4; + var$5 = 0; + while (var$5 < $length) { + var$10[var$5] = $dst.data[var$5 + 0 | 0]; + var$5 = var$5 + 1 | 0; + } + var$8.$suppressionEnabled = 1; + var$8.$writableStackTrace = 1; + var$8.$message = var$9; + $rt_throw(var$8); +} +var jl_Math = $rt_classWithoutFields(); +function jn_ByteBuffer() { + var a = this; jn_Buffer.call(a); + a.$start1 = 0; + a.$array1 = null; + a.$order = null; +} +function jn_ByteBuffer_put($this, $src, $offset, $length) { + var var$4, var$5, var$6, var$7, $pos, var$9, var$10, var$11, $i, var$13; + if (!$length) + return $this; + if ($this.$readOnly0) { + var$4 = new jn_ReadOnlyBufferException; + var$4.$suppressionEnabled = 1; + var$4.$writableStackTrace = 1; + $rt_throw(var$4); + } + var$5 = $this.$limit; + var$6 = $this.$position; + if ((var$5 - var$6 | 0) < $length) { + var$4 = new jn_BufferOverflowException; + var$4.$suppressionEnabled = 1; + var$4.$writableStackTrace = 1; + $rt_throw(var$4); + } + if ($offset >= 0) { + var$7 = $src.data; + var$5 = var$7.length; + if ($offset < var$5) { + $pos = $offset + $length | 0; + if ($pos > var$5) { + var$4 = new jl_IndexOutOfBoundsException; + var$9 = new jl_StringBuilder; + var$9.$buffer = $rt_createCharArray(16); + jl_AbstractStringBuilder_insert(var$9, var$9.$length, $rt_s(64)); + jl_AbstractStringBuilder_insert0(var$9, var$9.$length, $pos, 10); + jl_AbstractStringBuilder_insert(var$9, var$9.$length, $rt_s(59)); + jl_AbstractStringBuilder_insert0(var$9, var$9.$length, var$5, 10); + var$10 = new jl_String; + $src = var$9.$buffer; + $length = var$9.$length; + var$7 = $rt_createCharArray($length); + var$11 = var$7.data; + var$10.$characters = var$7; + var$5 = 0; + while (var$5 < $length) { + var$11[var$5] = $src.data[var$5 + 0 | 0]; + var$5 = var$5 + 1 | 0; + } + var$4.$suppressionEnabled = 1; + var$4.$writableStackTrace = 1; + var$4.$message = var$10; + $rt_throw(var$4); + } + if ($length >= 0) { + $pos = var$6 + $this.$start1 | 0; + $i = 0; + while ($i < $length) { + $src = $this.$array1.data; + var$13 = $pos + 1 | 0; + var$5 = $offset + 1 | 0; + $src[$pos] = var$7[$offset]; + $i = $i + 1 | 0; + $pos = var$13; + $offset = var$5; + } + $this.$position = var$6 + $length | 0; + return $this; + } + var$4 = new jl_IndexOutOfBoundsException; + var$9 = new jl_StringBuilder; + var$9.$buffer = $rt_createCharArray(16); + jl_AbstractStringBuilder_insert(var$9, var$9.$length, $rt_s(60)); + jl_AbstractStringBuilder_insert0(var$9, var$9.$length, $length, 10); + jl_AbstractStringBuilder_insert(var$9, var$9.$length, $rt_s(61)); + var$10 = new jl_String; + $src = var$9.$buffer; + $length = var$9.$length; + var$7 = $rt_createCharArray($length); + var$11 = var$7.data; + var$10.$characters = var$7; + var$5 = 0; + while (var$5 < $length) { + var$11[var$5] = $src.data[var$5 + 0 | 0]; + var$5 = var$5 + 1 | 0; + } + var$4.$suppressionEnabled = 1; + var$4.$writableStackTrace = 1; + var$4.$message = var$10; + $rt_throw(var$4); + } + } + $src = $src.data; + var$9 = new jl_IndexOutOfBoundsException; + var$4 = new jl_StringBuilder; + var$4.$buffer = $rt_createCharArray(16); + jl_AbstractStringBuilder_insert(var$4, var$4.$length, $rt_s(62)); + jl_AbstractStringBuilder_insert0(var$4, var$4.$length, $offset, 10); + jl_AbstractStringBuilder_insert(var$4, var$4.$length, $rt_s(56)); + $offset = $src.length; + jl_AbstractStringBuilder_insert0(var$4, var$4.$length, $offset, 10); + jl_AbstractStringBuilder_insert(var$4, var$4.$length, $rt_s(63)); + var$10 = new jl_String; + $src = var$4.$buffer; + $length = var$4.$length; + var$7 = $rt_createCharArray($length); + var$11 = var$7.data; + var$10.$characters = var$7; + var$5 = 0; + while (var$5 < $length) { + var$11[var$5] = $src.data[var$5 + 0 | 0]; + var$5 = var$5 + 1 | 0; + } + var$9.$suppressionEnabled = 1; + var$9.$writableStackTrace = 1; + var$9.$message = var$10; + $rt_throw(var$9); +} +function jnc_CodingErrorAction() { + jl_Object.call(this); + this.$name0 = null; +} +var jnc_CodingErrorAction_IGNORE = null; +var jnc_CodingErrorAction_REPLACE = null; +var jnc_CodingErrorAction_REPORT = null; +function jnc_CodingErrorAction__clinit_() { + var var$1; + var$1 = new jnc_CodingErrorAction; + var$1.$name0 = $rt_s(3); + jnc_CodingErrorAction_IGNORE = var$1; + var$1 = new jnc_CodingErrorAction; + var$1.$name0 = $rt_s(4); + jnc_CodingErrorAction_REPLACE = var$1; + var$1 = new jnc_CodingErrorAction; + var$1.$name0 = $rt_s(5); + jnc_CodingErrorAction_REPORT = var$1; +} +var jn_CharBufferImpl = $rt_classWithoutFields(jn_CharBuffer); +function jn_CharBufferOverArray() { + var a = this; jn_CharBufferImpl.call(a); + a.$readOnly = 0; + a.$start0 = 0; + a.$array0 = null; +} +function jnc_CharsetEncoder() { + var a = this; jl_Object.call(a); + a.$charset0 = null; + a.$replacement = null; + a.$averageBytesPerChar = 0.0; + a.$maxBytesPerChar = 0.0; + a.$malformedAction = null; + a.$unmappableAction = null; + a.$status = 0; +} +function jnc_CharsetEncoder_encode($this, $in, $out, $endOfInput) { + var $remaining, $result, $e, $action, var$8, var$9, var$10, $$je; + a: { + $remaining = $this.$status; + if ($remaining != 3) { + if ($endOfInput) + break a; + if ($remaining != 2) + break a; + } + $in = new jl_IllegalStateException; + $in.$suppressionEnabled = 1; + $in.$writableStackTrace = 1; + $rt_throw($in); + } + $this.$status = !$endOfInput ? 1 : 2; + while (true) { + try { + $result = jnci_BufferedEncoder_encodeLoop($this, $in, $out); + } catch ($$e) { + $$je = $rt_wrapException($$e); + if ($$je instanceof jl_RuntimeException) { + $e = $$je; + $in = new jnc_CoderMalfunctionError; + $in.$suppressionEnabled = 1; + $in.$writableStackTrace = 1; + $in.$cause = $e; + $rt_throw($in); + } else { + throw $$e; + } + } + $remaining = $result.$kind; + if ($remaining ? 0 : 1) { + if (!$endOfInput) + return $result; + $remaining = $in.$limit - $in.$position | 0; + if ($remaining <= 0) + return $result; + $result = new jnc_CoderResult; + $result.$kind = 2; + $result.$length0 = $remaining; + } else if ($remaining != 1 ? 0 : 1) + break; + $action = !($result.$kind != 3 ? 0 : 1) ? $this.$malformedAction : $this.$unmappableAction; + b: { + if ($action !== jnc_CodingErrorAction_REPLACE) { + if ($action === jnc_CodingErrorAction_IGNORE) + break b; + else + return $result; + } + var$8 = $out.$limit - $out.$position | 0; + var$9 = $this.$replacement; + $remaining = var$9.data.length; + if (var$8 < $remaining) + return jnc_CoderResult_OVERFLOW; + jn_ByteBuffer_put($out, var$9, 0, $remaining); + } + var$10 = $in.$position; + $remaining = $result.$kind; + var$8 = $remaining != 2 ? 0 : 1; + if (!(!var$8 && !($remaining != 3 ? 0 : 1) ? 0 : 1)) { + $in = new jl_UnsupportedOperationException; + $in.$suppressionEnabled = 1; + $in.$writableStackTrace = 1; + $rt_throw($in); + } + jn_Buffer_position($in, var$10 + $result.$length0 | 0); + } + return $result; +} +function jnc_CoderResult() { + var a = this; jl_Object.call(a); + a.$kind = 0; + a.$length0 = 0; +} +var jnc_CoderResult_UNDERFLOW = null; +var jnc_CoderResult_OVERFLOW = null; +function jnc_CoderResult__clinit_() { + var var$1; + var$1 = new jnc_CoderResult; + var$1.$kind = 0; + var$1.$length0 = 0; + jnc_CoderResult_UNDERFLOW = var$1; + var$1 = new jnc_CoderResult; + var$1.$kind = 1; + var$1.$length0 = 0; + jnc_CoderResult_OVERFLOW = var$1; +} +function jn_ByteBufferImpl() { + var a = this; jn_ByteBuffer.call(a); + a.$direct = 0; + a.$readOnly0 = 0; +} +function jn_ByteOrder() { + jl_Object.call(this); + this.$name1 = null; +} +var jn_ByteOrder_BIG_ENDIAN = null; +var jn_ByteOrder_LITTLE_ENDIAN = null; +function jn_ByteOrder__clinit_() { + var var$1; + var$1 = new jn_ByteOrder; + var$1.$name1 = $rt_s(6); + jn_ByteOrder_BIG_ENDIAN = var$1; + var$1 = new jn_ByteOrder; + var$1.$name1 = $rt_s(7); + jn_ByteOrder_LITTLE_ENDIAN = var$1; +} +function jur_Pattern() { + var a = this; jl_Object.call(a); + a.$lexemes = null; + a.$flags = 0; + a.$backRefs = null; + a.$needsBackRefReplacement = 0; + a.$globalGroupIndex = 0; + a.$compCount = 0; + a.$consCount = 0; + a.$start2 = null; +} +function jur_Pattern_split($this, $inputSeq, $limit) { + var $res, $mat, $index, $curPos, var$7, var$8, var$9, var$10, var$11, var$12; + $res = new ju_ArrayList; + $res.$array = $rt_createArray(jl_Object, 10); + $mat = jur_Matcher__init_($this, $inputSeq); + $index = 0; + $curPos = 0; + if (!$inputSeq.$characters.data.length) { + var$7 = $rt_createArray(jl_String, 1); + var$7.data[0] = $rt_s(47); + return var$7; + } + a: { + while (true) { + if (!jur_Matcher_find($mat)) + break a; + var$8 = $index + 1 | 0; + if (var$8 >= $limit && $limit > 0) + break a; + var$9 = $mat.$matchResult; + if (!var$9.$valid) { + $inputSeq = new jl_IllegalStateException; + $inputSeq.$suppressionEnabled = 1; + $inputSeq.$writableStackTrace = 1; + $rt_throw($inputSeq); + } + if (0 >= var$9.$groupCount) { + $inputSeq = new jl_IndexOutOfBoundsException; + $res = new jl_StringBuilder; + jl_Object__init_0($res); + $res.$buffer = $rt_createCharArray(16); + jl_AbstractStringBuilder_insert0($res, $res.$length, 0, 10); + $mat = new jl_String; + var$7 = $res.$buffer; + $index = $res.$length; + var$10 = $rt_createCharArray($index); + var$11 = var$10.data; + $mat.$characters = var$10; + var$8 = 0; + while (var$8 < $index) { + var$11[var$8] = var$7.data[var$8 + 0 | 0]; + var$8 = var$8 + 1 | 0; + } + $inputSeq.$suppressionEnabled = 1; + $inputSeq.$writableStackTrace = 1; + $inputSeq.$message = $mat; + $rt_throw($inputSeq); + } + var$12 = var$9.$groupBounds.data[0]; + if ($curPos > var$12) { + $inputSeq = new jl_IndexOutOfBoundsException; + $inputSeq.$suppressionEnabled = 1; + $inputSeq.$writableStackTrace = 1; + $rt_throw($inputSeq); + } + var$9 = new jl_String; + var$7 = $inputSeq.$characters; + $index = var$12 - $curPos | 0; + var$10 = $rt_createCharArray($index); + var$11 = var$10.data; + var$9.$characters = var$10; + var$12 = 0; + while (var$12 < $index) { + var$11[var$12] = var$7.data[var$12 + $curPos | 0]; + var$12 = var$12 + 1 | 0; + } + ju_ArrayList_ensureCapacity($res, $res.$size + 1 | 0); + var$7 = $res.$array.data; + var$12 = $res.$size; + $res.$size = var$12 + 1 | 0; + var$7[var$12] = var$9; + $res.$modCount = $res.$modCount + 1 | 0; + var$9 = $mat.$matchResult; + if (!var$9.$valid) + break; + if (0 >= var$9.$groupCount) { + $inputSeq = new jl_IndexOutOfBoundsException; + $res = new jl_StringBuilder; + jl_Object__init_0($res); + $res.$buffer = $rt_createCharArray(16); + jl_AbstractStringBuilder_insert0($res, $res.$length, 0, 10); + $res = jl_StringBuilder_toString($res); + $inputSeq.$suppressionEnabled = 1; + $inputSeq.$writableStackTrace = 1; + $inputSeq.$message = $res; + $rt_throw($inputSeq); + } + $curPos = var$9.$groupBounds.data[1]; + $index = var$8; + } + $inputSeq = new jl_IllegalStateException; + $inputSeq.$suppressionEnabled = 1; + $inputSeq.$writableStackTrace = 1; + $rt_throw($inputSeq); + } + var$11 = $inputSeq.$characters.data; + var$12 = var$11.length; + if ($curPos > var$12) { + $inputSeq = new jl_IndexOutOfBoundsException; + $inputSeq.$suppressionEnabled = 1; + $inputSeq.$writableStackTrace = 1; + $rt_throw($inputSeq); + } + $inputSeq = new jl_String; + var$8 = var$12 - $curPos | 0; + var$7 = $rt_createCharArray(var$8); + var$10 = var$7.data; + $inputSeq.$characters = var$7; + var$12 = 0; + while (var$12 < var$8) { + var$10[var$12] = var$11[var$12 + $curPos | 0]; + var$12 = var$12 + 1 | 0; + } + b: { + ju_ArrayList_ensureCapacity($res, $res.$size + 1 | 0); + var$7 = $res.$array.data; + var$8 = $res.$size; + $res.$size = var$8 + 1 | 0; + var$7[var$8] = $inputSeq; + $res.$modCount = $res.$modCount + 1 | 0; + $index = $index + 1 | 0; + if (!$limit) + while (true) { + $index = $index + (-1) | 0; + if ($index < 0) + break; + ju_ArrayList_checkIndex($res, $index); + if (jl_String_length($res.$array.data[$index])) + break b; + ju_ArrayList_remove($res, $index); + } + } + if ($index < 0) + $index = 0; + return ju_AbstractCollection_toArray($res, $rt_createArray(jl_String, $index)); +} +function jur_Pattern_pattern($this) { + return $this.$lexemes.$orig; +} +function jur_Pattern_compile($pattern, $flags) { + var var$3; + if ($pattern === null) { + $pattern = new jl_NullPointerException; + $pattern.$suppressionEnabled = 1; + $pattern.$writableStackTrace = 1; + $pattern.$message = $rt_s(65); + $rt_throw($pattern); + } + if ($flags && ($flags | 255) != 255) { + $pattern = new jl_IllegalArgumentException; + $pattern.$suppressionEnabled = 1; + $pattern.$writableStackTrace = 1; + $pattern.$message = $rt_s(47); + $rt_throw($pattern); + } + jur_AbstractSet_counter = 1; + var$3 = new jur_Pattern; + var$3.$backRefs = $rt_createArray(jur_FSet, 10); + var$3.$globalGroupIndex = (-1); + var$3.$compCount = (-1); + var$3.$consCount = (-1); + return jur_Pattern_compileImpl(var$3, $pattern, $flags); +} +function jur_Pattern_compileImpl($this, $pattern, $flags) { + var var$3, var$4, var$5; + $this.$lexemes = jur_Lexer__init_($pattern, $flags); + $this.$flags = $flags; + $pattern = jur_Pattern_processExpression($this, (-1), $flags, null); + $this.$start2 = $pattern; + var$3 = $this.$lexemes; + if (!var$3.$ch && !var$3.$lookAhead && var$3.$index == var$3.$patternFullLength && !(var$3.$curST === null ? 0 : 1) ? 1 : 0) { + if ($this.$needsBackRefReplacement) + $pattern.$processSecondPass(); + return $this; + } + $pattern = new jur_PatternSyntaxException; + var$4 = var$3.$orig; + var$5 = var$3.$curToc; + $pattern.$suppressionEnabled = 1; + $pattern.$writableStackTrace = 1; + $pattern.$index0 = (-1); + $pattern.$desc = $rt_s(47); + $pattern.$pattern = var$4; + $pattern.$index0 = var$5; + $rt_throw($pattern); +} +function jur_Pattern_processAlternations($this, $last) { + var $auxRange, var$3, var$4, var$5, $rangeSet, var$7; + $auxRange = new jur_CharClass; + var$3 = $this.$flags; + var$4 = (var$3 & 2) != 2 ? 0 : 1; + var$5 = (var$3 & 64) != 64 ? 0 : 1; + $rangeSet = new ju_BitSet; + $rangeSet.$data0 = $rt_createIntArray(64); + $auxRange.$lowHighSurrogates = $rangeSet; + $rangeSet = new ju_BitSet; + $rangeSet.$data0 = $rt_createIntArray(0); + $auxRange.$bits = $rangeSet; + $auxRange.$ci = var$4; + $auxRange.$uci = var$5; + while (true) { + var$7 = $this.$lexemes; + var$3 = var$7.$ch; + if (!var$3 && !var$7.$lookAhead && var$7.$index == var$7.$patternFullLength && !(var$7.$curST === null ? 0 : 1) ? 1 : 0) + break; + var$5 = !var$3 && !var$7.$lookAhead && var$7.$index == var$7.$patternFullLength && !(var$7.$curST === null ? 0 : 1) ? 1 : 0; + if (!(!var$5 && !(var$7.$curST === null ? 0 : 1) && (var$3 < 0 ? 0 : 1) ? 1 : 0)) + break; + var$5 = var$7.$lookAhead; + if (var$5 && var$5 != (-536870788) && var$5 != (-536870871)) + break; + jur_Lexer_movePointer(var$7); + jur_CharClass_add($auxRange, var$7.$lookBack); + $rangeSet = $this.$lexemes; + if ($rangeSet.$ch != (-536870788)) + continue; + jur_Lexer_movePointer($rangeSet); + } + $rangeSet = jur_Pattern_processRangeSet($this, $auxRange); + $rangeSet.$setNext($last); + return $rangeSet; +} +function jur_Pattern_processExpression($this, $ch, $newFlags, $last) { + var $children, $saveFlags, $saveChangedFlags, $fSet, var$8, var$9, var$10, $child; + $children = new ju_ArrayList; + $children.$array = $rt_createArray(jl_Object, 10); + $saveFlags = $this.$flags; + $saveChangedFlags = 0; + if ($newFlags != $saveFlags) + $this.$flags = $newFlags; + a: { + switch ($ch) { + case -1073741784: + $fSet = new jur_NonCapFSet; + $newFlags = $this.$consCount + 1 | 0; + $this.$consCount = $newFlags; + jur_FSet_$callClinit(); + var$8 = jur_AbstractSet_counter; + jur_AbstractSet_counter = var$8 + 1 | 0; + $last = new jl_AbstractStringBuilder; + $last.$buffer = $rt_createCharArray(20); + $fSet.$index1 = (jl_AbstractStringBuilder_insert0($last, $last.$length, var$8, 10)).$toString(); + $fSet.$groupIndex = $newFlags; + break a; + case -536870872: + case -268435416: + $fSet = new jur_AheadFSet; + jur_FSet_$callClinit(); + var$8 = jur_AbstractSet_counter; + jur_AbstractSet_counter = var$8 + 1 | 0; + $last = new jl_AbstractStringBuilder; + $last.$buffer = $rt_createCharArray(20); + $fSet.$index1 = (jl_AbstractStringBuilder_insert0($last, $last.$length, var$8, 10)).$toString(); + $fSet.$groupIndex = (-1); + break a; + case -134217688: + case -67108824: + $fSet = new jur_BehindFSet; + var$9 = $this.$consCount + 1 | 0; + $this.$consCount = var$9; + jur_FSet_$callClinit(); + $newFlags = jur_AbstractSet_counter; + jur_AbstractSet_counter = $newFlags + 1 | 0; + $last = new jl_AbstractStringBuilder; + $last.$buffer = $rt_createCharArray(20); + $fSet.$index1 = (jl_AbstractStringBuilder_insert0($last, $last.$length, $newFlags, 10)).$toString(); + $fSet.$groupIndex = var$9; + break a; + case -33554392: + break; + default: + $newFlags = $this.$globalGroupIndex + 1 | 0; + $this.$globalGroupIndex = $newFlags; + if ($last !== null) { + $fSet = new jur_FSet; + jur_FSet_$callClinit(); + jur_AbstractSet__init_($fSet); + $fSet.$groupIndex = $newFlags; + } else { + $fSet = new jur_FinalSet; + jur_FSet__init_($fSet, 0); + $saveChangedFlags = 1; + } + var$8 = $this.$globalGroupIndex; + if (var$8 <= (-1)) + break a; + if (var$8 >= 10) + break a; + $this.$backRefs.data[var$8] = $fSet; + break a; + } + $fSet = new jur_AtomicFSet; + var$10 = $this.$consCount + 1 | 0; + $this.$consCount = var$10; + jur_FSet_$callClinit(); + $newFlags = jur_AbstractSet_counter; + jur_AbstractSet_counter = $newFlags + 1 | 0; + $fSet.$index1 = jl_Integer_toString($newFlags, 10); + $fSet.$groupIndex = var$10; + } + while (true) { + if (jur_Lexer_isLetter($this.$lexemes) && $this.$lexemes.$lookAhead == (-536870788)) + $child = jur_Pattern_processAlternations($this, $fSet); + else if ($this.$lexemes.$ch == (-536870788)) { + $child = jur_EmptySet__init_($fSet); + jur_Lexer_next($this.$lexemes); + } else { + $child = jur_Pattern_processSubExpression($this, $fSet); + if (jur_Lexer_peek($this.$lexemes) == (-536870788)) + jur_Lexer_next($this.$lexemes); + } + if ($child !== null) + ju_ArrayList_add($children, $child); + if (jur_Lexer_isEmpty($this.$lexemes)) + break; + if (jur_Lexer_peek($this.$lexemes) == (-536870871)) + break; + } + if (jur_Lexer_back($this.$lexemes) == (-536870788)) + ju_ArrayList_add($children, jur_EmptySet__init_($fSet)); + if ($this.$flags != $saveFlags && !$saveChangedFlags) { + $this.$flags = $saveFlags; + jur_Lexer_restoreFlags($this.$lexemes, $saveFlags); + } + switch ($ch) { + case -1073741784: + break; + case -536870872: + return jur_PositiveLookAhead__init_($children, $fSet); + case -268435416: + return jur_NegativeLookAhead__init_($children, $fSet); + case -134217688: + return jur_PositiveLookBehind__init_($children, $fSet); + case -67108824: + return jur_NegativeLookBehind__init_($children, $fSet); + case -33554392: + return jur_AtomicJointSet__init_($children, $fSet); + default: + switch (ju_ArrayList_size($children)) { + case 0: + break; + case 1: + return jur_SingleSet__init_(ju_ArrayList_get($children, 0), $fSet); + default: + return jur_JointSet__init_($children, $fSet); + } + return jur_EmptySet__init_($fSet); + } + return jur_NonCapJointSet__init_($children, $fSet); +} +function jur_Pattern_processSequence($this) { + var $substring, var$2, var$3, var$4, var$5, $ch, var$7, var$8, var$9, var$10; + $substring = new jl_StringBuffer; + $substring.$buffer = $rt_createCharArray(16); + while (true) { + var$2 = $this.$lexemes; + var$3 = var$2.$ch; + if (!var$3 && !var$2.$lookAhead && var$2.$index == var$2.$patternFullLength && !(var$2.$curST === null ? 0 : 1) ? 1 : 0) + break; + var$4 = !var$3 && !var$2.$lookAhead && var$2.$index == var$2.$patternFullLength && !(var$2.$curST === null ? 0 : 1) ? 1 : 0; + if (!(!var$4 && !(var$2.$curST === null ? 0 : 1) && (var$3 < 0 ? 0 : 1) ? 1 : 0)) + break; + if (var$3 <= 56319 && var$3 >= 55296 ? 1 : 0) + break; + if (var$3 <= 57343 && var$3 >= 56320 ? 1 : 0) + break; + var$5 = var$2.$lookAheadST; + var$4 = var$5 === null ? 0 : 1; + if (!(!var$4 && !var$2.$lookAhead)) { + var$4 = var$5 === null ? 0 : 1; + if (!(!var$4 && (var$2.$lookAhead < 0 ? 0 : 1))) { + var$3 = var$2.$lookAhead; + if (var$3 != (-536870871) && (var$3 & (-2147418113)) != (-2147483608) && var$3 != (-536870788) && var$3 != (-536870876)) + break; + } + } + jur_Lexer_movePointer(var$2); + $ch = var$2.$lookBack; + var$4 = $rt_compare($ch, 65536); + if (!(var$4 >= 0 && $ch <= 1114111 ? 1 : 0)) { + var$4 = $ch & 65535; + var$7 = $substring.$length; + jl_AbstractStringBuilder_insertSpace($substring, var$7, var$7 + 1 | 0); + $substring.$buffer.data[var$7] = var$4; + } else { + if (var$4 < 0) { + var$8 = $rt_createCharArray(1); + var$8.data[0] = $ch & 65535; + } else + var$8 = $rt_createCharArrayFromData([(55296 | ($ch - 65536 | 0) >> 10 & 1023) & 65535, (56320 | $ch & 1023) & 65535]); + var$8 = var$8.data; + var$4 = 0; + var$7 = var$8.length; + var$3 = $substring.$length; + jl_AbstractStringBuilder_insertSpace($substring, var$3, var$3 + var$7 | 0); + var$9 = var$7 + var$4 | 0; + while (var$4 < var$9) { + var$10 = $substring.$buffer.data; + $ch = var$3 + 1 | 0; + var$7 = var$4 + 1 | 0; + var$10[var$3] = var$8[var$4]; + var$3 = $ch; + var$4 = var$7; + } + } + } + var$7 = $this.$flags; + if (!((var$7 & 2) != 2 ? 0 : 1)) + return jur_SequenceSet__init_($substring); + if (!((var$7 & 64) != 64 ? 0 : 1)) + return jur_CISequenceSet__init_($substring); + var$2 = new jur_UCISequenceSet; + var$4 = jur_AbstractSet_counter; + jur_AbstractSet_counter = var$4 + 1 | 0; + var$2.$index1 = jl_Integer_toString0(var$4); + var$2.$charCount = 1; + var$5 = new jl_StringBuilder; + jl_AbstractStringBuilder__init_0(var$5); + var$4 = 0; + while (var$4 < jl_StringBuffer_length($substring)) { + jl_StringBuilder_append(var$5, jl_Character_toLowerCase(jl_Character_toUpperCase(jl_StringBuffer_charAt($substring, var$4)))); + var$4 = var$4 + 1 | 0; + } + var$2.$string = jl_StringBuilder_toString(var$5); + var$2.$charCount = jl_StringBuilder_length(var$5); + return var$2; +} +function jur_Pattern_processDecomposedChar($this) { + var $codePoints, $curSymb, $curSymbIndex, var$4, var$5, var$6, $codePointsHangul, $readCodePoints, var$9; + $codePoints = $rt_createIntArray(4); + $curSymb = (-1); + $curSymbIndex = (-1); + var$4 = $this.$lexemes; + var$5 = var$4.$ch; + if (!(!var$5 && !var$4.$lookAhead && var$4.$index == var$4.$patternFullLength && !(var$4.$curST === null ? 0 : 1) ? 1 : 0)) { + var$6 = !var$5 && !var$4.$lookAhead && var$4.$index == var$4.$patternFullLength && !(var$4.$curST === null ? 0 : 1) ? 1 : 0; + if (!var$6 && !(var$4.$curST === null ? 0 : 1) && (var$5 < 0 ? 0 : 1) ? 1 : 0) { + $codePointsHangul = $codePoints.data; + jur_Lexer_movePointer(var$4); + $curSymb = var$4.$lookBack; + $codePointsHangul[0] = $curSymb; + $curSymbIndex = $curSymb - 4352 | 0; + } + } + if ($curSymbIndex >= 0 && $curSymbIndex < 19) { + $codePointsHangul = $rt_createCharArray(3); + $codePoints = $codePointsHangul.data; + $codePoints[0] = $curSymb & 65535; + var$4 = $this.$lexemes; + $readCodePoints = var$4.$ch; + $curSymb = $readCodePoints - 4449 | 0; + if ($curSymb >= 0 && $curSymb < 21) { + $codePoints[1] = $readCodePoints & 65535; + jur_Lexer_movePointer(var$4); + var$4 = $this.$lexemes; + $readCodePoints = var$4.$ch; + $curSymbIndex = $readCodePoints - 4519 | 0; + if ($curSymbIndex >= 0 && $curSymbIndex < 28) { + $codePoints[2] = $readCodePoints & 65535; + jur_Lexer_movePointer(var$4); + var$4 = new jur_HangulDecomposedCharSet; + $curSymb = jur_AbstractSet_counter; + jur_AbstractSet_counter = $curSymb + 1 | 0; + var$9 = new jl_AbstractStringBuilder; + var$9.$buffer = $rt_createCharArray(20); + var$4.$index1 = (jl_AbstractStringBuilder_insert0(var$9, var$9.$length, $curSymb, 10)).$toString(); + var$4.$decomposedChar = $codePointsHangul; + var$4.$decomposedCharLength = 3; + return var$4; + } + var$9 = new jur_HangulDecomposedCharSet; + $readCodePoints = jur_AbstractSet_counter; + jur_AbstractSet_counter = $readCodePoints + 1 | 0; + var$4 = new jl_AbstractStringBuilder; + var$4.$buffer = $rt_createCharArray(20); + var$9.$index1 = (jl_AbstractStringBuilder_insert0(var$4, var$4.$length, $readCodePoints, 10)).$toString(); + var$9.$decomposedChar = $codePointsHangul; + var$9.$decomposedCharLength = 2; + return var$9; + } + $curSymb = $this.$flags; + if (!(($curSymb & 2) != 2 ? 0 : 1)) { + var$4 = new jur_CharSet; + $readCodePoints = $codePoints[0]; + jur_LeafSet__init_(var$4); + var$4.$ch0 = $readCodePoints; + return var$4; + } + if (($curSymb & 64) != 64 ? 0 : 1) + return jur_UCICharSet__init_($codePoints[0]); + return jur_CICharSet__init_($codePoints[0]); + } + $codePointsHangul = $codePoints.data; + $curSymb = 1; + while ($curSymb < 4 && !jur_Lexer_isEmpty($this.$lexemes) && jur_Lexer_isLetter($this.$lexemes)) { + $readCodePoints = $curSymb + 1 | 0; + $codePointsHangul[$curSymb] = jur_Lexer_next($this.$lexemes); + $curSymb = $readCodePoints; + } + if ($curSymb == 1 && !jur_Lexer_hasSingleCodepointDecomposition($codePointsHangul[0])) + return jur_Pattern_processCharSet($this, $codePointsHangul[0]); + if (!jur_Pattern_hasFlag($this, 2)) + return jur_DecomposedCharSet__init_($codePoints, $curSymb); + if (jur_Pattern_hasFlag($this, 64)) + return jur_UCIDecomposedCharSet__init_($codePoints, $curSymb); + return jur_CIDecomposedCharSet__init_($codePoints, $curSymb); +} +function jur_Pattern_processSubExpression($this, $last) { + var $term, var$3, var$4, $cur, $next, var$7; + $term = $this.$lexemes; + var$3 = $term.$ch; + var$4 = !var$3 && !$term.$lookAhead && $term.$index == $term.$patternFullLength && !($term.$curST === null ? 0 : 1) ? 1 : 0; + var$4 = !var$4 && !($term.$curST === null ? 0 : 1) && (var$3 < 0 ? 0 : 1) ? 1 : 0; + if (var$4 && !($term.$lookAheadST === null ? 0 : 1) && ($term.$lookAhead < 0 ? 0 : 1)) { + if (!(($this.$flags & 128) != 128 ? 0 : 1)) { + var$4 = var$3 <= 56319 && var$3 >= 55296 ? 1 : 0; + $cur = !var$4 && !jur_Lexer_isLowSurrogate($term) ? jur_Pattern_processSequence($this) : jur_Pattern_processQuantifier($this, $last, jur_Pattern_processTerminal($this, $last)); + } else { + $cur = jur_Pattern_processDecomposedChar($this); + $next = $this.$lexemes; + var$3 = $next.$ch; + if (!(!var$3 && !$next.$lookAhead && $next.$index == $next.$patternFullLength && !($next.$curST === null ? 0 : 1) ? 1 : 0) && !(var$3 == (-536870871) && !($last instanceof jur_FinalSet)) && var$3 != (-536870788)) { + var$4 = !var$3 && !$next.$lookAhead && $next.$index == $next.$patternFullLength && !($next.$curST === null ? 0 : 1) ? 1 : 0; + if (!(!var$4 && !($next.$curST === null ? 0 : 1) && (var$3 < 0 ? 0 : 1) ? 1 : 0)) + $cur = jur_Pattern_processQuantifier($this, $last, $cur); + } + } + } else if (var$3 != (-536870871)) + $cur = jur_Pattern_processQuantifier($this, $last, jur_Pattern_processTerminal($this, $last)); + else { + if ($last instanceof jur_FinalSet) + $rt_throw(jur_PatternSyntaxException__init_($rt_s(47), jur_Lexer_toString($term), jur_Lexer_getIndex($this.$lexemes))); + $cur = new jur_EmptySet; + jur_LeafSet__init_0($cur, $last); + $cur.$charCount = 0; + } + $term = $this.$lexemes; + var$4 = $term.$ch; + var$7 = !var$4 && !$term.$lookAhead && $term.$index == $term.$patternFullLength && !($term.$curST === null ? 0 : 1) ? 1 : 0; + if (!var$7 && !(var$4 == (-536870871) && !($last instanceof jur_FinalSet)) && var$4 != (-536870788)) { + $next = jur_Pattern_processSubExpression($this, $last); + if ($cur instanceof jur_LeafQuantifierSet && !($cur instanceof jur_CompositeQuantifierSet) && !($cur instanceof jur_GroupQuantifierSet) && !($cur instanceof jur_AltQuantifierSet)) { + $term = $cur; + if (!$next.$first($term.$innerSet)) + $cur = jur_UnifiedQuantifierSet__init_($term); + } + if (($next.$getType0() & 65535) != 43) + $cur.$setNext($next); + else + $cur.$setNext($next.$innerSet); + } else { + if ($cur === null) + return null; + $cur.$setNext($last); + } + if (($cur.$getType0() & 65535) != 43) + return $cur; + return $cur.$innerSet; +} +function jur_Pattern_processQuantifier($this, $last, $term) { + var $q, $quant, var$5, $leaf, $q_0; + $q = $this.$lexemes; + $quant = $q.$ch; + if ($term !== null && !($term instanceof jur_LeafSet)) { + switch ($quant) { + case -2147483606: + jur_Lexer_movePointer($q); + $q = new jur_PossessiveGroupQuantifierSet; + var$5 = jur_AbstractSet_counter; + jur_AbstractSet_counter = var$5 + 1 | 0; + $leaf = new jl_AbstractStringBuilder; + jl_Object__init_0($leaf); + $leaf.$buffer = $rt_createCharArray(20); + $q.$index1 = (jl_AbstractStringBuilder_insert0($leaf, $leaf.$length, var$5, 10)).$toString(); + $q.$next0 = $last; + $q.$innerSet = $term; + $q.$type = $quant; + jur_FSet_$callClinit(); + $term.$setNext(jur_FSet_posFSet); + return $q; + case -2147483605: + jur_Lexer_movePointer($q); + $q = new jur_PosPlusGroupQuantifierSet; + $quant = jur_AbstractSet_counter; + jur_AbstractSet_counter = $quant + 1 | 0; + $leaf = new jl_AbstractStringBuilder; + jl_Object__init_0($leaf); + $leaf.$buffer = $rt_createCharArray(20); + $q.$index1 = (jl_AbstractStringBuilder_insert0($leaf, $leaf.$length, $quant, 10)).$toString(); + $q.$next0 = $last; + $q.$innerSet = $term; + $q.$type = (-2147483606); + jur_FSet_$callClinit(); + $term.$setNext(jur_FSet_posFSet); + return $q; + case -2147483585: + jur_Lexer_movePointer($q); + $q = new jur_PosAltGroupQuantifierSet; + $quant = jur_AbstractSet_counter; + jur_AbstractSet_counter = $quant + 1 | 0; + $q.$index1 = (jl_AbstractStringBuilder_append0(jl_AbstractStringBuilder__init_1(20), $quant, 10)).$toString(); + $q.$next0 = $last; + $q.$innerSet = $term; + $q.$type = (-536870849); + jur_FSet_$callClinit(); + $term.$setNext(jur_FSet_posFSet); + return $q; + case -2147483525: + $leaf = new jur_PosCompositeGroupQuantifierSet; + $q_0 = $q.$curST; + jur_Lexer_movePointer($q); + $q = $q_0; + var$5 = $this.$compCount + 1 | 0; + $this.$compCount = var$5; + jur_AbstractSet__init_0($leaf, $last); + $leaf.$innerSet = $term; + $leaf.$type = (-536870849); + $leaf.$quantifier = $q; + $leaf.$setCounter = var$5; + jur_FSet_$callClinit(); + $term.$setNext(jur_FSet_posFSet); + return $leaf; + case -1073741782: + case -1073741781: + jur_Lexer_next($q); + $q = jur_ReluctantGroupQuantifierSet__init_($term, $last, $quant); + $term.$setNext($q); + return $q; + case -1073741761: + jur_Lexer_next($q); + $q = jur_RelAltGroupQuantifierSet__init_($term, $last, (-536870849)); + $term.$setNext($last); + return $q; + case -1073741701: + $q_0 = new jur_RelCompositeGroupQuantifierSet; + $q = jur_Lexer_nextSpecial($q); + $quant = $this.$compCount + 1 | 0; + $this.$compCount = $quant; + jur_RelCompositeGroupQuantifierSet__init_($q_0, $q, $term, $last, (-536870849), $quant); + $term.$setNext($q_0); + return $q_0; + case -536870870: + case -536870869: + jur_Lexer_next($q); + $q = $term.$getType0() != (-2147483602) ? jur_GroupQuantifierSet__init_($term, $last, $quant) : jur_Pattern_hasFlag($this, 32) ? jur_DotAllQuantifierSet__init_($term, $last, $quant) : jur_DotQuantifierSet__init_($term, $last, $quant, jur_AbstractLineTerminator_getInstance($this.$flags)); + $term.$setNext($q); + return $q; + case -536870849: + jur_Lexer_next($q); + $q = jur_AltGroupQuantifierSet__init_($term, $last, (-536870849)); + $term.$setNext($last); + return $q; + case -536870789: + $q_0 = new jur_CompositeGroupQuantifierSet; + $q = jur_Lexer_nextSpecial($q); + $quant = $this.$compCount + 1 | 0; + $this.$compCount = $quant; + jur_CompositeGroupQuantifierSet__init_($q_0, $q, $term, $last, (-536870849), $quant); + $term.$setNext($q_0); + return $q_0; + default: + } + return $term; + } + $leaf = null; + if ($term !== null) + $leaf = $term; + switch ($quant) { + case -2147483606: + case -2147483605: + jur_Lexer_next($q); + $q = jur_PossessiveQuantifierSet__init_($leaf, $last, $quant); + jur_AbstractSet_setNext($leaf, $q); + return $q; + case -2147483585: + jur_Lexer_next($q); + return jur_PossessiveAltQuantifierSet__init_($leaf, $last, (-2147483585)); + case -2147483525: + return jur_PossessiveCompositeQuantifierSet__init_(jur_Lexer_nextSpecial($q), $leaf, $last, (-2147483525)); + case -1073741782: + case -1073741781: + jur_Lexer_next($q); + $q = jur_ReluctantQuantifierSet__init_($leaf, $last, $quant); + jur_AbstractSet_setNext($leaf, $q); + return $q; + case -1073741761: + jur_Lexer_next($q); + return jur_ReluctantAltQuantifierSet__init_($leaf, $last, (-1073741761)); + case -1073741701: + return jur_ReluctantCompositeQuantifierSet__init_(jur_Lexer_nextSpecial($q), $leaf, $last, (-1073741701)); + case -536870870: + case -536870869: + jur_Lexer_next($q); + $q = jur_LeafQuantifierSet__init_($leaf, $last, $quant); + jur_AbstractSet_setNext($leaf, $q); + return $q; + case -536870849: + jur_Lexer_next($q); + return jur_AltQuantifierSet__init_($leaf, $last, (-536870849)); + case -536870789: + return jur_CompositeQuantifierSet__init_(jur_Lexer_nextSpecial($q), $leaf, $last, (-536870789)); + default: + } + return $term; +} +function jur_Pattern_processTerminal($this, $last) { + var $term, var$3, $cc, $ch, $newFlags, var$7, $negative, $number; + $term = null; + var$3 = $last instanceof jur_FinalSet; + while (true) { + a: { + $cc = $this.$lexemes; + $ch = $cc.$ch; + if (($ch & (-2147418113)) == (-2147483608)) { + jur_Lexer_movePointer($cc); + $newFlags = ($ch & 16711680) >> 16; + $ch = $ch & (-16711681); + if ($ch == (-16777176)) + $this.$flags = $newFlags; + else { + if ($ch != (-1073741784)) + $newFlags = $this.$flags; + $term = jur_Pattern_processExpression($this, $ch, $newFlags, $last); + $cc = $this.$lexemes; + if ($cc.$ch != (-536870871)) { + $last = new jur_PatternSyntaxException; + var$7 = $cc.$orig; + $negative = $cc.$curToc; + $last.$suppressionEnabled = 1; + $last.$writableStackTrace = 1; + $last.$index0 = (-1); + $last.$desc = $rt_s(47); + $last.$pattern = var$7; + $last.$index0 = $negative; + $rt_throw($last); + } + jur_Lexer_movePointer($cc); + } + } else { + b: { + c: { + switch ($ch) { + case -2147483599: + case -2147483598: + case -2147483597: + case -2147483596: + case -2147483595: + case -2147483594: + case -2147483593: + case -2147483592: + case -2147483591: + break c; + case -2147483583: + jur_Lexer_next($cc); + $term = new jur_SOLSet; + jur_AbstractSet__init_($term); + break a; + case -2147483582: + jur_Lexer_next($cc); + $term = jur_WordBoundary__init_(0); + break a; + case -2147483577: + break; + case -2147483558: + jur_Lexer_next($cc); + $term = new jur_EOLSet; + $number = $this.$consCount + 1 | 0; + $this.$consCount = $number; + jur_EOLSet__init_($term, $number); + break a; + case -2147483550: + jur_Lexer_next($cc); + $term = jur_WordBoundary__init_(1); + break a; + case -2147483526: + jur_Lexer_next($cc); + $term = jur_EOISet__init_(); + break a; + case -536870876: + jur_Lexer_next($cc); + $this.$consCount = $this.$consCount + 1 | 0; + if (jur_Pattern_hasFlag($this, 8)) { + if (jur_Pattern_hasFlag($this, 1)) { + $term = jur_UMultiLineEOLSet__init_($this.$consCount); + break a; + } + $term = jur_MultiLineEOLSet__init_($this.$consCount); + break a; + } + if (jur_Pattern_hasFlag($this, 1)) { + $term = jur_UEOLSet__init_($this.$consCount); + break a; + } + $term = jur_EOLSet__init_0($this.$consCount); + break a; + case -536870866: + jur_Lexer_next($cc); + if (jur_Pattern_hasFlag($this, 32)) { + $term = jur_DotAllSet__init_(); + break a; + } + $term = jur_DotSet__init_(jur_AbstractLineTerminator_getInstance($this.$flags)); + break a; + case -536870821: + jur_Lexer_next($cc); + $negative = 0; + if (jur_Lexer_peek($this.$lexemes) == (-536870818)) { + $negative = 1; + jur_Lexer_next($this.$lexemes); + } + $term = jur_Pattern_processRange($this, $negative, $last); + if (jur_Lexer_peek($this.$lexemes) != (-536870819)) + $rt_throw(jur_PatternSyntaxException__init_($rt_s(47), jur_Lexer_toString($this.$lexemes), jur_Lexer_getIndex($this.$lexemes))); + jur_Lexer_setMode($this.$lexemes, 1); + jur_Lexer_next($this.$lexemes); + break a; + case -536870818: + jur_Lexer_next($cc); + $this.$consCount = $this.$consCount + 1 | 0; + if (!jur_Pattern_hasFlag($this, 8)) { + $term = jur_SOLSet__init_(); + break a; + } + $term = jur_MultiLineSOLSet__init_(jur_AbstractLineTerminator_getInstance($this.$flags)); + break a; + case 0: + $cc = jur_Lexer_peekSpecial($cc); + if ($cc !== null) + $term = jur_Pattern_processRangeSet($this, $cc); + else { + if (jur_Lexer_isEmpty($this.$lexemes)) { + $term = jur_EmptySet__init_($last); + break a; + } + $term = jur_CharSet__init_($ch & 65535); + } + jur_Lexer_next($this.$lexemes); + break a; + default: + break b; + } + jur_Lexer_next($cc); + $term = jur_PreviousMatch__init_(); + break a; + } + $number = ($ch & 2147483647) - 48 | 0; + if ($this.$globalGroupIndex < $number) + $rt_throw(jur_PatternSyntaxException__init_($rt_s(47), jur_Lexer_toString($cc), jur_Lexer_getIndex($this.$lexemes))); + jur_Lexer_next($cc); + $this.$consCount = $this.$consCount + 1 | 0; + $term = !jur_Pattern_hasFlag($this, 2) ? jur_BackReferenceSet__init_($number, $this.$consCount) : jur_Pattern_hasFlag($this, 64) ? jur_UCIBackReferenceSet__init_($number, $this.$consCount) : jur_CIBackReferenceSet__init_($number, $this.$consCount); + $this.$backRefs.data[$number].$isBackReferenced = 1; + $this.$needsBackRefReplacement = 1; + break a; + } + if ($ch >= 0 && !jur_Lexer_isSpecial($cc)) { + $term = jur_Pattern_processCharSet($this, $ch); + jur_Lexer_next($this.$lexemes); + } else if ($ch == (-536870788)) + $term = jur_EmptySet__init_($last); + else { + if ($ch != (-536870871)) + $rt_throw(jur_PatternSyntaxException__init_(!jur_Lexer_isSpecial($this.$lexemes) ? jl_Character_toString($ch & 65535) : (jur_Lexer_peekSpecial($this.$lexemes)).$toString(), jur_Lexer_toString($this.$lexemes), jur_Lexer_getIndex($this.$lexemes))); + if (var$3) + $rt_throw(jur_PatternSyntaxException__init_($rt_s(47), jur_Lexer_toString($this.$lexemes), jur_Lexer_getIndex($this.$lexemes))); + $term = jur_EmptySet__init_($last); + } + } + } + if ($ch != (-16777176)) + break; + } + return $term; +} +function jur_Pattern_processRange($this, $negative, $last) { + var $rangeSet; + $rangeSet = jur_Pattern_processRangeSet($this, jur_Pattern_processRangeExpression($this, $negative)); + $rangeSet.$setNext($last); + return $rangeSet; +} +function jur_Pattern_processRangeExpression($this, $alt) { + var $res, $cur, $negative, $cs, $buffer, $intersection, $notClosed, $firstInClass, var$10, var$11, $$je; + $res = new jur_CharClass; + $cur = $this.$flags; + $negative = ($cur & 2) != 2 ? 0 : 1; + $cur = ($cur & 64) != 64 ? 0 : 1; + $cs = new ju_BitSet; + $cs.$data0 = $rt_createIntArray(64); + $res.$lowHighSurrogates = $cs; + $cs = new ju_BitSet; + $cs.$data0 = $rt_createIntArray(0); + $res.$bits = $cs; + $res.$ci = $negative; + $res.$uci = $cur; + jur_AbstractCharClass_setNegative($res, $alt); + $buffer = (-1); + $intersection = 0; + $notClosed = 0; + $firstInClass = 1; + a: { + b: { + c: while (true) { + var$10 = $this.$lexemes; + $alt = var$10.$ch; + if (!$alt && !var$10.$lookAhead && var$10.$index == var$10.$patternFullLength && !(var$10.$curST === null ? 0 : 1) ? 1 : 0) + break a; + $notClosed = $alt == (-536870819) && !$firstInClass ? 0 : 1; + if (!$notClosed) + break a; + d: { + switch ($alt) { + case -536870874: + if ($buffer >= 0) + jur_CharClass_add($res, $buffer); + $buffer = jur_Lexer_next($this.$lexemes); + if (jur_Lexer_peek($this.$lexemes) != (-536870874)) { + $buffer = 38; + break d; + } + if (jur_Lexer_lookAhead($this.$lexemes) == (-536870821)) { + jur_Lexer_next($this.$lexemes); + $intersection = 1; + $buffer = (-1); + break d; + } + jur_Lexer_next($this.$lexemes); + if ($firstInClass) { + $res = jur_Pattern_processRangeExpression($this, 0); + break d; + } + if (jur_Lexer_peek($this.$lexemes) == (-536870819)) + break d; + jur_CharClass_intersection($res, jur_Pattern_processRangeExpression($this, 0)); + break d; + case -536870867: + if (!$firstInClass && jur_Lexer_lookAhead(var$10) != (-536870819) && jur_Lexer_lookAhead($this.$lexemes) != (-536870821) && $buffer >= 0) { + jur_Lexer_next($this.$lexemes); + $cur = jur_Lexer_peek($this.$lexemes); + if (jur_Lexer_isSpecial($this.$lexemes)) + break c; + if ($cur < 0 && jur_Lexer_lookAhead($this.$lexemes) != (-536870819) && jur_Lexer_lookAhead($this.$lexemes) != (-536870821) && $buffer >= 0) + break c; + e: { + try { + if (jur_Lexer_isLetter0($cur)) + break e; + $cur = $cur & 65535; + break e; + } catch ($$e) { + $$je = $rt_wrapException($$e); + if ($$je instanceof jl_Exception) { + break b; + } else { + throw $$e; + } + } + } + try { + jur_CharClass_add0($res, $buffer, $cur); + } catch ($$e) { + $$je = $rt_wrapException($$e); + if ($$je instanceof jl_Exception) { + break b; + } else { + throw $$e; + } + } + jur_Lexer_next($this.$lexemes); + $buffer = (-1); + break d; + } + if ($buffer >= 0) + jur_CharClass_add($res, $buffer); + $buffer = 45; + jur_Lexer_next($this.$lexemes); + break d; + case -536870821: + if ($buffer >= 0) { + jur_CharClass_add($res, $buffer); + $buffer = (-1); + } + jur_Lexer_movePointer($this.$lexemes); + $negative = 0; + $cs = $this.$lexemes; + if ($cs.$ch == (-536870818)) { + jur_Lexer_movePointer($cs); + $negative = 1; + } + if (!$intersection) + jur_CharClass_union($res, jur_Pattern_processRangeExpression($this, $negative)); + else + jur_CharClass_intersection($res, jur_Pattern_processRangeExpression($this, $negative)); + $intersection = 0; + jur_Lexer_next($this.$lexemes); + break d; + case -536870819: + break; + case -536870818: + if ($buffer >= 0) + jur_CharClass_add($res, $buffer); + $buffer = 94; + jur_Lexer_movePointer($this.$lexemes); + break d; + case 0: + if ($buffer >= 0) + jur_CharClass_add($res, $buffer); + $cs = $this.$lexemes.$curST; + if ($cs === null) + $buffer = 0; + else { + jur_CharClass_add1($res, $cs); + $buffer = (-1); + } + jur_Lexer_movePointer($this.$lexemes); + break d; + default: + if ($buffer >= 0) + jur_CharClass_add($res, $buffer); + $cs = $this.$lexemes; + jur_Lexer_movePointer($cs); + $buffer = $cs.$lookBack; + break d; + } + if ($buffer >= 0) + jur_CharClass_add($res, $buffer); + $buffer = 93; + jur_Lexer_movePointer($this.$lexemes); + } + $firstInClass = 0; + } + $rt_throw(jur_PatternSyntaxException__init_($rt_s(47), jur_Pattern_pattern($this), jur_Lexer_getIndex($this.$lexemes))); + } + $rt_throw(jur_PatternSyntaxException__init_($rt_s(47), jur_Pattern_pattern($this), jur_Lexer_getIndex($this.$lexemes))); + } + if (!$notClosed) { + if ($buffer >= 0) + jur_CharClass_add($res, $buffer); + return $res; + } + $res = new jur_PatternSyntaxException; + var$11 = var$10.$orig; + $alt = var$10.$curToc - 1 | 0; + $res.$suppressionEnabled = 1; + $res.$writableStackTrace = 1; + $res.$index0 = (-1); + $res.$desc = $rt_s(47); + $res.$pattern = var$11; + $res.$index0 = $alt; + $rt_throw($res); +} +function jur_Pattern_processCharSet($this, $ch) { + var $isSupplCodePoint, var$3, var$4, var$5, var$6; + $isSupplCodePoint = $ch >= 65536 && $ch <= 1114111 ? 1 : 0; + var$3 = $this.$flags; + if ((var$3 & 2) != 2 ? 0 : 1) { + a: { + if (!($ch >= 97 && $ch <= 122)) { + if ($ch < 65) + break a; + if ($ch > 90) + break a; + } + var$4 = new jur_CICharSet; + $ch = $ch & 65535; + var$5 = jur_AbstractSet_counter; + jur_AbstractSet_counter = var$5 + 1 | 0; + var$6 = new jl_AbstractStringBuilder; + var$6.$buffer = $rt_createCharArray(20); + var$4.$index1 = (jl_AbstractStringBuilder_insert0(var$6, var$6.$length, var$5, 10)).$toString(); + var$4.$charCount = 1; + var$4.$ch1 = $ch; + var$4.$supplement = jur_Pattern_getSupplement($ch); + return var$4; + } + if (((var$3 & 64) != 64 ? 0 : 1) && $ch > 128) { + if ($isSupplCodePoint) { + var$4 = new jur_UCISupplCharSet; + var$5 = jur_AbstractSet_counter; + jur_AbstractSet_counter = var$5 + 1 | 0; + var$6 = new jl_AbstractStringBuilder; + var$6.$buffer = $rt_createCharArray(20); + var$4.$index1 = (jl_AbstractStringBuilder_insert0(var$6, var$6.$length, var$5, 10)).$toString(); + var$4.$charCount = 1; + var$4.$charCount = 2; + var$4.$ch2 = (String.fromCharCode((String.fromCharCode($ch)).toUpperCase().charCodeAt(0))).toLowerCase().charCodeAt(0); + return var$4; + } + if ($ch <= 57343 && $ch >= 56320 ? 1 : 0) { + var$4 = new jur_LowSurrogateCharSet; + $ch = $ch & 65535; + var$5 = jur_AbstractSet_counter; + jur_AbstractSet_counter = var$5 + 1 | 0; + var$6 = new jl_AbstractStringBuilder; + var$6.$buffer = $rt_createCharArray(20); + var$4.$index1 = (jl_AbstractStringBuilder_insert0(var$6, var$6.$length, var$5, 10)).$toString(); + var$4.$low = $ch; + return var$4; + } + if ($ch <= 56319 && $ch >= 55296 ? 1 : 0) + return jur_HighSurrogateCharSet__init_($ch & 65535); + var$4 = new jur_UCICharSet; + $ch = $ch & 65535; + var$5 = jur_AbstractSet_counter; + jur_AbstractSet_counter = var$5 + 1 | 0; + var$4.$index1 = jl_Integer_toString(var$5, 10); + var$4.$charCount = 1; + var$4.$ch3 = jl_Character_toLowerCase((otp_Platform_stringFromCharCode($ch)).toUpperCase().charCodeAt(0) & 65535); + return var$4; + } + } + if ($isSupplCodePoint) + return jur_SupplCharSet__init_($ch); + if (jur_Lexer_isLowSurrogate0($ch)) + return jur_LowSurrogateCharSet__init_($ch & 65535); + if (!jur_Lexer_isHighSurrogate($ch)) + return jur_CharSet__init_($ch & 65535); + return jur_HighSurrogateCharSet__init_($ch & 65535); +} +function jur_Pattern_processRangeSet($this, $charClass) { + var $surrogates, $lowHighSurrRangeSet, var$4, var$5, var$6, var$7; + if (!jur_AbstractCharClass_hasLowHighSurrogates($charClass)) { + if (!$charClass.$mayContainSupplCodepoints) { + if ($charClass.$hasUCI()) + return jur_UCIRangeSet__init_($charClass); + return jur_RangeSet__init_($charClass); + } + if (!$charClass.$hasUCI()) + return jur_SupplRangeSet__init_($charClass); + $surrogates = new jur_UCISupplRangeSet; + jur_SupplRangeSet__init_0($surrogates, $charClass); + return $surrogates; + } + $surrogates = jur_AbstractCharClass_getSurrogates($charClass); + $lowHighSurrRangeSet = new jur_LowHighSurrogateRangeSet; + var$4 = jur_AbstractSet_counter; + jur_AbstractSet_counter = var$4 + 1 | 0; + var$5 = new jl_AbstractStringBuilder; + var$5.$buffer = $rt_createCharArray(20); + $lowHighSurrRangeSet.$index1 = (jl_AbstractStringBuilder_insert0(var$5, var$5.$length, var$4, 10)).$toString(); + $lowHighSurrRangeSet.$surrChars = $surrogates; + $lowHighSurrRangeSet.$alt = $surrogates.$alt0; + if (!$charClass.$mayContainSupplCodepoints) { + if (!$charClass.$hasUCI()) + return jur_CompositeRangeSet__init_(jur_RangeSet__init_(jur_AbstractCharClass_getWithoutSurrogates($charClass)), $lowHighSurrRangeSet); + $surrogates = new jur_CompositeRangeSet; + var$5 = new jur_UCIRangeSet; + $charClass = jur_AbstractCharClass_getWithoutSurrogates($charClass); + var$4 = jur_AbstractSet_counter; + jur_AbstractSet_counter = var$4 + 1 | 0; + var$6 = new jl_AbstractStringBuilder; + var$6.$buffer = $rt_createCharArray(20); + var$5.$index1 = (jl_AbstractStringBuilder_insert0(var$6, var$6.$length, var$4, 10)).$toString(); + var$5.$charCount = 1; + var$5.$chars = $charClass; + var$5.$alt1 = $charClass.$alt0; + jur_CompositeRangeSet__init_0($surrogates, var$5, $lowHighSurrRangeSet); + return $surrogates; + } + if (!$charClass.$hasUCI()) { + $surrogates = new jur_CompositeRangeSet; + var$5 = new jur_SupplRangeSet; + var$6 = jur_AbstractCharClass_getWithoutSurrogates($charClass); + var$4 = jur_AbstractSet_counter; + jur_AbstractSet_counter = var$4 + 1 | 0; + $charClass = new jl_AbstractStringBuilder; + $charClass.$buffer = $rt_createCharArray(20); + var$5.$index1 = (jl_AbstractStringBuilder_insert0($charClass, $charClass.$length, var$4, 10)).$toString(); + var$5.$chars0 = var$6; + var$5.$alt2 = var$6.$alt0; + var$7 = jur_AbstractSet_counter; + jur_AbstractSet_counter = var$7 + 1 | 0; + $charClass = new jl_AbstractStringBuilder; + $charClass.$buffer = $rt_createCharArray(20); + $surrogates.$index1 = (jl_AbstractStringBuilder_insert0($charClass, $charClass.$length, var$7, 10)).$toString(); + $surrogates.$withoutSurrogates = var$5; + $surrogates.$withSurrogates = $lowHighSurrRangeSet; + return $surrogates; + } + $surrogates = new jur_CompositeRangeSet; + var$5 = new jur_UCISupplRangeSet; + $charClass = jur_AbstractCharClass_getWithoutSurrogates($charClass); + var$4 = jur_AbstractSet_counter; + jur_AbstractSet_counter = var$4 + 1 | 0; + var$6 = new jl_AbstractStringBuilder; + jl_Object__init_0(var$6); + var$6.$buffer = $rt_createCharArray(20); + var$5.$index1 = (jl_AbstractStringBuilder_insert0(var$6, var$6.$length, var$4, 10)).$toString(); + var$5.$chars0 = $charClass; + var$5.$alt2 = $charClass.$alt0; + var$4 = jur_AbstractSet_counter; + jur_AbstractSet_counter = var$4 + 1 | 0; + $charClass = new jl_AbstractStringBuilder; + $charClass.$buffer = $rt_createCharArray(20); + $surrogates.$index1 = (jl_AbstractStringBuilder_insert0($charClass, $charClass.$length, var$4, 10)).$toString(); + $surrogates.$withoutSurrogates = var$5; + $surrogates.$withSurrogates = $lowHighSurrRangeSet; + return $surrogates; +} +function jur_Pattern_getSupplement($ch) { + if ($ch >= 97 && $ch <= 122) + $ch = ($ch - 32 | 0) & 65535; + else if ($ch >= 65 && $ch <= 90) + $ch = ($ch + 32 | 0) & 65535; + return $ch; +} +function jur_Pattern_hasFlag($this, $flag) { + return ($this.$flags & $flag) != $flag ? 0 : 1; +} +var ju_Arrays = $rt_classWithoutFields(); +var otji_IDBObjectStoreParameters = $rt_classWithoutFields(); +function otji_IDBObjectStoreParameters_create$js_body$_1() { + return { }; +} +function jnci_BufferedEncoder() { + var a = this; jnc_CharsetEncoder.call(a); + a.$inArray = null; + a.$outArray = null; +} +function jnci_BufferedEncoder_encodeLoop($this, $in, $out) { + var $inArray, $inPos, $inSize, $outArray, $outSize, var$8, $i, var$10, $outPos, $outSize_0, $result, $controller; + $inArray = $this.$inArray; + $inPos = 0; + $inSize = 0; + $outArray = $this.$outArray; + a: { + while (true) { + if (($inPos + 32 | 0) > $inSize) { + $outSize = $in.$position; + var$8 = $in.$limit; + if ($outSize >= var$8 ? 0 : 1) { + $i = $inPos; + while ($i < $inSize) { + var$10 = $inArray.data; + var$10[$i - $inPos | 0] = var$10[$i]; + $i = $i + 1 | 0; + } + var$10 = $inArray.data; + $i = $inSize - $inPos | 0; + $outPos = (var$8 - $outSize | 0) + $i | 0; + $inSize = var$10.length; + if ($outPos < $inSize) + $inSize = $outPos; + jn_CharBuffer_get($in, $inArray, $i, $inSize - $i | 0); + $inPos = 0; + } + } + $i = $out.$position; + $outSize_0 = $out.$limit; + if (!($i >= $outSize_0 ? 0 : 1)) { + $i = $in.$position >= $in.$limit ? 0 : 1; + $result = !$i && $inPos >= $inSize ? jnc_CoderResult_UNDERFLOW : jnc_CoderResult_OVERFLOW; + break a; + } + var$10 = $outArray.data; + $outSize = $outSize_0 - $i | 0; + $outSize_0 = var$10.length; + if ($outSize < $outSize_0) + $outSize_0 = $outSize; + $controller = new jnci_BufferedEncoder$Controller; + $controller.$in = $in; + $controller.$out1 = $out; + $result = jnci_UTF8Encoder_arrayEncode($this, $inArray, $inPos, $inSize, $outArray, 0, $outSize_0, $controller); + $inPos = $controller.$inPosition; + $outPos = $controller.$outPosition; + if ($result === null) { + $i = $in.$position >= $in.$limit ? 0 : 1; + if (!$i && $inPos >= $inSize) + $result = jnc_CoderResult_UNDERFLOW; + else if (!($out.$position >= $out.$limit ? 0 : 1) && $inPos >= $inSize) + $result = jnc_CoderResult_OVERFLOW; + } + jn_ByteBuffer_put($out, $outArray, 0, $outPos); + if ($result !== null) + break; + } + } + jn_Buffer_position($in, $in.$position - ($inSize - $inPos | 0) | 0); + return $result; +} +var jnci_UTF8Encoder = $rt_classWithoutFields(jnci_BufferedEncoder); +function jnci_UTF8Encoder_arrayEncode($this, $inArray, $inPos, $inSize, $outArray, $outPos, $outSize, $controller) { + var $result, var$9, var$10, $ch, $low, var$13, $codePoint, var$15; + $result = null; + a: { + while ($inPos < $inSize) { + if ($outPos >= $outSize) { + var$9 = $inPos; + break a; + } + var$10 = $inArray.data; + var$9 = $inPos + 1 | 0; + $ch = var$10[$inPos]; + if ($ch < 128) { + var$10 = $outArray.data; + $low = $outPos + 1 | 0; + var$10[$outPos] = $ch << 24 >> 24; + } else if ($ch < 2048) { + if (($outPos + 2 | 0) > $outSize) { + var$9 = var$9 + (-1) | 0; + var$13 = $controller.$out1; + if ((var$13.$limit - var$13.$position | 0) < 2 ? 0 : 1) + break a; + $result = jnc_CoderResult_OVERFLOW; + break a; + } + var$10 = $outArray.data; + $inPos = $outPos + 1 | 0; + var$10[$outPos] = (192 | $ch >> 6) << 24 >> 24; + $low = $inPos + 1 | 0; + var$10[$inPos] = (128 | $ch & 63) << 24 >> 24; + } else { + $codePoint = $ch & 64512; + $low = $rt_compare($codePoint, 55296); + $inPos = $low ? 0 : 1; + if (!(!$inPos && !($codePoint != 56320 ? 0 : 1) ? 0 : 1)) { + if (($outPos + 3 | 0) > $outSize) { + var$9 = var$9 + (-1) | 0; + var$13 = $controller.$out1; + if ((var$13.$limit - var$13.$position | 0) < 3 ? 0 : 1) + break a; + $result = jnc_CoderResult_OVERFLOW; + break a; + } + var$10 = $outArray.data; + $inPos = $outPos + 1 | 0; + var$10[$outPos] = (224 | $ch >> 12) << 24 >> 24; + $outPos = $inPos + 1 | 0; + var$10[$inPos] = (128 | $ch >> 6 & 63) << 24 >> 24; + $low = $outPos + 1 | 0; + var$10[$outPos] = (128 | $ch & 63) << 24 >> 24; + } else { + if (!($low ? 0 : 1)) { + $result = new jnc_CoderResult; + $result.$kind = 2; + $result.$length0 = 1; + break a; + } + if (var$9 >= $inSize) { + var$13 = $controller.$in; + if (var$13.$position >= var$13.$limit ? 0 : 1) + break a; + $result = jnc_CoderResult_UNDERFLOW; + break a; + } + var$15 = var$9 + 1 | 0; + $low = var$10[var$9]; + if (!(($low & 64512) != 56320 ? 0 : 1)) { + var$9 = var$15 + (-2) | 0; + $result = new jnc_CoderResult; + $result.$kind = 2; + $result.$length0 = 1; + break a; + } + if (($outPos + 4 | 0) > $outSize) { + var$9 = var$15 + (-2) | 0; + var$13 = $controller.$out1; + if ((var$13.$limit - var$13.$position | 0) < 4 ? 0 : 1) + break a; + $result = jnc_CoderResult_OVERFLOW; + break a; + } + var$10 = $outArray.data; + $codePoint = (($ch & 1023) << 10 | $low & 1023) + 65536 | 0; + $low = $outPos + 1 | 0; + var$10[$outPos] = (240 | $codePoint >> 18) << 24 >> 24; + $inPos = $low + 1 | 0; + var$10[$low] = (128 | $codePoint >> 12 & 63) << 24 >> 24; + $outPos = $inPos + 1 | 0; + var$10[$inPos] = (128 | $codePoint >> 6 & 63) << 24 >> 24; + $low = $outPos + 1 | 0; + var$10[$outPos] = (128 | $codePoint & 63) << 24 >> 24; + var$9 = var$15; + } + } + $inPos = var$9; + $outPos = $low; + } + var$9 = $inPos; + } + $controller.$inPosition = var$9; + $controller.$outPosition = $outPos; + return $result; +} +var ji_IOException = $rt_classWithoutFields(jl_Exception); +var jlr_Array = $rt_classWithoutFields(); +function jlr_Array_getLength(var$1) { + if (var$1 === null || var$1.constructor.$meta.item === undefined) { + $rt_throw(jl_IllegalArgumentException__init_()); + } + return var$1.data.length; +} +function jlr_Array_newInstanceImpl(var$1, var$2) { + if (var$1.$meta.primitive) { + if (var$1 == $rt_bytecls()) { + return $rt_createByteArray(var$2); + } + if (var$1 == $rt_shortcls()) { + return $rt_createShortArray(var$2); + } + if (var$1 == $rt_charcls()) { + return $rt_createCharArray(var$2); + } + if (var$1 == $rt_intcls()) { + return $rt_createIntArray(var$2); + } + if (var$1 == $rt_longcls()) { + return $rt_createLongArray(var$2); + } + if (var$1 == $rt_floatcls()) { + return $rt_createFloatArray(var$2); + } + if (var$1 == $rt_doublecls()) { + return $rt_createDoubleArray(var$2); + } + if (var$1 == $rt_booleancls()) { + return $rt_createBooleanArray(var$2); + } + } else { + return $rt_createArray(var$1, var$2) + } +} +var jl_NullPointerException = $rt_classWithoutFields(jl_RuntimeException); +function jur_AbstractSet() { + var a = this; jl_Object.call(a); + a.$next0 = null; + a.$isSecondPassVisited = 0; + a.$index1 = null; + a.$type = 0; +} +var jur_AbstractSet_counter = 0; +function jur_AbstractSet__init_($this) { + var var$1, var$2; + var$1 = jur_AbstractSet_counter; + jur_AbstractSet_counter = var$1 + 1 | 0; + var$2 = new jl_AbstractStringBuilder; + var$2.$buffer = $rt_createCharArray(20); + $this.$index1 = (jl_AbstractStringBuilder_insert0(var$2, var$2.$length, var$1, 10)).$toString(); +} +function jur_AbstractSet__init_0($this, $n) { + var var$2, var$3; + var$2 = jur_AbstractSet_counter; + jur_AbstractSet_counter = var$2 + 1 | 0; + var$3 = new jl_AbstractStringBuilder; + var$3.$buffer = $rt_createCharArray(20); + $this.$index1 = (jl_AbstractStringBuilder_insert0(var$3, var$3.$length, var$2, 10)).$toString(); + $this.$next0 = $n; +} +function jur_AbstractSet_find($this, $stringIndex, $testString, $matchResult) { + var $length; + $length = $matchResult.$rightBound; + while (true) { + if ($stringIndex > $length) + return (-1); + if ($this.$matches($stringIndex, $testString, $matchResult) >= 0) + break; + $stringIndex = $stringIndex + 1 | 0; + } + return $stringIndex; +} +function jur_AbstractSet_findBack($this, $stringIndex, $startSearch, $testString, $matchResult) { + while (true) { + if ($startSearch < $stringIndex) + return (-1); + if ($this.$matches($startSearch, $testString, $matchResult) >= 0) + break; + $startSearch = $startSearch + (-1) | 0; + } + return $startSearch; +} +function jur_AbstractSet_setType($this, $type) { + $this.$type = $type; +} +function jur_AbstractSet_getType($this) { + return $this.$type; +} +function jur_AbstractSet_getNext($this) { + return $this.$next0; +} +function jur_AbstractSet_setNext($this, $next) { + $this.$next0 = $next; +} +function jur_AbstractSet_first($this, $set) { + return 1; +} +function jur_AbstractSet_processBackRefReplacement($this) { + return null; +} +function jur_AbstractSet_processSecondPass($this) { + var $set; + $this.$isSecondPassVisited = 1; + $set = $this.$next0; + if ($set !== null) { + if (!$set.$isSecondPassVisited) { + $set = $set.$processBackRefReplacement(); + if ($set !== null) { + $this.$next0.$isSecondPassVisited = 1; + $this.$next0 = $set; + } + $this.$next0.$processSecondPass(); + } else if ($set instanceof jur_SingleSet && $set.$fSet.$isBackReferenced) + $this.$next0 = $set.$next0; + } +} +function jur_AbstractSet__clinit_() { + jur_AbstractSet_counter = 1; +} +var jl_NegativeArraySizeException = $rt_classWithoutFields(jl_RuntimeException); +var otjc_JSArray = $rt_classWithoutFields(); +function otjc_JSArray_get$exported$0(var$0, var$1) { + return var$0.$get(var$1); +} +function otjc_JSArray_getLength$exported$1(var$0) { + return var$0.$getLength0(); +} +var otjc_JSString = $rt_classWithoutFields(); +function jur_FSet() { + var a = this; jur_AbstractSet.call(a); + a.$isBackReferenced = 0; + a.$groupIndex = 0; +} +var jur_FSet_posFSet = null; +function jur_FSet_$callClinit() { + jur_FSet_$callClinit = $rt_eraseClinit(jur_FSet); + jur_FSet__clinit_(); +} +function jur_FSet__init_0(var_0) { + var var_1 = new jur_FSet(); + jur_FSet__init_(var_1, var_0); + return var_1; +} +function jur_FSet__init_($this, $groupIndex) { + var var$2, var$3; + jur_FSet_$callClinit(); + var$2 = jur_AbstractSet_counter; + jur_AbstractSet_counter = var$2 + 1 | 0; + var$3 = new jl_AbstractStringBuilder; + var$3.$buffer = $rt_createCharArray(20); + $this.$index1 = (jl_AbstractStringBuilder_insert0(var$3, var$3.$length, var$2, 10)).$toString(); + $this.$groupIndex = $groupIndex; +} +function jur_FSet_matches($this, $stringIndex, $testString, $matchResult) { + var $end, var$5, $shift; + $end = $this.$groupIndex; + var$5 = $matchResult.$groupBounds.data; + $shift = ($end * 2 | 0) + 1 | 0; + $end = var$5[$shift]; + var$5[$shift] = $stringIndex; + $shift = $this.$next0.$matches($stringIndex, $testString, $matchResult); + if ($shift < 0) { + $stringIndex = $this.$groupIndex; + $matchResult.$groupBounds.data[($stringIndex * 2 | 0) + 1 | 0] = $end; + } + return $shift; +} +function jur_FSet_getGroupIndex($this) { + return $this.$groupIndex; +} +function jur_FSet_hasConsumed($this, $mr) { + return 0; +} +function jur_FSet__clinit_() { + var var$1, var$2, var$3; + var$1 = new jur_FSet$PossessiveFSet; + var$2 = jur_AbstractSet_counter; + jur_AbstractSet_counter = var$2 + 1 | 0; + var$3 = new jl_AbstractStringBuilder; + var$3.$buffer = $rt_createCharArray(20); + var$1.$index1 = (jl_AbstractStringBuilder_insert0(var$3, var$3.$length, var$2, 10)).$toString(); + jur_FSet_posFSet = var$1; +} +function jur_Lexer() { + var a = this; jl_Object.call(a); + a.$pattern1 = null; + a.$flags0 = 0; + a.$mode = 0; + a.$savedMode = 0; + a.$lookBack = 0; + a.$ch = 0; + a.$lookAhead = 0; + a.$patternFullLength = 0; + a.$curST = null; + a.$lookAheadST = null; + a.$index = 0; + a.$prevNW = 0; + a.$curToc = 0; + a.$lookAheadToc = 0; + a.$orig = null; +} +var jur_Lexer_decompTable = null; +var jur_Lexer_singleDecompTable = null; +var jur_Lexer_singleDecompTableSize = 0; +function jur_Lexer__init_(var_0, var_1) { + var var_2 = new jur_Lexer(); + jur_Lexer__init_0(var_2, var_0, var_1); + return var_2; +} +function jur_Lexer__init_0($this, $pattern, $flags) { + var var$3, var$4, var$5, var$6, var$7, var$8, var$9, var$10, var$11, var$12; + a: { + $this.$mode = 1; + $this.$orig = $pattern; + if (($flags & 16) > 0) { + var$3 = new jl_StringBuilder; + var$3.$buffer = $rt_createCharArray(16); + jl_AbstractStringBuilder_insert(var$3, var$3.$length, $rt_s(66)); + var$4 = 0; + while (true) { + var$5 = jl_String_indexOf0($pattern, $rt_s(67), var$4); + if (var$5 < 0) { + var$6 = $pattern.$characters.data; + var$5 = var$6.length; + if (var$4 > var$5) { + $pattern = new jl_IndexOutOfBoundsException; + $pattern.$suppressionEnabled = 1; + $pattern.$writableStackTrace = 1; + $rt_throw($pattern); + } + $pattern = new jl_String; + var$7 = var$5 - var$4 | 0; + var$8 = $rt_createCharArray(var$7); + var$9 = var$8.data; + $pattern.$characters = var$8; + var$5 = 0; + while (var$5 < var$7) { + var$9[var$5] = var$6[var$5 + var$4 | 0]; + var$5 = var$5 + 1 | 0; + } + jl_AbstractStringBuilder_insert(var$3, var$3.$length, $pattern); + jl_AbstractStringBuilder_insert(var$3, var$3.$length, $rt_s(67)); + $pattern = new jl_String; + var$6 = var$3.$buffer; + var$10 = var$3.$length; + var$8 = $rt_createCharArray(var$10); + var$9 = var$8.data; + $pattern.$characters = var$8; + var$4 = 0; + while (var$4 < var$10) { + var$9[var$4] = var$6.data[var$4 + 0 | 0]; + var$4 = var$4 + 1 | 0; + } + break a; + } + var$7 = var$5 + 2 | 0; + if (var$4 > var$7) + break; + var$11 = new jl_String; + var$8 = $pattern.$characters; + var$5 = var$7 - var$4 | 0; + var$9 = $rt_createCharArray(var$5); + var$6 = var$9.data; + var$11.$characters = var$9; + var$10 = 0; + while (var$10 < var$5) { + var$6[var$10] = var$8.data[var$10 + var$4 | 0]; + var$10 = var$10 + 1 | 0; + } + jl_AbstractStringBuilder_insert(var$3, var$3.$length, var$11); + jl_AbstractStringBuilder_insert(var$3, var$3.$length, $rt_s(68)); + var$4 = var$7; + } + $pattern = new jl_IndexOutOfBoundsException; + $pattern.$suppressionEnabled = 1; + $pattern.$writableStackTrace = 1; + $rt_throw($pattern); + } else if (($flags & 128) <= 0) { + } + } + var$8 = $pattern.$characters.data; + var$5 = var$8.length; + var$9 = $rt_createCharArray(var$5 + 2 | 0); + $this.$pattern1 = var$9; + var$6 = $rt_createCharArray(var$5); + var$12 = var$6.data; + var$7 = 0; + var$10 = var$12.length; + while (var$7 < var$10) { + var$12[var$7] = var$8[var$7]; + var$7 = var$7 + 1 | 0; + } + jl_System_arraycopy(var$6, 0, var$9, 0, var$5); + var$8 = $this.$pattern1.data; + var$7 = var$8.length; + var$8[var$7 - 1 | 0] = 0; + var$8[var$7 - 2 | 0] = 0; + $this.$patternFullLength = var$7; + $this.$flags0 = $flags; + jur_Lexer_movePointer($this); + jur_Lexer_movePointer($this); +} +function jur_Lexer_peek($this) { + return $this.$ch; +} +function jur_Lexer_setMode($this, $mode) { + if ($mode > 0 && $mode < 3) + $this.$mode = $mode; + if ($mode == 1) { + $this.$lookAhead = $this.$ch; + $this.$lookAheadST = $this.$curST; + $this.$index = $this.$lookAheadToc; + $this.$lookAheadToc = $this.$curToc; + jur_Lexer_movePointer($this); + } +} +function jur_Lexer_restoreFlags($this, $flags) { + var var$2; + $this.$flags0 = $flags; + $this.$lookAhead = $this.$ch; + $this.$lookAheadST = $this.$curST; + var$2 = $this.$curToc; + $this.$index = var$2 + 1 | 0; + $this.$lookAheadToc = var$2; + jur_Lexer_movePointer($this); +} +function jur_Lexer_peekSpecial($this) { + return $this.$curST; +} +function jur_Lexer_isSpecial($this) { + return $this.$curST === null ? 0 : 1; +} +function jur_Lexer_next($this) { + jur_Lexer_movePointer($this); + return $this.$lookBack; +} +function jur_Lexer_nextSpecial($this) { + var $res; + $res = $this.$curST; + jur_Lexer_movePointer($this); + return $res; +} +function jur_Lexer_lookAhead($this) { + return $this.$lookAhead; +} +function jur_Lexer_back($this) { + return $this.$lookBack; +} +function jur_Lexer_movePointer($this) { + var $reread, $nonCap, var$3, $behind, $mod, $cs, $negative, $$je; + $this.$lookBack = $this.$ch; + $this.$ch = $this.$lookAhead; + $this.$curST = $this.$lookAheadST; + $this.$curToc = $this.$lookAheadToc; + $this.$lookAheadToc = $this.$index; + while (true) { + $reread = 0; + $nonCap = $this.$index >= $this.$pattern1.data.length ? 0 : jur_Lexer_nextCodePoint($this); + $this.$lookAhead = $nonCap; + $this.$lookAheadST = null; + if ($this.$mode == 4) { + if ($nonCap != 92) + return; + $nonCap = $this.$index; + var$3 = $this.$pattern1.data; + $nonCap = $nonCap >= var$3.length ? 0 : var$3[jur_Lexer_nextIndex($this)]; + $this.$lookAhead = $nonCap; + switch ($nonCap) { + case 69: + break; + default: + $this.$lookAhead = 92; + $this.$index = $this.$prevNW; + return; + } + $this.$mode = $this.$savedMode; + $this.$lookAhead = $this.$index > ($this.$pattern1.data.length - 2 | 0) ? 0 : jur_Lexer_nextCodePoint($this); + } + a: { + $nonCap = $this.$lookAhead; + if ($nonCap != 92) { + $behind = $this.$mode; + if ($behind == 1) + switch ($nonCap) { + case 36: + $this.$lookAhead = (-536870876); + break a; + case 40: + if ($this.$pattern1.data[$this.$index] != 63) { + $this.$lookAhead = (-2147483608); + break a; + } + jur_Lexer_nextIndex($this); + $nonCap = $this.$pattern1.data[$this.$index]; + $behind = 0; + while (true) { + b: { + if ($behind) { + $behind = 0; + switch ($nonCap) { + case 33: + break; + case 61: + $this.$lookAhead = (-134217688); + jur_Lexer_nextIndex($this); + break b; + default: + $rt_throw(jur_PatternSyntaxException__init_($rt_s(47), jur_Lexer_toString($this), $this.$index)); + } + $this.$lookAhead = (-67108824); + jur_Lexer_nextIndex($this); + } else { + switch ($nonCap) { + case 33: + break; + case 60: + jur_Lexer_nextIndex($this); + $nonCap = $this.$pattern1.data[$this.$index]; + $behind = 1; + break b; + case 61: + $this.$lookAhead = (-536870872); + jur_Lexer_nextIndex($this); + break b; + case 62: + $this.$lookAhead = (-33554392); + jur_Lexer_nextIndex($this); + break b; + default: + $mod = jur_Lexer_readFlags($this); + $this.$lookAhead = $mod; + if ($mod < 256) { + $this.$flags0 = $mod; + $mod = $mod << 16; + $this.$lookAhead = $mod; + $this.$lookAhead = (-1073741784) | $mod; + break b; + } + $mod = $mod & 255; + $this.$lookAhead = $mod; + $this.$flags0 = $mod; + $mod = $mod << 16; + $this.$lookAhead = $mod; + $this.$lookAhead = (-16777176) | $mod; + break b; + } + $this.$lookAhead = (-268435416); + jur_Lexer_nextIndex($this); + } + } + if (!$behind) + break; + } + break a; + case 41: + $this.$lookAhead = (-536870871); + break a; + case 42: + case 43: + case 63: + $behind = $this.$index; + var$3 = $this.$pattern1.data; + switch ($behind >= var$3.length ? 42 : var$3[$behind]) { + case 43: + $this.$lookAhead = $nonCap | (-2147483648); + jur_Lexer_nextIndex($this); + break a; + case 63: + $this.$lookAhead = $nonCap | (-1073741824); + jur_Lexer_nextIndex($this); + break a; + default: + } + $this.$lookAhead = $nonCap | (-536870912); + break a; + case 46: + $this.$lookAhead = (-536870866); + break a; + case 91: + $this.$lookAhead = (-536870821); + jur_Lexer_setMode($this, 2); + break a; + case 93: + if ($behind != 2) + break a; + $this.$lookAhead = (-536870819); + break a; + case 94: + $this.$lookAhead = (-536870818); + break a; + case 123: + $this.$lookAheadST = jur_Lexer_processQuantifier($this, $nonCap); + break a; + case 124: + $this.$lookAhead = (-536870788); + break a; + default: + } + else if ($behind == 2) + switch ($nonCap) { + case 38: + $this.$lookAhead = (-536870874); + break a; + case 45: + $this.$lookAhead = (-536870867); + break a; + case 91: + $this.$lookAhead = (-536870821); + break a; + case 93: + $this.$lookAhead = (-536870819); + break a; + case 94: + $this.$lookAhead = (-536870818); + break a; + default: + } + } else { + $nonCap = $this.$index >= ($this.$pattern1.data.length - 2 | 0) ? (-1) : jur_Lexer_nextCodePoint($this); + c: { + $this.$lookAhead = $nonCap; + switch ($nonCap) { + case -1: + $rt_throw(jur_PatternSyntaxException__init_($rt_s(47), jur_Lexer_toString($this), $this.$index)); + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + case 9: + case 10: + case 11: + case 12: + case 13: + case 14: + case 15: + case 16: + case 17: + case 18: + case 19: + case 20: + case 21: + case 22: + case 23: + case 24: + case 25: + case 26: + case 27: + case 28: + case 29: + case 30: + case 31: + case 32: + case 33: + case 34: + case 35: + case 36: + case 37: + case 38: + case 39: + case 40: + case 41: + case 42: + case 43: + case 44: + case 45: + case 46: + case 47: + case 58: + case 59: + case 60: + case 61: + case 62: + case 63: + case 64: + case 91: + case 92: + case 93: + case 94: + case 95: + case 96: + case 118: + break; + case 48: + $this.$lookAhead = jur_Lexer_readOctals($this); + break a; + case 49: + case 50: + case 51: + case 52: + case 53: + case 54: + case 55: + case 56: + case 57: + if ($this.$mode != 1) + break a; + $this.$lookAhead = (-2147483648) | $nonCap; + break a; + case 65: + $this.$lookAhead = (-2147483583); + break a; + case 66: + $this.$lookAhead = (-2147483582); + break a; + case 67: + case 69: + case 70: + case 72: + case 73: + case 74: + case 75: + case 76: + case 77: + case 78: + case 79: + case 82: + case 84: + case 85: + case 86: + case 88: + case 89: + case 103: + case 104: + case 105: + case 106: + case 107: + case 108: + case 109: + case 111: + case 113: + case 121: + $rt_throw(jur_PatternSyntaxException__init_($rt_s(47), jur_Lexer_toString($this), $this.$index)); + case 68: + case 83: + case 87: + case 100: + case 115: + case 119: + $this.$lookAheadST = jur_AbstractCharClass_getPredefinedClass(jl_String__init_1($this.$pattern1, $this.$prevNW, 1), 0); + $this.$lookAhead = 0; + break a; + case 71: + $this.$lookAhead = (-2147483577); + break a; + case 80: + case 112: + break c; + case 81: + $this.$savedMode = $this.$mode; + $this.$mode = 4; + $reread = 1; + break a; + case 90: + $this.$lookAhead = (-2147483558); + break a; + case 97: + $this.$lookAhead = 7; + break a; + case 98: + $this.$lookAhead = (-2147483550); + break a; + case 99: + $nonCap = $this.$index; + var$3 = $this.$pattern1.data; + if ($nonCap >= (var$3.length - 2 | 0)) + $rt_throw(jur_PatternSyntaxException__init_($rt_s(47), jur_Lexer_toString($this), $this.$index)); + $this.$lookAhead = var$3[jur_Lexer_nextIndex($this)] & 31; + break a; + case 101: + $this.$lookAhead = 27; + break a; + case 102: + $this.$lookAhead = 12; + break a; + case 110: + $this.$lookAhead = 10; + break a; + case 114: + $this.$lookAhead = 13; + break a; + case 116: + $this.$lookAhead = 9; + break a; + case 117: + $this.$lookAhead = jur_Lexer_readHex($this, 4); + break a; + case 120: + $this.$lookAhead = jur_Lexer_readHex($this, 2); + break a; + case 122: + $this.$lookAhead = (-2147483526); + break a; + default: + } + break a; + } + $cs = jur_Lexer_parseCharClassName($this); + $negative = 0; + if ($this.$lookAhead == 80) + $negative = 1; + try { + $this.$lookAheadST = jur_AbstractCharClass_getPredefinedClass($cs, $negative); + } catch ($$e) { + $$je = $rt_wrapException($$e); + if ($$je instanceof ju_MissingResourceException) { + $rt_throw(jur_PatternSyntaxException__init_($rt_s(47), jur_Lexer_toString($this), $this.$index)); + } else { + throw $$e; + } + } + $this.$lookAhead = 0; + } + } + if ($reread) + continue; + else + break; + } +} +function jur_Lexer_parseCharClassName($this) { + var $sb, $ch, var$3, var$4, var$5, var$6, var$7, var$8, var$9, var$10; + $sb = new jl_StringBuilder; + $sb.$buffer = $rt_createCharArray(10); + $ch = $this.$index; + var$3 = $this.$pattern1.data; + if ($ch < (var$3.length - 2 | 0)) { + if (var$3[$ch] != 123) { + $sb = new jl_StringBuilder; + $sb.$buffer = $rt_createCharArray(16); + jl_AbstractStringBuilder_insert($sb, $sb.$length, $rt_s(69)); + var$4 = new jl_String; + var$3 = $this.$pattern1; + var$5 = $this.$index; + $this.$prevNW = var$5; + if ($this.$flags0 & 4) + jur_Lexer_skipComments($this); + else + $this.$index = var$5 + 1 | 0; + var$6 = $this.$prevNW; + var$7 = $rt_createCharArray(1); + var$8 = var$7.data; + var$4.$characters = var$7; + var$5 = 0; + while (var$5 < 1) { + var$8[var$5] = var$3.data[var$5 + var$6 | 0]; + var$5 = var$5 + 1 | 0; + } + jl_AbstractStringBuilder_insert($sb, $sb.$length, var$4); + var$4 = new jl_String; + var$3 = $sb.$buffer; + var$5 = $sb.$length; + var$7 = $rt_createCharArray(var$5); + var$8 = var$7.data; + var$4.$characters = var$7; + var$9 = 0; + while (var$9 < var$5) { + var$8[var$9] = var$3.data[var$9 + 0 | 0]; + var$9 = var$9 + 1 | 0; + } + return var$4; + } + $this.$prevNW = $ch; + if ($this.$flags0 & 4) + jur_Lexer_skipComments($this); + else + $this.$index = $ch + 1 | 0; + $ch = 0; + a: { + while (true) { + var$5 = $this.$index; + var$3 = $this.$pattern1.data; + if (var$5 >= (var$3.length - 2 | 0)) + break; + $this.$prevNW = var$5; + if ($this.$flags0 & 4) + jur_Lexer_skipComments($this); + else + $this.$index = var$5 + 1 | 0; + $ch = var$3[$this.$prevNW]; + if ($ch == 125) + break a; + var$5 = $sb.$length; + jl_AbstractStringBuilder_insertSpace($sb, var$5, var$5 + 1 | 0); + $sb.$buffer.data[var$5] = $ch; + } + } + if ($ch != 125) { + $sb = new jur_PatternSyntaxException; + var$10 = $this.$orig; + $ch = $this.$index; + $sb.$suppressionEnabled = 1; + $sb.$writableStackTrace = 1; + $sb.$index0 = (-1); + $sb.$desc = $rt_s(47); + $sb.$pattern = var$10; + $sb.$index0 = $ch; + $rt_throw($sb); + } + } + $ch = $sb.$length; + if (!$ch) { + $sb = new jur_PatternSyntaxException; + var$10 = $this.$orig; + $ch = $this.$index; + $sb.$suppressionEnabled = 1; + $sb.$writableStackTrace = 1; + $sb.$index0 = (-1); + $sb.$desc = $rt_s(47); + $sb.$pattern = var$10; + $sb.$index0 = $ch; + $rt_throw($sb); + } + var$4 = new jl_String; + var$3 = $sb.$buffer; + var$7 = $rt_createCharArray($ch); + var$8 = var$7.data; + var$4.$characters = var$7; + var$9 = 0; + while (var$9 < $ch) { + var$8[var$9] = var$3.data[var$9 + 0 | 0]; + var$9 = var$9 + 1 | 0; + } + var$5 = var$8.length; + if (var$5 == 1) { + $sb = new jl_StringBuilder; + $sb.$buffer = $rt_createCharArray(16); + jl_AbstractStringBuilder_insert($sb, $sb.$length, $rt_s(69)); + jl_AbstractStringBuilder_insert($sb, $sb.$length, var$4); + var$4 = new jl_String; + var$3 = $sb.$buffer; + var$5 = $sb.$length; + var$7 = $rt_createCharArray(var$5); + var$8 = var$7.data; + var$4.$characters = var$7; + var$9 = 0; + while (var$9 < var$5) { + var$8[var$9] = var$3.data[var$9 + 0 | 0]; + var$9 = var$9 + 1 | 0; + } + return var$4; + } + b: { + c: { + if (var$5 > 3) { + if (var$4 === $rt_s(69) ? 1 : jl_String_startsWith(var$4, $rt_s(69), 0)) + break c; + if (jl_String_startsWith0(var$4, $rt_s(70))) + break c; + } + break b; + } + var$4 = jl_String_substring(var$4, 2, var$4.$characters.data.length); + } + return var$4; +} +function jur_Lexer_processQuantifier($this, $ch) { + var $sb, $min, $max, var$5, var$6, $mod, var$8, $$je; + $sb = new jl_StringBuilder; + $sb.$buffer = $rt_createCharArray(4); + $min = (-1); + $max = 2147483647; + a: { + while (true) { + var$5 = $this.$index; + var$6 = $this.$pattern1.data; + if (var$5 >= var$6.length) + break a; + $this.$prevNW = var$5; + if ($this.$flags0 & 4) + jur_Lexer_skipComments($this); + else + $this.$index = var$5 + 1 | 0; + $ch = var$6[$this.$prevNW]; + if ($ch == 125) + break a; + if ($ch == 44 && $min < 0) + try { + $min = jl_Integer_parseInt(jl_StringBuilder_toString($sb), 10); + jl_StringBuilder_delete($sb, 0, jl_StringBuilder_length($sb)); + continue; + } catch ($$e) { + $$je = $rt_wrapException($$e); + if ($$je instanceof jl_NumberFormatException) { + break; + } else { + throw $$e; + } + } + $mod = $ch & 65535; + var$5 = $sb.$length; + jl_AbstractStringBuilder_insertSpace($sb, var$5, var$5 + 1 | 0); + $sb.$buffer.data[var$5] = $mod; + } + $sb = new jur_PatternSyntaxException; + var$8 = $this.$orig; + $ch = $this.$index; + $sb.$suppressionEnabled = 1; + $sb.$writableStackTrace = 1; + $sb.$index0 = (-1); + $sb.$desc = $rt_s(47); + $sb.$pattern = var$8; + $sb.$index0 = $ch; + $rt_throw($sb); + } + if ($ch != 125) { + $sb = new jur_PatternSyntaxException; + var$8 = $this.$orig; + $ch = $this.$index; + $sb.$suppressionEnabled = 1; + $sb.$writableStackTrace = 1; + $sb.$index0 = (-1); + $sb.$desc = $rt_s(47); + $sb.$pattern = var$8; + $sb.$index0 = $ch; + $rt_throw($sb); + } + if ($sb.$length > 0) + b: { + try { + $max = jl_Integer_parseInt(jl_StringBuilder_toString($sb), 10); + if ($min >= 0) + break b; + $min = $max; + break b; + } catch ($$e) { + $$je = $rt_wrapException($$e); + if ($$je instanceof jl_NumberFormatException) { + } else { + throw $$e; + } + } + $sb = new jur_PatternSyntaxException; + var$8 = $this.$orig; + $ch = $this.$index; + $sb.$suppressionEnabled = 1; + $sb.$writableStackTrace = 1; + $sb.$index0 = (-1); + $sb.$desc = $rt_s(47); + $sb.$pattern = var$8; + $sb.$index0 = $ch; + $rt_throw($sb); + } + else if ($min < 0) { + $sb = new jur_PatternSyntaxException; + var$8 = $this.$orig; + $ch = $this.$index; + $sb.$suppressionEnabled = 1; + $sb.$writableStackTrace = 1; + $sb.$index0 = (-1); + $sb.$desc = $rt_s(47); + $sb.$pattern = var$8; + $sb.$index0 = $ch; + $rt_throw($sb); + } + if (($min | $max | ($max - $min | 0)) < 0) { + $sb = new jur_PatternSyntaxException; + var$8 = $this.$orig; + $ch = $this.$index; + $sb.$suppressionEnabled = 1; + $sb.$writableStackTrace = 1; + $sb.$index0 = (-1); + $sb.$desc = $rt_s(47); + $sb.$pattern = var$8; + $sb.$index0 = $ch; + $rt_throw($sb); + } + var$5 = $this.$index; + var$6 = $this.$pattern1.data; + $mod = var$5 >= var$6.length ? 42 : var$6[var$5]; + c: { + switch ($mod) { + case 43: + $this.$lookAhead = (-2147483525); + $this.$prevNW = var$5; + if ($this.$flags0 & 4) + jur_Lexer_skipComments($this); + else + $this.$index = var$5 + 1 | 0; + break c; + case 63: + $this.$lookAhead = (-1073741701); + $this.$prevNW = var$5; + if ($this.$flags0 & 4) + jur_Lexer_skipComments($this); + else + $this.$index = var$5 + 1 | 0; + break c; + default: + } + $this.$lookAhead = (-536870789); + } + $sb = new jur_Quantifier; + $sb.$min = $min; + $sb.$max = $max; + return $sb; +} +function jur_Lexer_toString($this) { + return $this.$orig; +} +function jur_Lexer_isEmpty($this) { + return !$this.$ch && !$this.$lookAhead && $this.$index == $this.$patternFullLength && !($this.$curST === null ? 0 : 1) ? 1 : 0; +} +function jur_Lexer_isLetter0($ch) { + return $ch < 0 ? 0 : 1; +} +function jur_Lexer_isLetter($this) { + var var$1, var$2; + var$1 = $this.$ch; + var$2 = !var$1 && !$this.$lookAhead && $this.$index == $this.$patternFullLength && !($this.$curST === null ? 0 : 1) ? 1 : 0; + return !var$2 && !($this.$curST === null ? 0 : 1) && (var$1 < 0 ? 0 : 1) ? 1 : 0; +} +function jur_Lexer_isLowSurrogate($this) { + var var$1; + var$1 = $this.$ch; + return var$1 <= 57343 && var$1 >= 56320 ? 1 : 0; +} +function jur_Lexer_isHighSurrogate($ch) { + return $ch <= 56319 && $ch >= 55296 ? 1 : 0; +} +function jur_Lexer_isLowSurrogate0($ch) { + return $ch <= 57343 && $ch >= 56320 ? 1 : 0; +} +function jur_Lexer_readHex($this, $max) { + var $st, $length, $i, var$5, var$6, var$7, var$8, var$9, $$je; + $st = new jl_StringBuilder; + $st.$buffer = $rt_createCharArray($max); + $length = $this.$pattern1.data.length - 2 | 0; + $i = 0; + while (true) { + var$5 = $rt_compare($i, $max); + if (var$5 >= 0) + break; + var$6 = $this.$index; + if (var$6 >= $length) + break; + var$7 = $this.$pattern1; + $this.$prevNW = var$6; + if ($this.$flags0 & 4) + jur_Lexer_skipComments($this); + else + $this.$index = var$6 + 1 | 0; + var$6 = var$7.data[$this.$prevNW]; + var$8 = $st.$length; + jl_AbstractStringBuilder_insertSpace($st, var$8, var$8 + 1 | 0); + $st.$buffer.data[var$8] = var$6; + $i = $i + 1 | 0; + } + if (!var$5) + a: { + try { + $max = jl_Integer_parseInt(jl_StringBuilder_toString($st), 16); + } catch ($$e) { + $$je = $rt_wrapException($$e); + if ($$je instanceof jl_NumberFormatException) { + break a; + } else { + throw $$e; + } + } + return $max; + } + $st = new jur_PatternSyntaxException; + var$9 = $this.$orig; + $max = $this.$index; + $st.$suppressionEnabled = 1; + $st.$writableStackTrace = 1; + $st.$index0 = (-1); + $st.$desc = $rt_s(47); + $st.$pattern = var$9; + $st.$index0 = $max; + $rt_throw($st); +} +function jur_Lexer_readOctals($this) { + var $max, $i, var$3, $length, $first, var$6, var$7, var$8, var$9, var$10; + $max = 3; + $i = 1; + var$3 = $this.$pattern1.data; + $length = var$3.length - 2 | 0; + $first = jl_Character_getNumericValue(var$3[$this.$index]); + if ($first >= 8) + $first = (-1); + switch ($first) { + case -1: + break; + default: + if ($first > 3) + $max = 2; + var$6 = $this.$index; + $this.$prevNW = var$6; + if ($this.$flags0 & 4) + jur_Lexer_skipComments($this); + else + $this.$index = var$6 + 1 | 0; + a: { + while (true) { + if ($i >= $max) + break a; + var$7 = $this.$index; + if (var$7 >= $length) + break a; + var$8 = jl_Character_getNumericValue($this.$pattern1.data[var$7]); + if (var$8 >= 8) + var$8 = (-1); + if (var$8 < 0) + break; + $first = ($first * 8 | 0) + var$8 | 0; + var$6 = $this.$index; + $this.$prevNW = var$6; + if ($this.$flags0 & 4) + jur_Lexer_skipComments($this); + else + $this.$index = var$6 + 1 | 0; + $i = $i + 1 | 0; + } + } + return $first; + } + var$9 = new jur_PatternSyntaxException; + var$10 = $this.$orig; + $max = $this.$index; + var$9.$suppressionEnabled = 1; + var$9.$writableStackTrace = 1; + var$9.$index0 = (-1); + var$9.$desc = $rt_s(47); + var$9.$pattern = var$10; + var$9.$index0 = $max; + $rt_throw(var$9); +} +function jur_Lexer_readFlags($this) { + var $pos, $res, var$3, var$4, var$5, var$6, var$7; + $pos = 1; + $res = $this.$flags0; + a: while (true) { + var$3 = $this.$index; + var$4 = $this.$pattern1.data; + if (var$3 >= var$4.length) { + var$5 = new jur_PatternSyntaxException; + var$6 = $this.$orig; + var$5.$suppressionEnabled = 1; + var$5.$writableStackTrace = 1; + var$5.$index0 = (-1); + var$5.$desc = $rt_s(47); + var$5.$pattern = var$6; + var$5.$index0 = var$3; + $rt_throw(var$5); + } + b: { + c: { + switch (var$4[var$3]) { + case 41: + $this.$prevNW = var$3; + if ($this.$flags0 & 4) + jur_Lexer_skipComments($this); + else + $this.$index = var$3 + 1 | 0; + return $res | 256; + case 45: + if (!$pos) { + var$7 = new jur_PatternSyntaxException; + var$6 = $this.$orig; + var$7.$suppressionEnabled = 1; + var$7.$writableStackTrace = 1; + var$7.$index0 = (-1); + var$7.$desc = $rt_s(47); + var$7.$pattern = var$6; + var$7.$index0 = var$3; + $rt_throw(var$7); + } + $pos = 0; + break b; + case 58: + break a; + case 100: + break c; + case 105: + $res = $pos ? $res | 2 : ($res ^ 2) & $res; + break b; + case 109: + $res = $pos ? $res | 8 : ($res ^ 8) & $res; + break b; + case 115: + $res = $pos ? $res | 32 : ($res ^ 32) & $res; + break b; + case 117: + $res = $pos ? $res | 64 : ($res ^ 64) & $res; + break b; + case 120: + $res = $pos ? $res | 4 : ($res ^ 4) & $res; + break b; + default: + } + break b; + } + $res = $pos ? $res | 1 : ($res ^ 1) & $res; + } + $this.$prevNW = var$3; + if ($this.$flags0 & 4) + jur_Lexer_skipComments($this); + else + $this.$index = var$3 + 1 | 0; + } + $this.$prevNW = var$3; + if ($this.$flags0 & 4) + jur_Lexer_skipComments($this); + else + $this.$index = var$3 + 1 | 0; + return $res; +} +function jur_Lexer_nextIndex($this) { + var var$1; + var$1 = $this.$index; + $this.$prevNW = var$1; + if ($this.$flags0 & 4) + jur_Lexer_skipComments($this); + else + $this.$index = var$1 + 1 | 0; + return $this.$prevNW; +} +function jur_Lexer_skipComments($this) { + var $length, var$2, var$3, var$4; + $length = $this.$pattern1.data.length - 2 | 0; + $this.$index = $this.$index + 1 | 0; + a: while (true) { + var$2 = $this.$index; + if (var$2 < $length) { + b: { + var$2 = $this.$pattern1.data[var$2]; + switch (var$2) { + case 9: + case 10: + case 11: + case 12: + case 13: + case 28: + case 29: + case 30: + case 31: + break; + case 160: + case 8199: + case 8239: + var$2 = 0; + break b; + default: + c: { + switch (jl_Character_getType(var$2)) { + case 12: + case 13: + case 14: + break; + default: + var$2 = 0; + break c; + } + var$2 = 1; + } + break b; + } + var$2 = 1; + } + if (var$2) { + $this.$index = $this.$index + 1 | 0; + continue; + } + } + var$2 = $this.$index; + if (var$2 >= $length) + break; + var$3 = $this.$pattern1.data; + if (var$3[var$2] != 35) + break; + $this.$index = var$2 + 1 | 0; + while (true) { + var$4 = $this.$index; + if (var$4 >= $length) + continue a; + var$2 = var$3[var$4]; + if (var$2 != 10 && var$2 != 13 && var$2 != 133 && (var$2 | 1) != 8233 ? 0 : 1) + continue a; + $this.$index = var$4 + 1 | 0; + } + } + return var$2; +} +function jur_Lexer_getHangulDecomposition($ch) { + var $sIndex, $l, $v, $t; + $sIndex = $ch - 44032 | 0; + if ($sIndex >= 0 && $sIndex < 11172) { + $l = 4352 + ($sIndex / 588 | 0) | 0; + $v = 4449 + (($sIndex % 588 | 0) / 28 | 0) | 0; + $t = $sIndex % 28 | 0; + return !$t ? $rt_createIntArrayFromData([$l, $v]) : $rt_createIntArrayFromData([$l, $v, 4519 + $t | 0]); + } + return null; +} +function jur_Lexer_hasSingleCodepointDecomposition($ch) { + return jur_Lexer_singleDecompTable.$get2($ch) == jur_Lexer_singleDecompTableSize ? 0 : 1; +} +function jur_Lexer_hasDecompositionNonNullCanClass($ch) { + return ($ch != 832 ? 0 : 1) | ($ch != 833 ? 0 : 1) | ($ch != 835 ? 0 : 1) | ($ch != 836 ? 0 : 1); +} +function jur_Lexer_nextCodePoint($this) { + var var$1, $lowExpectedIndex, var$3, $high, $low; + var$1 = $this.$pattern1; + $lowExpectedIndex = $this.$index; + $this.$prevNW = $lowExpectedIndex; + if ($this.$flags0 & 4) + jur_Lexer_skipComments($this); + else + $this.$index = $lowExpectedIndex + 1 | 0; + var$1 = var$1.data; + var$3 = $this.$prevNW; + $high = var$1[var$3]; + if (($high & 64512) != 55296 ? 0 : 1) { + $lowExpectedIndex = var$3 + 1 | 0; + var$1 = $this.$pattern1.data; + if ($lowExpectedIndex < var$1.length) { + $low = var$1[$lowExpectedIndex]; + if (($low & 64512) != 56320 ? 0 : 1) { + var$3 = $this.$index; + $this.$prevNW = var$3; + if ($this.$flags0 & 4) + jur_Lexer_skipComments($this); + else + $this.$index = var$3 + 1 | 0; + return (($high & 1023) << 10 | $low & 1023) + 65536 | 0; + } + } + } + return $high; +} +function jur_Lexer_getIndex($this) { + return $this.$curToc; +} +function jur_PatternSyntaxException() { + var a = this; jl_IllegalArgumentException.call(a); + a.$desc = null; + a.$pattern = null; + a.$index0 = 0; +} +function jur_PatternSyntaxException__init_(var_0, var_1, var_2) { + var var_3 = new jur_PatternSyntaxException(); + jur_PatternSyntaxException__init_0(var_3, var_0, var_1, var_2); + return var_3; +} +function jur_PatternSyntaxException__init_0($this, $description, $pattern, $index) { + $this.$suppressionEnabled = 1; + $this.$writableStackTrace = 1; + $this.$index0 = (-1); + $this.$desc = $description; + $this.$pattern = $pattern; + $this.$index0 = $index; +} +var jur_NonCapFSet = $rt_classWithoutFields(jur_FSet); +function jur_NonCapFSet_matches($this, $stringIndex, $testString, $matchResult) { + var $gr, var$5; + $gr = $this.$groupIndex; + var$5 = $matchResult.$consumers.data; + var$5[$gr] = $stringIndex - var$5[$gr] | 0; + return $this.$next0.$matches($stringIndex, $testString, $matchResult); +} +function jur_NonCapFSet_hasConsumed($this, $mr) { + return 0; +} +var jur_AheadFSet = $rt_classWithoutFields(jur_FSet); +function jur_AheadFSet_matches($this, $stringIndex, $testString, $matchResult) { + return $stringIndex; +} +var jur_BehindFSet = $rt_classWithoutFields(jur_FSet); +function jur_BehindFSet_matches($this, $stringIndex, $testString, $matchResult) { + var $gr; + $gr = $this.$groupIndex; + if ($matchResult.$consumers.data[$gr] != $stringIndex) + $stringIndex = (-1); + return $stringIndex; +} +function jur_AtomicFSet() { + jur_FSet.call(this); + this.$index2 = 0; +} +function jur_AtomicFSet_matches($this, $stringIndex, $testString, $matchResult) { + var $gr, var$5; + $gr = $this.$groupIndex; + var$5 = $matchResult.$consumers.data; + var$5[$gr] = $stringIndex - var$5[$gr] | 0; + $this.$index2 = $stringIndex; + return $stringIndex; +} +function jur_AtomicFSet_hasConsumed($this, $mr) { + return 0; +} +var jur_FinalSet = $rt_classWithoutFields(jur_FSet); +function jur_FinalSet_matches($this, $stringIndex, $testString, $matchResult) { + if ($matchResult.$mode0 != 1 && $stringIndex != $matchResult.$rightBound) + return (-1); + $matchResult.$valid = 1; + $matchResult.$groupBounds.data[1] = $stringIndex; + return $stringIndex; +} +function jur_LeafSet() { + jur_AbstractSet.call(this); + this.$charCount = 0; +} +function jur_LeafSet__init_0($this, $next) { + var var$2, var$3; + var$2 = jur_AbstractSet_counter; + jur_AbstractSet_counter = var$2 + 1 | 0; + var$3 = new jl_AbstractStringBuilder; + var$3.$buffer = $rt_createCharArray(20); + $this.$index1 = (jl_AbstractStringBuilder_insert0(var$3, var$3.$length, var$2, 10)).$toString(); + $this.$next0 = $next; + $this.$charCount = 1; + $this.$type = 1; +} +function jur_LeafSet__init_($this) { + var var$1, var$2; + var$1 = jur_AbstractSet_counter; + jur_AbstractSet_counter = var$1 + 1 | 0; + var$2 = new jl_AbstractStringBuilder; + var$2.$buffer = $rt_createCharArray(20); + $this.$index1 = (jl_AbstractStringBuilder_insert0(var$2, var$2.$length, var$1, 10)).$toString(); + $this.$charCount = 1; +} +function jur_LeafSet_matches($this, $stringIndex, $testString, $matchResult) { + var $shift; + if (($stringIndex + $this.$charCount0() | 0) > $matchResult.$rightBound) { + $matchResult.$hitEnd = 1; + return (-1); + } + $shift = $this.$accepts($stringIndex, $testString); + if ($shift < 0) + return (-1); + return $this.$next0.$matches($stringIndex + $shift | 0, $testString, $matchResult); +} +function jur_LeafSet_charCount($this) { + return $this.$charCount; +} +function jur_LeafSet_hasConsumed($this, $mr) { + return 1; +} +var jur_EmptySet = $rt_classWithoutFields(jur_LeafSet); +function jur_EmptySet__init_(var_0) { + var var_1 = new jur_EmptySet(); + jur_EmptySet__init_0(var_1, var_0); + return var_1; +} +function jur_EmptySet__init_0($this, $next) { + var var$2, var$3; + var$2 = jur_AbstractSet_counter; + jur_AbstractSet_counter = var$2 + 1 | 0; + var$3 = new jl_AbstractStringBuilder; + var$3.$buffer = $rt_createCharArray(20); + $this.$index1 = (jl_AbstractStringBuilder_insert0(var$3, var$3.$length, var$2, 10)).$toString(); + $this.$next0 = $next; + $this.$charCount = 1; + $this.$type = 1; + $this.$charCount = 0; +} +function jur_EmptySet_accepts($this, $stringIndex, $testString) { + return 0; +} +function jur_EmptySet_find($this, $stringIndex, $testString, $matchResult) { + var $strLength, $startStr, $low, var$7, $high; + $strLength = $matchResult.$rightBound; + $startStr = $matchResult.$leftBound; + a: { + b: { + while (true) { + $low = $rt_compare($stringIndex, $strLength); + if ($low > 0) + return (-1); + if ($low < 0) { + if ($stringIndex < 0) + break b; + var$7 = $testString.$characters.data; + $high = var$7.length; + if ($stringIndex >= $high) + break b; + if (((var$7[$stringIndex] & 64512) != 56320 ? 0 : 1) && $stringIndex > $startStr) { + $low = $stringIndex - 1 | 0; + if ($low < 0) + break a; + if ($low >= $high) + break a; + if ((var$7[$low] & 64512) != 55296 ? 0 : 1) { + $stringIndex = $stringIndex + 1 | 0; + continue; + } + } + } + if ($this.$next0.$matches($stringIndex, $testString, $matchResult) >= 0) + break; + $stringIndex = $stringIndex + 1 | 0; + } + return $stringIndex; + } + $testString = new jl_StringIndexOutOfBoundsException; + $testString.$suppressionEnabled = 1; + $testString.$writableStackTrace = 1; + $rt_throw($testString); + } + $testString = new jl_StringIndexOutOfBoundsException; + $testString.$suppressionEnabled = 1; + $testString.$writableStackTrace = 1; + $rt_throw($testString); +} +function jur_EmptySet_findBack($this, $stringIndex, $startSearch, $testString, $matchResult) { + var $strLength, $startStr, var$7, var$8, $low; + $strLength = $matchResult.$rightBound; + $startStr = $matchResult.$leftBound; + a: { + b: { + while (true) { + if ($startSearch < $stringIndex) + return (-1); + if ($startSearch < $strLength) { + if ($startSearch < 0) + break b; + var$7 = $testString.$characters.data; + var$8 = var$7.length; + if ($startSearch >= var$8) + break b; + if (((var$7[$startSearch] & 64512) != 56320 ? 0 : 1) && $startSearch > $startStr) { + $low = $startSearch - 1 | 0; + if ($low < 0) + break a; + if ($low >= var$8) + break a; + if ((var$7[$low] & 64512) != 55296 ? 0 : 1) { + $startSearch = $startSearch + (-1) | 0; + continue; + } + } + } + if ($this.$next0.$matches($startSearch, $testString, $matchResult) >= 0) + break; + $startSearch = $startSearch + (-1) | 0; + } + return $startSearch; + } + $testString = new jl_StringIndexOutOfBoundsException; + $testString.$suppressionEnabled = 1; + $testString.$writableStackTrace = 1; + $rt_throw($testString); + } + $testString = new jl_StringIndexOutOfBoundsException; + $testString.$suppressionEnabled = 1; + $testString.$writableStackTrace = 1; + $rt_throw($testString); +} +function jur_EmptySet_hasConsumed($this, $mr) { + return 0; +} +function jur_JointSet() { + var a = this; jur_AbstractSet.call(a); + a.$children = null; + a.$fSet = null; + a.$groupIndex0 = 0; +} +function jur_JointSet__init_(var_0, var_1) { + var var_2 = new jur_JointSet(); + jur_JointSet__init_0(var_2, var_0, var_1); + return var_2; +} +function jur_JointSet__init_0($this, $children, $fSet) { + var var$3, var$4; + var$3 = jur_AbstractSet_counter; + jur_AbstractSet_counter = var$3 + 1 | 0; + var$4 = new jl_AbstractStringBuilder; + var$4.$buffer = $rt_createCharArray(20); + $this.$index1 = (jl_AbstractStringBuilder_insert0(var$4, var$4.$length, var$3, 10)).$toString(); + $this.$children = $children; + $this.$fSet = $fSet; + $this.$groupIndex0 = $fSet.$groupIndex; +} +function jur_JointSet_matches($this, $stringIndex, $testString, $matchResult) { + var $e, $size, var$6, $shift, $start, $i; + $e = $this.$children; + if ($e === null) + return (-1); + $size = $this.$groupIndex0; + var$6 = $matchResult.$groupBounds.data; + $shift = $size * 2 | 0; + $start = var$6[$shift]; + var$6[$shift] = $stringIndex; + $size = $e.$size; + $i = 0; + a: { + while (true) { + if ($i >= $size) { + $stringIndex = $this.$groupIndex0; + $matchResult.$groupBounds.data[$stringIndex * 2 | 0] = $start; + return (-1); + } + $e = $this.$children; + if ($i < 0) + break a; + if ($i >= $e.$size) + break a; + $shift = $e.$array.data[$i].$matches($stringIndex, $testString, $matchResult); + if ($shift >= 0) + break; + $i = $i + 1 | 0; + } + return $shift; + } + $testString = new jl_IndexOutOfBoundsException; + $testString.$suppressionEnabled = 1; + $testString.$writableStackTrace = 1; + $rt_throw($testString); +} +function jur_JointSet_setNext($this, $next) { + $this.$fSet.$next0 = $next; +} +function jur_JointSet_first($this, $set) { + var var$2, $i$index, var$4, var$5, $i$index_0; + a: { + b: { + var$2 = $this.$children; + if (var$2 !== null) { + $i$index = 0; + var$4 = var$2.$modCount; + var$5 = var$2.$size; + while (true) { + if (!($i$index >= var$5 ? 0 : 1)) + break b; + if (var$4 < var$2.$modCount) { + $set = new ju_ConcurrentModificationException; + $set.$suppressionEnabled = 1; + $set.$writableStackTrace = 1; + $rt_throw($set); + } + $i$index_0 = $i$index + 1 | 0; + if ($i$index < 0) + break a; + if ($i$index >= var$2.$size) + break a; + if (var$2.$array.data[$i$index].$first($set)) + break; + $i$index = $i$index_0; + } + return 1; + } + } + return 0; + } + $set = new jl_IndexOutOfBoundsException; + $set.$suppressionEnabled = 1; + $set.$writableStackTrace = 1; + $rt_throw($set); +} +function jur_JointSet_hasConsumed($this, $matchResult) { + var var$2, var$3, var$4; + var$2 = $this.$groupIndex0; + var$3 = $matchResult.$groupBounds.data; + var$2 = var$2 * 2 | 0; + var$4 = var$2 + 1 | 0; + return var$3[var$4] >= 0 && var$3[var$2] == var$3[var$4] ? 0 : 1; +} +function jur_JointSet_processSecondPass($this) { + var $child, $childrenSize, $i, $set; + $this.$isSecondPassVisited = 1; + $child = $this.$fSet; + if ($child !== null && !$child.$isSecondPassVisited) + jur_AbstractSet_processSecondPass($child); + a: { + b: { + $child = $this.$children; + if ($child !== null) { + $childrenSize = $child.$size; + $i = 0; + while (true) { + if ($i >= $childrenSize) + break b; + $child = $this.$children; + if ($i < 0) + break a; + if ($i >= $child.$size) + break a; + $child = $child.$array.data[$i]; + $set = $child.$processBackRefReplacement(); + if ($set === null) + $set = $child; + else { + $child.$isSecondPassVisited = 1; + ju_ArrayList_remove($this.$children, $i); + ju_ArrayList_add0($this.$children, $i, $set); + } + if (!$set.$isSecondPassVisited) + $set.$processSecondPass(); + $i = $i + 1 | 0; + } + } + } + if ($this.$next0 !== null) + jur_AbstractSet_processSecondPass($this); + return; + } + $child = new jl_IndexOutOfBoundsException; + $child.$suppressionEnabled = 1; + $child.$writableStackTrace = 1; + $rt_throw($child); +} +var jur_NonCapJointSet = $rt_classWithoutFields(jur_JointSet); +function jur_NonCapJointSet__init_(var_0, var_1) { + var var_2 = new jur_NonCapJointSet(); + jur_NonCapJointSet__init_0(var_2, var_0, var_1); + return var_2; +} +function jur_NonCapJointSet__init_0($this, $children, $fSet) { + var var$3, var$4; + var$3 = jur_AbstractSet_counter; + jur_AbstractSet_counter = var$3 + 1 | 0; + var$4 = new jl_AbstractStringBuilder; + var$4.$buffer = $rt_createCharArray(20); + $this.$index1 = (jl_AbstractStringBuilder_insert0(var$4, var$4.$length, var$3, 10)).$toString(); + $this.$children = $children; + $this.$fSet = $fSet; + $this.$groupIndex0 = $fSet.$groupIndex; +} +function jur_NonCapJointSet_matches($this, $stringIndex, $testString, $matchResult) { + var $i, var$5, $start, $size, $e, $shift; + $i = $this.$groupIndex0; + var$5 = $matchResult.$consumers.data; + $start = var$5[$i]; + var$5[$i] = $stringIndex; + $size = $this.$children.$size; + $i = 0; + a: { + while (true) { + if ($i >= $size) { + $stringIndex = $this.$groupIndex0; + $matchResult.$consumers.data[$stringIndex] = $start; + return (-1); + } + $e = $this.$children; + if ($i < 0) + break a; + if ($i >= $e.$size) + break a; + $shift = $e.$array.data[$i].$matches($stringIndex, $testString, $matchResult); + if ($shift >= 0) + break; + $i = $i + 1 | 0; + } + return $shift; + } + $testString = new jl_IndexOutOfBoundsException; + $testString.$suppressionEnabled = 1; + $testString.$writableStackTrace = 1; + $rt_throw($testString); +} +function jur_NonCapJointSet_hasConsumed($this, $matchResult) { + var $cons; + $cons = $this.$groupIndex0; + return !$matchResult.$consumers.data[$cons] ? 0 : 1; +} +var jur_AtomicJointSet = $rt_classWithoutFields(jur_NonCapJointSet); +function jur_AtomicJointSet__init_(var_0, var_1) { + var var_2 = new jur_AtomicJointSet(); + jur_AtomicJointSet__init_0(var_2, var_0, var_1); + return var_2; +} +function jur_AtomicJointSet__init_0($this, $children, $fSet) { + var var$3, var$4; + var$3 = jur_AbstractSet_counter; + jur_AbstractSet_counter = var$3 + 1 | 0; + var$4 = new jl_AbstractStringBuilder; + var$4.$buffer = $rt_createCharArray(20); + $this.$index1 = (jl_AbstractStringBuilder_insert0(var$4, var$4.$length, var$3, 10)).$toString(); + $this.$children = $children; + $this.$fSet = $fSet; + $this.$groupIndex0 = $fSet.$groupIndex; +} +function jur_AtomicJointSet_matches($this, $stringIndex, $testString, $matchResult) { + var $shift, var$5, $start, $size, $i, $e; + $shift = $this.$groupIndex0; + var$5 = $matchResult.$consumers.data; + $start = var$5[$shift]; + var$5[$shift] = $stringIndex; + $size = $this.$children.$size; + $i = 0; + a: { + while ($i < $size) { + $e = $this.$children; + if ($i < 0) + break a; + if ($i >= $e.$size) + break a; + if ($e.$array.data[$i].$matches($stringIndex, $testString, $matchResult) >= 0) + return $this.$next0.$matches($this.$fSet.$index2, $testString, $matchResult); + $i = $i + 1 | 0; + } + $stringIndex = $this.$groupIndex0; + $matchResult.$consumers.data[$stringIndex] = $start; + return (-1); + } + $testString = new jl_IndexOutOfBoundsException; + $testString.$suppressionEnabled = 1; + $testString.$writableStackTrace = 1; + $rt_throw($testString); +} +function jur_AtomicJointSet_setNext($this, $next) { + $this.$next0 = $next; +} +var jur_PositiveLookAhead = $rt_classWithoutFields(jur_AtomicJointSet); +function jur_PositiveLookAhead__init_(var_0, var_1) { + var var_2 = new jur_PositiveLookAhead(); + jur_PositiveLookAhead__init_0(var_2, var_0, var_1); + return var_2; +} +function jur_PositiveLookAhead__init_0($this, $children, $fSet) { + var var$3, var$4; + var$3 = jur_AbstractSet_counter; + jur_AbstractSet_counter = var$3 + 1 | 0; + var$4 = new jl_AbstractStringBuilder; + jl_Object__init_0(var$4); + var$4.$buffer = $rt_createCharArray(20); + $this.$index1 = (jl_AbstractStringBuilder_insert0(var$4, var$4.$length, var$3, 10)).$toString(); + $this.$children = $children; + $this.$fSet = $fSet; + $this.$groupIndex0 = $fSet.$groupIndex; +} +function jur_PositiveLookAhead_matches($this, $stringIndex, $testString, $matchResult) { + var $size, $i, $e; + $size = $this.$children.$size; + $i = 0; + a: { + while ($i < $size) { + $e = $this.$children; + if ($i < 0) + break a; + if ($i >= $e.$size) + break a; + if ($e.$array.data[$i].$matches($stringIndex, $testString, $matchResult) >= 0) + return $this.$next0.$matches($stringIndex, $testString, $matchResult); + $i = $i + 1 | 0; + } + return (-1); + } + $testString = new jl_IndexOutOfBoundsException; + $testString.$suppressionEnabled = 1; + $testString.$writableStackTrace = 1; + $rt_throw($testString); +} +function jur_PositiveLookAhead_hasConsumed($this, $matchResult) { + return 0; +} +var jur_NegativeLookAhead = $rt_classWithoutFields(jur_AtomicJointSet); +function jur_NegativeLookAhead__init_(var_0, var_1) { + var var_2 = new jur_NegativeLookAhead(); + jur_NegativeLookAhead__init_0(var_2, var_0, var_1); + return var_2; +} +function jur_NegativeLookAhead__init_0($this, $children, $fSet) { + var var$3, var$4; + var$3 = jur_AbstractSet_counter; + jur_AbstractSet_counter = var$3 + 1 | 0; + var$4 = new jl_AbstractStringBuilder; + jl_Object__init_0(var$4); + var$4.$buffer = $rt_createCharArray(20); + $this.$index1 = (jl_AbstractStringBuilder_insert0(var$4, var$4.$length, var$3, 10)).$toString(); + $this.$children = $children; + $this.$fSet = $fSet; + $this.$groupIndex0 = $fSet.$groupIndex; +} +function jur_NegativeLookAhead_matches($this, $stringIndex, $testString, $matchResult) { + var $size, $i, $e; + $size = $this.$children.$size; + $i = 0; + a: { + while (true) { + if ($i >= $size) + return $this.$next0.$matches($stringIndex, $testString, $matchResult); + $e = $this.$children; + if ($i < 0) + break a; + if ($i >= $e.$size) + break a; + if ($e.$array.data[$i].$matches($stringIndex, $testString, $matchResult) >= 0) + break; + $i = $i + 1 | 0; + } + return (-1); + } + $testString = new jl_IndexOutOfBoundsException; + $testString.$suppressionEnabled = 1; + $testString.$writableStackTrace = 1; + $rt_throw($testString); +} +function jur_NegativeLookAhead_hasConsumed($this, $matchResult) { + return 0; +} +var jur_PositiveLookBehind = $rt_classWithoutFields(jur_AtomicJointSet); +function jur_PositiveLookBehind__init_(var_0, var_1) { + var var_2 = new jur_PositiveLookBehind(); + jur_PositiveLookBehind__init_0(var_2, var_0, var_1); + return var_2; +} +function jur_PositiveLookBehind__init_0($this, $children, $fSet) { + var var$3, var$4; + var$3 = jur_AbstractSet_counter; + jur_AbstractSet_counter = var$3 + 1 | 0; + var$4 = new jl_AbstractStringBuilder; + jl_Object__init_0(var$4); + var$4.$buffer = $rt_createCharArray(20); + $this.$index1 = (jl_AbstractStringBuilder_insert0(var$4, var$4.$length, var$3, 10)).$toString(); + $this.$children = $children; + $this.$fSet = $fSet; + $this.$groupIndex0 = $fSet.$groupIndex; +} +function jur_PositiveLookBehind_matches($this, $stringIndex, $testString, $matchResult) { + var $size, $leftBound, $shift, $i, $e; + $size = $this.$children.$size; + $leftBound = $matchResult.$transparentBounds ? 0 : $matchResult.$leftBound; + a: { + b: { + $shift = $this.$next0.$matches($stringIndex, $testString, $matchResult); + if ($shift >= 0) { + $i = $this.$groupIndex0; + $matchResult.$consumers.data[$i] = $stringIndex; + $i = 0; + while (true) { + if ($i >= $size) + break b; + $e = $this.$children; + if ($i < 0) + break a; + if ($i >= $e.$size) + break a; + if ($e.$array.data[$i].$findBack($leftBound, $stringIndex, $testString, $matchResult) >= 0) { + $stringIndex = $this.$groupIndex0; + $matchResult.$consumers.data[$stringIndex] = (-1); + return $shift; + } + $i = $i + 1 | 0; + } + } + } + return (-1); + } + $testString = new jl_IndexOutOfBoundsException; + $testString.$suppressionEnabled = 1; + $testString.$writableStackTrace = 1; + $rt_throw($testString); +} +function jur_PositiveLookBehind_hasConsumed($this, $matchResult) { + return 0; +} +var jur_NegativeLookBehind = $rt_classWithoutFields(jur_AtomicJointSet); +function jur_NegativeLookBehind__init_(var_0, var_1) { + var var_2 = new jur_NegativeLookBehind(); + jur_NegativeLookBehind__init_0(var_2, var_0, var_1); + return var_2; +} +function jur_NegativeLookBehind__init_0($this, $children, $fSet) { + var var$3, var$4; + var$3 = jur_AbstractSet_counter; + jur_AbstractSet_counter = var$3 + 1 | 0; + var$4 = new jl_AbstractStringBuilder; + jl_Object__init_0(var$4); + var$4.$buffer = $rt_createCharArray(20); + $this.$index1 = (jl_AbstractStringBuilder_insert0(var$4, var$4.$length, var$3, 10)).$toString(); + $this.$children = $children; + $this.$fSet = $fSet; + $this.$groupIndex0 = $fSet.$groupIndex; +} +function jur_NegativeLookBehind_matches($this, $stringIndex, $testString, $matchResult) { + var $size, $i, $e; + $size = $this.$children.$size; + $i = $this.$groupIndex0; + $matchResult.$consumers.data[$i] = $stringIndex; + $i = 0; + a: { + while (true) { + if ($i >= $size) + return $this.$next0.$matches($stringIndex, $testString, $matchResult); + $e = $this.$children; + if ($i < 0) + break a; + if ($i >= $e.$size) + break a; + if ($e.$array.data[$i].$findBack(0, $stringIndex, $testString, $matchResult) >= 0) + break; + $i = $i + 1 | 0; + } + return (-1); + } + $testString = new jl_IndexOutOfBoundsException; + $testString.$suppressionEnabled = 1; + $testString.$writableStackTrace = 1; + $rt_throw($testString); +} +function jur_NegativeLookBehind_hasConsumed($this, $matchResult) { + return 0; +} +function jur_SingleSet() { + jur_JointSet.call(this); + this.$kid = null; +} +function jur_SingleSet__init_(var_0, var_1) { + var var_2 = new jur_SingleSet(); + jur_SingleSet__init_0(var_2, var_0, var_1); + return var_2; +} +function jur_SingleSet__init_0($this, $child, $fSet) { + var var$3, var$4; + var$3 = jur_AbstractSet_counter; + jur_AbstractSet_counter = var$3 + 1 | 0; + var$4 = new jl_AbstractStringBuilder; + var$4.$buffer = $rt_createCharArray(20); + $this.$index1 = (jl_AbstractStringBuilder_insert0(var$4, var$4.$length, var$3, 10)).$toString(); + $this.$kid = $child; + $this.$fSet = $fSet; + $this.$groupIndex0 = $fSet.$groupIndex; +} +function jur_SingleSet_matches($this, $stringIndex, $testString, $matchResult) { + var $shift, var$5, $start; + $shift = $this.$groupIndex0; + var$5 = $matchResult.$groupBounds.data; + $shift = $shift * 2 | 0; + $start = var$5[$shift]; + var$5[$shift] = $stringIndex; + $shift = $this.$kid.$matches($stringIndex, $testString, $matchResult); + if ($shift >= 0) + return $shift; + $shift = $this.$groupIndex0; + $matchResult.$groupBounds.data[$shift * 2 | 0] = $start; + return (-1); +} +function jur_SingleSet_find($this, $stringIndex, $testString, $matchResult) { + var $res; + $res = $this.$kid.$find0($stringIndex, $testString, $matchResult); + if ($res >= 0) { + $stringIndex = $this.$groupIndex0; + $matchResult.$groupBounds.data[$stringIndex * 2 | 0] = $res; + } + return $res; +} +function jur_SingleSet_findBack($this, $stringIndex, $lastIndex, $testString, $matchResult) { + var $res; + $res = $this.$kid.$findBack($stringIndex, $lastIndex, $testString, $matchResult); + if ($res >= 0) { + $stringIndex = $this.$groupIndex0; + $matchResult.$groupBounds.data[$stringIndex * 2 | 0] = $res; + } + return $res; +} +function jur_SingleSet_first($this, $set) { + return $this.$kid.$first($set); +} +function jur_SingleSet_processBackRefReplacement($this) { + var $set, var$2, var$3, var$4, var$5; + $set = new jur_BackReferencedSingleSet; + var$2 = $this.$kid; + var$3 = $this.$fSet; + var$4 = jur_AbstractSet_counter; + jur_AbstractSet_counter = var$4 + 1 | 0; + var$5 = new jl_AbstractStringBuilder; + jl_Object__init_0(var$5); + var$5.$buffer = $rt_createCharArray(20); + $set.$index1 = (jl_AbstractStringBuilder_insert0(var$5, var$5.$length, var$4, 10)).$toString(); + $set.$kid = var$2; + $set.$fSet = var$3; + $set.$groupIndex0 = var$3.$groupIndex; + $this.$next0 = $set; + return $set; +} +function jur_SingleSet_processSecondPass($this) { + var $set; + $this.$isSecondPassVisited = 1; + $set = $this.$fSet; + if ($set !== null && !$set.$isSecondPassVisited) + jur_AbstractSet_processSecondPass($set); + $set = $this.$kid; + if ($set !== null && !$set.$isSecondPassVisited) { + $set = $set.$processBackRefReplacement(); + if ($set !== null) { + $this.$kid.$isSecondPassVisited = 1; + $this.$kid = $set; + } + $this.$kid.$processSecondPass(); + } +} +var jl_ArrayStoreException = $rt_classWithoutFields(jl_RuntimeException); +var jur_SpecialToken = $rt_classWithoutFields(); +function jur_AbstractCharClass() { + var a = this; jur_SpecialToken.call(a); + a.$alt0 = 0; + a.$altSurrogates = 0; + a.$lowHighSurrogates = null; + a.$charClassWithoutSurrogates = null; + a.$charClassWithSurrogates = null; + a.$mayContainSupplCodepoints = 0; +} +var jur_AbstractCharClass_charClasses = null; +function jur_AbstractCharClass_getBits($this) { + return null; +} +function jur_AbstractCharClass_getLowHighSurrogates($this) { + return $this.$lowHighSurrogates; +} +function jur_AbstractCharClass_hasLowHighSurrogates($this) { + return !$this.$altSurrogates ? (ju_BitSet_nextSetBit($this.$lowHighSurrogates, 0) >= 2048 ? 0 : 1) : ju_BitSet_nextClearBit($this.$lowHighSurrogates, 0) >= 2048 ? 0 : 1; +} +function jur_AbstractCharClass_mayContainSupplCodepoints($this) { + return $this.$mayContainSupplCodepoints; +} +function jur_AbstractCharClass_getInstance($this) { + return $this; +} +function jur_AbstractCharClass_getSurrogates($this) { + var $lHS, var$2; + if ($this.$charClassWithSurrogates === null) { + $lHS = $this.$getLowHighSurrogates(); + var$2 = new jur_AbstractCharClass$1; + var$2.$this$0 = $this; + var$2.$val$lHS = $lHS; + $lHS = new ju_BitSet; + $lHS.$data0 = $rt_createIntArray(64); + var$2.$lowHighSurrogates = $lHS; + $this.$charClassWithSurrogates = var$2; + jur_AbstractCharClass_setNegative(var$2, $this.$altSurrogates); + } + return $this.$charClassWithSurrogates; +} +function jur_AbstractCharClass_getWithoutSurrogates($this) { + var $lHS, var$2; + if ($this.$charClassWithoutSurrogates === null) { + $lHS = $this.$getLowHighSurrogates(); + var$2 = new jur_AbstractCharClass$2; + var$2.$this$00 = $this; + var$2.$val$lHS0 = $lHS; + var$2.$val$thisClass = $this; + $lHS = new ju_BitSet; + $lHS.$data0 = $rt_createIntArray(64); + var$2.$lowHighSurrogates = $lHS; + $this.$charClassWithoutSurrogates = var$2; + jur_AbstractCharClass_setNegative(var$2, $this.$alt0); + $this.$charClassWithoutSurrogates.$mayContainSupplCodepoints = $this.$mayContainSupplCodepoints; + } + return $this.$charClassWithoutSurrogates; +} +function jur_AbstractCharClass_hasUCI($this) { + return 0; +} +function jur_AbstractCharClass_setNegative($this, $value) { + var var$2; + var$2 = $this.$alt0; + if (var$2 ^ $value) { + $this.$alt0 = var$2 ? 0 : 1; + $this.$altSurrogates = $this.$altSurrogates ? 0 : 1; + } + if (!$this.$mayContainSupplCodepoints) + $this.$mayContainSupplCodepoints = 1; + return $this; +} +function jur_AbstractCharClass_isNegative($this) { + return $this.$alt0; +} +function jur_AbstractCharClass_getPredefinedClass($name, $negative) { + $name = jur_AbstractCharClass$PredefinedCharacterClasses_getObject(jur_AbstractCharClass_charClasses, $name); + if (!$negative && $name.$posValue === null) + $name.$posValue = $name.$computeValue(); + else if ($negative && $name.$negValue === null) + $name.$negValue = jur_AbstractCharClass_setNegative($name.$computeValue(), 1); + return $negative ? $name.$negValue : $name.$posValue; +} +function jur_AbstractCharClass__clinit_() { + jur_AbstractCharClass_charClasses = new jur_AbstractCharClass$PredefinedCharacterClasses; +} +function jur_CharClass() { + var a = this; jur_AbstractCharClass.call(a); + a.$ci = 0; + a.$uci = 0; + a.$hasUCI0 = 0; + a.$invertedSurrogates = 0; + a.$inverted = 0; + a.$hideBits = 0; + a.$bits = null; + a.$nonBitSet = null; +} +function jur_CharClass_add($this, $ch) { + var var$2; + a: { + if ($this.$ci) { + b: { + if (!($ch >= 97 && $ch <= 122)) { + if ($ch < 65) + break b; + if ($ch > 90) + break b; + } + if ($this.$inverted) { + ju_BitSet_clear($this.$bits, jur_Pattern_getSupplement($ch & 65535)); + break a; + } + ju_BitSet_set($this.$bits, jur_Pattern_getSupplement($ch & 65535)); + break a; + } + if ($this.$uci && $ch > 128) { + $this.$hasUCI0 = 1; + $ch = (String.fromCharCode((String.fromCharCode($ch)).toUpperCase().charCodeAt(0))).toLowerCase().charCodeAt(0); + } + } + } + var$2 = $ch <= 56319 && $ch >= 55296 ? 1 : 0; + if (!(!var$2 && !($ch <= 57343 && $ch >= 56320 ? 1 : 0))) { + if ($this.$invertedSurrogates) + ju_BitSet_clear($this.$lowHighSurrogates, $ch - 55296 | 0); + else + ju_BitSet_set($this.$lowHighSurrogates, $ch - 55296 | 0); + } + if ($this.$inverted) + ju_BitSet_clear($this.$bits, $ch); + else + ju_BitSet_set($this.$bits, $ch); + if (!$this.$mayContainSupplCodepoints && ($ch >= 65536 && $ch <= 1114111 ? 1 : 0)) + $this.$mayContainSupplCodepoints = 1; + return $this; +} +function jur_CharClass_add1($this, $cc) { + var $curAlt, $nb, var$4; + if (!$this.$mayContainSupplCodepoints && $cc.$mayContainSupplCodepoints) + $this.$mayContainSupplCodepoints = 1; + if ($this.$invertedSurrogates) { + if (!$cc.$altSurrogates) + ju_BitSet_andNot($this.$lowHighSurrogates, $cc.$getLowHighSurrogates()); + else + ju_BitSet_and($this.$lowHighSurrogates, $cc.$getLowHighSurrogates()); + } else if (!$cc.$altSurrogates) + ju_BitSet_or($this.$lowHighSurrogates, $cc.$getLowHighSurrogates()); + else { + ju_BitSet_xor($this.$lowHighSurrogates, $cc.$getLowHighSurrogates()); + ju_BitSet_and($this.$lowHighSurrogates, $cc.$getLowHighSurrogates()); + $this.$altSurrogates = $this.$altSurrogates ? 0 : 1; + $this.$invertedSurrogates = 1; + } + if (!$this.$hideBits && $cc.$getBits() !== null) { + if ($this.$inverted) { + if (!$cc.$alt0) + ju_BitSet_andNot($this.$bits, $cc.$getBits()); + else + ju_BitSet_and($this.$bits, $cc.$getBits()); + } else if (!$cc.$alt0) + ju_BitSet_or($this.$bits, $cc.$getBits()); + else { + ju_BitSet_xor($this.$bits, $cc.$getBits()); + ju_BitSet_and($this.$bits, $cc.$getBits()); + $this.$alt0 = $this.$alt0 ? 0 : 1; + $this.$inverted = 1; + } + } else { + $curAlt = $this.$alt0; + $nb = $this.$nonBitSet; + if ($nb !== null) { + if (!$curAlt) { + var$4 = new jur_CharClass$5; + var$4.$this$01 = $this; + var$4.$val$curAlt = $curAlt; + var$4.$val$nb = $nb; + var$4.$val$cc = $cc; + $cc = new ju_BitSet; + $cc.$data0 = $rt_createIntArray(64); + var$4.$lowHighSurrogates = $cc; + $this.$nonBitSet = var$4; + } else { + var$4 = new jur_CharClass$4; + var$4.$this$02 = $this; + var$4.$val$curAlt0 = $curAlt; + var$4.$val$nb0 = $nb; + var$4.$val$cc0 = $cc; + $cc = new ju_BitSet; + $cc.$data0 = $rt_createIntArray(64); + var$4.$lowHighSurrogates = $cc; + $this.$nonBitSet = var$4; + } + } else { + if ($curAlt && !$this.$inverted && ($this.$bits.$length2 ? 0 : 1)) { + $nb = new jur_CharClass$1; + $nb.$this$03 = $this; + $nb.$val$cc1 = $cc; + $cc = new ju_BitSet; + $cc.$data0 = $rt_createIntArray(64); + $nb.$lowHighSurrogates = $cc; + $this.$nonBitSet = $nb; + } else if (!$curAlt) { + $nb = new jur_CharClass$3; + $nb.$this$04 = $this; + $nb.$val$curAlt1 = $curAlt; + $nb.$val$cc2 = $cc; + $cc = new ju_BitSet; + $cc.$data0 = $rt_createIntArray(64); + $nb.$lowHighSurrogates = $cc; + $this.$nonBitSet = $nb; + } else { + $nb = new jur_CharClass$2; + $nb.$this$05 = $this; + $nb.$val$curAlt2 = $curAlt; + $nb.$val$cc3 = $cc; + $cc = new ju_BitSet; + $cc.$data0 = $rt_createIntArray(64); + $nb.$lowHighSurrogates = $cc; + $this.$nonBitSet = $nb; + } + $this.$hideBits = 1; + } + } + return $this; +} +function jur_CharClass_add0($this, $i, $end) { + var var$3; + if ($i > $end) { + var$3 = new jl_IllegalArgumentException; + var$3.$suppressionEnabled = 1; + var$3.$writableStackTrace = 1; + $rt_throw(var$3); + } + a: { + b: { + if (!$this.$ci) { + if ($end < 55296) + break b; + if ($i > 57343) + break b; + } + $end = $end + 1 | 0; + while (true) { + if ($i >= $end) + break a; + jur_CharClass_add($this, $i); + $i = $i + 1 | 0; + } + } + if ($this.$inverted) + ju_BitSet_clear0($this.$bits, $i, $end + 1 | 0); + else + ju_BitSet_set0($this.$bits, $i, $end + 1 | 0); + } + return $this; +} +function jur_CharClass_union($this, $clazz) { + var $curAlt, var$3, $nb, var$5; + if (!$this.$mayContainSupplCodepoints && $clazz.$mayContainSupplCodepoints) + $this.$mayContainSupplCodepoints = 1; + if ($clazz.$hasUCI0) + $this.$hasUCI0 = 1; + $curAlt = $this.$altSurrogates; + if (!($curAlt ^ $clazz.$altSurrogates)) { + if (!$curAlt) + ju_BitSet_or($this.$lowHighSurrogates, $clazz.$lowHighSurrogates); + else + ju_BitSet_and($this.$lowHighSurrogates, $clazz.$lowHighSurrogates); + } else if ($curAlt) + ju_BitSet_andNot($this.$lowHighSurrogates, $clazz.$lowHighSurrogates); + else { + ju_BitSet_xor($this.$lowHighSurrogates, $clazz.$lowHighSurrogates); + ju_BitSet_and($this.$lowHighSurrogates, $clazz.$lowHighSurrogates); + $this.$altSurrogates = 1; + } + a: { + if (!$this.$hideBits) { + var$3 = $clazz.$hideBits; + if ((!var$3 ? $clazz.$bits : null) !== null) { + $curAlt = $this.$alt0; + if (!($curAlt ^ $clazz.$alt0)) { + if (!$curAlt) { + ju_BitSet_or($this.$bits, !var$3 ? $clazz.$bits : null); + break a; + } + ju_BitSet_and($this.$bits, !var$3 ? $clazz.$bits : null); + break a; + } + if ($curAlt) { + ju_BitSet_andNot($this.$bits, !var$3 ? $clazz.$bits : null); + break a; + } + ju_BitSet_xor($this.$bits, !var$3 ? $clazz.$bits : null); + ju_BitSet_and($this.$bits, !$clazz.$hideBits ? $clazz.$bits : null); + $this.$alt0 = 1; + break a; + } + } + $curAlt = $this.$alt0; + $nb = $this.$nonBitSet; + if ($nb !== null) { + if (!$curAlt) { + var$5 = new jur_CharClass$11; + var$5.$this$06 = $this; + var$5.$val$curAlt3 = $curAlt; + var$5.$val$nb1 = $nb; + var$5.$val$clazz = $clazz; + $clazz = new ju_BitSet; + $clazz.$data0 = $rt_createIntArray(64); + var$5.$lowHighSurrogates = $clazz; + $this.$nonBitSet = var$5; + } else { + var$5 = new jur_CharClass$10; + var$5.$this$07 = $this; + var$5.$val$curAlt4 = $curAlt; + var$5.$val$nb2 = $nb; + var$5.$val$clazz0 = $clazz; + $clazz = new ju_BitSet; + $clazz.$data0 = $rt_createIntArray(64); + var$5.$lowHighSurrogates = $clazz; + $this.$nonBitSet = var$5; + } + } else { + if (!$this.$inverted && ($this.$bits.$length2 ? 0 : 1)) { + if (!$curAlt) { + $nb = new jur_CharClass$7; + $nb.$this$08 = $this; + $nb.$val$clazz1 = $clazz; + $clazz = new ju_BitSet; + $clazz.$data0 = $rt_createIntArray(64); + $nb.$lowHighSurrogates = $clazz; + $this.$nonBitSet = $nb; + } else { + $nb = new jur_CharClass$6; + $nb.$this$09 = $this; + $nb.$val$clazz2 = $clazz; + $clazz = new ju_BitSet; + $clazz.$data0 = $rt_createIntArray(64); + $nb.$lowHighSurrogates = $clazz; + $this.$nonBitSet = $nb; + } + } else if (!$curAlt) { + $nb = new jur_CharClass$9; + $nb.$this$010 = $this; + $nb.$val$clazz3 = $clazz; + $nb.$val$curAlt5 = $curAlt; + $clazz = new ju_BitSet; + $clazz.$data0 = $rt_createIntArray(64); + $nb.$lowHighSurrogates = $clazz; + $this.$nonBitSet = $nb; + } else { + $nb = new jur_CharClass$8; + $nb.$this$011 = $this; + $nb.$val$clazz4 = $clazz; + $nb.$val$curAlt6 = $curAlt; + $clazz = new ju_BitSet; + $clazz.$data0 = $rt_createIntArray(64); + $nb.$lowHighSurrogates = $clazz; + $this.$nonBitSet = $nb; + } + $this.$hideBits = 1; + } + } +} +function jur_CharClass_intersection($this, $clazz) { + var $curAlt, var$3, $nb, var$5; + if (!$this.$mayContainSupplCodepoints && $clazz.$mayContainSupplCodepoints) + $this.$mayContainSupplCodepoints = 1; + if ($clazz.$hasUCI0) + $this.$hasUCI0 = 1; + $curAlt = $this.$altSurrogates; + if (!($curAlt ^ $clazz.$altSurrogates)) { + if (!$curAlt) + ju_BitSet_and($this.$lowHighSurrogates, $clazz.$lowHighSurrogates); + else + ju_BitSet_or($this.$lowHighSurrogates, $clazz.$lowHighSurrogates); + } else if (!$curAlt) + ju_BitSet_andNot($this.$lowHighSurrogates, $clazz.$lowHighSurrogates); + else { + ju_BitSet_xor($this.$lowHighSurrogates, $clazz.$lowHighSurrogates); + ju_BitSet_and($this.$lowHighSurrogates, $clazz.$lowHighSurrogates); + $this.$altSurrogates = 0; + } + a: { + if (!$this.$hideBits) { + var$3 = $clazz.$hideBits; + if ((!var$3 ? $clazz.$bits : null) !== null) { + $curAlt = $this.$alt0; + if (!($curAlt ^ $clazz.$alt0)) { + if (!$curAlt) { + ju_BitSet_and($this.$bits, !var$3 ? $clazz.$bits : null); + break a; + } + ju_BitSet_or($this.$bits, !var$3 ? $clazz.$bits : null); + break a; + } + if (!$curAlt) { + ju_BitSet_andNot($this.$bits, !var$3 ? $clazz.$bits : null); + break a; + } + ju_BitSet_xor($this.$bits, !var$3 ? $clazz.$bits : null); + ju_BitSet_and($this.$bits, !$clazz.$hideBits ? $clazz.$bits : null); + $this.$alt0 = 0; + break a; + } + } + $curAlt = $this.$alt0; + $nb = $this.$nonBitSet; + if ($nb !== null) { + if (!$curAlt) { + var$5 = new jur_CharClass$17; + var$5.$this$012 = $this; + var$5.$val$curAlt7 = $curAlt; + var$5.$val$nb3 = $nb; + var$5.$val$clazz5 = $clazz; + $clazz = new ju_BitSet; + $clazz.$data0 = $rt_createIntArray(64); + var$5.$lowHighSurrogates = $clazz; + $this.$nonBitSet = var$5; + } else { + var$5 = new jur_CharClass$16; + var$5.$this$013 = $this; + var$5.$val$curAlt8 = $curAlt; + var$5.$val$nb4 = $nb; + var$5.$val$clazz6 = $clazz; + $clazz = new ju_BitSet; + $clazz.$data0 = $rt_createIntArray(64); + var$5.$lowHighSurrogates = $clazz; + $this.$nonBitSet = var$5; + } + } else { + if (!$this.$inverted && ($this.$bits.$length2 ? 0 : 1)) { + if (!$curAlt) { + $nb = new jur_CharClass$13; + $nb.$this$014 = $this; + $nb.$val$clazz7 = $clazz; + $clazz = new ju_BitSet; + $clazz.$data0 = $rt_createIntArray(64); + $nb.$lowHighSurrogates = $clazz; + $this.$nonBitSet = $nb; + } else { + $nb = new jur_CharClass$12; + $nb.$this$015 = $this; + $nb.$val$clazz8 = $clazz; + $clazz = new ju_BitSet; + $clazz.$data0 = $rt_createIntArray(64); + $nb.$lowHighSurrogates = $clazz; + $this.$nonBitSet = $nb; + } + } else if (!$curAlt) { + $nb = new jur_CharClass$15; + $nb.$this$016 = $this; + $nb.$val$clazz9 = $clazz; + $nb.$val$curAlt9 = $curAlt; + $clazz = new ju_BitSet; + $clazz.$data0 = $rt_createIntArray(64); + $nb.$lowHighSurrogates = $clazz; + $this.$nonBitSet = $nb; + } else { + $nb = new jur_CharClass$14; + $nb.$this$017 = $this; + $nb.$val$clazz10 = $clazz; + $nb.$val$curAlt10 = $curAlt; + $clazz = new ju_BitSet; + $clazz.$data0 = $rt_createIntArray(64); + $nb.$lowHighSurrogates = $clazz; + $this.$nonBitSet = $nb; + } + $this.$hideBits = 1; + } + } +} +function jur_CharClass_contains($this, $ch) { + var var$2, var$3, var$4, var$5; + var$2 = $this.$nonBitSet; + if (var$2 !== null) + return $this.$alt0 ^ var$2.$contains($ch); + var$3 = $this.$alt0; + var$2 = $this.$bits; + var$4 = $ch / 32 | 0; + var$5 = var$2.$data0.data; + return var$3 ^ (var$4 < var$5.length && var$5[var$4] & 1 << ($ch % 32 | 0) ? 1 : 0); +} +function jur_CharClass_getBits($this) { + if (!$this.$hideBits) + return $this.$bits; + return null; +} +function jur_CharClass_getLowHighSurrogates($this) { + return $this.$lowHighSurrogates; +} +function jur_CharClass_getInstance($this) { + var $bs, $res; + if ($this.$nonBitSet !== null) + return $this; + $bs = !$this.$hideBits ? $this.$bits : null; + $res = new jur_CharClass$18; + $res.$this$018 = $this; + $res.$val$bs = $bs; + $bs = new ju_BitSet; + $bs.$data0 = $rt_createIntArray(64); + $res.$lowHighSurrogates = $bs; + return jur_AbstractCharClass_setNegative($res, $this.$alt0); +} +function jur_CharClass_toString($this) { + var $temp, $i, var$3, var$4, var$5, var$6, var$7, var$8, var$9, var$10, var$11; + $temp = new jl_StringBuilder; + $temp.$buffer = $rt_createCharArray(16); + $i = ju_BitSet_nextSetBit($this.$bits, 0); + while ($i >= 0) { + if ($i < 65536) { + var$3 = $rt_createCharArray(1); + var$3.data[0] = $i & 65535; + } else + var$3 = $rt_createCharArrayFromData([(55296 | ($i - 65536 | 0) >> 10 & 1023) & 65535, (56320 | $i & 1023) & 65535]); + var$4 = var$3.data; + var$5 = 0; + var$6 = var$4.length; + var$7 = $temp.$length; + jl_AbstractStringBuilder_insertSpace($temp, var$7, var$7 + var$6 | 0); + var$6 = var$6 + var$5 | 0; + while (var$5 < var$6) { + var$3 = $temp.$buffer.data; + var$8 = var$7 + 1 | 0; + var$9 = var$5 + 1 | 0; + var$3[var$7] = var$4[var$5]; + var$7 = var$8; + var$5 = var$9; + } + var$6 = $temp.$length; + jl_AbstractStringBuilder_insertSpace($temp, var$6, var$6 + 1 | 0); + $temp.$buffer.data[var$6] = 124; + $i = ju_BitSet_nextSetBit($this.$bits, $i + 1 | 0); + } + var$7 = $temp.$length; + if (var$7 > 0) + jl_AbstractStringBuilder_deleteCharAt($temp, var$7 - 1 | 0); + var$10 = new jl_String; + var$3 = $temp.$buffer; + var$7 = $temp.$length; + var$4 = $rt_createCharArray(var$7); + var$11 = var$4.data; + var$10.$characters = var$4; + var$9 = 0; + while (var$9 < var$7) { + var$11[var$9] = var$3.data[var$9 + 0 | 0]; + var$9 = var$9 + 1 | 0; + } + return var$10; +} +function jur_CharClass_hasUCI($this) { + return $this.$hasUCI0; +} +function ju_MissingResourceException() { + var a = this; jl_RuntimeException.call(a); + a.$className = null; + a.$key = null; +} +function jur_QuantifierSet() { + jur_AbstractSet.call(this); + this.$innerSet = null; +} +function jur_QuantifierSet_getInnerSet($this) { + return $this.$innerSet; +} +function jur_QuantifierSet_first($this, $set) { + return !$this.$innerSet.$first($set) && !$this.$next0.$first($set) ? 0 : 1; +} +function jur_QuantifierSet_hasConsumed($this, $mr) { + return 1; +} +function jur_QuantifierSet_processSecondPass($this) { + var $set; + $this.$isSecondPassVisited = 1; + $set = $this.$next0; + if ($set !== null && !$set.$isSecondPassVisited) { + $set = $set.$processBackRefReplacement(); + if ($set !== null) { + $this.$next0.$isSecondPassVisited = 1; + $this.$next0 = $set; + } + $this.$next0.$processSecondPass(); + } + $set = $this.$innerSet; + if ($set !== null) { + if (!$set.$isSecondPassVisited) { + $set = $set.$processBackRefReplacement(); + if ($set !== null) { + $this.$innerSet.$isSecondPassVisited = 1; + $this.$innerSet = $set; + } + $this.$innerSet.$processSecondPass(); + } else if ($set instanceof jur_SingleSet && $set.$fSet.$isBackReferenced) + $this.$innerSet = $set.$next0; + } +} +function jur_LeafQuantifierSet() { + jur_QuantifierSet.call(this); + this.$leaf = null; +} +function jur_LeafQuantifierSet__init_(var_0, var_1, var_2) { + var var_3 = new jur_LeafQuantifierSet(); + jur_LeafQuantifierSet__init_0(var_3, var_0, var_1, var_2); + return var_3; +} +function jur_LeafQuantifierSet__init_0($this, $innerSet, $next, $type) { + var var$4, var$5; + var$4 = jur_AbstractSet_counter; + jur_AbstractSet_counter = var$4 + 1 | 0; + var$5 = new jl_AbstractStringBuilder; + var$5.$buffer = $rt_createCharArray(20); + $this.$index1 = (jl_AbstractStringBuilder_insert0(var$5, var$5.$length, var$4, 10)).$toString(); + $this.$next0 = $next; + $this.$innerSet = $innerSet; + $this.$type = $type; + $this.$leaf = $innerSet; +} +function jur_LeafQuantifierSet_matches($this, $stringIndex, $testString, $matchResult) { + var $i, var$5; + $i = 0; + a: { + while (($stringIndex + $this.$leaf.$charCount0() | 0) <= $matchResult.$rightBound) { + var$5 = $this.$leaf.$accepts($stringIndex, $testString); + if (var$5 <= 0) + break a; + $stringIndex = $stringIndex + var$5 | 0; + $i = $i + 1 | 0; + } + } + while (true) { + if ($i < 0) + return (-1); + var$5 = $this.$next0.$matches($stringIndex, $testString, $matchResult); + if (var$5 >= 0) + break; + $stringIndex = $stringIndex - $this.$leaf.$charCount0() | 0; + $i = $i + (-1) | 0; + } + return var$5; +} +function jur_CompositeQuantifierSet() { + jur_LeafQuantifierSet.call(this); + this.$quantifier0 = null; +} +function jur_CompositeQuantifierSet__init_(var_0, var_1, var_2, var_3) { + var var_4 = new jur_CompositeQuantifierSet(); + jur_CompositeQuantifierSet__init_0(var_4, var_0, var_1, var_2, var_3); + return var_4; +} +function jur_CompositeQuantifierSet__init_0($this, $quant, $innerSet, $next, $type) { + var var$5, var$6; + var$5 = jur_AbstractSet_counter; + jur_AbstractSet_counter = var$5 + 1 | 0; + var$6 = new jl_AbstractStringBuilder; + var$6.$buffer = $rt_createCharArray(20); + $this.$index1 = (jl_AbstractStringBuilder_insert0(var$6, var$6.$length, var$5, 10)).$toString(); + $this.$next0 = $next; + $this.$innerSet = $innerSet; + $this.$type = $type; + $this.$leaf = $innerSet; + $this.$quantifier0 = $quant; +} +function jur_CompositeQuantifierSet_matches($this, $stringIndex, $testString, $matchResult) { + var var$4, $min, $max, $i, $shift; + var$4 = $this.$quantifier0; + $min = var$4.$min; + $max = var$4.$max; + $i = 0; + while (true) { + if ($i >= $min) { + a: { + while ($i < $max) { + if (($stringIndex + $this.$leaf.$charCount0() | 0) > $matchResult.$rightBound) + break a; + $shift = $this.$leaf.$accepts($stringIndex, $testString); + if ($shift < 1) + break a; + $stringIndex = $stringIndex + $shift | 0; + $i = $i + 1 | 0; + } + } + while (true) { + if ($i < $min) + return (-1); + $shift = $this.$next0.$matches($stringIndex, $testString, $matchResult); + if ($shift >= 0) + break; + $stringIndex = $stringIndex - $this.$leaf.$charCount0() | 0; + $i = $i + (-1) | 0; + } + return $shift; + } + if (($stringIndex + $this.$leaf.$charCount0() | 0) > $matchResult.$rightBound) { + $matchResult.$hitEnd = 1; + return (-1); + } + $shift = $this.$leaf.$accepts($stringIndex, $testString); + if ($shift < 1) + break; + $stringIndex = $stringIndex + $shift | 0; + $i = $i + 1 | 0; + } + return (-1); +} +var jur_GroupQuantifierSet = $rt_classWithoutFields(jur_QuantifierSet); +function jur_GroupQuantifierSet__init_(var_0, var_1, var_2) { + var var_3 = new jur_GroupQuantifierSet(); + jur_GroupQuantifierSet__init_0(var_3, var_0, var_1, var_2); + return var_3; +} +function jur_GroupQuantifierSet__init_0($this, $innerSet, $next, $type) { + var var$4, var$5; + var$4 = jur_AbstractSet_counter; + jur_AbstractSet_counter = var$4 + 1 | 0; + var$5 = new jl_AbstractStringBuilder; + var$5.$buffer = $rt_createCharArray(20); + $this.$index1 = (jl_AbstractStringBuilder_insert0(var$5, var$5.$length, var$4, 10)).$toString(); + $this.$next0 = $next; + $this.$innerSet = $innerSet; + $this.$type = $type; +} +function jur_GroupQuantifierSet_matches($this, $stringIndex, $testString, $matchResult) { + var $nextIndex; + if (!$this.$innerSet.$hasConsumed($matchResult)) + return $this.$next0.$matches($stringIndex, $testString, $matchResult); + $nextIndex = $this.$innerSet.$matches($stringIndex, $testString, $matchResult); + if ($nextIndex >= 0) + return $nextIndex; + return $this.$next0.$matches($stringIndex, $testString, $matchResult); +} +var jur_AltQuantifierSet = $rt_classWithoutFields(jur_LeafQuantifierSet); +function jur_AltQuantifierSet__init_(var_0, var_1, var_2) { + var var_3 = new jur_AltQuantifierSet(); + jur_AltQuantifierSet__init_0(var_3, var_0, var_1, var_2); + return var_3; +} +function jur_AltQuantifierSet__init_0($this, $innerSet, $next, $type) { + var var$4, var$5; + var$4 = jur_AbstractSet_counter; + jur_AbstractSet_counter = var$4 + 1 | 0; + var$5 = new jl_AbstractStringBuilder; + var$5.$buffer = $rt_createCharArray(20); + $this.$index1 = (jl_AbstractStringBuilder_insert0(var$5, var$5.$length, var$4, 10)).$toString(); + $this.$next0 = $next; + $this.$innerSet = $innerSet; + $this.$type = $type; + $this.$leaf = $innerSet; +} +function jur_AltQuantifierSet_matches($this, $stringIndex, $testString, $matchResult) { + var $shift; + $shift = $this.$innerSet.$matches($stringIndex, $testString, $matchResult); + if ($shift < 0) + $shift = $this.$next0.$matches($stringIndex, $testString, $matchResult); + return $shift; +} +function jur_AltQuantifierSet_setNext($this, $next) { + $this.$next0 = $next; + $this.$innerSet.$setNext($next); +} +var jur_UnifiedQuantifierSet = $rt_classWithoutFields(jur_LeafQuantifierSet); +function jur_UnifiedQuantifierSet__init_(var_0) { + var var_1 = new jur_UnifiedQuantifierSet(); + jur_UnifiedQuantifierSet__init_0(var_1, var_0); + return var_1; +} +function jur_UnifiedQuantifierSet__init_0($this, $quant) { + var var$2, var$3, var$4, var$5; + var$2 = $quant.$innerSet; + var$3 = $quant.$next0; + var$4 = $quant.$type; + var$5 = jur_AbstractSet_counter; + jur_AbstractSet_counter = var$5 + 1 | 0; + $quant = new jl_AbstractStringBuilder; + $quant.$buffer = $rt_createCharArray(20); + $this.$index1 = (jl_AbstractStringBuilder_insert0($quant, $quant.$length, var$5, 10)).$toString(); + $this.$next0 = var$3; + $this.$innerSet = var$2; + $this.$type = var$4; + $this.$leaf = var$2; + var$2.$setNext($this); +} +function jur_UnifiedQuantifierSet_matches($this, $stringIndex, $testString, $matchResult) { + while (($stringIndex + $this.$leaf.$charCount0() | 0) <= $matchResult.$rightBound && $this.$leaf.$accepts($stringIndex, $testString) > 0) { + $stringIndex = $stringIndex + $this.$leaf.$charCount0() | 0; + } + return $this.$next0.$matches($stringIndex, $testString, $matchResult); +} +function jur_UnifiedQuantifierSet_find($this, $stringIndex, $testString, $matchResult) { + var $startSearch, $newSearch, $newSearch_0; + $startSearch = $this.$next0.$find0($stringIndex, $testString, $matchResult); + if ($startSearch < 0) + return (-1); + $newSearch = $startSearch - $this.$leaf.$charCount0() | 0; + while ($newSearch >= $stringIndex && $this.$leaf.$accepts($newSearch, $testString) > 0) { + $newSearch_0 = $newSearch - $this.$leaf.$charCount0() | 0; + $startSearch = $newSearch; + $newSearch = $newSearch_0; + } + return $startSearch; +} +function jur_AbstractCharClass$LazyCharClass() { + var a = this; jl_Object.call(a); + a.$posValue = null; + a.$negValue = null; +} +function jur_AbstractCharClass$LazyCharClass_getValue($this, $negative) { + if (!$negative && $this.$posValue === null) + $this.$posValue = $this.$computeValue(); + else if ($negative && $this.$negValue === null) + $this.$negValue = jur_AbstractCharClass_setNegative($this.$computeValue(), 1); + if ($negative) + return $this.$negValue; + return $this.$posValue; +} +var jl_NumberFormatException = $rt_classWithoutFields(jl_IllegalArgumentException); +function jl_NumberFormatException__init_0(var_0) { + var var_1 = new jl_NumberFormatException(); + jl_NumberFormatException__init_(var_1, var_0); + return var_1; +} +function jl_NumberFormatException__init_($this, $message) { + $this.$suppressionEnabled = 1; + $this.$writableStackTrace = 1; + $this.$message = $message; +} +function jur_Quantifier() { + var a = this; jur_SpecialToken.call(a); + a.$min = 0; + a.$max = 0; +} +function jur_Quantifier_toString($this) { + var var$1, var$2, var$3, var$4, var$5, var$6, var$7, var$8; + var$1 = new jl_StringBuilder; + var$1.$buffer = $rt_createCharArray(16); + jl_AbstractStringBuilder_insert(var$1, var$1.$length, $rt_s(71)); + var$2 = $this.$min; + jl_AbstractStringBuilder_insert0(var$1, var$1.$length, var$2, 10); + jl_AbstractStringBuilder_insert(var$1, var$1.$length, $rt_s(72)); + var$3 = $this.$max; + if (var$3 == 2147483647) + var$4 = $rt_s(47); + else { + var$4 = new jl_AbstractStringBuilder; + var$4.$buffer = $rt_createCharArray(20); + var$4 = (jl_AbstractStringBuilder_insert0(var$4, var$4.$length, var$3, 10)).$toString(); + } + jl_AbstractStringBuilder_insert(var$1, var$1.$length, var$4); + jl_AbstractStringBuilder_insert(var$1, var$1.$length, $rt_s(73)); + var$4 = new jl_String; + var$5 = var$1.$buffer; + var$3 = var$1.$length; + var$6 = $rt_createCharArray(var$3); + var$7 = var$6.data; + var$4.$characters = var$6; + var$8 = 0; + while (var$8 < var$3) { + var$7[var$8] = var$5.data[var$8 + 0 | 0]; + var$8 = var$8 + 1 | 0; + } + return var$4; +} +var jur_FSet$PossessiveFSet = $rt_classWithoutFields(jur_AbstractSet); +function jur_FSet$PossessiveFSet_matches($this, $stringIndex, $testString, $matchResult) { + return $stringIndex; +} +function jur_FSet$PossessiveFSet_hasConsumed($this, $mr) { + return 0; +} +function ju_BitSet() { + var a = this; jl_Object.call(a); + a.$data0 = null; + a.$length2 = 0; +} +function ju_BitSet_set($this, $bitIndex) { + var $index, var$3; + $index = $bitIndex / 32 | 0; + if ($bitIndex >= $this.$length2) { + ju_BitSet_ensureCapacity($this, $index + 1 | 0); + $this.$length2 = $bitIndex + 1 | 0; + } + var$3 = $this.$data0.data; + var$3[$index] = var$3[$index] | 1 << ($bitIndex % 32 | 0); +} +function ju_BitSet_set0($this, $fromIndex, $toIndex) { + var var$3, $fromDataIndex, $toDataIndex, var$6, var$7, $i; + if ($fromIndex > $toIndex) { + var$3 = new jl_IndexOutOfBoundsException; + var$3.$suppressionEnabled = 1; + var$3.$writableStackTrace = 1; + $rt_throw(var$3); + } + $fromDataIndex = $fromIndex / 32 | 0; + $toDataIndex = $toIndex / 32 | 0; + if ($toIndex > $this.$length2) { + ju_BitSet_ensureCapacity($this, $toDataIndex + 1 | 0); + $this.$length2 = $toIndex; + } + if ($fromDataIndex == $toDataIndex) { + var$6 = $this.$data0.data; + $toDataIndex = var$6[$fromDataIndex]; + var$7 = (-1) << ($fromIndex % 32 | 0); + $fromIndex = $toIndex % 32 | 0; + var$6[$fromDataIndex] = $toDataIndex | var$7 & (!$fromIndex ? 0 : (-1) >>> (32 - $fromIndex | 0)); + } else { + var$6 = $this.$data0.data; + var$6[$fromDataIndex] = var$6[$fromDataIndex] | (-1) << ($fromIndex % 32 | 0); + $i = $fromDataIndex + 1 | 0; + while ($i < $toDataIndex) { + var$6[$i] = (-1); + $i = $i + 1 | 0; + } + if ($toIndex & 31) { + $i = var$6[$toDataIndex]; + $fromIndex = $toIndex % 32 | 0; + var$6[$toDataIndex] = $i | (!$fromIndex ? 0 : (-1) >>> (32 - $fromIndex | 0)); + } + } +} +function ju_BitSet_clear($this, $bitIndex) { + var $index, var$3, var$4, var$5; + $index = $bitIndex / 32 | 0; + var$3 = $this.$data0.data; + if ($index < var$3.length) { + var$4 = var$3[$index]; + var$5 = ($bitIndex % 32 | 0) & 31; + var$3[$index] = var$4 & ((-2) << var$5 | (-2) >>> (32 - var$5 | 0)); + if ($bitIndex == ($this.$length2 - 1 | 0)) + ju_BitSet_recalculateLength($this); + } +} +function ju_BitSet_clear0($this, $fromIndex, $toIndex) { + var var$3, $fromDataIndex, $toDataIndex, var$6, $i, var$8; + if ($fromIndex > $toIndex) { + var$3 = new jl_IndexOutOfBoundsException; + var$3.$suppressionEnabled = 1; + var$3.$writableStackTrace = 1; + $rt_throw(var$3); + } + $fromDataIndex = $this.$length2; + if ($fromIndex >= $fromDataIndex) + return; + if ($fromDataIndex < $toIndex) + $toIndex = $fromDataIndex; + $fromDataIndex = $fromIndex / 32 | 0; + $toDataIndex = $toIndex / 32 | 0; + if ($fromDataIndex == $toDataIndex) { + var$6 = $this.$data0.data; + $i = var$6[$fromDataIndex]; + $fromIndex = $fromIndex % 32 | 0; + var$6[$fromDataIndex] = $i & ((!$fromIndex ? 0 : (-1) >>> (32 - $fromIndex | 0)) | (-1) << ($toIndex % 32 | 0)); + } else { + var$6 = $this.$data0.data; + var$8 = var$6[$fromDataIndex]; + $fromIndex = $fromIndex % 32 | 0; + var$6[$fromDataIndex] = var$8 & (!$fromIndex ? 0 : (-1) >>> (32 - $fromIndex | 0)); + $i = $fromDataIndex + 1 | 0; + while ($i < $toDataIndex) { + var$6[$i] = 0; + $i = $i + 1 | 0; + } + if ($toIndex & 31) + var$6[$toDataIndex] = var$6[$toDataIndex] & (-1) << ($toIndex % 32 | 0); + } + ju_BitSet_recalculateLength($this); +} +function ju_BitSet_nextSetBit($this, $fromIndex) { + var $top, $index, var$4, $i; + $top = $this.$length2; + if ($fromIndex >= $top) + return (-1); + $index = $fromIndex / 32 | 0; + var$4 = $this.$data0.data; + $i = var$4[$index] >>> ($fromIndex % 32 | 0); + if ($i) + return jl_Integer_numberOfTrailingZeros($i) + $fromIndex | 0; + $top = ($top + 31 | 0) / 32 | 0; + $i = $index + 1 | 0; + while ($i < $top) { + if (var$4[$i]) + return ($i * 32 | 0) + jl_Integer_numberOfTrailingZeros(var$4[$i]) | 0; + $i = $i + 1 | 0; + } + return (-1); +} +function ju_BitSet_nextClearBit($this, $fromIndex) { + var var$2, $index, var$4, $top, $i; + var$2 = $this.$length2; + if ($fromIndex >= var$2) + return $fromIndex; + $index = $fromIndex / 32 | 0; + var$4 = $this.$data0.data; + $top = (var$4[$index] ^ (-1)) >>> ($fromIndex % 32 | 0); + if ($top) + return jl_Integer_numberOfTrailingZeros($top) + $fromIndex | 0; + $top = (var$2 + 31 | 0) / 32 | 0; + $i = $index + 1 | 0; + while ($i < $top) { + if (var$4[$i] != (-1)) + return ($i * 32 | 0) + jl_Integer_numberOfTrailingZeros(var$4[$i] ^ (-1)) | 0; + $i = $i + 1 | 0; + } + return var$2; +} +function ju_BitSet_ensureCapacity($this, $capacity) { + var var$2, var$3, $newArrayLength, $newArrayLength_0, var$6, var$7; + var$2 = $this.$data0.data; + var$3 = var$2.length; + if (var$3 >= $capacity) + return; + $newArrayLength = ($capacity * 3 | 0) / 2 | 0; + $newArrayLength_0 = (var$3 * 2 | 0) + 1 | 0; + if ($newArrayLength > $newArrayLength_0) + $newArrayLength_0 = $newArrayLength; + var$6 = $rt_createIntArray($newArrayLength_0); + if ($newArrayLength_0 < var$3) + var$3 = $newArrayLength_0; + var$7 = var$6.data; + $capacity = 0; + while ($capacity < var$3) { + var$7[$capacity] = var$2[$capacity]; + $capacity = $capacity + 1 | 0; + } + $this.$data0 = var$6; +} +function ju_BitSet_recalculateLength($this) { + var $top, $i, $sz; + $top = ($this.$length2 + 31 | 0) / 32 | 0; + $this.$length2 = $top * 32 | 0; + $i = $top - 1 | 0; + a: { + while (true) { + if ($i < 0) + break a; + $sz = jl_Integer_numberOfLeadingZeros($this.$data0.data[$i]); + if ($sz < 32) + break; + $i = $i + (-1) | 0; + $this.$length2 = $this.$length2 - 32 | 0; + } + $this.$length2 = $this.$length2 - $sz | 0; + } +} +function ju_BitSet_intersects($this, $set) { + var var$2, $sz, var$4, $sz_0, $i; + var$2 = $this.$data0.data; + $sz = var$2.length; + var$4 = $set.$data0.data; + $sz_0 = var$4.length; + if ($sz < $sz_0) + $sz_0 = $sz; + $i = 0; + while ($i < $sz_0) { + if (var$2[$i] & var$4[$i]) + return 1; + $i = $i + 1 | 0; + } + return 0; +} +function ju_BitSet_and($this, $set) { + var var$2, var$3, var$4, $sz, $i, var$7, var$8; + var$2 = $this.$data0.data; + var$3 = var$2.length; + var$4 = $set.$data0.data; + $sz = var$4.length; + if (var$3 < $sz) + $sz = var$3; + $i = 0; + while ($i < $sz) { + var$2[$i] = var$2[$i] & var$4[$i]; + $i = $i + 1 | 0; + } + while ($sz < var$3) { + var$2[$sz] = 0; + $sz = $sz + 1 | 0; + } + var$7 = $this.$length2; + var$8 = $set.$length2; + if (var$7 < var$8) + var$8 = var$7; + $this.$length2 = var$8; + ju_BitSet_recalculateLength($this); +} +function ju_BitSet_andNot($this, $set) { + var var$2, $sz, var$4, $sz_0, $i; + var$2 = $this.$data0.data; + $sz = var$2.length; + var$4 = $set.$data0.data; + $sz_0 = var$4.length; + if ($sz < $sz_0) + $sz_0 = $sz; + $i = 0; + while ($i < $sz_0) { + var$2[$i] = var$2[$i] & (var$4[$i] ^ (-1)); + $i = $i + 1 | 0; + } + ju_BitSet_recalculateLength($this); +} +function ju_BitSet_or($this, $set) { + var $sz, $sz_0, var$4, var$5, $i; + $sz = $this.$length2; + $sz_0 = $set.$length2; + if ($sz > $sz_0) + $sz_0 = $sz; + $this.$length2 = $sz_0; + ju_BitSet_ensureCapacity($this, ($sz_0 + 31 | 0) / 32 | 0); + var$4 = $this.$data0.data; + $sz = var$4.length; + var$5 = $set.$data0.data; + $sz_0 = var$5.length; + if ($sz < $sz_0) + $sz_0 = $sz; + $i = 0; + while ($i < $sz_0) { + var$4[$i] = var$4[$i] | var$5[$i]; + $i = $i + 1 | 0; + } +} +function ju_BitSet_xor($this, $set) { + var $sz, $i, var$4, var$5, $sz_0; + $sz = $this.$length2; + $i = $set.$length2; + if ($sz > $i) + $i = $sz; + $this.$length2 = $i; + ju_BitSet_ensureCapacity($this, ($i + 31 | 0) / 32 | 0); + var$4 = $this.$data0.data; + $sz = var$4.length; + var$5 = $set.$data0.data; + $sz_0 = var$5.length; + if ($sz < $sz_0) + $sz_0 = $sz; + $i = 0; + while ($i < $sz_0) { + var$4[$i] = var$4[$i] ^ var$5[$i]; + $i = $i + 1 | 0; + } + ju_BitSet_recalculateLength($this); +} +function jur_LowHighSurrogateRangeSet() { + var a = this; jur_JointSet.call(a); + a.$surrChars = null; + a.$alt = 0; +} +function jur_LowHighSurrogateRangeSet_matches($this, $stringIndex, $testString, $matchResult) { + var $startStr, $strLength, var$6, var$7, $ch, $low, $high; + $startStr = $matchResult.$leftBound; + $strLength = $matchResult.$rightBound; + var$6 = $stringIndex + 1 | 0; + $strLength = $rt_compare(var$6, $strLength); + if ($strLength > 0) { + $matchResult.$hitEnd = 1; + return (-1); + } + if ($stringIndex >= 0) { + var$7 = $testString.$characters.data; + if ($stringIndex < var$7.length) { + $ch = var$7[$stringIndex]; + if (!$this.$surrChars.$contains($ch)) + return (-1); + $low = $ch & 64512; + $high = $low != 55296 ? 0 : 1; + a: { + if ($high) { + if ($strLength >= 0) + break a; + if (var$6 >= 0) { + var$7 = $testString.$characters.data; + if (var$6 < var$7.length) { + if ((var$7[var$6] & 64512) != 56320 ? 0 : 1) + return (-1); + break a; + } + } + $testString = new jl_StringIndexOutOfBoundsException; + $testString.$suppressionEnabled = 1; + $testString.$writableStackTrace = 1; + $rt_throw($testString); + } + if (($low != 56320 ? 0 : 1) && $stringIndex > $startStr) { + $high = $stringIndex - 1 | 0; + if ($high >= 0) { + var$7 = $testString.$characters.data; + if ($high < var$7.length) { + if (!((var$7[$high] & 64512) != 55296 ? 0 : 1)) + break a; + return (-1); + } + } + $testString = new jl_StringIndexOutOfBoundsException; + $testString.$suppressionEnabled = 1; + $testString.$writableStackTrace = 1; + $rt_throw($testString); + } + } + return $this.$next0.$matches(var$6, $testString, $matchResult); + } + } + $testString = new jl_StringIndexOutOfBoundsException; + $testString.$suppressionEnabled = 1; + $testString.$writableStackTrace = 1; + $rt_throw($testString); +} +function jur_CompositeRangeSet() { + var a = this; jur_JointSet.call(a); + a.$withoutSurrogates = null; + a.$withSurrogates = null; +} +function jur_CompositeRangeSet__init_(var_0, var_1) { + var var_2 = new jur_CompositeRangeSet(); + jur_CompositeRangeSet__init_0(var_2, var_0, var_1); + return var_2; +} +function jur_CompositeRangeSet__init_0($this, $withoutSurrogates, $withSurrogates) { + var var$3, var$4; + var$3 = jur_AbstractSet_counter; + jur_AbstractSet_counter = var$3 + 1 | 0; + var$4 = new jl_AbstractStringBuilder; + var$4.$buffer = $rt_createCharArray(20); + $this.$index1 = (jl_AbstractStringBuilder_insert0(var$4, var$4.$length, var$3, 10)).$toString(); + $this.$withoutSurrogates = $withoutSurrogates; + $this.$withSurrogates = $withSurrogates; +} +function jur_CompositeRangeSet_matches($this, $stringIndex, $testString, $matchResult) { + var $shift; + $shift = $this.$withoutSurrogates.$matches($stringIndex, $testString, $matchResult); + if ($shift < 0) + $shift = jur_LowHighSurrogateRangeSet_matches($this.$withSurrogates, $stringIndex, $testString, $matchResult); + if ($shift >= 0) + return $shift; + return (-1); +} +function jur_CompositeRangeSet_setNext($this, $next) { + $this.$next0 = $next; + $this.$withSurrogates.$next0 = $next; + $this.$withoutSurrogates.$setNext($next); +} +function jur_CompositeRangeSet_hasConsumed($this, $matchResult) { + return 1; +} +function jur_CompositeRangeSet_first($this, $set) { + return 1; +} +function jur_SupplRangeSet() { + var a = this; jur_JointSet.call(a); + a.$chars0 = null; + a.$alt2 = 0; +} +function jur_SupplRangeSet__init_(var_0) { + var var_1 = new jur_SupplRangeSet(); + jur_SupplRangeSet__init_0(var_1, var_0); + return var_1; +} +function jur_SupplRangeSet__init_0($this, $cc) { + var var$2, var$3; + var$2 = jur_AbstractSet_counter; + jur_AbstractSet_counter = var$2 + 1 | 0; + var$3 = new jl_AbstractStringBuilder; + var$3.$buffer = $rt_createCharArray(20); + $this.$index1 = (jl_AbstractStringBuilder_insert0(var$3, var$3.$length, var$2, 10)).$toString(); + $this.$chars0 = $cc.$getInstance1(); + $this.$alt2 = $cc.$alt0; +} +function jur_SupplRangeSet_matches($this, $stringIndex, $testString, $matchResult) { + var $strLength, $low, var$6, $high, $offset; + a: { + $strLength = $matchResult.$rightBound; + if ($stringIndex < $strLength) { + $low = $stringIndex + 1 | 0; + if ($stringIndex >= 0) { + var$6 = $testString.$characters.data; + if ($stringIndex < var$6.length) { + $high = var$6[$stringIndex]; + if ($this.$contains($high)) { + $offset = $this.$next0.$matches($low, $testString, $matchResult); + if ($offset > 0) + return $offset; + } + if ($low >= $strLength) + break a; + $strLength = $low + 1 | 0; + if ($low >= 0) { + var$6 = $testString.$characters.data; + if ($low < var$6.length) { + $low = var$6[$low]; + $stringIndex = ($high & 64512) != 55296 ? 0 : 1; + if (!($stringIndex && (($low & 64512) != 56320 ? 0 : 1) ? 1 : 0)) + break a; + if (!$this.$contains((($high & 1023) << 10 | $low & 1023) + 65536 | 0)) + break a; + else + return $this.$next0.$matches($strLength, $testString, $matchResult); + } + } + $testString = new jl_StringIndexOutOfBoundsException; + $testString.$suppressionEnabled = 1; + $testString.$writableStackTrace = 1; + $rt_throw($testString); + } + } + $testString = new jl_StringIndexOutOfBoundsException; + $testString.$suppressionEnabled = 1; + $testString.$writableStackTrace = 1; + $rt_throw($testString); + } + } + return (-1); +} +function jur_SupplRangeSet_contains($this, $ch) { + return $this.$chars0.$contains($ch); +} +function jur_SupplRangeSet_first($this, $set) { + var var$2, var$3; + if ($set instanceof jur_SupplCharSet) + return $this.$chars0.$contains($set.$ch4); + if ($set instanceof jur_CharSet) + return $this.$chars0.$contains($set.$ch0); + if ($set instanceof jur_SupplRangeSet) { + var$2 = $this.$chars0; + $set = $set.$chars0; + return var$2.$getBits() !== null && $set.$getBits() !== null ? ju_BitSet_intersects(var$2.$getBits(), $set.$getBits()) : 1; + } + if (!($set instanceof jur_RangeSet)) + return 1; + var$2 = $this.$chars0; + var$3 = $set.$chars1; + return var$2.$getBits() !== null && var$3.$getBits() !== null ? ju_BitSet_intersects(var$2.$getBits(), var$3.$getBits()) : 1; +} +function jur_SupplRangeSet_getChars($this) { + return $this.$chars0; +} +function jur_SupplRangeSet_setNext($this, $next) { + $this.$next0 = $next; +} +function jur_SupplRangeSet_hasConsumed($this, $mr) { + return 1; +} +var jur_UCISupplRangeSet = $rt_classWithoutFields(jur_SupplRangeSet); +function jur_UCISupplRangeSet_contains($this, $ch) { + return $this.$chars0.$contains((String.fromCharCode((String.fromCharCode($ch)).toUpperCase().charCodeAt(0))).toLowerCase().charCodeAt(0)); +} +function jur_UCIRangeSet() { + var a = this; jur_LeafSet.call(a); + a.$chars = null; + a.$alt1 = 0; +} +function jur_UCIRangeSet__init_(var_0) { + var var_1 = new jur_UCIRangeSet(); + jur_UCIRangeSet__init_0(var_1, var_0); + return var_1; +} +function jur_UCIRangeSet__init_0($this, $cc) { + var var$2, var$3; + var$2 = jur_AbstractSet_counter; + jur_AbstractSet_counter = var$2 + 1 | 0; + var$3 = new jl_AbstractStringBuilder; + var$3.$buffer = $rt_createCharArray(20); + $this.$index1 = (jl_AbstractStringBuilder_insert0(var$3, var$3.$length, var$2, 10)).$toString(); + $this.$charCount = 1; + $this.$chars = $cc.$getInstance1(); + $this.$alt1 = $cc.$alt0; +} +function jur_UCIRangeSet_accepts($this, $strIndex, $testString) { + var var$3, var$4; + var$3 = $this.$chars; + if ($strIndex >= 0) { + var$4 = $testString.$characters.data; + if ($strIndex < var$4.length) + return !var$3.$contains((String.fromCharCode((String.fromCharCode(var$4[$strIndex])).toUpperCase().charCodeAt(0) & 65535)).toLowerCase().charCodeAt(0) & 65535) ? (-1) : 1; + } + $testString = new jl_StringIndexOutOfBoundsException; + $testString.$suppressionEnabled = 1; + $testString.$writableStackTrace = 1; + $rt_throw($testString); +} +function jur_RangeSet() { + var a = this; jur_LeafSet.call(a); + a.$chars1 = null; + a.$alt3 = 0; +} +function jur_RangeSet__init_(var_0) { + var var_1 = new jur_RangeSet(); + jur_RangeSet__init_0(var_1, var_0); + return var_1; +} +function jur_RangeSet__init_0($this, $cc) { + var var$2, var$3; + var$2 = jur_AbstractSet_counter; + jur_AbstractSet_counter = var$2 + 1 | 0; + var$3 = new jl_AbstractStringBuilder; + var$3.$buffer = $rt_createCharArray(20); + $this.$index1 = (jl_AbstractStringBuilder_insert0(var$3, var$3.$length, var$2, 10)).$toString(); + $this.$charCount = 1; + $this.$chars1 = $cc.$getInstance1(); + $this.$alt3 = $cc.$alt0; +} +function jur_RangeSet_accepts($this, $strIndex, $testString) { + var var$3, var$4; + var$3 = $this.$chars1; + if ($strIndex >= 0) { + var$4 = $testString.$characters.data; + if ($strIndex < var$4.length) + return !var$3.$contains(var$4[$strIndex]) ? (-1) : 1; + } + $testString = new jl_StringIndexOutOfBoundsException; + $testString.$suppressionEnabled = 1; + $testString.$writableStackTrace = 1; + $rt_throw($testString); +} +function jur_RangeSet_first($this, $set) { + var var$2, var$3; + if ($set instanceof jur_CharSet) + return $this.$chars1.$contains($set.$ch0); + if ($set instanceof jur_RangeSet) { + var$2 = $this.$chars1; + $set = $set.$chars1; + return var$2.$getBits() !== null && $set.$getBits() !== null ? ju_BitSet_intersects(var$2.$getBits(), $set.$getBits()) : 1; + } + if (!($set instanceof jur_SupplRangeSet)) { + if (!($set instanceof jur_SupplCharSet)) + return 1; + return 0; + } + var$2 = $this.$chars1; + var$3 = $set.$chars0; + return var$2.$getBits() !== null && var$3.$getBits() !== null ? ju_BitSet_intersects(var$2.$getBits(), var$3.$getBits()) : 1; +} +function jur_HangulDecomposedCharSet() { + var a = this; jur_JointSet.call(a); + a.$decomposedChar = null; + a.$decomposedCharUTF16 = null; + a.$decomposedCharLength = 0; +} +function jur_HangulDecomposedCharSet_setNext($this, $next) { + $this.$next0 = $next; +} +function jur_HangulDecomposedCharSet_matches($this, $strIndex, $testString, $matchResult) { + var $rightBound, $decompSyllable, $vIndex, $tIndex, var$8, $decompCurSymb, $curSymb, $i, $lIndex; + $rightBound = $matchResult.$rightBound; + $decompSyllable = $rt_createIntArray(3); + $vIndex = (-1); + $tIndex = (-1); + if ($strIndex >= $rightBound) + return (-1); + var$8 = $strIndex + 1 | 0; + if ($strIndex >= 0) { + $decompCurSymb = $testString.$characters.data; + if ($strIndex < $decompCurSymb.length) { + $curSymb = $decompCurSymb[$strIndex]; + $decompCurSymb = jur_Lexer_getHangulDecomposition($curSymb); + if ($decompCurSymb !== null) { + $decompCurSymb = $decompCurSymb.data; + $i = 0; + $strIndex = $decompCurSymb.length; + $curSymb = $this.$decomposedCharLength; + if ($strIndex != $curSymb) + return (-1); + while (true) { + if ($i >= $curSymb) + return $this.$next0.$matches(var$8, $testString, $matchResult); + if ($decompCurSymb[$i] != $this.$decomposedChar.data[$i]) + break; + $i = $i + 1 | 0; + } + return (-1); + } + $decompSyllable = $decompSyllable.data; + $decompSyllable[0] = $curSymb; + $lIndex = $curSymb - 4352 | 0; + if ($lIndex >= 0 && $lIndex < 19) { + a: { + if (var$8 < $rightBound) { + if (var$8 >= 0) { + $decompCurSymb = $testString.$characters.data; + if (var$8 < $decompCurSymb.length) { + $curSymb = $decompCurSymb[var$8]; + $vIndex = $curSymb - 4449 | 0; + break a; + } + } + $testString = new jl_StringIndexOutOfBoundsException; + $testString.$suppressionEnabled = 1; + $testString.$writableStackTrace = 1; + $rt_throw($testString); + } + } + if ($vIndex >= 0 && $vIndex < 21) { + b: { + $strIndex = var$8 + 1 | 0; + $decompSyllable[1] = $curSymb; + if ($strIndex < $rightBound) { + if ($strIndex >= 0) { + $decompCurSymb = $testString.$characters.data; + if ($strIndex < $decompCurSymb.length) { + $curSymb = $decompCurSymb[$strIndex]; + $tIndex = $curSymb - 4519 | 0; + break b; + } + } + $testString = new jl_StringIndexOutOfBoundsException; + $testString.$suppressionEnabled = 1; + $testString.$writableStackTrace = 1; + $rt_throw($testString); + } + } + if ($tIndex >= 0 && $tIndex < 28) { + c: { + $strIndex = $strIndex + 1 | 0; + $decompSyllable[2] = $curSymb; + if ($this.$decomposedCharLength == 3) { + $curSymb = $decompSyllable[0]; + $decompCurSymb = $this.$decomposedChar.data; + if ($curSymb == $decompCurSymb[0] && $decompSyllable[1] == $decompCurSymb[1] && $decompSyllable[2] == $decompCurSymb[2]) { + $strIndex = $this.$next0.$matches($strIndex, $testString, $matchResult); + break c; + } + } + $strIndex = (-1); + } + return $strIndex; + } + d: { + if ($this.$decomposedCharLength == 2) { + $curSymb = $decompSyllable[0]; + $decompCurSymb = $this.$decomposedChar.data; + if ($curSymb == $decompCurSymb[0] && $decompSyllable[1] == $decompCurSymb[1]) { + $strIndex = $this.$next0.$matches($strIndex, $testString, $matchResult); + break d; + } + } + $strIndex = (-1); + } + return $strIndex; + } + return (-1); + } + return (-1); + } + } + $testString = new jl_StringIndexOutOfBoundsException; + $testString.$suppressionEnabled = 1; + $testString.$writableStackTrace = 1; + $rt_throw($testString); +} +function jur_HangulDecomposedCharSet_first($this, $set) { + var var$2, var$3, var$4, var$5, var$6, var$7; + a: { + if ($set instanceof jur_HangulDecomposedCharSet) { + $set = $set; + if ($set.$decomposedCharUTF16 === null) { + var$2 = new jl_String; + var$3 = $set.$decomposedChar.data; + var$4 = var$3.length; + var$5 = $rt_createCharArray(var$4); + var$6 = var$5.data; + var$2.$characters = var$5; + var$7 = 0; + while (var$7 < var$4) { + var$6[var$7] = var$3[var$7]; + var$7 = var$7 + 1 | 0; + } + $set.$decomposedCharUTF16 = var$2; + } + var$2 = $set.$decomposedCharUTF16; + if ($this.$decomposedCharUTF16 === null) { + $set = new jl_String; + var$3 = $this.$decomposedChar.data; + var$4 = var$3.length; + var$5 = $rt_createCharArray(var$4); + var$6 = var$5.data; + $set.$characters = var$5; + var$7 = 0; + while (var$7 < var$4) { + var$6[var$7] = var$3[var$7]; + var$7 = var$7 + 1 | 0; + } + $this.$decomposedCharUTF16 = $set; + } + if (!jl_String_equals(var$2, $this.$decomposedCharUTF16)) { + var$4 = 0; + break a; + } + } + var$4 = 1; + } + return var$4; +} +function jur_HangulDecomposedCharSet_hasConsumed($this, $matchResult) { + return 1; +} +function jur_CharSet() { + jur_LeafSet.call(this); + this.$ch0 = 0; +} +function jur_CharSet__init_(var_0) { + var var_1 = new jur_CharSet(); + jur_CharSet__init_0(var_1, var_0); + return var_1; +} +function jur_CharSet__init_0($this, $ch) { + var var$2, var$3; + var$2 = jur_AbstractSet_counter; + jur_AbstractSet_counter = var$2 + 1 | 0; + var$3 = new jl_AbstractStringBuilder; + var$3.$buffer = $rt_createCharArray(20); + $this.$index1 = (jl_AbstractStringBuilder_insert0(var$3, var$3.$length, var$2, 10)).$toString(); + $this.$charCount = 1; + $this.$ch0 = $ch; +} +function jur_CharSet_charCount($this) { + return 1; +} +function jur_CharSet_accepts($this, $strIndex, $testString) { + var var$3, var$4; + var$3 = $this.$ch0; + if ($strIndex >= 0) { + var$4 = $testString.$characters.data; + if ($strIndex < var$4.length) + return var$3 != var$4[$strIndex] ? (-1) : 1; + } + $testString = new jl_StringIndexOutOfBoundsException; + $testString.$suppressionEnabled = 1; + $testString.$writableStackTrace = 1; + $rt_throw($testString); +} +function jur_CharSet_find($this, $strIndex, $testStr, $matchResult) { + var $strLength, var$5, var$6, var$7, var$8, var$9; + if ($testStr instanceof jl_String) { + $strLength = $matchResult.$rightBound; + while (true) { + if ($strIndex >= $strLength) + return (-1); + var$5 = jl_String_indexOf($testStr, $this.$ch0, $strIndex); + if (var$5 < 0) + return (-1); + var$6 = $this.$next0; + $strIndex = var$5 + 1 | 0; + if (var$6.$matches($strIndex, $testStr, $matchResult) >= 0) + break; + } + return var$5; + } + var$7 = $matchResult.$rightBound; + a: { + b: { + while (true) { + if ($strIndex > var$7) { + $strIndex = (-1); + break b; + } + var$5 = $strIndex + 1 | 0; + if (var$5 > $matchResult.$rightBound) { + $matchResult.$hitEnd = 1; + var$8 = (-1); + } else { + var$8 = $this.$ch0; + if ($strIndex < 0) + break a; + var$9 = $testStr.$characters.data; + if ($strIndex >= var$9.length) + break a; + var$8 = var$8 != var$9[$strIndex] ? (-1) : 1; + var$8 = var$8 < 0 ? (-1) : $this.$next0.$matches($strIndex + var$8 | 0, $testStr, $matchResult); + } + if (var$8 >= 0) + break; + $strIndex = var$5; + } + } + return $strIndex; + } + $testStr = new jl_StringIndexOutOfBoundsException; + jl_Throwable__init_0($testStr); + $rt_throw($testStr); +} +function jur_CharSet_findBack($this, $strIndex, $lastIndex, $testStr, $matchResult) { + var var$5, var$6; + if ($testStr instanceof jl_String) { + a: { + while (true) { + if ($lastIndex < $strIndex) + return (-1); + var$5 = jl_String_lastIndexOf($testStr, $this.$ch0, $lastIndex); + if (var$5 < 0) + break a; + if (var$5 < $strIndex) + break a; + if ($this.$next0.$matches(var$5 + 1 | 0, $testStr, $matchResult) >= 0) + break; + $lastIndex = var$5 + (-1) | 0; + } + return var$5; + } + return (-1); + } + b: { + c: { + while (true) { + if ($lastIndex < $strIndex) { + $lastIndex = (-1); + break c; + } + if (($lastIndex + 1 | 0) > $matchResult.$rightBound) { + $matchResult.$hitEnd = 1; + var$5 = (-1); + } else { + var$5 = $this.$ch0; + if ($lastIndex < 0) + break b; + var$6 = $testStr.$characters.data; + if ($lastIndex >= var$6.length) + break b; + var$5 = var$5 != var$6[$lastIndex] ? (-1) : 1; + var$5 = var$5 < 0 ? (-1) : $this.$next0.$matches($lastIndex + var$5 | 0, $testStr, $matchResult); + } + if (var$5 >= 0) + break; + $lastIndex = $lastIndex + (-1) | 0; + } + } + return $lastIndex; + } + $testStr = new jl_StringIndexOutOfBoundsException; + jl_Throwable__init_0($testStr); + $rt_throw($testStr); +} +function jur_CharSet_first($this, $set) { + var var$2, var$3, var$4, var$5; + if ($set instanceof jur_CharSet) + return $set.$ch0 != $this.$ch0 ? 0 : 1; + if (!($set instanceof jur_RangeSet)) { + if ($set instanceof jur_SupplRangeSet) + return $set.$contains($this.$ch0); + if (!($set instanceof jur_SupplCharSet)) + return 1; + return 0; + } + $set = $set; + var$2 = $this.$ch0; + var$3 = $rt_createCharArray(1).data; + var$3[0] = var$2; + var$2 = var$3.length; + var$4 = $rt_createCharArray(var$2).data; + var$5 = 0; + while (var$5 < var$2) { + var$4[var$5] = var$3[var$5]; + var$5 = var$5 + 1 | 0; + } + $set = $set.$chars1; + if (0 >= var$4.length) { + $set = new jl_StringIndexOutOfBoundsException; + $set.$suppressionEnabled = 1; + $set.$writableStackTrace = 1; + $rt_throw($set); + } + return (!$set.$contains(var$4[0]) ? (-1) : 1) <= 0 ? 0 : 1; +} +function jur_UCICharSet() { + jur_LeafSet.call(this); + this.$ch3 = 0; +} +function jur_UCICharSet__init_(var_0) { + var var_1 = new jur_UCICharSet(); + jur_UCICharSet__init_0(var_1, var_0); + return var_1; +} +function jur_UCICharSet__init_0($this, $ch) { + var var$2, var$3; + var$2 = jur_AbstractSet_counter; + jur_AbstractSet_counter = var$2 + 1 | 0; + var$3 = new jl_AbstractStringBuilder; + var$3.$buffer = $rt_createCharArray(20); + $this.$index1 = (jl_AbstractStringBuilder_insert0(var$3, var$3.$length, var$2, 10)).$toString(); + $this.$charCount = 1; + $this.$ch3 = (String.fromCharCode((String.fromCharCode($ch)).toUpperCase().charCodeAt(0) & 65535)).toLowerCase().charCodeAt(0) & 65535; +} +function jur_UCICharSet_accepts($this, $strIndex, $testString) { + var var$3, var$4; + var$3 = $this.$ch3; + if ($strIndex >= 0) { + var$4 = $testString.$characters.data; + if ($strIndex < var$4.length) + return var$3 != ((String.fromCharCode((String.fromCharCode(var$4[$strIndex])).toUpperCase().charCodeAt(0) & 65535)).toLowerCase().charCodeAt(0) & 65535) ? (-1) : 1; + } + $testString = new jl_StringIndexOutOfBoundsException; + $testString.$suppressionEnabled = 1; + $testString.$writableStackTrace = 1; + $rt_throw($testString); +} +function jur_CICharSet() { + var a = this; jur_LeafSet.call(a); + a.$ch1 = 0; + a.$supplement = 0; +} +function jur_CICharSet__init_(var_0) { + var var_1 = new jur_CICharSet(); + jur_CICharSet__init_0(var_1, var_0); + return var_1; +} +function jur_CICharSet__init_0($this, $ch) { + var var$2, var$3; + var$2 = jur_AbstractSet_counter; + jur_AbstractSet_counter = var$2 + 1 | 0; + var$3 = new jl_AbstractStringBuilder; + var$3.$buffer = $rt_createCharArray(20); + $this.$index1 = (jl_AbstractStringBuilder_insert0(var$3, var$3.$length, var$2, 10)).$toString(); + $this.$charCount = 1; + $this.$ch1 = $ch; + $this.$supplement = jur_Pattern_getSupplement($ch); +} +function jur_CICharSet_accepts($this, $strIndex, $testString) { + var var$3, var$4, var$5; + var$3 = $this.$ch1; + if ($strIndex >= 0) { + var$4 = $testString.$characters.data; + var$5 = $rt_compare($strIndex, var$4.length); + if (var$5 < 0) { + a: { + b: { + if (var$3 != var$4[$strIndex]) { + var$3 = $this.$supplement; + if ($strIndex < 0) + break a; + if (var$5 >= 0) + break a; + if (var$3 != var$4[$strIndex]) { + $strIndex = (-1); + break b; + } + } + $strIndex = 1; + } + return $strIndex; + } + $testString = new jl_StringIndexOutOfBoundsException; + $testString.$suppressionEnabled = 1; + $testString.$writableStackTrace = 1; + $rt_throw($testString); + } + } + $testString = new jl_StringIndexOutOfBoundsException; + $testString.$suppressionEnabled = 1; + $testString.$writableStackTrace = 1; + $rt_throw($testString); +} +function jur_DecomposedCharSet() { + var a = this; jur_JointSet.call(a); + a.$readCharsForCodePoint = 0; + a.$decomposedCharUTF160 = null; + a.$decomposedChar0 = null; + a.$decomposedCharLength0 = 0; +} +function jur_DecomposedCharSet__init_(var_0, var_1) { + var var_2 = new jur_DecomposedCharSet(); + jur_DecomposedCharSet__init_0(var_2, var_0, var_1); + return var_2; +} +function jur_DecomposedCharSet__init_0($this, $decomposedChar, $decomposedCharLength) { + var var$3, var$4; + var$3 = jur_AbstractSet_counter; + jur_AbstractSet_counter = var$3 + 1 | 0; + var$4 = new jl_AbstractStringBuilder; + var$4.$buffer = $rt_createCharArray(20); + $this.$index1 = (jl_AbstractStringBuilder_insert0(var$4, var$4.$length, var$3, 10)).$toString(); + $this.$readCharsForCodePoint = 1; + $this.$decomposedChar0 = $decomposedChar; + $this.$decomposedCharLength0 = $decomposedCharLength; +} +function jur_DecomposedCharSet_setNext($this, $next) { + $this.$next0 = $next; +} +function jur_DecomposedCharSet_matches($this, $strIndex, $testString, $matchResult) { + var $decCodePoint, $rightBound, $curChar, var$7, $decCurCodePoint, var$9, var$10; + $decCodePoint = $rt_createIntArray(4); + $rightBound = $matchResult.$rightBound; + if ($strIndex >= $rightBound) + return (-1); + $curChar = jur_DecomposedCharSet_codePointAt($this, $strIndex, $testString, $rightBound); + var$7 = $strIndex + $this.$readCharsForCodePoint | 0; + $decCurCodePoint = jur_Lexer_decompTable.$get3($curChar); + if ($decCurCodePoint === null) { + var$9 = $decCodePoint.data; + $strIndex = 1; + var$9[0] = $curChar; + } else { + $strIndex = $decCurCodePoint.data.length; + jl_System_arraycopy($decCurCodePoint, 0, $decCodePoint, 0, $strIndex); + $strIndex = 0 + $strIndex | 0; + } + a: { + if (var$7 < $rightBound) { + $decCurCodePoint = $decCodePoint.data; + $curChar = jur_DecomposedCharSet_codePointAt($this, var$7, $testString, $rightBound); + while ($strIndex < 4) { + if (!jur_Lexer_hasDecompositionNonNullCanClass($curChar)) { + var$10 = $strIndex + 1 | 0; + $decCurCodePoint[$strIndex] = $curChar; + } else { + var$9 = (jur_Lexer_decompTable.$get3($curChar)).data; + if (var$9.length != 2) { + var$10 = $strIndex + 1 | 0; + $decCurCodePoint[$strIndex] = var$9[0]; + } else { + $curChar = $strIndex + 1 | 0; + $decCurCodePoint[$strIndex] = var$9[0]; + var$10 = $curChar + 1 | 0; + $decCurCodePoint[$curChar] = var$9[1]; + } + } + var$7 = var$7 + $this.$readCharsForCodePoint | 0; + if (var$7 >= $rightBound) { + $strIndex = var$10; + break a; + } + $curChar = jur_DecomposedCharSet_codePointAt($this, var$7, $testString, $rightBound); + $strIndex = var$10; + } + } + } + if ($strIndex != $this.$decomposedCharLength0) + return (-1); + var$9 = $decCodePoint.data; + $curChar = 0; + while (true) { + if ($curChar >= $strIndex) + return $this.$next0.$matches(var$7, $testString, $matchResult); + if (var$9[$curChar] != $this.$decomposedChar0.data[$curChar]) + break; + $curChar = $curChar + 1 | 0; + } + return (-1); +} +function jur_DecomposedCharSet_codePointAt($this, $strIndex, $testString, $rightBound) { + var $curCodePointUTF16, $curChar, $low, var$7; + a: { + $this.$readCharsForCodePoint = 1; + if ($strIndex >= ($rightBound - 1 | 0)) { + if ($strIndex >= 0) { + $curCodePointUTF16 = $testString.$characters.data; + if ($strIndex < $curCodePointUTF16.length) { + $curChar = $curCodePointUTF16[$strIndex]; + break a; + } + } + $testString = new jl_StringIndexOutOfBoundsException; + $testString.$suppressionEnabled = 1; + $testString.$writableStackTrace = 1; + $rt_throw($testString); + } + $rightBound = $strIndex + 1 | 0; + if ($strIndex >= 0) { + $curCodePointUTF16 = $testString.$characters.data; + $low = $curCodePointUTF16.length; + if ($strIndex < $low) { + $curChar = $curCodePointUTF16[$strIndex]; + if ($rightBound >= 0 && $rightBound < $low) { + $low = $curCodePointUTF16[$rightBound]; + $strIndex = ($curChar & 64512) != 55296 ? 0 : 1; + if ($strIndex && (($low & 64512) != 56320 ? 0 : 1) ? 1 : 0) { + $curCodePointUTF16 = $rt_createCharArray(2); + var$7 = $curCodePointUTF16.data; + var$7[0] = $curChar; + var$7[1] = $low; + $curChar = jl_Character_codePointAt($curCodePointUTF16, 0, var$7.length); + $this.$readCharsForCodePoint = 2; + } + break a; + } + $testString = new jl_StringIndexOutOfBoundsException; + $testString.$suppressionEnabled = 1; + $testString.$writableStackTrace = 1; + $rt_throw($testString); + } + } + $testString = new jl_StringIndexOutOfBoundsException; + $testString.$suppressionEnabled = 1; + $testString.$writableStackTrace = 1; + $rt_throw($testString); + } + return $curChar; +} +function jur_DecomposedCharSet_first($this, $set) { + var var$2, var$3, var$4, var$5, var$6, var$7, var$8, var$9, var$10, var$11; + a: { + if ($set instanceof jur_DecomposedCharSet) { + $set = $set; + if ($set.$decomposedCharUTF160 === null) { + var$2 = new jl_StringBuilder; + var$2.$buffer = $rt_createCharArray(16); + var$3 = 0; + while (var$3 < $set.$decomposedCharLength0) { + var$4 = $set.$decomposedChar0.data[var$3]; + if (var$4 < 65536) { + var$5 = $rt_createCharArray(1); + var$5.data[0] = var$4 & 65535; + } else + var$5 = $rt_createCharArrayFromData([(55296 | (var$4 - 65536 | 0) >> 10 & 1023) & 65535, (56320 | var$4 & 1023) & 65535]); + var$6 = var$5.data.length; + jl_AbstractStringBuilder_insert1(var$2, var$2.$length, var$5, 0, var$6); + var$3 = var$3 + 1 | 0; + } + var$7 = new jl_String; + var$5 = var$2.$buffer; + var$4 = var$2.$length; + var$8 = $rt_createCharArray(var$4); + var$9 = var$8.data; + var$7.$characters = var$8; + var$6 = 0; + while (var$6 < var$4) { + var$9[var$6] = var$5.data[var$6 + 0 | 0]; + var$6 = var$6 + 1 | 0; + } + $set.$decomposedCharUTF160 = var$7; + } + var$2 = $set.$decomposedCharUTF160; + if ($this.$decomposedCharUTF160 === null) { + $set = new jl_StringBuilder; + $set.$buffer = $rt_createCharArray(16); + var$3 = 0; + while (var$3 < $this.$decomposedCharLength0) { + var$10 = $this.$decomposedChar0.data[var$3]; + if (var$10 < 65536) { + var$5 = $rt_createCharArray(1); + var$5.data[0] = var$10 & 65535; + } else + var$5 = $rt_createCharArrayFromData([(55296 | (var$10 - 65536 | 0) >> 10 & 1023) & 65535, (56320 | var$10 & 1023) & 65535]); + var$11 = var$5.data.length; + jl_AbstractStringBuilder_insert1($set, $set.$length, var$5, 0, var$11); + var$3 = var$3 + 1 | 0; + } + var$7 = new jl_String; + var$5 = $set.$buffer; + var$4 = $set.$length; + var$8 = $rt_createCharArray(var$4); + var$9 = var$8.data; + var$7.$characters = var$8; + var$6 = 0; + while (var$6 < var$4) { + var$9[var$6] = var$5.data[var$6 + 0 | 0]; + var$6 = var$6 + 1 | 0; + } + $this.$decomposedCharUTF160 = var$7; + } + if (!jl_String_equals(var$2, $this.$decomposedCharUTF160)) { + var$3 = 0; + break a; + } + } + var$3 = 1; + } + return var$3; +} +function jur_DecomposedCharSet_hasConsumed($this, $matchResult) { + return 1; +} +var jur_UCIDecomposedCharSet = $rt_classWithoutFields(jur_DecomposedCharSet); +function jur_UCIDecomposedCharSet__init_(var_0, var_1) { + var var_2 = new jur_UCIDecomposedCharSet(); + jur_UCIDecomposedCharSet__init_0(var_2, var_0, var_1); + return var_2; +} +function jur_UCIDecomposedCharSet__init_0($this, $decomp, $decomposedCharLength) { + var var$3, var$4; + var$3 = jur_AbstractSet_counter; + jur_AbstractSet_counter = var$3 + 1 | 0; + var$4 = new jl_AbstractStringBuilder; + var$4.$buffer = $rt_createCharArray(20); + $this.$index1 = (jl_AbstractStringBuilder_insert0(var$4, var$4.$length, var$3, 10)).$toString(); + $this.$readCharsForCodePoint = 1; + $this.$decomposedChar0 = $decomp; + $this.$decomposedCharLength0 = $decomposedCharLength; +} +var jur_CIDecomposedCharSet = $rt_classWithoutFields(jur_DecomposedCharSet); +function jur_CIDecomposedCharSet__init_(var_0, var_1) { + var var_2 = new jur_CIDecomposedCharSet(); + jur_CIDecomposedCharSet__init_0(var_2, var_0, var_1); + return var_2; +} +function jur_CIDecomposedCharSet__init_0($this, $decomp, $decomposedCharLength) { + var var$3, var$4; + var$3 = jur_AbstractSet_counter; + jur_AbstractSet_counter = var$3 + 1 | 0; + var$4 = new jl_AbstractStringBuilder; + var$4.$buffer = $rt_createCharArray(20); + $this.$index1 = (jl_AbstractStringBuilder_insert0(var$4, var$4.$length, var$3, 10)).$toString(); + $this.$readCharsForCodePoint = 1; + $this.$decomposedChar0 = $decomp; + $this.$decomposedCharLength0 = $decomposedCharLength; +} +var jur_PossessiveGroupQuantifierSet = $rt_classWithoutFields(jur_GroupQuantifierSet); +function jur_PossessiveGroupQuantifierSet_matches($this, $stringIndex, $testString, $matchResult) { + var $stringIndex_0; + while (true) { + $stringIndex_0 = $this.$innerSet.$matches($stringIndex, $testString, $matchResult); + if ($stringIndex_0 <= 0) + break; + $stringIndex = $stringIndex_0; + } + return $this.$next0.$matches($stringIndex, $testString, $matchResult); +} +var jur_PosPlusGroupQuantifierSet = $rt_classWithoutFields(jur_GroupQuantifierSet); +function jur_PosPlusGroupQuantifierSet_matches($this, $stringIndex, $testString, $matchResult) { + var $nextIndex; + $nextIndex = $this.$innerSet.$matches($stringIndex, $testString, $matchResult); + if ($nextIndex < 0) + return (-1); + if ($nextIndex > $stringIndex) { + while (true) { + $stringIndex = $this.$innerSet.$matches($nextIndex, $testString, $matchResult); + if ($stringIndex <= $nextIndex) + break; + $nextIndex = $stringIndex; + } + $stringIndex = $nextIndex; + } + return $this.$next0.$matches($stringIndex, $testString, $matchResult); +} +var jur_AltGroupQuantifierSet = $rt_classWithoutFields(jur_GroupQuantifierSet); +function jur_AltGroupQuantifierSet__init_(var_0, var_1, var_2) { + var var_3 = new jur_AltGroupQuantifierSet(); + jur_AltGroupQuantifierSet__init_0(var_3, var_0, var_1, var_2); + return var_3; +} +function jur_AltGroupQuantifierSet__init_0($this, $innerSet, $next, $type) { + var var$4, var$5; + var$4 = jur_AbstractSet_counter; + jur_AbstractSet_counter = var$4 + 1 | 0; + var$5 = new jl_AbstractStringBuilder; + var$5.$buffer = $rt_createCharArray(20); + $this.$index1 = (jl_AbstractStringBuilder_insert0(var$5, var$5.$length, var$4, 10)).$toString(); + $this.$next0 = $next; + $this.$innerSet = $innerSet; + $this.$type = $type; +} +function jur_AltGroupQuantifierSet_matches($this, $stringIndex, $testString, $matchResult) { + var $nextIndex; + if (!$this.$innerSet.$hasConsumed($matchResult)) + return $this.$next0.$matches($stringIndex, $testString, $matchResult); + $nextIndex = $this.$innerSet.$matches($stringIndex, $testString, $matchResult); + if ($nextIndex >= 0) + return $nextIndex; + return $this.$next0.$matches($stringIndex, $testString, $matchResult); +} +function jur_AltGroupQuantifierSet_setNext($this, $next) { + $this.$next0 = $next; + $this.$innerSet.$setNext($next); +} +var jur_PosAltGroupQuantifierSet = $rt_classWithoutFields(jur_AltGroupQuantifierSet); +function jur_PosAltGroupQuantifierSet_matches($this, $stringIndex, $testString, $matchResult) { + var $nextIndex; + $nextIndex = $this.$innerSet.$matches($stringIndex, $testString, $matchResult); + if ($nextIndex <= 0) + $nextIndex = $stringIndex; + return $this.$next0.$matches($nextIndex, $testString, $matchResult); +} +function jur_PosAltGroupQuantifierSet_setNext($this, $next) { + $this.$next0 = $next; +} +function jur_CompositeGroupQuantifierSet() { + var a = this; jur_GroupQuantifierSet.call(a); + a.$quantifier = null; + a.$setCounter = 0; +} +function jur_CompositeGroupQuantifierSet__init_0(var_0, var_1, var_2, var_3, var_4) { + var var_5 = new jur_CompositeGroupQuantifierSet(); + jur_CompositeGroupQuantifierSet__init_(var_5, var_0, var_1, var_2, var_3, var_4); + return var_5; +} +function jur_CompositeGroupQuantifierSet__init_($this, $quant, $innerSet, $next, $type, $setCounter) { + var var$6, var$7; + var$6 = jur_AbstractSet_counter; + jur_AbstractSet_counter = var$6 + 1 | 0; + var$7 = new jl_AbstractStringBuilder; + var$7.$buffer = $rt_createCharArray(20); + $this.$index1 = (jl_AbstractStringBuilder_insert0(var$7, var$7.$length, var$6, 10)).$toString(); + $this.$next0 = $next; + $this.$innerSet = $innerSet; + $this.$type = $type; + $this.$quantifier = $quant; + $this.$setCounter = $setCounter; +} +function jur_CompositeGroupQuantifierSet_matches($this, $stringIndex, $testString, $matchResult) { + var $enterCounter, var$5, $nextIndex, var$7; + $enterCounter = $this.$setCounter; + $enterCounter = $matchResult.$compQuantCounters.data[$enterCounter]; + if (!$this.$innerSet.$hasConsumed($matchResult)) + return $this.$next0.$matches($stringIndex, $testString, $matchResult); + if ($enterCounter >= $this.$quantifier.$max) + return $this.$next0.$matches($stringIndex, $testString, $matchResult); + var$5 = $this.$setCounter; + $enterCounter = $enterCounter + 1 | 0; + $matchResult.$compQuantCounters.data[var$5] = $enterCounter; + $nextIndex = $this.$innerSet.$matches($stringIndex, $testString, $matchResult); + if ($nextIndex >= 0) { + $stringIndex = $this.$setCounter; + $matchResult.$compQuantCounters.data[$stringIndex] = 0; + return $nextIndex; + } + $nextIndex = $this.$setCounter; + $enterCounter = $enterCounter + (-1) | 0; + var$7 = $matchResult.$compQuantCounters.data; + var$7[$nextIndex] = $enterCounter; + if ($enterCounter >= $this.$quantifier.$min) + return $this.$next0.$matches($stringIndex, $testString, $matchResult); + var$7[$nextIndex] = 0; + return (-1); +} +var jur_PosCompositeGroupQuantifierSet = $rt_classWithoutFields(jur_CompositeGroupQuantifierSet); +function jur_PosCompositeGroupQuantifierSet_matches($this, $stringIndex, $testString, $matchResult) { + var $counter, $max, $nextIndex; + $counter = 0; + $max = $this.$quantifier.$max; + a: { + while (true) { + $nextIndex = $this.$innerSet.$matches($stringIndex, $testString, $matchResult); + if ($nextIndex <= $stringIndex) + break a; + if ($counter >= $max) + break; + $counter = $counter + 1 | 0; + $stringIndex = $nextIndex; + } + } + if ($nextIndex < 0 && $counter < $this.$quantifier.$min) + return (-1); + return $this.$next0.$matches($stringIndex, $testString, $matchResult); +} +var jur_ReluctantGroupQuantifierSet = $rt_classWithoutFields(jur_GroupQuantifierSet); +function jur_ReluctantGroupQuantifierSet__init_(var_0, var_1, var_2) { + var var_3 = new jur_ReluctantGroupQuantifierSet(); + jur_ReluctantGroupQuantifierSet__init_0(var_3, var_0, var_1, var_2); + return var_3; +} +function jur_ReluctantGroupQuantifierSet__init_0($this, $innerSet, $next, $type) { + var var$4, var$5; + var$4 = jur_AbstractSet_counter; + jur_AbstractSet_counter = var$4 + 1 | 0; + var$5 = new jl_AbstractStringBuilder; + var$5.$buffer = $rt_createCharArray(20); + $this.$index1 = (jl_AbstractStringBuilder_insert0(var$5, var$5.$length, var$4, 10)).$toString(); + $this.$next0 = $next; + $this.$innerSet = $innerSet; + $this.$type = $type; +} +function jur_ReluctantGroupQuantifierSet_matches($this, $stringIndex, $testString, $matchResult) { + var $res; + if (!$this.$innerSet.$hasConsumed($matchResult)) + return $this.$next0.$matches($stringIndex, $testString, $matchResult); + $res = $this.$next0.$matches($stringIndex, $testString, $matchResult); + if ($res >= 0) + return $res; + return $this.$innerSet.$matches($stringIndex, $testString, $matchResult); +} +var jur_RelAltGroupQuantifierSet = $rt_classWithoutFields(jur_AltGroupQuantifierSet); +function jur_RelAltGroupQuantifierSet__init_(var_0, var_1, var_2) { + var var_3 = new jur_RelAltGroupQuantifierSet(); + jur_RelAltGroupQuantifierSet__init_0(var_3, var_0, var_1, var_2); + return var_3; +} +function jur_RelAltGroupQuantifierSet__init_0($this, $innerSet, $next, $type) { + var var$4, var$5; + var$4 = jur_AbstractSet_counter; + jur_AbstractSet_counter = var$4 + 1 | 0; + var$5 = new jl_AbstractStringBuilder; + jl_Object__init_0(var$5); + var$5.$buffer = $rt_createCharArray(20); + $this.$index1 = (jl_AbstractStringBuilder_insert0(var$5, var$5.$length, var$4, 10)).$toString(); + $this.$next0 = $next; + $this.$innerSet = $innerSet; + $this.$type = $type; +} +function jur_RelAltGroupQuantifierSet_matches($this, $stringIndex, $testString, $matchResult) { + var $nextIndex; + if (!$this.$innerSet.$hasConsumed($matchResult)) + return $this.$next0.$matches($stringIndex, $testString, $matchResult); + $nextIndex = $this.$next0.$matches($stringIndex, $testString, $matchResult); + if ($nextIndex < 0) + $nextIndex = $this.$innerSet.$matches($stringIndex, $testString, $matchResult); + return $nextIndex; +} +var jur_RelCompositeGroupQuantifierSet = $rt_classWithoutFields(jur_CompositeGroupQuantifierSet); +function jur_RelCompositeGroupQuantifierSet__init_0(var_0, var_1, var_2, var_3, var_4) { + var var_5 = new jur_RelCompositeGroupQuantifierSet(); + jur_RelCompositeGroupQuantifierSet__init_(var_5, var_0, var_1, var_2, var_3, var_4); + return var_5; +} +function jur_RelCompositeGroupQuantifierSet__init_($this, $quant, $innerSet, $next, $type, $setCounter) { + var var$6, var$7; + var$6 = jur_AbstractSet_counter; + jur_AbstractSet_counter = var$6 + 1 | 0; + var$7 = new jl_AbstractStringBuilder; + jl_Object__init_0(var$7); + var$7.$buffer = $rt_createCharArray(20); + $this.$index1 = (jl_AbstractStringBuilder_insert0(var$7, var$7.$length, var$6, 10)).$toString(); + $this.$next0 = $next; + $this.$innerSet = $innerSet; + $this.$type = $type; + $this.$quantifier = $quant; + $this.$setCounter = $setCounter; +} +function jur_RelCompositeGroupQuantifierSet_matches($this, $stringIndex, $testString, $matchResult) { + var $nextIndex, $enterCounter, var$6; + $nextIndex = $this.$setCounter; + $enterCounter = $matchResult.$compQuantCounters.data[$nextIndex]; + if (!$this.$innerSet.$hasConsumed($matchResult)) + return $this.$next0.$matches($stringIndex, $testString, $matchResult); + var$6 = $this.$quantifier; + if ($enterCounter >= var$6.$max) { + $nextIndex = $this.$setCounter; + $matchResult.$compQuantCounters.data[$nextIndex] = 0; + return $this.$next0.$matches($stringIndex, $testString, $matchResult); + } + if ($enterCounter < var$6.$min) { + $nextIndex = $this.$setCounter; + $matchResult.$compQuantCounters.data[$nextIndex] = $enterCounter + 1 | 0; + $nextIndex = $this.$innerSet.$matches($stringIndex, $testString, $matchResult); + } else { + $nextIndex = $this.$next0.$matches($stringIndex, $testString, $matchResult); + if ($nextIndex >= 0) { + $stringIndex = $this.$setCounter; + $matchResult.$compQuantCounters.data[$stringIndex] = 0; + return $nextIndex; + } + $nextIndex = $this.$setCounter; + $matchResult.$compQuantCounters.data[$nextIndex] = $enterCounter + 1 | 0; + $nextIndex = $this.$innerSet.$matches($stringIndex, $testString, $matchResult); + } + return $nextIndex; +} +var jur_DotAllQuantifierSet = $rt_classWithoutFields(jur_QuantifierSet); +function jur_DotAllQuantifierSet__init_(var_0, var_1, var_2) { + var var_3 = new jur_DotAllQuantifierSet(); + jur_DotAllQuantifierSet__init_0(var_3, var_0, var_1, var_2); + return var_3; +} +function jur_DotAllQuantifierSet__init_0($this, $innerSet, $next, $type) { + var var$4, var$5; + var$4 = jur_AbstractSet_counter; + jur_AbstractSet_counter = var$4 + 1 | 0; + var$5 = new jl_AbstractStringBuilder; + var$5.$buffer = $rt_createCharArray(20); + $this.$index1 = (jl_AbstractStringBuilder_insert0(var$5, var$5.$length, var$4, 10)).$toString(); + $this.$next0 = $next; + $this.$innerSet = $innerSet; + $this.$type = $type; +} +function jur_DotAllQuantifierSet_matches($this, $stringIndex, $testString, $matchResult) { + var $strLength; + $strLength = $matchResult.$rightBound; + if ($strLength > $stringIndex) + return $this.$next0.$findBack($stringIndex, $strLength, $testString, $matchResult); + return $this.$next0.$matches($stringIndex, $testString, $matchResult); +} +function jur_DotAllQuantifierSet_find($this, $stringIndex, $testString, $matchResult) { + var $strLength; + $strLength = $matchResult.$rightBound; + if ($this.$next0.$findBack($stringIndex, $strLength, $testString, $matchResult) >= 0) + return $stringIndex; + return (-1); +} +function jur_DotQuantifierSet() { + jur_QuantifierSet.call(this); + this.$lt = null; +} +function jur_DotQuantifierSet__init_(var_0, var_1, var_2, var_3) { + var var_4 = new jur_DotQuantifierSet(); + jur_DotQuantifierSet__init_0(var_4, var_0, var_1, var_2, var_3); + return var_4; +} +function jur_DotQuantifierSet__init_0($this, $innerSet, $next, $type, $lt) { + var var$5, var$6; + var$5 = jur_AbstractSet_counter; + jur_AbstractSet_counter = var$5 + 1 | 0; + var$6 = new jl_AbstractStringBuilder; + var$6.$buffer = $rt_createCharArray(20); + $this.$index1 = (jl_AbstractStringBuilder_insert0(var$6, var$6.$length, var$5, 10)).$toString(); + $this.$next0 = $next; + $this.$innerSet = $innerSet; + $this.$type = $type; + $this.$lt = $lt; +} +function jur_DotQuantifierSet_matches($this, $stringIndex, $testString, $matchResult) { + var $strLength, $startSearch, var$6, var$7; + $strLength = $matchResult.$rightBound; + $startSearch = $stringIndex; + a: { + while (true) { + if ($startSearch >= $strLength) { + $startSearch = (-1); + break a; + } + var$6 = $this.$lt; + if ($startSearch < 0) + break; + var$7 = $testString.$characters.data; + if ($startSearch >= var$7.length) + break; + if (var$6.$isLineTerminator(var$7[$startSearch])) + break a; + $startSearch = $startSearch + 1 | 0; + } + $testString = new jl_StringIndexOutOfBoundsException; + $testString.$suppressionEnabled = 1; + $testString.$writableStackTrace = 1; + $rt_throw($testString); + } + if ($startSearch >= 0) + $strLength = $startSearch; + if ($strLength > $stringIndex) + return $this.$next0.$findBack($stringIndex, $strLength, $testString, $matchResult); + return $this.$next0.$matches($stringIndex, $testString, $matchResult); +} +function jur_DotQuantifierSet_find($this, $stringIndex, $testString, $matchResult) { + var $strLength, $res, $nextSearch, var$7, var$8, var$9, $leftBound; + $strLength = $matchResult.$rightBound; + $res = $this.$next0.$find0($stringIndex, $testString, $matchResult); + if ($res < 0) + return (-1); + $nextSearch = $res; + a: { + while (true) { + if ($nextSearch >= $strLength) { + $nextSearch = (-1); + break a; + } + var$7 = $this.$lt; + if ($nextSearch < 0) + break; + var$8 = $testString.$characters.data; + if ($nextSearch >= var$8.length) + break; + if (var$7.$isLineTerminator(var$8[$nextSearch])) + break a; + $nextSearch = $nextSearch + 1 | 0; + } + $testString = new jl_StringIndexOutOfBoundsException; + $testString.$suppressionEnabled = 1; + $testString.$writableStackTrace = 1; + $rt_throw($testString); + } + if ($nextSearch >= 0) + $strLength = $nextSearch; + var$9 = $this.$next0.$findBack($res, $strLength, $testString, $matchResult); + if ($res > var$9) + var$9 = $res; + if (var$9 <= 0) + $leftBound = var$9 ? (-1) : 0; + else { + $leftBound = var$9 - 1 | 0; + b: { + while (true) { + if ($leftBound < $stringIndex) { + $leftBound = (-1); + break b; + } + $matchResult = $this.$lt; + if ($leftBound < 0) + break; + var$8 = $testString.$characters.data; + if ($leftBound >= var$8.length) + break; + if ($matchResult.$isLineTerminator(var$8[$leftBound])) + break b; + $leftBound = $leftBound + (-1) | 0; + } + $testString = new jl_StringIndexOutOfBoundsException; + $testString.$suppressionEnabled = 1; + $testString.$writableStackTrace = 1; + $rt_throw($testString); + } + } + if ($leftBound >= $stringIndex) + $stringIndex = $leftBound >= var$9 ? $leftBound : $leftBound + 1 | 0; + return $stringIndex; +} +var jur_AbstractLineTerminator = $rt_classWithoutFields(); +var jur_AbstractLineTerminator_unixLT = null; +var jur_AbstractLineTerminator_unicodeLT = null; +function jur_AbstractLineTerminator_getInstance($flag) { + var var$2; + if (!($flag & 1)) { + var$2 = jur_AbstractLineTerminator_unicodeLT; + if (var$2 !== null) + return var$2; + var$2 = new jur_AbstractLineTerminator$2; + jur_AbstractLineTerminator_unicodeLT = var$2; + return var$2; + } + var$2 = jur_AbstractLineTerminator_unixLT; + if (var$2 !== null) + return var$2; + var$2 = new jur_AbstractLineTerminator$1; + jur_AbstractLineTerminator_unixLT = var$2; + return var$2; +} +var jur_PossessiveQuantifierSet = $rt_classWithoutFields(jur_LeafQuantifierSet); +function jur_PossessiveQuantifierSet__init_(var_0, var_1, var_2) { + var var_3 = new jur_PossessiveQuantifierSet(); + jur_PossessiveQuantifierSet__init_0(var_3, var_0, var_1, var_2); + return var_3; +} +function jur_PossessiveQuantifierSet__init_0($this, $innerSet, $next, $type) { + var var$4, var$5; + var$4 = jur_AbstractSet_counter; + jur_AbstractSet_counter = var$4 + 1 | 0; + var$5 = new jl_AbstractStringBuilder; + var$5.$buffer = $rt_createCharArray(20); + $this.$index1 = (jl_AbstractStringBuilder_insert0(var$5, var$5.$length, var$4, 10)).$toString(); + $this.$next0 = $next; + $this.$innerSet = $innerSet; + $this.$type = $type; + $this.$leaf = $innerSet; +} +function jur_PossessiveQuantifierSet_matches($this, $stringIndex, $testString, $matchResult) { + var var$4; + a: { + while (true) { + if (($stringIndex + $this.$leaf.$charCount0() | 0) > $matchResult.$rightBound) + break a; + var$4 = $this.$leaf.$accepts($stringIndex, $testString); + if (var$4 < 1) + break; + $stringIndex = $stringIndex + var$4 | 0; + } + } + return $this.$next0.$matches($stringIndex, $testString, $matchResult); +} +var jur_PossessiveAltQuantifierSet = $rt_classWithoutFields(jur_AltQuantifierSet); +function jur_PossessiveAltQuantifierSet__init_(var_0, var_1, var_2) { + var var_3 = new jur_PossessiveAltQuantifierSet(); + jur_PossessiveAltQuantifierSet__init_0(var_3, var_0, var_1, var_2); + return var_3; +} +function jur_PossessiveAltQuantifierSet__init_0($this, $innerSet, $next, $type) { + var var$4, var$5; + var$4 = jur_AbstractSet_counter; + jur_AbstractSet_counter = var$4 + 1 | 0; + var$5 = new jl_AbstractStringBuilder; + jl_Object__init_0(var$5); + var$5.$buffer = $rt_createCharArray(20); + $this.$index1 = (jl_AbstractStringBuilder_insert0(var$5, var$5.$length, var$4, 10)).$toString(); + $this.$next0 = $next; + $this.$innerSet = $innerSet; + $this.$type = $type; + $this.$leaf = $innerSet; +} +function jur_PossessiveAltQuantifierSet_matches($this, $stringIndex, $testString, $matchResult) { + var var$4; + if (($stringIndex + $this.$leaf.$charCount0() | 0) <= $matchResult.$rightBound) { + var$4 = $this.$leaf.$accepts($stringIndex, $testString); + if (var$4 >= 1) + $stringIndex = $stringIndex + var$4 | 0; + } + return $this.$next0.$matches($stringIndex, $testString, $matchResult); +} +var jur_PossessiveCompositeQuantifierSet = $rt_classWithoutFields(jur_CompositeQuantifierSet); +function jur_PossessiveCompositeQuantifierSet__init_(var_0, var_1, var_2, var_3) { + var var_4 = new jur_PossessiveCompositeQuantifierSet(); + jur_PossessiveCompositeQuantifierSet__init_0(var_4, var_0, var_1, var_2, var_3); + return var_4; +} +function jur_PossessiveCompositeQuantifierSet__init_0($this, $quant, $innerSet, $next, $type) { + var var$5, var$6; + var$5 = jur_AbstractSet_counter; + jur_AbstractSet_counter = var$5 + 1 | 0; + var$6 = new jl_AbstractStringBuilder; + jl_Object__init_0(var$6); + var$6.$buffer = $rt_createCharArray(20); + $this.$index1 = (jl_AbstractStringBuilder_insert0(var$6, var$6.$length, var$5, 10)).$toString(); + $this.$next0 = $next; + $this.$innerSet = $innerSet; + $this.$type = $type; + $this.$leaf = $innerSet; + $this.$quantifier0 = $quant; +} +function jur_PossessiveCompositeQuantifierSet_matches($this, $stringIndex, $testString, $matchResult) { + var var$4, $min, $max, $i, $shift; + var$4 = $this.$quantifier0; + $min = var$4.$min; + $max = var$4.$max; + $i = 0; + while (true) { + if ($i >= $min) { + a: { + while (true) { + if ($i >= $max) + break a; + if (($stringIndex + $this.$leaf.$charCount0() | 0) > $matchResult.$rightBound) + break a; + $shift = $this.$leaf.$accepts($stringIndex, $testString); + if ($shift < 1) + break; + $stringIndex = $stringIndex + $shift | 0; + $i = $i + 1 | 0; + } + } + return $this.$next0.$matches($stringIndex, $testString, $matchResult); + } + if (($stringIndex + $this.$leaf.$charCount0() | 0) > $matchResult.$rightBound) { + $matchResult.$hitEnd = 1; + return (-1); + } + $shift = $this.$leaf.$accepts($stringIndex, $testString); + if ($shift < 1) + break; + $stringIndex = $stringIndex + $shift | 0; + $i = $i + 1 | 0; + } + return (-1); +} +var jur_ReluctantQuantifierSet = $rt_classWithoutFields(jur_LeafQuantifierSet); +function jur_ReluctantQuantifierSet__init_(var_0, var_1, var_2) { + var var_3 = new jur_ReluctantQuantifierSet(); + jur_ReluctantQuantifierSet__init_0(var_3, var_0, var_1, var_2); + return var_3; +} +function jur_ReluctantQuantifierSet__init_0($this, $innerSet, $next, $type) { + var var$4, var$5; + var$4 = jur_AbstractSet_counter; + jur_AbstractSet_counter = var$4 + 1 | 0; + var$5 = new jl_AbstractStringBuilder; + var$5.$buffer = $rt_createCharArray(20); + $this.$index1 = (jl_AbstractStringBuilder_insert0(var$5, var$5.$length, var$4, 10)).$toString(); + $this.$next0 = $next; + $this.$innerSet = $innerSet; + $this.$type = $type; + $this.$leaf = $innerSet; +} +function jur_ReluctantQuantifierSet_matches($this, $stringIndex, $testString, $matchResult) { + var var$4; + while (true) { + var$4 = $this.$next0.$matches($stringIndex, $testString, $matchResult); + if (var$4 >= 0) + break; + if (($stringIndex + $this.$leaf.$charCount0() | 0) <= $matchResult.$rightBound) { + var$4 = $this.$leaf.$accepts($stringIndex, $testString); + $stringIndex = $stringIndex + var$4 | 0; + } + if (var$4 < 1) + return (-1); + } + return var$4; +} +var jur_ReluctantAltQuantifierSet = $rt_classWithoutFields(jur_AltQuantifierSet); +function jur_ReluctantAltQuantifierSet__init_(var_0, var_1, var_2) { + var var_3 = new jur_ReluctantAltQuantifierSet(); + jur_ReluctantAltQuantifierSet__init_0(var_3, var_0, var_1, var_2); + return var_3; +} +function jur_ReluctantAltQuantifierSet__init_0($this, $innerSet, $next, $type) { + var var$4, var$5; + var$4 = jur_AbstractSet_counter; + jur_AbstractSet_counter = var$4 + 1 | 0; + var$5 = new jl_AbstractStringBuilder; + jl_Object__init_0(var$5); + var$5.$buffer = $rt_createCharArray(20); + $this.$index1 = (jl_AbstractStringBuilder_insert0(var$5, var$5.$length, var$4, 10)).$toString(); + $this.$next0 = $next; + $this.$innerSet = $innerSet; + $this.$type = $type; + $this.$leaf = $innerSet; +} +function jur_ReluctantAltQuantifierSet_matches($this, $stringIndex, $testString, $matchResult) { + var $shift; + $shift = $this.$next0.$matches($stringIndex, $testString, $matchResult); + if ($shift >= 0) + return $shift; + return $this.$innerSet.$matches($stringIndex, $testString, $matchResult); +} +var jur_ReluctantCompositeQuantifierSet = $rt_classWithoutFields(jur_CompositeQuantifierSet); +function jur_ReluctantCompositeQuantifierSet__init_(var_0, var_1, var_2, var_3) { + var var_4 = new jur_ReluctantCompositeQuantifierSet(); + jur_ReluctantCompositeQuantifierSet__init_0(var_4, var_0, var_1, var_2, var_3); + return var_4; +} +function jur_ReluctantCompositeQuantifierSet__init_0($this, $quant, $innerSet, $next, $type) { + var var$5, var$6; + var$5 = jur_AbstractSet_counter; + jur_AbstractSet_counter = var$5 + 1 | 0; + var$6 = new jl_AbstractStringBuilder; + jl_Object__init_0(var$6); + var$6.$buffer = $rt_createCharArray(20); + $this.$index1 = (jl_AbstractStringBuilder_insert0(var$6, var$6.$length, var$5, 10)).$toString(); + $this.$next0 = $next; + $this.$innerSet = $innerSet; + $this.$type = $type; + $this.$leaf = $innerSet; + $this.$quantifier0 = $quant; +} +function jur_ReluctantCompositeQuantifierSet_matches($this, $stringIndex, $testString, $matchResult) { + var var$4, $min, $max, $i, var$8, var$9; + var$4 = $this.$quantifier0; + $min = var$4.$min; + $max = var$4.$max; + $i = 0; + while (true) { + if ($i >= $min) { + a: { + while (true) { + var$8 = $this.$next0.$matches($stringIndex, $testString, $matchResult); + if (var$8 >= 0) + break; + if (($stringIndex + $this.$leaf.$charCount0() | 0) <= $matchResult.$rightBound) { + var$8 = $this.$leaf.$accepts($stringIndex, $testString); + $stringIndex = $stringIndex + var$8 | 0; + $i = $i + 1 | 0; + } + if (var$8 < 1) + break a; + if ($i > $max) + break a; + } + return var$8; + } + return (-1); + } + if (($stringIndex + $this.$leaf.$charCount0() | 0) > $matchResult.$rightBound) { + $matchResult.$hitEnd = 1; + return (-1); + } + var$9 = $this.$leaf.$accepts($stringIndex, $testString); + if (var$9 < 1) + break; + $stringIndex = $stringIndex + var$9 | 0; + $i = $i + 1 | 0; + } + return (-1); +} +var jur_SOLSet = $rt_classWithoutFields(jur_AbstractSet); +function jur_SOLSet__init_() { + var var_0 = new jur_SOLSet(); + jur_SOLSet__init_0(var_0); + return var_0; +} +function jur_SOLSet__init_0($this) { + var var$1, var$2; + var$1 = jur_AbstractSet_counter; + jur_AbstractSet_counter = var$1 + 1 | 0; + var$2 = new jl_AbstractStringBuilder; + var$2.$buffer = $rt_createCharArray(20); + $this.$index1 = (jl_AbstractStringBuilder_insert0(var$2, var$2.$length, var$1, 10)).$toString(); +} +function jur_SOLSet_matches($this, $strIndex, $testString, $matchResult) { + if ($strIndex && !($matchResult.$anchoringBounds && $strIndex == $matchResult.$leftBound)) + return (-1); + return $this.$next0.$matches($strIndex, $testString, $matchResult); +} +function jur_SOLSet_hasConsumed($this, $matchResult) { + return 0; +} +function jur_WordBoundary() { + jur_AbstractSet.call(this); + this.$positive = 0; +} +function jur_WordBoundary__init_(var_0) { + var var_1 = new jur_WordBoundary(); + jur_WordBoundary__init_0(var_1, var_0); + return var_1; +} +function jur_WordBoundary__init_0($this, $positive) { + var var$2, var$3; + var$2 = jur_AbstractSet_counter; + jur_AbstractSet_counter = var$2 + 1 | 0; + var$3 = new jl_AbstractStringBuilder; + var$3.$buffer = $rt_createCharArray(20); + $this.$index1 = (jl_AbstractStringBuilder_insert0(var$3, var$3.$length, var$2, 10)).$toString(); + $this.$positive = $positive; +} +function jur_WordBoundary_matches($this, $stringIndex, $testString, $matchResult) { + var $ch1, var$5, $ch2, $leftBound; + a: { + if ($stringIndex >= $matchResult.$rightBound) + $ch1 = 32; + else { + if ($stringIndex >= 0) { + var$5 = $testString.$characters.data; + if ($stringIndex < var$5.length) { + $ch1 = var$5[$stringIndex]; + break a; + } + } + $testString = new jl_StringIndexOutOfBoundsException; + $testString.$suppressionEnabled = 1; + $testString.$writableStackTrace = 1; + $rt_throw($testString); + } + } + b: { + if (!$stringIndex) + $ch2 = 32; + else { + $ch2 = $stringIndex - 1 | 0; + if ($ch2 >= 0) { + var$5 = $testString.$characters.data; + if ($ch2 < var$5.length) { + $ch2 = var$5[$ch2]; + break b; + } + } + $testString = new jl_StringIndexOutOfBoundsException; + $testString.$suppressionEnabled = 1; + $testString.$writableStackTrace = 1; + $rt_throw($testString); + } + } + $leftBound = $matchResult.$transparentBounds ? 0 : $matchResult.$leftBound; + return ($ch1 != 32 && !jur_WordBoundary_isSpace($this, $ch1, $stringIndex, $leftBound, $testString) ? 0 : 1) ^ ($ch2 != 32 && !jur_WordBoundary_isSpace($this, $ch2, $stringIndex - 1 | 0, $leftBound, $testString) ? 0 : 1) ^ $this.$positive ? (-1) : $this.$next0.$matches($stringIndex, $testString, $matchResult); +} +function jur_WordBoundary_hasConsumed($this, $matchResult) { + return 0; +} +function jur_WordBoundary_isSpace($this, $ch, $index, $leftBound, $testString) { + var var$5, var$6; + a: { + b: { + switch (jl_Character_getType($ch)) { + case 1: + case 2: + case 3: + case 4: + case 5: + case 9: + break; + case 6: + case 7: + case 8: + break b; + default: + break b; + } + var$5 = 1; + break a; + } + var$5 = 0; + } + if (!var$5 && $ch != 95) { + c: { + d: { + if (jl_Character_getType($ch) == 6) + while (true) { + $index = $index + (-1) | 0; + if ($index < $leftBound) + break d; + if ($index < 0) + break c; + var$6 = $testString.$characters.data; + if ($index >= var$6.length) + break c; + e: { + f: { + $ch = var$6[$index]; + switch (jl_Character_getType($ch)) { + case 1: + case 2: + case 3: + case 4: + case 5: + case 9: + break; + case 6: + case 7: + case 8: + break f; + default: + break f; + } + var$5 = 1; + break e; + } + var$5 = 0; + } + if (var$5) + return 0; + if (jl_Character_getType($ch) != 6) + return 1; + } + } + return 1; + } + $testString = new jl_StringIndexOutOfBoundsException; + $testString.$suppressionEnabled = 1; + $testString.$writableStackTrace = 1; + $rt_throw($testString); + } + return 0; +} +var jur_PreviousMatch = $rt_classWithoutFields(jur_AbstractSet); +function jur_PreviousMatch__init_() { + var var_0 = new jur_PreviousMatch(); + jur_PreviousMatch__init_0(var_0); + return var_0; +} +function jur_PreviousMatch__init_0($this) { + var var$1, var$2; + var$1 = jur_AbstractSet_counter; + jur_AbstractSet_counter = var$1 + 1 | 0; + var$2 = new jl_AbstractStringBuilder; + var$2.$buffer = $rt_createCharArray(20); + $this.$index1 = (jl_AbstractStringBuilder_insert0(var$2, var$2.$length, var$1, 10)).$toString(); +} +function jur_PreviousMatch_matches($this, $stringIndex, $testString, $matchResult) { + if ($stringIndex != $matchResult.$previousMatch) + return (-1); + return $this.$next0.$matches($stringIndex, $testString, $matchResult); +} +function jur_PreviousMatch_hasConsumed($this, $matchResult) { + return 0; +} +function jur_EOLSet() { + jur_AbstractSet.call(this); + this.$consCounter = 0; +} +function jur_EOLSet__init_0(var_0) { + var var_1 = new jur_EOLSet(); + jur_EOLSet__init_(var_1, var_0); + return var_1; +} +function jur_EOLSet__init_($this, $counter) { + var var$2, var$3; + var$2 = jur_AbstractSet_counter; + jur_AbstractSet_counter = var$2 + 1 | 0; + var$3 = new jl_AbstractStringBuilder; + var$3.$buffer = $rt_createCharArray(20); + $this.$index1 = (jl_AbstractStringBuilder_insert0(var$3, var$3.$length, var$2, 10)).$toString(); + $this.$consCounter = $counter; +} +function jur_EOLSet_matches($this, $strIndex, $testString, $matchResult) { + var $rightBound, $ch, var$6, var$7; + $rightBound = $matchResult.$anchoringBounds ? $matchResult.$rightBound : $testString.$characters.data.length; + if ($strIndex >= $rightBound) { + $ch = $this.$consCounter; + $matchResult.$consumers.data[$ch] = 0; + return $this.$next0.$matches($strIndex, $testString, $matchResult); + } + a: { + var$6 = $rightBound - $strIndex | 0; + if (var$6 == 2) { + if ($strIndex >= 0) { + var$7 = $testString.$characters.data; + $ch = var$7.length; + if ($strIndex < $ch) { + if (var$7[$strIndex] != 13) + break a; + $rightBound = $strIndex + 1 | 0; + if ($rightBound >= 0 && $rightBound < $ch) { + if (var$7[$rightBound] != 10) + break a; + $ch = $this.$consCounter; + $matchResult.$consumers.data[$ch] = 0; + return $this.$next0.$matches($strIndex, $testString, $matchResult); + } + $testString = new jl_StringIndexOutOfBoundsException; + $testString.$suppressionEnabled = 1; + $testString.$writableStackTrace = 1; + $rt_throw($testString); + } + } + $testString = new jl_StringIndexOutOfBoundsException; + $testString.$suppressionEnabled = 1; + $testString.$writableStackTrace = 1; + $rt_throw($testString); + } + } + b: { + c: { + if (var$6 == 1) { + if ($strIndex >= 0) { + var$7 = $testString.$characters.data; + if ($strIndex < var$7.length) { + $ch = var$7[$strIndex]; + if ($ch == 10) + break b; + if ($ch == 13) + break b; + if ($ch == 133) + break b; + if (($ch | 1) != 8233) + break c; + else + break b; + } + } + $testString = new jl_StringIndexOutOfBoundsException; + $testString.$suppressionEnabled = 1; + $testString.$writableStackTrace = 1; + $rt_throw($testString); + } + } + return (-1); + } + $rightBound = $this.$consCounter; + $matchResult.$consumers.data[$rightBound] = 0; + return $this.$next0.$matches($strIndex, $testString, $matchResult); +} +function jur_EOLSet_hasConsumed($this, $matchResult) { + var var$2, var$3, $res; + var$2 = $this.$consCounter; + var$3 = $matchResult.$consumers.data; + $res = !var$3[var$2] ? 0 : 1; + var$3[var$2] = (-1); + return $res; +} +var jur_EOISet = $rt_classWithoutFields(jur_AbstractSet); +function jur_EOISet__init_() { + var var_0 = new jur_EOISet(); + jur_EOISet__init_0(var_0); + return var_0; +} +function jur_EOISet__init_0($this) { + var var$1, var$2; + var$1 = jur_AbstractSet_counter; + jur_AbstractSet_counter = var$1 + 1 | 0; + var$2 = new jl_AbstractStringBuilder; + var$2.$buffer = $rt_createCharArray(20); + $this.$index1 = (jl_AbstractStringBuilder_insert0(var$2, var$2.$length, var$1, 10)).$toString(); +} +function jur_EOISet_matches($this, $stringIndex, $testString, $matchResult) { + if ($stringIndex < (!$matchResult.$transparentBounds ? $matchResult.$rightBound : $testString.$characters.data.length)) + return (-1); + $matchResult.$hitEnd = 1; + $matchResult.$requireEnd = 1; + return $this.$next0.$matches($stringIndex, $testString, $matchResult); +} +function jur_EOISet_hasConsumed($this, $matchResult) { + return 0; +} +function jur_MultiLineSOLSet() { + jur_AbstractSet.call(this); + this.$lt0 = null; +} +function jur_MultiLineSOLSet__init_(var_0) { + var var_1 = new jur_MultiLineSOLSet(); + jur_MultiLineSOLSet__init_0(var_1, var_0); + return var_1; +} +function jur_MultiLineSOLSet__init_0($this, $lt) { + var var$2, var$3; + var$2 = jur_AbstractSet_counter; + jur_AbstractSet_counter = var$2 + 1 | 0; + var$3 = new jl_AbstractStringBuilder; + var$3.$buffer = $rt_createCharArray(20); + $this.$index1 = (jl_AbstractStringBuilder_insert0(var$3, var$3.$length, var$2, 10)).$toString(); + $this.$lt0 = $lt; +} +function jur_MultiLineSOLSet_matches($this, $strIndex, $testString, $matchResult) { + var var$4, var$5, var$6, var$7, var$8; + a: { + b: { + c: { + if ($strIndex != $matchResult.$rightBound) { + if (!$strIndex) + break b; + if ($matchResult.$anchoringBounds && $strIndex == $matchResult.$leftBound) + break b; + var$4 = $this.$lt0; + var$5 = $strIndex - 1 | 0; + if (var$5 >= 0) { + var$6 = $testString.$characters.data; + var$7 = var$6.length; + if (var$5 < var$7) { + var$8 = var$6[var$5]; + if ($strIndex < 0) + break a; + if ($strIndex >= var$7) + break a; + if (!var$4.$isAfterLineTerminator(var$8, var$6[$strIndex])) + break c; + else + break b; + } + } + $testString = new jl_StringIndexOutOfBoundsException; + $testString.$suppressionEnabled = 1; + $testString.$writableStackTrace = 1; + $rt_throw($testString); + } + } + return (-1); + } + return $this.$next0.$matches($strIndex, $testString, $matchResult); + } + $testString = new jl_StringIndexOutOfBoundsException; + $testString.$suppressionEnabled = 1; + $testString.$writableStackTrace = 1; + $rt_throw($testString); +} +function jur_MultiLineSOLSet_hasConsumed($this, $matchResult) { + return 0; +} +var jur_DotAllSet = $rt_classWithoutFields(jur_JointSet); +function jur_DotAllSet__init_() { + var var_0 = new jur_DotAllSet(); + jur_DotAllSet__init_0(var_0); + return var_0; +} +function jur_DotAllSet__init_0($this) { + var var$1, var$2; + var$1 = jur_AbstractSet_counter; + jur_AbstractSet_counter = var$1 + 1 | 0; + var$2 = new jl_AbstractStringBuilder; + var$2.$buffer = $rt_createCharArray(20); + $this.$index1 = (jl_AbstractStringBuilder_insert0(var$2, var$2.$length, var$1, 10)).$toString(); +} +function jur_DotAllSet_matches($this, $stringIndex, $testString, $matchResult) { + var $strLength, var$5, var$6, var$7, $high, $low, var$10; + $strLength = $matchResult.$rightBound; + var$5 = $stringIndex + 1 | 0; + if (var$5 > $strLength) { + $matchResult.$hitEnd = 1; + return (-1); + } + if ($stringIndex >= 0) { + var$6 = $testString.$characters.data; + var$7 = var$6.length; + if ($stringIndex < var$7) { + $high = $rt_compare(var$6[$stringIndex] & 64512, 55296); + $low = $high ? 0 : 1; + a: { + if ($low) { + var$10 = $stringIndex + 2 | 0; + if (var$10 <= $strLength) { + if (var$5 >= 0 && var$5 < var$7) { + $low = var$6[var$5]; + $stringIndex = $high ? 0 : 1; + if (!($stringIndex && (($low & 64512) != 56320 ? 0 : 1) ? 1 : 0)) + break a; + else + return $this.$next0.$matches(var$10, $testString, $matchResult); + } + $testString = new jl_StringIndexOutOfBoundsException; + $testString.$suppressionEnabled = 1; + $testString.$writableStackTrace = 1; + $rt_throw($testString); + } + } + } + return $this.$next0.$matches(var$5, $testString, $matchResult); + } + } + $testString = new jl_StringIndexOutOfBoundsException; + $testString.$suppressionEnabled = 1; + $testString.$writableStackTrace = 1; + $rt_throw($testString); +} +function jur_DotAllSet_setNext($this, $next) { + $this.$next0 = $next; +} +function jur_DotAllSet_getType($this) { + return (-2147483602); +} +function jur_DotAllSet_hasConsumed($this, $matchResult) { + return 1; +} +function jur_DotSet() { + jur_JointSet.call(this); + this.$lt1 = null; +} +function jur_DotSet__init_(var_0) { + var var_1 = new jur_DotSet(); + jur_DotSet__init_0(var_1, var_0); + return var_1; +} +function jur_DotSet__init_0($this, $lt) { + var var$2, var$3; + var$2 = jur_AbstractSet_counter; + jur_AbstractSet_counter = var$2 + 1 | 0; + var$3 = new jl_AbstractStringBuilder; + var$3.$buffer = $rt_createCharArray(20); + $this.$index1 = (jl_AbstractStringBuilder_insert0(var$3, var$3.$length, var$2, 10)).$toString(); + $this.$lt1 = $lt; +} +function jur_DotSet_matches($this, $stringIndex, $testString, $matchResult) { + var $strLength, var$5, var$6, var$7, $high, var$9, $low, var$11; + $strLength = $matchResult.$rightBound; + var$5 = $stringIndex + 1 | 0; + if (var$5 > $strLength) { + $matchResult.$hitEnd = 1; + return (-1); + } + if ($stringIndex >= 0) { + var$6 = $testString.$characters.data; + var$7 = var$6.length; + if ($stringIndex < var$7) { + $high = var$6[$stringIndex]; + var$9 = $rt_compare($high & 64512, 55296); + $low = var$9 ? 0 : 1; + a: { + if ($low) { + var$11 = $stringIndex + 2 | 0; + if (var$11 <= $strLength) { + if (var$5 >= 0 && var$5 < var$7) { + $low = var$6[var$5]; + $stringIndex = var$9 ? 0 : 1; + if (!($stringIndex && (($low & 64512) != 56320 ? 0 : 1) ? 1 : 0)) + break a; + else + return $this.$lt1.$isLineTerminator((($high & 1023) << 10 | $low & 1023) + 65536 | 0) ? (-1) : $this.$next0.$matches(var$11, $testString, $matchResult); + } + $testString = new jl_StringIndexOutOfBoundsException; + $testString.$suppressionEnabled = 1; + $testString.$writableStackTrace = 1; + $rt_throw($testString); + } + } + } + return $this.$lt1.$isLineTerminator($high) ? (-1) : $this.$next0.$matches(var$5, $testString, $matchResult); + } + } + $testString = new jl_StringIndexOutOfBoundsException; + $testString.$suppressionEnabled = 1; + $testString.$writableStackTrace = 1; + $rt_throw($testString); +} +function jur_DotSet_setNext($this, $next) { + $this.$next0 = $next; +} +function jur_DotSet_getType($this) { + return (-2147483602); +} +function jur_DotSet_hasConsumed($this, $matchResult) { + return 1; +} +function jur_UEOLSet() { + jur_AbstractSet.call(this); + this.$consCounter0 = 0; +} +function jur_UEOLSet__init_(var_0) { + var var_1 = new jur_UEOLSet(); + jur_UEOLSet__init_0(var_1, var_0); + return var_1; +} +function jur_UEOLSet__init_0($this, $counter) { + var var$2, var$3; + var$2 = jur_AbstractSet_counter; + jur_AbstractSet_counter = var$2 + 1 | 0; + var$3 = new jl_AbstractStringBuilder; + var$3.$buffer = $rt_createCharArray(20); + $this.$index1 = (jl_AbstractStringBuilder_insert0(var$3, var$3.$length, var$2, 10)).$toString(); + $this.$consCounter0 = $counter; +} +function jur_UEOLSet_matches($this, $strIndex, $testString, $matchResult) { + var $rightBound, var$5, var$6; + $rightBound = $matchResult.$anchoringBounds ? $matchResult.$rightBound : $testString.$characters.data.length; + if ($strIndex >= $rightBound) { + $rightBound = $this.$consCounter0; + $matchResult.$consumers.data[$rightBound] = 0; + return $this.$next0.$matches($strIndex, $testString, $matchResult); + } + a: { + if (($rightBound - $strIndex | 0) == 1) { + if ($strIndex >= 0) { + var$5 = $testString.$characters.data; + if ($strIndex < var$5.length) { + if (var$5[$strIndex] != 10) + break a; + else { + var$6 = $this.$consCounter0; + $matchResult.$consumers.data[var$6] = 1; + return $this.$next0.$matches($strIndex + 1 | 0, $testString, $matchResult); + } + } + } + $testString = new jl_StringIndexOutOfBoundsException; + $testString.$suppressionEnabled = 1; + $testString.$writableStackTrace = 1; + $rt_throw($testString); + } + } + return (-1); +} +function jur_UEOLSet_hasConsumed($this, $matchResult) { + var var$2, var$3, $res; + var$2 = $this.$consCounter0; + var$3 = $matchResult.$consumers.data; + $res = !var$3[var$2] ? 0 : 1; + var$3[var$2] = (-1); + return $res; +} +function jur_UMultiLineEOLSet() { + jur_AbstractSet.call(this); + this.$consCounter1 = 0; +} +function jur_UMultiLineEOLSet__init_(var_0) { + var var_1 = new jur_UMultiLineEOLSet(); + jur_UMultiLineEOLSet__init_0(var_1, var_0); + return var_1; +} +function jur_UMultiLineEOLSet__init_0($this, $counter) { + var var$2, var$3; + var$2 = jur_AbstractSet_counter; + jur_AbstractSet_counter = var$2 + 1 | 0; + var$3 = new jl_AbstractStringBuilder; + var$3.$buffer = $rt_createCharArray(20); + $this.$index1 = (jl_AbstractStringBuilder_insert0(var$3, var$3.$length, var$2, 10)).$toString(); + $this.$consCounter1 = $counter; +} +function jur_UMultiLineEOLSet_matches($this, $strIndex, $testString, $matchResult) { + var $strDif, var$5, var$6; + if (($matchResult.$anchoringBounds ? $matchResult.$rightBound - $strIndex | 0 : $testString.$characters.data.length - $strIndex | 0) <= 0) { + $strDif = $this.$consCounter1; + $matchResult.$consumers.data[$strDif] = 0; + return $this.$next0.$matches($strIndex, $testString, $matchResult); + } + if ($strIndex >= 0) { + var$5 = $testString.$characters.data; + if ($strIndex < var$5.length) { + if (var$5[$strIndex] != 10) + return (-1); + var$6 = $this.$consCounter1; + $matchResult.$consumers.data[var$6] = 1; + return $this.$next0.$matches($strIndex + 1 | 0, $testString, $matchResult); + } + } + $testString = new jl_StringIndexOutOfBoundsException; + $testString.$suppressionEnabled = 1; + $testString.$writableStackTrace = 1; + $rt_throw($testString); +} +function jur_UMultiLineEOLSet_hasConsumed($this, $matchResult) { + var var$2, var$3, $res; + var$2 = $this.$consCounter1; + var$3 = $matchResult.$consumers.data; + $res = !var$3[var$2] ? 0 : 1; + var$3[var$2] = (-1); + return $res; +} +function jur_MultiLineEOLSet() { + jur_AbstractSet.call(this); + this.$consCounter2 = 0; +} +function jur_MultiLineEOLSet__init_(var_0) { + var var_1 = new jur_MultiLineEOLSet(); + jur_MultiLineEOLSet__init_0(var_1, var_0); + return var_1; +} +function jur_MultiLineEOLSet__init_0($this, $counter) { + var var$2, var$3; + var$2 = jur_AbstractSet_counter; + jur_AbstractSet_counter = var$2 + 1 | 0; + var$3 = new jl_AbstractStringBuilder; + var$3.$buffer = $rt_createCharArray(20); + $this.$index1 = (jl_AbstractStringBuilder_insert0(var$3, var$3.$length, var$2, 10)).$toString(); + $this.$consCounter2 = $counter; +} +function jur_MultiLineEOLSet_matches($this, $strIndex, $testString, $matchResult) { + var $strDif, var$5, $ch1, $ch2; + $strDif = $matchResult.$anchoringBounds ? $matchResult.$leftBound - $strIndex | 0 : $testString.$characters.data.length - $strIndex | 0; + if (!$strDif) { + $strDif = $this.$consCounter2; + $matchResult.$consumers.data[$strDif] = 0; + return $this.$next0.$matches($strIndex, $testString, $matchResult); + } + a: { + if ($strDif < 2) { + if ($strIndex >= 0) { + var$5 = $testString.$characters.data; + if ($strIndex < var$5.length) { + $ch1 = var$5[$strIndex]; + $ch2 = 97; + break a; + } + } + $testString = new jl_StringIndexOutOfBoundsException; + $testString.$suppressionEnabled = 1; + $testString.$writableStackTrace = 1; + $rt_throw($testString); + } + if ($strIndex >= 0) { + var$5 = $testString.$characters.data; + $ch2 = var$5.length; + if ($strIndex < $ch2) { + $ch1 = var$5[$strIndex]; + $strDif = $strIndex + 1 | 0; + if ($strDif >= 0 && $strDif < $ch2) { + $ch2 = var$5[$strDif]; + break a; + } + $testString = new jl_StringIndexOutOfBoundsException; + $testString.$suppressionEnabled = 1; + $testString.$writableStackTrace = 1; + $rt_throw($testString); + } + } + $testString = new jl_StringIndexOutOfBoundsException; + $testString.$suppressionEnabled = 1; + $testString.$writableStackTrace = 1; + $rt_throw($testString); + } + switch ($ch1) { + case 10: + case 133: + case 8232: + case 8233: + $strDif = $this.$consCounter2; + $matchResult.$consumers.data[$strDif] = 0; + return $this.$next0.$matches($strIndex, $testString, $matchResult); + case 13: + if ($ch2 != 10) { + $strDif = $this.$consCounter2; + $matchResult.$consumers.data[$strDif] = 0; + return $this.$next0.$matches($strIndex, $testString, $matchResult); + } + $strDif = $this.$consCounter2; + $matchResult.$consumers.data[$strDif] = 0; + return $this.$next0.$matches($strIndex, $testString, $matchResult); + default: + } + return (-1); +} +function jur_MultiLineEOLSet_hasConsumed($this, $matchResult) { + var var$2, var$3, $res; + var$2 = $this.$consCounter2; + var$3 = $matchResult.$consumers.data; + $res = !var$3[var$2] ? 0 : 1; + var$3[var$2] = (-1); + return $res; +} +function jur_CIBackReferenceSet() { + var a = this; jur_JointSet.call(a); + a.$referencedGroup = 0; + a.$consCounter3 = 0; +} +function jur_CIBackReferenceSet__init_(var_0, var_1) { + var var_2 = new jur_CIBackReferenceSet(); + jur_CIBackReferenceSet__init_0(var_2, var_0, var_1); + return var_2; +} +function jur_CIBackReferenceSet__init_0($this, $groupIndex, $consCounter) { + var var$3, var$4; + var$3 = jur_AbstractSet_counter; + jur_AbstractSet_counter = var$3 + 1 | 0; + var$4 = new jl_AbstractStringBuilder; + var$4.$buffer = $rt_createCharArray(20); + $this.$index1 = (jl_AbstractStringBuilder_insert0(var$4, var$4.$length, var$3, 10)).$toString(); + $this.$referencedGroup = $groupIndex; + $this.$consCounter3 = $consCounter; +} +function jur_CIBackReferenceSet_matches($this, $stringIndex, $testString, $matchResult) { + var $group, $i, var$6, var$7, var$8, var$9, var$10; + $group = jur_CIBackReferenceSet_getString($this, $matchResult); + if ($group !== null && ($stringIndex + $group.$characters.data.length | 0) <= $matchResult.$rightBound) { + $i = 0; + a: { + b: { + c: { + d: { + while (true) { + var$6 = $group.$characters.data; + var$7 = var$6.length; + var$8 = $rt_compare($i, var$7); + if (var$8 >= 0) { + $i = $this.$consCounter3; + $matchResult.$consumers.data[$i] = var$7; + return $this.$next0.$matches($stringIndex + var$7 | 0, $testString, $matchResult); + } + if ($i < 0) + break c; + if (var$8 >= 0) + break c; + var$9 = var$6[$i]; + var$7 = $stringIndex + $i | 0; + if (var$7 < 0) + break d; + var$10 = $testString.$characters.data; + if (var$7 >= var$10.length) + break d; + if (var$9 != var$10[var$7]) { + if ($i < 0) + break a; + if (var$8 >= 0) + break a; + var$8 = jur_Pattern_getSupplement(var$6[$i]); + if (var$7 < 0) + break b; + var$10 = $testString.$characters.data; + if (var$7 >= var$10.length) + break b; + if (var$8 != var$10[var$7]) + break; + } + $i = $i + 1 | 0; + } + return (-1); + } + $testString = new jl_StringIndexOutOfBoundsException; + $testString.$suppressionEnabled = 1; + $testString.$writableStackTrace = 1; + $rt_throw($testString); + } + $testString = new jl_StringIndexOutOfBoundsException; + $testString.$suppressionEnabled = 1; + $testString.$writableStackTrace = 1; + $rt_throw($testString); + } + $testString = new jl_StringIndexOutOfBoundsException; + $testString.$suppressionEnabled = 1; + $testString.$writableStackTrace = 1; + $rt_throw($testString); + } + $testString = new jl_StringIndexOutOfBoundsException; + $testString.$suppressionEnabled = 1; + $testString.$writableStackTrace = 1; + $rt_throw($testString); + } + return (-1); +} +function jur_CIBackReferenceSet_setNext($this, $next) { + $this.$next0 = $next; +} +function jur_CIBackReferenceSet_getString($this, $matchResult) { + var var$2, var$3, var$4, var$5, var$6, var$7, $res, var$9; + a: { + var$2 = $this.$referencedGroup; + var$3 = $matchResult.$groupBounds.data; + var$4 = var$2 * 2 | 0; + var$5 = var$3[var$4]; + var$6 = var$3[var$4 + 1 | 0]; + var$2 = var$6 | var$5; + var$4 = var$6 - var$5 | 0; + if ((var$2 | var$4) >= 0) { + var$7 = $matchResult.$string0.$characters.data; + if (var$6 <= var$7.length) { + if (var$5 > var$6) { + $matchResult = new jl_IndexOutOfBoundsException; + $matchResult.$suppressionEnabled = 1; + $matchResult.$writableStackTrace = 1; + $rt_throw($matchResult); + } + $res = new jl_String; + var$3 = $rt_createCharArray(var$4); + var$9 = var$3.data; + $res.$characters = var$3; + var$2 = 0; + while (var$2 < var$4) { + var$9[var$2] = var$7[var$2 + var$5 | 0]; + var$2 = var$2 + 1 | 0; + } + break a; + } + } + $res = null; + } + return $res; +} +function jur_CIBackReferenceSet_hasConsumed($this, $matchResult) { + var var$2, var$3, $res; + var$2 = $this.$consCounter3; + var$3 = $matchResult.$consumers.data; + $res = !var$3[var$2] ? 0 : 1; + var$3[var$2] = (-1); + return $res; +} +var jur_BackReferenceSet = $rt_classWithoutFields(jur_CIBackReferenceSet); +function jur_BackReferenceSet__init_(var_0, var_1) { + var var_2 = new jur_BackReferenceSet(); + jur_BackReferenceSet__init_0(var_2, var_0, var_1); + return var_2; +} +function jur_BackReferenceSet__init_0($this, $groupIndex, $consCounter) { + var var$3, var$4; + var$3 = jur_AbstractSet_counter; + jur_AbstractSet_counter = var$3 + 1 | 0; + var$4 = new jl_AbstractStringBuilder; + var$4.$buffer = $rt_createCharArray(20); + $this.$index1 = (jl_AbstractStringBuilder_insert0(var$4, var$4.$length, var$3, 10)).$toString(); + $this.$referencedGroup = $groupIndex; + $this.$consCounter3 = $consCounter; +} +function jur_BackReferenceSet_matches($this, $stringIndex, $testString, $matchResult) { + var $group, $shift, var$6; + $group = jur_CIBackReferenceSet_getString($this, $matchResult); + if ($group !== null && ($stringIndex + $group.$characters.data.length | 0) <= $matchResult.$rightBound) { + $shift = !jl_String_startsWith($testString, $group, $stringIndex) ? (-1) : $group.$characters.data.length; + if ($shift < 0) + return (-1); + var$6 = $this.$consCounter3; + $matchResult.$consumers.data[var$6] = $shift; + return $this.$next0.$matches($stringIndex + $shift | 0, $testString, $matchResult); + } + return (-1); +} +function jur_BackReferenceSet_find($this, $strIndex, $testString, $matchResult) { + var $group, $strLength; + $group = jur_CIBackReferenceSet_getString($this, $matchResult); + $strLength = $matchResult.$leftBound; + if ($group !== null && ($strIndex + $group.$characters.data.length | 0) <= $strLength) { + while (true) { + if ($strIndex > $strLength) + return (-1); + $strIndex = jl_String_indexOf0($testString, $group, $strIndex); + if ($strIndex < 0) + return (-1); + if ($this.$next0.$matches($strIndex + $group.$characters.data.length | 0, $testString, $matchResult) >= 0) + break; + $strIndex = $strIndex + 1 | 0; + } + return $strIndex; + } + return (-1); +} +function jur_BackReferenceSet_findBack($this, $strIndex, $lastIndex, $testString, $matchResult) { + var $group, var$6; + $group = jur_CIBackReferenceSet_getString($this, $matchResult); + if ($group === null) + return (-1); + a: { + while (true) { + if ($lastIndex < $strIndex) + return (-1); + var$6 = jl_String_lastIndexOf0($testString, $group, $lastIndex); + if (var$6 < 0) + break a; + if (var$6 < $strIndex) + break a; + if ($this.$next0.$matches(var$6 + $group.$characters.data.length | 0, $testString, $matchResult) >= 0) + break; + $lastIndex = var$6 + (-1) | 0; + } + return var$6; + } + return (-1); +} +function jur_BackReferenceSet_first($this, $set) { + return 1; +} +var jur_UCIBackReferenceSet = $rt_classWithoutFields(jur_CIBackReferenceSet); +function jur_UCIBackReferenceSet__init_(var_0, var_1) { + var var_2 = new jur_UCIBackReferenceSet(); + jur_UCIBackReferenceSet__init_0(var_2, var_0, var_1); + return var_2; +} +function jur_UCIBackReferenceSet__init_0($this, $groupIndex, $consCounter) { + var var$3, var$4; + var$3 = jur_AbstractSet_counter; + jur_AbstractSet_counter = var$3 + 1 | 0; + var$4 = new jl_AbstractStringBuilder; + var$4.$buffer = $rt_createCharArray(20); + $this.$index1 = (jl_AbstractStringBuilder_insert0(var$4, var$4.$length, var$3, 10)).$toString(); + $this.$referencedGroup = $groupIndex; + $this.$consCounter3 = $consCounter; +} +function jur_UCIBackReferenceSet_matches($this, $stringIndex, $testString, $matchResult) { + var var$4, var$5, var$6, var$7, $i, var$9, $group, var$11; + a: { + var$4 = $this.$referencedGroup; + var$5 = $matchResult.$groupBounds.data; + var$6 = var$4 * 2 | 0; + var$7 = var$5[var$6]; + $i = var$5[var$6 + 1 | 0]; + var$6 = $i | var$7; + var$4 = $i - var$7 | 0; + if ((var$6 | var$4) >= 0) { + var$9 = $matchResult.$string0.$characters.data; + if ($i <= var$9.length) { + if (var$7 > $i) { + $testString = new jl_IndexOutOfBoundsException; + $testString.$suppressionEnabled = 1; + $testString.$writableStackTrace = 1; + jl_Throwable_fillInStackTrace($testString); + $rt_throw($testString); + } + $group = new jl_String; + var$5 = $rt_createCharArray(var$4); + var$11 = var$5.data; + $group.$characters = var$5; + var$6 = 0; + while (var$6 < var$4) { + var$11[var$6] = var$9[var$6 + var$7 | 0]; + var$6 = var$6 + 1 | 0; + } + break a; + } + } + $group = null; + } + if ($group !== null && ($stringIndex + $group.$characters.data.length | 0) <= $matchResult.$rightBound) { + $i = 0; + b: { + c: { + while (true) { + var$5 = $group.$characters.data; + var$6 = var$5.length; + var$4 = $rt_compare($i, var$6); + if (var$4 >= 0) { + var$4 = $this.$consCounter3; + $matchResult.$consumers.data[var$4] = var$6; + return $this.$next0.$matches($stringIndex + var$6 | 0, $testString, $matchResult); + } + if ($i < 0) + break b; + if (var$4 >= 0) + break b; + var$6 = (String.fromCharCode((String.fromCharCode(var$5[$i])).toUpperCase().charCodeAt(0) & 65535)).toLowerCase().charCodeAt(0) & 65535; + var$7 = $stringIndex + $i | 0; + if (var$7 < 0) + break c; + var$5 = $testString.$characters.data; + if (var$7 >= var$5.length) + break c; + if (var$6 != ((String.fromCharCode((String.fromCharCode(var$5[var$7])).toUpperCase().charCodeAt(0) & 65535)).toLowerCase().charCodeAt(0) & 65535)) + break; + $i = $i + 1 | 0; + } + return (-1); + } + $testString = new jl_StringIndexOutOfBoundsException; + $testString.$suppressionEnabled = 1; + $testString.$writableStackTrace = 1; + $rt_throw($testString); + } + $testString = new jl_StringIndexOutOfBoundsException; + $testString.$suppressionEnabled = 1; + $testString.$writableStackTrace = 1; + $rt_throw($testString); + } + return (-1); +} +var jl_StringBuffer = $rt_classWithoutFields(jl_AbstractStringBuilder); +function jl_StringBuffer_insert($this, var$1, var$2, var$3, var$4) { + var var$5, var$6, var$7, var$8; + jl_AbstractStringBuilder_insertSpace($this, var$1, var$1 + var$4 | 0); + var$5 = var$4 + var$3 | 0; + while (var$3 < var$5) { + var$6 = var$2.data; + var$7 = $this.$buffer.data; + var$4 = var$1 + 1 | 0; + var$8 = var$3 + 1 | 0; + var$7[var$1] = var$6[var$3]; + var$1 = var$4; + var$3 = var$8; + } + return $this; +} +function jl_StringBuffer_append($this, var$1, var$2, var$3) { + var var$4, var$5, var$6, var$7, var$8; + var$4 = $this.$length; + jl_AbstractStringBuilder_insertSpace($this, var$4, var$4 + var$3 | 0); + var$5 = var$3 + var$2 | 0; + while (var$2 < var$5) { + var$6 = var$1.data; + var$7 = $this.$buffer.data; + var$3 = var$4 + 1 | 0; + var$8 = var$2 + 1 | 0; + var$7[var$4] = var$6[var$2]; + var$4 = var$3; + var$2 = var$8; + } + return $this; +} +function jl_StringBuffer_charAt($this, var$1) { + var var$2; + if (var$1 >= 0 && var$1 < $this.$length) + return $this.$buffer.data[var$1]; + var$2 = new jl_IndexOutOfBoundsException; + var$2.$suppressionEnabled = 1; + var$2.$writableStackTrace = 1; + $rt_throw(var$2); +} +function jl_StringBuffer_length($this) { + return $this.$length; +} +function jl_StringBuffer_ensureCapacity($this, var$1) { + jl_AbstractStringBuilder_ensureCapacity($this, var$1); +} +function jl_StringBuffer_insert0($this, var$1, var$2) { + jl_AbstractStringBuilder_insertSpace($this, var$1, var$1 + 1 | 0); + $this.$buffer.data[var$1] = var$2; + return $this; +} +function jur_SequenceSet() { + var a = this; jur_LeafSet.call(a); + a.$string1 = null; + a.$leftToRight = null; + a.$rightToLeft = null; +} +function jur_SequenceSet__init_(var_0) { + var var_1 = new jur_SequenceSet(); + jur_SequenceSet__init_0(var_1, var_0); + return var_1; +} +function jur_SequenceSet__init_0($this, $substring) { + var $j, var$3, var$4, var$5, var$6, var$7, var$8, var$9; + $j = jur_AbstractSet_counter; + jur_AbstractSet_counter = $j + 1 | 0; + var$3 = new jl_AbstractStringBuilder; + var$3.$buffer = $rt_createCharArray(20); + $this.$index1 = (jl_AbstractStringBuilder_insert0(var$3, var$3.$length, $j, 10)).$toString(); + $this.$charCount = 1; + var$3 = new jl_String; + var$4 = $substring.$buffer; + var$5 = $substring.$length; + var$6 = $rt_createCharArray(var$5); + var$7 = var$6.data; + var$3.$characters = var$6; + var$8 = 0; + while (var$8 < var$5) { + var$7[var$8] = var$4.data[var$8 + 0 | 0]; + var$8 = var$8 + 1 | 0; + } + $this.$string1 = var$3; + $this.$charCount = var$5; + $this.$leftToRight = jur_SequenceSet$IntHash__init_(var$5); + $this.$rightToLeft = jur_SequenceSet$IntHash__init_($this.$charCount); + $j = 0; + a: { + b: { + while (true) { + var$9 = $this.$charCount; + if ($j >= (var$9 - 1 | 0)) + break; + $substring = $this.$leftToRight; + var$3 = $this.$string1; + if ($j < 0) + break a; + var$7 = var$3.$characters.data; + if ($j >= var$7.length) + break a; + jur_SequenceSet$IntHash_put($substring, var$7[$j], (var$9 - $j | 0) - 1 | 0); + $substring = $this.$rightToLeft; + var$3 = $this.$string1; + var$9 = ($this.$charCount - $j | 0) - 1 | 0; + if (var$9 < 0) + break b; + var$7 = var$3.$characters.data; + if (var$9 >= var$7.length) + break b; + jur_SequenceSet$IntHash_put($substring, var$7[var$9], var$9); + $j = $j + 1 | 0; + } + return; + } + $substring = new jl_StringIndexOutOfBoundsException; + $substring.$suppressionEnabled = 1; + $substring.$writableStackTrace = 1; + $rt_throw($substring); + } + $substring = new jl_StringIndexOutOfBoundsException; + $substring.$suppressionEnabled = 1; + $substring.$writableStackTrace = 1; + $rt_throw($substring); +} +function jur_SequenceSet_accepts($this, $strIndex, $testString) { + var var$3, var$4, var$5, var$6, var$7, var$8; + var$3 = 0; + a: { + b: { + c: { + while (true) { + var$4 = $this.$charCount; + if (var$3 >= var$4) + break; + var$5 = var$3 + $strIndex | 0; + if (var$5 < 0) + break a; + var$6 = $testString.$characters.data; + if (var$5 >= var$6.length) + break a; + var$7 = var$6[var$5]; + var$8 = $this.$string1; + if (var$3 < 0) + break b; + var$6 = var$8.$characters.data; + if (var$3 >= var$6.length) + break b; + if (var$7 != var$6[var$3]) { + $strIndex = 0; + break c; + } + var$3 = var$3 + 1 | 0; + } + $strIndex = 1; + } + if (!$strIndex) + var$4 = (-1); + return var$4; + } + $testString = new jl_StringIndexOutOfBoundsException; + $testString.$suppressionEnabled = 1; + $testString.$writableStackTrace = 1; + $rt_throw($testString); + } + $testString = new jl_StringIndexOutOfBoundsException; + $testString.$suppressionEnabled = 1; + $testString.$writableStackTrace = 1; + $rt_throw($testString); +} +function jur_SequenceSet_find($this, $strIndex, $testString, $matchResult) { + var $strLength, var$5; + $strLength = $matchResult.$rightBound; + while (true) { + if ($strIndex > $strLength) + return (-1); + var$5 = jur_SequenceSet_indexOf($this, $testString, $strIndex, $strLength); + if (var$5 < 0) + return (-1); + if ($this.$next0.$matches(var$5 + $this.$charCount | 0, $testString, $matchResult) >= 0) + break; + $strIndex = var$5 + 1 | 0; + } + return var$5; +} +function jur_SequenceSet_findBack($this, $strIndex, $lastIndex, $testString, $matchResult) { + while (true) { + if ($lastIndex < $strIndex) + return (-1); + $lastIndex = jur_SequenceSet_lastIndexOf($this, $testString, $strIndex, $lastIndex); + if ($lastIndex < 0) + return (-1); + if ($this.$next0.$matches($lastIndex + $this.$charCount | 0, $testString, $matchResult) >= 0) + break; + $lastIndex = $lastIndex + (-1) | 0; + } + return $lastIndex; +} +function jur_SequenceSet_first($this, $set) { + var var$2, var$3, var$4, var$5, var$6, var$7; + if ($set instanceof jur_CharSet) { + var$2 = $set.$ch0; + var$3 = $this.$string1.$characters.data; + if (0 < var$3.length) + return var$2 != var$3[0] ? 0 : 1; + $set = new jl_StringIndexOutOfBoundsException; + $set.$suppressionEnabled = 1; + $set.$writableStackTrace = 1; + $rt_throw($set); + } + if ($set instanceof jur_RangeSet) { + $set = $set; + var$3 = $this.$string1.$characters; + var$4 = $rt_createCharArray(1).data; + var$5 = 0; + while (var$5 < 1) { + var$4[var$5] = var$3.data[var$5 + 0 | 0]; + var$5 = var$5 + 1 | 0; + } + $set = $set.$chars1; + if (0 >= var$4.length) { + $set = new jl_StringIndexOutOfBoundsException; + $set.$suppressionEnabled = 1; + $set.$writableStackTrace = 1; + $rt_throw($set); + } + return (!$set.$contains(var$4[0]) ? (-1) : 1) <= 0 ? 0 : 1; + } + if (!($set instanceof jur_SupplRangeSet)) { + if (!($set instanceof jur_SupplCharSet)) + return 1; + a: { + var$3 = $this.$string1.$characters.data; + var$6 = var$3.length; + if (var$6 > 1) { + var$5 = $set.$ch4; + if (0 >= var$6) { + $set = new jl_StringIndexOutOfBoundsException; + $set.$suppressionEnabled = 1; + $set.$writableStackTrace = 1; + $rt_throw($set); + } + var$7 = var$3[0]; + if (1 >= var$6) { + $set = new jl_StringIndexOutOfBoundsException; + jl_Throwable__init_0($set); + $rt_throw($set); + } + if (var$5 == jl_Character_toCodePoint(var$7, var$3[1])) { + var$2 = 1; + break a; + } + } + var$2 = 0; + } + return var$2; + } + $set = $set; + var$3 = $this.$string1.$characters.data; + if (0 >= var$3.length) { + $set = new jl_StringIndexOutOfBoundsException; + $set.$suppressionEnabled = 1; + $set.$writableStackTrace = 1; + $rt_throw($set); + } + b: { + c: { + if (!$set.$contains(var$3[0])) { + var$3 = $this.$string1.$characters.data; + var$7 = var$3.length; + if (var$7 <= 1) + break c; + if (0 >= var$7) { + $set = new jl_StringIndexOutOfBoundsException; + $set.$suppressionEnabled = 1; + $set.$writableStackTrace = 1; + $rt_throw($set); + } + var$5 = var$3[0]; + if (1 >= var$7) { + $set = new jl_StringIndexOutOfBoundsException; + $set.$suppressionEnabled = 1; + $set.$writableStackTrace = 1; + $rt_throw($set); + } + if (!$set.$contains(((var$5 & 1023) << 10 | var$3[1] & 1023) + 65536 | 0)) + break c; + } + var$2 = 1; + break b; + } + var$2 = 0; + } + return var$2; +} +function jur_SequenceSet_indexOf($this, $str, $i, $to) { + var var$4, $ch, var$6, $last, var$8, var$9, var$10, var$11, var$12, var$13; + var$4 = $this.$string1; + $ch = $this.$charCount - 1 | 0; + if ($ch >= 0) { + var$6 = var$4.$characters.data; + if ($ch < var$6.length) { + $last = var$6[$ch]; + a: { + b: { + c: { + while (true) { + var$8 = $this.$charCount; + if ($i > ($to - var$8 | 0)) + return (-1); + var$9 = ($i + var$8 | 0) - 1 | 0; + if (var$9 < 0) + break c; + var$6 = $str.$characters.data; + var$10 = var$6.length; + if (var$9 >= var$10) + break c; + $ch = var$6[var$9]; + if ($ch == $last) { + var$9 = 0; + d: { + while (var$9 < var$8) { + var$11 = var$9 + $i | 0; + if (var$11 < 0) + break a; + if (var$11 >= var$10) + break a; + var$12 = var$6[var$11]; + var$4 = $this.$string1; + if (var$9 < 0) + break b; + var$13 = var$4.$characters.data; + if (var$9 >= var$13.length) + break b; + if (var$12 != var$13[var$9]) { + var$10 = 0; + break d; + } + var$9 = var$9 + 1 | 0; + } + var$10 = 1; + } + if (var$10) + break; + } + $i = $i + jur_SequenceSet$IntHash_get($this.$leftToRight, $ch) | 0; + } + return $i; + } + $str = new jl_StringIndexOutOfBoundsException; + $str.$suppressionEnabled = 1; + $str.$writableStackTrace = 1; + $rt_throw($str); + } + $str = new jl_StringIndexOutOfBoundsException; + $str.$suppressionEnabled = 1; + $str.$writableStackTrace = 1; + $rt_throw($str); + } + $str = new jl_StringIndexOutOfBoundsException; + $str.$suppressionEnabled = 1; + $str.$writableStackTrace = 1; + $rt_throw($str); + } + } + $str = new jl_StringIndexOutOfBoundsException; + $str.$suppressionEnabled = 1; + $str.$writableStackTrace = 1; + $rt_throw($str); +} +function jur_SequenceSet_lastIndexOf($this, $str, $to, $i) { + var var$4, $first, $delta, $ch, var$8, $size, var$10, var$11; + var$4 = $this.$string1.$characters.data; + if (0 >= var$4.length) { + $str = new jl_StringIndexOutOfBoundsException; + $str.$suppressionEnabled = 1; + $str.$writableStackTrace = 1; + $rt_throw($str); + } + $first = var$4[0]; + $delta = ($str.$characters.data.length - $i | 0) - $this.$charCount | 0; + if ($delta <= 0) + $i = $i + $delta | 0; + a: { + b: { + c: { + while (true) { + if ($i < $to) + return (-1); + if ($i < 0) + break c; + var$4 = $str.$characters.data; + $delta = var$4.length; + if ($i >= $delta) + break c; + $ch = var$4[$i]; + if ($ch == $first) { + var$8 = 0; + d: { + while (var$8 < $this.$charCount) { + $size = var$8 + $i | 0; + if ($size < 0) + break a; + if ($size >= $delta) + break a; + $size = var$4[$size]; + var$10 = $this.$string1; + if (var$8 < 0) + break b; + var$11 = var$10.$characters.data; + if (var$8 >= var$11.length) + break b; + if ($size != var$11[var$8]) { + $size = 0; + break d; + } + var$8 = var$8 + 1 | 0; + } + $size = 1; + } + if ($size) + break; + } + $i = $i - jur_SequenceSet$IntHash_get($this.$rightToLeft, $ch) | 0; + } + return $i; + } + $str = new jl_StringIndexOutOfBoundsException; + $str.$suppressionEnabled = 1; + $str.$writableStackTrace = 1; + $rt_throw($str); + } + $str = new jl_StringIndexOutOfBoundsException; + $str.$suppressionEnabled = 1; + $str.$writableStackTrace = 1; + $rt_throw($str); + } + $str = new jl_StringIndexOutOfBoundsException; + $str.$suppressionEnabled = 1; + $str.$writableStackTrace = 1; + $rt_throw($str); +} +function jur_UCISequenceSet() { + jur_LeafSet.call(this); + this.$string = null; +} +function jur_UCISequenceSet_accepts($this, $strIndex, $testString) { + var $i, var$4, var$5, var$6, var$7; + $i = 0; + a: { + b: { + while (true) { + var$4 = $this.$string.$characters.data; + var$5 = var$4.length; + var$6 = $rt_compare($i, var$5); + if (var$6 >= 0) + break; + if ($i < 0) + break a; + if (var$6 >= 0) + break a; + var$5 = var$4[$i]; + var$7 = $strIndex + $i | 0; + if (var$7 < 0) + break b; + var$4 = $testString.$characters.data; + if (var$7 >= var$4.length) + break b; + if (var$5 != ((String.fromCharCode((String.fromCharCode(var$4[var$7])).toUpperCase().charCodeAt(0) & 65535)).toLowerCase().charCodeAt(0) & 65535)) + return (-1); + $i = $i + 1 | 0; + } + return var$5; + } + $testString = new jl_StringIndexOutOfBoundsException; + $testString.$suppressionEnabled = 1; + $testString.$writableStackTrace = 1; + $rt_throw($testString); + } + $testString = new jl_StringIndexOutOfBoundsException; + $testString.$suppressionEnabled = 1; + $testString.$writableStackTrace = 1; + $rt_throw($testString); +} +function jur_CISequenceSet() { + jur_LeafSet.call(this); + this.$string2 = null; +} +function jur_CISequenceSet__init_(var_0) { + var var_1 = new jur_CISequenceSet(); + jur_CISequenceSet__init_0(var_1, var_0); + return var_1; +} +function jur_CISequenceSet__init_0($this, $substring) { + var var$2, var$3, var$4, var$5, var$6, var$7, var$8; + var$2 = jur_AbstractSet_counter; + jur_AbstractSet_counter = var$2 + 1 | 0; + var$3 = new jl_AbstractStringBuilder; + var$3.$buffer = $rt_createCharArray(20); + $this.$index1 = (jl_AbstractStringBuilder_insert0(var$3, var$3.$length, var$2, 10)).$toString(); + $this.$charCount = 1; + var$3 = new jl_String; + var$4 = $substring.$buffer; + var$5 = $substring.$length; + var$6 = $rt_createCharArray(var$5); + var$7 = var$6.data; + var$3.$characters = var$6; + var$8 = 0; + while (var$8 < var$5) { + var$7[var$8] = var$4.data[var$8 + 0 | 0]; + var$8 = var$8 + 1 | 0; + } + $this.$string2 = var$3; + $this.$charCount = var$5; +} +function jur_CISequenceSet_accepts($this, $strIndex, $testString) { + var $i, var$4, var$5, var$6, var$7, var$8, var$9; + $i = 0; + a: { + b: { + c: { + d: { + while (true) { + var$4 = $this.$string2.$characters.data; + var$5 = var$4.length; + var$6 = $rt_compare($i, var$5); + if (var$6 >= 0) + break; + if ($i < 0) + break c; + if (var$6 >= 0) + break c; + var$7 = var$4[$i]; + var$8 = $strIndex + $i | 0; + if (var$8 < 0) + break d; + var$9 = $testString.$characters.data; + if (var$8 >= var$9.length) + break d; + if (var$7 != var$9[var$8]) { + if ($i < 0) + break a; + if (var$6 >= 0) + break a; + var$5 = jur_Pattern_getSupplement(var$4[$i]); + if (var$8 < 0) + break b; + var$4 = $testString.$characters.data; + if (var$8 >= var$4.length) + break b; + if (var$5 != var$4[var$8]) + return (-1); + } + $i = $i + 1 | 0; + } + return var$5; + } + $testString = new jl_StringIndexOutOfBoundsException; + $testString.$suppressionEnabled = 1; + $testString.$writableStackTrace = 1; + $rt_throw($testString); + } + $testString = new jl_StringIndexOutOfBoundsException; + $testString.$suppressionEnabled = 1; + $testString.$writableStackTrace = 1; + $rt_throw($testString); + } + $testString = new jl_StringIndexOutOfBoundsException; + $testString.$suppressionEnabled = 1; + $testString.$writableStackTrace = 1; + $rt_throw($testString); + } + $testString = new jl_StringIndexOutOfBoundsException; + $testString.$suppressionEnabled = 1; + $testString.$writableStackTrace = 1; + $rt_throw($testString); +} +var jur_AbstractCharClass$PredefinedCharacterClasses = $rt_classWithoutFields(); +var jur_AbstractCharClass$PredefinedCharacterClasses_space = null; +var jur_AbstractCharClass$PredefinedCharacterClasses_digit = null; +var jur_AbstractCharClass$PredefinedCharacterClasses_contents = null; +function jur_AbstractCharClass$PredefinedCharacterClasses_getObject($this, $name) { + var $i, $row, var$4; + $i = 0; + while (true) { + $row = jur_AbstractCharClass$PredefinedCharacterClasses_contents.data; + if ($i >= $row.length) { + var$4 = new ju_MissingResourceException; + var$4.$suppressionEnabled = 1; + var$4.$writableStackTrace = 1; + var$4.$message = $rt_s(47); + var$4.$className = $rt_s(47); + var$4.$key = $name; + $rt_throw(var$4); + } + $row = $row[$i].data; + if (jl_String_equals($name, $row[0])) + break; + $i = $i + 1 | 0; + } + return $row[1]; +} +function jur_AbstractCharClass$PredefinedCharacterClasses__clinit_() { + jur_AbstractCharClass$PredefinedCharacterClasses_space = jur_AbstractCharClass$LazySpace__init_(); + jur_AbstractCharClass$PredefinedCharacterClasses_digit = jur_AbstractCharClass$LazyDigit__init_(); + jur_AbstractCharClass$PredefinedCharacterClasses_contents = $rt_createArrayFromData($rt_arraycls(jl_Object), [$rt_createArrayFromData(jl_Object, [$rt_s(74), jur_AbstractCharClass$LazyLower__init_()]), $rt_createArrayFromData(jl_Object, [$rt_s(75), jur_AbstractCharClass$LazyUpper__init_()]), $rt_createArrayFromData(jl_Object, [$rt_s(76), jur_AbstractCharClass$LazyASCII__init_()]), $rt_createArrayFromData(jl_Object, [$rt_s(77), jur_AbstractCharClass$LazyAlpha__init_()]), $rt_createArrayFromData(jl_Object, + [$rt_s(78), jur_AbstractCharClass$PredefinedCharacterClasses_digit]), $rt_createArrayFromData(jl_Object, [$rt_s(79), jur_AbstractCharClass$LazyAlnum__init_()]), $rt_createArrayFromData(jl_Object, [$rt_s(80), jur_AbstractCharClass$LazyPunct__init_()]), $rt_createArrayFromData(jl_Object, [$rt_s(81), jur_AbstractCharClass$LazyGraph__init_()]), $rt_createArrayFromData(jl_Object, [$rt_s(82), jur_AbstractCharClass$LazyPrint__init_()]), $rt_createArrayFromData(jl_Object, [$rt_s(83), jur_AbstractCharClass$LazyBlank__init_()]), + $rt_createArrayFromData(jl_Object, [$rt_s(84), jur_AbstractCharClass$LazyCntrl__init_()]), $rt_createArrayFromData(jl_Object, [$rt_s(85), jur_AbstractCharClass$LazyXDigit__init_()]), $rt_createArrayFromData(jl_Object, [$rt_s(86), jur_AbstractCharClass$LazyJavaLowerCase__init_()]), $rt_createArrayFromData(jl_Object, [$rt_s(87), jur_AbstractCharClass$LazyJavaUpperCase__init_()]), $rt_createArrayFromData(jl_Object, [$rt_s(88), jur_AbstractCharClass$LazyJavaWhitespace__init_()]), $rt_createArrayFromData(jl_Object, + [$rt_s(89), jur_AbstractCharClass$LazyJavaMirrored__init_()]), $rt_createArrayFromData(jl_Object, [$rt_s(90), jur_AbstractCharClass$LazyJavaDefined__init_()]), $rt_createArrayFromData(jl_Object, [$rt_s(91), jur_AbstractCharClass$LazyJavaDigit__init_()]), $rt_createArrayFromData(jl_Object, [$rt_s(92), jur_AbstractCharClass$LazyJavaIdentifierIgnorable__init_()]), $rt_createArrayFromData(jl_Object, [$rt_s(93), jur_AbstractCharClass$LazyJavaISOControl__init_()]), $rt_createArrayFromData(jl_Object, [$rt_s(94), + jur_AbstractCharClass$LazyJavaJavaIdentifierPart__init_()]), $rt_createArrayFromData(jl_Object, [$rt_s(95), jur_AbstractCharClass$LazyJavaJavaIdentifierStart__init_()]), $rt_createArrayFromData(jl_Object, [$rt_s(96), jur_AbstractCharClass$LazyJavaLetter__init_()]), $rt_createArrayFromData(jl_Object, [$rt_s(97), jur_AbstractCharClass$LazyJavaLetterOrDigit__init_()]), $rt_createArrayFromData(jl_Object, [$rt_s(98), jur_AbstractCharClass$LazyJavaSpaceChar__init_()]), $rt_createArrayFromData(jl_Object, [$rt_s(99), + jur_AbstractCharClass$LazyJavaTitleCase__init_()]), $rt_createArrayFromData(jl_Object, [$rt_s(100), jur_AbstractCharClass$LazyJavaUnicodeIdentifierPart__init_()]), $rt_createArrayFromData(jl_Object, [$rt_s(101), jur_AbstractCharClass$LazyJavaUnicodeIdentifierStart__init_()]), $rt_createArrayFromData(jl_Object, [$rt_s(102), jur_AbstractCharClass$PredefinedCharacterClasses_space]), $rt_createArrayFromData(jl_Object, [$rt_s(103), jur_AbstractCharClass$LazyWord__init_()]), $rt_createArrayFromData(jl_Object, + [$rt_s(104), jur_AbstractCharClass$LazyNonWord__init_()]), $rt_createArrayFromData(jl_Object, [$rt_s(105), jur_AbstractCharClass$PredefinedCharacterClasses_space]), $rt_createArrayFromData(jl_Object, [$rt_s(106), jur_AbstractCharClass$LazyNonSpace__init_()]), $rt_createArrayFromData(jl_Object, [$rt_s(107), jur_AbstractCharClass$PredefinedCharacterClasses_digit]), $rt_createArrayFromData(jl_Object, [$rt_s(108), jur_AbstractCharClass$LazyNonDigit__init_()]), $rt_createArrayFromData(jl_Object, [$rt_s(109), + jur_AbstractCharClass$LazyRange__init_(0, 127)]), $rt_createArrayFromData(jl_Object, [$rt_s(110), jur_AbstractCharClass$LazyRange__init_(128, 255)]), $rt_createArrayFromData(jl_Object, [$rt_s(111), jur_AbstractCharClass$LazyRange__init_(256, 383)]), $rt_createArrayFromData(jl_Object, [$rt_s(112), jur_AbstractCharClass$LazyRange__init_(384, 591)]), $rt_createArrayFromData(jl_Object, [$rt_s(113), jur_AbstractCharClass$LazyRange__init_(592, 687)]), $rt_createArrayFromData(jl_Object, [$rt_s(114), jur_AbstractCharClass$LazyRange__init_(688, + 767)]), $rt_createArrayFromData(jl_Object, [$rt_s(115), jur_AbstractCharClass$LazyRange__init_(768, 879)]), $rt_createArrayFromData(jl_Object, [$rt_s(116), jur_AbstractCharClass$LazyRange__init_(880, 1023)]), $rt_createArrayFromData(jl_Object, [$rt_s(117), jur_AbstractCharClass$LazyRange__init_(1024, 1279)]), $rt_createArrayFromData(jl_Object, [$rt_s(118), jur_AbstractCharClass$LazyRange__init_(1280, 1327)]), $rt_createArrayFromData(jl_Object, [$rt_s(119), jur_AbstractCharClass$LazyRange__init_(1328, 1423)]), + $rt_createArrayFromData(jl_Object, [$rt_s(120), jur_AbstractCharClass$LazyRange__init_(1424, 1535)]), $rt_createArrayFromData(jl_Object, [$rt_s(121), jur_AbstractCharClass$LazyRange__init_(1536, 1791)]), $rt_createArrayFromData(jl_Object, [$rt_s(122), jur_AbstractCharClass$LazyRange__init_(1792, 1871)]), $rt_createArrayFromData(jl_Object, [$rt_s(123), jur_AbstractCharClass$LazyRange__init_(1872, 1919)]), $rt_createArrayFromData(jl_Object, [$rt_s(124), jur_AbstractCharClass$LazyRange__init_(1920, 1983)]), + $rt_createArrayFromData(jl_Object, [$rt_s(125), jur_AbstractCharClass$LazyRange__init_(2304, 2431)]), $rt_createArrayFromData(jl_Object, [$rt_s(126), jur_AbstractCharClass$LazyRange__init_(2432, 2559)]), $rt_createArrayFromData(jl_Object, [$rt_s(127), jur_AbstractCharClass$LazyRange__init_(2560, 2687)]), $rt_createArrayFromData(jl_Object, [$rt_s(128), jur_AbstractCharClass$LazyRange__init_(2688, 2815)]), $rt_createArrayFromData(jl_Object, [$rt_s(129), jur_AbstractCharClass$LazyRange__init_(2816, 2943)]), + $rt_createArrayFromData(jl_Object, [$rt_s(130), jur_AbstractCharClass$LazyRange__init_(2944, 3071)]), $rt_createArrayFromData(jl_Object, [$rt_s(131), jur_AbstractCharClass$LazyRange__init_(3072, 3199)]), $rt_createArrayFromData(jl_Object, [$rt_s(132), jur_AbstractCharClass$LazyRange__init_(3200, 3327)]), $rt_createArrayFromData(jl_Object, [$rt_s(133), jur_AbstractCharClass$LazyRange__init_(3328, 3455)]), $rt_createArrayFromData(jl_Object, [$rt_s(134), jur_AbstractCharClass$LazyRange__init_(3456, 3583)]), + $rt_createArrayFromData(jl_Object, [$rt_s(135), jur_AbstractCharClass$LazyRange__init_(3584, 3711)]), $rt_createArrayFromData(jl_Object, [$rt_s(136), jur_AbstractCharClass$LazyRange__init_(3712, 3839)]), $rt_createArrayFromData(jl_Object, [$rt_s(137), jur_AbstractCharClass$LazyRange__init_(3840, 4095)]), $rt_createArrayFromData(jl_Object, [$rt_s(138), jur_AbstractCharClass$LazyRange__init_(4096, 4255)]), $rt_createArrayFromData(jl_Object, [$rt_s(139), jur_AbstractCharClass$LazyRange__init_(4256, 4351)]), + $rt_createArrayFromData(jl_Object, [$rt_s(140), jur_AbstractCharClass$LazyRange__init_(4352, 4607)]), $rt_createArrayFromData(jl_Object, [$rt_s(141), jur_AbstractCharClass$LazyRange__init_(4608, 4991)]), $rt_createArrayFromData(jl_Object, [$rt_s(142), jur_AbstractCharClass$LazyRange__init_(4992, 5023)]), $rt_createArrayFromData(jl_Object, [$rt_s(143), jur_AbstractCharClass$LazyRange__init_(5024, 5119)]), $rt_createArrayFromData(jl_Object, [$rt_s(144), jur_AbstractCharClass$LazyRange__init_(5120, 5759)]), + $rt_createArrayFromData(jl_Object, [$rt_s(145), jur_AbstractCharClass$LazyRange__init_(5760, 5791)]), $rt_createArrayFromData(jl_Object, [$rt_s(146), jur_AbstractCharClass$LazyRange__init_(5792, 5887)]), $rt_createArrayFromData(jl_Object, [$rt_s(147), jur_AbstractCharClass$LazyRange__init_(5888, 5919)]), $rt_createArrayFromData(jl_Object, [$rt_s(148), jur_AbstractCharClass$LazyRange__init_(5920, 5951)]), $rt_createArrayFromData(jl_Object, [$rt_s(149), jur_AbstractCharClass$LazyRange__init_(5952, 5983)]), + $rt_createArrayFromData(jl_Object, [$rt_s(150), jur_AbstractCharClass$LazyRange__init_(5984, 6015)]), $rt_createArrayFromData(jl_Object, [$rt_s(151), jur_AbstractCharClass$LazyRange__init_(6016, 6143)]), $rt_createArrayFromData(jl_Object, [$rt_s(152), jur_AbstractCharClass$LazyRange__init_(6144, 6319)]), $rt_createArrayFromData(jl_Object, [$rt_s(153), jur_AbstractCharClass$LazyRange__init_(6400, 6479)]), $rt_createArrayFromData(jl_Object, [$rt_s(154), jur_AbstractCharClass$LazyRange__init_(6480, 6527)]), + $rt_createArrayFromData(jl_Object, [$rt_s(155), jur_AbstractCharClass$LazyRange__init_(6528, 6623)]), $rt_createArrayFromData(jl_Object, [$rt_s(156), jur_AbstractCharClass$LazyRange__init_(6624, 6655)]), $rt_createArrayFromData(jl_Object, [$rt_s(157), jur_AbstractCharClass$LazyRange__init_(6656, 6687)]), $rt_createArrayFromData(jl_Object, [$rt_s(158), jur_AbstractCharClass$LazyRange__init_(7424, 7551)]), $rt_createArrayFromData(jl_Object, [$rt_s(159), jur_AbstractCharClass$LazyRange__init_(7552, 7615)]), + $rt_createArrayFromData(jl_Object, [$rt_s(160), jur_AbstractCharClass$LazyRange__init_(7616, 7679)]), $rt_createArrayFromData(jl_Object, [$rt_s(161), jur_AbstractCharClass$LazyRange__init_(7680, 7935)]), $rt_createArrayFromData(jl_Object, [$rt_s(162), jur_AbstractCharClass$LazyRange__init_(7936, 8191)]), $rt_createArrayFromData(jl_Object, [$rt_s(163), jur_AbstractCharClass$LazyRange__init_(8192, 8303)]), $rt_createArrayFromData(jl_Object, [$rt_s(164), jur_AbstractCharClass$LazyRange__init_(8304, 8351)]), + $rt_createArrayFromData(jl_Object, [$rt_s(165), jur_AbstractCharClass$LazyRange__init_(8352, 8399)]), $rt_createArrayFromData(jl_Object, [$rt_s(166), jur_AbstractCharClass$LazyRange__init_(8400, 8447)]), $rt_createArrayFromData(jl_Object, [$rt_s(167), jur_AbstractCharClass$LazyRange__init_(8448, 8527)]), $rt_createArrayFromData(jl_Object, [$rt_s(168), jur_AbstractCharClass$LazyRange__init_(8528, 8591)]), $rt_createArrayFromData(jl_Object, [$rt_s(169), jur_AbstractCharClass$LazyRange__init_(8592, 8703)]), + $rt_createArrayFromData(jl_Object, [$rt_s(170), jur_AbstractCharClass$LazyRange__init_(8704, 8959)]), $rt_createArrayFromData(jl_Object, [$rt_s(171), jur_AbstractCharClass$LazyRange__init_(8960, 9215)]), $rt_createArrayFromData(jl_Object, [$rt_s(172), jur_AbstractCharClass$LazyRange__init_(9216, 9279)]), $rt_createArrayFromData(jl_Object, [$rt_s(173), jur_AbstractCharClass$LazyRange__init_(9280, 9311)]), $rt_createArrayFromData(jl_Object, [$rt_s(174), jur_AbstractCharClass$LazyRange__init_(9312, 9471)]), + $rt_createArrayFromData(jl_Object, [$rt_s(175), jur_AbstractCharClass$LazyRange__init_(9472, 9599)]), $rt_createArrayFromData(jl_Object, [$rt_s(176), jur_AbstractCharClass$LazyRange__init_(9600, 9631)]), $rt_createArrayFromData(jl_Object, [$rt_s(177), jur_AbstractCharClass$LazyRange__init_(9632, 9727)]), $rt_createArrayFromData(jl_Object, [$rt_s(178), jur_AbstractCharClass$LazyRange__init_(9728, 9983)]), $rt_createArrayFromData(jl_Object, [$rt_s(179), jur_AbstractCharClass$LazyRange__init_(9984, 10175)]), + $rt_createArrayFromData(jl_Object, [$rt_s(180), jur_AbstractCharClass$LazyRange__init_(10176, 10223)]), $rt_createArrayFromData(jl_Object, [$rt_s(181), jur_AbstractCharClass$LazyRange__init_(10224, 10239)]), $rt_createArrayFromData(jl_Object, [$rt_s(182), jur_AbstractCharClass$LazyRange__init_(10240, 10495)]), $rt_createArrayFromData(jl_Object, [$rt_s(183), jur_AbstractCharClass$LazyRange__init_(10496, 10623)]), $rt_createArrayFromData(jl_Object, [$rt_s(184), jur_AbstractCharClass$LazyRange__init_(10624, + 10751)]), $rt_createArrayFromData(jl_Object, [$rt_s(185), jur_AbstractCharClass$LazyRange__init_(10752, 11007)]), $rt_createArrayFromData(jl_Object, [$rt_s(186), jur_AbstractCharClass$LazyRange__init_(11008, 11263)]), $rt_createArrayFromData(jl_Object, [$rt_s(187), jur_AbstractCharClass$LazyRange__init_(11264, 11359)]), $rt_createArrayFromData(jl_Object, [$rt_s(188), jur_AbstractCharClass$LazyRange__init_(11392, 11519)]), $rt_createArrayFromData(jl_Object, [$rt_s(189), jur_AbstractCharClass$LazyRange__init_(11520, + 11567)]), $rt_createArrayFromData(jl_Object, [$rt_s(190), jur_AbstractCharClass$LazyRange__init_(11568, 11647)]), $rt_createArrayFromData(jl_Object, [$rt_s(191), jur_AbstractCharClass$LazyRange__init_(11648, 11743)]), $rt_createArrayFromData(jl_Object, [$rt_s(192), jur_AbstractCharClass$LazyRange__init_(11776, 11903)]), $rt_createArrayFromData(jl_Object, [$rt_s(193), jur_AbstractCharClass$LazyRange__init_(11904, 12031)]), $rt_createArrayFromData(jl_Object, [$rt_s(194), jur_AbstractCharClass$LazyRange__init_(12032, + 12255)]), $rt_createArrayFromData(jl_Object, [$rt_s(195), jur_AbstractCharClass$LazyRange__init_(12272, 12287)]), $rt_createArrayFromData(jl_Object, [$rt_s(196), jur_AbstractCharClass$LazyRange__init_(12288, 12351)]), $rt_createArrayFromData(jl_Object, [$rt_s(197), jur_AbstractCharClass$LazyRange__init_(12352, 12447)]), $rt_createArrayFromData(jl_Object, [$rt_s(198), jur_AbstractCharClass$LazyRange__init_(12448, 12543)]), $rt_createArrayFromData(jl_Object, [$rt_s(199), jur_AbstractCharClass$LazyRange__init_(12544, + 12591)]), $rt_createArrayFromData(jl_Object, [$rt_s(200), jur_AbstractCharClass$LazyRange__init_(12592, 12687)]), $rt_createArrayFromData(jl_Object, [$rt_s(201), jur_AbstractCharClass$LazyRange__init_(12688, 12703)]), $rt_createArrayFromData(jl_Object, [$rt_s(202), jur_AbstractCharClass$LazyRange__init_(12704, 12735)]), $rt_createArrayFromData(jl_Object, [$rt_s(203), jur_AbstractCharClass$LazyRange__init_(12736, 12783)]), $rt_createArrayFromData(jl_Object, [$rt_s(204), jur_AbstractCharClass$LazyRange__init_(12784, + 12799)]), $rt_createArrayFromData(jl_Object, [$rt_s(205), jur_AbstractCharClass$LazyRange__init_(12800, 13055)]), $rt_createArrayFromData(jl_Object, [$rt_s(206), jur_AbstractCharClass$LazyRange__init_(13056, 13311)]), $rt_createArrayFromData(jl_Object, [$rt_s(207), jur_AbstractCharClass$LazyRange__init_(13312, 19893)]), $rt_createArrayFromData(jl_Object, [$rt_s(208), jur_AbstractCharClass$LazyRange__init_(19904, 19967)]), $rt_createArrayFromData(jl_Object, [$rt_s(209), jur_AbstractCharClass$LazyRange__init_(19968, + 40959)]), $rt_createArrayFromData(jl_Object, [$rt_s(210), jur_AbstractCharClass$LazyRange__init_(40960, 42127)]), $rt_createArrayFromData(jl_Object, [$rt_s(211), jur_AbstractCharClass$LazyRange__init_(42128, 42191)]), $rt_createArrayFromData(jl_Object, [$rt_s(212), jur_AbstractCharClass$LazyRange__init_(42752, 42783)]), $rt_createArrayFromData(jl_Object, [$rt_s(213), jur_AbstractCharClass$LazyRange__init_(43008, 43055)]), $rt_createArrayFromData(jl_Object, [$rt_s(214), jur_AbstractCharClass$LazyRange__init_(44032, + 55203)]), $rt_createArrayFromData(jl_Object, [$rt_s(215), jur_AbstractCharClass$LazyRange__init_(55296, 56191)]), $rt_createArrayFromData(jl_Object, [$rt_s(216), jur_AbstractCharClass$LazyRange__init_(56192, 56319)]), $rt_createArrayFromData(jl_Object, [$rt_s(217), jur_AbstractCharClass$LazyRange__init_(56320, 57343)]), $rt_createArrayFromData(jl_Object, [$rt_s(218), jur_AbstractCharClass$LazyRange__init_(57344, 63743)]), $rt_createArrayFromData(jl_Object, [$rt_s(219), jur_AbstractCharClass$LazyRange__init_(63744, + 64255)]), $rt_createArrayFromData(jl_Object, [$rt_s(220), jur_AbstractCharClass$LazyRange__init_(64256, 64335)]), $rt_createArrayFromData(jl_Object, [$rt_s(221), jur_AbstractCharClass$LazyRange__init_(64336, 65023)]), $rt_createArrayFromData(jl_Object, [$rt_s(222), jur_AbstractCharClass$LazyRange__init_(65024, 65039)]), $rt_createArrayFromData(jl_Object, [$rt_s(223), jur_AbstractCharClass$LazyRange__init_(65040, 65055)]), $rt_createArrayFromData(jl_Object, [$rt_s(224), jur_AbstractCharClass$LazyRange__init_(65056, + 65071)]), $rt_createArrayFromData(jl_Object, [$rt_s(225), jur_AbstractCharClass$LazyRange__init_(65072, 65103)]), $rt_createArrayFromData(jl_Object, [$rt_s(226), jur_AbstractCharClass$LazyRange__init_(65104, 65135)]), $rt_createArrayFromData(jl_Object, [$rt_s(227), jur_AbstractCharClass$LazyRange__init_(65136, 65279)]), $rt_createArrayFromData(jl_Object, [$rt_s(228), jur_AbstractCharClass$LazyRange__init_(65280, 65519)]), $rt_createArrayFromData(jl_Object, [$rt_s(229), jur_AbstractCharClass$LazyRange__init_(0, + 1114111)]), $rt_createArrayFromData(jl_Object, [$rt_s(230), jur_AbstractCharClass$LazySpecialsBlock__init_()]), $rt_createArrayFromData(jl_Object, [$rt_s(231), jur_AbstractCharClass$LazyCategory__init_(0, 1)]), $rt_createArrayFromData(jl_Object, [$rt_s(232), jur_AbstractCharClass$LazyCategoryScope__init_(62, 1)]), $rt_createArrayFromData(jl_Object, [$rt_s(233), jur_AbstractCharClass$LazyCategory__init_(1, 1)]), $rt_createArrayFromData(jl_Object, [$rt_s(234), jur_AbstractCharClass$LazyCategory__init_(2, 1)]), + $rt_createArrayFromData(jl_Object, [$rt_s(235), jur_AbstractCharClass$LazyCategory__init_(3, 0)]), $rt_createArrayFromData(jl_Object, [$rt_s(236), jur_AbstractCharClass$LazyCategory__init_(4, 0)]), $rt_createArrayFromData(jl_Object, [$rt_s(237), jur_AbstractCharClass$LazyCategory__init_(5, 1)]), $rt_createArrayFromData(jl_Object, [$rt_s(238), jur_AbstractCharClass$LazyCategoryScope__init_(448, 1)]), $rt_createArrayFromData(jl_Object, [$rt_s(239), jur_AbstractCharClass$LazyCategory__init_(6, 1)]), $rt_createArrayFromData(jl_Object, + [$rt_s(240), jur_AbstractCharClass$LazyCategory__init_(7, 0)]), $rt_createArrayFromData(jl_Object, [$rt_s(241), jur_AbstractCharClass$LazyCategory__init_(8, 1)]), $rt_createArrayFromData(jl_Object, [$rt_s(242), jur_AbstractCharClass$LazyCategoryScope__init_(3584, 1)]), $rt_createArrayFromData(jl_Object, [$rt_s(243), jur_AbstractCharClass$LazyCategory__init_(9, 1)]), $rt_createArrayFromData(jl_Object, [$rt_s(244), jur_AbstractCharClass$LazyCategory__init_(10, 1)]), $rt_createArrayFromData(jl_Object, [$rt_s(245), + jur_AbstractCharClass$LazyCategory__init_(11, 1)]), $rt_createArrayFromData(jl_Object, [$rt_s(246), jur_AbstractCharClass$LazyCategoryScope__init_(28672, 0)]), $rt_createArrayFromData(jl_Object, [$rt_s(247), jur_AbstractCharClass$LazyCategory__init_(12, 0)]), $rt_createArrayFromData(jl_Object, [$rt_s(248), jur_AbstractCharClass$LazyCategory__init_(13, 0)]), $rt_createArrayFromData(jl_Object, [$rt_s(249), jur_AbstractCharClass$LazyCategory__init_(14, 0)]), $rt_createArrayFromData(jl_Object, [$rt_s(250), jur_AbstractCharClass$LazyCategoryScope__init_0(983040, + 1, 1)]), $rt_createArrayFromData(jl_Object, [$rt_s(251), jur_AbstractCharClass$LazyCategory__init_(15, 0)]), $rt_createArrayFromData(jl_Object, [$rt_s(252), jur_AbstractCharClass$LazyCategory__init_(16, 1)]), $rt_createArrayFromData(jl_Object, [$rt_s(253), jur_AbstractCharClass$LazyCategory__init_(18, 1)]), $rt_createArrayFromData(jl_Object, [$rt_s(254), jur_AbstractCharClass$LazyCategory__init_0(19, 0, 1)]), $rt_createArrayFromData(jl_Object, [$rt_s(255), jur_AbstractCharClass$LazyCategoryScope__init_(1643118592, + 1)]), $rt_createArrayFromData(jl_Object, [$rt_s(256), jur_AbstractCharClass$LazyCategory__init_(20, 0)]), $rt_createArrayFromData(jl_Object, [$rt_s(257), jur_AbstractCharClass$LazyCategory__init_(21, 0)]), $rt_createArrayFromData(jl_Object, [$rt_s(258), jur_AbstractCharClass$LazyCategory__init_(22, 0)]), $rt_createArrayFromData(jl_Object, [$rt_s(259), jur_AbstractCharClass$LazyCategory__init_(23, 0)]), $rt_createArrayFromData(jl_Object, [$rt_s(260), jur_AbstractCharClass$LazyCategory__init_(24, 1)]), $rt_createArrayFromData(jl_Object, + [$rt_s(261), jur_AbstractCharClass$LazyCategoryScope__init_(2113929216, 1)]), $rt_createArrayFromData(jl_Object, [$rt_s(262), jur_AbstractCharClass$LazyCategory__init_(25, 1)]), $rt_createArrayFromData(jl_Object, [$rt_s(263), jur_AbstractCharClass$LazyCategory__init_(26, 0)]), $rt_createArrayFromData(jl_Object, [$rt_s(264), jur_AbstractCharClass$LazyCategory__init_(27, 0)]), $rt_createArrayFromData(jl_Object, [$rt_s(265), jur_AbstractCharClass$LazyCategory__init_(28, 1)]), $rt_createArrayFromData(jl_Object, + [$rt_s(266), jur_AbstractCharClass$LazyCategory__init_(29, 0)]), $rt_createArrayFromData(jl_Object, [$rt_s(267), jur_AbstractCharClass$LazyCategory__init_(30, 0)])]); +} +function jur_UCISupplCharSet() { + jur_LeafSet.call(this); + this.$ch2 = 0; +} +function jur_UCISupplCharSet_accepts($this, $strIndex, $testString) { + var $low, var$4, var$5, $high; + $low = $strIndex + 1 | 0; + if ($strIndex >= 0) { + var$4 = $testString.$characters.data; + var$5 = var$4.length; + if ($strIndex < var$5) { + $high = var$4[$strIndex]; + if ($low >= 0 && $low < var$5) { + $low = var$4[$low]; + return $this.$ch2 != (String.fromCharCode((String.fromCharCode((($high & 1023) << 10 | $low & 1023) + 65536 | 0)).toUpperCase().charCodeAt(0))).toLowerCase().charCodeAt(0) ? (-1) : 2; + } + $testString = new jl_StringIndexOutOfBoundsException; + $testString.$suppressionEnabled = 1; + $testString.$writableStackTrace = 1; + $rt_throw($testString); + } + } + $testString = new jl_StringIndexOutOfBoundsException; + $testString.$suppressionEnabled = 1; + $testString.$writableStackTrace = 1; + $rt_throw($testString); +} +function jur_LowSurrogateCharSet() { + jur_JointSet.call(this); + this.$low = 0; +} +function jur_LowSurrogateCharSet__init_(var_0) { + var var_1 = new jur_LowSurrogateCharSet(); + jur_LowSurrogateCharSet__init_0(var_1, var_0); + return var_1; +} +function jur_LowSurrogateCharSet__init_0($this, $low) { + var var$2, var$3; + var$2 = jur_AbstractSet_counter; + jur_AbstractSet_counter = var$2 + 1 | 0; + var$3 = new jl_AbstractStringBuilder; + var$3.$buffer = $rt_createCharArray(20); + $this.$index1 = (jl_AbstractStringBuilder_insert0(var$3, var$3.$length, var$2, 10)).$toString(); + $this.$low = $low; +} +function jur_LowSurrogateCharSet_setNext($this, $next) { + $this.$next0 = $next; +} +function jur_LowSurrogateCharSet_matches($this, $stringIndex, $testString, $matchResult) { + var var$4, var$5, var$6, $low, $high; + var$4 = $stringIndex + 1 | 0; + if (var$4 > $matchResult.$rightBound) { + $matchResult.$hitEnd = 1; + return (-1); + } + if ($stringIndex >= 0) { + var$5 = $testString.$characters.data; + var$6 = var$5.length; + if ($stringIndex < var$6) { + a: { + $low = var$5[$stringIndex]; + if ($stringIndex > $matchResult.$leftBound) { + $high = $stringIndex - 1 | 0; + if ($high >= 0 && $high < var$6) { + if (!((var$5[$high] & 64512) != 55296 ? 0 : 1)) + break a; + return (-1); + } + $testString = new jl_StringIndexOutOfBoundsException; + $testString.$suppressionEnabled = 1; + $testString.$writableStackTrace = 1; + $rt_throw($testString); + } + } + if ($this.$low != $low) + return (-1); + return $this.$next0.$matches(var$4, $testString, $matchResult); + } + } + $testString = new jl_StringIndexOutOfBoundsException; + $testString.$suppressionEnabled = 1; + $testString.$writableStackTrace = 1; + $rt_throw($testString); +} +function jur_LowSurrogateCharSet_find($this, $strIndex, $testStr, $matchResult) { + var var$4, $startStr, $strLength, var$7, var$8, var$9; + if (!($testStr instanceof jl_String)) { + var$4 = $matchResult.$rightBound; + a: { + while (true) { + if ($strIndex > var$4) { + $strIndex = (-1); + break a; + } + if (jur_LowSurrogateCharSet_matches($this, $strIndex, $testStr, $matchResult) >= 0) + break; + $strIndex = $strIndex + 1 | 0; + } + } + return $strIndex; + } + $startStr = $matchResult.$leftBound; + $strLength = $matchResult.$rightBound; + b: { + while (true) { + if ($strIndex >= $strLength) + return (-1); + var$7 = jl_String_indexOf($testStr, $this.$low, $strIndex); + if (var$7 < 0) + return (-1); + if (var$7 > $startStr) { + $strIndex = var$7 - 1 | 0; + if ($strIndex < 0) + break b; + var$8 = $testStr.$characters.data; + if ($strIndex >= var$8.length) + break b; + if ((var$8[$strIndex] & 64512) != 55296 ? 0 : 1) { + $strIndex = var$7 + 1 | 0; + continue; + } + } + var$9 = $this.$next0; + $strIndex = var$7 + 1 | 0; + if (var$9.$matches($strIndex, $testStr, $matchResult) >= 0) + break; + } + return var$7; + } + $testStr = new jl_StringIndexOutOfBoundsException; + $testStr.$suppressionEnabled = 1; + $testStr.$writableStackTrace = 1; + $rt_throw($testStr); +} +function jur_LowSurrogateCharSet_findBack($this, $strIndex, $lastIndex, $testStr, $matchResult) { + var $startStr, var$6, var$7; + if (!($testStr instanceof jl_String)) { + a: { + while (true) { + if ($lastIndex < $strIndex) { + $lastIndex = (-1); + break a; + } + if (jur_LowSurrogateCharSet_matches($this, $lastIndex, $testStr, $matchResult) >= 0) + break; + $lastIndex = $lastIndex + (-1) | 0; + } + } + return $lastIndex; + } + $startStr = $matchResult.$leftBound; + b: { + c: { + while (true) { + if ($lastIndex < $strIndex) + return (-1); + var$6 = jl_String_lastIndexOf($testStr, $this.$low, $lastIndex); + if (var$6 < 0) + break c; + if (var$6 < $strIndex) + break c; + if (var$6 > $startStr) { + $lastIndex = var$6 - 1 | 0; + if ($lastIndex < 0) + break b; + var$7 = $testStr.$characters.data; + if ($lastIndex >= var$7.length) + break b; + if ((var$7[$lastIndex] & 64512) != 55296 ? 0 : 1) { + $lastIndex = var$6 + (-2) | 0; + continue; + } + } + if ($this.$next0.$matches(var$6 + 1 | 0, $testStr, $matchResult) >= 0) + break; + $lastIndex = var$6 + (-1) | 0; + } + return var$6; + } + return (-1); + } + $testStr = new jl_StringIndexOutOfBoundsException; + $testStr.$suppressionEnabled = 1; + $testStr.$writableStackTrace = 1; + $rt_throw($testStr); +} +function jur_LowSurrogateCharSet_first($this, $set) { + if ($set instanceof jur_CharSet) + return 0; + if ($set instanceof jur_RangeSet) + return 0; + if ($set instanceof jur_SupplRangeSet) + return 0; + if ($set instanceof jur_SupplCharSet) + return 0; + if ($set instanceof jur_HighSurrogateCharSet) + return 0; + if (!($set instanceof jur_LowSurrogateCharSet)) + return 1; + return $set.$low != $this.$low ? 0 : 1; +} +function jur_LowSurrogateCharSet_hasConsumed($this, $matchResult) { + return 1; +} +function jur_HighSurrogateCharSet() { + jur_JointSet.call(this); + this.$high = 0; +} +function jur_HighSurrogateCharSet__init_(var_0) { + var var_1 = new jur_HighSurrogateCharSet(); + jur_HighSurrogateCharSet__init_0(var_1, var_0); + return var_1; +} +function jur_HighSurrogateCharSet__init_0($this, $high) { + var var$2, var$3; + var$2 = jur_AbstractSet_counter; + jur_AbstractSet_counter = var$2 + 1 | 0; + var$3 = new jl_AbstractStringBuilder; + var$3.$buffer = $rt_createCharArray(20); + $this.$index1 = (jl_AbstractStringBuilder_insert0(var$3, var$3.$length, var$2, 10)).$toString(); + $this.$high = $high; +} +function jur_HighSurrogateCharSet_setNext($this, $next) { + $this.$next0 = $next; +} +function jur_HighSurrogateCharSet_matches($this, $stringIndex, $testString, $matchResult) { + var $strLength, var$5, var$6, $low, $high; + $strLength = $matchResult.$rightBound; + var$5 = $stringIndex + 1 | 0; + $strLength = $rt_compare(var$5, $strLength); + if ($strLength > 0) { + $matchResult.$hitEnd = 1; + return (-1); + } + if ($stringIndex >= 0) { + var$6 = $testString.$characters.data; + $low = var$6.length; + if ($stringIndex < $low) { + a: { + $high = var$6[$stringIndex]; + if ($strLength < 0) { + if (var$5 >= 0 && var$5 < $low) { + if (!((var$6[var$5] & 64512) != 56320 ? 0 : 1)) + break a; + return (-1); + } + $testString = new jl_StringIndexOutOfBoundsException; + $testString.$suppressionEnabled = 1; + $testString.$writableStackTrace = 1; + $rt_throw($testString); + } + } + if ($this.$high != $high) + return (-1); + return $this.$next0.$matches(var$5, $testString, $matchResult); + } + } + $testString = new jl_StringIndexOutOfBoundsException; + $testString.$suppressionEnabled = 1; + $testString.$writableStackTrace = 1; + $rt_throw($testString); +} +function jur_HighSurrogateCharSet_find($this, $strIndex, $testStr, $matchResult) { + var $strLength, var$5, var$6; + if (!($testStr instanceof jl_String)) { + $strLength = $matchResult.$rightBound; + a: { + while (true) { + if ($strIndex > $strLength) { + $strIndex = (-1); + break a; + } + if (jur_HighSurrogateCharSet_matches($this, $strIndex, $testStr, $matchResult) >= 0) + break; + $strIndex = $strIndex + 1 | 0; + } + } + return $strIndex; + } + $strLength = $matchResult.$rightBound; + b: { + while (true) { + if ($strIndex >= $strLength) + return (-1); + var$5 = jl_String_indexOf($testStr, $this.$high, $strIndex); + if (var$5 < 0) + return (-1); + $strIndex = var$5 + 1 | 0; + if ($strIndex < $strLength) { + if ($strIndex < 0) + break b; + var$6 = $testStr.$characters.data; + if ($strIndex >= var$6.length) + break b; + if ((var$6[$strIndex] & 64512) != 56320 ? 0 : 1) { + $strIndex = var$5 + 2 | 0; + continue; + } + } + if ($this.$next0.$matches($strIndex, $testStr, $matchResult) >= 0) + break; + } + return var$5; + } + $testStr = new jl_StringIndexOutOfBoundsException; + $testStr.$suppressionEnabled = 1; + $testStr.$writableStackTrace = 1; + $rt_throw($testStr); +} +function jur_HighSurrogateCharSet_findBack($this, $strIndex, $lastIndex, $testStr, $matchResult) { + var $strLength, var$6, var$7; + if (!($testStr instanceof jl_String)) { + a: { + while (true) { + if ($lastIndex < $strIndex) { + $lastIndex = (-1); + break a; + } + if (jur_HighSurrogateCharSet_matches($this, $lastIndex, $testStr, $matchResult) >= 0) + break; + $lastIndex = $lastIndex + (-1) | 0; + } + } + return $lastIndex; + } + $strLength = $matchResult.$rightBound; + b: { + c: { + while (true) { + if ($lastIndex < $strIndex) + return (-1); + var$6 = jl_String_lastIndexOf($testStr, $this.$high, $lastIndex); + if (var$6 < 0) + break c; + if (var$6 < $strIndex) + break c; + $lastIndex = var$6 + 1 | 0; + if ($lastIndex < $strLength) { + if ($lastIndex < 0) + break b; + var$7 = $testStr.$characters.data; + if ($lastIndex >= var$7.length) + break b; + if ((var$7[$lastIndex] & 64512) != 56320 ? 0 : 1) { + $lastIndex = var$6 + (-1) | 0; + continue; + } + } + if ($this.$next0.$matches($lastIndex, $testStr, $matchResult) >= 0) + break; + $lastIndex = var$6 + (-1) | 0; + } + return var$6; + } + return (-1); + } + $testStr = new jl_StringIndexOutOfBoundsException; + $testStr.$suppressionEnabled = 1; + $testStr.$writableStackTrace = 1; + $rt_throw($testStr); +} +function jur_HighSurrogateCharSet_first($this, $set) { + if ($set instanceof jur_CharSet) + return 0; + if ($set instanceof jur_RangeSet) + return 0; + if ($set instanceof jur_SupplRangeSet) + return 0; + if ($set instanceof jur_SupplCharSet) + return 0; + if ($set instanceof jur_LowSurrogateCharSet) + return 0; + if (!($set instanceof jur_HighSurrogateCharSet)) + return 1; + return $set.$high != $this.$high ? 0 : 1; +} +function jur_HighSurrogateCharSet_hasConsumed($this, $matchResult) { + return 1; +} +function jur_SupplCharSet() { + var a = this; jur_LeafSet.call(a); + a.$high0 = 0; + a.$low0 = 0; + a.$ch4 = 0; +} +function jur_SupplCharSet__init_(var_0) { + var var_1 = new jur_SupplCharSet(); + jur_SupplCharSet__init_0(var_1, var_0); + return var_1; +} +function jur_SupplCharSet__init_0($this, $ch) { + var var$2, var$3, $chUTF16; + var$2 = jur_AbstractSet_counter; + jur_AbstractSet_counter = var$2 + 1 | 0; + var$3 = new jl_AbstractStringBuilder; + var$3.$buffer = $rt_createCharArray(20); + $this.$index1 = (jl_AbstractStringBuilder_insert0(var$3, var$3.$length, var$2, 10)).$toString(); + $this.$charCount = 1; + $this.$charCount = 2; + $this.$ch4 = $ch; + if ($ch < 65536) { + $chUTF16 = $rt_createCharArray(1); + $chUTF16.data[0] = $ch & 65535; + } else + $chUTF16 = $rt_createCharArrayFromData([(55296 | ($ch - 65536 | 0) >> 10 & 1023) & 65535, (56320 | $ch & 1023) & 65535]); + $chUTF16 = $chUTF16.data; + $this.$high0 = $chUTF16[0]; + $this.$low0 = $chUTF16[1]; +} +function jur_SupplCharSet_accepts($this, $strIndex, $testString) { + var $low, var$4, var$5, $high; + $low = $strIndex + 1 | 0; + if ($strIndex >= 0) { + var$4 = $testString.$characters.data; + var$5 = var$4.length; + if ($strIndex < var$5) { + $high = var$4[$strIndex]; + if ($low >= 0 && $low < var$5) { + $low = var$4[$low]; + return $this.$high0 == $high && $this.$low0 == $low ? 2 : (-1); + } + $testString = new jl_StringIndexOutOfBoundsException; + $testString.$suppressionEnabled = 1; + $testString.$writableStackTrace = 1; + $rt_throw($testString); + } + } + $testString = new jl_StringIndexOutOfBoundsException; + $testString.$suppressionEnabled = 1; + $testString.$writableStackTrace = 1; + $rt_throw($testString); +} +function jur_SupplCharSet_find($this, $strIndex, $testStr, $matchResult) { + var $strLength, var$5, $ch, var$7, var$8; + if ($testStr instanceof jl_String) { + $strLength = $matchResult.$rightBound; + a: { + while ($strIndex < $strLength) { + $strIndex = jl_String_indexOf($testStr, $this.$high0, $strIndex); + if ($strIndex < 0) + return (-1); + $strIndex = $strIndex + 1 | 0; + if ($strIndex >= $strLength) + continue; + if ($strIndex < 0) + break a; + var$5 = $testStr.$characters.data; + if ($strIndex >= var$5.length) + break a; + $ch = var$5[$strIndex]; + if ($this.$low0 == $ch && $this.$next0.$matches($strIndex + 1 | 0, $testStr, $matchResult) >= 0) + return $strIndex + (-1) | 0; + $strIndex = $strIndex + 1 | 0; + } + return (-1); + } + $testStr = new jl_StringIndexOutOfBoundsException; + $testStr.$suppressionEnabled = 1; + $testStr.$writableStackTrace = 1; + $rt_throw($testStr); + } + var$7 = $matchResult.$rightBound; + b: { + c: { + d: { + while (true) { + if ($strIndex > var$7) { + $strIndex = (-1); + break d; + } + if (($strIndex + $this.$charCount | 0) > $matchResult.$rightBound) { + $matchResult.$hitEnd = 1; + $ch = (-1); + } else { + $ch = $strIndex + 1 | 0; + if ($strIndex < 0) + break b; + var$5 = $testStr.$characters.data; + $strLength = var$5.length; + if ($strIndex >= $strLength) + break b; + var$8 = var$5[$strIndex]; + if ($ch < 0) + break c; + if ($ch >= $strLength) + break c; + $strLength = var$5[$ch]; + $ch = $this.$high0 == var$8 && $this.$low0 == $strLength ? 2 : (-1); + $ch = $ch < 0 ? (-1) : $this.$next0.$matches($strIndex + $ch | 0, $testStr, $matchResult); + } + if ($ch >= 0) + break; + $strIndex = $strIndex + 1 | 0; + } + } + return $strIndex; + } + $testStr = new jl_StringIndexOutOfBoundsException; + jl_Throwable__init_0($testStr); + $rt_throw($testStr); + } + $testStr = new jl_StringIndexOutOfBoundsException; + jl_Throwable__init_0($testStr); + $rt_throw($testStr); +} +function jur_SupplCharSet_findBack($this, $strIndex, $lastIndex, $testStr, $matchResult) { + var var$5, var$6, var$7, var$8, var$9; + if ($testStr instanceof jl_String) { + a: { + b: { + while (true) { + if ($lastIndex < $strIndex) + return (-1); + $lastIndex = jl_String_lastIndexOf($testStr, $this.$low0, $lastIndex) + (-1) | 0; + if ($lastIndex < 0) + break b; + if ($lastIndex < $strIndex) + break b; + var$5 = $this.$high0; + if ($lastIndex < 0) + break a; + var$6 = $testStr.$characters.data; + if ($lastIndex >= var$6.length) + break a; + if (var$5 == var$6[$lastIndex] && $this.$next0.$matches($lastIndex + 2 | 0, $testStr, $matchResult) >= 0) + break; + $lastIndex = $lastIndex + (-1) | 0; + } + return $lastIndex; + } + return (-1); + } + $testStr = new jl_StringIndexOutOfBoundsException; + $testStr.$suppressionEnabled = 1; + $testStr.$writableStackTrace = 1; + $rt_throw($testStr); + } + c: { + d: { + e: { + while (true) { + if ($lastIndex < $strIndex) { + $lastIndex = (-1); + break e; + } + if (($lastIndex + $this.$charCount | 0) > $matchResult.$rightBound) { + $matchResult.$hitEnd = 1; + var$5 = (-1); + } else { + var$7 = $lastIndex + 1 | 0; + if ($lastIndex < 0) + break c; + var$6 = $testStr.$characters.data; + var$5 = var$6.length; + if ($lastIndex >= var$5) + break c; + var$8 = var$6[$lastIndex]; + if (var$7 < 0) + break d; + if (var$7 >= var$5) + break d; + var$9 = var$6[var$7]; + var$5 = $this.$high0 == var$8 && $this.$low0 == var$9 ? 2 : (-1); + var$5 = var$5 < 0 ? (-1) : $this.$next0.$matches($lastIndex + var$5 | 0, $testStr, $matchResult); + } + if (var$5 >= 0) + break; + $lastIndex = $lastIndex + (-1) | 0; + } + } + return $lastIndex; + } + $testStr = new jl_StringIndexOutOfBoundsException; + jl_Throwable__init_0($testStr); + $rt_throw($testStr); + } + $testStr = new jl_StringIndexOutOfBoundsException; + jl_Throwable__init_0($testStr); + $rt_throw($testStr); +} +function jur_SupplCharSet_first($this, $set) { + if ($set instanceof jur_SupplCharSet) + return $set.$ch4 != $this.$ch4 ? 0 : 1; + if ($set instanceof jur_SupplRangeSet) + return $set.$contains($this.$ch4); + if ($set instanceof jur_CharSet) + return 0; + if (!($set instanceof jur_RangeSet)) + return 1; + return 0; +} +var jur_AbstractLineTerminator$1 = $rt_classWithoutFields(jur_AbstractLineTerminator); +function jur_AbstractLineTerminator$1_isLineTerminator($this, $ch) { + return $ch != 10 ? 0 : 1; +} +function jur_AbstractLineTerminator$1_isAfterLineTerminator($this, $ch, $ch2) { + return $ch != 10 ? 0 : 1; +} +var jur_AbstractLineTerminator$2 = $rt_classWithoutFields(jur_AbstractLineTerminator); +function jur_AbstractLineTerminator$2_isLineTerminator($this, $ch) { + return $ch != 10 && $ch != 13 && $ch != 133 && ($ch | 1) != 8233 ? 0 : 1; +} +function jur_AbstractLineTerminator$2_isAfterLineTerminator($this, $ch, $ch2) { + a: { + b: { + if ($ch != 10 && $ch != 133 && ($ch | 1) != 8233) { + if ($ch != 13) + break b; + if ($ch2 == 10) + break b; + } + $ch = 1; + break a; + } + $ch = 0; + } + return $ch; +} +function jur_SequenceSet$IntHash() { + var a = this; jl_Object.call(a); + a.$table = null; + a.$values = null; + a.$mask = 0; + a.$size1 = 0; +} +function jur_SequenceSet$IntHash__init_(var_0) { + var var_1 = new jur_SequenceSet$IntHash(); + jur_SequenceSet$IntHash__init_0(var_1, var_0); + return var_1; +} +function jur_SequenceSet$IntHash__init_0($this, $size) { + var var$2, var$3; + while (true) { + var$2 = $this.$mask; + if ($size < var$2) + break; + $this.$mask = var$2 << 1 | 1; + } + var$3 = var$2 << 1 | 1; + $this.$mask = var$3; + var$3 = var$3 + 1 | 0; + $this.$table = $rt_createIntArray(var$3); + $this.$values = $rt_createIntArray(var$3); + $this.$size1 = $size; +} +function jur_SequenceSet$IntHash_put($this, $key, $value) { + var $i, var$4, $hashCode, var$6; + $i = 0; + var$4 = $this.$mask; + $hashCode = $key & var$4; + while (true) { + var$6 = $this.$table.data; + if (!var$6[$hashCode]) + break; + if (var$6[$hashCode] == $key) + break; + $i = ($i + 1 | 0) & var$4; + $hashCode = ($hashCode + $i | 0) & var$4; + } + var$6[$hashCode] = $key; + $this.$values.data[$hashCode] = $value; +} +function jur_SequenceSet$IntHash_get($this, $key) { + var var$2, $hashCode, $i, $storedKey; + var$2 = $this.$mask; + $hashCode = $key & var$2; + $i = 0; + while (true) { + $storedKey = $this.$table.data[$hashCode]; + if (!$storedKey) + break; + if ($storedKey == $key) + return $this.$values.data[$hashCode]; + $i = ($i + 1 | 0) & var$2; + $hashCode = ($hashCode + $i | 0) & var$2; + } + return $this.$size1; +} +var jur_IntHash = $rt_classWithoutFields(); +var jur_AbstractCharClass$LazySpace = $rt_classWithoutFields(jur_AbstractCharClass$LazyCharClass); +function jur_AbstractCharClass$LazySpace__init_() { + var var_0 = new jur_AbstractCharClass$LazySpace(); + jur_AbstractCharClass$LazySpace__init_0(var_0); + return var_0; +} +function jur_AbstractCharClass$LazySpace__init_0($this) {} +function jur_AbstractCharClass$LazySpace_computeValue($this) { + var var$1, var$2; + var$1 = new jur_CharClass; + var$2 = new ju_BitSet; + var$2.$data0 = $rt_createIntArray(64); + var$1.$lowHighSurrogates = var$2; + var$2 = new ju_BitSet; + var$2.$data0 = $rt_createIntArray(0); + var$1.$bits = var$2; + return jur_CharClass_add(jur_CharClass_add0(var$1, 9, 13), 32); +} +var jur_AbstractCharClass$LazyDigit = $rt_classWithoutFields(jur_AbstractCharClass$LazyCharClass); +function jur_AbstractCharClass$LazyDigit__init_() { + var var_0 = new jur_AbstractCharClass$LazyDigit(); + jur_AbstractCharClass$LazyDigit__init_0(var_0); + return var_0; +} +function jur_AbstractCharClass$LazyDigit__init_0($this) {} +function jur_AbstractCharClass$LazyDigit_computeValue($this) { + var var$1, var$2; + var$1 = new jur_CharClass; + var$2 = new ju_BitSet; + var$2.$data0 = $rt_createIntArray(64); + var$1.$lowHighSurrogates = var$2; + var$2 = new ju_BitSet; + var$2.$data0 = $rt_createIntArray(0); + var$1.$bits = var$2; + return jur_CharClass_add0(var$1, 48, 57); +} +var jur_AbstractCharClass$LazyLower = $rt_classWithoutFields(jur_AbstractCharClass$LazyCharClass); +function jur_AbstractCharClass$LazyLower__init_() { + var var_0 = new jur_AbstractCharClass$LazyLower(); + jur_AbstractCharClass$LazyLower__init_0(var_0); + return var_0; +} +function jur_AbstractCharClass$LazyLower__init_0($this) {} +function jur_AbstractCharClass$LazyLower_computeValue($this) { + var var$1, var$2; + var$1 = new jur_CharClass; + var$2 = new ju_BitSet; + var$2.$data0 = $rt_createIntArray(64); + var$1.$lowHighSurrogates = var$2; + var$2 = new ju_BitSet; + var$2.$data0 = $rt_createIntArray(0); + var$1.$bits = var$2; + return jur_CharClass_add0(var$1, 97, 122); +} +var jur_AbstractCharClass$LazyUpper = $rt_classWithoutFields(jur_AbstractCharClass$LazyCharClass); +function jur_AbstractCharClass$LazyUpper__init_() { + var var_0 = new jur_AbstractCharClass$LazyUpper(); + jur_AbstractCharClass$LazyUpper__init_0(var_0); + return var_0; +} +function jur_AbstractCharClass$LazyUpper__init_0($this) {} +function jur_AbstractCharClass$LazyUpper_computeValue($this) { + var var$1, var$2; + var$1 = new jur_CharClass; + var$2 = new ju_BitSet; + var$2.$data0 = $rt_createIntArray(64); + var$1.$lowHighSurrogates = var$2; + var$2 = new ju_BitSet; + var$2.$data0 = $rt_createIntArray(0); + var$1.$bits = var$2; + return jur_CharClass_add0(var$1, 65, 90); +} +var jur_AbstractCharClass$LazyASCII = $rt_classWithoutFields(jur_AbstractCharClass$LazyCharClass); +function jur_AbstractCharClass$LazyASCII__init_() { + var var_0 = new jur_AbstractCharClass$LazyASCII(); + jur_AbstractCharClass$LazyASCII__init_0(var_0); + return var_0; +} +function jur_AbstractCharClass$LazyASCII__init_0($this) {} +function jur_AbstractCharClass$LazyASCII_computeValue($this) { + var var$1, var$2; + var$1 = new jur_CharClass; + var$2 = new ju_BitSet; + var$2.$data0 = $rt_createIntArray(64); + var$1.$lowHighSurrogates = var$2; + var$2 = new ju_BitSet; + var$2.$data0 = $rt_createIntArray(0); + var$1.$bits = var$2; + return jur_CharClass_add0(var$1, 0, 127); +} +var jur_AbstractCharClass$LazyAlpha = $rt_classWithoutFields(jur_AbstractCharClass$LazyCharClass); +function jur_AbstractCharClass$LazyAlpha__init_() { + var var_0 = new jur_AbstractCharClass$LazyAlpha(); + jur_AbstractCharClass$LazyAlpha__init_0(var_0); + return var_0; +} +function jur_AbstractCharClass$LazyAlpha__init_0($this) {} +function jur_AbstractCharClass$LazyAlpha_computeValue($this) { + var var$1, var$2; + var$1 = new jur_CharClass; + var$2 = new ju_BitSet; + var$2.$data0 = $rt_createIntArray(64); + var$1.$lowHighSurrogates = var$2; + var$2 = new ju_BitSet; + var$2.$data0 = $rt_createIntArray(0); + var$1.$bits = var$2; + return jur_CharClass_add0(jur_CharClass_add0(var$1, 97, 122), 65, 90); +} +var jur_AbstractCharClass$LazyAlnum = $rt_classWithoutFields(jur_AbstractCharClass$LazyAlpha); +function jur_AbstractCharClass$LazyAlnum__init_() { + var var_0 = new jur_AbstractCharClass$LazyAlnum(); + jur_AbstractCharClass$LazyAlnum__init_0(var_0); + return var_0; +} +function jur_AbstractCharClass$LazyAlnum__init_0($this) {} +function jur_AbstractCharClass$LazyAlnum_computeValue($this) { + var var$1, var$2; + var$1 = new jur_CharClass; + var$2 = new ju_BitSet; + var$2.$data0 = $rt_createIntArray(64); + var$1.$lowHighSurrogates = var$2; + var$2 = new ju_BitSet; + var$2.$data0 = $rt_createIntArray(0); + var$1.$bits = var$2; + return jur_CharClass_add0(jur_CharClass_add0(jur_CharClass_add0(var$1, 97, 122), 65, 90), 48, 57); +} +var jur_AbstractCharClass$LazyPunct = $rt_classWithoutFields(jur_AbstractCharClass$LazyCharClass); +function jur_AbstractCharClass$LazyPunct__init_() { + var var_0 = new jur_AbstractCharClass$LazyPunct(); + jur_AbstractCharClass$LazyPunct__init_0(var_0); + return var_0; +} +function jur_AbstractCharClass$LazyPunct__init_0($this) {} +function jur_AbstractCharClass$LazyPunct_computeValue($this) { + var var$1, var$2; + var$1 = new jur_CharClass; + var$2 = new ju_BitSet; + var$2.$data0 = $rt_createIntArray(64); + var$1.$lowHighSurrogates = var$2; + var$2 = new ju_BitSet; + var$2.$data0 = $rt_createIntArray(0); + var$1.$bits = var$2; + return jur_CharClass_add0(jur_CharClass_add0(jur_CharClass_add0(var$1, 33, 64), 91, 96), 123, 126); +} +var jur_AbstractCharClass$LazyGraph = $rt_classWithoutFields(jur_AbstractCharClass$LazyAlnum); +function jur_AbstractCharClass$LazyGraph__init_() { + var var_0 = new jur_AbstractCharClass$LazyGraph(); + jur_AbstractCharClass$LazyGraph__init_0(var_0); + return var_0; +} +function jur_AbstractCharClass$LazyGraph__init_0($this) {} +function jur_AbstractCharClass$LazyGraph_computeValue($this) { + var var$1, var$2; + var$1 = new jur_CharClass; + var$2 = new ju_BitSet; + var$2.$data0 = $rt_createIntArray(64); + var$1.$lowHighSurrogates = var$2; + var$2 = new ju_BitSet; + var$2.$data0 = $rt_createIntArray(0); + var$1.$bits = var$2; + return jur_CharClass_add0(jur_CharClass_add0(jur_CharClass_add0(jur_CharClass_add0(jur_CharClass_add0(jur_CharClass_add0(var$1, 97, 122), 65, 90), 48, 57), 33, 64), 91, 96), 123, 126); +} +var jur_AbstractCharClass$LazyPrint = $rt_classWithoutFields(jur_AbstractCharClass$LazyGraph); +function jur_AbstractCharClass$LazyPrint__init_() { + var var_0 = new jur_AbstractCharClass$LazyPrint(); + jur_AbstractCharClass$LazyPrint__init_0(var_0); + return var_0; +} +function jur_AbstractCharClass$LazyPrint__init_0($this) {} +function jur_AbstractCharClass$LazyPrint_computeValue($this) { + var var$1, var$2; + var$1 = new jur_CharClass; + var$2 = new ju_BitSet; + var$2.$data0 = $rt_createIntArray(64); + var$1.$lowHighSurrogates = var$2; + var$2 = new ju_BitSet; + var$2.$data0 = $rt_createIntArray(0); + var$1.$bits = var$2; + return jur_CharClass_add(jur_CharClass_add0(jur_CharClass_add0(jur_CharClass_add0(jur_CharClass_add0(jur_CharClass_add0(jur_CharClass_add0(var$1, 97, 122), 65, 90), 48, 57), 33, 64), 91, 96), 123, 126), 32); +} +var jur_AbstractCharClass$LazyBlank = $rt_classWithoutFields(jur_AbstractCharClass$LazyCharClass); +function jur_AbstractCharClass$LazyBlank__init_() { + var var_0 = new jur_AbstractCharClass$LazyBlank(); + jur_AbstractCharClass$LazyBlank__init_0(var_0); + return var_0; +} +function jur_AbstractCharClass$LazyBlank__init_0($this) {} +function jur_AbstractCharClass$LazyBlank_computeValue($this) { + var var$1, var$2; + var$1 = new jur_CharClass; + var$2 = new ju_BitSet; + var$2.$data0 = $rt_createIntArray(64); + var$1.$lowHighSurrogates = var$2; + var$2 = new ju_BitSet; + var$2.$data0 = $rt_createIntArray(0); + var$1.$bits = var$2; + return jur_CharClass_add(jur_CharClass_add(var$1, 32), 9); +} +var jur_AbstractCharClass$LazyCntrl = $rt_classWithoutFields(jur_AbstractCharClass$LazyCharClass); +function jur_AbstractCharClass$LazyCntrl__init_() { + var var_0 = new jur_AbstractCharClass$LazyCntrl(); + jur_AbstractCharClass$LazyCntrl__init_0(var_0); + return var_0; +} +function jur_AbstractCharClass$LazyCntrl__init_0($this) {} +function jur_AbstractCharClass$LazyCntrl_computeValue($this) { + var var$1, var$2; + var$1 = new jur_CharClass; + var$2 = new ju_BitSet; + var$2.$data0 = $rt_createIntArray(64); + var$1.$lowHighSurrogates = var$2; + var$2 = new ju_BitSet; + var$2.$data0 = $rt_createIntArray(0); + var$1.$bits = var$2; + return jur_CharClass_add(jur_CharClass_add0(var$1, 0, 31), 127); +} +var jur_AbstractCharClass$LazyXDigit = $rt_classWithoutFields(jur_AbstractCharClass$LazyCharClass); +function jur_AbstractCharClass$LazyXDigit__init_() { + var var_0 = new jur_AbstractCharClass$LazyXDigit(); + jur_AbstractCharClass$LazyXDigit__init_0(var_0); + return var_0; +} +function jur_AbstractCharClass$LazyXDigit__init_0($this) {} +function jur_AbstractCharClass$LazyXDigit_computeValue($this) { + var var$1, var$2; + var$1 = new jur_CharClass; + var$2 = new ju_BitSet; + var$2.$data0 = $rt_createIntArray(64); + var$1.$lowHighSurrogates = var$2; + var$2 = new ju_BitSet; + var$2.$data0 = $rt_createIntArray(0); + var$1.$bits = var$2; + return jur_CharClass_add0(jur_CharClass_add0(jur_CharClass_add0(var$1, 48, 57), 97, 102), 65, 70); +} +var jur_AbstractCharClass$LazyJavaLowerCase = $rt_classWithoutFields(jur_AbstractCharClass$LazyCharClass); +function jur_AbstractCharClass$LazyJavaLowerCase__init_() { + var var_0 = new jur_AbstractCharClass$LazyJavaLowerCase(); + jur_AbstractCharClass$LazyJavaLowerCase__init_0(var_0); + return var_0; +} +function jur_AbstractCharClass$LazyJavaLowerCase__init_0($this) {} +function jur_AbstractCharClass$LazyJavaLowerCase_computeValue($this) { + var $chCl, var$2; + $chCl = new jur_AbstractCharClass$LazyJavaLowerCase$1; + $chCl.$this$019 = $this; + var$2 = new ju_BitSet; + var$2.$data0 = $rt_createIntArray(64); + $chCl.$lowHighSurrogates = var$2; + $chCl.$mayContainSupplCodepoints = 1; + return $chCl; +} +var jur_AbstractCharClass$LazyJavaUpperCase = $rt_classWithoutFields(jur_AbstractCharClass$LazyCharClass); +function jur_AbstractCharClass$LazyJavaUpperCase__init_() { + var var_0 = new jur_AbstractCharClass$LazyJavaUpperCase(); + jur_AbstractCharClass$LazyJavaUpperCase__init_0(var_0); + return var_0; +} +function jur_AbstractCharClass$LazyJavaUpperCase__init_0($this) {} +function jur_AbstractCharClass$LazyJavaUpperCase_computeValue($this) { + var $chCl, var$2; + $chCl = new jur_AbstractCharClass$LazyJavaUpperCase$1; + $chCl.$this$020 = $this; + var$2 = new ju_BitSet; + var$2.$data0 = $rt_createIntArray(64); + $chCl.$lowHighSurrogates = var$2; + $chCl.$mayContainSupplCodepoints = 1; + return $chCl; +} +var jur_AbstractCharClass$LazyJavaWhitespace = $rt_classWithoutFields(jur_AbstractCharClass$LazyCharClass); +function jur_AbstractCharClass$LazyJavaWhitespace__init_() { + var var_0 = new jur_AbstractCharClass$LazyJavaWhitespace(); + jur_AbstractCharClass$LazyJavaWhitespace__init_0(var_0); + return var_0; +} +function jur_AbstractCharClass$LazyJavaWhitespace__init_0($this) {} +function jur_AbstractCharClass$LazyJavaWhitespace_computeValue($this) { + var var$1, var$2; + var$1 = new jur_AbstractCharClass$LazyJavaWhitespace$1; + var$1.$this$021 = $this; + var$2 = new ju_BitSet; + var$2.$data0 = $rt_createIntArray(64); + var$1.$lowHighSurrogates = var$2; + return var$1; +} +var jur_AbstractCharClass$LazyJavaMirrored = $rt_classWithoutFields(jur_AbstractCharClass$LazyCharClass); +function jur_AbstractCharClass$LazyJavaMirrored__init_() { + var var_0 = new jur_AbstractCharClass$LazyJavaMirrored(); + jur_AbstractCharClass$LazyJavaMirrored__init_0(var_0); + return var_0; +} +function jur_AbstractCharClass$LazyJavaMirrored__init_0($this) {} +function jur_AbstractCharClass$LazyJavaMirrored_computeValue($this) { + var var$1, var$2; + var$1 = new jur_AbstractCharClass$LazyJavaMirrored$1; + var$1.$this$022 = $this; + var$2 = new ju_BitSet; + var$2.$data0 = $rt_createIntArray(64); + var$1.$lowHighSurrogates = var$2; + return var$1; +} +var jur_AbstractCharClass$LazyJavaDefined = $rt_classWithoutFields(jur_AbstractCharClass$LazyCharClass); +function jur_AbstractCharClass$LazyJavaDefined__init_() { + var var_0 = new jur_AbstractCharClass$LazyJavaDefined(); + jur_AbstractCharClass$LazyJavaDefined__init_0(var_0); + return var_0; +} +function jur_AbstractCharClass$LazyJavaDefined__init_0($this) {} +function jur_AbstractCharClass$LazyJavaDefined_computeValue($this) { + var $chCl, var$2; + $chCl = new jur_AbstractCharClass$LazyJavaDefined$1; + $chCl.$this$023 = $this; + var$2 = new ju_BitSet; + var$2.$data0 = $rt_createIntArray(64); + $chCl.$lowHighSurrogates = var$2; + ju_BitSet_set0(var$2, 0, 2048); + $chCl.$mayContainSupplCodepoints = 1; + return $chCl; +} +var jur_AbstractCharClass$LazyJavaDigit = $rt_classWithoutFields(jur_AbstractCharClass$LazyCharClass); +function jur_AbstractCharClass$LazyJavaDigit__init_() { + var var_0 = new jur_AbstractCharClass$LazyJavaDigit(); + jur_AbstractCharClass$LazyJavaDigit__init_0(var_0); + return var_0; +} +function jur_AbstractCharClass$LazyJavaDigit__init_0($this) {} +function jur_AbstractCharClass$LazyJavaDigit_computeValue($this) { + var $chCl, var$2; + $chCl = new jur_AbstractCharClass$LazyJavaDigit$1; + $chCl.$this$024 = $this; + var$2 = new ju_BitSet; + var$2.$data0 = $rt_createIntArray(64); + $chCl.$lowHighSurrogates = var$2; + $chCl.$mayContainSupplCodepoints = 1; + return $chCl; +} +var jur_AbstractCharClass$LazyJavaIdentifierIgnorable = $rt_classWithoutFields(jur_AbstractCharClass$LazyCharClass); +function jur_AbstractCharClass$LazyJavaIdentifierIgnorable__init_() { + var var_0 = new jur_AbstractCharClass$LazyJavaIdentifierIgnorable(); + jur_AbstractCharClass$LazyJavaIdentifierIgnorable__init_0(var_0); + return var_0; +} +function jur_AbstractCharClass$LazyJavaIdentifierIgnorable__init_0($this) {} +function jur_AbstractCharClass$LazyJavaIdentifierIgnorable_computeValue($this) { + var $chCl, var$2; + $chCl = new jur_AbstractCharClass$LazyJavaIdentifierIgnorable$1; + $chCl.$this$025 = $this; + var$2 = new ju_BitSet; + var$2.$data0 = $rt_createIntArray(64); + $chCl.$lowHighSurrogates = var$2; + $chCl.$mayContainSupplCodepoints = 1; + return $chCl; +} +var jur_AbstractCharClass$LazyJavaISOControl = $rt_classWithoutFields(jur_AbstractCharClass$LazyCharClass); +function jur_AbstractCharClass$LazyJavaISOControl__init_() { + var var_0 = new jur_AbstractCharClass$LazyJavaISOControl(); + jur_AbstractCharClass$LazyJavaISOControl__init_0(var_0); + return var_0; +} +function jur_AbstractCharClass$LazyJavaISOControl__init_0($this) {} +function jur_AbstractCharClass$LazyJavaISOControl_computeValue($this) { + var var$1, var$2; + var$1 = new jur_AbstractCharClass$LazyJavaISOControl$1; + var$1.$this$026 = $this; + var$2 = new ju_BitSet; + var$2.$data0 = $rt_createIntArray(64); + var$1.$lowHighSurrogates = var$2; + return var$1; +} +var jur_AbstractCharClass$LazyJavaJavaIdentifierPart = $rt_classWithoutFields(jur_AbstractCharClass$LazyCharClass); +function jur_AbstractCharClass$LazyJavaJavaIdentifierPart__init_() { + var var_0 = new jur_AbstractCharClass$LazyJavaJavaIdentifierPart(); + jur_AbstractCharClass$LazyJavaJavaIdentifierPart__init_0(var_0); + return var_0; +} +function jur_AbstractCharClass$LazyJavaJavaIdentifierPart__init_0($this) {} +function jur_AbstractCharClass$LazyJavaJavaIdentifierPart_computeValue($this) { + var $chCl, var$2; + $chCl = new jur_AbstractCharClass$LazyJavaJavaIdentifierPart$1; + $chCl.$this$027 = $this; + var$2 = new ju_BitSet; + var$2.$data0 = $rt_createIntArray(64); + $chCl.$lowHighSurrogates = var$2; + $chCl.$mayContainSupplCodepoints = 1; + return $chCl; +} +var jur_AbstractCharClass$LazyJavaJavaIdentifierStart = $rt_classWithoutFields(jur_AbstractCharClass$LazyCharClass); +function jur_AbstractCharClass$LazyJavaJavaIdentifierStart__init_() { + var var_0 = new jur_AbstractCharClass$LazyJavaJavaIdentifierStart(); + jur_AbstractCharClass$LazyJavaJavaIdentifierStart__init_0(var_0); + return var_0; +} +function jur_AbstractCharClass$LazyJavaJavaIdentifierStart__init_0($this) {} +function jur_AbstractCharClass$LazyJavaJavaIdentifierStart_computeValue($this) { + var $chCl, var$2; + $chCl = new jur_AbstractCharClass$LazyJavaJavaIdentifierStart$1; + $chCl.$this$028 = $this; + var$2 = new ju_BitSet; + var$2.$data0 = $rt_createIntArray(64); + $chCl.$lowHighSurrogates = var$2; + $chCl.$mayContainSupplCodepoints = 1; + return $chCl; +} +var jur_AbstractCharClass$LazyJavaLetter = $rt_classWithoutFields(jur_AbstractCharClass$LazyCharClass); +function jur_AbstractCharClass$LazyJavaLetter__init_() { + var var_0 = new jur_AbstractCharClass$LazyJavaLetter(); + jur_AbstractCharClass$LazyJavaLetter__init_0(var_0); + return var_0; +} +function jur_AbstractCharClass$LazyJavaLetter__init_0($this) {} +function jur_AbstractCharClass$LazyJavaLetter_computeValue($this) { + var $chCl, var$2; + $chCl = new jur_AbstractCharClass$LazyJavaLetter$1; + $chCl.$this$029 = $this; + var$2 = new ju_BitSet; + var$2.$data0 = $rt_createIntArray(64); + $chCl.$lowHighSurrogates = var$2; + $chCl.$mayContainSupplCodepoints = 1; + return $chCl; +} +var jur_AbstractCharClass$LazyJavaLetterOrDigit = $rt_classWithoutFields(jur_AbstractCharClass$LazyCharClass); +function jur_AbstractCharClass$LazyJavaLetterOrDigit__init_() { + var var_0 = new jur_AbstractCharClass$LazyJavaLetterOrDigit(); + jur_AbstractCharClass$LazyJavaLetterOrDigit__init_0(var_0); + return var_0; +} +function jur_AbstractCharClass$LazyJavaLetterOrDigit__init_0($this) {} +function jur_AbstractCharClass$LazyJavaLetterOrDigit_computeValue($this) { + var $chCl, var$2; + $chCl = new jur_AbstractCharClass$LazyJavaLetterOrDigit$1; + $chCl.$this$030 = $this; + var$2 = new ju_BitSet; + var$2.$data0 = $rt_createIntArray(64); + $chCl.$lowHighSurrogates = var$2; + $chCl.$mayContainSupplCodepoints = 1; + return $chCl; +} +var jur_AbstractCharClass$LazyJavaSpaceChar = $rt_classWithoutFields(jur_AbstractCharClass$LazyCharClass); +function jur_AbstractCharClass$LazyJavaSpaceChar__init_() { + var var_0 = new jur_AbstractCharClass$LazyJavaSpaceChar(); + jur_AbstractCharClass$LazyJavaSpaceChar__init_0(var_0); + return var_0; +} +function jur_AbstractCharClass$LazyJavaSpaceChar__init_0($this) {} +function jur_AbstractCharClass$LazyJavaSpaceChar_computeValue($this) { + var var$1, var$2; + var$1 = new jur_AbstractCharClass$LazyJavaSpaceChar$1; + var$1.$this$031 = $this; + var$2 = new ju_BitSet; + var$2.$data0 = $rt_createIntArray(64); + var$1.$lowHighSurrogates = var$2; + return var$1; +} +var jur_AbstractCharClass$LazyJavaTitleCase = $rt_classWithoutFields(jur_AbstractCharClass$LazyCharClass); +function jur_AbstractCharClass$LazyJavaTitleCase__init_() { + var var_0 = new jur_AbstractCharClass$LazyJavaTitleCase(); + jur_AbstractCharClass$LazyJavaTitleCase__init_0(var_0); + return var_0; +} +function jur_AbstractCharClass$LazyJavaTitleCase__init_0($this) {} +function jur_AbstractCharClass$LazyJavaTitleCase_computeValue($this) { + var var$1, var$2; + var$1 = new jur_AbstractCharClass$LazyJavaTitleCase$1; + var$1.$this$032 = $this; + var$2 = new ju_BitSet; + var$2.$data0 = $rt_createIntArray(64); + var$1.$lowHighSurrogates = var$2; + return var$1; +} +var jur_AbstractCharClass$LazyJavaUnicodeIdentifierPart = $rt_classWithoutFields(jur_AbstractCharClass$LazyCharClass); +function jur_AbstractCharClass$LazyJavaUnicodeIdentifierPart__init_() { + var var_0 = new jur_AbstractCharClass$LazyJavaUnicodeIdentifierPart(); + jur_AbstractCharClass$LazyJavaUnicodeIdentifierPart__init_0(var_0); + return var_0; +} +function jur_AbstractCharClass$LazyJavaUnicodeIdentifierPart__init_0($this) {} +function jur_AbstractCharClass$LazyJavaUnicodeIdentifierPart_computeValue($this) { + var $chCl, var$2; + $chCl = new jur_AbstractCharClass$LazyJavaUnicodeIdentifierPart$1; + $chCl.$this$033 = $this; + var$2 = new ju_BitSet; + var$2.$data0 = $rt_createIntArray(64); + $chCl.$lowHighSurrogates = var$2; + $chCl.$mayContainSupplCodepoints = 1; + return $chCl; +} +var jur_AbstractCharClass$LazyJavaUnicodeIdentifierStart = $rt_classWithoutFields(jur_AbstractCharClass$LazyCharClass); +function jur_AbstractCharClass$LazyJavaUnicodeIdentifierStart__init_() { + var var_0 = new jur_AbstractCharClass$LazyJavaUnicodeIdentifierStart(); + jur_AbstractCharClass$LazyJavaUnicodeIdentifierStart__init_0(var_0); + return var_0; +} +function jur_AbstractCharClass$LazyJavaUnicodeIdentifierStart__init_0($this) {} +function jur_AbstractCharClass$LazyJavaUnicodeIdentifierStart_computeValue($this) { + var $chCl, var$2; + $chCl = new jur_AbstractCharClass$LazyJavaUnicodeIdentifierStart$1; + $chCl.$this$034 = $this; + var$2 = new ju_BitSet; + var$2.$data0 = $rt_createIntArray(64); + $chCl.$lowHighSurrogates = var$2; + $chCl.$mayContainSupplCodepoints = 1; + return $chCl; +} +var jur_AbstractCharClass$LazyWord = $rt_classWithoutFields(jur_AbstractCharClass$LazyCharClass); +function jur_AbstractCharClass$LazyWord__init_() { + var var_0 = new jur_AbstractCharClass$LazyWord(); + jur_AbstractCharClass$LazyWord__init_0(var_0); + return var_0; +} +function jur_AbstractCharClass$LazyWord__init_0($this) {} +function jur_AbstractCharClass$LazyWord_computeValue($this) { + var var$1, var$2; + var$1 = new jur_CharClass; + var$2 = new ju_BitSet; + var$2.$data0 = $rt_createIntArray(64); + var$1.$lowHighSurrogates = var$2; + var$2 = new ju_BitSet; + var$2.$data0 = $rt_createIntArray(0); + var$1.$bits = var$2; + return jur_CharClass_add(jur_CharClass_add0(jur_CharClass_add0(jur_CharClass_add0(var$1, 97, 122), 65, 90), 48, 57), 95); +} +var jur_AbstractCharClass$LazyNonWord = $rt_classWithoutFields(jur_AbstractCharClass$LazyWord); +function jur_AbstractCharClass$LazyNonWord__init_() { + var var_0 = new jur_AbstractCharClass$LazyNonWord(); + jur_AbstractCharClass$LazyNonWord__init_0(var_0); + return var_0; +} +function jur_AbstractCharClass$LazyNonWord__init_0($this) {} +function jur_AbstractCharClass$LazyNonWord_computeValue($this) { + var $chCl, var$2; + $chCl = new jur_CharClass; + var$2 = new ju_BitSet; + var$2.$data0 = $rt_createIntArray(64); + $chCl.$lowHighSurrogates = var$2; + var$2 = new ju_BitSet; + var$2.$data0 = $rt_createIntArray(0); + $chCl.$bits = var$2; + $chCl = jur_AbstractCharClass_setNegative(jur_CharClass_add(jur_CharClass_add0(jur_CharClass_add0(jur_CharClass_add0($chCl, 97, 122), 65, 90), 48, 57), 95), 1); + $chCl.$mayContainSupplCodepoints = 1; + return $chCl; +} +var jur_AbstractCharClass$LazyNonSpace = $rt_classWithoutFields(jur_AbstractCharClass$LazySpace); +function jur_AbstractCharClass$LazyNonSpace__init_() { + var var_0 = new jur_AbstractCharClass$LazyNonSpace(); + jur_AbstractCharClass$LazyNonSpace__init_0(var_0); + return var_0; +} +function jur_AbstractCharClass$LazyNonSpace__init_0($this) {} +function jur_AbstractCharClass$LazyNonSpace_computeValue($this) { + var $chCl, var$2; + $chCl = new jur_CharClass; + var$2 = new ju_BitSet; + var$2.$data0 = $rt_createIntArray(64); + $chCl.$lowHighSurrogates = var$2; + var$2 = new ju_BitSet; + var$2.$data0 = $rt_createIntArray(0); + $chCl.$bits = var$2; + $chCl = jur_AbstractCharClass_setNegative(jur_CharClass_add(jur_CharClass_add0($chCl, 9, 13), 32), 1); + $chCl.$mayContainSupplCodepoints = 1; + return $chCl; +} +var jur_AbstractCharClass$LazyNonDigit = $rt_classWithoutFields(jur_AbstractCharClass$LazyDigit); +function jur_AbstractCharClass$LazyNonDigit__init_() { + var var_0 = new jur_AbstractCharClass$LazyNonDigit(); + jur_AbstractCharClass$LazyNonDigit__init_0(var_0); + return var_0; +} +function jur_AbstractCharClass$LazyNonDigit__init_0($this) {} +function jur_AbstractCharClass$LazyNonDigit_computeValue($this) { + var $chCl, var$2; + $chCl = new jur_CharClass; + var$2 = new ju_BitSet; + var$2.$data0 = $rt_createIntArray(64); + $chCl.$lowHighSurrogates = var$2; + var$2 = new ju_BitSet; + var$2.$data0 = $rt_createIntArray(0); + $chCl.$bits = var$2; + $chCl = jur_AbstractCharClass_setNegative(jur_CharClass_add0($chCl, 48, 57), 1); + $chCl.$mayContainSupplCodepoints = 1; + return $chCl; +} +function jur_AbstractCharClass$LazyRange() { + var a = this; jur_AbstractCharClass$LazyCharClass.call(a); + a.$start3 = 0; + a.$end0 = 0; +} +function jur_AbstractCharClass$LazyRange__init_(var_0, var_1) { + var var_2 = new jur_AbstractCharClass$LazyRange(); + jur_AbstractCharClass$LazyRange__init_0(var_2, var_0, var_1); + return var_2; +} +function jur_AbstractCharClass$LazyRange__init_0($this, $start, $end) { + $this.$start3 = $start; + $this.$end0 = $end; +} +function jur_AbstractCharClass$LazyRange_computeValue($this) { + var $chCl, var$2; + $chCl = new jur_CharClass; + var$2 = new ju_BitSet; + var$2.$data0 = $rt_createIntArray(64); + $chCl.$lowHighSurrogates = var$2; + var$2 = new ju_BitSet; + var$2.$data0 = $rt_createIntArray(0); + $chCl.$bits = var$2; + return jur_CharClass_add0($chCl, $this.$start3, $this.$end0); +} +var jur_AbstractCharClass$LazySpecialsBlock = $rt_classWithoutFields(jur_AbstractCharClass$LazyCharClass); +function jur_AbstractCharClass$LazySpecialsBlock__init_() { + var var_0 = new jur_AbstractCharClass$LazySpecialsBlock(); + jur_AbstractCharClass$LazySpecialsBlock__init_0(var_0); + return var_0; +} +function jur_AbstractCharClass$LazySpecialsBlock__init_0($this) {} +function jur_AbstractCharClass$LazySpecialsBlock_computeValue($this) { + var var$1, var$2; + var$1 = new jur_CharClass; + var$2 = new ju_BitSet; + var$2.$data0 = $rt_createIntArray(64); + var$1.$lowHighSurrogates = var$2; + var$2 = new ju_BitSet; + var$2.$data0 = $rt_createIntArray(0); + var$1.$bits = var$2; + return jur_CharClass_add0(jur_CharClass_add0(var$1, 65279, 65279), 65520, 65533); +} +function jur_AbstractCharClass$LazyCategory() { + var a = this; jur_AbstractCharClass$LazyCharClass.call(a); + a.$category = 0; + a.$mayContainSupplCodepoints0 = 0; + a.$containsAllSurrogates = 0; +} +function jur_AbstractCharClass$LazyCategory__init_(var_0, var_1) { + var var_2 = new jur_AbstractCharClass$LazyCategory(); + jur_AbstractCharClass$LazyCategory__init_1(var_2, var_0, var_1); + return var_2; +} +function jur_AbstractCharClass$LazyCategory__init_0(var_0, var_1, var_2) { + var var_3 = new jur_AbstractCharClass$LazyCategory(); + jur_AbstractCharClass$LazyCategory__init_2(var_3, var_0, var_1, var_2); + return var_3; +} +function jur_AbstractCharClass$LazyCategory__init_1($this, $cat, $mayContainSupplCodepoints) { + $this.$mayContainSupplCodepoints0 = $mayContainSupplCodepoints; + $this.$category = $cat; +} +function jur_AbstractCharClass$LazyCategory__init_2($this, $cat, $mayContainSupplCodepoints, $containsAllSurrogates) { + $this.$containsAllSurrogates = $containsAllSurrogates; + $this.$mayContainSupplCodepoints0 = $mayContainSupplCodepoints; + $this.$category = $cat; +} +function jur_AbstractCharClass$LazyCategory_computeValue($this) { + var $chCl, var$2, var$3; + $chCl = new jur_UnicodeCategory; + var$2 = $this.$category; + var$3 = new ju_BitSet; + var$3.$data0 = $rt_createIntArray(64); + $chCl.$lowHighSurrogates = var$3; + $chCl.$category0 = var$2; + if ($this.$containsAllSurrogates) + ju_BitSet_set0(var$3, 0, 2048); + $chCl.$mayContainSupplCodepoints = $this.$mayContainSupplCodepoints0; + return $chCl; +} +function jur_AbstractCharClass$LazyCategoryScope() { + var a = this; jur_AbstractCharClass$LazyCharClass.call(a); + a.$category1 = 0; + a.$mayContainSupplCodepoints1 = 0; + a.$containsAllSurrogates0 = 0; +} +function jur_AbstractCharClass$LazyCategoryScope__init_(var_0, var_1) { + var var_2 = new jur_AbstractCharClass$LazyCategoryScope(); + jur_AbstractCharClass$LazyCategoryScope__init_1(var_2, var_0, var_1); + return var_2; +} +function jur_AbstractCharClass$LazyCategoryScope__init_0(var_0, var_1, var_2) { + var var_3 = new jur_AbstractCharClass$LazyCategoryScope(); + jur_AbstractCharClass$LazyCategoryScope__init_2(var_3, var_0, var_1, var_2); + return var_3; +} +function jur_AbstractCharClass$LazyCategoryScope__init_1($this, $cat, $mayContainSupplCodepoints) { + $this.$mayContainSupplCodepoints1 = $mayContainSupplCodepoints; + $this.$category1 = $cat; +} +function jur_AbstractCharClass$LazyCategoryScope__init_2($this, $cat, $mayContainSupplCodepoints, $containsAllSurrogates) { + $this.$containsAllSurrogates0 = $containsAllSurrogates; + $this.$mayContainSupplCodepoints1 = $mayContainSupplCodepoints; + $this.$category1 = $cat; +} +function jur_AbstractCharClass$LazyCategoryScope_computeValue($this) { + var $chCl, var$2, var$3; + $chCl = new jur_UnicodeCategoryScope; + var$2 = $this.$category1; + var$3 = new ju_BitSet; + var$3.$data0 = $rt_createIntArray(64); + $chCl.$lowHighSurrogates = var$3; + $chCl.$category0 = var$2; + if ($this.$containsAllSurrogates0) + ju_BitSet_set0(var$3, 0, 2048); + $chCl.$mayContainSupplCodepoints = $this.$mayContainSupplCodepoints1; + return $chCl; +} +var otpp_ResourceAccessor = $rt_classWithoutFields(); +var otciu_UnicodeHelper = $rt_classWithoutFields(); +function otciu_UnicodeHelper_decodeIntPairsDiff($text) { + var $flow, $data, var$4, var$5, $sz, $j, $lastKey, $lastValue, $i, var$11, var$12; + $flow = new otci_CharFlow; + $data = $text.$characters.data; + var$4 = $rt_createCharArray($data.length); + var$5 = var$4.data; + $sz = 0; + $j = var$5.length; + while ($sz < $j) { + var$5[$sz] = $data[$sz]; + $sz = $sz + 1 | 0; + } + $flow.$characters0 = var$4; + $sz = otci_Base46_decodeUnsigned($flow); + $data = $rt_createIntArray($sz * 2 | 0); + var$4 = $data.data; + $j = 0; + $lastKey = 0; + $lastValue = 0; + $i = 0; + while ($i < $sz) { + var$11 = otci_Base46_decodeUnsigned($flow); + var$12 = var$11 / 2 | 0; + if (var$11 % 2 | 0) + var$12 = -var$12 | 0; + $lastKey = $lastKey + var$12 | 0; + var$11 = otci_Base46_decodeUnsigned($flow); + var$12 = var$11 / 2 | 0; + if (var$11 % 2 | 0) + var$12 = -var$12 | 0; + $lastValue = $lastValue + var$12 | 0; + var$12 = $j + 1 | 0; + var$4[$j] = $lastKey; + $j = var$12 + 1 | 0; + var$4[var$12] = $lastValue; + $i = $i + 1 | 0; + } + return $data; +} +function otciu_UnicodeHelper_decodeByte($c) { + if ($c > 92) + return (($c - 32 | 0) - 2 | 0) << 24 >> 24; + if ($c <= 34) + return ($c - 32 | 0) << 24 >> 24; + return (($c - 32 | 0) - 1 | 0) << 24 >> 24; +} +function otciu_UnicodeHelper_extractRle($encoded) { + var $ranges, var$3, var$4, $index, $rangeIndex, $codePoint, $i, $buffer, $digit, var$11, var$12, $b, $count, $pos, $j, var$17, var$18; + $ranges = $rt_createArray(otciu_UnicodeHelper$Range, 16384); + var$3 = $ranges.data; + var$4 = $rt_createByteArray(16384).data; + $index = 0; + $rangeIndex = 0; + $codePoint = 0; + $i = 0; + a: { + b: { + while (true) { + $buffer = $encoded.$characters.data; + $digit = $rt_compare($i, $buffer.length); + if ($digit >= 0) { + var$11 = $ranges.constructor; + if (var$11 === null) + $encoded = null; + else { + $encoded = var$11.classObject; + if ($encoded === null) { + $encoded = new jl_Class; + $encoded.$platformClass = var$11; + var$12 = $encoded; + var$11.classObject = var$12; + } + } + $encoded = jl_Class_getComponentType($encoded); + if ($encoded === null) { + $encoded = new jl_NullPointerException; + $encoded.$suppressionEnabled = 1; + $encoded.$writableStackTrace = 1; + $rt_throw($encoded); + } + if ($encoded === $rt_cls($rt_voidcls())) { + $encoded = new jl_IllegalArgumentException; + $encoded.$suppressionEnabled = 1; + $encoded.$writableStackTrace = 1; + $rt_throw($encoded); + } + if ($rangeIndex < 0) { + $encoded = new jl_NegativeArraySizeException; + $encoded.$suppressionEnabled = 1; + $encoded.$writableStackTrace = 1; + $rt_throw($encoded); + } + var$12 = jlr_Array_newInstanceImpl($encoded.$platformClass, $rangeIndex); + $index = var$3.length; + if ($rangeIndex < $index) + $index = $rangeIndex; + $rangeIndex = 0; + while ($rangeIndex < $index) { + var$12.data[$rangeIndex] = var$3[$rangeIndex]; + $rangeIndex = $rangeIndex + 1 | 0; + } + return var$12; + } + if ($i < 0) + break; + if ($digit >= 0) + break; + $b = otciu_UnicodeHelper_decodeByte($buffer[$i]); + if ($b == 64) { + $i = $i + 1 | 0; + if ($i < 0) + break b; + $buffer = $encoded.$characters.data; + if ($i >= $buffer.length) + break b; + $b = otciu_UnicodeHelper_decodeByte($buffer[$i]); + $count = 0; + $pos = 1; + $j = 0; + while ($j < 3) { + $i = $i + 1 | 0; + if ($i < 0) + break a; + $buffer = $encoded.$characters.data; + if ($i >= $buffer.length) + break a; + $count = $count | $rt_imul($pos, otciu_UnicodeHelper_decodeByte($buffer[$i])); + $pos = $pos * 64 | 0; + $j = $j + 1 | 0; + } + } else if ($b < 32) + $count = 1; + else { + $b = ($b - 32 | 0) << 24 >> 24; + $i = $i + 1 | 0; + $count = otciu_UnicodeHelper_decodeByte(jl_String_charAt($encoded, $i)); + } + if (!$b && $count >= 128) { + if ($index > 0) { + $digit = $rangeIndex + 1 | 0; + var$11 = new otciu_UnicodeHelper$Range; + $pos = $codePoint + $index | 0; + $buffer = $rt_createByteArray($index); + $j = var$4.length; + if ($index < $j) + $j = $index; + var$17 = $buffer.data; + var$18 = 0; + while (var$18 < $j) { + var$17[var$18] = var$4[var$18]; + var$18 = var$18 + 1 | 0; + } + var$11.$start = $codePoint; + var$11.$end = $pos; + var$11.$data = $buffer; + var$3[$rangeIndex] = var$11; + $rangeIndex = $digit; + } + $codePoint = $codePoint + ($index + $count | 0) | 0; + $index = 0; + } else { + $digit = $index + $count | 0; + $pos = var$4.length; + if ($digit < $pos) + $j = $rangeIndex; + else { + $j = $rangeIndex + 1 | 0; + var$11 = new otciu_UnicodeHelper$Range; + var$18 = $codePoint + $index | 0; + $buffer = $rt_createByteArray($index); + if ($index < $pos) + $pos = $index; + var$17 = $buffer.data; + $index = 0; + while ($index < $pos) { + var$17[$index] = var$4[$index]; + $index = $index + 1 | 0; + } + var$11.$start = $codePoint; + var$11.$end = var$18; + var$11.$data = $buffer; + var$3[$rangeIndex] = var$11; + $codePoint = $codePoint + $digit | 0; + $index = 0; + } + while (true) { + $rangeIndex = $count + (-1) | 0; + if ($count <= 0) + break; + $digit = $index + 1 | 0; + var$4[$index] = $b; + $index = $digit; + $count = $rangeIndex; + } + $rangeIndex = $j; + } + $i = $i + 1 | 0; + } + $encoded = new jl_StringIndexOutOfBoundsException; + $encoded.$suppressionEnabled = 1; + $encoded.$writableStackTrace = 1; + $rt_throw($encoded); + } + $encoded = new jl_StringIndexOutOfBoundsException; + $encoded.$suppressionEnabled = 1; + $encoded.$writableStackTrace = 1; + $rt_throw($encoded); + } + $encoded = new jl_StringIndexOutOfBoundsException; + $encoded.$suppressionEnabled = 1; + $encoded.$writableStackTrace = 1; + $rt_throw($encoded); +} +function otciu_UnicodeHelper$Range() { + var a = this; jl_Object.call(a); + a.$start = 0; + a.$end = 0; + a.$data = null; +} +function otci_CharFlow() { + var a = this; jl_Object.call(a); + a.$characters0 = null; + a.$pointer = 0; +} +var otci_Base46 = $rt_classWithoutFields(); +function otci_Base46_decodeUnsigned($seq) { + var $number, $pos, var$4, $hasMore, $digit; + $number = 0; + $pos = 1; + while (true) { + var$4 = $seq.$characters0.data; + $hasMore = $seq.$pointer; + $seq.$pointer = $hasMore + 1 | 0; + $digit = var$4[$hasMore]; + $digit = $digit < 34 ? $digit - 32 | 0 : $digit >= 92 ? ($digit - 32 | 0) - 2 | 0 : ($digit - 32 | 0) - 1 | 0; + $hasMore = ($digit % 2 | 0) != 1 ? 0 : 1; + $number = $number + $rt_imul($pos, $digit / 2 | 0) | 0; + $pos = $pos * 46 | 0; + if (!$hasMore) + break; + } + return $number; +} +function jur_AbstractCharClass$1() { + var a = this; jur_AbstractCharClass.call(a); + a.$val$lHS = null; + a.$this$0 = null; +} +function jur_AbstractCharClass$1_contains($this, $ch) { + var $index, var$3, var$4, var$5; + $index = $ch - 55296 | 0; + if ($index >= 0 && $index < 2048) { + $ch = $this.$altSurrogates; + var$3 = $this.$val$lHS; + var$4 = $index / 32 | 0; + var$5 = var$3.$data0.data; + $ch = $ch ^ (var$4 < var$5.length && var$5[var$4] & 1 << ($index % 32 | 0) ? 1 : 0); + } else + $ch = 0; + return $ch; +} +function jur_AbstractCharClass$2() { + var a = this; jur_AbstractCharClass.call(a); + a.$val$lHS0 = null; + a.$val$thisClass = null; + a.$this$00 = null; +} +function jur_AbstractCharClass$2_contains($this, $ch) { + var $index, var$3, var$4, $containslHS, var$6; + $index = $ch - 55296 | 0; + if ($index >= 0 && $index < 2048) { + var$3 = $this.$altSurrogates; + var$4 = $this.$val$lHS0; + $containslHS = $index / 32 | 0; + var$6 = var$4.$data0.data; + $containslHS = var$3 ^ ($containslHS < var$6.length && var$6[$containslHS] & 1 << ($index % 32 | 0) ? 1 : 0); + } else + $containslHS = 0; + return $this.$val$thisClass.$contains($ch) && !$containslHS ? 1 : 0; +} +function jur_CharClass$18() { + var a = this; jur_AbstractCharClass.call(a); + a.$val$bs = null; + a.$this$018 = null; +} +function jur_CharClass$18_contains($this, $ch) { + var var$2, var$3, var$4, var$5; + var$2 = $this.$alt0; + var$3 = $this.$val$bs; + var$4 = $ch / 32 | 0; + var$5 = var$3.$data0.data; + return var$2 ^ (var$4 < var$5.length && var$5[var$4] & 1 << ($ch % 32 | 0) ? 1 : 0); +} +function jur_CharClass$18_toString($this) { + var $temp, $i, var$3, var$4, var$5, var$6, var$7, var$8, var$9, var$10, var$11; + $temp = new jl_StringBuilder; + $temp.$buffer = $rt_createCharArray(16); + $i = ju_BitSet_nextSetBit($this.$val$bs, 0); + while ($i >= 0) { + if ($i < 65536) { + var$3 = $rt_createCharArray(1); + var$3.data[0] = $i & 65535; + } else + var$3 = $rt_createCharArrayFromData([(55296 | ($i - 65536 | 0) >> 10 & 1023) & 65535, (56320 | $i & 1023) & 65535]); + var$4 = var$3.data; + var$5 = 0; + var$6 = var$4.length; + var$7 = $temp.$length; + jl_AbstractStringBuilder_insertSpace($temp, var$7, var$7 + var$6 | 0); + var$6 = var$6 + var$5 | 0; + while (var$5 < var$6) { + var$3 = $temp.$buffer.data; + var$8 = var$7 + 1 | 0; + var$9 = var$5 + 1 | 0; + var$3[var$7] = var$4[var$5]; + var$7 = var$8; + var$5 = var$9; + } + var$6 = $temp.$length; + jl_AbstractStringBuilder_insertSpace($temp, var$6, var$6 + 1 | 0); + $temp.$buffer.data[var$6] = 124; + $i = ju_BitSet_nextSetBit($this.$val$bs, $i + 1 | 0); + } + var$7 = $temp.$length; + if (var$7 > 0) + jl_AbstractStringBuilder_deleteCharAt($temp, var$7 - 1 | 0); + var$10 = new jl_String; + var$3 = $temp.$buffer; + var$7 = $temp.$length; + var$4 = $rt_createCharArray(var$7); + var$11 = var$4.data; + var$10.$characters = var$4; + var$9 = 0; + while (var$9 < var$7) { + var$11[var$9] = var$3.data[var$9 + 0 | 0]; + var$9 = var$9 + 1 | 0; + } + return var$10; +} +function jur_CharClass$1() { + var a = this; jur_AbstractCharClass.call(a); + a.$val$cc1 = null; + a.$this$03 = null; +} +function jur_CharClass$1_contains($this, $ch) { + return $this.$val$cc1.$contains($ch); +} +function jur_CharClass$3() { + var a = this; jur_AbstractCharClass.call(a); + a.$val$curAlt1 = 0; + a.$val$cc2 = null; + a.$this$04 = null; +} +function jur_CharClass$3_contains($this, $ch) { + var var$2, var$3, var$4, var$5, var$6; + var$2 = $this.$val$curAlt1; + var$3 = $this.$this$04; + var$4 = var$3.$bits; + var$5 = $ch / 32 | 0; + var$6 = var$4.$data0.data; + var$5 = var$5 < var$6.length && var$6[var$5] & 1 << ($ch % 32 | 0) ? 1 : 0; + return !(var$2 ^ var$5) && !(var$2 ^ var$3.$inverted ^ $this.$val$cc2.$contains($ch)) ? 0 : 1; +} +function jur_CharClass$2() { + var a = this; jur_AbstractCharClass.call(a); + a.$val$curAlt2 = 0; + a.$val$cc3 = null; + a.$this$05 = null; +} +function jur_CharClass$2_contains($this, $ch) { + var var$2, var$3, var$4, var$5, var$6; + var$2 = $this.$val$curAlt2; + var$3 = $this.$this$05; + var$4 = var$3.$bits; + var$5 = $ch / 32 | 0; + var$6 = var$4.$data0.data; + var$5 = var$5 < var$6.length && var$6[var$5] & 1 << ($ch % 32 | 0) ? 1 : 0; + return !(var$2 ^ var$5) && !(var$2 ^ var$3.$inverted ^ $this.$val$cc3.$contains($ch)) ? 1 : 0; +} +function jur_CharClass$5() { + var a = this; jur_AbstractCharClass.call(a); + a.$val$curAlt = 0; + a.$val$nb = null; + a.$val$cc = null; + a.$this$01 = null; +} +function jur_CharClass$5_contains($this, $ch) { + return $this.$val$curAlt ^ (!$this.$val$nb.$contains($ch) && !$this.$val$cc.$contains($ch) ? 0 : 1); +} +function jur_CharClass$4() { + var a = this; jur_AbstractCharClass.call(a); + a.$val$curAlt0 = 0; + a.$val$nb0 = null; + a.$val$cc0 = null; + a.$this$02 = null; +} +function jur_CharClass$4_contains($this, $ch) { + return $this.$val$curAlt0 ^ (!$this.$val$nb0.$contains($ch) && !$this.$val$cc0.$contains($ch) ? 0 : 1) ? 0 : 1; +} +function jur_CharClass$7() { + var a = this; jur_AbstractCharClass.call(a); + a.$val$clazz1 = null; + a.$this$08 = null; +} +function jur_CharClass$7_contains($this, $ch) { + var var$2, var$3, var$4, var$5, var$6; + var$2 = $this.$val$clazz1; + var$3 = var$2.$nonBitSet; + if (var$3 !== null) + $ch = var$2.$alt0 ^ var$3.$contains($ch); + else { + var$4 = var$2.$alt0; + var$2 = var$2.$bits; + var$5 = $ch / 32 | 0; + var$6 = var$2.$data0.data; + $ch = var$4 ^ (var$5 < var$6.length && var$6[var$5] & 1 << ($ch % 32 | 0) ? 1 : 0); + } + return $ch; +} +function jur_CharClass$6() { + var a = this; jur_AbstractCharClass.call(a); + a.$val$clazz2 = null; + a.$this$09 = null; +} +function jur_CharClass$6_contains($this, $ch) { + var var$2, var$3, var$4, var$5, var$6; + var$2 = $this.$val$clazz2; + var$3 = var$2.$nonBitSet; + if (var$3 !== null) + $ch = var$2.$alt0 ^ var$3.$contains($ch); + else { + var$4 = var$2.$alt0; + var$2 = var$2.$bits; + var$5 = $ch / 32 | 0; + var$6 = var$2.$data0.data; + $ch = var$4 ^ (var$5 < var$6.length && var$6[var$5] & 1 << ($ch % 32 | 0) ? 1 : 0); + } + return $ch ? 0 : 1; +} +function jur_CharClass$9() { + var a = this; jur_AbstractCharClass.call(a); + a.$val$clazz3 = null; + a.$val$curAlt5 = 0; + a.$this$010 = null; +} +function jur_CharClass$9_contains($this, $ch) { + var var$2, var$3, var$4, var$5, var$6; + var$2 = $this.$val$clazz3; + var$3 = var$2.$nonBitSet; + if (var$3 !== null) + var$4 = var$2.$alt0 ^ var$3.$contains($ch); + else { + var$4 = var$2.$alt0; + var$2 = var$2.$bits; + var$5 = $ch / 32 | 0; + var$6 = var$2.$data0.data; + var$4 = var$4 ^ (var$5 < var$6.length && var$6[var$5] & 1 << ($ch % 32 | 0) ? 1 : 0); + } + a: { + if (!var$4) { + var$4 = $this.$val$curAlt5; + var$2 = $this.$this$010.$bits; + var$5 = $ch / 32 | 0; + var$6 = var$2.$data0.data; + if (!(var$4 ^ (var$5 < var$6.length && var$6[var$5] & 1 << ($ch % 32 | 0) ? 1 : 0))) { + $ch = 0; + break a; + } + } + $ch = 1; + } + return $ch; +} +function jur_CharClass$8() { + var a = this; jur_AbstractCharClass.call(a); + a.$val$clazz4 = null; + a.$val$curAlt6 = 0; + a.$this$011 = null; +} +function jur_CharClass$8_contains($this, $ch) { + var var$2, var$3, var$4, var$5, var$6; + var$2 = $this.$val$clazz4; + var$3 = var$2.$nonBitSet; + if (var$3 !== null) + var$4 = var$2.$alt0 ^ var$3.$contains($ch); + else { + var$4 = var$2.$alt0; + var$2 = var$2.$bits; + var$5 = $ch / 32 | 0; + var$6 = var$2.$data0.data; + var$4 = var$4 ^ (var$5 < var$6.length && var$6[var$5] & 1 << ($ch % 32 | 0) ? 1 : 0); + } + a: { + if (!var$4) { + var$4 = $this.$val$curAlt6; + var$2 = $this.$this$011.$bits; + var$5 = $ch / 32 | 0; + var$6 = var$2.$data0.data; + if (!(var$4 ^ (var$5 < var$6.length && var$6[var$5] & 1 << ($ch % 32 | 0) ? 1 : 0))) { + $ch = 1; + break a; + } + } + $ch = 0; + } + return $ch; +} +function jur_CharClass$11() { + var a = this; jur_AbstractCharClass.call(a); + a.$val$curAlt3 = 0; + a.$val$nb1 = null; + a.$val$clazz = null; + a.$this$06 = null; +} +function jur_CharClass$11_contains($this, $ch) { + var var$2, var$3, var$4, var$5, var$6; + a: { + if (!($this.$val$curAlt3 ^ $this.$val$nb1.$contains($ch))) { + var$2 = $this.$val$clazz; + var$3 = var$2.$nonBitSet; + if (var$3 !== null) + $ch = var$2.$alt0 ^ var$3.$contains($ch); + else { + var$4 = var$2.$alt0; + var$2 = var$2.$bits; + var$5 = $ch / 32 | 0; + var$6 = var$2.$data0.data; + $ch = var$4 ^ (var$5 < var$6.length && var$6[var$5] & 1 << ($ch % 32 | 0) ? 1 : 0); + } + if (!$ch) { + $ch = 0; + break a; + } + } + $ch = 1; + } + return $ch; +} +function jur_CharClass$10() { + var a = this; jur_AbstractCharClass.call(a); + a.$val$curAlt4 = 0; + a.$val$nb2 = null; + a.$val$clazz0 = null; + a.$this$07 = null; +} +function jur_CharClass$10_contains($this, $ch) { + var var$2, var$3, var$4, var$5, var$6; + a: { + if (!($this.$val$curAlt4 ^ $this.$val$nb2.$contains($ch))) { + var$2 = $this.$val$clazz0; + var$3 = var$2.$nonBitSet; + if (var$3 !== null) + $ch = var$2.$alt0 ^ var$3.$contains($ch); + else { + var$4 = var$2.$alt0; + var$2 = var$2.$bits; + var$5 = $ch / 32 | 0; + var$6 = var$2.$data0.data; + $ch = var$4 ^ (var$5 < var$6.length && var$6[var$5] & 1 << ($ch % 32 | 0) ? 1 : 0); + } + if (!$ch) { + $ch = 1; + break a; + } + } + $ch = 0; + } + return $ch; +} +function jur_CharClass$13() { + var a = this; jur_AbstractCharClass.call(a); + a.$val$clazz7 = null; + a.$this$014 = null; +} +function jur_CharClass$13_contains($this, $ch) { + var var$2, var$3, var$4, var$5, var$6; + var$2 = $this.$val$clazz7; + var$3 = var$2.$nonBitSet; + if (var$3 !== null) + $ch = var$2.$alt0 ^ var$3.$contains($ch); + else { + var$4 = var$2.$alt0; + var$2 = var$2.$bits; + var$5 = $ch / 32 | 0; + var$6 = var$2.$data0.data; + $ch = var$4 ^ (var$5 < var$6.length && var$6[var$5] & 1 << ($ch % 32 | 0) ? 1 : 0); + } + return $ch; +} +function jur_CharClass$12() { + var a = this; jur_AbstractCharClass.call(a); + a.$val$clazz8 = null; + a.$this$015 = null; +} +function jur_CharClass$12_contains($this, $ch) { + var var$2, var$3, var$4, var$5, var$6; + var$2 = $this.$val$clazz8; + var$3 = var$2.$nonBitSet; + if (var$3 !== null) + $ch = var$2.$alt0 ^ var$3.$contains($ch); + else { + var$4 = var$2.$alt0; + var$2 = var$2.$bits; + var$5 = $ch / 32 | 0; + var$6 = var$2.$data0.data; + $ch = var$4 ^ (var$5 < var$6.length && var$6[var$5] & 1 << ($ch % 32 | 0) ? 1 : 0); + } + return $ch ? 0 : 1; +} +function jur_CharClass$15() { + var a = this; jur_AbstractCharClass.call(a); + a.$val$clazz9 = null; + a.$val$curAlt9 = 0; + a.$this$016 = null; +} +function jur_CharClass$15_contains($this, $ch) { + var var$2, var$3, var$4, var$5, var$6; + var$2 = $this.$val$clazz9; + var$3 = var$2.$nonBitSet; + if (var$3 !== null) + var$4 = var$2.$alt0 ^ var$3.$contains($ch); + else { + var$4 = var$2.$alt0; + var$2 = var$2.$bits; + var$5 = $ch / 32 | 0; + var$6 = var$2.$data0.data; + var$4 = var$4 ^ (var$5 < var$6.length && var$6[var$5] & 1 << ($ch % 32 | 0) ? 1 : 0); + } + a: { + if (var$4) { + var$4 = $this.$val$curAlt9; + var$2 = $this.$this$016.$bits; + var$5 = $ch / 32 | 0; + var$6 = var$2.$data0.data; + if (var$4 ^ (var$5 < var$6.length && var$6[var$5] & 1 << ($ch % 32 | 0) ? 1 : 0)) { + $ch = 1; + break a; + } + } + $ch = 0; + } + return $ch; +} +function jur_CharClass$14() { + var a = this; jur_AbstractCharClass.call(a); + a.$val$clazz10 = null; + a.$val$curAlt10 = 0; + a.$this$017 = null; +} +function jur_CharClass$14_contains($this, $ch) { + var var$2, var$3, var$4, var$5, var$6; + var$2 = $this.$val$clazz10; + var$3 = var$2.$nonBitSet; + if (var$3 !== null) + var$4 = var$2.$alt0 ^ var$3.$contains($ch); + else { + var$4 = var$2.$alt0; + var$2 = var$2.$bits; + var$5 = $ch / 32 | 0; + var$6 = var$2.$data0.data; + var$4 = var$4 ^ (var$5 < var$6.length && var$6[var$5] & 1 << ($ch % 32 | 0) ? 1 : 0); + } + a: { + if (var$4) { + var$4 = $this.$val$curAlt10; + var$2 = $this.$this$017.$bits; + var$5 = $ch / 32 | 0; + var$6 = var$2.$data0.data; + if (var$4 ^ (var$5 < var$6.length && var$6[var$5] & 1 << ($ch % 32 | 0) ? 1 : 0)) { + $ch = 0; + break a; + } + } + $ch = 1; + } + return $ch; +} +function jur_CharClass$17() { + var a = this; jur_AbstractCharClass.call(a); + a.$val$curAlt7 = 0; + a.$val$nb3 = null; + a.$val$clazz5 = null; + a.$this$012 = null; +} +function jur_CharClass$17_contains($this, $ch) { + var var$2, var$3, var$4, var$5, var$6; + a: { + if ($this.$val$curAlt7 ^ $this.$val$nb3.$contains($ch)) { + var$2 = $this.$val$clazz5; + var$3 = var$2.$nonBitSet; + if (var$3 !== null) + $ch = var$2.$alt0 ^ var$3.$contains($ch); + else { + var$4 = var$2.$alt0; + var$2 = var$2.$bits; + var$5 = $ch / 32 | 0; + var$6 = var$2.$data0.data; + $ch = var$4 ^ (var$5 < var$6.length && var$6[var$5] & 1 << ($ch % 32 | 0) ? 1 : 0); + } + if ($ch) { + $ch = 1; + break a; + } + } + $ch = 0; + } + return $ch; +} +function jur_CharClass$16() { + var a = this; jur_AbstractCharClass.call(a); + a.$val$curAlt8 = 0; + a.$val$nb4 = null; + a.$val$clazz6 = null; + a.$this$013 = null; +} +function jur_CharClass$16_contains($this, $ch) { + var var$2, var$3, var$4, var$5, var$6; + a: { + if ($this.$val$curAlt8 ^ $this.$val$nb4.$contains($ch)) { + var$2 = $this.$val$clazz6; + var$3 = var$2.$nonBitSet; + if (var$3 !== null) + $ch = var$2.$alt0 ^ var$3.$contains($ch); + else { + var$4 = var$2.$alt0; + var$2 = var$2.$bits; + var$5 = $ch / 32 | 0; + var$6 = var$2.$data0.data; + $ch = var$4 ^ (var$5 < var$6.length && var$6[var$5] & 1 << ($ch % 32 | 0) ? 1 : 0); + } + if ($ch) { + $ch = 0; + break a; + } + } + $ch = 1; + } + return $ch; +} +var jur_BackReferencedSingleSet = $rt_classWithoutFields(jur_SingleSet); +function jur_BackReferencedSingleSet_find($this, $startSearch, $testString, $matchResult) { + var $res, $lastIndex, var$6, var$7, var$8, $saveStart; + $res = 0; + $lastIndex = $matchResult.$rightBound; + a: { + while (true) { + if ($startSearch > $lastIndex) { + $startSearch = $res; + break a; + } + var$6 = $this.$groupIndex0; + var$7 = $matchResult.$groupBounds.data; + var$8 = var$6 * 2 | 0; + $saveStart = var$7[var$8]; + var$7[var$8] = $startSearch; + $res = $this.$kid.$matches($startSearch, $testString, $matchResult); + if ($res >= 0) + break; + var$8 = $this.$groupIndex0; + $matchResult.$groupBounds.data[var$8 * 2 | 0] = $saveStart; + $startSearch = $startSearch + 1 | 0; + } + } + return $startSearch; +} +function jur_BackReferencedSingleSet_findBack($this, $stringIndex, $startSearch, $testString, $matchResult) { + var $res, var$6, var$7, var$8, $saveStart; + $res = 0; + a: { + while (true) { + if ($startSearch < $stringIndex) { + $startSearch = $res; + break a; + } + var$6 = $this.$groupIndex0; + var$7 = $matchResult.$groupBounds.data; + var$8 = var$6 * 2 | 0; + $saveStart = var$7[var$8]; + var$7[var$8] = $startSearch; + $res = $this.$kid.$matches($startSearch, $testString, $matchResult); + if ($res >= 0) + break; + var$8 = $this.$groupIndex0; + $matchResult.$groupBounds.data[var$8 * 2 | 0] = $saveStart; + $startSearch = $startSearch + (-1) | 0; + } + } + return $startSearch; +} +function jur_BackReferencedSingleSet_processBackRefReplacement($this) { + return null; +} +var ju_Iterator = $rt_classWithoutFields(0); +function ju_AbstractList$1() { + var a = this; jl_Object.call(a); + a.$index3 = 0; + a.$modCount0 = 0; + a.$size2 = 0; + a.$removeIndex = 0; + a.$this$035 = null; +} +var otcic_Console = $rt_classWithoutFields(); +var jur_MatchResult = $rt_classWithoutFields(0); +function jur_Matcher() { + var a = this; jl_Object.call(a); + a.$pat = null; + a.$start4 = null; + a.$string3 = null; + a.$matchResult = null; + a.$leftBound0 = 0; + a.$rightBound0 = 0; +} +function jur_Matcher__init_(var_0, var_1) { + var var_2 = new jur_Matcher(); + jur_Matcher__init_0(var_2, var_0, var_1); + return var_2; +} +function jur_Matcher_find0($this, $start) { + var var$2, $stringLength, var$4, var$5, var$6, var$7, var$8, var$9, var$10, var$11; + var$2 = $this.$string3; + $stringLength = var$2.$characters.data.length; + if ($start >= 0 && $start <= $stringLength) { + var$4 = $this.$matchResult; + var$4.$valid = 0; + var$4.$mode0 = 2; + var$5 = var$4.$groupBounds.data; + var$6 = 0; + var$7 = var$5.length; + if (var$6 > var$7) { + var$2 = new jl_IllegalArgumentException; + jl_Throwable__init_0(var$2); + $rt_throw(var$2); + } + while (var$6 < var$7) { + var$8 = var$6 + 1 | 0; + var$5[var$6] = (-1); + var$6 = var$8; + } + var$5 = var$4.$consumers.data; + var$6 = 0; + var$7 = var$5.length; + if (var$6 > var$7) { + var$2 = new jl_IllegalArgumentException; + jl_Throwable__init_0(var$2); + $rt_throw(var$2); + } + while (var$6 < var$7) { + var$8 = var$6 + 1 | 0; + var$5[var$6] = (-1); + var$6 = var$8; + } + var$4.$startIndex = var$4.$leftBound; + var$4.$mode0 = 1; + var$4.$startIndex = $start; + $stringLength = var$4.$previousMatch; + if ($stringLength < 0) + $stringLength = $start; + var$4.$previousMatch = $stringLength; + $start = $this.$start4.$find0($start, var$2, var$4); + if ($start == (-1)) + $this.$matchResult.$hitEnd = 1; + if ($start >= 0) { + var$2 = $this.$matchResult; + $start = var$2.$valid; + if ($start) { + var$5 = var$2.$groupBounds.data; + if (var$5[0] == (-1)) { + var$6 = var$2.$startIndex; + var$5[0] = var$6; + var$5[1] = var$6; + } + if (!$start) { + var$2 = new jl_IllegalStateException; + var$2.$suppressionEnabled = 1; + var$2.$writableStackTrace = 1; + $rt_throw(var$2); + } + if (0 < var$2.$groupCount) { + var$2.$previousMatch = var$5[1]; + return 1; + } + var$2 = new jl_IndexOutOfBoundsException; + var$4 = new jl_StringBuilder; + jl_Object__init_0(var$4); + var$4.$buffer = $rt_createCharArray(16); + jl_AbstractStringBuilder_insert0(var$4, var$4.$length, 0, 10); + var$9 = new jl_String; + var$5 = var$4.$buffer; + $stringLength = var$4.$length; + var$10 = $rt_createCharArray($stringLength); + var$11 = var$10.data; + var$9.$characters = var$10; + var$6 = 0; + while (var$6 < $stringLength) { + var$11[var$6] = var$5.data[var$6 + 0 | 0]; + var$6 = var$6 + 1 | 0; + } + var$2.$suppressionEnabled = 1; + var$2.$writableStackTrace = 1; + var$2.$message = var$9; + $rt_throw(var$2); + } + } + $this.$matchResult.$startIndex = (-1); + return 0; + } + var$2 = new jl_IndexOutOfBoundsException; + var$4 = new jl_StringBuilder; + var$4.$buffer = $rt_createCharArray(16); + jl_AbstractStringBuilder_insert0(var$4, var$4.$length, $start, 10); + var$9 = new jl_String; + var$5 = var$4.$buffer; + $stringLength = var$4.$length; + var$10 = $rt_createCharArray($stringLength); + var$11 = var$10.data; + var$9.$characters = var$10; + var$6 = 0; + while (var$6 < $stringLength) { + var$11[var$6] = var$5.data[var$6 + 0 | 0]; + var$6 = var$6 + 1 | 0; + } + var$2.$suppressionEnabled = 1; + var$2.$writableStackTrace = 1; + var$2.$message = var$9; + $rt_throw(var$2); +} +function jur_Matcher_find($this) { + var $length, var$2, var$3, var$4, var$5, var$6, var$7, var$8, var$9, var$10, var$11, var$12; + $length = $this.$string3.$characters.data.length; + var$2 = $this.$matchResult; + if (!var$2.$transparentBounds) + $length = $this.$rightBound0; + if (var$2.$startIndex >= 0 && var$2.$mode0 == 1) { + var$3 = var$2.$valid; + if (!var$3) { + var$2 = new jl_IllegalStateException; + var$2.$suppressionEnabled = 1; + var$2.$writableStackTrace = 1; + $rt_throw(var$2); + } + var$4 = $rt_compare(0, var$2.$groupCount); + if (var$4 >= 0) { + var$2 = new jl_IndexOutOfBoundsException; + var$5 = new jl_StringBuilder; + var$5.$buffer = $rt_createCharArray(16); + jl_AbstractStringBuilder_insert0(var$5, var$5.$length, 0, 10); + var$6 = new jl_String; + var$7 = var$5.$buffer; + $length = var$5.$length; + var$8 = $rt_createCharArray($length); + var$9 = var$8.data; + var$6.$characters = var$8; + var$10 = 0; + while (var$10 < $length) { + var$9[var$10] = var$7.data[var$10 + 0 | 0]; + var$10 = var$10 + 1 | 0; + } + var$2.$suppressionEnabled = 1; + var$2.$writableStackTrace = 1; + var$2.$message = var$6; + $rt_throw(var$2); + } + var$7 = var$2.$groupBounds.data; + var$11 = var$7[1]; + var$2.$startIndex = var$11; + if (!var$3) { + var$2 = new jl_IllegalStateException; + var$2.$suppressionEnabled = 1; + var$2.$writableStackTrace = 1; + $rt_throw(var$2); + } + if (var$4 >= 0) { + var$2 = new jl_IndexOutOfBoundsException; + var$5 = new jl_StringBuilder; + var$5.$buffer = $rt_createCharArray(16); + jl_AbstractStringBuilder_insert0(var$5, var$5.$length, 0, 10); + var$6 = new jl_String; + var$7 = var$5.$buffer; + $length = var$5.$length; + var$8 = $rt_createCharArray($length); + var$9 = var$8.data; + var$6.$characters = var$8; + var$10 = 0; + while (var$10 < $length) { + var$9[var$10] = var$7.data[var$10 + 0 | 0]; + var$10 = var$10 + 1 | 0; + } + var$2.$suppressionEnabled = 1; + var$2.$writableStackTrace = 1; + var$2.$message = var$6; + $rt_throw(var$2); + } + var$10 = var$7[1]; + if (!var$3) { + var$2 = new jl_IllegalStateException; + var$2.$suppressionEnabled = 1; + var$2.$writableStackTrace = 1; + $rt_throw(var$2); + } + if (var$4 < 0) { + if (var$10 == var$7[0]) + var$2.$startIndex = var$11 + 1 | 0; + var$12 = var$2.$startIndex; + return var$12 <= $length && jur_Matcher_find0($this, var$12) ? 1 : 0; + } + var$2 = new jl_IndexOutOfBoundsException; + var$5 = new jl_StringBuilder; + var$5.$buffer = $rt_createCharArray(16); + jl_AbstractStringBuilder_insert0(var$5, var$5.$length, 0, 10); + var$6 = new jl_String; + var$7 = var$5.$buffer; + $length = var$5.$length; + var$8 = $rt_createCharArray($length); + var$9 = var$8.data; + var$6.$characters = var$8; + var$10 = 0; + while (var$10 < $length) { + var$9[var$10] = var$7.data[var$10 + 0 | 0]; + var$10 = var$10 + 1 | 0; + } + var$2.$suppressionEnabled = 1; + var$2.$writableStackTrace = 1; + var$2.$message = var$6; + $rt_throw(var$2); + } + return jur_Matcher_find0($this, $this.$leftBound0); +} +function jur_Matcher__init_0($this, $pat, $cs) { + var var$3; + $this.$leftBound0 = (-1); + $this.$rightBound0 = (-1); + $this.$pat = $pat; + $this.$start4 = $pat.$start2; + $this.$string3 = $cs; + $this.$leftBound0 = 0; + var$3 = $cs.$characters.data.length; + $this.$rightBound0 = var$3; + $this.$matchResult = jur_MatchResultImpl__init_($cs, 0, var$3, $pat.$globalGroupIndex, $pat.$compCount + 1 | 0, $pat.$consCount + 1 | 0); +} +var jnc_CoderMalfunctionError = $rt_classWithoutFields(jl_Error); +function jur_AbstractCharClass$LazyJavaLowerCase$1() { + jur_AbstractCharClass.call(this); + this.$this$019 = null; +} +function jur_AbstractCharClass$LazyJavaLowerCase$1_contains($this, $ch) { + return jl_Character_getType($ch) != 2 ? 0 : 1; +} +function jur_AbstractCharClass$LazyJavaUpperCase$1() { + jur_AbstractCharClass.call(this); + this.$this$020 = null; +} +function jur_AbstractCharClass$LazyJavaUpperCase$1_contains($this, $ch) { + return jl_Character_getType($ch) != 1 ? 0 : 1; +} +function jur_AbstractCharClass$LazyJavaWhitespace$1() { + jur_AbstractCharClass.call(this); + this.$this$021 = null; +} +function jur_AbstractCharClass$LazyJavaWhitespace$1_contains($this, $ch) { + a: { + switch ($ch) { + case 9: + case 10: + case 11: + case 12: + case 13: + case 28: + case 29: + case 30: + case 31: + break; + case 160: + case 8199: + case 8239: + $ch = 0; + break a; + default: + b: { + switch (jl_Character_getType($ch)) { + case 12: + case 13: + case 14: + break; + default: + $ch = 0; + break b; + } + $ch = 1; + } + break a; + } + $ch = 1; + } + return $ch; +} +function jur_AbstractCharClass$LazyJavaMirrored$1() { + jur_AbstractCharClass.call(this); + this.$this$022 = null; +} +function jur_AbstractCharClass$LazyJavaMirrored$1_contains($this, $ch) { + return 0; +} +function jur_AbstractCharClass$LazyJavaDefined$1() { + jur_AbstractCharClass.call(this); + this.$this$023 = null; +} +function jur_AbstractCharClass$LazyJavaDefined$1_contains($this, $ch) { + return !jl_Character_getType($ch) ? 0 : 1; +} +function jur_AbstractCharClass$LazyJavaDigit$1() { + jur_AbstractCharClass.call(this); + this.$this$024 = null; +} +function jur_AbstractCharClass$LazyJavaDigit$1_contains($this, $ch) { + return jl_Character_getType($ch) != 9 ? 0 : 1; +} +function jur_AbstractCharClass$LazyJavaIdentifierIgnorable$1() { + jur_AbstractCharClass.call(this); + this.$this$025 = null; +} +function jur_AbstractCharClass$LazyJavaIdentifierIgnorable$1_contains($this, $ch) { + return jl_Character_isIdentifierIgnorable($ch); +} +function jur_AbstractCharClass$LazyJavaISOControl$1() { + jur_AbstractCharClass.call(this); + this.$this$026 = null; +} +function jur_AbstractCharClass$LazyJavaISOControl$1_contains($this, $ch) { + a: { + b: { + if (!($ch >= 0 && $ch <= 31)) { + if ($ch < 127) + break b; + if ($ch > 159) + break b; + } + $ch = 1; + break a; + } + $ch = 0; + } + return $ch; +} +function jur_AbstractCharClass$LazyJavaJavaIdentifierPart$1() { + jur_AbstractCharClass.call(this); + this.$this$027 = null; +} +function jur_AbstractCharClass$LazyJavaJavaIdentifierPart$1_contains($this, $ch) { + a: { + b: { + switch (jl_Character_getType($ch)) { + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 8: + case 9: + case 10: + case 23: + case 26: + break; + case 7: + case 11: + case 12: + case 13: + case 14: + case 15: + case 16: + case 17: + case 18: + case 19: + case 20: + case 21: + case 22: + case 24: + case 25: + break b; + default: + break b; + } + $ch = 1; + break a; + } + $ch = jl_Character_isIdentifierIgnorable($ch); + } + return $ch; +} +function jur_AbstractCharClass$LazyJavaJavaIdentifierStart$1() { + jur_AbstractCharClass.call(this); + this.$this$028 = null; +} +function jur_AbstractCharClass$LazyJavaJavaIdentifierStart$1_contains($this, $ch) { + a: { + b: { + switch (jl_Character_getType($ch)) { + case 1: + case 2: + case 3: + case 4: + case 5: + case 10: + case 23: + case 26: + break; + case 6: + case 7: + case 8: + case 9: + case 11: + case 12: + case 13: + case 14: + case 15: + case 16: + case 17: + case 18: + case 19: + case 20: + case 21: + case 22: + case 24: + case 25: + break b; + default: + break b; + } + $ch = 1; + break a; + } + $ch = jl_Character_isIdentifierIgnorable($ch); + } + return $ch; +} +function jur_AbstractCharClass$LazyJavaLetter$1() { + jur_AbstractCharClass.call(this); + this.$this$029 = null; +} +function jur_AbstractCharClass$LazyJavaLetter$1_contains($this, $ch) { + a: { + switch (jl_Character_getType($ch)) { + case 1: + case 2: + case 3: + case 4: + case 5: + break; + default: + $ch = 0; + break a; + } + $ch = 1; + } + return $ch; +} +function jur_AbstractCharClass$LazyJavaLetterOrDigit$1() { + jur_AbstractCharClass.call(this); + this.$this$030 = null; +} +function jur_AbstractCharClass$LazyJavaLetterOrDigit$1_contains($this, $ch) { + a: { + b: { + switch (jl_Character_getType($ch)) { + case 1: + case 2: + case 3: + case 4: + case 5: + case 9: + break; + case 6: + case 7: + case 8: + break b; + default: + break b; + } + $ch = 1; + break a; + } + $ch = 0; + } + return $ch; +} +function jur_AbstractCharClass$LazyJavaSpaceChar$1() { + jur_AbstractCharClass.call(this); + this.$this$031 = null; +} +function jur_AbstractCharClass$LazyJavaSpaceChar$1_contains($this, $ch) { + a: { + switch (jl_Character_getType($ch)) { + case 12: + case 13: + case 14: + break; + default: + $ch = 0; + break a; + } + $ch = 1; + } + return $ch; +} +function jur_AbstractCharClass$LazyJavaTitleCase$1() { + jur_AbstractCharClass.call(this); + this.$this$032 = null; +} +function jur_AbstractCharClass$LazyJavaTitleCase$1_contains($this, $ch) { + return jl_Character_getType($ch) != 3 ? 0 : 1; +} +function jur_AbstractCharClass$LazyJavaUnicodeIdentifierPart$1() { + jur_AbstractCharClass.call(this); + this.$this$033 = null; +} +function jur_AbstractCharClass$LazyJavaUnicodeIdentifierPart$1_contains($this, $ch) { + a: { + b: { + switch (jl_Character_getType($ch)) { + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 8: + case 9: + case 10: + case 23: + break; + case 7: + case 11: + case 12: + case 13: + case 14: + case 15: + case 16: + case 17: + case 18: + case 19: + case 20: + case 21: + case 22: + break b; + default: + break b; + } + $ch = 1; + break a; + } + $ch = jl_Character_isIdentifierIgnorable($ch); + } + return $ch; +} +function jur_AbstractCharClass$LazyJavaUnicodeIdentifierStart$1() { + jur_AbstractCharClass.call(this); + this.$this$034 = null; +} +function jur_AbstractCharClass$LazyJavaUnicodeIdentifierStart$1_contains($this, $ch) { + a: { + b: { + switch (jl_Character_getType($ch)) { + case 1: + case 2: + case 3: + case 4: + case 5: + case 10: + break; + case 6: + case 7: + case 8: + case 9: + break b; + default: + break b; + } + $ch = 1; + break a; + } + $ch = jl_Character_isIdentifierIgnorable($ch); + } + return $ch; +} +function jur_UnicodeCategory() { + jur_AbstractCharClass.call(this); + this.$category0 = 0; +} +function jur_UnicodeCategory_contains($this, $ch) { + return $this.$alt0 ^ ($this.$category0 != jl_Character_getType($ch & 65535) ? 0 : 1); +} +var jur_UnicodeCategoryScope = $rt_classWithoutFields(jur_UnicodeCategory); +function jur_UnicodeCategoryScope_contains($this, $ch) { + return $this.$alt0 ^ (!($this.$category0 >> jl_Character_getType($ch & 65535) & 1) ? 0 : 1); +} +var ju_ConcurrentModificationException = $rt_classWithoutFields(jl_RuntimeException); +function jur_MatchResultImpl() { + var a = this; jl_Object.call(a); + a.$groupBounds = null; + a.$consumers = null; + a.$compQuantCounters = null; + a.$string0 = null; + a.$groupCount = 0; + a.$valid = 0; + a.$leftBound = 0; + a.$rightBound = 0; + a.$startIndex = 0; + a.$transparentBounds = 0; + a.$anchoringBounds = 0; + a.$hitEnd = 0; + a.$requireEnd = 0; + a.$previousMatch = 0; + a.$mode0 = 0; +} +function jur_MatchResultImpl__init_(var_0, var_1, var_2, var_3, var_4, var_5) { + var var_6 = new jur_MatchResultImpl(); + jur_MatchResultImpl__init_0(var_6, var_0, var_1, var_2, var_3, var_4, var_5); + return var_6; +} +function jur_MatchResultImpl__init_0($this, $string, $leftBound, $rightBound, $groupCount, $compQuantCount, $consumersCount) { + var var$7, var$8, var$9, var$10, var$11, var$12; + $this.$previousMatch = (-1); + var$7 = $groupCount + 1 | 0; + $this.$groupCount = var$7; + var$8 = $rt_createIntArray(var$7 * 2 | 0); + $this.$groupBounds = var$8; + var$9 = $rt_createIntArray($consumersCount); + var$10 = var$9.data; + $this.$consumers = var$9; + $groupCount = 0; + $consumersCount = var$10.length; + var$11 = $rt_compare($groupCount, $consumersCount); + if (var$11 > 0) { + $string = new jl_IllegalArgumentException; + $string.$suppressionEnabled = 1; + $string.$writableStackTrace = 1; + $rt_throw($string); + } + while ($groupCount < $consumersCount) { + var$7 = $groupCount + 1 | 0; + var$10[$groupCount] = (-1); + $groupCount = var$7; + } + if ($compQuantCount > 0) + $this.$compQuantCounters = $rt_createIntArray($compQuantCount); + var$8 = var$8.data; + var$7 = 0; + var$12 = var$8.length; + $groupCount = $rt_compare(var$7, var$12); + if ($groupCount > 0) { + $string = new jl_IllegalArgumentException; + $string.$suppressionEnabled = 1; + $string.$writableStackTrace = 1; + $rt_throw($string); + } + while (var$7 < var$12) { + $compQuantCount = var$7 + 1 | 0; + var$8[var$7] = (-1); + var$7 = $compQuantCount; + } + $this.$valid = 0; + $this.$mode0 = 2; + $compQuantCount = 0; + if ($groupCount > 0) { + $string = new jl_IllegalArgumentException; + $string.$suppressionEnabled = 1; + $string.$writableStackTrace = 1; + $rt_throw($string); + } + while ($compQuantCount < var$12) { + $groupCount = $compQuantCount + 1 | 0; + var$8[$compQuantCount] = (-1); + $compQuantCount = $groupCount; + } + $groupCount = 0; + if (var$11 > 0) { + $string = new jl_IllegalArgumentException; + $string.$suppressionEnabled = 1; + $string.$writableStackTrace = 1; + $rt_throw($string); + } + while ($groupCount < $consumersCount) { + var$7 = $groupCount + 1 | 0; + var$10[$groupCount] = (-1); + $groupCount = var$7; + } + if ($string !== null) + $this.$string0 = $string; + if ($leftBound >= 0) { + $this.$leftBound = $leftBound; + $this.$rightBound = $rightBound; + } + $this.$startIndex = $this.$leftBound; +} +var jl_UnsupportedOperationException = $rt_classWithoutFields(jl_RuntimeException); +function jnci_BufferedEncoder$Controller() { + var a = this; jl_Object.call(a); + a.$in = null; + a.$out1 = null; + a.$inPosition = 0; + a.$outPosition = 0; +} +var jn_ReadOnlyBufferException = $rt_classWithoutFields(jl_UnsupportedOperationException); +var jn_BufferOverflowException = $rt_classWithoutFields(jl_RuntimeException); +var jn_BufferUnderflowException = $rt_classWithoutFields(jl_RuntimeException); +var jur_IntArrHash = $rt_classWithoutFields(); +$rt_packages([-1, "java", 0, "util", 1, "regex", 0, "lang" +]); +$rt_metadata([jl_Object, "Object", 3, 0, [], 0, 3, 0, 0, ["$toString", $rt_wrapFunction0(jl_Object_toString)], +nles_IntegratedServer, 0, jl_Object, [], 0, 3, 0, 0, 0, +jlr_AnnotatedElement, 0, jl_Object, [], 3, 3, 0, 0, 0, +jlr_Type, 0, jl_Object, [], 3, 3, 0, 0, 0, +jl_Class, 0, jl_Object, [jlr_AnnotatedElement, jlr_Type], 0, 3, 0, 0, 0, +otji_JS, 0, jl_Object, [], 4, 0, 0, 0, 0, +otp_Platform, 0, jl_Object, [], 4, 3, 0, 0, 0, +ji_Serializable, 0, jl_Object, [], 3, 3, 0, 0, 0, +jl_Comparable, 0, jl_Object, [], 3, 3, 0, 0, 0, +jl_CharSequence, 0, jl_Object, [], 3, 3, 0, 0, 0, +jl_String, 0, jl_Object, [ji_Serializable, jl_Comparable, jl_CharSequence], 0, 3, 0, 0, ["$toString", $rt_wrapFunction0(jl_String_toString)], +jl_Throwable, 0, jl_Object, [], 0, 3, 0, 0, 0, +jl_Error, 0, jl_Throwable, [], 0, 3, 0, 0, 0, +jl_LinkageError, 0, jl_Error, [], 0, 3, 0, 0, 0, +jl_NoClassDefFoundError, 0, jl_LinkageError, [], 0, 3, 0, 0, 0, +jl_AbstractStringBuilder, 0, jl_Object, [ji_Serializable, jl_CharSequence], 0, 0, 0, 0, ["$ensureCapacity", $rt_wrapFunction1(jl_AbstractStringBuilder_ensureCapacity), "$toString", $rt_wrapFunction0(jl_AbstractStringBuilder_toString)], +jl_Appendable, 0, jl_Object, [], 3, 3, 0, 0, 0, +jl_StringBuilder, 0, jl_AbstractStringBuilder, [jl_Appendable], 0, 3, 0, 0, ["$insert1", $rt_wrapFunction4(jl_StringBuilder_insert), "$append2", $rt_wrapFunction3(jl_StringBuilder_append0), "$toString", $rt_wrapFunction0(jl_StringBuilder_toString), "$ensureCapacity", $rt_wrapFunction1(jl_StringBuilder_ensureCapacity), "$insert2", $rt_wrapFunction2(jl_StringBuilder_insert0)], +jl_Number, 0, jl_Object, [ji_Serializable], 1, 3, 0, 0, 0, +jl_Integer, 0, jl_Number, [jl_Comparable], 0, 3, 0, 0, 0, +jl_IncompatibleClassChangeError, 0, jl_LinkageError, [], 0, 3, 0, 0, 0, +jl_NoSuchFieldError, 0, jl_IncompatibleClassChangeError, [], 0, 3, 0, 0, 0, +jl_NoSuchMethodError, 0, jl_IncompatibleClassChangeError, [], 0, 3, 0, 0, 0, +jl_Exception, 0, jl_Throwable, [], 0, 3, 0, 0, 0, +jl_RuntimeException, 0, jl_Exception, [], 0, 3, 0, 0, 0, +nles_SYS, 0, jl_Object, [], 0, 3, 0, nles_SYS_$callClinit, 0, +nles_VFSTestClass, 0, jl_Object, [], 0, 3, 0, 0, 0, +otci_IntegerUtil, 0, jl_Object, [], 4, 3, 0, 0, 0, +nles_VFile, 0, jl_Object, [], 0, 3, 0, 0, ["$toString", $rt_wrapFunction0(nles_VFile_toString)], +jl_System, 0, jl_Object, [], 4, 3, 0, 0, 0, +ju_Comparator, 0, jl_Object, [], 3, 3, 0, 0, 0, +jl_String$_clinit_$lambda$_84_0, 0, jl_Object, [ju_Comparator], 0, 3, 0, 0, 0, +jl_Character, 0, jl_Object, [jl_Comparable], 0, 3, 0, 0, 0, +nles_BooleanResult, 0, jl_Object, [], 0, 3, 0, 0, 0, +nles_VirtualFilesystem, 0, jl_Object, [], 0, 3, 0, 0, 0, +nles_VirtualFilesystem$VFSHandle, 0, jl_Object, [], 0, 3, 0, 0, 0, +otj_JSObject, 0, jl_Object, [], 3, 3, 0, 0, 0, +otjde_EventTarget, 0, jl_Object, [otj_JSObject], 3, 3, 0, 0, 0, +otjde_FocusEventTarget, 0, jl_Object, [otjde_EventTarget], 3, 3, 0, 0, 0, +otjde_MouseEventTarget, 0, jl_Object, [otjde_EventTarget], 3, 3, 0, 0, 0, +otjde_KeyboardEventTarget, 0, jl_Object, [otjde_EventTarget], 3, 3, 0, 0, 0, +otjde_LoadEventTarget, 0, jl_Object, [otjde_EventTarget], 3, 3, 0, 0, 0, +otjde_GamepadEventTarget, 0, jl_Object, [otjde_EventTarget], 3, 3, 0, 0, 0, +otjb_WindowEventTarget, 0, jl_Object, [otjde_EventTarget, otjde_FocusEventTarget, otjde_MouseEventTarget, otjde_KeyboardEventTarget, otjde_LoadEventTarget, otjde_GamepadEventTarget], 3, 3, 0, 0, 0, +otjb_StorageProvider, 0, jl_Object, [], 3, 3, 0, 0, 0, +otjc_JSArrayReader, 0, jl_Object, [otj_JSObject], 3, 3, 0, 0, 0, +otjb_Window, 0, jl_Object, [otj_JSObject, otjb_WindowEventTarget, otjb_StorageProvider, otjc_JSArrayReader], 1, 3, 0, 0, ["$addEventListener$exported$0", $rt_wrapFunction2(otjb_Window_addEventListener$exported$0), "$removeEventListener$exported$1", $rt_wrapFunction2(otjb_Window_removeEventListener$exported$1), "$get$exported$2", $rt_wrapFunction1(otjb_Window_get$exported$2), "$removeEventListener$exported$3", $rt_wrapFunction3(otjb_Window_removeEventListener$exported$3), "$dispatchEvent$exported$4", $rt_wrapFunction1(otjb_Window_dispatchEvent$exported$4), +"$getLength$exported$5", $rt_wrapFunction0(otjb_Window_getLength$exported$5), "$addEventListener$exported$6", $rt_wrapFunction3(otjb_Window_addEventListener$exported$6)], +jl_AutoCloseable, 0, jl_Object, [], 3, 3, 0, 0, 0, +ji_Closeable, 0, jl_Object, [jl_AutoCloseable], 3, 3, 0, 0, 0, +ji_Flushable, 0, jl_Object, [], 3, 3, 0, 0, 0]); +$rt_metadata([ji_OutputStream, 0, jl_Object, [ji_Closeable, ji_Flushable], 1, 3, 0, 0, 0, +ji_FilterOutputStream, 0, ji_OutputStream, [], 0, 3, 0, 0, 0, +ji_PrintStream, 0, ji_FilterOutputStream, [], 0, 3, 0, 0, 0, +otcic_StdoutOutputStream, 0, ji_OutputStream, [], 0, 3, 0, 0, 0, +oti_AsyncCallback, 0, jl_Object, [], 3, 3, 0, 0, 0, +otpp_AsyncCallbackWrapper, 0, jl_Object, [oti_AsyncCallback], 0, 0, 0, 0, ["$complete", $rt_wrapFunction1(otpp_AsyncCallbackWrapper_complete), "$error", $rt_wrapFunction1(otpp_AsyncCallbackWrapper_error)], +nles_SYS$PromiseHandler, 0, jl_Object, [otj_JSObject], 3, 0, 0, 0, 0, +nles_SYS$requestPersist$lambda$_2_0, 0, jl_Object, [nles_SYS$PromiseHandler], 0, 3, 0, 0, ["$complete$exported$0", $rt_wrapFunction1(nles_SYS$requestPersist$lambda$_2_0_complete$exported$0)], +nles_VirtualFilesystem$AsyncHandlers, 0, jl_Object, [], 0, 3, 0, 0, 0, +nles_VirtualFilesystem$DatabaseOpen, 0, jl_Object, [], 0, 3, 0, 0, 0, +jl_Iterable, 0, jl_Object, [], 3, 3, 0, 0, 0, +ju_Collection, 0, jl_Object, [jl_Iterable], 3, 3, 0, 0, 0, +ju_AbstractCollection, 0, jl_Object, [ju_Collection], 1, 3, 0, 0, 0, +ju_List, 0, jl_Object, [ju_Collection], 3, 3, 0, 0, 0, +ju_AbstractList, 0, ju_AbstractCollection, [ju_List], 1, 3, 0, 0, 0, +jl_Cloneable, 0, jl_Object, [], 3, 3, 0, 0, 0, +ju_RandomAccess, 0, jl_Object, [], 3, 3, 0, 0, 0, +ju_ArrayList, 0, ju_AbstractList, [jl_Cloneable, ji_Serializable, ju_RandomAccess], 0, 3, 0, 0, 0, +jnc_Charset, 0, jl_Object, [jl_Comparable], 1, 3, 0, 0, 0, +jnci_UTF8Charset, 0, jnc_Charset, [], 0, 3, 0, 0, 0, +otji_EventHandler, 0, jl_Object, [otj_JSObject], 3, 3, 0, 0, 0, +nles_VirtualFilesystem$AsyncHandlers$1, 0, jl_Object, [otji_EventHandler], 0, 0, 0, 0, ["$handleEvent$exported$0", $rt_wrapFunction0(nles_VirtualFilesystem$AsyncHandlers$1_handleEvent$exported$0)], +nles_VirtualFilesystem$AsyncHandlers$2, 0, jl_Object, [otji_EventHandler], 0, 0, 0, 0, ["$handleEvent$exported$0", $rt_wrapFunction0(nles_VirtualFilesystem$AsyncHandlers$2_handleEvent$exported$0)], +nles_VirtualFilesystem$AsyncHandlers$3, 0, jl_Object, [otji_EventHandler], 0, 0, 0, 0, ["$handleEvent$exported$0", $rt_wrapFunction0(nles_VirtualFilesystem$AsyncHandlers$3_handleEvent$exported$0)], +otjde_EventListener, 0, jl_Object, [otj_JSObject], 3, 3, 0, 0, 0, +nles_VirtualFilesystem$AsyncHandlers$4, 0, jl_Object, [otjde_EventListener], 0, 0, 0, 0, ["$handleEvent$exported$00", $rt_wrapFunction1(nles_VirtualFilesystem$AsyncHandlers$4_handleEvent$exported$0)], +otji_IDBFactory, 0, jl_Object, [otj_JSObject], 1, 3, 0, 0, 0, +ju_Map, 0, jl_Object, [], 3, 3, 0, 0, 0, +ju_AbstractMap, 0, jl_Object, [ju_Map], 1, 3, 0, 0, 0, +ju_HashMap, 0, ju_AbstractMap, [jl_Cloneable, ji_Serializable], 0, 3, 0, 0, 0, +jl_IllegalStateException, "IllegalStateException", 3, jl_Exception, [], 0, 3, 0, 0, 0, +jl_IllegalArgumentException, 0, jl_RuntimeException, [], 0, 3, 0, 0, 0, +jnc_IllegalCharsetNameException, 0, jl_IllegalArgumentException, [], 0, 3, 0, 0, 0, +jl_CloneNotSupportedException, 0, jl_Exception, [], 0, 3, 0, 0, 0, +jl_IndexOutOfBoundsException, 0, jl_RuntimeException, [], 0, 3, 0, 0, 0, +jl_StringIndexOutOfBoundsException, 0, jl_IndexOutOfBoundsException, [], 0, 3, 0, 0, 0, +ju_Map$Entry, 0, jl_Object, [], 3, 3, 0, 0, 0, +ju_MapEntry, 0, jl_Object, [ju_Map$Entry, jl_Cloneable], 0, 0, 0, 0, 0, +ju_HashMap$HashEntry, 0, ju_MapEntry, [], 0, 0, 0, 0, 0, +jn_Buffer, 0, jl_Object, [], 1, 3, 0, 0, 0, +jl_Readable, 0, jl_Object, [], 3, 3, 0, 0, 0, +jn_CharBuffer, 0, jn_Buffer, [jl_Comparable, jl_Appendable, jl_CharSequence, jl_Readable], 1, 3, 0, 0, 0, +jl_Math, 0, jl_Object, [], 4, 3, 0, 0, 0, +jn_ByteBuffer, 0, jn_Buffer, [jl_Comparable], 1, 3, 0, 0, 0, +jnc_CodingErrorAction, 0, jl_Object, [], 0, 3, 0, 0, 0, +jn_CharBufferImpl, 0, jn_CharBuffer, [], 1, 0, 0, 0, 0, +jn_CharBufferOverArray, 0, jn_CharBufferImpl, [], 0, 0, 0, 0, 0, +jnc_CharsetEncoder, 0, jl_Object, [], 1, 3, 0, 0, 0, +jnc_CoderResult, 0, jl_Object, [], 0, 3, 0, 0, 0, +jn_ByteBufferImpl, 0, jn_ByteBuffer, [], 0, 0, 0, 0, 0]); +$rt_metadata([jn_ByteOrder, 0, jl_Object, [], 4, 3, 0, 0, 0, +jur_Pattern, 0, jl_Object, [ji_Serializable], 4, 3, 0, 0, 0, +ju_Arrays, 0, jl_Object, [], 0, 3, 0, 0, 0, +otji_IDBObjectStoreParameters, 0, jl_Object, [otj_JSObject], 1, 3, 0, 0, 0, +jnci_BufferedEncoder, 0, jnc_CharsetEncoder, [], 1, 3, 0, 0, 0, +jnci_UTF8Encoder, 0, jnci_BufferedEncoder, [], 0, 3, 0, 0, 0, +ji_IOException, 0, jl_Exception, [], 0, 3, 0, 0, 0, +jlr_Array, 0, jl_Object, [], 4, 3, 0, 0, 0, +jl_NullPointerException, 0, jl_RuntimeException, [], 0, 3, 0, 0, 0, +jur_AbstractSet, 0, jl_Object, [], 1, 0, 0, 0, ["$find0", $rt_wrapFunction3(jur_AbstractSet_find), "$findBack", $rt_wrapFunction4(jur_AbstractSet_findBack), "$getType0", $rt_wrapFunction0(jur_AbstractSet_getType), "$setNext", $rt_wrapFunction1(jur_AbstractSet_setNext), "$first", $rt_wrapFunction1(jur_AbstractSet_first), "$processBackRefReplacement", $rt_wrapFunction0(jur_AbstractSet_processBackRefReplacement), "$processSecondPass", $rt_wrapFunction0(jur_AbstractSet_processSecondPass)], +jl_NegativeArraySizeException, 0, jl_RuntimeException, [], 0, 3, 0, 0, 0, +otjc_JSArray, 0, jl_Object, [otjc_JSArrayReader], 1, 3, 0, 0, ["$get$exported$0", $rt_wrapFunction1(otjc_JSArray_get$exported$0), "$getLength$exported$1", $rt_wrapFunction0(otjc_JSArray_getLength$exported$1)], +otjc_JSString, 0, jl_Object, [otj_JSObject], 1, 3, 0, 0, 0, +jur_FSet, 0, jur_AbstractSet, [], 0, 0, 0, jur_FSet_$callClinit, ["$matches", $rt_wrapFunction3(jur_FSet_matches), "$hasConsumed", $rt_wrapFunction1(jur_FSet_hasConsumed)], +jur_Lexer, 0, jl_Object, [], 0, 0, 0, 0, 0, +jur_PatternSyntaxException, 0, jl_IllegalArgumentException, [], 0, 3, 0, 0, 0, +jur_NonCapFSet, 0, jur_FSet, [], 0, 0, 0, 0, ["$matches", $rt_wrapFunction3(jur_NonCapFSet_matches), "$hasConsumed", $rt_wrapFunction1(jur_NonCapFSet_hasConsumed)], +jur_AheadFSet, 0, jur_FSet, [], 0, 0, 0, 0, ["$matches", $rt_wrapFunction3(jur_AheadFSet_matches)], +jur_BehindFSet, 0, jur_FSet, [], 0, 0, 0, 0, ["$matches", $rt_wrapFunction3(jur_BehindFSet_matches)], +jur_AtomicFSet, 0, jur_FSet, [], 0, 0, 0, 0, ["$matches", $rt_wrapFunction3(jur_AtomicFSet_matches), "$hasConsumed", $rt_wrapFunction1(jur_AtomicFSet_hasConsumed)], +jur_FinalSet, 0, jur_FSet, [], 0, 0, 0, 0, ["$matches", $rt_wrapFunction3(jur_FinalSet_matches)], +jur_LeafSet, 0, jur_AbstractSet, [], 1, 0, 0, 0, ["$matches", $rt_wrapFunction3(jur_LeafSet_matches), "$charCount0", $rt_wrapFunction0(jur_LeafSet_charCount), "$hasConsumed", $rt_wrapFunction1(jur_LeafSet_hasConsumed)], +jur_EmptySet, 0, jur_LeafSet, [], 0, 0, 0, 0, ["$accepts", $rt_wrapFunction2(jur_EmptySet_accepts), "$find0", $rt_wrapFunction3(jur_EmptySet_find), "$findBack", $rt_wrapFunction4(jur_EmptySet_findBack), "$hasConsumed", $rt_wrapFunction1(jur_EmptySet_hasConsumed)], +jur_JointSet, 0, jur_AbstractSet, [], 0, 0, 0, 0, ["$matches", $rt_wrapFunction3(jur_JointSet_matches), "$setNext", $rt_wrapFunction1(jur_JointSet_setNext), "$first", $rt_wrapFunction1(jur_JointSet_first), "$hasConsumed", $rt_wrapFunction1(jur_JointSet_hasConsumed), "$processSecondPass", $rt_wrapFunction0(jur_JointSet_processSecondPass)], +jur_NonCapJointSet, 0, jur_JointSet, [], 0, 0, 0, 0, ["$matches", $rt_wrapFunction3(jur_NonCapJointSet_matches), "$hasConsumed", $rt_wrapFunction1(jur_NonCapJointSet_hasConsumed)], +jur_AtomicJointSet, 0, jur_NonCapJointSet, [], 0, 0, 0, 0, ["$matches", $rt_wrapFunction3(jur_AtomicJointSet_matches), "$setNext", $rt_wrapFunction1(jur_AtomicJointSet_setNext)], +jur_PositiveLookAhead, 0, jur_AtomicJointSet, [], 0, 0, 0, 0, ["$matches", $rt_wrapFunction3(jur_PositiveLookAhead_matches), "$hasConsumed", $rt_wrapFunction1(jur_PositiveLookAhead_hasConsumed)], +jur_NegativeLookAhead, 0, jur_AtomicJointSet, [], 0, 0, 0, 0, ["$matches", $rt_wrapFunction3(jur_NegativeLookAhead_matches), "$hasConsumed", $rt_wrapFunction1(jur_NegativeLookAhead_hasConsumed)], +jur_PositiveLookBehind, 0, jur_AtomicJointSet, [], 0, 0, 0, 0, ["$matches", $rt_wrapFunction3(jur_PositiveLookBehind_matches), "$hasConsumed", $rt_wrapFunction1(jur_PositiveLookBehind_hasConsumed)], +jur_NegativeLookBehind, 0, jur_AtomicJointSet, [], 0, 0, 0, 0, ["$matches", $rt_wrapFunction3(jur_NegativeLookBehind_matches), "$hasConsumed", $rt_wrapFunction1(jur_NegativeLookBehind_hasConsumed)], +jur_SingleSet, 0, jur_JointSet, [], 0, 0, 0, 0, ["$matches", $rt_wrapFunction3(jur_SingleSet_matches), "$find0", $rt_wrapFunction3(jur_SingleSet_find), "$findBack", $rt_wrapFunction4(jur_SingleSet_findBack), "$first", $rt_wrapFunction1(jur_SingleSet_first), "$processBackRefReplacement", $rt_wrapFunction0(jur_SingleSet_processBackRefReplacement), "$processSecondPass", $rt_wrapFunction0(jur_SingleSet_processSecondPass)], +jl_ArrayStoreException, 0, jl_RuntimeException, [], 0, 3, 0, 0, 0, +jur_SpecialToken, 0, jl_Object, [], 1, 0, 0, 0, 0, +jur_AbstractCharClass, 0, jur_SpecialToken, [], 1, 0, 0, 0, ["$getBits", $rt_wrapFunction0(jur_AbstractCharClass_getBits), "$getLowHighSurrogates", $rt_wrapFunction0(jur_AbstractCharClass_getLowHighSurrogates), "$getInstance1", $rt_wrapFunction0(jur_AbstractCharClass_getInstance), "$hasUCI", $rt_wrapFunction0(jur_AbstractCharClass_hasUCI)], +jur_CharClass, "CharClass", 2, jur_AbstractCharClass, [], 0, 0, 0, 0, ["$contains", $rt_wrapFunction1(jur_CharClass_contains), "$getBits", $rt_wrapFunction0(jur_CharClass_getBits), "$getLowHighSurrogates", $rt_wrapFunction0(jur_CharClass_getLowHighSurrogates), "$getInstance1", $rt_wrapFunction0(jur_CharClass_getInstance), "$toString", $rt_wrapFunction0(jur_CharClass_toString), "$hasUCI", $rt_wrapFunction0(jur_CharClass_hasUCI)], +ju_MissingResourceException, 0, jl_RuntimeException, [], 0, 3, 0, 0, 0, +jur_QuantifierSet, 0, jur_AbstractSet, [], 1, 0, 0, 0, ["$first", $rt_wrapFunction1(jur_QuantifierSet_first), "$hasConsumed", $rt_wrapFunction1(jur_QuantifierSet_hasConsumed), "$processSecondPass", $rt_wrapFunction0(jur_QuantifierSet_processSecondPass)], +jur_LeafQuantifierSet, 0, jur_QuantifierSet, [], 0, 0, 0, 0, ["$matches", $rt_wrapFunction3(jur_LeafQuantifierSet_matches)], +jur_CompositeQuantifierSet, 0, jur_LeafQuantifierSet, [], 0, 0, 0, 0, ["$matches", $rt_wrapFunction3(jur_CompositeQuantifierSet_matches)], +jur_GroupQuantifierSet, 0, jur_QuantifierSet, [], 0, 0, 0, 0, ["$matches", $rt_wrapFunction3(jur_GroupQuantifierSet_matches)], +jur_AltQuantifierSet, 0, jur_LeafQuantifierSet, [], 0, 0, 0, 0, ["$matches", $rt_wrapFunction3(jur_AltQuantifierSet_matches), "$setNext", $rt_wrapFunction1(jur_AltQuantifierSet_setNext)], +jur_UnifiedQuantifierSet, 0, jur_LeafQuantifierSet, [], 0, 0, 0, 0, ["$matches", $rt_wrapFunction3(jur_UnifiedQuantifierSet_matches), "$find0", $rt_wrapFunction3(jur_UnifiedQuantifierSet_find)], +jur_AbstractCharClass$LazyCharClass, 0, jl_Object, [], 1, 0, 0, 0, 0, +jl_NumberFormatException, 0, jl_IllegalArgumentException, [], 0, 3, 0, 0, 0, +jur_Quantifier, "Quantifier", 2, jur_SpecialToken, [jl_Cloneable], 0, 0, 0, 0, ["$toString", $rt_wrapFunction0(jur_Quantifier_toString)], +jur_FSet$PossessiveFSet, 0, jur_AbstractSet, [], 0, 0, 0, 0, ["$matches", $rt_wrapFunction3(jur_FSet$PossessiveFSet_matches), "$hasConsumed", $rt_wrapFunction1(jur_FSet$PossessiveFSet_hasConsumed)], +ju_BitSet, 0, jl_Object, [jl_Cloneable, ji_Serializable], 0, 3, 0, 0, 0, +jur_LowHighSurrogateRangeSet, 0, jur_JointSet, [], 0, 0, 0, 0, 0, +jur_CompositeRangeSet, 0, jur_JointSet, [], 0, 0, 0, 0, ["$matches", $rt_wrapFunction3(jur_CompositeRangeSet_matches), "$setNext", $rt_wrapFunction1(jur_CompositeRangeSet_setNext), "$hasConsumed", $rt_wrapFunction1(jur_CompositeRangeSet_hasConsumed), "$first", $rt_wrapFunction1(jur_CompositeRangeSet_first)], +jur_SupplRangeSet, 0, jur_JointSet, [], 0, 0, 0, 0, ["$matches", $rt_wrapFunction3(jur_SupplRangeSet_matches), "$contains", $rt_wrapFunction1(jur_SupplRangeSet_contains), "$first", $rt_wrapFunction1(jur_SupplRangeSet_first), "$setNext", $rt_wrapFunction1(jur_SupplRangeSet_setNext), "$hasConsumed", $rt_wrapFunction1(jur_SupplRangeSet_hasConsumed)]]); +$rt_metadata([jur_UCISupplRangeSet, 0, jur_SupplRangeSet, [], 0, 0, 0, 0, ["$contains", $rt_wrapFunction1(jur_UCISupplRangeSet_contains)], +jur_UCIRangeSet, 0, jur_LeafSet, [], 0, 0, 0, 0, ["$accepts", $rt_wrapFunction2(jur_UCIRangeSet_accepts)], +jur_RangeSet, 0, jur_LeafSet, [], 0, 0, 0, 0, ["$accepts", $rt_wrapFunction2(jur_RangeSet_accepts), "$first", $rt_wrapFunction1(jur_RangeSet_first)], +jur_HangulDecomposedCharSet, 0, jur_JointSet, [], 0, 0, 0, 0, ["$setNext", $rt_wrapFunction1(jur_HangulDecomposedCharSet_setNext), "$matches", $rt_wrapFunction3(jur_HangulDecomposedCharSet_matches), "$first", $rt_wrapFunction1(jur_HangulDecomposedCharSet_first), "$hasConsumed", $rt_wrapFunction1(jur_HangulDecomposedCharSet_hasConsumed)], +jur_CharSet, 0, jur_LeafSet, [], 0, 0, 0, 0, ["$charCount0", $rt_wrapFunction0(jur_CharSet_charCount), "$accepts", $rt_wrapFunction2(jur_CharSet_accepts), "$find0", $rt_wrapFunction3(jur_CharSet_find), "$findBack", $rt_wrapFunction4(jur_CharSet_findBack), "$first", $rt_wrapFunction1(jur_CharSet_first)], +jur_UCICharSet, 0, jur_LeafSet, [], 0, 0, 0, 0, ["$accepts", $rt_wrapFunction2(jur_UCICharSet_accepts)], +jur_CICharSet, 0, jur_LeafSet, [], 0, 0, 0, 0, ["$accepts", $rt_wrapFunction2(jur_CICharSet_accepts)], +jur_DecomposedCharSet, 0, jur_JointSet, [], 0, 0, 0, 0, ["$setNext", $rt_wrapFunction1(jur_DecomposedCharSet_setNext), "$matches", $rt_wrapFunction3(jur_DecomposedCharSet_matches), "$first", $rt_wrapFunction1(jur_DecomposedCharSet_first), "$hasConsumed", $rt_wrapFunction1(jur_DecomposedCharSet_hasConsumed)], +jur_UCIDecomposedCharSet, 0, jur_DecomposedCharSet, [], 0, 0, 0, 0, 0, +jur_CIDecomposedCharSet, 0, jur_DecomposedCharSet, [], 0, 0, 0, 0, 0, +jur_PossessiveGroupQuantifierSet, 0, jur_GroupQuantifierSet, [], 0, 0, 0, 0, ["$matches", $rt_wrapFunction3(jur_PossessiveGroupQuantifierSet_matches)], +jur_PosPlusGroupQuantifierSet, 0, jur_GroupQuantifierSet, [], 0, 0, 0, 0, ["$matches", $rt_wrapFunction3(jur_PosPlusGroupQuantifierSet_matches)], +jur_AltGroupQuantifierSet, 0, jur_GroupQuantifierSet, [], 0, 0, 0, 0, ["$matches", $rt_wrapFunction3(jur_AltGroupQuantifierSet_matches), "$setNext", $rt_wrapFunction1(jur_AltGroupQuantifierSet_setNext)], +jur_PosAltGroupQuantifierSet, 0, jur_AltGroupQuantifierSet, [], 0, 0, 0, 0, ["$matches", $rt_wrapFunction3(jur_PosAltGroupQuantifierSet_matches), "$setNext", $rt_wrapFunction1(jur_PosAltGroupQuantifierSet_setNext)], +jur_CompositeGroupQuantifierSet, 0, jur_GroupQuantifierSet, [], 0, 0, 0, 0, ["$matches", $rt_wrapFunction3(jur_CompositeGroupQuantifierSet_matches)], +jur_PosCompositeGroupQuantifierSet, 0, jur_CompositeGroupQuantifierSet, [], 0, 0, 0, 0, ["$matches", $rt_wrapFunction3(jur_PosCompositeGroupQuantifierSet_matches)], +jur_ReluctantGroupQuantifierSet, 0, jur_GroupQuantifierSet, [], 0, 0, 0, 0, ["$matches", $rt_wrapFunction3(jur_ReluctantGroupQuantifierSet_matches)], +jur_RelAltGroupQuantifierSet, 0, jur_AltGroupQuantifierSet, [], 0, 0, 0, 0, ["$matches", $rt_wrapFunction3(jur_RelAltGroupQuantifierSet_matches)], +jur_RelCompositeGroupQuantifierSet, 0, jur_CompositeGroupQuantifierSet, [], 0, 0, 0, 0, ["$matches", $rt_wrapFunction3(jur_RelCompositeGroupQuantifierSet_matches)], +jur_DotAllQuantifierSet, 0, jur_QuantifierSet, [], 0, 0, 0, 0, ["$matches", $rt_wrapFunction3(jur_DotAllQuantifierSet_matches), "$find0", $rt_wrapFunction3(jur_DotAllQuantifierSet_find)], +jur_DotQuantifierSet, 0, jur_QuantifierSet, [], 0, 0, 0, 0, ["$matches", $rt_wrapFunction3(jur_DotQuantifierSet_matches), "$find0", $rt_wrapFunction3(jur_DotQuantifierSet_find)], +jur_AbstractLineTerminator, 0, jl_Object, [], 1, 0, 0, 0, 0, +jur_PossessiveQuantifierSet, 0, jur_LeafQuantifierSet, [], 0, 0, 0, 0, ["$matches", $rt_wrapFunction3(jur_PossessiveQuantifierSet_matches)], +jur_PossessiveAltQuantifierSet, 0, jur_AltQuantifierSet, [], 0, 0, 0, 0, ["$matches", $rt_wrapFunction3(jur_PossessiveAltQuantifierSet_matches)], +jur_PossessiveCompositeQuantifierSet, 0, jur_CompositeQuantifierSet, [], 0, 0, 0, 0, ["$matches", $rt_wrapFunction3(jur_PossessiveCompositeQuantifierSet_matches)], +jur_ReluctantQuantifierSet, 0, jur_LeafQuantifierSet, [], 0, 0, 0, 0, ["$matches", $rt_wrapFunction3(jur_ReluctantQuantifierSet_matches)], +jur_ReluctantAltQuantifierSet, 0, jur_AltQuantifierSet, [], 0, 0, 0, 0, ["$matches", $rt_wrapFunction3(jur_ReluctantAltQuantifierSet_matches)], +jur_ReluctantCompositeQuantifierSet, 0, jur_CompositeQuantifierSet, [], 0, 0, 0, 0, ["$matches", $rt_wrapFunction3(jur_ReluctantCompositeQuantifierSet_matches)], +jur_SOLSet, 0, jur_AbstractSet, [], 4, 0, 0, 0, ["$matches", $rt_wrapFunction3(jur_SOLSet_matches), "$hasConsumed", $rt_wrapFunction1(jur_SOLSet_hasConsumed)], +jur_WordBoundary, 0, jur_AbstractSet, [], 0, 0, 0, 0, ["$matches", $rt_wrapFunction3(jur_WordBoundary_matches), "$hasConsumed", $rt_wrapFunction1(jur_WordBoundary_hasConsumed)], +jur_PreviousMatch, 0, jur_AbstractSet, [], 0, 0, 0, 0, ["$matches", $rt_wrapFunction3(jur_PreviousMatch_matches), "$hasConsumed", $rt_wrapFunction1(jur_PreviousMatch_hasConsumed)], +jur_EOLSet, 0, jur_AbstractSet, [], 4, 0, 0, 0, ["$matches", $rt_wrapFunction3(jur_EOLSet_matches), "$hasConsumed", $rt_wrapFunction1(jur_EOLSet_hasConsumed)], +jur_EOISet, 0, jur_AbstractSet, [], 0, 0, 0, 0, ["$matches", $rt_wrapFunction3(jur_EOISet_matches), "$hasConsumed", $rt_wrapFunction1(jur_EOISet_hasConsumed)], +jur_MultiLineSOLSet, 0, jur_AbstractSet, [], 0, 0, 0, 0, ["$matches", $rt_wrapFunction3(jur_MultiLineSOLSet_matches), "$hasConsumed", $rt_wrapFunction1(jur_MultiLineSOLSet_hasConsumed)], +jur_DotAllSet, 0, jur_JointSet, [], 0, 0, 0, 0, ["$matches", $rt_wrapFunction3(jur_DotAllSet_matches), "$setNext", $rt_wrapFunction1(jur_DotAllSet_setNext), "$getType0", $rt_wrapFunction0(jur_DotAllSet_getType), "$hasConsumed", $rt_wrapFunction1(jur_DotAllSet_hasConsumed)], +jur_DotSet, 0, jur_JointSet, [], 4, 0, 0, 0, ["$matches", $rt_wrapFunction3(jur_DotSet_matches), "$setNext", $rt_wrapFunction1(jur_DotSet_setNext), "$getType0", $rt_wrapFunction0(jur_DotSet_getType), "$hasConsumed", $rt_wrapFunction1(jur_DotSet_hasConsumed)], +jur_UEOLSet, 0, jur_AbstractSet, [], 4, 0, 0, 0, ["$matches", $rt_wrapFunction3(jur_UEOLSet_matches), "$hasConsumed", $rt_wrapFunction1(jur_UEOLSet_hasConsumed)], +jur_UMultiLineEOLSet, 0, jur_AbstractSet, [], 0, 0, 0, 0, ["$matches", $rt_wrapFunction3(jur_UMultiLineEOLSet_matches), "$hasConsumed", $rt_wrapFunction1(jur_UMultiLineEOLSet_hasConsumed)], +jur_MultiLineEOLSet, 0, jur_AbstractSet, [], 0, 0, 0, 0, ["$matches", $rt_wrapFunction3(jur_MultiLineEOLSet_matches), "$hasConsumed", $rt_wrapFunction1(jur_MultiLineEOLSet_hasConsumed)], +jur_CIBackReferenceSet, 0, jur_JointSet, [], 0, 0, 0, 0, ["$matches", $rt_wrapFunction3(jur_CIBackReferenceSet_matches), "$setNext", $rt_wrapFunction1(jur_CIBackReferenceSet_setNext), "$hasConsumed", $rt_wrapFunction1(jur_CIBackReferenceSet_hasConsumed)], +jur_BackReferenceSet, 0, jur_CIBackReferenceSet, [], 0, 0, 0, 0, ["$matches", $rt_wrapFunction3(jur_BackReferenceSet_matches), "$find0", $rt_wrapFunction3(jur_BackReferenceSet_find), "$findBack", $rt_wrapFunction4(jur_BackReferenceSet_findBack), "$first", $rt_wrapFunction1(jur_BackReferenceSet_first)], +jur_UCIBackReferenceSet, 0, jur_CIBackReferenceSet, [], 0, 0, 0, 0, ["$matches", $rt_wrapFunction3(jur_UCIBackReferenceSet_matches)], +jl_StringBuffer, 0, jl_AbstractStringBuilder, [jl_Appendable], 0, 3, 0, 0, ["$insert1", $rt_wrapFunction4(jl_StringBuffer_insert), "$append2", $rt_wrapFunction3(jl_StringBuffer_append), "$ensureCapacity", $rt_wrapFunction1(jl_StringBuffer_ensureCapacity), "$insert2", $rt_wrapFunction2(jl_StringBuffer_insert0)], +jur_SequenceSet, 0, jur_LeafSet, [], 0, 0, 0, 0, ["$accepts", $rt_wrapFunction2(jur_SequenceSet_accepts), "$find0", $rt_wrapFunction3(jur_SequenceSet_find), "$findBack", $rt_wrapFunction4(jur_SequenceSet_findBack), "$first", $rt_wrapFunction1(jur_SequenceSet_first)], +jur_UCISequenceSet, 0, jur_LeafSet, [], 0, 0, 0, 0, ["$accepts", $rt_wrapFunction2(jur_UCISequenceSet_accepts)], +jur_CISequenceSet, 0, jur_LeafSet, [], 0, 0, 0, 0, ["$accepts", $rt_wrapFunction2(jur_CISequenceSet_accepts)], +jur_AbstractCharClass$PredefinedCharacterClasses, 0, jl_Object, [], 4, 0, 0, 0, 0, +jur_UCISupplCharSet, 0, jur_LeafSet, [], 0, 0, 0, 0, ["$accepts", $rt_wrapFunction2(jur_UCISupplCharSet_accepts)], +jur_LowSurrogateCharSet, 0, jur_JointSet, [], 0, 0, 0, 0, ["$setNext", $rt_wrapFunction1(jur_LowSurrogateCharSet_setNext), "$matches", $rt_wrapFunction3(jur_LowSurrogateCharSet_matches), "$find0", $rt_wrapFunction3(jur_LowSurrogateCharSet_find), "$findBack", $rt_wrapFunction4(jur_LowSurrogateCharSet_findBack), "$first", $rt_wrapFunction1(jur_LowSurrogateCharSet_first), "$hasConsumed", $rt_wrapFunction1(jur_LowSurrogateCharSet_hasConsumed)], +jur_HighSurrogateCharSet, 0, jur_JointSet, [], 0, 0, 0, 0, ["$setNext", $rt_wrapFunction1(jur_HighSurrogateCharSet_setNext), "$matches", $rt_wrapFunction3(jur_HighSurrogateCharSet_matches), "$find0", $rt_wrapFunction3(jur_HighSurrogateCharSet_find), "$findBack", $rt_wrapFunction4(jur_HighSurrogateCharSet_findBack), "$first", $rt_wrapFunction1(jur_HighSurrogateCharSet_first), "$hasConsumed", $rt_wrapFunction1(jur_HighSurrogateCharSet_hasConsumed)]]); +$rt_metadata([jur_SupplCharSet, 0, jur_LeafSet, [], 0, 0, 0, 0, ["$accepts", $rt_wrapFunction2(jur_SupplCharSet_accepts), "$find0", $rt_wrapFunction3(jur_SupplCharSet_find), "$findBack", $rt_wrapFunction4(jur_SupplCharSet_findBack), "$first", $rt_wrapFunction1(jur_SupplCharSet_first)], +jur_AbstractLineTerminator$1, 0, jur_AbstractLineTerminator, [], 0, 0, 0, 0, ["$isLineTerminator", $rt_wrapFunction1(jur_AbstractLineTerminator$1_isLineTerminator), "$isAfterLineTerminator", $rt_wrapFunction2(jur_AbstractLineTerminator$1_isAfterLineTerminator)], +jur_AbstractLineTerminator$2, 0, jur_AbstractLineTerminator, [], 0, 0, 0, 0, ["$isLineTerminator", $rt_wrapFunction1(jur_AbstractLineTerminator$2_isLineTerminator), "$isAfterLineTerminator", $rt_wrapFunction2(jur_AbstractLineTerminator$2_isAfterLineTerminator)], +jur_SequenceSet$IntHash, 0, jl_Object, [], 0, 0, 0, 0, 0, +jur_IntHash, 0, jl_Object, [], 0, 0, 0, 0, 0, +jur_AbstractCharClass$LazySpace, 0, jur_AbstractCharClass$LazyCharClass, [], 0, 0, 0, 0, ["$computeValue", $rt_wrapFunction0(jur_AbstractCharClass$LazySpace_computeValue)], +jur_AbstractCharClass$LazyDigit, 0, jur_AbstractCharClass$LazyCharClass, [], 0, 0, 0, 0, ["$computeValue", $rt_wrapFunction0(jur_AbstractCharClass$LazyDigit_computeValue)], +jur_AbstractCharClass$LazyLower, 0, jur_AbstractCharClass$LazyCharClass, [], 0, 0, 0, 0, ["$computeValue", $rt_wrapFunction0(jur_AbstractCharClass$LazyLower_computeValue)], +jur_AbstractCharClass$LazyUpper, 0, jur_AbstractCharClass$LazyCharClass, [], 0, 0, 0, 0, ["$computeValue", $rt_wrapFunction0(jur_AbstractCharClass$LazyUpper_computeValue)], +jur_AbstractCharClass$LazyASCII, 0, jur_AbstractCharClass$LazyCharClass, [], 0, 0, 0, 0, ["$computeValue", $rt_wrapFunction0(jur_AbstractCharClass$LazyASCII_computeValue)], +jur_AbstractCharClass$LazyAlpha, 0, jur_AbstractCharClass$LazyCharClass, [], 0, 0, 0, 0, ["$computeValue", $rt_wrapFunction0(jur_AbstractCharClass$LazyAlpha_computeValue)], +jur_AbstractCharClass$LazyAlnum, 0, jur_AbstractCharClass$LazyAlpha, [], 0, 0, 0, 0, ["$computeValue", $rt_wrapFunction0(jur_AbstractCharClass$LazyAlnum_computeValue)], +jur_AbstractCharClass$LazyPunct, 0, jur_AbstractCharClass$LazyCharClass, [], 0, 0, 0, 0, ["$computeValue", $rt_wrapFunction0(jur_AbstractCharClass$LazyPunct_computeValue)], +jur_AbstractCharClass$LazyGraph, 0, jur_AbstractCharClass$LazyAlnum, [], 0, 0, 0, 0, ["$computeValue", $rt_wrapFunction0(jur_AbstractCharClass$LazyGraph_computeValue)], +jur_AbstractCharClass$LazyPrint, 0, jur_AbstractCharClass$LazyGraph, [], 0, 0, 0, 0, ["$computeValue", $rt_wrapFunction0(jur_AbstractCharClass$LazyPrint_computeValue)], +jur_AbstractCharClass$LazyBlank, 0, jur_AbstractCharClass$LazyCharClass, [], 0, 0, 0, 0, ["$computeValue", $rt_wrapFunction0(jur_AbstractCharClass$LazyBlank_computeValue)], +jur_AbstractCharClass$LazyCntrl, 0, jur_AbstractCharClass$LazyCharClass, [], 0, 0, 0, 0, ["$computeValue", $rt_wrapFunction0(jur_AbstractCharClass$LazyCntrl_computeValue)], +jur_AbstractCharClass$LazyXDigit, 0, jur_AbstractCharClass$LazyCharClass, [], 0, 0, 0, 0, ["$computeValue", $rt_wrapFunction0(jur_AbstractCharClass$LazyXDigit_computeValue)], +jur_AbstractCharClass$LazyJavaLowerCase, 0, jur_AbstractCharClass$LazyCharClass, [], 0, 0, 0, 0, ["$computeValue", $rt_wrapFunction0(jur_AbstractCharClass$LazyJavaLowerCase_computeValue)], +jur_AbstractCharClass$LazyJavaUpperCase, 0, jur_AbstractCharClass$LazyCharClass, [], 0, 0, 0, 0, ["$computeValue", $rt_wrapFunction0(jur_AbstractCharClass$LazyJavaUpperCase_computeValue)], +jur_AbstractCharClass$LazyJavaWhitespace, 0, jur_AbstractCharClass$LazyCharClass, [], 0, 0, 0, 0, ["$computeValue", $rt_wrapFunction0(jur_AbstractCharClass$LazyJavaWhitespace_computeValue)], +jur_AbstractCharClass$LazyJavaMirrored, 0, jur_AbstractCharClass$LazyCharClass, [], 0, 0, 0, 0, ["$computeValue", $rt_wrapFunction0(jur_AbstractCharClass$LazyJavaMirrored_computeValue)], +jur_AbstractCharClass$LazyJavaDefined, 0, jur_AbstractCharClass$LazyCharClass, [], 0, 0, 0, 0, ["$computeValue", $rt_wrapFunction0(jur_AbstractCharClass$LazyJavaDefined_computeValue)], +jur_AbstractCharClass$LazyJavaDigit, 0, jur_AbstractCharClass$LazyCharClass, [], 0, 0, 0, 0, ["$computeValue", $rt_wrapFunction0(jur_AbstractCharClass$LazyJavaDigit_computeValue)], +jur_AbstractCharClass$LazyJavaIdentifierIgnorable, 0, jur_AbstractCharClass$LazyCharClass, [], 0, 0, 0, 0, ["$computeValue", $rt_wrapFunction0(jur_AbstractCharClass$LazyJavaIdentifierIgnorable_computeValue)], +jur_AbstractCharClass$LazyJavaISOControl, 0, jur_AbstractCharClass$LazyCharClass, [], 0, 0, 0, 0, ["$computeValue", $rt_wrapFunction0(jur_AbstractCharClass$LazyJavaISOControl_computeValue)], +jur_AbstractCharClass$LazyJavaJavaIdentifierPart, 0, jur_AbstractCharClass$LazyCharClass, [], 0, 0, 0, 0, ["$computeValue", $rt_wrapFunction0(jur_AbstractCharClass$LazyJavaJavaIdentifierPart_computeValue)], +jur_AbstractCharClass$LazyJavaJavaIdentifierStart, 0, jur_AbstractCharClass$LazyCharClass, [], 0, 0, 0, 0, ["$computeValue", $rt_wrapFunction0(jur_AbstractCharClass$LazyJavaJavaIdentifierStart_computeValue)], +jur_AbstractCharClass$LazyJavaLetter, 0, jur_AbstractCharClass$LazyCharClass, [], 0, 0, 0, 0, ["$computeValue", $rt_wrapFunction0(jur_AbstractCharClass$LazyJavaLetter_computeValue)], +jur_AbstractCharClass$LazyJavaLetterOrDigit, 0, jur_AbstractCharClass$LazyCharClass, [], 0, 0, 0, 0, ["$computeValue", $rt_wrapFunction0(jur_AbstractCharClass$LazyJavaLetterOrDigit_computeValue)], +jur_AbstractCharClass$LazyJavaSpaceChar, 0, jur_AbstractCharClass$LazyCharClass, [], 0, 0, 0, 0, ["$computeValue", $rt_wrapFunction0(jur_AbstractCharClass$LazyJavaSpaceChar_computeValue)], +jur_AbstractCharClass$LazyJavaTitleCase, 0, jur_AbstractCharClass$LazyCharClass, [], 0, 0, 0, 0, ["$computeValue", $rt_wrapFunction0(jur_AbstractCharClass$LazyJavaTitleCase_computeValue)], +jur_AbstractCharClass$LazyJavaUnicodeIdentifierPart, 0, jur_AbstractCharClass$LazyCharClass, [], 0, 0, 0, 0, ["$computeValue", $rt_wrapFunction0(jur_AbstractCharClass$LazyJavaUnicodeIdentifierPart_computeValue)], +jur_AbstractCharClass$LazyJavaUnicodeIdentifierStart, 0, jur_AbstractCharClass$LazyCharClass, [], 0, 0, 0, 0, ["$computeValue", $rt_wrapFunction0(jur_AbstractCharClass$LazyJavaUnicodeIdentifierStart_computeValue)], +jur_AbstractCharClass$LazyWord, 0, jur_AbstractCharClass$LazyCharClass, [], 0, 0, 0, 0, ["$computeValue", $rt_wrapFunction0(jur_AbstractCharClass$LazyWord_computeValue)], +jur_AbstractCharClass$LazyNonWord, 0, jur_AbstractCharClass$LazyWord, [], 0, 0, 0, 0, ["$computeValue", $rt_wrapFunction0(jur_AbstractCharClass$LazyNonWord_computeValue)], +jur_AbstractCharClass$LazyNonSpace, 0, jur_AbstractCharClass$LazySpace, [], 0, 0, 0, 0, ["$computeValue", $rt_wrapFunction0(jur_AbstractCharClass$LazyNonSpace_computeValue)], +jur_AbstractCharClass$LazyNonDigit, 0, jur_AbstractCharClass$LazyDigit, [], 0, 0, 0, 0, ["$computeValue", $rt_wrapFunction0(jur_AbstractCharClass$LazyNonDigit_computeValue)], +jur_AbstractCharClass$LazyRange, 0, jur_AbstractCharClass$LazyCharClass, [], 0, 0, 0, 0, ["$computeValue", $rt_wrapFunction0(jur_AbstractCharClass$LazyRange_computeValue)], +jur_AbstractCharClass$LazySpecialsBlock, 0, jur_AbstractCharClass$LazyCharClass, [], 0, 0, 0, 0, ["$computeValue", $rt_wrapFunction0(jur_AbstractCharClass$LazySpecialsBlock_computeValue)], +jur_AbstractCharClass$LazyCategory, 0, jur_AbstractCharClass$LazyCharClass, [], 0, 0, 0, 0, ["$computeValue", $rt_wrapFunction0(jur_AbstractCharClass$LazyCategory_computeValue)], +jur_AbstractCharClass$LazyCategoryScope, 0, jur_AbstractCharClass$LazyCharClass, [], 0, 0, 0, 0, ["$computeValue", $rt_wrapFunction0(jur_AbstractCharClass$LazyCategoryScope_computeValue)], +otpp_ResourceAccessor, 0, jl_Object, [], 4, 0, 0, 0, 0, +otciu_UnicodeHelper, 0, jl_Object, [], 4, 3, 0, 0, 0, +otciu_UnicodeHelper$Range, 0, jl_Object, [], 0, 3, 0, 0, 0, +otci_CharFlow, 0, jl_Object, [], 0, 3, 0, 0, 0, +otci_Base46, 0, jl_Object, [], 4, 3, 0, 0, 0, +jur_AbstractCharClass$1, "AbstractCharClass$1", 2, jur_AbstractCharClass, [], 0, 0, 0, 0, ["$contains", $rt_wrapFunction1(jur_AbstractCharClass$1_contains)], +jur_AbstractCharClass$2, "AbstractCharClass$2", 2, jur_AbstractCharClass, [], 0, 0, 0, 0, ["$contains", $rt_wrapFunction1(jur_AbstractCharClass$2_contains)], +jur_CharClass$18, "CharClass$18", 2, jur_AbstractCharClass, [], 0, 0, 0, 0, ["$contains", $rt_wrapFunction1(jur_CharClass$18_contains), "$toString", $rt_wrapFunction0(jur_CharClass$18_toString)]]); +$rt_metadata([jur_CharClass$1, 0, jur_AbstractCharClass, [], 0, 0, 0, 0, ["$contains", $rt_wrapFunction1(jur_CharClass$1_contains)], +jur_CharClass$3, 0, jur_AbstractCharClass, [], 0, 0, 0, 0, ["$contains", $rt_wrapFunction1(jur_CharClass$3_contains)], +jur_CharClass$2, 0, jur_AbstractCharClass, [], 0, 0, 0, 0, ["$contains", $rt_wrapFunction1(jur_CharClass$2_contains)], +jur_CharClass$5, 0, jur_AbstractCharClass, [], 0, 0, 0, 0, ["$contains", $rt_wrapFunction1(jur_CharClass$5_contains)], +jur_CharClass$4, 0, jur_AbstractCharClass, [], 0, 0, 0, 0, ["$contains", $rt_wrapFunction1(jur_CharClass$4_contains)], +jur_CharClass$7, 0, jur_AbstractCharClass, [], 0, 0, 0, 0, ["$contains", $rt_wrapFunction1(jur_CharClass$7_contains)], +jur_CharClass$6, 0, jur_AbstractCharClass, [], 0, 0, 0, 0, ["$contains", $rt_wrapFunction1(jur_CharClass$6_contains)], +jur_CharClass$9, 0, jur_AbstractCharClass, [], 0, 0, 0, 0, ["$contains", $rt_wrapFunction1(jur_CharClass$9_contains)], +jur_CharClass$8, 0, jur_AbstractCharClass, [], 0, 0, 0, 0, ["$contains", $rt_wrapFunction1(jur_CharClass$8_contains)], +jur_CharClass$11, 0, jur_AbstractCharClass, [], 0, 0, 0, 0, ["$contains", $rt_wrapFunction1(jur_CharClass$11_contains)], +jur_CharClass$10, 0, jur_AbstractCharClass, [], 0, 0, 0, 0, ["$contains", $rt_wrapFunction1(jur_CharClass$10_contains)], +jur_CharClass$13, 0, jur_AbstractCharClass, [], 0, 0, 0, 0, ["$contains", $rt_wrapFunction1(jur_CharClass$13_contains)], +jur_CharClass$12, 0, jur_AbstractCharClass, [], 0, 0, 0, 0, ["$contains", $rt_wrapFunction1(jur_CharClass$12_contains)], +jur_CharClass$15, 0, jur_AbstractCharClass, [], 0, 0, 0, 0, ["$contains", $rt_wrapFunction1(jur_CharClass$15_contains)], +jur_CharClass$14, 0, jur_AbstractCharClass, [], 0, 0, 0, 0, ["$contains", $rt_wrapFunction1(jur_CharClass$14_contains)], +jur_CharClass$17, 0, jur_AbstractCharClass, [], 0, 0, 0, 0, ["$contains", $rt_wrapFunction1(jur_CharClass$17_contains)], +jur_CharClass$16, 0, jur_AbstractCharClass, [], 0, 0, 0, 0, ["$contains", $rt_wrapFunction1(jur_CharClass$16_contains)], +jur_BackReferencedSingleSet, 0, jur_SingleSet, [], 0, 0, 0, 0, ["$find0", $rt_wrapFunction3(jur_BackReferencedSingleSet_find), "$findBack", $rt_wrapFunction4(jur_BackReferencedSingleSet_findBack), "$processBackRefReplacement", $rt_wrapFunction0(jur_BackReferencedSingleSet_processBackRefReplacement)], +ju_Iterator, 0, jl_Object, [], 3, 3, 0, 0, 0, +ju_AbstractList$1, 0, jl_Object, [ju_Iterator], 0, 0, 0, 0, 0, +otcic_Console, 0, jl_Object, [], 4, 3, 0, 0, 0, +jur_MatchResult, 0, jl_Object, [], 3, 3, 0, 0, 0, +jur_Matcher, 0, jl_Object, [jur_MatchResult], 4, 3, 0, 0, 0, +jnc_CoderMalfunctionError, 0, jl_Error, [], 0, 3, 0, 0, 0, +jur_AbstractCharClass$LazyJavaLowerCase$1, "AbstractCharClass$LazyJavaLowerCase$1", 2, jur_AbstractCharClass, [], 0, 0, 0, 0, ["$contains", $rt_wrapFunction1(jur_AbstractCharClass$LazyJavaLowerCase$1_contains)], +jur_AbstractCharClass$LazyJavaUpperCase$1, "AbstractCharClass$LazyJavaUpperCase$1", 2, jur_AbstractCharClass, [], 0, 0, 0, 0, ["$contains", $rt_wrapFunction1(jur_AbstractCharClass$LazyJavaUpperCase$1_contains)], +jur_AbstractCharClass$LazyJavaWhitespace$1, "AbstractCharClass$LazyJavaWhitespace$1", 2, jur_AbstractCharClass, [], 0, 0, 0, 0, ["$contains", $rt_wrapFunction1(jur_AbstractCharClass$LazyJavaWhitespace$1_contains)], +jur_AbstractCharClass$LazyJavaMirrored$1, "AbstractCharClass$LazyJavaMirrored$1", 2, jur_AbstractCharClass, [], 0, 0, 0, 0, ["$contains", $rt_wrapFunction1(jur_AbstractCharClass$LazyJavaMirrored$1_contains)], +jur_AbstractCharClass$LazyJavaDefined$1, "AbstractCharClass$LazyJavaDefined$1", 2, jur_AbstractCharClass, [], 0, 0, 0, 0, ["$contains", $rt_wrapFunction1(jur_AbstractCharClass$LazyJavaDefined$1_contains)], +jur_AbstractCharClass$LazyJavaDigit$1, "AbstractCharClass$LazyJavaDigit$1", 2, jur_AbstractCharClass, [], 0, 0, 0, 0, ["$contains", $rt_wrapFunction1(jur_AbstractCharClass$LazyJavaDigit$1_contains)], +jur_AbstractCharClass$LazyJavaIdentifierIgnorable$1, "AbstractCharClass$LazyJavaIdentifierIgnorable$1", 2, jur_AbstractCharClass, [], 0, 0, 0, 0, ["$contains", $rt_wrapFunction1(jur_AbstractCharClass$LazyJavaIdentifierIgnorable$1_contains)], +jur_AbstractCharClass$LazyJavaISOControl$1, "AbstractCharClass$LazyJavaISOControl$1", 2, jur_AbstractCharClass, [], 0, 0, 0, 0, ["$contains", $rt_wrapFunction1(jur_AbstractCharClass$LazyJavaISOControl$1_contains)], +jur_AbstractCharClass$LazyJavaJavaIdentifierPart$1, "AbstractCharClass$LazyJavaJavaIdentifierPart$1", 2, jur_AbstractCharClass, [], 0, 0, 0, 0, ["$contains", $rt_wrapFunction1(jur_AbstractCharClass$LazyJavaJavaIdentifierPart$1_contains)], +jur_AbstractCharClass$LazyJavaJavaIdentifierStart$1, "AbstractCharClass$LazyJavaJavaIdentifierStart$1", 2, jur_AbstractCharClass, [], 0, 0, 0, 0, ["$contains", $rt_wrapFunction1(jur_AbstractCharClass$LazyJavaJavaIdentifierStart$1_contains)], +jur_AbstractCharClass$LazyJavaLetter$1, "AbstractCharClass$LazyJavaLetter$1", 2, jur_AbstractCharClass, [], 0, 0, 0, 0, ["$contains", $rt_wrapFunction1(jur_AbstractCharClass$LazyJavaLetter$1_contains)], +jur_AbstractCharClass$LazyJavaLetterOrDigit$1, "AbstractCharClass$LazyJavaLetterOrDigit$1", 2, jur_AbstractCharClass, [], 0, 0, 0, 0, ["$contains", $rt_wrapFunction1(jur_AbstractCharClass$LazyJavaLetterOrDigit$1_contains)], +jur_AbstractCharClass$LazyJavaSpaceChar$1, "AbstractCharClass$LazyJavaSpaceChar$1", 2, jur_AbstractCharClass, [], 0, 0, 0, 0, ["$contains", $rt_wrapFunction1(jur_AbstractCharClass$LazyJavaSpaceChar$1_contains)], +jur_AbstractCharClass$LazyJavaTitleCase$1, "AbstractCharClass$LazyJavaTitleCase$1", 2, jur_AbstractCharClass, [], 0, 0, 0, 0, ["$contains", $rt_wrapFunction1(jur_AbstractCharClass$LazyJavaTitleCase$1_contains)], +jur_AbstractCharClass$LazyJavaUnicodeIdentifierPart$1, "AbstractCharClass$LazyJavaUnicodeIdentifierPart$1", 2, jur_AbstractCharClass, [], 0, 0, 0, 0, ["$contains", $rt_wrapFunction1(jur_AbstractCharClass$LazyJavaUnicodeIdentifierPart$1_contains)], +jur_AbstractCharClass$LazyJavaUnicodeIdentifierStart$1, "AbstractCharClass$LazyJavaUnicodeIdentifierStart$1", 2, jur_AbstractCharClass, [], 0, 0, 0, 0, ["$contains", $rt_wrapFunction1(jur_AbstractCharClass$LazyJavaUnicodeIdentifierStart$1_contains)], +jur_UnicodeCategory, "UnicodeCategory", 2, jur_AbstractCharClass, [], 0, 0, 0, 0, ["$contains", $rt_wrapFunction1(jur_UnicodeCategory_contains)], +jur_UnicodeCategoryScope, "UnicodeCategoryScope", 2, jur_UnicodeCategory, [], 0, 0, 0, 0, ["$contains", $rt_wrapFunction1(jur_UnicodeCategoryScope_contains)], +ju_ConcurrentModificationException, 0, jl_RuntimeException, [], 0, 3, 0, 0, 0, +jur_MatchResultImpl, 0, jl_Object, [jur_MatchResult], 0, 0, 0, 0, 0, +jl_UnsupportedOperationException, 0, jl_RuntimeException, [], 0, 3, 0, 0, 0, +jnci_BufferedEncoder$Controller, 0, jl_Object, [], 0, 3, 0, 0, 0, +jn_ReadOnlyBufferException, 0, jl_UnsupportedOperationException, [], 0, 3, 0, 0, 0, +jn_BufferOverflowException, 0, jl_RuntimeException, [], 0, 3, 0, 0, 0, +jn_BufferUnderflowException, 0, jl_RuntimeException, [], 0, 3, 0, 0, 0, +jur_IntArrHash, 0, jl_Object, [], 0, 0, 0, 0, 0]); +function $rt_array(cls, data) { + this.$monitor = null; + this.$id$ = 0; + this.type = cls; + this.data = data; + this.constructor = $rt_arraycls(cls); +} +$rt_array.prototype = Object.create(($rt_objcls()).prototype); +$rt_array.prototype.toString = function() { + var str = "["; + for (var i = 0;i < this.data.length;++i) { + if (i > 0) { + str += ", "; + } + str += this.data[i].toString(); + } + str += "]"; + return str; +}; +$rt_setCloneMethod($rt_array.prototype, function() { + var dataCopy; + if ('slice' in this.data) { + dataCopy = this.data.slice(); + } else { + dataCopy = new this.data.constructor(this.data.length); + for (var i = 0;i < dataCopy.length;++i) { + dataCopy[i] = this.data[i]; + } + } + return new $rt_array(this.type, dataCopy); +}); +$rt_stringPool(["@", "\\", "UTF-8", "IGNORE", "REPLACE", "REPORT", "BIG_ENDIAN", "LITTLE_ENDIAN", "null", "String contains invalid digits: ", "String contains digits out of radix ", ": ", "The value is too big for int type: ", "String is null or empty", "Illegal radix: ", "_net_lax1dude_eaglercraft_sp_VirtualFilesystem_1_5_2", "COULD NOT INIT FILESYSTEM: ", "test1", "/test1", "/test2/", "test2/", "test2/teste", "\\test2\\teste", "\\test2\\teste\\..\\eag", "test2", "teste", "eag", "../", "../../", ".", "you/eag", +" you/ eag ", "\\yee\\", "yeeler", "yee", "yee2", "yee/deevler/", "yee/../../../../", "yee/../../deevler../../", "0", "/", "..", "Either src or dest is null", "The filesystem requested is already in use on a different tab.", "The IDBFactory.open() request failed, reason: ", "Virtual Filesystem Object: ", "IDBFactory threw an exception, IndexedDB is most likely not supported in this browser.", "", "\n\n", "Action must be non-null", "Replacement preconditions do not hold", "Index out of bounds", "open error", +"path", "IndexedDB is not supported in this browser", "New position ", " is outside of range [0;", "]", "The last char in dst ", " is outside of array of size ", "Length ", " must be non-negative", "Offset ", ")", "The last byte in src ", "Patter is null", "\\Q", "\\E", "\\\\E\\Q", "Is", "In", "{", ",", "}", "Lower", "Upper", "ASCII", "Alpha", "Digit", "Alnum", "Punct", "Graph", "Print", "Blank", "Cntrl", "XDigit", "javaLowerCase", "javaUpperCase", "javaWhitespace", "javaMirrored", "javaDefined", "javaDigit", +"javaIdentifierIgnorable", "javaISOControl", "javaJavaIdentifierPart", "javaJavaIdentifierStart", "javaLetter", "javaLetterOrDigit", "javaSpaceChar", "javaTitleCase", "javaUnicodeIdentifierPart", "javaUnicodeIdentifierStart", "Space", "w", "W", "s", "S", "d", "D", "BasicLatin", "Latin-1Supplement", "LatinExtended-A", "LatinExtended-B", "IPAExtensions", "SpacingModifierLetters", "CombiningDiacriticalMarks", "Greek", "Cyrillic", "CyrillicSupplement", "Armenian", "Hebrew", "Arabic", "Syriac", "ArabicSupplement", +"Thaana", "Devanagari", "Bengali", "Gurmukhi", "Gujarati", "Oriya", "Tamil", "Telugu", "Kannada", "Malayalam", "Sinhala", "Thai", "Lao", "Tibetan", "Myanmar", "Georgian", "HangulJamo", "Ethiopic", "EthiopicSupplement", "Cherokee", "UnifiedCanadianAboriginalSyllabics", "Ogham", "Runic", "Tagalog", "Hanunoo", "Buhid", "Tagbanwa", "Khmer", "Mongolian", "Limbu", "TaiLe", "NewTaiLue", "KhmerSymbols", "Buginese", "PhoneticExtensions", "PhoneticExtensionsSupplement", "CombiningDiacriticalMarksSupplement", "LatinExtendedAdditional", +"GreekExtended", "GeneralPunctuation", "SuperscriptsandSubscripts", "CurrencySymbols", "CombiningMarksforSymbols", "LetterlikeSymbols", "NumberForms", "Arrows", "MathematicalOperators", "MiscellaneousTechnical", "ControlPictures", "OpticalCharacterRecognition", "EnclosedAlphanumerics", "BoxDrawing", "BlockElements", "GeometricShapes", "MiscellaneousSymbols", "Dingbats", "MiscellaneousMathematicalSymbols-A", "SupplementalArrows-A", "BraillePatterns", "SupplementalArrows-B", "MiscellaneousMathematicalSymbols-B", +"SupplementalMathematicalOperators", "MiscellaneousSymbolsandArrows", "Glagolitic", "Coptic", "GeorgianSupplement", "Tifinagh", "EthiopicExtended", "SupplementalPunctuation", "CJKRadicalsSupplement", "KangxiRadicals", "IdeographicDescriptionCharacters", "CJKSymbolsandPunctuation", "Hiragana", "Katakana", "Bopomofo", "HangulCompatibilityJamo", "Kanbun", "BopomofoExtended", "CJKStrokes", "KatakanaPhoneticExtensions", "EnclosedCJKLettersandMonths", "CJKCompatibility", "CJKUnifiedIdeographsExtensionA", "YijingHexagramSymbols", +"CJKUnifiedIdeographs", "YiSyllables", "YiRadicals", "ModifierToneLetters", "SylotiNagri", "HangulSyllables", "HighSurrogates", "HighPrivateUseSurrogates", "LowSurrogates", "PrivateUseArea", "CJKCompatibilityIdeographs", "AlphabeticPresentationForms", "ArabicPresentationForms-A", "VariationSelectors", "VerticalForms", "CombiningHalfMarks", "CJKCompatibilityForms", "SmallFormVariants", "ArabicPresentationForms-B", "HalfwidthandFullwidthForms", "all", "Specials", "Cn", "IsL", "Lu", "Ll", "Lt", "Lm", "Lo", "IsM", +"Mn", "Me", "Mc", "N", "Nd", "Nl", "No", "IsZ", "Zs", "Zl", "Zp", "IsC", "Cc", "Cf", "Co", "Cs", "IsP", "Pd", "Ps", "Pe", "Pc", "Po", "IsS", "Sm", "Sc", "Sk", "So", "Pi", "Pf"]); +jl_String.prototype.toString = function() { + return $rt_ustr(this); +}; +jl_String.prototype.valueOf = jl_String.prototype.toString; +jl_Object.prototype.toString = function() { + return $rt_ustr(jl_Object_toString(this)); +}; +jl_Object.prototype.__teavm_class__ = function() { + return $dbg_class(this); +}; +function TeaVMThread(runner) { + this.status = 3; + this.stack = []; + this.suspendCallback = null; + this.runner = runner; + this.attribute = null; + this.completeCallback = null; +} +TeaVMThread.prototype.push = function() { + for (var i = 0;i < arguments.length;++i) { + this.stack.push(arguments[i]); + } + return this; +}; +TeaVMThread.prototype.s = TeaVMThread.prototype.push; +TeaVMThread.prototype.pop = function() { + return this.stack.pop(); +}; +TeaVMThread.prototype.l = TeaVMThread.prototype.pop; +TeaVMThread.prototype.isResuming = function() { + return this.status === 2; +}; +TeaVMThread.prototype.isSuspending = function() { + return this.status === 1; +}; +TeaVMThread.prototype.suspend = function(callback) { + this.suspendCallback = callback; + this.status = 1; +}; +TeaVMThread.prototype.start = function(callback) { + if (this.status !== 3) { + throw new Error("Thread already started"); + } + if ($rt_currentNativeThread !== null) { + throw new Error("Another thread is running"); + } + this.status = 0; + this.completeCallback = callback ? callback : function(result) { + if (result instanceof Error) { + throw result; + } + }; + this.run(); +}; +TeaVMThread.prototype.resume = function() { + if ($rt_currentNativeThread !== null) { + throw new Error("Another thread is running"); + } + this.status = 2; + this.run(); +}; +TeaVMThread.prototype.run = function() { + $rt_currentNativeThread = this; + var result; + try { + result = this.runner(); + } catch (e){ + result = e; + } finally { + $rt_currentNativeThread = null; + } + if (this.suspendCallback !== null) { + var self = this; + var callback = this.suspendCallback; + this.suspendCallback = null; + callback(function() { + self.resume(); + }); + } else if (this.status === 0) { + this.completeCallback(result); + } +}; +function $rt_suspending() { + var thread = $rt_nativeThread(); + return thread != null && thread.isSuspending(); +} +function $rt_resuming() { + var thread = $rt_nativeThread(); + return thread != null && thread.isResuming(); +} +function $rt_suspend(callback) { + var nativeThread = $rt_nativeThread(); + if (nativeThread === null) { + throw new Error("Suspension point reached from non-threading context (perhaps, from native JS method)."); + } + return nativeThread.suspend(callback); +} +function $rt_startThread(runner, callback) { + (new TeaVMThread(runner)).start(callback); +} +var $rt_currentNativeThread = null; +function $rt_nativeThread() { + return $rt_currentNativeThread; +} +function $rt_invalidPointer() { + throw new Error("Invalid recorded state"); +} +main = $rt_mainStarter(nles_IntegratedServer_main); +main.javaException = $rt_javaException; +(function() { + var c; + c = otjb_Window.prototype; + c.dispatchEvent = c.$dispatchEvent$exported$4; + c.addEventListener = c.$addEventListener$exported$0; + c.removeEventListener = c.$removeEventListener$exported$1; + c.getLength = c.$getLength$exported$5; + c.get = c.$get$exported$2; + c.addEventListener = c.$addEventListener$exported$6; + c.removeEventListener = c.$removeEventListener$exported$3; + c = nles_SYS$requestPersist$lambda$_2_0.prototype; + c.complete = c.$complete$exported$0; + c = nles_VirtualFilesystem$AsyncHandlers$1.prototype; + c.handleEvent = c.$handleEvent$exported$0; + c = nles_VirtualFilesystem$AsyncHandlers$2.prototype; + c.handleEvent = c.$handleEvent$exported$0; + c = nles_VirtualFilesystem$AsyncHandlers$3.prototype; + c.handleEvent = c.$handleEvent$exported$0; + c = nles_VirtualFilesystem$AsyncHandlers$4.prototype; + c.handleEvent = c.$handleEvent$exported$00; + c = otjc_JSArray.prototype; + c.getLength = c.$getLength$exported$1; + c.get = c.$get$exported$0; +})(); +})(); diff --git a/javascript/classes_server.js.map b/javascript/classes_server.js.map new file mode 100644 index 0000000..cb492ac --- /dev/null +++ b/javascript/classes_server.js.map @@ -0,0 +1 @@ +{"version":3,"file":"classes_server.js","sourceRoot":"src","sources":["org/teavm/classlib/java/lang/TObject.java","org/teavm/classlib/java/lang/TClass.java","org/teavm/classlib/java/lang/TAbstractStringBuilder.java","org/teavm/classlib/java/lang/TStringBuilder.java","org/teavm/classlib/java/lang/TInteger.java","org/teavm/classlib/java/lang/TString.java","org/teavm/classlib/java/lang/TThrowable.java","org/teavm/classlib/java/util/THashMap.java","org/teavm/classlib/java/lang/TSystem.java","net/lax1dude/eaglercraft/sp/IntegratedServer.java","net/lax1dude/eaglercraft/sp/VirtualFilesystem.java","org/teavm/classlib/java/io/TPrintStream.java","org/teavm/classlib/java/nio/charset/TCodingErrorAction.java","org/teavm/classlib/java/nio/TByteOrder.java","org/teavm/classlib/impl/console/StdoutOutputStream.java","org/teavm/classlib/java/lang/TCharacter.java","org/teavm/classlib/java/io/TFilterOutputStream.java","org/teavm/classlib/java/nio/charset/impl/TUTF8Charset.java","org/teavm/classlib/java/nio/charset/TCharset.java","org/teavm/classlib/java/nio/charset/TCoderResult.java","org/teavm/classlib/java/lang/TFloat.java","org/teavm/classlib/impl/console/StderrOutputStream.java","org/teavm/platform/Platform.java","org/teavm/classlib/java/util/TArrays.java","org/teavm/classlib/java/lang/TMath.java","org/teavm/classlib/java/nio/TByteBuffer.java","org/teavm/classlib/java/nio/charset/TUnsupportedCharsetException.java","org/teavm/classlib/java/nio/TBuffer.java","org/teavm/classlib/java/nio/TByteBufferImpl.java","org/teavm/classlib/java/nio/TCharBufferOverArray.java","org/teavm/classlib/java/nio/TCharBuffer.java","org/teavm/classlib/impl/IntegerUtil.java","org/teavm/classlib/java/util/TMapEntry.java","org/teavm/jso/indexeddb/IDBFactory.java","org/teavm/classlib/java/io/TOutputStream.java","org/teavm/classlib/java/nio/charset/TCharsetEncoder.java","org/teavm/classlib/impl/console/Console.java","org/teavm/platform/plugin/AsyncCallbackWrapper.java","org/teavm/jso/impl/JS.java","org/teavm/jso/indexeddb/IDBObjectStoreParameters.java","org/teavm/classlib/java/nio/charset/TIllegalCharsetNameException.java","org/teavm/classlib/java/nio/charset/impl/TBufferedDecoder.java","org/teavm/classlib/java/nio/charset/impl/TBufferedEncoder.java","org/teavm/classlib/java/lang/TException.java","org/teavm/classlib/java/nio/charset/TMalformedInputException.java","org/teavm/classlib/java/nio/charset/TUnmappableCharacterException.java","org/teavm/classlib/java/nio/charset/impl/TUTF8Encoder.java","org/teavm/classlib/java/nio/charset/TStandardCharsets.java","org/teavm/classlib/java/nio/charset/impl/TAsciiCharset.java","org/teavm/classlib/java/nio/charset/impl/TIso8859Charset.java","org/teavm/classlib/java/nio/charset/impl/TUTF16Charset.java","org/teavm/classlib/java/nio/charset/impl/TUTF16Decoder.java","org/teavm/classlib/java/nio/charset/impl/TUTF16Encoder.java","org/teavm/classlib/java/nio/charset/TCharsetDecoder.java","org/teavm/classlib/java/nio/charset/impl/TAsciiEncoder.java","org/teavm/classlib/java/nio/charset/impl/TIso8859Encoder.java","org/teavm/classlib/java/nio/charset/impl/TUTF8Decoder.java","org/teavm/classlib/java/nio/charset/impl/TAsciiDecoder.java","org/teavm/classlib/java/nio/charset/impl/TIso8859Decoder.java","org/teavm/classlib/impl/text/FloatAnalyzer.java","org/teavm/classlib/java/lang/TCloneNotSupportedException.java","org/teavm/classlib/java/lang/TStringIndexOutOfBoundsException.java","org/teavm/classlib/java/lang/TIndexOutOfBoundsException.java","org/teavm/classlib/java/lang/TRuntimeException.java","org/teavm/classlib/java/lang/TNoSuchFieldError.java","org/teavm/classlib/java/lang/TIncompatibleClassChangeError.java","org/teavm/classlib/java/lang/TLinkageError.java","org/teavm/classlib/java/lang/TError.java","org/teavm/classlib/java/lang/TNoSuchMethodError.java","org/teavm/classlib/java/lang/TIllegalArgumentException.java","org/teavm/classlib/java/lang/TAssertionError.java","org/teavm/classlib/java/lang/TArrayStoreException.java","org/teavm/classlib/java/lang/TNullPointerException.java","org/teavm/classlib/java/lang/TIllegalStateException.java","org/teavm/classlib/java/nio/TCharBufferImpl.java","org/teavm/classlib/java/nio/TBufferUnderflowException.java","org/teavm/classlib/java/nio/TReadOnlyBufferException.java","org/teavm/classlib/java/lang/TUnsupportedOperationException.java","org/teavm/classlib/java/nio/TBufferOverflowException.java","org/teavm/classlib/java/nio/charset/TCoderMalfunctionError.java","org/teavm/classlib/java/nio/charset/TBufferOverflowException.java","org/teavm/classlib/java/nio/charset/TCharacterCodingException.java","org/teavm/classlib/java/io/TIOException.java","org/teavm/classlib/java/nio/charset/TBufferUnderflowException.java"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;yBA4NA,gBCpJA,W,CACA,O,KAEA,gBACA,W,EACA,SAVA,MACA,oB,EDwJA,S;mCAwBA,QEzMA,UCsKA,IDlJA,GCkJA,OHyDA,IACA,U,EACA,wB,CI3NA,KJ6NA,MI7NA,IDgKA,IDlJA,GCkJA,ID2UA,oBGreA,sBACA,I,MAAA,G,EACA,mBADA,Q,CL4LA,S;yBA+EA,eACA,8B,EACA,SM3QA,MACA,MN0QA,K,CAEA,QACA,4BACA,S;;qNKtSA,UDVA,mBUJA,UCSA,oBAkEA,aE1EA,SAGA,kBCEA,QACA,e,MAAA,G,EACA,EADA,IACA,EADA,Q,CAGA,SACA,UDVA,KLJA,SAMA,UANA,KACA,SAKA,UALA,KACA,SAIA,UAJA,KOAA,QAOA,MACA,MARA,KACA,QAMA,MACA,MAPA,KNHA,SAKA;MALA,KACA,SAIA,UAJA,KQEA,UDIA,OAOA,+BX1BA,gBCwOA,SHgEA,SACA,OA1CA,mBA2CA,MACA,UAqCA,qBGxGA,MAOA,O,YACA,sCFjMA,Y,EACA,SQ/BA,KR+BA,EQ/BA,CLUA,QTUA,USVA,MACA,WAeA,OACA,QHIA,K,IAEA,KChDA,OCsPA,IAIA,ML8UA,O,EACA,0B,YAAA,O,CAAA,eACA,mBADA,Q,GAIA,MExMA,WAOA,IAPA,gBAOA,E,MACA;KACA,KADA,GACA,CADA,C,EAEA,M,CGrJA,EH+HA,iBG/HA,CACA,W,EACA,e,iBA5IA,I,uBA4IA,6BH+MA,UG3VA,I,YAAA,iCDhHA,KCgHA,KDhHA,EACA,cCqPA,I,YAAA,mC,YDrPA,uCACA,e,YAAA,iC,YAAA,uCAEA,O,YAAA,yC,YAAA;oBACA,O,cAAA,yC,cAAA,yBACA,Q,cAAA,yC,cAAA,yBAEA,c,cAAA,iC,cAAA,uCACA,c,cAAA,iC,cAAA,uCACA,e,cAAA,iC;YAAA,uCAEA,W,cAAA,2C,cAAA,yBACA,W,cAAA,2C,cAAA,yBACA,Y,cAAA,2C,cAAA,yBAEA,c,cAAA,iC,cAAA,uCACA,c,cAAA;+B,cAAA,uCACA,e,cAAA,iC,cAAA,uCAEA,O;;;;uBR4CA,W,CACA,YAEA,gBACA,W,EACA,SAVA,MACA,oB,CAWA,S;yBqBgKA,ErByDA,GqBzDA,YrBvKA,W,CACA,O,KAEA,gBACA,W,EACA,SAVA,MACA,oB,EAoOA,S;;;;;yBqBlOA,Q,CACA,SAEA,qBACA,I,MAAA,U,EACA,a,CACA,SAFA,Q,CAKA,S;;;;;;;6BjB/BA,0CACA,I,MAAA,G,EACA,UADA,Q;yCAqCA,0BACA,IACA,I,MAAA,G,EACA,wBACA,U,EAIA,qB,MAHA,aUuIA,OADA,WACA,gBVvIA,CACA,aU0IA,oBV1IA,C,CAJA,gB,CASA,2B,EkBtDA,OC6HA,M,C,ID1HA,SADA,I,MAAA,G,EACA,UADA,Q,ClBqDA,M;yBA4BA,O,EAAA,wB,CAGA,Y,CAFA,SCrEA,MACA,MDoEA,K;mCAwZA,Q,CACA,SAEA,oB,CACA,SArYA,4CAwYA,O,CACA,SAEA,I,kBAAA,iB,CAAA,MAnaA,M,CAAA,e,CAAA,QAGA,OAHA,M,CAAA,e,CAAA,QAoaA,MAjaA,I,CAkaA,SAFA,Q,CAKA,S,CAvaA,SCrEA,MACA,MDoEA,K,CAAA,SCrEA,MACA,MDoEA,K;8BAidA,O,EACA,0B,YAAA,O,CAAA,eACA,mBADA,Q,GAIA,W;iCA3bA,kB,SAudA,SAEA,iBACA,IACA,I,YAAA,6B,CAAA,M,GACA,eUtdA,EVsdA,IUtdA,mB,EVsdA,QUldA,IVkdA,IUldA,kB,EVsdA,aiBraA,qBPjCA,EVscA,IUtcA,WVscA,IUtcA,cOiCA,EP4CA,4BVyXA,a,EAFA,aiBnaA,qBjBmaA,IiBnaA,EP4CA,4BALA,MV4XA,C,CAHA,Y,CAUA,iB;cA5lBA,U;;;iBCkCA,MACA,MAEA,M;eAmCA,S;;;;;kCJxCA,O,EAAA,a,EAGA,W,CACA,Q,KGmFA,sB,CHjFA,SCxDA,KD0DA,EG2EA,eH3EA,EC1DA,ED2DA,c,MAAA,I,EACA,eGyEA,eHzEA,SADA,W,CG0EA,sBHvEA,UAEA,I,eAAA,iB,CAAA,MACA,cG4CA,M,CAAA,e,CAAA,QH5CA,UG+CA,IH/CA,CADA,Y,CAGA,S,CG2CA,SCrEA,MACA,MDoEA,K,EH3DA,SIVA,MACA,MJSA,K;sCAgCA,IACA,M,EACA,IACA,Q,IAEA,M,OAKA,a,KAHA,aACA,+B,CAIA,oB,MAEA,IACA,IACA,iB,eACA,gB,EAIA,IAJA,Q,CAEA,QACA,M,CAAA,U,QAKA,QAEA,a,KACA,I,KACA,2B,aAEA,O,CAAA,QACA,oCACA,QACA,Y,GAGA,S;+CAqDA,Y,OACA,aACA,2BACA,gBACA,QACA,S,QAEA,aACA,2BACA,gBACA,gBACA,QACA,S,CACA,e,EACA,aACA,2BACA,gBACA,QACA,S,CACA,mB,EACA,M,EACA,iB,MAEA,aACA,2B,CAEA,2BACA,iBACA,iBACA,iBACA;IACA,iBACA,iBACA,SACA,S,CAGA,KACA,QACA,OACA,OACA,OACA,IACA,I,KAEA,IAIA,IACA,QACA,M,CACA,QAIA,O,CAAA,I,KAAA,S,CAAA,I,KACA,M,EAKA,qBACA,QACA,I,MANA,QACA,QsB7EA,M,C,ItB8EA,I,OAUA,QACA,mB,CACA,QAEA,M,CACA,Q,OAIA,I,CACA,QAKA,QAHA,OAGA,I,MACA,I,KACA,2B,CAEA,YACA,I,MAAA,G,EAEA,O,CAIA,I,KAHA,QACA,Q,CAIA,uCACA,W,KAAA,I;CACA,gB,CAEA,SAZA,Q,OAiBA,2BACA,O,CAAA,I,KACA,QACA,gB,CAEA,O,CAAA,I,KACA,mC,CAEA,2B,CAEA,S;yBA0IA,oB,CACA,SAEA,IACA,IACA,mB,EACA,IACA,Y,CAEA,oB,CAAA,I,KACA,MAGA,kB,CAAA,I,KACA,MAGA,kB,CACA,MAEA,S;iCAsDA,6B,CACA,OAEA,gB,CAEA,a,KADA,YsB/VA,M,C,IAAA,M,C,I,CDjIA,OC6HA,M,C,ID1HA,SADA,I,MAAA,G,EACA,UADA,Q,CrBgeA,M;8BAyIA,cCroBA,KDsoBA,WCtoBA,EDuoBA,Q,MAAA,I,EACA,6BADA,W,CAGA,kB;;;;;yCEpZA,UAEA,IACA,S,KAEA,K,KAAA,IAEA,Q,MAAA,I,KAEA,MAEA,Q,MAAA,I,KAEA,MAEA,Q,MAAA,I,KAEA,MAEA,Q,CAEA,MAEA,oB;cArQA,mB;;;;iBE4CA,MACA,MAEA,M;;;iBAHA,MACA,MAEA,M;;;;iBAHA,MACA,MAEA,M;;oLI0LA,MHuIA,W,EAoBA,c,MACA,oB,EACA,M,UFiLA,O,EACA,0B,YAAA,O,CAAA,eACA,mBADA,Q,GAIA,MExMA,WAOA,IAPA,gBAOA,E,MACA,Q,EAAA,S,EAAA,MA8QA,sB,CA7QA,M,CACA,M,EGrJA,EH+HA,iBG/HA,CACA,W,EACA,eArNA;MACA,MAKA,OACA,MH6ZA,U,CGrNA,S;+LAIA,MHuIA,W,EAoBA,c,MACA,oB,EACA,M,UFiLA,O,EACA,0B,YAAA,O,CAAA,eACA,mBADA,Q,GAIA,MExMA,WAOA,IAPA,gBAOA,E,MACA,Q,EAAA,S,EAAA,MA8QA,sB,CA7QA,M,CACA,M,EGrJA,EH+HA,iBG/HA,CACA,W,EACA;cArNA,UACA,MAKA,OACA,M,MAuDA,I,EACA,I,iBHqWA,U,YGtWA,U,EACA,I,iBA4JA,S,OA5JA,uCACA,MHoWA,UGzMA,S,OA5JA,uCACA,MA2JA,S;8CA0IA,W,CAAA,YACA,QQjVA,Q,KAwEA,KAvEA,WXoUA,W,EAoBA,c,MACA,oB,EACA,M,UFiLA,O,EACA,0B,YAAA,O,CAAA,eACA,mBADA,Q,GAIA,MExMA,WAOA,IAPA,gBAOA,E,MACA,Q,EAAA,S,EAAA,MA8QA,sB,CA7QA,M,CACA,M,EWlVA,EX4TA,iBW5TA,CACA,W,EACA,SZbA,MACA,MoBrCA,URiDA,K,CbWA,EoBnCA,MpBmCA,QoBnCA,iBE1BA,SAGA,MACA,MFHA;IAIA,MACA,MACA,MACA,MGDA,MACA,M,OVqFA,KADA,GADA,GADA,MACA,CADA,EACA,CACA,CADA,EACA,CACA,I,Q,yEAEA,SZlCA,MACA,MAEA,UACA,MY8BA,K,CSnFA,M,OAgBA,GtBuDA,EsB3EA,G,CtB4EA,IwBlDA,GxBkDA,C,KAEA,IsBNA,OtBMA,iByBMA,mB,CpBoSA,S;;8CFhWA,Y,EACA,SQ/BA,KR+BA,EQ/BA,CLUA,QTUA,USVA,MACA,WAeA,OACA,QHIA,K,CAEA,U;+CAsBA,qB,EAGA,4CACA,O,QAGA,Q,ERuIA,gBCpJA,W,CACA,O,KAEA,gBACA,W,EACA,SAVA,MACA,oB,EOkBA,QRsIA,gBCpJA,W,CACA,O,KAEA,gBACA,W,EACA,SAVA,MACA,oB,EOmBA,QACA,qB,EAGA,Q,CAAA,Qc+HA,KrBoDA,GqBpDA,yBrBoDA,GqBpDA,qB,Ed7HA,IAEA,Q,MAAA,G,EACA,iBPCA,EODA,IPCA;KqB3CA,gEACA,mBADA,K,Ed4CA,cACA,SFzCA,MACA,MEwCA,K,CAJA,Y,CAOA,cACA,O,CcmHA,KrBoDA,GqBpDA,qB,CdlHA,QckHA,GrBoDA,GqBpDA,oB,CdlHA,Q,KAAA,Q,CAfA,SF/BA,MACA,ME8BA,K,EAoBA,cACA,O,CALA,SF/CA,MACA,ME8CA,K,CAtBA,QFzBA,MACA,MEwBA,K,CAJA,SFVA,MACA,MAEA,UEOA,K;;;;+CuBxDA,aAGA,OACA,QACA,+BACA,YAEA,cACA,I,MACA,I,EACA,2BACA,Y,CAGA,Q1BUA,iCACA,I,MAAA,G,EACA,UADA,Q,C0BXA,S;;;;;qBxB2OA,gB,CACA,kB,MAGA,UAEA,QACA,SACA,SACA,SACA,SAEA,OADA,SACA,K;qBAgIA,c,MACA,oB,EACA,M,CAEA,S;mCAuDA,W,EA3DA,kB,MACA,oB,EACA,M,CA2DA,W,EACA,cACA,OA+BA,SApcA,OyBLA,MACA,MzBKA,MAocA,SACA,OAhCA,2B,CA2EA,e,UFwCA,O,EACA,0B,YAAA,O,CAAA,eACA,mBADA,Q,GAIA,MElHA,8BA/EA,O,MACA,Q,EAAA,S,EAAA,MA8QA,sB,CA7QA,M,CACA,M,CA8EA,W,EACA,cAqBA,SApcA,OyBLA,MACA,MzBKA,MAocA;mBACA,OArBA,2B,CAgEA,e,EA1DA,MACA,MACA,S;qCAqCA,gBAhRA,mBAmRA,IAIA,Q,YAJA,yB,CAAA,MACA,OACA,U,MACA,Q,EACA,QACA,MACA,SACA,W,CAPA,Q,CAWA,MA7MA,qB;iBA6UA,2B;;;yB0BtoBA,oFACA,gC,EACA,S3BsCA,MACA,MAEA,U2BzCA,K,CvB4PA,wBACA,SAAA,cAAA,oCAMA,SAAA,OAAA,kCAMA,SAAA,OAAA,0CAMA,SAAA,cAAA,kDAMA,SAAA,OAAA,gD;;yBAqCA,EADA,sCACA,oDAEA,SAAA,cAAA,kDAMA,SAAA,OAAA,gD;;2BA2BA,EADA,uCACA,0EAEA,SAAA,OAAA,kDAMA,SAAA,OAAA,gD;;;;;;+BwBxWA,I,MAAA,G,EACA,4BADA,Y;;;8CvB4GA,SADA,QmB/FA,4BHnBA,SAGA,MACA,MGDA,MACA,MDGA,MACA,MACA,MlB0GA,OagCA,M,C,IAIA,O,C,KbpCA,OcrFA,EdqFA,McrFA,QAJA,iBE1BA,SAGA,MACA,MFHA,QAIA,MACA,MACA,MACA,MGDA,MACA,MjB6GA,gBwB9DA,W,EACA,Q7BRA,MACA,MAEA,U6BKA,K,CAEA,MAgBA,M,YhB3DA,ER0GA,aQ1GA,UQHA,MhB2FA,kB,CACA,OAEA,W,QApCA,YAGA,Q;iBADA,O,CgBZA,MACA,QACA,S,MhB8DA,M,aQ7GA,ERkHA,SQlHA,UQHA,MhB2FA,kB,CACA,OAEA,W,QApCA,YAGA,Q,kEADA,O,CgBZA,MACA,QACA,S,MhBsEA,M;yBAmEA,MRXA,IDlJA,GCkJA,IDkRA,MAIA,aACA,eS3QA,M;qCAaA,MTuTA,MSvTA,yB,CAAA,OACA,QTuXA,M,EACA,QI9hBA,MACA,MAEA,UJ2hBA,K,OAEA,G,EACA,sD,CS1XA,YACA,GT8XA,K;;6BkChkBA,iB;ctBtBA,U;;;mJJ0BA,UACA,MAKA,OACA,M,MAuDA,I,EACA,I,iBApDA,O,OAoDA,uCACA,MArDA,O;6HAmDA,a,EACA,I,iBAGA,O,OAHA,uCACA,MAEA,O;gPAOA,I,YAAA,iCA4RA,W,CAAA,O,KACA,QQjVA,Q,KAwEA,KAvEA,WXoUA,W,EAoBA,c,MACA,oB,EACA,M,UFiLA,O,EACA,0B,YAAA,O,CAAA,eACA,mBADA;M,GAIA,MExMA,WAOA,IAPA,gBAOA,E,MACA,Q,EAAA,S,EAAA,MA8QA,sB,CA7QA,M,CACA,M,EWlVA,EX4TA,iBW5TA,CACA,W,EACA,SZbA,MACA,MoBrCA,URiDA,K,CbWA,EoBnCA,MpBmCA,QoBnCA,iBExBA,MAFA,SAGA,MACA,MFHA,QAIA,MACA,MACA,MACA,MGDA,MACA,M,OVqFA,KADA,GADA,GADA,MACA,CADA,EACA,CACA,CADA,EACA,CACA,I,Q,yEAEA,SZlCA,MACA,MAEA,UACA,MY8BA,K,CSnFA,M,OAgBA,GtBuDA,EsB3EA,G,CtB4EA,IwBlDA,GxBkDA,C,KAEA,IsBNA,OtBMA;GyBMA,mB,EpBOA,S;+LAgBA,M,CACA,YAEA,M,EAAA,iB,QAEA,I,KACA,uBACA,c,CAEA,S,EArHA,EAuHA,IAvHA,IAuHA,M,YAAA,iCACA,W,CACA,YAEA,oBACA,sBACA,gBACA,I,MAAA,c,EACA,kBADA,Q,CAGA,M,QAKA;G,KAHA,yBACA,qB,EAKA,S;0NA0OA,W,CAAA,O,KQ3UA,Q,KAwEA,KAvEA,WXoUA,W,EAoBA,c,MACA,oB,EACA,M,UFiLA,O,EACA,0B,YAAA,O,CAAA,eACA,mBADA,Q,GAIA,MExMA,WAOA,IAPA,gBAOA,E,MACA,Q,EAAA,S,EAAA,MA8QA;oB,CA7QA,M,CACA,M,EWlVA,EX4TA,iBW5TA,CACA,W,EACA,SZbA,MACA,MoBrCA,URiDA,K,Cb6fA,MyBxhBA,EzBwhBA,MyBxhBA,QAJA,iBHjBA,MAFA,SAGA,MACA,MGDA,MACA,MDGA,MACA,MACA,M,OX+FA,KADA,GADA,GADA,MACA,CADA,EACA,CACA,CADA,EACA,CACA,I,Q,yEAEA,SZ7CA,MACA,MAEA,UACA,MYyCA,K,CS9FA,M,OAgBA,GtBohBA,EsBxiBA,G,CF4GA,M,KpB+bA,IsBneA,OtBmeA,EoB7eA,SpB6eA,MoB7eA,S,Ef+EA,I,YAAA,2BACA,O;;0MAOA,iB,EAGA,uBACA,M,QAEA,I,KACA,OACA,c,CAEA,M,iBAGA,qBACA,mBACA,aArKA,EAsKA,IAtKA,IAsKA,M,iBAfA,O,OAeA,2C,EFtIA,Y,EACA,SQtCA,KRsCA,EQtCA,CLUA,QTUA,USVA,MACA;OAeA,OACA,QHWA,K,CAEA,KEoIA,QRxJA,UCsKA,IDlJA,GCkJA,QOdA,MPcA,IDlJA,GCkJA,ID2UA,oBGreA,sBACA,I,MAAA,G,EACA,mBADA,Q,CMoKA,MRXA,IDlJA,GCkJA,IDkRA,MAIA,aACA,eS3QA,M,CDvBA,O,OATA,uBASA,O;+LAOA,M,EAAA,uB,EACA,iCACA,oBACA,oBApLA,EAqLA,IArLA,IAqLA,M,kBAIA,O,OAJA,2C,EFrJA,Y,EACA,SQtCA,KRsCA,EQtCA,CLUA,QTUA,USVA,MACA,WAeA,OACA,QHWA,K,CAEA,KEmJA,QRvKA,UCsKA,IDlJA,GCkJA,QOCA;KPDA,IDlJA,GCkJA,ID2UA,oBGreA,sBACA,I,MAAA,G,EACA,mBADA,Q,CMoKA,MRXA,IDlJA,GCkJA,IDkRA,MAIA,aACA,eS3QA,M,CDRA,O;;;;uCKaA,cADA,WACA,iB;eAIA,4B;iBAyGA,mB,CAGA,iDAFA,S;cAlTA,oBAkEA,a;;;qBsBrEA,SAJA,MAIA,S;iBAKA,S;iBAKA,U;;;;;uB3B0PA,qB2B/PA,S;;uB3BqQA,c2BrQA,S;;;mC3B2QA,8C4BnDA,0BACA,I,MAAA,G,EACA,wBADA,Q,CC/NA,Y7BiRA,oC;;uBAMA,qB2BjRA,S;;uB3BuRA,c2BvRA,S;;0BhC0HA,sB,UarHA,SZqBA,MACA,MkCrCA,OtBeA,K,CbyFA,O,EACA,SCrEA,MACA,MDoEA,K,CaxFA,Ob0FA,Ia1FA,C,EACA,SZkBA,MACA,MkCrCA,OtBkBA,K,CAEA,I,eb4GA,Wa5GA,Ob4GA,Qa5GA,S,CAAA,MboFA,M,CAAA,e,CAAA,Q,GAGA,O,gEa7EA,Q,CAAA,Q,KACA,SZKA,MACA,MkCrCA,OtB+BA,K,GAXA,Q,CAgBA,O,CbqEA,SCrEA,MACA,MDoEA,K;qBalEA,oC,EAAA,O,CAAA,e,CAAA,Q,CAAA,Y,CAAA,I,CAAA,S;eAoBA,W;qCAiCA,KADA,GADA,GADA,MACA,CADA,EACA,CACA,CADA,EACA,CACA,I,uDAAA,Q,kBAHA,S,CAKA,SZlCA,MACA,MAEA,UACA,MY8BA,K;qCASA,KADA,GADA,GADA,MACA,CADA,EACA,CACA,CADA,EACA,CACA,I,uDAAA,Q,kBAHA,S,CAKA,SZ7CA,MACA,MAEA,UACA,MYyCA,K;;iCD5FA,SwBPA,+BAJA,YACA,YxBUA,S;6BAKA,SkBIA,wBAbA,WACA,MA+BA,W,MAAA,M,EA1BA,OACA,WACA,SACA,QOhBA,YACA,YzBeA,S,CkBwBA,QQnCA,YRmCA,K;4BlB1CA,SAGA,kBCEA,QACA,e,MAAA,G,EACA,EADA,IACA,EADA,Q,CAGA,SACA,UDVA,K;;;;;;;;;;;qCUeA,e,EAIA,MACA,Q,CACA,MAEA,S,CAPA,gBzBKA,UCsKA,IDlJA,GCkJA,QDjHA,cCiHA,IDlJA,GCkJA,QwB3KA,MzB0DA,cCiHA,IDlJA,GCkJA,QD2UA,oBGreA,sBACA,I,MAAA,G,EACA,mBADA,Q,CCaA,MACA,MAEA,MqBlCA,K;eAkDA,QACA,MACA,SACA,S;;;6CGAA,O,EAAA,0B,EAGA,c,EACA,gB5BpDA,UCsKA,IDlJA,GCkJA,QDjHA,cCiHA,IDlJA,GCkJA,QDjHA,cA4bA,oBGreA,sBACA,I,MAAA,G,EACA,mBADA,Q,CCaA,MACA,MAEA,MwBuBA,K,CHMA,YGHA,GHGA,OGHA,E,EACA,SxBzCA,MACA,MwBwCA,K,CAEA,O,EAIA,Q,MAAA,G,EACA,qBDlEA,iBCkEA,CADA,gB,CAGA,UACA,S,CAPA,gB5B3DA,UCsKA,IDlJA,GCkJA,QDjHA,cCiHA,IDlJA,GCkJA,QD2UA;mBGreA,sBACA,I,MAAA,G,EACA,mBADA,Q,CCaA,MACA,MAEA,MwB8BA,K,EAVA,yB5BjDA,UCsKA,IDlJA,GCkJA,QDjHA,cCiHA,IDlJA,GCkJA,Q2BrHA,W5BIA,cCiHA,IDlJA,GCkJA,QD2UA,oBGreA,sBACA,I,MAAA,G,EACA,mBADA,Q,CCaA,MACA,MAEA,MwBoBA,K;6CD3BA,M,ECsEA,SxB7EA,MACA,MwB4EA,K,CHlCA,YGoCA,GHpCA,OGoCA,E,EACA,SxBhFA,MACA,MwB+EA,K,CAEA,O,EAAA,0B,EAGA,c,EACA,gB5BrGA,UCsKA,IDlJA,GCkJA,QDjHA,cCiHA,IDlJA,GCkJA,QDjHA,cA4bA,oBGreA,sBACA,I,MAAA,G,EACA,mBADA,Q,CCaA,MACA,MAEA,MwBwEA,K,CAGA,O,EAIA,Q,MAAA,G,EACA,gBD3GA,kBC2GA,ID3GA,CC0GA,gB,CAGA,UACA,S,CAPA,gB5BzGA,UCsKA;ADlJA,GCkJA,QDjHA,cCiHA,IDlJA,GCkJA,QD2UA,oBGreA,sBACA,I,MAAA,G,EACA,mBADA,Q,CCaA,MACA,MAEA,MwB4EA,K,EAPA,yB5BlGA,UCsKA,IDlJA,GCkJA,QDjHA,cCiHA,IDlJA,GCkJA,Q2BpEA,W5B7CA,cCiHA,IDlJA,GCkJA,QD2UA,oBGreA,sBACA,I,MAAA,G,EACA,mBADA,Q,CCaA,MACA,MAEA,MwBqEA,K;2CD5EA,M,ECmGA,SxB1GA,MACA,MwByGA,K,CAEA,QHjEA,YGkEA,GHlEA,OGkEA,E,EACA,SxB9GA,MACA,MwB6GA,K,CAEA,O,EzBpBA,kByBoBA,M,EAGA,M,EACA,gB5BnIA,UCsKA,IDlJA,GCkJA,QDjHA,cCiHA,IDlJA,GCkJA,QE3DA,kBHtDA,cA4bA,oBGreA,sBACA,I,MAAA,G,EACA,mBADA,Q,CCaA,MACA,MAEA,MwBuGA,K,CAEA,O,QAIA,G,EACA,gBDzIA,kBCyIA,ODzIA,S,CC2IA,YACA,S,CAPA,gB5BvIA,UCsKA;ADlJA,GCkJA,QDjHA,cCiHA,IDlJA,GCkJA,QDjHA,cA4bA,oBGreA,sBACA,I,MAAA,G,EACA,mBADA,Q,CCaA,MACA,MAEA,MwB0GA,K,EAPA,gB5BhIA,UCsKA,IDlJA,GCkJA,QDjHA,cCiHA,IDlJA,GCkJA,QE3DA,kBHtDA,cCiHA,IDlJA,GCkJA,QD2UA,oBGreA,sBACA,I,MAAA,G,EACA,mBADA,Q,CCaA,MACA,MAEA,MwBmGA,K;eHnFA,QACA,MACA,SG+OA,S;;;6CLpQA,O,EAAA,0B,EAGA,c,EACA,gBvB9BA,UCsKA,IDlJA,GCkJA,QDjHA,cCiHA,IDlJA,GCkJA,QDjHA,cA4bA,oBGreA,sBACA,I,MAAA,G,EACA,mBADA,Q,CCaA,MACA,MAEA,MmBCA,K,CE4BA,YFzBA,GEyBA,OFzBA,E,EACA,SnBnBA,MACA,MmBkBA,K,CAEA,O,EAGA,UACA,I,MAAA,G,EACA,qCADA,gB,CAGA,UACA,S,CAPA,gBvBrCA,UCsKA,IDlJA,GCkJA,QDjHA,cCiHA,IDlJA,GCkJA;OD2UA,oBGreA,sBACA,I,MAAA,G,EACA,mBADA,Q,CCaA,MACA,MAEA,MmBQA,K,EAVA,yBvB3BA,UCsKA,IDlJA,GCkJA,QDjHA,cCiHA,IDlJA,GCkJA,QsB3IA,WvB0BA,cCiHA,IDlJA,GCkJA,QD2UA,oBGreA,sBACA,I,MAAA,G,EACA,mBADA,Q,CCaA,MACA,MAEA,MmBFA,K;mDA8BA,SGaA,M,EHVA,SnB7CA,MACA,MmB4CA,K,CEFA,YFIA,GEJA,OFIA,E,EACA,SnBhDA,MACA,MmB+CA,K,CAEA,O,EAAA,0B,EAGA,c,EACA,gBvBrEA,UCsKA,IDlJA,GCkJA,QDjHA,cCiHA,IDlJA,GCkJA,QDjHA,cA4bA,oBGreA,sBACA,I,MAAA,G,EACA,mBADA,Q,CCaA,MACA,MAEA,MmBwCA,K,CAGA,O,EAGA,UACA,I,MAAA,G,EACA,qCADA,gB,CAGA,UACA,S,CAPA;MvBzEA,UCsKA,IDlJA,GCkJA,QDjHA,cCiHA,IDlJA,GCkJA,QD2UA,oBGreA,sBACA,I,MAAA,G,EACA,mBADA,Q,CCaA,MACA,MAEA,MmB4CA,K,EAPA,yBvBlEA,UCsKA,IDlJA,GCkJA,QDjHA,cCiHA,IDlJA,GCkJA,QsBpGA,WvBbA,cCiHA,IDlJA,GCkJA,QD2UA,oBGreA,sBACA,I,MAAA,G,EACA,mBADA,Q,CCaA,MACA,MAEA,MmBqCA,K;;wDb3FA,SAMA,UANA,KACA,SAKA,UALA,KACA,SAIA,UAJA,K;;;;uBuBwDA,W,EAGA,MAEA,S,CAJA,Q7BRA,MACA,MAEA,U6BKA,K;;uBAeA,W,EAGA,MAEA,S,CAJA,Q7BxBA,MACA,MAEA,U6BqBA,K;;+CAmBA,c,OAAA,e,CAAA,Q,CACA,S7BvDA,MACA,M6BsDA,K,CAGA,Y,gBAIA,Y,sDAEA,S7B1BA,MACA,MAEA,M6BuBA,K,kBhB1FA,M,gBgBqGA,SRhCA,YQ0BA,O,CAGA,ShBvEA,QAhCA,MACA,M,MAQA,W,CgBmGA,M,GhBvFA,Y,YgB2FA,S,EAMA,S,CAAA,Q,KACA,S,CR7CA,YQuCA,6B,CACA,UVdA,Y,CE9FA,MRWA;e,SAIA,W,OAKA,SbKA,MACA,MaNA,K,CWqSA,KKrMA,EhB9FA,GgB8FA,ELqMA,E,CKlNA,S;qCRnCA,Y,OF1DA,SGrBA,ODDA,SAGA,MACA,MFHA,QAIA,MACA,MACA,MACA,MGDA,MACA,MO8HA,S,CAmGA,OAhGA,WVtHA,M,EACA,gBvBEA,UCsKA,IDlJA,GCkJA,QDjHA,cA4bA,oBGreA,sBACA,I,MAAA,G,EACA,mBADA,Q,CCaA,MACA,MAEA,MmB/BA,K,CAEA,SGrBA,ODDA,SAGA,MACA,MFHA,QAIA,MACA,MACA,MACA,MGDA,MACA,M,YOqIA,cACA,S,CAAA,MAEA,S,EACA,UACA,S,CAEA,S,CAAA,SACA,M,CAIA;ahBlIA,iB,MAIA,W,4CAuBA,SbbA,MACA,MaYA,K,OAEA,ebfA,MACA,MsCrCA,OzBmDA,K,OAEA,ebjBA,MACA,MuCrCA,O1BqDA,K,QAAA,Q,CANA,SbXA,MACA,MaUA,K,cArCA,EgBoJA,ShBpJA,G,SgBqJA,M,IhBjJA,U,CgBmJA,SACA,U,CV+FA,MU3FA,S;mCVnDA,WU+FA,mBZpLA,OCoHA,M,C,IDjHA,SADA,I,MAAA,G,EACA,UADA,Q,CEHA,WAJA,iBE1BA,SAGA,MACA,MFHA,QAIA,MACA,MACA,MACA,MGDA,MACA,MH4QA,KExQA,GFwQA,EU9DA,S;yBAIA,oB,EACA,S7BtLA,MACA,M6BqLA,K,CAUA,KAPA,Q,CACA,OAEA,S;iBAIA,U;eAIA,OAEA,S;;;;mBhBrOA,MACA,M;eAIA,e;uBAYA,iBAJA,WAQA,WARA,K;qBAmBA,QAhCA,MACA,MA+BA,S;uBAQA,U,SAEA,SbXA,MACA,MaUA,K,OAEA,SbbA,MACA,MaYA,K,OAEA,ebfA,MACA,MsCrCA,OzBmDA,K,OAEA,ebjBA,MACA,MuCrCA,O1BqDA,K;oBAvDA,QAOA,MACA,MARA,KACA,QAMA,MACA,MAPA,K;;;4CNHA,SAKA,UALA,KACA,SAIA,UAJA,K;;;;+C6BmBA,OACA,IACA,IACA,O,eAMA,a,Ef0DA,uB,Ee1DA,I,MACA,G,EACA,uBADA,Q,CAIA,SADA,QACA,EfiDA,OejDA,gBlBoHA,M,C,IkBnHA,gBACA,I,EfmDA,0B,EAAA,e,Me/CA,I,OACA,Q,CAKA,SfqCA,QerCA,WlBwGA,M,C,IkBvGA,SAoCA,OACA,MApCA,sBACA,OACA,OACA,W,EfoCA,e,OenCA,I,CACA,K,KfkCA,oBejCA,I,CACA,K,CAKA,YACA;I,CAAA,M,EZ2QA,KHzTA,GemDA,UZsQA,EYpQA,S;;iDI1DA,O,SACA,G,EAAA,O,EAAA,Y,CACA,wBACA,Q,EACA,gC,MACA,S,EACA,Y,EACA,WJmFA,SfjBA,WeiBA,M,CIlFA,QACA,a,CAIA,yCACA,gC,M/BsHA,wB,iBAIA,e,O+BxHA,Y,EACA,WJyEA,SfjBA,WeiBA,M,CIxEA,QACA,a,CAIA,0CACA;8BACA,gC,mB3BMA,QAhCA,MACA,M2BqDA,Q,CA1BA,O,EJmDA,OfDA,e,CmBjDA,QACA,a,CAIA,e/BuGA,0B,E+BrGA,W3BJA,QAhCA,MACA,M2BqCA,Q,CAEA,Y,EACA,WJkDA,SfjBA,WeiBA,M,CIjDA,QACA,a,CAKA,S/ByGA,gC+BzGA,iCACA,oCACA,mCACA,oC,EACA,Q,CAIA;G,CJuCA,OAIA,OIvCA,S;;;;4B5BsDA,SXiKA,SACA,OA1CA,mBA2CA,MACA,UAqCA,qBWzMA,KAGA,oEAGA,e,MAAA,G,EAAA,OXgUA,GW/TA,EX+TA,CWlYA,GXkYA,IWhUA,Q;;;;;;;;;kC6BzHA,MACA,SCJA,kB9BIA,SACA,e,MAAA,G,EACA,EADA,IACA,EADA,Q,CAGA,UACA,U6BLA,KACA,SELA,kB/BIA,SACA,e,MAAA,G,EACA,EADA,IACA,EADA,Q,CAGA,UACA,U6BJA,KACA,SGHA,kBhCCA,SACA,e,MAAA,G,EACA,EADA,IACA,EADA,Q,CAGA,UACA,UgCLA,OACA,OHCA,KACA,SGJA,kBhCCA,SACA,e,MAAA,G,EACA,EADA,IACA,EADA,Q,CAGA,UACA,UgCLA,OACA,OHEA,KACA,SGLA,kBhCCA,SACA;c,MAAA,G,EACA,EADA,IACA,EADA,Q,CAGA,UACA,UgCLA,OACA,OHGA,K;;qBCEA,SPLA,gBAJA,YACA,YOQA,S;6BAKA,SbMA,wBAbA,WACA,MA+BA,W,MAAA,M,EA1BA,OACA,WACA,SACA,QOhBA,YACA,YMaA,S,Cb0BA,QQnCA,YRmCA,K;;qBc/BA,SRLA,gBAJA,YACA,YQQA,S;6BAKA,SdMA,wBAbA,WACA,MA+BA,W,MAAA,M,EA1BA,OACA,WACA,SACA,QOhBA,YACA,YOaA,S,Cd0BA,QQnCA,YRmCA,K;;yBe1BA,uBTVA,gBAJA,YACA,YUCA,OACA,ODWA,S;iCAKA,uBfCA,wBAbA,WACA,MA+BA,W,MAAA,M,EA1BA,OACA,WACA,SACA,QOhBA,YACA,YUCA,OACA,OFgBA,S,CfqBA,QQnCA,YRmCA,K;;;;;;uBzBiUA,gBAlBA,O2B/UA,S;;uB3BuWA,gBAxBA,O2B/UA,S;;;;;;6BDCA,iB;cfZA,U;;uBXyUA,0B2B9TA,S;;uB3BoUA,c2BpUA,S;;mCdg7BA,gB,EACA,QjBv5BA,MACA,MiBs5BA,K,OAGA,YAGA,Q,YAGA,SADA,cACA,OACA,O,CAAA,MAEA,O,EAMA,QACA,M,CACA,mB,MAPA,QACA,M,CACA,mB,EAJA,S;;;;;yC8B/7BA,WACA,YACA,OAIA,S,EACA,gBnDOA,UCsKA,IDlJA,GCkJA,QA9EA,KDuDA,GCvDA,IDyZA,oBGreA,sBACA,I,MAAA,G,EACA,mBADA,Q,CCaA,MACA,MAEA,M+CpCA,K,CAGA,Q,EAIA,OACA,OACA,OACA,O,CANA,gBnDGA,UCsKA,IDlJA,GCkJA,QA9EA,KDuDA,GCvDA,IDyZA,oBGreA,sBACA,I,MAAA,G,EACA,mBADA,Q,CCaA,MACA,MAEA,M+ChCA,K;uBAiCA,W,EAGA,OAEA,S,CAJA,Q/CLA,MACA,MAEA,U+CEA,K;;uBAeA,W,EAGA,OAEA,S,CAJA,Q/CrBA,MACA,MAEA,U+CkBA,K;;wCAmBA,0B,EAGA,U,gBAIA,Y,sDAEA,S/CtBA,MACA,MAEA,M+CmBA,K,kBlClFA,iB,CkCoFA,M,gB1BfA,uB,E0BmBA,Y,E1BvBA,QR1CA,QAhCA,MACA,MkCiGA,S,CAEA,G1B1BA,W0B0BA,MhDuBA,c,CgDjBA,U5BoKA,K4BzKA,E1B3BA,O0B2BA,E5ByKA,E4BxKA,Y,EACA,OvB2DA,SzBvCA,eyBuCA,E,GuBpDA,S,ClC7FA,W,EkC+FA,gB,CACA,SAEA,S,E1BzCA,Y0B0CA;MhDOA,kBgDPA,M,CACA,UvB6CA,Y,CH5JA,MRWA,iB,SAIA,W,OAKA,SbKA,MACA,MaNA,K,CMoPA,K4BrJA,ElC7FA,GkC6FA,E5BqJA,E,MNzPA,W,EkCsGA,gB,CACA,SAEA,S,E1BpDA,Y0BqDA,OhDJA,kBgDIA,M,CACA,UvBkCA,Y,CH5JA,MRWA,iB,SAIA,W,OAKA,SbKA,MACA,MaNA,K,CMoPA,K4B1IA,ElCxGA,GkCwGA,E5B0IA,E,E4BhLA,S,CAXA,S/CpDA,MACA,M+CmDA,K;uBAuDA,mB,EACA,S/C5GA,MACA,M+C2GA,K,CAEA,MACA,OA2EA,EA3EA,C;eAIA,MAEA,S;qCAIA,M,MAAA,I,EACA,S/C1HA,MACA,M+CyHA,K,C1B/EA,Y,OGjEA,SDbA,OFFA,SAGA,MACA,MGDA,MACA,MDGA,MACA,MACA,MwByJA,S,MAVA,MAgBA,W7BjBA,M,C,IM3IA,M,EACA,gB5BSA,UCsKA,IDlJA,GCkJA,QDjHA,cA4bA,oBGreA,sBACA,I,MAAA,G,EACA,mBADA,Q,CCaA,MACA,MAEA,MwBtCA,K,CAEA,SDbA,OFFA,SAGA,MACA,MGDA,MACA,MDGA,MACA,MACA,M,YwBkKA,cACA,Q,CAAA,MlC7JA,a,CkCgKA;GAEA,S,CAAA,SACA,M,CAIA,clC/JA,iB,MAIA,W,4CAuBA,Q,OAEA,W,OAEA,W,QAAA,Q,CANA,Q,ckCgGA,mB,EACA,S/C5GA,MACA,M+C2GA,K,CAEA,MlCxIA,GkCoNA,ElCpNA,M,CkCkLA,MAGA,U,CAIA,MACA,S;qCxBnKA,WwBoLA,mB7B/DA,M,C,IDjIA,OC6HA,M,C,ID1HA,SADA,I,MAAA,G,EACA,UADA,Q,CODA,WAJA,iBHnBA,SAGA,MACA,MGDA,MACA,MDGA,MACA,MACA,MC4TA,KHzTA,GGyTA,EuB5GA,S;iBAMA,U;;;;6CCxNA,O,SACA,G,EAAA,O,EAAA,Y,CACA,wBvCkIA,yB,EuChIA,O,EZ8EA,O,IAAA,CfTA,WeSA,O,EY5EA,a,CAEA,WAEA,Q,KvC8HA,EuC5HA,IvC4HA,mB,EIzGA,QAhCA,MACA,MmCcA,Q,CAEA,WnCmBA,QApCA,MACA,MmCmBA,Q,CvCqHA,e,EIzGA,QAhCA,MACA,M,CmCwBA,S,EnCWA,QApCA,MACA,MmC4BA,WACA,Q,CAJA,wC,CAMA,I,CZ+DA,OAIA,OYhEA,S;;6CClCA,O,SACA,G,EAAA,O,EAAA,Y,CACA,wBxCkIA,yB,EwChIA,O,Eb8EA,O,IAAA,CfTA,WeSA,O,Ea5EA,a,CAEA,WAEA,Q,KxC8HA,EwC5HA,IxC4HA,mB,EIzGA,QAhCA,MACA,MoCcA,Q,CAEA,WpCmBA,QApCA,MACA,MoCmBA,Q,CxCqHA,e,EIzGA,QAhCA,MACA,M,CoCwBA,S,EAGA,WpCQA,QApCA,MACA,MoC6BA,Q,CAJA,wC,CAMA,I,Cb+DA,OAIA,OahEA,S;;qCH7BA,O,EACA,Y,EVgFA,MU/EA,QzBsEA,cyBtEA,S,CAEA,OACA,Q,EAIA,2BACA,kB,MAJA,2BACA,kB,EAOA,aAEA,mBAFA,CACA,mBADA,C;6CAOA,O,SACA,G,EAAA,O,CAAA,QACA,wBrCwGA,U,IAAA,c,EAIA,e,EqC/EA,WjC1BA,QAhCA,MACA,MiC2DA,Q,CAEA,Y,EAIA,WVyBA,SfjBA,WeiBA,M,CUxBA,QACA,a,CALA,sCACA,8B,MAjCA,O,EACA,WVmDA,UfTA,WeSA,M,CUlDA,QACA,a,CAIA,erCmGA,0B,EqCpFA,WjCrBA,QAhCA,MACA,MiCsDA,Q,CAfA,Y,EAMA;OV6CA,SfjBA,WeiBA,M,CU5CA,QACA,a,CAPA,sCACA,0BACA,6BACA,0B,GVmDA,OAIA,OUtBA,S;6CAKA,O,SACA,G,EAAA,O,CAAA,QACA,wBrCiDA,U,IAAA,c,EAIA,e,EqCxBA,WjCjFA,QAhCA,MACA,MiCkHA,Q,CAEA,Y,EAIA,WV9BA,SfjBA,WeiBA,M,CU+BA,QACA,a,CALA,mCACA,iC,MAjCA,O,EACA,WVJA,UfTA,WeSA,M,CUKA,QACA,a,CAIA,erC4CA,0B,EqC7BA,WjC5EA,QAhCA,MACA,MiC6GA,Q,CAfA,Y,EAMA;OVVA,SfjBA,WeiBA,M,CUWA,QACA,a,CAPA,mCACA,6BACA,0BACA,6B,GVJA,OAIA,OUiCA,S;;6CX7HA,OACA,IACA,IACA,O,eAMA,a,Ed8DA,uB,Ec9DA,I,MACA,G,EACA,uBADA,Q,CAIA,SADA,QACA,EdqDA,OcrDA,gBjBwHA,M,C,IiBvHA,gBACA,I,EduDA,0B,EAAA,e,McnDA,I,OACA,Q,CAKA,SdyCA,QczCA,WjB4GA,M,C,IiB3GA,SAgCA,MACA,OAhCA,sBACA,OACA,mB,CACA,KAKA,SAHA,GAGA,EACA,W,CAAA,M,EhBkOA,KExQA,Gc2CA,UhB6NA,EgB3NA,S;;uDelDA,O,eACA,G,EAAA,O,CAAA,QACA,4BACA,W,EACA,8B,MACA,e,EACA,O,EACA,WfmEA,SdDA,WcCA,M,CelEA,QACA,a,CAIA,eAoEA,sB,EAlEA,WrCgBA,QAhCA,MACA,MqCiBA,Q,CAEA,iD,MACA,e,EAsBA,e,EA2BA,WrCtCA,UqCwCA,Q,CA5BA,Y,EACA,WACA,U,CAAA,QACA,a,CAIA;U,EACA,WACA,U,CAAA,QACA,a,CAIA,eACA,eACA,eACA,W,CAAA,mB,CAAA,mB,CAAA,QAMA,SADA,sCACA,mBACA,mB,MA9CA,Y,EACA,WfoDA,SdDA,WcCA,M,CenDA,QACA,a,CAIA,eACA,eAoDA,sB,CAnDA,QAmDA,sB,CAnDA,QAKA,oCzCiGA,yB,OAIA,e,MyCnGA;GrCNA,QAhCA,MACA,MqCuCA,Q,CAEA,wB,CACA,Q,CAzCA,Q,CA4DA,WACA,QACA,Q,CAhCA,WrCAA,QAhCA,MACA,M,CsBsFA,OAIA,MebA,S;iBAIA,wB;;2CCjFA,O,SACA,G,EAAA,O,CAAA,QACA,4BACA,Q,EtC4BA,QAhCA,MACA,MsCKA,WACA,Q,CAEA,sC,EhB8EA,OAIA,MgB3EA,S;;6CCfA,O,MACA,Q,EACA,SACA,SADA,mBACA,6B,CjBmFA,OAIA,MiBjFA,S;;uCPJA,O,EACA,Y,EVgEA,MU/DA,QxBsEA,cwBtEA,S,CAGA,SADA,OACA,eACA,U,EACA,a,CAIA,W,KAHA,QACA,O,OAIA,U,CAQA,W,KAPA,a,CAIA,W,KAHA,QACA,O,EASA,aAEA,mBAFA,CACA,mBADA,C;6CAOA,O,SACA,G,EAAA,O,CAAA,QACA,Y,EVmCA,SdDA,WcCA,M,CUlCA,QACA,a,CAIA,4BACA,QACA,KADA,UACA,WpCqFA,U,IAAA,c,EAIA,e,EoC7DA,WhC5CA,QAhCA,MACA,MgC6EA,Q,CAEA,4B,MA9BA,a,EVyBA,M,IAAA,CdDA,WcCA,O,CUvBA,KAEA,WACA,Q,CAEA,mBACA,QACA,KADA,UACA,WpC8EA,0B,EoC5EA,WhC7BA,QAhCA,MACA,MgC8DA,Q,CAEA;U,EVkBA,UdTA,WcSA,M,CUjBA,QACA,a,CAIA,wBACA,e,GVeA,OAIA,MUNA,S;6CAKA,O,SACA,G,EAAA,O,CAAA,QACA,Y,EVjBA,SdDA,WcCA,M,CUkBA,QACA,a,CAIA,4BACA,QACA,GADA,QACA,apCiCA,U,IAAA,c,EAIA,e,EoCTA,WhChGA,QAhCA,MACA,MgCiIA,Q,CAEA,4B,MA9BA,a,EV3BA,M,IAAA,CdDA,WcCA,O,CU6BA,KAEA,WACA,Q,CAEA,mBACA,QACA,GADA,QACA,apC0BA,0B,EoCxBA,WhCjFA,QAhCA,MACA,MgCkHA,Q,CAEA;U,EVlCA,UdTA,WcSA,M,CUmCA,QACA,a,CAIA,wBACA,e,GVrCA,OAIA,MU8CA,S;;;;e7C1GA,MACA,M;;;eADA,MACA,M;;;iBADA,MACA,MsCrCA,O;;;iBtCoCA,MACA,MuCrCA,O;;;;;;qCzBGA,OAOA,qB;;0ElBRA,0EAEA,6SAGA,yEAEA;QACA,U;;2EyD2CA,wBACA,4BACA,YACA,Y,WAEA,OACA,OACA,O,CAGA,I,KASA,Y,KAPA,O,MACA,0B,EACA,OACA,WACA,Q,EAMA,KpC22BA,SoC32BA,MpC22BA,WoC12BA,M,CACA,cAEA,UACA,IADA,UACA,GAEA,gDACA,gB,EACA,QAEA,IADA,UACA,GACA,+B,CAGA,eACA,OACA,IADA;AAEA,IAFA,EAEA,OAFA,CAGA,aACA,OACA,a,CACA,OA0BA,K,MACA,I,EACA,S,CAGA,GADA,OACA,S,CACA,SAMA,K,MACA,I,EACA,S,CAGA,MADA,OACA,W,CACA,SAvCA,mBACA,KADA,IAEA,IACA,WADA,QAGA,iBAHA,GAFA,CAQA,gB,EACA,QACA,S,MACA,c,EACA,WACA,S,CAGA,OACA,Y;kCArHA,WACA,WAMA,aAGA,MAEA,Q,MAAA,I,EACA,uCACA,aAEA,iBACA,iB,MACA,wB,EACA,OACA,QACA,O,CAEA,eAXA,Q,CAgBA,MACA,I,MAAA,I,EAEA,Q,MACA,W,EACA,OACA,QACA,W,CAGA,SACA,YAEA,cADA,iBACA,WAFA,EAMA,6CACA,aAjBA,Q;;;;uBlBiDA,adDA,WcCA,O;uBAQA,cdTA,WcSA,O"} \ No newline at end of file diff --git a/javascript/servertest.html b/javascript/servertest.html new file mode 100644 index 0000000..9979932 --- /dev/null +++ b/javascript/servertest.html @@ -0,0 +1,16 @@ + + +eaglercraft server + + + + + + + \ No newline at end of file diff --git a/sp-server/.classpath b/sp-server/.classpath new file mode 100644 index 0000000..8cd7d7c --- /dev/null +++ b/sp-server/.classpath @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/sp-server/.project b/sp-server/.project new file mode 100644 index 0000000..1ce8e25 --- /dev/null +++ b/sp-server/.project @@ -0,0 +1,23 @@ + + + eaglercraft-sp-server + Project sp-server created by Buildship. + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.buildship.core.gradleprojectbuilder + + + + + + org.eclipse.jdt.core.javanature + org.eclipse.buildship.core.gradleprojectnature + + diff --git a/sp-server/build.gradle b/sp-server/build.gradle new file mode 100644 index 0000000..12d3b81 --- /dev/null +++ b/sp-server/build.gradle @@ -0,0 +1,110 @@ + +buildscript { + repositories { + flatDir { + dirs "deps" + } + } + + dependencies { + classpath name: "gson-2.2.4" + classpath name: "joda-time-2.7" + classpath name: "jzlib-1.1.3" + classpath name: "teavm-classlib-0.7.0-SNAPSHOT" + classpath name: "teavm-interop-0.7.0-SNAPSHOT" + classpath name: "teavm-jso-0.7.0-SNAPSHOT" + classpath name: "teavm-jso-apis-0.7.0-SNAPSHOT" + classpath name: "teavm-jso-impl-0.7.0-SNAPSHOT" + classpath name: "teavm-platform-0.7.0-SNAPSHOT" + classpath name: "teavm-metaprogramming-api-0.7.0-SNAPSHOT" + classpath name: "teavm-metaprogramming-impl-0.7.0-SNAPSHOT" + classpath name: "teavm-core-0.7.0-SNAPSHOT" + classpath name: "teavm-tooling-0.7.0-SNAPSHOT" + classpath name: "teavm-cli-0.6.1" + classpath name: "teavm-gradle-plugin-1.0.0-patched" + } +} + +apply plugin: "java" +apply plugin: "eclipse" +apply plugin: "io.github.zebalu.teavm-gradle-plugin" + +sourceCompatibility = 1.8 +targetCompatibility = 1.8 + +sourceSets { + main { + java { + srcDir "src/main/java" + srcDir "src/ipc/java" + } + } +} + +repositories { + flatDir { + dirs "deps" + } +} + +dependencies { + implementation name: "gson-2.2.4" + implementation name: "joda-time-2.7" + implementation name: "jzlib-1.1.3" + implementation name: "teavm-classlib-0.7.0-SNAPSHOT" + implementation name: "teavm-interop-0.7.0-SNAPSHOT" + implementation name: "teavm-jso-0.7.0-SNAPSHOT" + implementation name: "teavm-jso-apis-0.7.0-SNAPSHOT" + implementation name: "teavm-jso-impl-0.7.0-SNAPSHOT" + implementation name: "teavm-platform-0.7.0-SNAPSHOT" + implementation name: "teavm-metaprogramming-api-0.7.0-SNAPSHOT" + implementation name: "teavm-metaprogramming-impl-0.7.0-SNAPSHOT" +} + +teavm { + + compileScopes = null; + minifying = false; + maxTopLevelNames = 10000; + properties = null; + debugInformationGenerated = false; + sourceMapsGenerated = false; + sourceFilesCopied = false; + incremental = false; + transformers = null; + + /** Where to save the result */ + targetDirectory = file("../javascript"); + + /** The directory to monitor to decide if compile is up-to-date or not */ + sourceDirectory = file("src"); + + /** How to name the result file. */ + targetFileName = "classes_server.js"; + + /** Which class holds your public static void main(Strin[] args) method */ + mainClass = "net.lax1dude.eaglercraft.sp.IntegratedServer"; + + /** This will be the name of your main method after compilation. */ + entryPointName = "main"; + + classesToPreserve = null; + stopOnErrors = false; + optimizationLevel = "FULL"; //org.teavm.vm.TeaVMOptimizationLevel.SIMPLE; + fastGlobalAnalysis = false; + targetType = "JAVASCRIPT"; //org.teavm.tooling.TeaVMTargetType.JAVASCRIPT; + cacheDirectory = null; + wasmVersion = "V_0x1"; //org.teavm.backend.wasm.render.WasmBinaryVersion.V_0x1; + minHeapSize = 4; + maxHeapSize = 128; + outOfProcess = false; + processMemory = 512; + longjmpSupported = true; + heapDump = false; + + /** Add name of configurations here where to look for jarfiles. */ + includeJarsFrom = []; + + /** By default teavmc taskd epends on javaCompile task, unless this varaibale is true. */ + skipJavaCompile = false; +} diff --git a/sp-server/deps/gson-2.2.4-sources.jar b/sp-server/deps/gson-2.2.4-sources.jar new file mode 100644 index 0000000..74d3cc5 Binary files /dev/null and b/sp-server/deps/gson-2.2.4-sources.jar differ diff --git a/sp-server/deps/gson-2.2.4.jar b/sp-server/deps/gson-2.2.4.jar new file mode 100644 index 0000000..75fe27c Binary files /dev/null and b/sp-server/deps/gson-2.2.4.jar differ diff --git a/sp-server/deps/joda-time-2.7-sources.jar b/sp-server/deps/joda-time-2.7-sources.jar new file mode 100644 index 0000000..9f4ec33 Binary files /dev/null and b/sp-server/deps/joda-time-2.7-sources.jar differ diff --git a/sp-server/deps/joda-time-2.7.jar b/sp-server/deps/joda-time-2.7.jar new file mode 100644 index 0000000..5a94523 Binary files /dev/null and b/sp-server/deps/joda-time-2.7.jar differ diff --git a/sp-server/deps/jzlib-1.1.3-sources.jar b/sp-server/deps/jzlib-1.1.3-sources.jar new file mode 100644 index 0000000..c70efe7 Binary files /dev/null and b/sp-server/deps/jzlib-1.1.3-sources.jar differ diff --git a/sp-server/deps/jzlib-1.1.3.jar b/sp-server/deps/jzlib-1.1.3.jar new file mode 100644 index 0000000..2fa60b1 Binary files /dev/null and b/sp-server/deps/jzlib-1.1.3.jar differ diff --git a/sp-server/deps/teavm-classlib-0.7.0-SNAPSHOT-javadoc.jar b/sp-server/deps/teavm-classlib-0.7.0-SNAPSHOT-javadoc.jar new file mode 100644 index 0000000..0b6e3b3 Binary files /dev/null and b/sp-server/deps/teavm-classlib-0.7.0-SNAPSHOT-javadoc.jar differ diff --git a/sp-server/deps/teavm-classlib-0.7.0-SNAPSHOT-sources.jar b/sp-server/deps/teavm-classlib-0.7.0-SNAPSHOT-sources.jar new file mode 100644 index 0000000..04bfa3e Binary files /dev/null and b/sp-server/deps/teavm-classlib-0.7.0-SNAPSHOT-sources.jar differ diff --git a/sp-server/deps/teavm-classlib-0.7.0-SNAPSHOT.jar b/sp-server/deps/teavm-classlib-0.7.0-SNAPSHOT.jar new file mode 100644 index 0000000..70ab82e Binary files /dev/null and b/sp-server/deps/teavm-classlib-0.7.0-SNAPSHOT.jar differ diff --git a/sp-server/deps/teavm-cli-0.6.1.jar b/sp-server/deps/teavm-cli-0.6.1.jar new file mode 100644 index 0000000..0655260 Binary files /dev/null and b/sp-server/deps/teavm-cli-0.6.1.jar differ diff --git a/sp-server/deps/teavm-core-0.7.0-SNAPSHOT-javadoc.jar b/sp-server/deps/teavm-core-0.7.0-SNAPSHOT-javadoc.jar new file mode 100644 index 0000000..dc2bbb8 Binary files /dev/null and b/sp-server/deps/teavm-core-0.7.0-SNAPSHOT-javadoc.jar differ diff --git a/sp-server/deps/teavm-core-0.7.0-SNAPSHOT-sources.jar b/sp-server/deps/teavm-core-0.7.0-SNAPSHOT-sources.jar new file mode 100644 index 0000000..e6993dc Binary files /dev/null and b/sp-server/deps/teavm-core-0.7.0-SNAPSHOT-sources.jar differ diff --git a/sp-server/deps/teavm-core-0.7.0-SNAPSHOT.jar b/sp-server/deps/teavm-core-0.7.0-SNAPSHOT.jar new file mode 100644 index 0000000..f067b24 Binary files /dev/null and b/sp-server/deps/teavm-core-0.7.0-SNAPSHOT.jar differ diff --git a/sp-server/deps/teavm-gradle-plugin-1.0.0-patched.jar b/sp-server/deps/teavm-gradle-plugin-1.0.0-patched.jar new file mode 100644 index 0000000..822004e Binary files /dev/null and b/sp-server/deps/teavm-gradle-plugin-1.0.0-patched.jar differ diff --git a/sp-server/deps/teavm-interop-0.7.0-SNAPSHOT-javadoc.jar b/sp-server/deps/teavm-interop-0.7.0-SNAPSHOT-javadoc.jar new file mode 100644 index 0000000..46d2cb6 Binary files /dev/null and b/sp-server/deps/teavm-interop-0.7.0-SNAPSHOT-javadoc.jar differ diff --git a/sp-server/deps/teavm-interop-0.7.0-SNAPSHOT-sources.jar b/sp-server/deps/teavm-interop-0.7.0-SNAPSHOT-sources.jar new file mode 100644 index 0000000..7a22e3b Binary files /dev/null and b/sp-server/deps/teavm-interop-0.7.0-SNAPSHOT-sources.jar differ diff --git a/sp-server/deps/teavm-interop-0.7.0-SNAPSHOT.jar b/sp-server/deps/teavm-interop-0.7.0-SNAPSHOT.jar new file mode 100644 index 0000000..3e2b274 Binary files /dev/null and b/sp-server/deps/teavm-interop-0.7.0-SNAPSHOT.jar differ diff --git a/sp-server/deps/teavm-jso-0.7.0-SNAPSHOT-javadoc.jar b/sp-server/deps/teavm-jso-0.7.0-SNAPSHOT-javadoc.jar new file mode 100644 index 0000000..7f29815 Binary files /dev/null and b/sp-server/deps/teavm-jso-0.7.0-SNAPSHOT-javadoc.jar differ diff --git a/sp-server/deps/teavm-jso-0.7.0-SNAPSHOT-sources.jar b/sp-server/deps/teavm-jso-0.7.0-SNAPSHOT-sources.jar new file mode 100644 index 0000000..0ed898f Binary files /dev/null and b/sp-server/deps/teavm-jso-0.7.0-SNAPSHOT-sources.jar differ diff --git a/sp-server/deps/teavm-jso-0.7.0-SNAPSHOT.jar b/sp-server/deps/teavm-jso-0.7.0-SNAPSHOT.jar new file mode 100644 index 0000000..a176a73 Binary files /dev/null and b/sp-server/deps/teavm-jso-0.7.0-SNAPSHOT.jar differ diff --git a/sp-server/deps/teavm-jso-apis-0.7.0-SNAPSHOT-javadoc.jar b/sp-server/deps/teavm-jso-apis-0.7.0-SNAPSHOT-javadoc.jar new file mode 100644 index 0000000..80f3bf5 Binary files /dev/null and b/sp-server/deps/teavm-jso-apis-0.7.0-SNAPSHOT-javadoc.jar differ diff --git a/sp-server/deps/teavm-jso-apis-0.7.0-SNAPSHOT-sources.jar b/sp-server/deps/teavm-jso-apis-0.7.0-SNAPSHOT-sources.jar new file mode 100644 index 0000000..d12a6d1 Binary files /dev/null and b/sp-server/deps/teavm-jso-apis-0.7.0-SNAPSHOT-sources.jar differ diff --git a/sp-server/deps/teavm-jso-apis-0.7.0-SNAPSHOT.jar b/sp-server/deps/teavm-jso-apis-0.7.0-SNAPSHOT.jar new file mode 100644 index 0000000..3ed254d Binary files /dev/null and b/sp-server/deps/teavm-jso-apis-0.7.0-SNAPSHOT.jar differ diff --git a/sp-server/deps/teavm-jso-impl-0.7.0-SNAPSHOT-javadoc.jar b/sp-server/deps/teavm-jso-impl-0.7.0-SNAPSHOT-javadoc.jar new file mode 100644 index 0000000..ed4fe59 Binary files /dev/null and b/sp-server/deps/teavm-jso-impl-0.7.0-SNAPSHOT-javadoc.jar differ diff --git a/sp-server/deps/teavm-jso-impl-0.7.0-SNAPSHOT-sources.jar b/sp-server/deps/teavm-jso-impl-0.7.0-SNAPSHOT-sources.jar new file mode 100644 index 0000000..29f3c17 Binary files /dev/null and b/sp-server/deps/teavm-jso-impl-0.7.0-SNAPSHOT-sources.jar differ diff --git a/sp-server/deps/teavm-jso-impl-0.7.0-SNAPSHOT.jar b/sp-server/deps/teavm-jso-impl-0.7.0-SNAPSHOT.jar new file mode 100644 index 0000000..8478f1c Binary files /dev/null and b/sp-server/deps/teavm-jso-impl-0.7.0-SNAPSHOT.jar differ diff --git a/sp-server/deps/teavm-metaprogramming-api-0.7.0-SNAPSHOT-javadoc.jar b/sp-server/deps/teavm-metaprogramming-api-0.7.0-SNAPSHOT-javadoc.jar new file mode 100644 index 0000000..ca41bb0 Binary files /dev/null and b/sp-server/deps/teavm-metaprogramming-api-0.7.0-SNAPSHOT-javadoc.jar differ diff --git a/sp-server/deps/teavm-metaprogramming-api-0.7.0-SNAPSHOT-sources.jar b/sp-server/deps/teavm-metaprogramming-api-0.7.0-SNAPSHOT-sources.jar new file mode 100644 index 0000000..3fc879b Binary files /dev/null and b/sp-server/deps/teavm-metaprogramming-api-0.7.0-SNAPSHOT-sources.jar differ diff --git a/sp-server/deps/teavm-metaprogramming-api-0.7.0-SNAPSHOT.jar b/sp-server/deps/teavm-metaprogramming-api-0.7.0-SNAPSHOT.jar new file mode 100644 index 0000000..4d7e4ad Binary files /dev/null and b/sp-server/deps/teavm-metaprogramming-api-0.7.0-SNAPSHOT.jar differ diff --git a/sp-server/deps/teavm-metaprogramming-impl-0.7.0-SNAPSHOT-javadoc.jar b/sp-server/deps/teavm-metaprogramming-impl-0.7.0-SNAPSHOT-javadoc.jar new file mode 100644 index 0000000..01feb06 Binary files /dev/null and b/sp-server/deps/teavm-metaprogramming-impl-0.7.0-SNAPSHOT-javadoc.jar differ diff --git a/sp-server/deps/teavm-metaprogramming-impl-0.7.0-SNAPSHOT-sources.jar b/sp-server/deps/teavm-metaprogramming-impl-0.7.0-SNAPSHOT-sources.jar new file mode 100644 index 0000000..be48f2e Binary files /dev/null and b/sp-server/deps/teavm-metaprogramming-impl-0.7.0-SNAPSHOT-sources.jar differ diff --git a/sp-server/deps/teavm-metaprogramming-impl-0.7.0-SNAPSHOT.jar b/sp-server/deps/teavm-metaprogramming-impl-0.7.0-SNAPSHOT.jar new file mode 100644 index 0000000..123361b Binary files /dev/null and b/sp-server/deps/teavm-metaprogramming-impl-0.7.0-SNAPSHOT.jar differ diff --git a/sp-server/deps/teavm-platform-0.7.0-SNAPSHOT-javadoc.jar b/sp-server/deps/teavm-platform-0.7.0-SNAPSHOT-javadoc.jar new file mode 100644 index 0000000..5020b5c Binary files /dev/null and b/sp-server/deps/teavm-platform-0.7.0-SNAPSHOT-javadoc.jar differ diff --git a/sp-server/deps/teavm-platform-0.7.0-SNAPSHOT-sources.jar b/sp-server/deps/teavm-platform-0.7.0-SNAPSHOT-sources.jar new file mode 100644 index 0000000..47f90e5 Binary files /dev/null and b/sp-server/deps/teavm-platform-0.7.0-SNAPSHOT-sources.jar differ diff --git a/sp-server/deps/teavm-platform-0.7.0-SNAPSHOT.jar b/sp-server/deps/teavm-platform-0.7.0-SNAPSHOT.jar new file mode 100644 index 0000000..ae3efaf Binary files /dev/null and b/sp-server/deps/teavm-platform-0.7.0-SNAPSHOT.jar differ diff --git a/sp-server/deps/teavm-tooling-0.7.0-SNAPSHOT-javadoc.jar b/sp-server/deps/teavm-tooling-0.7.0-SNAPSHOT-javadoc.jar new file mode 100644 index 0000000..07cfdaa Binary files /dev/null and b/sp-server/deps/teavm-tooling-0.7.0-SNAPSHOT-javadoc.jar differ diff --git a/sp-server/deps/teavm-tooling-0.7.0-SNAPSHOT-sources.jar b/sp-server/deps/teavm-tooling-0.7.0-SNAPSHOT-sources.jar new file mode 100644 index 0000000..06c2435 Binary files /dev/null and b/sp-server/deps/teavm-tooling-0.7.0-SNAPSHOT-sources.jar differ diff --git a/sp-server/deps/teavm-tooling-0.7.0-SNAPSHOT.jar b/sp-server/deps/teavm-tooling-0.7.0-SNAPSHOT.jar new file mode 100644 index 0000000..dc7a422 Binary files /dev/null and b/sp-server/deps/teavm-tooling-0.7.0-SNAPSHOT.jar differ diff --git a/sp-server/settings.gradle b/sp-server/settings.gradle new file mode 100644 index 0000000..14ddd4c --- /dev/null +++ b/sp-server/settings.gradle @@ -0,0 +1,12 @@ +/* + * This file was generated by the Gradle 'init' task. + * + * The settings file is used to specify which projects to include in your build. + * + * Detailed information about configuring a multi-project build in Gradle can be found + * in the user manual at https://docs.gradle.org/6.0/userguide/multi_project_builds.html + */ + +rootProject.name = 'eaglercraft-sp-server' + +// you eagler \ No newline at end of file diff --git a/sp-server/src/ipc/java/net/lax1dude/eaglercraft/sp/ipc/IPCInputStream.java b/sp-server/src/ipc/java/net/lax1dude/eaglercraft/sp/ipc/IPCInputStream.java new file mode 100644 index 0000000..f9a736e --- /dev/null +++ b/sp-server/src/ipc/java/net/lax1dude/eaglercraft/sp/ipc/IPCInputStream.java @@ -0,0 +1,44 @@ +package net.lax1dude.eaglercraft.sp.ipc; + +import java.io.IOException; +import java.io.InputStream; + +class IPCInputStream extends InputStream { + + private byte[] currentBuffer = null; + private int idx = 0; + private String errorName = null; + + void feedBuffer(byte[] b) { + currentBuffer = b; + idx = 0; + errorName = null; + } + + void nameBuffer(String str) { + errorName = str; + } + + @Override + public int read() throws IOException { + try { + return ((int)currentBuffer[++idx]) & 0xFF; + }catch(ArrayIndexOutOfBoundsException a) { + throw new IOException("IPCInputStream buffer underflow" + (errorName == null ? "" : (" while deserializing '" + errorName + "'")), a); + } + } + + @Override + public int read(byte b[], int off, int len) throws IOException { + if(idx + len > currentBuffer.length) { + throw new IOException("IPCInputStream buffer underflow" + (errorName == null ? "" : (" while deserializing '" + errorName + "'")), new ArrayIndexOutOfBoundsException(idx + len - 1)); + } + if(off + len > b.length) { + throw new ArrayIndexOutOfBoundsException(off + len - 1); + } + System.arraycopy(b, off, currentBuffer, idx, len); + idx += len; + return 0; + } + +} diff --git a/sp-server/src/ipc/java/net/lax1dude/eaglercraft/sp/ipc/IPCOutputStream.java b/sp-server/src/ipc/java/net/lax1dude/eaglercraft/sp/ipc/IPCOutputStream.java new file mode 100644 index 0000000..75e5011 --- /dev/null +++ b/sp-server/src/ipc/java/net/lax1dude/eaglercraft/sp/ipc/IPCOutputStream.java @@ -0,0 +1,55 @@ +package net.lax1dude.eaglercraft.sp.ipc; + +import java.io.IOException; +import java.io.OutputStream; + +class IPCOutputStream extends OutputStream { + + private String className = null; + private byte[] currentBuffer = null; + private int idx = 0; + private int originalSize = 0; + + void feedBuffer(byte[] buf, String clazzName) { + currentBuffer = buf; + idx = 0; + originalSize = buf.length; + className = clazzName; + } + + byte[] returnBuffer() { + if(className != null && currentBuffer.length != originalSize) { + System.err.println("WARNING: Packet '" + className + "' was supposed to be " + originalSize + " bytes but buffer has grown by " + (currentBuffer.length - originalSize) + " to " + currentBuffer.length + " bytes"); + } + return currentBuffer; + } + + void growBuffer(int i) { + int ii = currentBuffer.length; + int iii = i - ii; + if(iii > 0) { + byte[] n = new byte[i]; + System.arraycopy(currentBuffer, 0, n, 0, ii); + currentBuffer = n; + } + } + + @Override + public void write(int b) throws IOException { + if(idx >= currentBuffer.length) { + growBuffer(idx + 1); + } + currentBuffer[idx] = (byte) b; + ++idx; + } + + @Override + public void write(byte b[], int off, int len) throws IOException { + if(idx + len > currentBuffer.length) { + growBuffer(idx + len); + } + System.arraycopy(b, off, currentBuffer, idx, len); + idx += len; + } + +} diff --git a/sp-server/src/ipc/java/net/lax1dude/eaglercraft/sp/ipc/IPCPacket00StartServer.java b/sp-server/src/ipc/java/net/lax1dude/eaglercraft/sp/ipc/IPCPacket00StartServer.java new file mode 100644 index 0000000..931acc0 --- /dev/null +++ b/sp-server/src/ipc/java/net/lax1dude/eaglercraft/sp/ipc/IPCPacket00StartServer.java @@ -0,0 +1,40 @@ +package net.lax1dude.eaglercraft.sp.ipc; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; + +public class IPCPacket00StartServer implements IPCPacketBase { + + public static final int ID = 0x00; + + public String worldName; + + public IPCPacket00StartServer() { + } + + public IPCPacket00StartServer(String worldName) { + this.worldName = worldName; + } + + @Override + public void deserialize(DataInput bin) throws IOException { + worldName = bin.readUTF(); + } + + @Override + public void serialize(DataOutput bin) throws IOException { + bin.writeUTF(worldName); + } + + @Override + public int id() { + return ID; + } + + @Override + public int size() { + return IPCPacketBase.strLen(worldName); + } + +} diff --git a/sp-server/src/ipc/java/net/lax1dude/eaglercraft/sp/ipc/IPCPacket01StopServer.java b/sp-server/src/ipc/java/net/lax1dude/eaglercraft/sp/ipc/IPCPacket01StopServer.java new file mode 100644 index 0000000..08494d6 --- /dev/null +++ b/sp-server/src/ipc/java/net/lax1dude/eaglercraft/sp/ipc/IPCPacket01StopServer.java @@ -0,0 +1,32 @@ +package net.lax1dude.eaglercraft.sp.ipc; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; + +public class IPCPacket01StopServer implements IPCPacketBase { + + public static final int ID = 0x01; + + public IPCPacket01StopServer() { + } + + @Override + public void deserialize(DataInput bin) throws IOException { + } + + @Override + public void serialize(DataOutput bin) throws IOException { + } + + @Override + public int id() { + return ID; + } + + @Override + public int size() { + return 0; + } + +} diff --git a/sp-server/src/ipc/java/net/lax1dude/eaglercraft/sp/ipc/IPCPacket02InitWorld.java b/sp-server/src/ipc/java/net/lax1dude/eaglercraft/sp/ipc/IPCPacket02InitWorld.java new file mode 100644 index 0000000..b5f3d19 --- /dev/null +++ b/sp-server/src/ipc/java/net/lax1dude/eaglercraft/sp/ipc/IPCPacket02InitWorld.java @@ -0,0 +1,68 @@ +package net.lax1dude.eaglercraft.sp.ipc; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; + +public class IPCPacket02InitWorld implements IPCPacketBase { + + public static final int ID = 0x02; + + public String worldName; + public byte gamemode; + public byte worldType; + public String worldArgs; + public long seed; + public boolean cheats; + public boolean structures; + public boolean bonusChest; + + public IPCPacket02InitWorld() { + } + + public IPCPacket02InitWorld(String worldName, byte gamemode, byte worldType, String worldArgs, long seed, boolean cheats, boolean structures, boolean bonusChest) { + this.worldName = worldName; + this.gamemode = gamemode; + this.worldType = worldType; + this.worldArgs = worldArgs; + this.seed = seed; + this.cheats = cheats; + this.structures = structures; + this.bonusChest = bonusChest; + } + + @Override + public void deserialize(DataInput bin) throws IOException { + worldName = bin.readUTF(); + gamemode = bin.readByte(); + worldType = bin.readByte(); + worldArgs = bin.readUTF(); + seed = bin.readLong(); + cheats = bin.readBoolean(); + structures = bin.readBoolean(); + bonusChest = bin.readBoolean(); + } + + @Override + public void serialize(DataOutput bin) throws IOException { + bin.writeUTF(worldName); + bin.writeByte(gamemode); + bin.writeByte(worldType); + bin.writeUTF(worldArgs); + bin.writeLong(seed); + bin.writeBoolean(cheats); + bin.writeBoolean(structures); + bin.writeBoolean(bonusChest); + } + + @Override + public int id() { + return ID; + } + + @Override + public int size() { + return IPCPacketBase.strLen(worldName) + 1 + 1 + IPCPacketBase.strLen(worldArgs) + 8 + 1 + 1 + 1; + } + +} diff --git a/sp-server/src/ipc/java/net/lax1dude/eaglercraft/sp/ipc/IPCPacket03DeleteWorld.java b/sp-server/src/ipc/java/net/lax1dude/eaglercraft/sp/ipc/IPCPacket03DeleteWorld.java new file mode 100644 index 0000000..d3f2a0b --- /dev/null +++ b/sp-server/src/ipc/java/net/lax1dude/eaglercraft/sp/ipc/IPCPacket03DeleteWorld.java @@ -0,0 +1,40 @@ +package net.lax1dude.eaglercraft.sp.ipc; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; + +public class IPCPacket03DeleteWorld implements IPCPacketBase { + + public static final int ID = 0x03; + + public String worldName; + + public IPCPacket03DeleteWorld() { + } + + public IPCPacket03DeleteWorld(String worldName) { + this.worldName = worldName; + } + + @Override + public void deserialize(DataInput bin) throws IOException { + worldName = bin.readUTF(); + } + + @Override + public void serialize(DataOutput bin) throws IOException { + bin.writeUTF(worldName); + } + + @Override + public int id() { + return ID; + } + + @Override + public int size() { + return IPCPacketBase.strLen(worldName); + } + +} diff --git a/sp-server/src/ipc/java/net/lax1dude/eaglercraft/sp/ipc/IPCPacket04RenameWorld.java b/sp-server/src/ipc/java/net/lax1dude/eaglercraft/sp/ipc/IPCPacket04RenameWorld.java new file mode 100644 index 0000000..1d56e27 --- /dev/null +++ b/sp-server/src/ipc/java/net/lax1dude/eaglercraft/sp/ipc/IPCPacket04RenameWorld.java @@ -0,0 +1,48 @@ +package net.lax1dude.eaglercraft.sp.ipc; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; + +public class IPCPacket04RenameWorld implements IPCPacketBase { + + public static final int ID = 0x04; + + public String worldOldName; + public String worldNewName; + public boolean copy; + + public IPCPacket04RenameWorld() { + } + + public IPCPacket04RenameWorld(String worldOldName, String worldNewName, boolean copy) { + this.worldOldName = worldOldName; + this.worldNewName = worldNewName; + this.copy = copy; + } + + @Override + public void deserialize(DataInput bin) throws IOException { + worldOldName = bin.readUTF(); + worldNewName = bin.readUTF(); + copy = bin.readBoolean(); + } + + @Override + public void serialize(DataOutput bin) throws IOException { + bin.writeUTF(worldOldName); + bin.writeUTF(worldNewName); + bin.writeBoolean(copy); + } + + @Override + public int id() { + return ID; + } + + @Override + public int size() { + return IPCPacketBase.strLen(worldOldName) + IPCPacketBase.strLen(worldNewName) + 1; + } + +} diff --git a/sp-server/src/ipc/java/net/lax1dude/eaglercraft/sp/ipc/IPCPacket05RequestData.java b/sp-server/src/ipc/java/net/lax1dude/eaglercraft/sp/ipc/IPCPacket05RequestData.java new file mode 100644 index 0000000..00355aa --- /dev/null +++ b/sp-server/src/ipc/java/net/lax1dude/eaglercraft/sp/ipc/IPCPacket05RequestData.java @@ -0,0 +1,48 @@ +package net.lax1dude.eaglercraft.sp.ipc; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; + +public class IPCPacket05RequestData implements IPCPacketBase { + + public static final int ID = 0x05; + + public static final byte REQUEST_LEVEL_DAT = 0x00; + public static final byte REQUEST_LEVEL_EAG = 0x01; + public static final byte REQUEST_LEVEL_MCA = 0x02; + + public String worldName; + public byte request; + + public IPCPacket05RequestData() { + } + + public IPCPacket05RequestData(String worldName, byte request) { + this.worldName = worldName; + this.request = request; + } + + @Override + public void deserialize(DataInput bin) throws IOException { + worldName = bin.readUTF(); + request = bin.readByte(); + } + + @Override + public void serialize(DataOutput bin) throws IOException { + bin.writeUTF(worldName); + bin.writeByte(request); + } + + @Override + public int id() { + return ID; + } + + @Override + public int size() { + return IPCPacketBase.strLen(worldName) + 1; + } + +} diff --git a/sp-server/src/ipc/java/net/lax1dude/eaglercraft/sp/ipc/IPCPacket07ImportWorld.java b/sp-server/src/ipc/java/net/lax1dude/eaglercraft/sp/ipc/IPCPacket07ImportWorld.java new file mode 100644 index 0000000..83384be --- /dev/null +++ b/sp-server/src/ipc/java/net/lax1dude/eaglercraft/sp/ipc/IPCPacket07ImportWorld.java @@ -0,0 +1,46 @@ +package net.lax1dude.eaglercraft.sp.ipc; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; + +public class IPCPacket07ImportWorld implements IPCPacketBase { + + public static final int ID = 0x07; + + public String worldName; + public byte[] worldData; + + public IPCPacket07ImportWorld() { + } + + public IPCPacket07ImportWorld(String worldName, byte[] worldData, byte worldFormat) { + this.worldName = worldName; + this.worldData = worldData; + } + + @Override + public void deserialize(DataInput bin) throws IOException { + worldName = bin.readUTF(); + worldData = new byte[bin.readInt()]; + bin.readFully(worldData); + } + + @Override + public void serialize(DataOutput bin) throws IOException { + bin.writeUTF(worldName); + bin.writeInt(worldData.length); + bin.write(worldData); + } + + @Override + public int id() { + return ID; + } + + @Override + public int size() { + return IPCPacketBase.strLen(worldName) + worldData.length + 4; + } + +} diff --git a/sp-server/src/ipc/java/net/lax1dude/eaglercraft/sp/ipc/IPCPacket09RequestResponse.java b/sp-server/src/ipc/java/net/lax1dude/eaglercraft/sp/ipc/IPCPacket09RequestResponse.java new file mode 100644 index 0000000..e8e47db --- /dev/null +++ b/sp-server/src/ipc/java/net/lax1dude/eaglercraft/sp/ipc/IPCPacket09RequestResponse.java @@ -0,0 +1,42 @@ +package net.lax1dude.eaglercraft.sp.ipc; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; + +public class IPCPacket09RequestResponse implements IPCPacketBase { + + public static final int ID = 0x09; + + public byte[] response; + + public IPCPacket09RequestResponse() { + } + + public IPCPacket09RequestResponse(byte[] dat) { + this.response = dat; + } + + @Override + public void deserialize(DataInput bin) throws IOException { + response = new byte[bin.readInt()]; + bin.readFully(response); + } + + @Override + public void serialize(DataOutput bin) throws IOException { + bin.writeInt(response.length); + bin.write(response); + } + + @Override + public int id() { + return ID; + } + + @Override + public int size() { + return 4 + response.length; + } + +} diff --git a/sp-server/src/ipc/java/net/lax1dude/eaglercraft/sp/ipc/IPCPacket0ASetWorldDifficulty.java b/sp-server/src/ipc/java/net/lax1dude/eaglercraft/sp/ipc/IPCPacket0ASetWorldDifficulty.java new file mode 100644 index 0000000..6a549fe --- /dev/null +++ b/sp-server/src/ipc/java/net/lax1dude/eaglercraft/sp/ipc/IPCPacket0ASetWorldDifficulty.java @@ -0,0 +1,40 @@ +package net.lax1dude.eaglercraft.sp.ipc; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; + +public class IPCPacket0ASetWorldDifficulty implements IPCPacketBase { + + public static final int ID = 0x0A; + + public byte difficulty; + + public IPCPacket0ASetWorldDifficulty() { + } + + public IPCPacket0ASetWorldDifficulty(byte difficulty) { + this.difficulty = difficulty; + } + + @Override + public void deserialize(DataInput bin) throws IOException { + difficulty = bin.readByte(); + } + + @Override + public void serialize(DataOutput bin) throws IOException { + bin.writeByte(difficulty); + } + + @Override + public int id() { + return ID; + } + + @Override + public int size() { + return 1; + } + +} diff --git a/sp-server/src/ipc/java/net/lax1dude/eaglercraft/sp/ipc/IPCPacket0BPause.java b/sp-server/src/ipc/java/net/lax1dude/eaglercraft/sp/ipc/IPCPacket0BPause.java new file mode 100644 index 0000000..5bf0028 --- /dev/null +++ b/sp-server/src/ipc/java/net/lax1dude/eaglercraft/sp/ipc/IPCPacket0BPause.java @@ -0,0 +1,40 @@ +package net.lax1dude.eaglercraft.sp.ipc; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; + +public class IPCPacket0BPause implements IPCPacketBase { + + public static final int ID = 0x0B; + + public boolean pause; + + public IPCPacket0BPause() { + } + + public IPCPacket0BPause(boolean pause) { + this.pause = pause; + } + + @Override + public void deserialize(DataInput bin) throws IOException { + pause = bin.readBoolean(); + } + + @Override + public void serialize(DataOutput bin) throws IOException { + bin.writeBoolean(pause); + } + + @Override + public int id() { + return ID; + } + + @Override + public int size() { + return 1; + } + +} diff --git a/sp-server/src/ipc/java/net/lax1dude/eaglercraft/sp/ipc/IPCPacket0CPlayerChannel.java b/sp-server/src/ipc/java/net/lax1dude/eaglercraft/sp/ipc/IPCPacket0CPlayerChannel.java new file mode 100644 index 0000000..ad9d681 --- /dev/null +++ b/sp-server/src/ipc/java/net/lax1dude/eaglercraft/sp/ipc/IPCPacket0CPlayerChannel.java @@ -0,0 +1,44 @@ +package net.lax1dude.eaglercraft.sp.ipc; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; + +public class IPCPacket0CPlayerChannel implements IPCPacketBase { + + public static final int ID = 0x0C; + + public String channel; + public boolean open; + + public IPCPacket0CPlayerChannel() { + } + + public IPCPacket0CPlayerChannel(String channel, boolean open) { + this.channel = channel; + this.open = open; + } + + @Override + public void deserialize(DataInput bin) throws IOException { + channel = bin.readUTF(); + open = bin.readBoolean(); + } + + @Override + public void serialize(DataOutput bin) throws IOException { + bin.writeUTF(channel); + bin.writeBoolean(open); + } + + @Override + public int id() { + return ID; + } + + @Override + public int size() { + return IPCPacketBase.strLen(channel) + 1; + } + +} diff --git a/sp-server/src/ipc/java/net/lax1dude/eaglercraft/sp/ipc/IPCPacket0DProgressUpdate.java b/sp-server/src/ipc/java/net/lax1dude/eaglercraft/sp/ipc/IPCPacket0DProgressUpdate.java new file mode 100644 index 0000000..98f30f7 --- /dev/null +++ b/sp-server/src/ipc/java/net/lax1dude/eaglercraft/sp/ipc/IPCPacket0DProgressUpdate.java @@ -0,0 +1,44 @@ +package net.lax1dude.eaglercraft.sp.ipc; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; + +public class IPCPacket0DProgressUpdate implements IPCPacketBase { + + public static final int ID = 0x0D; + + public String updateMessage; + public float updateProgress; + + public IPCPacket0DProgressUpdate() { + } + + public IPCPacket0DProgressUpdate(String updateMessage, float updateProgress) { + this.updateMessage = updateMessage == null ? "" : updateMessage; + this.updateProgress = updateProgress; + } + + @Override + public void deserialize(DataInput bin) throws IOException { + updateMessage = bin.readUTF(); + updateProgress = bin.readFloat(); + } + + @Override + public void serialize(DataOutput bin) throws IOException { + bin.writeUTF(updateMessage); + bin.writeFloat(updateProgress); + } + + @Override + public int id() { + return ID; + } + + @Override + public int size() { + return IPCPacketBase.strLen(updateMessage) + 4; + } + +} diff --git a/sp-server/src/ipc/java/net/lax1dude/eaglercraft/sp/ipc/IPCPacket0EListWorlds.java b/sp-server/src/ipc/java/net/lax1dude/eaglercraft/sp/ipc/IPCPacket0EListWorlds.java new file mode 100644 index 0000000..8a81c70 --- /dev/null +++ b/sp-server/src/ipc/java/net/lax1dude/eaglercraft/sp/ipc/IPCPacket0EListWorlds.java @@ -0,0 +1,32 @@ +package net.lax1dude.eaglercraft.sp.ipc; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; + +public class IPCPacket0EListWorlds implements IPCPacketBase { + + public static final int ID = 0x0E; + + public IPCPacket0EListWorlds() { + } + + @Override + public void deserialize(DataInput bin) throws IOException { + } + + @Override + public void serialize(DataOutput bin) throws IOException { + } + + @Override + public int id() { + return ID; + } + + @Override + public int size() { + return 0; + } + +} diff --git a/sp-server/src/ipc/java/net/lax1dude/eaglercraft/sp/ipc/IPCPacket0FListFiles.java b/sp-server/src/ipc/java/net/lax1dude/eaglercraft/sp/ipc/IPCPacket0FListFiles.java new file mode 100644 index 0000000..fb00b24 --- /dev/null +++ b/sp-server/src/ipc/java/net/lax1dude/eaglercraft/sp/ipc/IPCPacket0FListFiles.java @@ -0,0 +1,40 @@ +package net.lax1dude.eaglercraft.sp.ipc; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; + +public class IPCPacket0FListFiles implements IPCPacketBase { + + public static final int ID = 0x0F; + + public String path; + + public IPCPacket0FListFiles() { + } + + public IPCPacket0FListFiles(String path) { + this.path = path; + } + + @Override + public void deserialize(DataInput bin) throws IOException { + this.path = bin.readUTF(); + } + + @Override + public void serialize(DataOutput bin) throws IOException { + bin.writeUTF(path); + } + + @Override + public int id() { + return ID; + } + + @Override + public int size() { + return IPCPacketBase.strLen(path); + } + +} diff --git a/sp-server/src/ipc/java/net/lax1dude/eaglercraft/sp/ipc/IPCPacket10FileRead.java b/sp-server/src/ipc/java/net/lax1dude/eaglercraft/sp/ipc/IPCPacket10FileRead.java new file mode 100644 index 0000000..75d8f3b --- /dev/null +++ b/sp-server/src/ipc/java/net/lax1dude/eaglercraft/sp/ipc/IPCPacket10FileRead.java @@ -0,0 +1,40 @@ +package net.lax1dude.eaglercraft.sp.ipc; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; + +public class IPCPacket10FileRead implements IPCPacketBase { + + public static final int ID = 0x10; + + public String file; + + public IPCPacket10FileRead() { + } + + public IPCPacket10FileRead(String file) { + this.file = file; + } + + @Override + public void deserialize(DataInput bin) throws IOException { + file = bin.readUTF(); + } + + @Override + public void serialize(DataOutput bin) throws IOException { + bin.writeUTF(file); + } + + @Override + public int id() { + return ID; + } + + @Override + public int size() { + return IPCPacketBase.strLen(file); + } + +} diff --git a/sp-server/src/ipc/java/net/lax1dude/eaglercraft/sp/ipc/IPCPacket12FileWrite.java b/sp-server/src/ipc/java/net/lax1dude/eaglercraft/sp/ipc/IPCPacket12FileWrite.java new file mode 100644 index 0000000..3bc5f5c --- /dev/null +++ b/sp-server/src/ipc/java/net/lax1dude/eaglercraft/sp/ipc/IPCPacket12FileWrite.java @@ -0,0 +1,44 @@ +package net.lax1dude.eaglercraft.sp.ipc; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; + +public class IPCPacket12FileWrite implements IPCPacketBase { + + public static final int ID = 0x12; + + public String path; + public byte[] data; + + public IPCPacket12FileWrite() { + } + + public IPCPacket12FileWrite(String path, byte[] data) { + this.path = path; + this.data = data; + } + + @Override + public void deserialize(DataInput bin) throws IOException { + path = bin.readUTF(); + } + + @Override + public void serialize(DataOutput bin) throws IOException { + bin.writeUTF(path); + bin.writeInt(data.length); + bin.write(data); + } + + @Override + public int id() { + return ID; + } + + @Override + public int size() { + return IPCPacketBase.strLen(path) + 4 + data.length; + } + +} diff --git a/sp-server/src/ipc/java/net/lax1dude/eaglercraft/sp/ipc/IPCPacket13FileCopyMove.java b/sp-server/src/ipc/java/net/lax1dude/eaglercraft/sp/ipc/IPCPacket13FileCopyMove.java new file mode 100644 index 0000000..c239968 --- /dev/null +++ b/sp-server/src/ipc/java/net/lax1dude/eaglercraft/sp/ipc/IPCPacket13FileCopyMove.java @@ -0,0 +1,48 @@ +package net.lax1dude.eaglercraft.sp.ipc; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; + +public class IPCPacket13FileCopyMove implements IPCPacketBase { + + public static final int ID = 0x13; + + public String fileOldName; + public String fileNewName; + public boolean copy; + + public IPCPacket13FileCopyMove() { + } + + public IPCPacket13FileCopyMove(String fileOldName, String fileNewName, boolean copy) { + this.fileOldName = fileOldName; + this.fileNewName = fileNewName; + this.copy = copy; + } + + @Override + public void deserialize(DataInput bin) throws IOException { + fileOldName = bin.readUTF(); + fileNewName = bin.readUTF(); + copy = bin.readBoolean(); + } + + @Override + public void serialize(DataOutput bin) throws IOException { + bin.writeUTF(fileOldName); + bin.writeUTF(fileNewName); + bin.writeBoolean(copy); + } + + @Override + public int id() { + return ID; + } + + @Override + public int size() { + return IPCPacketBase.strLen(fileOldName) + IPCPacketBase.strLen(fileNewName) + 1; + } + +} diff --git a/sp-server/src/ipc/java/net/lax1dude/eaglercraft/sp/ipc/IPCPacket14StringList.java b/sp-server/src/ipc/java/net/lax1dude/eaglercraft/sp/ipc/IPCPacket14StringList.java new file mode 100644 index 0000000..8d9c7c5 --- /dev/null +++ b/sp-server/src/ipc/java/net/lax1dude/eaglercraft/sp/ipc/IPCPacket14StringList.java @@ -0,0 +1,59 @@ +package net.lax1dude.eaglercraft.sp.ipc; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class IPCPacket14StringList implements IPCPacketBase { + + public static final int ID = 0x14; + + public final List stringList; + + public IPCPacket14StringList() { + stringList = new ArrayList(); + } + + public IPCPacket14StringList(String[] list) { + stringList = Arrays.asList(list); + } + + public IPCPacket14StringList(List list) { + stringList = list; + } + + @Override + public void deserialize(DataInput bin) throws IOException { + stringList.clear(); + int len = bin.readInt(); + for(int i = 0; i < len; ++i) { + stringList.add(bin.readUTF()); + } + } + + @Override + public void serialize(DataOutput bin) throws IOException { + bin.writeInt(stringList.size()); + for(String str : stringList) { + bin.writeUTF(str); + } + } + + @Override + public int id() { + return ID; + } + + @Override + public int size() { + int len = 4; + for(String str : stringList) { + len += IPCPacketBase.strLen(str); + } + return len; + } + +} diff --git a/sp-server/src/ipc/java/net/lax1dude/eaglercraft/sp/ipc/IPCPacketBase.java b/sp-server/src/ipc/java/net/lax1dude/eaglercraft/sp/ipc/IPCPacketBase.java new file mode 100644 index 0000000..634982b --- /dev/null +++ b/sp-server/src/ipc/java/net/lax1dude/eaglercraft/sp/ipc/IPCPacketBase.java @@ -0,0 +1,32 @@ +package net.lax1dude.eaglercraft.sp.ipc; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; + +public interface IPCPacketBase { + + public void deserialize(DataInput bin) throws IOException; + public void serialize(DataOutput bin) throws IOException; + public int id(); + public int size(); + + public static int strLen(String s) { + int count = 0; + for (int i = 0, len = s.length(); i < len; i++) { + char ch = s.charAt(i); + if (ch <= 0x7F) { + count++; + } else if (ch <= 0x7FF) { + count += 2; + } else if (Character.isHighSurrogate(ch)) { + count += 4; + ++i; + } else { + count += 3; + } + } + return count + 2; + } + +} diff --git a/sp-server/src/ipc/java/net/lax1dude/eaglercraft/sp/ipc/IPCPacketFFProcessKeepAlive.java b/sp-server/src/ipc/java/net/lax1dude/eaglercraft/sp/ipc/IPCPacketFFProcessKeepAlive.java new file mode 100644 index 0000000..bc7df09 --- /dev/null +++ b/sp-server/src/ipc/java/net/lax1dude/eaglercraft/sp/ipc/IPCPacketFFProcessKeepAlive.java @@ -0,0 +1,32 @@ +package net.lax1dude.eaglercraft.sp.ipc; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; + +public class IPCPacketFFProcessKeepAlive implements IPCPacketBase { + + public static final int ID = 0xFF; + + public IPCPacketFFProcessKeepAlive() { + } + + @Override + public void deserialize(DataInput bin) throws IOException { + } + + @Override + public void serialize(DataOutput bin) throws IOException { + } + + @Override + public int id() { + return ID; + } + + @Override + public int size() { + return 0; + } + +} diff --git a/sp-server/src/ipc/java/net/lax1dude/eaglercraft/sp/ipc/IPCPacketManager.java b/sp-server/src/ipc/java/net/lax1dude/eaglercraft/sp/ipc/IPCPacketManager.java new file mode 100644 index 0000000..a1caac9 --- /dev/null +++ b/sp-server/src/ipc/java/net/lax1dude/eaglercraft/sp/ipc/IPCPacketManager.java @@ -0,0 +1,75 @@ +package net.lax1dude.eaglercraft.sp.ipc; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.util.HashMap; + +public class IPCPacketManager { + + public static final HashMap> mappings = new HashMap(); + + public static final IPCInputStream IPC_INPUT_STREAM = new IPCInputStream(); + public static final IPCOutputStream IPC_OUTPUT_STREAM = new IPCOutputStream(); + + public static final DataInputStream IPC_DATA_INPUT_STREAM = new DataInputStream(IPC_INPUT_STREAM); + public static final DataOutputStream IPC_DATA_OUTPUT_STREAM = new DataOutputStream(IPC_OUTPUT_STREAM); + + static { + mappings.put(IPCPacket00StartServer.ID, IPCPacket00StartServer.class); + mappings.put(IPCPacket01StopServer.ID, IPCPacket01StopServer.class); + mappings.put(IPCPacket02InitWorld.ID, IPCPacket02InitWorld.class); + mappings.put(IPCPacket03DeleteWorld.ID, IPCPacket03DeleteWorld.class); + mappings.put(IPCPacket04RenameWorld.ID, IPCPacket04RenameWorld.class); + mappings.put(IPCPacket05RequestData.ID, IPCPacket05RequestData.class); + mappings.put(IPCPacket07ImportWorld.ID, IPCPacket07ImportWorld.class); + mappings.put(IPCPacket09RequestResponse.ID, IPCPacket09RequestResponse.class); + mappings.put(IPCPacket0ASetWorldDifficulty.ID, IPCPacket0ASetWorldDifficulty.class); + mappings.put(IPCPacket0BPause.ID, IPCPacket0BPause.class); + mappings.put(IPCPacket0CPlayerChannel.ID, IPCPacket0CPlayerChannel.class); + mappings.put(IPCPacket0DProgressUpdate.ID, IPCPacket0DProgressUpdate.class); + mappings.put(IPCPacket0EListWorlds.ID, IPCPacket0EListWorlds.class); + mappings.put(IPCPacket0FListFiles.ID, IPCPacket0FListFiles.class); + mappings.put(IPCPacket10FileRead.ID, IPCPacket10FileRead.class); + mappings.put(IPCPacket12FileWrite.ID, IPCPacket12FileWrite.class); + mappings.put(IPCPacket13FileCopyMove.ID, IPCPacket13FileCopyMove.class); + mappings.put(IPCPacket14StringList.ID, IPCPacket14StringList.class); + mappings.put(IPCPacketFFProcessKeepAlive.ID, IPCPacketFFProcessKeepAlive.class); + } + + public static byte[] IPCSerialize(IPCPacketBase pkt) throws IOException { + + IPC_OUTPUT_STREAM.feedBuffer(new byte[1 + pkt.size()], pkt.getClass().getSimpleName()); + IPC_OUTPUT_STREAM.write(pkt.id()); + pkt.serialize(IPC_DATA_OUTPUT_STREAM); + + return IPC_OUTPUT_STREAM.returnBuffer(); + } + + public static IPCPacketBase IPCDeserialize(byte[] pkt) throws IOException { + + IPC_INPUT_STREAM.feedBuffer(pkt); + int i = IPC_INPUT_STREAM.read(); + + Class pk = mappings.get(Integer.valueOf(i)); + if(pk == null) { + throw new IOException("Packet type 0x" + Integer.toHexString(i) + " doesn't exist"); + } + + IPCPacketBase p; + try { + p = pk.getDeclaredConstructor().newInstance(); + } catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException + | NoSuchMethodException | SecurityException e) { + throw new RuntimeException("Packet type '" + pk.getSimpleName() + "' could not be constructed", e); + } + + IPC_INPUT_STREAM.nameBuffer(pk.getSimpleName()); + + p.deserialize(IPC_DATA_INPUT_STREAM); + + return p; + } + +} diff --git a/sp-server/src/main/java/net/lax1dude/eaglercraft/sp/BooleanResult.java b/sp-server/src/main/java/net/lax1dude/eaglercraft/sp/BooleanResult.java new file mode 100644 index 0000000..576a6bf --- /dev/null +++ b/sp-server/src/main/java/net/lax1dude/eaglercraft/sp/BooleanResult.java @@ -0,0 +1,18 @@ +package net.lax1dude.eaglercraft.sp; + +public class BooleanResult { + + public static final BooleanResult TRUE = new BooleanResult(true); + public static final BooleanResult FALSE = new BooleanResult(false); + + public final boolean bool; + + private BooleanResult(boolean b) { + bool = b; + } + + public static BooleanResult _new(boolean b) { + return b ? TRUE : FALSE; + } + +} \ No newline at end of file diff --git a/sp-server/src/main/java/net/lax1dude/eaglercraft/sp/EAGMinecraftServer.java b/sp-server/src/main/java/net/lax1dude/eaglercraft/sp/EAGMinecraftServer.java new file mode 100644 index 0000000..7d6b2de --- /dev/null +++ b/sp-server/src/main/java/net/lax1dude/eaglercraft/sp/EAGMinecraftServer.java @@ -0,0 +1,78 @@ +package net.lax1dude.eaglercraft.sp; + +import java.io.File; +import java.io.IOException; + +import net.minecraft.server.MinecraftServer; +import net.minecraft.src.EnumGameType; +import net.minecraft.src.ILogAgent; +import net.minecraft.src.NetworkListenThread; + +public class EAGMinecraftServer extends MinecraftServer { + + public EAGMinecraftServer(File par1File) { + super(par1File); + // TODO Auto-generated constructor stub + } + + @Override + protected boolean startServer() throws IOException { + // TODO Auto-generated method stub + return false; + } + + @Override + public boolean canStructuresSpawn() { + // TODO Auto-generated method stub + return false; + } + + @Override + public EnumGameType getGameType() { + // TODO Auto-generated method stub + return null; + } + + @Override + public int getDifficulty() { + // TODO Auto-generated method stub + return 0; + } + + @Override + public boolean isHardcore() { + // TODO Auto-generated method stub + return false; + } + + @Override + public boolean isDedicatedServer() { + // TODO Auto-generated method stub + return false; + } + + @Override + public boolean isCommandBlockEnabled() { + // TODO Auto-generated method stub + return false; + } + + @Override + public NetworkListenThread getNetworkThread() { + // TODO Auto-generated method stub + return null; + } + + @Override + public String shareToLAN(EnumGameType var1, boolean var2) { + // TODO Auto-generated method stub + return null; + } + + @Override + public ILogAgent getLogAgent() { + // TODO Auto-generated method stub + return null; + } + +} diff --git a/sp-server/src/main/java/net/lax1dude/eaglercraft/sp/IntegratedServer.java b/sp-server/src/main/java/net/lax1dude/eaglercraft/sp/IntegratedServer.java new file mode 100644 index 0000000..7f7f579 --- /dev/null +++ b/sp-server/src/main/java/net/lax1dude/eaglercraft/sp/IntegratedServer.java @@ -0,0 +1,165 @@ +package net.lax1dude.eaglercraft.sp; + +import java.io.IOException; +import java.util.LinkedList; + +import org.teavm.jso.JSBody; +import org.teavm.jso.JSFunctor; +import org.teavm.jso.typedarrays.ArrayBuffer; +import org.teavm.jso.typedarrays.Uint8Array; + +import net.lax1dude.eaglercraft.sp.ipc.*; + +public class IntegratedServer { + + private static final LinkedList messageQueue = new LinkedList(); + + protected static class PKT { + protected final String channel; + protected final byte[] data; + protected PKT(String channel, byte[] data) { + this.channel = channel; + this.data = data; + } + } + + @JSFunctor + private static class WorkerBinaryPacketHandler { + + @SuppressWarnings("unused") + private void onMessage(String channel, ArrayBuffer buf) { + if(channel == null) { + System.err.println("Recieved IPC packet with null channel"); + return; + } + + if(buf == null) { + System.err.println("Recieved IPC packet with null buffer"); + return; + } + + Uint8Array a = Uint8Array.create(buf); + byte[] pkt = new byte[a.getLength()]; + for(int i = 0; i < a.getLength(); ++i) { + pkt[i] = (byte) a.get(i); + } + + messageQueue.add(new PKT(channel, pkt)); + } + + } + + private static void processAsyncMessageQueue() { + while(messageQueue.size() > 0) { + PKT msg = messageQueue.remove(0); + + if(msg.channel.equals("IPC")) { + + IPCPacketBase packet; + try { + packet = IPCPacketManager.IPCDeserialize(msg.data); + }catch(IOException e) { + System.err.print("Failed to deserialize IPC packet: "); + e.printStackTrace(); + return; + } + + int id = packet.id(); + switch(id) { + case IPCPacket00StartServer.ID: + + break; + case IPCPacket01StopServer.ID: + + break; + case IPCPacket02InitWorld.ID: + + break; + case IPCPacket03DeleteWorld.ID: + + break; + case IPCPacket04RenameWorld.ID: + + break; + case IPCPacket05RequestData.ID: + + break; + case IPCPacket07ImportWorld.ID: + + break; + case IPCPacket09RequestResponse.ID: + + break; + case IPCPacket0ASetWorldDifficulty.ID: + + break; + case IPCPacket0BPause.ID: + + break; + case IPCPacket0CPlayerChannel.ID: + + break; + case IPCPacket0EListWorlds.ID: + + break; + case IPCPacket0FListFiles.ID: + + break; + case IPCPacket10FileRead.ID: + + break; + case IPCPacket12FileWrite.ID: + + break; + case IPCPacket13FileCopyMove.ID: + + break; + case IPCPacket14StringList.ID: + + break; + default: + System.err.println("IPC packet type 0x" + Integer.toHexString(id) + " class '" + packet.getClass().getSimpleName() + "' was not handled"); + break; + } + + return; + } + + System.err.println("Unknown IPC channel: " + msg.channel); + } + } + + private static boolean isRunning = false; + + public static void halt() { + isRunning = false; + } + + private static void mainLoop() { + processAsyncMessageQueue(); + } + + @JSBody(params = { "wb" }, script = "onmessage = function(o) { wb(o.ch, o.dat); };") + private static native void registerPacketHandler(WorkerBinaryPacketHandler wb); + + public static void main(String[] args) { + + registerPacketHandler(new WorkerBinaryPacketHandler()); + + isRunning = true; + + while(isRunning) { + + mainLoop(); + + try { + Thread.sleep(1l); // allow some async to occur + }catch(InterruptedException e) { + System.err.println("you eagler"); + } + } + + // yee + } + +} diff --git a/sp-server/src/main/java/net/lax1dude/eaglercraft/sp/SYS.java b/sp-server/src/main/java/net/lax1dude/eaglercraft/sp/SYS.java new file mode 100644 index 0000000..38f94d1 --- /dev/null +++ b/sp-server/src/main/java/net/lax1dude/eaglercraft/sp/SYS.java @@ -0,0 +1,53 @@ +package net.lax1dude.eaglercraft.sp; + +import org.teavm.interop.Async; +import org.teavm.interop.AsyncCallback; +import org.teavm.jso.JSBody; +import org.teavm.jso.JSFunctor; +import org.teavm.jso.JSObject; +import org.teavm.jso.browser.Window; + +import net.lax1dude.eaglercraft.sp.VirtualFilesystem.VFSHandle; + +public class SYS { + + public static final boolean PERSIST; + public static final VirtualFilesystem VFS; + + @JSFunctor + private interface PromiseHandler extends JSObject { + void complete(JSObject result); + } + + @Async + private static native BooleanResult requestPersist(); + + private static void requestPersist(AsyncCallback callback) { + requestPersist0(res -> callback.complete(BooleanResult._new(res != null))); + } + + @JSBody(params = { "callback" }, script = "if(navigator.storage && navigator.storage.persist){" + + "navigator.storage.persist().then(function(persistent) {callback(persistent ? {p:true} : null);});" + + "}else{callback(null);}") + private static native void requestPersist0(PromiseHandler callback); + + static { + + PERSIST = requestPersist().bool; + + if(!PERSIST) { + Window.alert("PERSISTENT STORAGE NOT AVAILABLE, YOUR BROWSER MAY DELETE YOUR WORLDS!"); + } + + VFSHandle vh = VirtualFilesystem.openVFS("_net_lax1dude_eaglercraft_sp_VirtualFilesystem_1_5_2"); + + if(vh.vfs == null) { + Window.alert("COULD NOT INIT FILESYSTEM: " + vh.toString()); + } + + VFS = vh.vfs; + + } + + +} diff --git a/sp-server/src/main/java/net/lax1dude/eaglercraft/sp/VFSTestClass.java b/sp-server/src/main/java/net/lax1dude/eaglercraft/sp/VFSTestClass.java new file mode 100644 index 0000000..e354489 --- /dev/null +++ b/sp-server/src/main/java/net/lax1dude/eaglercraft/sp/VFSTestClass.java @@ -0,0 +1,117 @@ +package net.lax1dude.eaglercraft.sp; + +public class VFSTestClass { + + public static void test(VirtualFilesystem vfs) { + /* + System.out.println("'test1' exists: " + vfs.getFile("test1").exists()); + System.out.println("'test1' chars: " + vfs.getFile("test1").getAllChars()); + System.out.println("'test2' chars: " + vfs.getFile("test2").getAllChars()); + System.out.println("'test3' chars: " + vfs.getFile("test3").getAllChars()); + System.out.println("'test2' exists: " + vfs.getFile("test2").exists()); + System.out.println("'test3' exists: " + vfs.getFile("test3").exists()); + + System.out.println("'test1' set chars 'test string 1': " + vfs.getFile("test1").setAllChars("test string 1")); + System.out.println("'test2' set chars 'test string 2': " + vfs.getFile("test2").setAllChars("test string 2")); + System.out.println("'test3' set chars 'test string 3': " + vfs.getFile("test3").setAllChars("test string 3")); + + System.out.println("'test1' exists: " + vfs.getFile("test1").exists()); + System.out.println("'test2' exists: " + vfs.getFile("test2").exists()); + System.out.println("'test3' exists: " + vfs.getFile("test3").exists()); + + System.out.println("'test1' chars: " + vfs.getFile("test1").getAllChars()); + System.out.println("'test2' chars: " + vfs.getFile("test2").getAllChars()); + System.out.println("'test3' chars: " + vfs.getFile("test3").getAllChars()); + + System.out.println("'test3' delete: " + vfs.getFile("test3").delete()); + System.out.println("'test3' exists: " + vfs.getFile("test3").exists()); + + System.out.println("'test2' delete: " + vfs.getFile("test2").delete()); + System.out.println("'test2' chars: " + vfs.getFile("test2").getAllChars()); + + System.out.println("'test4' exists: " + vfs.getFile("test4").exists()); + System.out.println("'test1' to 'test4' rename: " + vfs.getFile("test1").rename("test4")); + System.out.println("'test4' exists: " + vfs.getFile("test4").exists()); + System.out.println("'test4' chars: " + vfs.getFile("test4").getAllChars()); + System.out.println("'test1' exists: " + vfs.getFile("test1").exists()); + System.out.println("'test4' to 'test1' rename: " + vfs.getFile("test4").rename("test1")); + System.out.println("'test4' exists: " + vfs.getFile("test4").exists()); + System.out.println("'test4' chars: " + vfs.getFile("test4").getAllChars()); + System.out.println("'test1' exists: " + vfs.getFile("test1").exists()); + System.out.println("'test1' chars: " + vfs.getFile("test1").getAllChars()); + + System.out.println("'test1' cache get chars: " + vfs.getFile("test1", true).getAllChars()); + System.out.println("'test1' cache exists: " + vfs.getFile("test1", true).exists()); + System.out.println("'test1' cache delete: " + vfs.getFile("test1", true).delete()); + System.out.println("'test1' cache exists: " + vfs.getFile("test1", true).exists()); + System.out.println("'test1' cache get chars: " + vfs.getFile("test1", true).getAllChars()); + + System.out.println("'test1' cache set chars 'test cache string 1': " + vfs.getFile("test1", true).setAllChars("test cache string 1")); + System.out.println("'test2' cache set chars 'test cache string 2': " + vfs.getFile("test2", true).setAllChars("test cache string 2")); + System.out.println("'test3' cache set chars 'test cache string 3': " + vfs.getFile("test3", true).setAllChars("test cache string 3")); + + System.out.println("'test1' cache chars: " + vfs.getFile("test1").getAllChars()); + System.out.println("'test2' cache chars: " + vfs.getFile("test2").getAllChars()); + System.out.println("'test3' cache chars: " + vfs.getFile("test3").getAllChars()); + + System.out.println("'test1' cache copy chars: " + VirtualFilesystem.utf8(vfs.getFile("test1").getAllBytes(true))); + System.out.println("'test2' cache copy chars: " + VirtualFilesystem.utf8(vfs.getFile("test2").getAllBytes(true))); + System.out.println("'test3' cache copy chars: " + VirtualFilesystem.utf8(vfs.getFile("test3").getAllBytes(true))); + */ + + VFile f = new VFile("test1"); + System.out.println(f); + + f = new VFile("/test1"); + System.out.println(f); + + f = new VFile("/test2/"); + System.out.println(f); + + f = new VFile("test2/"); + System.out.println(f); + + f = new VFile("test2/teste"); + System.out.println(f); + + f = new VFile("\\test2\\teste"); + System.out.println(f); + + f = new VFile("\\test2\\teste\\..\\eag"); + System.out.println(f); + + f = new VFile("test2", "teste", "eag"); + System.out.println(f); + + f = new VFile(f, "../", "test2", "teste", "eag"); + System.out.println(f); + + f = new VFile(f, "../../", "test2", ".", "eag"); + System.out.println(f); + + f = new VFile("you/eag", f); + System.out.println(f); + + f = new VFile(" you/ eag ", f); + System.out.println(f); + + f = new VFile("\\yee\\", f); + System.out.println(f); + + f = new VFile("\\yee\\", "yeeler", f, new VFile("yee")); + System.out.println(f); + + f = new VFile(f, new VFile("yee2")); + System.out.println(f); + + f = new VFile("yee/deevler/", new VFile("yee2")); + System.out.println(f); + + f = new VFile("yee/../../../../", new VFile("yee2")); + System.out.println(f); + + f = new VFile("yee/../../deevler../../", new VFile("yee2")); + System.out.println(f); + } + +} diff --git a/sp-server/src/main/java/net/lax1dude/eaglercraft/sp/VFile.java b/sp-server/src/main/java/net/lax1dude/eaglercraft/sp/VFile.java new file mode 100644 index 0000000..175d668 --- /dev/null +++ b/sp-server/src/main/java/net/lax1dude/eaglercraft/sp/VFile.java @@ -0,0 +1,213 @@ +package net.lax1dude.eaglercraft.sp; + +import java.io.InputStream; +import java.io.OutputStream; +import java.util.ArrayList; + +public class VFile { + + public static final String pathSeperator = "/"; + public static final String[] altPathSeperator = new String[] { "\\" }; + + public static String normalizePath(String p) { + for(int i = 0; i < altPathSeperator.length; ++i) { + p = p.replace(altPathSeperator[i], pathSeperator); + } + if(p.startsWith(pathSeperator)) { + p = p.substring(pathSeperator.length()); + } + if(p.endsWith(pathSeperator)) { + p = p.substring(0, p.length() - pathSeperator.length()); + } + return p; + } + + public static String[] splitPath(String p) { + String[] pth = normalizePath(p).split(pathSeperator); + for(int i = 0; i < pth.length; ++i) { + pth[i] = pth[i].trim(); + } + return pth; + } + + private String path; + + public static String createPath(Object... p) { + ArrayList r = new ArrayList(); + for(int i = 0; i < p.length; ++i) { + if(p[i] == null) { + continue; + } + String gg = p[i].toString(); + if(gg == null) { + continue; + } + String[] parts = splitPath(gg); + for(int j = 0; j < parts.length; ++j) { + if(parts[j] == null || parts[j].equals(".")) { + continue; + }else if(parts[j].equals("..") && r.size() > 0) { + int k = r.size() - 1; + if(!r.get(k).equals("..")) { + r.remove(k); + }else { + r.add(".."); + } + }else { + r.add(parts[j]); + } + } + } + if(r.size() > 0) { + StringBuilder s = new StringBuilder(); + for(int i = 0; i < r.size(); ++i) { + if(i > 0) { + s.append(pathSeperator); + } + s.append(r.get(i)); + } + return s.toString(); + }else { + return null; + } + } + + public VFile(Object... p) { + this.path = createPath(p); + } + + public InputStream getInputStream() { + return isRelative() ? null : SYS.VFS.getFile(path).getInputStream(); + } + + public OutputStream getOutputStream() { + return isRelative() ? null : SYS.VFS.getFile(path).getOutputStream(); + } + + public String toString() { + return path; + } + + public boolean isRelative() { + return path == null || path.contains(".."); + } + + public boolean canRead() { + return !isRelative() && SYS.VFS.fileExists(path); + } + + public String getPath() { + return path.equals("unnamed") ? null : path; + } + + public String getName() { + if(path == null) { + return null; + } + int i = path.indexOf(pathSeperator); + return i == -1 ? path : path.substring(i + 1); + } + + public boolean canWrite() { + return !isRelative(); + } + + public String getParent() { + if(path == null) { + return null; + } + int i = path.indexOf(pathSeperator); + return i == -1 ? ".." : path.substring(0, i); + } + + public int hashCode() { + return path == null ? 0 : path.hashCode(); + } + + public boolean equals(Object o) { + return path != null && o != null && (o instanceof VFile) && path.equals(((VFile)o).path); + } + + public boolean exists() { + return !isRelative() && SYS.VFS.fileExists(path); + } + + public boolean delete() { + return !isRelative() && SYS.VFS.deleteFile(path); + } + + public boolean renameTo(String p) { + if(!isRelative() && SYS.VFS.renameFile(path, p)) { + path = p; + return true; + } + return false; + } + + public int length() { + return isRelative() ? -1 : SYS.VFS.getFile(path).getSize(); + } + + public void getBytes(int fileOffset, byte[] array, int offset, int length) { + if(isRelative()) { + throw new ArrayIndexOutOfBoundsException("File is relative"); + } + SYS.VFS.getFile(path).getBytes(fileOffset, array, offset, length); + } + + public void setCacheEnabled() { + if(isRelative()) { + throw new RuntimeException("File is relative"); + } + SYS.VFS.getFile(path).setCacheEnabled(); + } + + public byte[] getAllBytes() { + if(isRelative()) { + return null; + } + return SYS.VFS.getFile(path).getAllBytes(); + } + + public String getAllChars() { + if(isRelative()) { + return null; + } + return SYS.VFS.getFile(path).getAllChars(); + } + + public String[] getAllLines() { + if(isRelative()) { + return null; + } + return SYS.VFS.getFile(path).getAllLines(); + } + + public byte[] getAllBytes(boolean copy) { + if(isRelative()) { + return null; + } + return SYS.VFS.getFile(path).getAllBytes(copy); + } + + public boolean setAllChars(String bytes) { + if(isRelative()) { + return false; + } + return SYS.VFS.getFile(path).setAllChars(bytes); + } + + public boolean setAllBytes(byte[] bytes) { + if(isRelative()) { + return false; + } + return SYS.VFS.getFile(path).setAllBytes(bytes); + } + + public boolean setAllBytes(byte[] bytes, boolean copy) { + if(isRelative()) { + return false; + } + return SYS.VFS.getFile(path).setAllBytes(bytes, copy); + } +} diff --git a/sp-server/src/main/java/net/lax1dude/eaglercraft/sp/VirtualFilesystem.java b/sp-server/src/main/java/net/lax1dude/eaglercraft/sp/VirtualFilesystem.java new file mode 100644 index 0000000..5bceb8e --- /dev/null +++ b/sp-server/src/main/java/net/lax1dude/eaglercraft/sp/VirtualFilesystem.java @@ -0,0 +1,572 @@ +package net.lax1dude.eaglercraft.sp; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.charset.Charset; +import java.util.HashMap; +import java.util.Iterator; + +import org.teavm.interop.Async; +import org.teavm.interop.AsyncCallback; +import org.teavm.jso.JSBody; +import org.teavm.jso.JSObject; +import org.teavm.jso.dom.events.Event; +import org.teavm.jso.dom.events.EventListener; +import org.teavm.jso.indexeddb.EventHandler; +import org.teavm.jso.indexeddb.IDBCountRequest; +import org.teavm.jso.indexeddb.IDBDatabase; +import org.teavm.jso.indexeddb.IDBFactory; +import org.teavm.jso.indexeddb.IDBGetRequest; +import org.teavm.jso.indexeddb.IDBObjectStoreParameters; +import org.teavm.jso.indexeddb.IDBOpenDBRequest; +import org.teavm.jso.indexeddb.IDBRequest; +import org.teavm.jso.indexeddb.IDBTransaction; +import org.teavm.jso.indexeddb.IDBVersionChangeEvent; +import org.teavm.jso.typedarrays.ArrayBuffer; +import org.teavm.jso.typedarrays.Uint8Array; + +public class VirtualFilesystem { + + protected static class VirtualOutputStream extends ByteArrayOutputStream { + private final VFSFile file; + + protected VirtualOutputStream(VFSFile file) { + this.file = file; + } + + public void close() throws IOException { + if(!file.setAllBytes(super.toByteArray(), false)) { + throw new IOException("Could not close stream and write to \"" + file.filePath + "\" on VFS \"" + file.virtualFilesystem.database + "\" (the file was probably deleted)"); + } + } + } + + public static class VFSFile { + + public final VirtualFilesystem virtualFilesystem; + protected boolean cacheEnabled; + protected String filePath; + protected int fileSize = -1; + protected boolean hasBeenDeleted = false; + protected boolean hasBeenAccessed = false; + protected boolean exists = false; + + protected byte[] cache = null; + protected long cacheHit; + + protected VFSFile(VirtualFilesystem vfs, String filePath, boolean cacheEnabled) { + this.virtualFilesystem = vfs; + this.filePath = filePath; + this.cacheHit = System.currentTimeMillis(); + if(cacheEnabled) { + setCacheEnabled(); + } + } + + public boolean equals(Object o) { + return (o instanceof VFSFile) && ((VFSFile)o).filePath.equals(filePath); + } + + public int hashCode() { + return filePath.hashCode(); + } + + public String getPath() { + return filePath; + } + + public int getSize() { + cacheHit = System.currentTimeMillis(); + if(fileSize < 0) { + if(cacheEnabled) { + byte[] b = getAllBytes(false); + if(b != null) { + fileSize = b.length; + } + }else { + ArrayBuffer dat = AsyncHandlers.readWholeFile(virtualFilesystem.indexeddb, filePath); + if(dat != null) { + fileSize = dat.getByteLength(); + } + } + } + return fileSize; + } + + public InputStream getInputStream() { + byte[] dat = getAllBytes(false); + if(dat == null) { + return null; + } + return new ByteArrayInputStream(dat); + } + + public OutputStream getOutputStream() { + return new VirtualOutputStream(this); + } + + public void getBytes(int fileOffset, byte[] array, int offset, int length) { + if(hasBeenDeleted) { + throw new ArrayIndexOutOfBoundsException("file '" + filePath + "' has been deleted"); + }else if(hasBeenAccessed && !exists) { + throw new ArrayIndexOutOfBoundsException("file '" + filePath + "' does not exist"); + } + cacheHit = System.currentTimeMillis(); + if(cacheEnabled && cache != null) { + System.arraycopy(cache, fileOffset, array, offset, length); + }else { + ArrayBuffer aa = AsyncHandlers.readWholeFile(virtualFilesystem.indexeddb, filePath); + hasBeenAccessed = true; + if(aa != null) { + exists = true; + }else { + exists = false; + throw new ArrayIndexOutOfBoundsException("file '" + filePath + "' does not exist"); + } + Uint8Array a = Uint8Array.create(aa); + this.fileSize = a.getByteLength(); + if(cacheEnabled) { + cache = new byte[fileSize]; + for(int i = 0; i < fileSize; ++i) { + cache[i] = (byte)a.get(i); + } + } + if(a.getLength() < fileOffset + length) { + throw new ArrayIndexOutOfBoundsException("file '" + filePath + "' size was "+a.getLength()+" but user tried to read index "+(fileOffset + length - 1)); + } + for(int i = 0; i < length; ++i) { + array[i + offset] = (byte)a.get(i + fileOffset); + } + } + } + + public void setCacheEnabled() { + if(!cacheEnabled && !hasBeenDeleted && !(hasBeenAccessed && !exists)) { + cacheHit = System.currentTimeMillis(); + cache = getAllBytes(false); + cacheEnabled = true; + } + } + + public byte[] getAllBytes() { + return getAllBytes(false); + } + + public String getAllChars() { + return utf8(getAllBytes(false)); + } + + public String[] getAllLines() { + return lines(getAllChars()); + } + + public byte[] getAllBytes(boolean copy) { + if(hasBeenDeleted || (hasBeenAccessed && !exists)) { + return null; + } + cacheHit = System.currentTimeMillis(); + if(cacheEnabled && cache != null) { + byte[] b = cache; + if(copy) { + b = new byte[cache.length]; + System.arraycopy(cache, 0, b, 0, cache.length); + } + return b; + }else { + hasBeenAccessed = true; + ArrayBuffer b = AsyncHandlers.readWholeFile(virtualFilesystem.indexeddb, filePath); + if(b != null) { + exists = true; + }else { + exists = false; + return null; + } + Uint8Array a = Uint8Array.create(b); + this.fileSize = a.getByteLength(); + byte[] array = new byte[fileSize]; + for(int i = 0; i < a.getByteLength(); ++i) { + array[i] = (byte)a.get(i); + } + if(cacheEnabled) { + if(copy) { + cache = new byte[fileSize]; + System.arraycopy(b, 0, cache, 0, cache.length); + }else { + cache = array; + } + } + return array; + } + } + + public boolean setAllChars(String bytes) { + return setAllBytes(utf8(bytes), true); + } + + public boolean setAllBytes(byte[] bytes) { + return setAllBytes(bytes, true); + } + + public boolean setAllBytes(byte[] bytes, boolean copy) { + if(hasBeenDeleted || bytes == null) { + return false; + } + cacheHit = System.currentTimeMillis(); + this.fileSize = bytes.length; + if(cacheEnabled) { + byte[] copz = bytes; + if(copy) { + copz = new byte[bytes.length]; + System.arraycopy(bytes, 0, copz, 0, bytes.length); + } + cache = copz; + return sync(); + }else { + ArrayBuffer a = ArrayBuffer.create(bytes.length); + Uint8Array ar = Uint8Array.create(a); + ar.set(bytes); + boolean s = AsyncHandlers.writeWholeFile(virtualFilesystem.indexeddb, filePath, a).bool; + hasBeenAccessed = true; + exists = exists || s; + return s; + } + } + + public boolean sync() { + if(cacheEnabled && cache != null && !hasBeenDeleted) { + cacheHit = System.currentTimeMillis(); + ArrayBuffer a = ArrayBuffer.create(cache.length); + Uint8Array ar = Uint8Array.create(a); + ar.set(cache); + boolean tryWrite = AsyncHandlers.writeWholeFile(virtualFilesystem.indexeddb, filePath, a).bool; + hasBeenAccessed = true; + exists = exists || tryWrite; + return tryWrite; + } + return false; + } + + public boolean delete() { + if(!hasBeenDeleted && !(hasBeenAccessed && !exists)) { + cacheHit = System.currentTimeMillis(); + if(!AsyncHandlers.deleteFile(virtualFilesystem.indexeddb, filePath).bool) { + hasBeenAccessed = true; + return false; + } + virtualFilesystem.fileMap.remove(filePath); + hasBeenDeleted = true; + hasBeenAccessed = true; + exists = false; + return true; + } + return false; + } + + public boolean rename(String newName) { + if(!hasBeenDeleted && !(hasBeenAccessed && !exists)) { + cacheHit = System.currentTimeMillis(); + ArrayBuffer arr = AsyncHandlers.readWholeFile(virtualFilesystem.indexeddb, filePath); + hasBeenAccessed = true; + if(arr != null) { + exists = true; + if(!AsyncHandlers.writeWholeFile(virtualFilesystem.indexeddb, newName, arr).bool) { + return false; + } + if(!AsyncHandlers.deleteFile(virtualFilesystem.indexeddb, filePath).bool) { + return false; + } + }else { + exists = false; + } + virtualFilesystem.fileMap.remove(filePath); + filePath = newName; + virtualFilesystem.fileMap.put(newName, this); + return true; + } + return false; + } + + public boolean exists() { + if(hasBeenDeleted) { + return false; + } + cacheHit = System.currentTimeMillis(); + if(hasBeenAccessed) { + return exists; + } + exists = AsyncHandlers.fileExists(virtualFilesystem.indexeddb, filePath).bool; + hasBeenAccessed = true; + return exists; + } + + } + + private final HashMap fileMap = new HashMap(); + + public final String database; + private final IDBDatabase indexeddb; + + public static class VFSHandle { + + public final boolean failedInit; + public final boolean failedLocked; + public final String failedError; + public final VirtualFilesystem vfs; + + public VFSHandle(boolean init, boolean locked, String error, VirtualFilesystem db) { + failedInit = init; + failedLocked = locked; + failedError = error; + vfs = db; + } + + public String toString() { + if(failedInit) { + return "IDBFactory threw an exception, IndexedDB is most likely not supported in this browser." + (failedError == null ? "" : "\n\n" + failedError); + } + if(failedLocked) { + return "The filesystem requested is already in use on a different tab."; + } + if(failedError != null) { + return "The IDBFactory.open() request failed, reason: " + failedError; + } + return "Virtual Filesystem Object: " + vfs.database; + } + + } + + public static VFSHandle openVFS(String db) { + DatabaseOpen evt = AsyncHandlers.openDB(db); + if(evt.failedInit) { + return new VFSHandle(true, false, evt.failedError, null); + } + if(evt.failedLocked) { + return new VFSHandle(false, true, null, null); + } + if(evt.failedError != null) { + return new VFSHandle(false, false, evt.failedError, null); + } + return new VFSHandle(false, false, null, new VirtualFilesystem(db, evt.database)); + } + + private VirtualFilesystem(String db, IDBDatabase idb) { + database = db; + indexeddb = idb; + } + + public void close() { + indexeddb.close(); + } + + public VFSFile getFile(String path) { + return getFile(path, false); + } + + public VFSFile getFile(String path, boolean cache) { + VFSFile f = fileMap.get(path); + if(f == null) { + fileMap.put(path, f = new VFSFile(this, path, cache)); + }else { + if(cache) { + f.setCacheEnabled(); + } + } + return f; + } + + public boolean renameFile(String oldName, String newName) { + return getFile(oldName).rename(newName); + } + + public boolean deleteFile(String path) { + return getFile(path).delete(); + } + + public boolean fileExists(String path) { + return getFile(path).exists(); + } + + public void flushCache(long age) { + long curr = System.currentTimeMillis(); + Iterator files = fileMap.values().iterator(); + while(files.hasNext()) { + if(curr - files.next().cacheHit > age) { + files.remove(); + } + } + } + + protected static class DatabaseOpen { + + protected final boolean failedInit; + protected final boolean failedLocked; + protected final String failedError; + + protected final IDBDatabase database; + + protected DatabaseOpen(boolean init, boolean locked, String error, IDBDatabase db) { + failedInit = init; + failedLocked = locked; + failedError = error; + database = db; + } + + } + + protected static class AsyncHandlers { + + @Async + protected static native DatabaseOpen openDB(String name); + + private static void openDB(String name, final AsyncCallback cb) { + IDBFactory i = null; + try { + i = IDBFactory.getInstance(); + }catch(Throwable t) { + cb.complete(new DatabaseOpen(true, false, t.toString(), null)); + } + final IDBOpenDBRequest f = i.open(name, 1); + f.setOnBlocked(new EventHandler() { + @Override + public void handleEvent() { + cb.complete(new DatabaseOpen(false, true, null, null)); + } + }); + f.setOnSuccess(new EventHandler() { + @Override + public void handleEvent() { + cb.complete(new DatabaseOpen(false, false, null, f.getResult())); + } + }); + f.setOnError(new EventHandler() { + @Override + public void handleEvent() { + cb.complete(new DatabaseOpen(false, false, "open error", null)); + } + }); + f.setOnUpgradeNeeded(new EventListener() { + @Override + public void handleEvent(IDBVersionChangeEvent evt) { + f.getResult().createObjectStore("filesystem", IDBObjectStoreParameters.create().keyPath("path")); + } + }); + } + + @Async + protected static native BooleanResult deleteFile(IDBDatabase db, String name); + + private static void deleteFile(IDBDatabase db, String name, final AsyncCallback cb) { + IDBTransaction tx = db.transaction("filesystem", "readwrite"); + final IDBRequest r = tx.objectStore("filesystem").delete(makeTheFuckingKeyWork(name)); + + r.addEventListener("success", new EventListener() { + @Override + public void handleEvent(Event evt) { + cb.complete(BooleanResult._new(true)); + } + }); + r.addEventListener("error", new EventListener() { + @Override + public void handleEvent(Event evt) { + cb.complete(BooleanResult._new(false)); + } + }); + } + + @JSBody(params = { "obj" }, script = "return (typeof obj === 'undefined') ? null : ((typeof obj.data === 'undefined') ? null : obj.data);") + protected static native ArrayBuffer readRow(JSObject obj); + + @JSBody(params = { "obj" }, script = "return [obj];") + private static native JSObject makeTheFuckingKeyWork(String k); + + @Async + protected static native ArrayBuffer readWholeFile(IDBDatabase db, String name); + + private static void readWholeFile(IDBDatabase db, String name, final AsyncCallback cb) { + IDBTransaction tx = db.transaction("filesystem", "readonly"); + final IDBGetRequest r = tx.objectStore("filesystem").get(makeTheFuckingKeyWork(name)); + r.addEventListener("success", new EventListener() { + @Override + public void handleEvent(Event evt) { + cb.complete(readRow(r.getResult())); + } + }); + r.addEventListener("error", new EventListener() { + @Override + public void handleEvent(Event evt) { + cb.complete(null); + } + }); + + } + + @Async + protected static native BooleanResult fileExists(IDBDatabase db, String name); + + private static void fileExists(IDBDatabase db, String name, final AsyncCallback cb) { + IDBTransaction tx = db.transaction("filesystem", "readonly"); + final IDBCountRequest r = tx.objectStore("filesystem").count(makeTheFuckingKeyWork(name)); + r.addEventListener("success", new EventListener() { + @Override + public void handleEvent(Event evt) { + cb.complete(BooleanResult._new(r.getResult() > 0)); + } + }); + r.addEventListener("error", new EventListener() { + @Override + public void handleEvent(Event evt) { + cb.complete(BooleanResult._new(false)); + } + }); + } + + @JSBody(params = { "pat", "dat" }, script = "return { path: pat, data: dat };") + protected static native JSObject writeRow(String name, ArrayBuffer data); + + @Async + protected static native BooleanResult writeWholeFile(IDBDatabase db, String name, ArrayBuffer data); + + private static void writeWholeFile(IDBDatabase db, String name, ArrayBuffer data, final AsyncCallback cb) { + IDBTransaction tx = db.transaction("filesystem", "readwrite"); + final IDBRequest r = tx.objectStore("filesystem").put(writeRow(name, data)); + + r.addEventListener("success", new EventListener() { + @Override + public void handleEvent(Event evt) { + cb.complete(BooleanResult._new(true)); + } + }); + r.addEventListener("error", new EventListener() { + @Override + public void handleEvent(Event evt) { + cb.complete(BooleanResult._new(false)); + } + }); + } + + } + + public static byte[] utf8(String str) { + if(str == null) return null; + return str.getBytes(Charset.forName("UTF-8")); + } + + public static String utf8(byte[] str) { + if(str == null) return null; + return new String(str, Charset.forName("UTF-8")); + } + + public static String CRLFtoLF(String str) { + if(str == null) return null; + return str.indexOf('\r') != -1 ? str.replace("\r", "") : str; + } + + public static String[] lines(String str) { + if(str == null) return null; + return CRLFtoLF(str).split("\n"); + } + +} \ No newline at end of file diff --git a/sp-server/src/main/java/net/minecraft/server/MinecraftServer.java b/sp-server/src/main/java/net/minecraft/server/MinecraftServer.java new file mode 100644 index 0000000..2e92e9d --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/server/MinecraftServer.java @@ -0,0 +1,1243 @@ +package net.minecraft.server; + +import java.awt.GraphicsEnvironment; +import java.io.File; +import java.io.IOException; +import java.security.KeyPair; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.Iterator; +import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; +import net.minecraft.src.AnvilSaveConverter; +import net.minecraft.src.AxisAlignedBB; +import net.minecraft.src.CallableIsServerModded; +import net.minecraft.src.CallableServerMemoryStats; +import net.minecraft.src.CallableServerProfiler; +import net.minecraft.src.ChunkCoordinates; +import net.minecraft.src.CommandBase; +import net.minecraft.src.ConvertingProgressUpdate; +import net.minecraft.src.CrashReport; +import net.minecraft.src.DedicatedServer; +import net.minecraft.src.DemoWorldServer; +import net.minecraft.src.DispenserBehaviors; +import net.minecraft.src.EntityPlayer; +import net.minecraft.src.EnumGameType; +import net.minecraft.src.ICommandManager; +import net.minecraft.src.ICommandSender; +import net.minecraft.src.ILogAgent; +import net.minecraft.src.IPlayerUsage; +import net.minecraft.src.IProgressUpdate; +import net.minecraft.src.ISaveFormat; +import net.minecraft.src.ISaveHandler; +import net.minecraft.src.IUpdatePlayerListBox; +import net.minecraft.src.MathHelper; +import net.minecraft.src.MinecraftException; +import net.minecraft.src.NetworkListenThread; +import net.minecraft.src.Packet; +import net.minecraft.src.Packet4UpdateTime; +import net.minecraft.src.PlayerUsageSnooper; +import net.minecraft.src.Profiler; +import net.minecraft.src.RConConsoleSource; +import net.minecraft.src.ReportedException; +import net.minecraft.src.ServerCommandManager; +import net.minecraft.src.ServerConfigurationManager; +import net.minecraft.src.StatList; +import net.minecraft.src.StringTranslate; +import net.minecraft.src.StringUtils; +import net.minecraft.src.ThreadDedicatedServer; +import net.minecraft.src.ThreadMinecraftServer; +import net.minecraft.src.World; +import net.minecraft.src.WorldInfo; +import net.minecraft.src.WorldManager; +import net.minecraft.src.WorldServer; +import net.minecraft.src.WorldServerMulti; +import net.minecraft.src.WorldSettings; +import net.minecraft.src.WorldType; + +public abstract class MinecraftServer implements ICommandSender, Runnable, IPlayerUsage { + /** Instance of Minecraft Server. */ + private static MinecraftServer mcServer = null; + private final ISaveFormat anvilConverterForAnvilFile; + + /** The PlayerUsageSnooper instance. */ + private final PlayerUsageSnooper usageSnooper = new PlayerUsageSnooper("server", this); + private final File anvilFile; + + /** List of names of players who are online. */ + private final List playersOnline = new ArrayList(); + private final ICommandManager commandManager; + public final Profiler theProfiler = new Profiler(); + + /** The server's hostname. */ + private String hostname; + + /** The server's port. */ + private int serverPort = -1; + + /** The server world instances. */ + public WorldServer[] worldServers; + + /** The ServerConfigurationManager instance. */ + private ServerConfigurationManager serverConfigManager; + + /** + * Indicates whether the server is running or not. Set to false to initiate a + * shutdown. + */ + private boolean serverRunning = true; + + /** Indicates to other classes that the server is safely stopped. */ + private boolean serverStopped = false; + + /** Incremented every tick. */ + private int tickCounter = 0; + + /** + * The task the server is currently working on(and will output on + * outputPercentRemaining). + */ + public String currentTask; + + /** The percentage of the current task finished so far. */ + public int percentDone; + + /** True if the server is in online mode. */ + private boolean onlineMode; + + /** True if the server has animals turned on. */ + private boolean canSpawnAnimals; + private boolean canSpawnNPCs; + + /** Indicates whether PvP is active on the server or not. */ + private boolean pvpEnabled; + + /** Determines if flight is allowed or not. */ + private boolean allowFlight; + + /** The server MOTD string. */ + private String motd; + + /** Maximum build height. */ + private int buildLimit; + private long lastSentPacketID; + private long lastSentPacketSize; + private long lastReceivedID; + private long lastReceivedSize; + public final long[] sentPacketCountArray = new long[100]; + public final long[] sentPacketSizeArray = new long[100]; + public final long[] receivedPacketCountArray = new long[100]; + public final long[] receivedPacketSizeArray = new long[100]; + public final long[] tickTimeArray = new long[100]; + + /** Stats are [dimension][tick%100] system.nanoTime is stored. */ + public long[][] timeOfLastDimensionTick; + private KeyPair serverKeyPair; + + /** Username of the server owner (for integrated servers) */ + private String serverOwner; + private String folderName; + private boolean isDemo; + private boolean enableBonusChest; + + /** + * If true, there is no need to save chunks or stop the server, because that is + * already being done. + */ + private boolean worldIsBeingDeleted; + private String texturePack = ""; + private boolean serverIsRunning = false; + + /** + * Set when warned for "Can't keep up", which triggers again after 15 seconds. + */ + private long timeOfLastWarning; + private String userMessage; + private boolean startProfiling; + private boolean field_104057_T = false; + + public MinecraftServer(File par1File) { + mcServer = this; + this.anvilFile = par1File; + this.commandManager = new ServerCommandManager(); + this.anvilConverterForAnvilFile = new AnvilSaveConverter(par1File); + this.registerDispenseBehaviors(); + } + + /** + * Register all dispense behaviors. + */ + private void registerDispenseBehaviors() { + DispenserBehaviors.func_96467_a(); + } + + /** + * Initialises the server and starts it. + */ + protected abstract boolean startServer() throws IOException; + + protected void convertMapIfNeeded(String par1Str) { + if (this.getActiveAnvilConverter().isOldMapFormat(par1Str)) { + this.getLogAgent().func_98233_a("Converting map!"); + this.setUserMessage("menu.convertingLevel"); + this.getActiveAnvilConverter().convertMapFormat(par1Str, new ConvertingProgressUpdate(this)); + } + } + + /** + * Typically "menu.convertingLevel", "menu.loadingLevel" or others. + */ + protected synchronized void setUserMessage(String par1Str) { + this.userMessage = par1Str; + } + + protected void loadAllWorlds(String par1Str, String par2Str, long par3, WorldType par5WorldType, String par6Str) { + this.convertMapIfNeeded(par1Str); + this.setUserMessage("menu.loadingLevel"); + this.worldServers = new WorldServer[3]; + this.timeOfLastDimensionTick = new long[this.worldServers.length][100]; + ISaveHandler var7 = this.anvilConverterForAnvilFile.getSaveLoader(par1Str, true); + WorldInfo var9 = var7.loadWorldInfo(); + WorldSettings var8; + + if (var9 == null) { + var8 = new WorldSettings(par3, this.getGameType(), this.canStructuresSpawn(), this.isHardcore(), + par5WorldType); + var8.func_82750_a(par6Str); + } else { + var8 = new WorldSettings(var9); + } + + if (this.enableBonusChest) { + var8.enableBonusChest(); + } + + for (int var10 = 0; var10 < this.worldServers.length; ++var10) { + byte var11 = 0; + + if (var10 == 1) { + var11 = -1; + } + + if (var10 == 2) { + var11 = 1; + } + + if (var10 == 0) { + if (this.isDemo()) { + this.worldServers[var10] = new DemoWorldServer(this, var7, par2Str, var11, this.theProfiler, + this.getLogAgent()); + } else { + this.worldServers[var10] = new WorldServer(this, var7, par2Str, var11, var8, this.theProfiler, + this.getLogAgent()); + } + } else { + this.worldServers[var10] = new WorldServerMulti(this, var7, par2Str, var11, var8, this.worldServers[0], + this.theProfiler, this.getLogAgent()); + } + + this.worldServers[var10].addWorldAccess(new WorldManager(this, this.worldServers[var10])); + + if (!this.isSinglePlayer()) { + this.worldServers[var10].getWorldInfo().setGameType(this.getGameType()); + } + + this.serverConfigManager.setPlayerManager(this.worldServers); + } + + this.setDifficultyForAllWorlds(this.getDifficulty()); + this.initialWorldChunkLoad(); + } + + protected void initialWorldChunkLoad() { + int var5 = 0; + this.setUserMessage("menu.generatingTerrain"); + byte var6 = 0; + this.getLogAgent().func_98233_a("Preparing start region for level " + var6); + WorldServer var7 = this.worldServers[var6]; + ChunkCoordinates var8 = var7.getSpawnPoint(); + long var9 = System.currentTimeMillis(); + + for (int var11 = -192; var11 <= 192 && this.isServerRunning(); var11 += 16) { + for (int var12 = -192; var12 <= 192 && this.isServerRunning(); var12 += 16) { + long var13 = System.currentTimeMillis(); + + if (var13 - var9 > 1000L) { + this.outputPercentRemaining("Preparing spawn area", var5 * 100 / 625); + var9 = var13; + } + + ++var5; + var7.theChunkProviderServer.loadChunk(var8.posX + var11 >> 4, var8.posZ + var12 >> 4); + } + } + + this.clearCurrentTask(); + } + + public abstract boolean canStructuresSpawn(); + + public abstract EnumGameType getGameType(); + + /** + * Defaults to "1" (Easy) for the dedicated server, defaults to "2" (Normal) on + * the client. + */ + public abstract int getDifficulty(); + + /** + * Defaults to false. + */ + public abstract boolean isHardcore(); + + /** + * Used to display a percent remaining given text and the percentage. + */ + protected void outputPercentRemaining(String par1Str, int par2) { + this.currentTask = par1Str; + this.percentDone = par2; + this.getLogAgent().func_98233_a(par1Str + ": " + par2 + "%"); + } + + /** + * Set current task to null and set its percentage to 0. + */ + protected void clearCurrentTask() { + this.currentTask = null; + this.percentDone = 0; + } + + /** + * par1 indicates if a log message should be output. + */ + protected void saveAllWorlds(boolean par1) { + if (!this.worldIsBeingDeleted) { + WorldServer[] var2 = this.worldServers; + int var3 = var2.length; + + for (int var4 = 0; var4 < var3; ++var4) { + WorldServer var5 = var2[var4]; + + if (var5 != null) { + if (!par1) { + this.getLogAgent().func_98233_a("Saving chunks for level \'" + + var5.getWorldInfo().getWorldName() + "\'/" + var5.provider.getDimensionName()); + } + + try { + var5.saveAllChunks(true, (IProgressUpdate) null); + } catch (MinecraftException var7) { + this.getLogAgent().func_98236_b(var7.getMessage()); + } + } + } + } + } + + /** + * Saves all necessary data as preparation for stopping the server. + */ + public void stopServer() { + if (!this.worldIsBeingDeleted) { + this.getLogAgent().func_98233_a("Stopping server"); + + if (this.getNetworkThread() != null) { + this.getNetworkThread().stopListening(); + } + + if (this.serverConfigManager != null) { + this.getLogAgent().func_98233_a("Saving players"); + this.serverConfigManager.saveAllPlayerData(); + this.serverConfigManager.removeAllPlayers(); + } + + this.getLogAgent().func_98233_a("Saving worlds"); + this.saveAllWorlds(false); + + for (int var1 = 0; var1 < this.worldServers.length; ++var1) { + WorldServer var2 = this.worldServers[var1]; + var2.flush(); + } + + if (this.usageSnooper != null && this.usageSnooper.isSnooperRunning()) { + this.usageSnooper.stopSnooper(); + } + } + } + + /** + * "getHostname" is already taken, but both return the hostname. + */ + public String getServerHostname() { + return this.hostname; + } + + public void setHostname(String par1Str) { + this.hostname = par1Str; + } + + public boolean isServerRunning() { + return this.serverRunning; + } + + /** + * Sets the serverRunning variable to false, in order to get the server to shut + * down. + */ + public void initiateShutdown() { + this.serverRunning = false; + } + + public void run() { + try { + if (this.startServer()) { + long var1 = System.currentTimeMillis(); + + for (long var50 = 0L; this.serverRunning; this.serverIsRunning = true) { + long var5 = System.currentTimeMillis(); + long var7 = var5 - var1; + + if (var7 > 2000L && var1 - this.timeOfLastWarning >= 15000L) { + this.getLogAgent().func_98236_b( + "Can\'t keep up! Did the system time change, or is the server overloaded?"); + var7 = 2000L; + this.timeOfLastWarning = var1; + } + + if (var7 < 0L) { + this.getLogAgent().func_98236_b("Time ran backwards! Did the system time change?"); + var7 = 0L; + } + + var50 += var7; + var1 = var5; + + if (this.worldServers[0].areAllPlayersAsleep()) { + this.tick(); + var50 = 0L; + } else { + while (var50 > 50L) { + var50 -= 50L; + this.tick(); + } + } + + Thread.sleep(1L); + } + } else { + this.finalTick((CrashReport) null); + } + } catch (Throwable var48) { + var48.printStackTrace(); + this.getLogAgent().logSevereException( + "Encountered an unexpected exception " + var48.getClass().getSimpleName(), var48); + CrashReport var2 = null; + + if (var48 instanceof ReportedException) { + var2 = this.addServerInfoToCrashReport(((ReportedException) var48).getCrashReport()); + } else { + var2 = this.addServerInfoToCrashReport(new CrashReport("Exception in server tick loop", var48)); + } + + File var3 = new File(new File(this.getDataDirectory(), "crash-reports"), + "crash-" + (new SimpleDateFormat("yyyy-MM-dd_HH.mm.ss")).format(new Date()) + "-server.txt"); + + if (var2.saveToFile(var3, this.getLogAgent())) { + this.getLogAgent().logSevere("This crash report has been saved to: " + var3.getAbsolutePath()); + } else { + this.getLogAgent().logSevere("We were unable to save this crash report to disk."); + } + + this.finalTick(var2); + } finally { + try { + this.stopServer(); + this.serverStopped = true; + } catch (Throwable var46) { + var46.printStackTrace(); + } finally { + this.systemExitNow(); + } + } + } + + protected File getDataDirectory() { + return new File("."); + } + + /** + * Called on exit from the main run() loop. + */ + protected void finalTick(CrashReport par1CrashReport) { + } + + /** + * Directly calls System.exit(0), instantly killing the program. + */ + protected void systemExitNow() { + } + + /** + * Main function called by run() every loop. + */ + protected void tick() { + long var1 = System.nanoTime(); + AxisAlignedBB.getAABBPool().cleanPool(); + ++this.tickCounter; + + if (this.startProfiling) { + this.startProfiling = false; + this.theProfiler.profilingEnabled = true; + this.theProfiler.clearProfiling(); + } + + this.theProfiler.startSection("root"); + this.updateTimeLightAndEntities(); + + if (this.tickCounter % 900 == 0) { + this.theProfiler.startSection("save"); + this.serverConfigManager.saveAllPlayerData(); + this.saveAllWorlds(true); + this.theProfiler.endSection(); + } + + this.theProfiler.startSection("tallying"); + this.tickTimeArray[this.tickCounter % 100] = System.nanoTime() - var1; + this.sentPacketCountArray[this.tickCounter % 100] = Packet.sentID - this.lastSentPacketID; + this.lastSentPacketID = Packet.sentID; + this.sentPacketSizeArray[this.tickCounter % 100] = Packet.sentSize - this.lastSentPacketSize; + this.lastSentPacketSize = Packet.sentSize; + this.receivedPacketCountArray[this.tickCounter % 100] = Packet.receivedID - this.lastReceivedID; + this.lastReceivedID = Packet.receivedID; + this.receivedPacketSizeArray[this.tickCounter % 100] = Packet.receivedSize - this.lastReceivedSize; + this.lastReceivedSize = Packet.receivedSize; + this.theProfiler.endSection(); + this.theProfiler.startSection("snooper"); + + if (!this.usageSnooper.isSnooperRunning() && this.tickCounter > 100) { + this.usageSnooper.startSnooper(); + } + + if (this.tickCounter % 6000 == 0) { + this.usageSnooper.addMemoryStatsToSnooper(); + } + + this.theProfiler.endSection(); + this.theProfiler.endSection(); + } + + public void updateTimeLightAndEntities() { + this.theProfiler.startSection("levels"); + int var1; + + for (var1 = 0; var1 < this.worldServers.length; ++var1) { + long var2 = System.nanoTime(); + + if (var1 == 0 || this.getAllowNether()) { + WorldServer var4 = this.worldServers[var1]; + this.theProfiler.startSection(var4.getWorldInfo().getWorldName()); + this.theProfiler.startSection("pools"); + var4.getWorldVec3Pool().clear(); + this.theProfiler.endSection(); + + if (this.tickCounter % 20 == 0) { + this.theProfiler.startSection("timeSync"); + this.serverConfigManager.sendPacketToAllPlayersInDimension( + new Packet4UpdateTime(var4.getTotalWorldTime(), var4.getWorldTime()), + var4.provider.dimensionId); + this.theProfiler.endSection(); + } + + this.theProfiler.startSection("tick"); + CrashReport var6; + + try { + var4.tick(); + } catch (Throwable var8) { + var6 = CrashReport.makeCrashReport(var8, "Exception ticking world"); + var4.addWorldInfoToCrashReport(var6); + throw new ReportedException(var6); + } + + try { + var4.updateEntities(); + } catch (Throwable var7) { + var6 = CrashReport.makeCrashReport(var7, "Exception ticking world entities"); + var4.addWorldInfoToCrashReport(var6); + throw new ReportedException(var6); + } + + this.theProfiler.endSection(); + this.theProfiler.startSection("tracker"); + var4.getEntityTracker().updateTrackedEntities(); + this.theProfiler.endSection(); + this.theProfiler.endSection(); + } + + this.timeOfLastDimensionTick[var1][this.tickCounter % 100] = System.nanoTime() - var2; + } + + this.theProfiler.endStartSection("connection"); + this.getNetworkThread().handleNetworkListenThread(); + this.theProfiler.endStartSection("players"); + this.serverConfigManager.onTick(); + this.theProfiler.endStartSection("tickables"); + + for (var1 = 0; var1 < this.playersOnline.size(); ++var1) { + ((IUpdatePlayerListBox) this.playersOnline.get(var1)).update(); + } + + this.theProfiler.endSection(); + } + + public boolean getAllowNether() { + return true; + } + + public void func_82010_a(IUpdatePlayerListBox par1IUpdatePlayerListBox) { + this.playersOnline.add(par1IUpdatePlayerListBox); + } + + public static void main(String[] par0ArrayOfStr) { + StatList.nopInit(); + ILogAgent var1 = null; + + try { + boolean var2 = !GraphicsEnvironment.isHeadless(); + String var3 = null; + String var4 = "."; + String var5 = null; + boolean var6 = false; + boolean var7 = false; + int var8 = -1; + + for (int var9 = 0; var9 < par0ArrayOfStr.length; ++var9) { + String var10 = par0ArrayOfStr[var9]; + String var11 = var9 == par0ArrayOfStr.length - 1 ? null : par0ArrayOfStr[var9 + 1]; + boolean var12 = false; + + if (!var10.equals("nogui") && !var10.equals("--nogui")) { + if (var10.equals("--port") && var11 != null) { + var12 = true; + + try { + var8 = Integer.parseInt(var11); + } catch (NumberFormatException var14) { + ; + } + } else if (var10.equals("--singleplayer") && var11 != null) { + var12 = true; + var3 = var11; + } else if (var10.equals("--universe") && var11 != null) { + var12 = true; + var4 = var11; + } else if (var10.equals("--world") && var11 != null) { + var12 = true; + var5 = var11; + } else if (var10.equals("--demo")) { + var6 = true; + } else if (var10.equals("--bonusChest")) { + var7 = true; + } + } else { + var2 = false; + } + + if (var12) { + ++var9; + } + } + + DedicatedServer var16 = new DedicatedServer(new File(var4)); + var1 = var16.getLogAgent(); + + if (var3 != null) { + var16.setServerOwner(var3); + } + + if (var5 != null) { + var16.setFolderName(var5); + } + + if (var8 >= 0) { + var16.setServerPort(var8); + } + + if (var6) { + var16.setDemo(true); + } + + if (var7) { + var16.canCreateBonusChest(true); + } + + if (var2) { + var16.enableGui(); + } + + var16.startServerThread(); + Runtime.getRuntime().addShutdownHook(new ThreadDedicatedServer(var16)); + } catch (Exception var15) { + if (var1 != null) { + var1.logSevereException("Failed to start the minecraft server", var15); + } else { + Logger.getAnonymousLogger().log(Level.SEVERE, "Failed to start the minecraft server", var15); + } + } + } + + public void startServerThread() { + (new ThreadMinecraftServer(this, "Server thread")).start(); + } + + /** + * Returns a File object from the specified string. + */ + public File getFile(String par1Str) { + return new File(this.getDataDirectory(), par1Str); + } + + /** + * Logs the message with a level of INFO. + */ + public void logInfo(String par1Str) { + this.getLogAgent().func_98233_a(par1Str); + } + + /** + * Logs the message with a level of WARN. + */ + public void logWarning(String par1Str) { + this.getLogAgent().func_98236_b(par1Str); + } + + /** + * Gets the worldServer by the given dimension. + */ + public WorldServer worldServerForDimension(int par1) { + return par1 == -1 ? this.worldServers[1] : (par1 == 1 ? this.worldServers[2] : this.worldServers[0]); + } + + /** + * Returns the server's hostname. + */ + public String getHostname() { + return this.hostname; + } + + /** + * Never used, but "getServerPort" is already taken. + */ + public int getPort() { + return this.serverPort; + } + + /** + * Returns the server message of the day + */ + public String getMotd() { + return this.motd; + } + + /** + * Returns the server's Minecraft version as string. + */ + public String getMinecraftVersion() { + return "1.5.2"; + } + + /** + * Returns the number of players currently on the server. + */ + public int getCurrentPlayerCount() { + return this.serverConfigManager.getCurrentPlayerCount(); + } + + /** + * Returns the maximum number of players allowed on the server. + */ + public int getMaxPlayers() { + return this.serverConfigManager.getMaxPlayers(); + } + + /** + * Returns an array of the usernames of all the connected players. + */ + public String[] getAllUsernames() { + return this.serverConfigManager.getAllUsernames(); + } + + /** + * Used by RCon's Query in the form of "MajorServerMod 1.2.3: MyPlugin 1.3; + * AnotherPlugin 2.1; AndSoForth 1.0". + */ + public String getPlugins() { + return ""; + } + + /** + * Handle a command received by an RCon instance + */ + public String handleRConCommand(String par1Str) { + RConConsoleSource.instance.resetLog(); + this.commandManager.executeCommand(RConConsoleSource.instance, par1Str); + return RConConsoleSource.instance.getLogContents(); + } + + /** + * Returns true if debugging is enabled, false otherwise. + */ + public boolean isDebuggingEnabled() { + return false; + } + + /** + * Logs the error message with a level of SEVERE. + */ + public void logSevere(String par1Str) { + this.getLogAgent().logSevere(par1Str); + } + + /** + * If isDebuggingEnabled(), logs the message with a level of INFO. + */ + public void logDebug(String par1Str) { + if (this.isDebuggingEnabled()) { + this.getLogAgent().func_98233_a(par1Str); + } + } + + public String getServerModName() { + return "vanilla"; + } + + /** + * Adds the server info, including from theWorldServer, to the crash report. + */ + public CrashReport addServerInfoToCrashReport(CrashReport par1CrashReport) { + par1CrashReport.func_85056_g().addCrashSectionCallable("Profiler Position", new CallableIsServerModded(this)); + + if (this.worldServers != null && this.worldServers.length > 0 && this.worldServers[0] != null) { + par1CrashReport.func_85056_g().addCrashSectionCallable("Vec3 Pool Size", new CallableServerProfiler(this)); + } + + if (this.serverConfigManager != null) { + par1CrashReport.func_85056_g().addCrashSectionCallable("Player Count", new CallableServerMemoryStats(this)); + } + + return par1CrashReport; + } + + /** + * If par2Str begins with /, then it searches for commands, otherwise it returns + * players. + */ + public List getPossibleCompletions(ICommandSender par1ICommandSender, String par2Str) { + ArrayList var3 = new ArrayList(); + + if (par2Str.startsWith("/")) { + par2Str = par2Str.substring(1); + boolean var10 = !par2Str.contains(" "); + List var11 = this.commandManager.getPossibleCommands(par1ICommandSender, par2Str); + + if (var11 != null) { + Iterator var12 = var11.iterator(); + + while (var12.hasNext()) { + String var13 = (String) var12.next(); + + if (var10) { + var3.add("/" + var13); + } else { + var3.add(var13); + } + } + } + + return var3; + } else { + String[] var4 = par2Str.split(" ", -1); + String var5 = var4[var4.length - 1]; + String[] var6 = this.serverConfigManager.getAllUsernames(); + int var7 = var6.length; + + for (int var8 = 0; var8 < var7; ++var8) { + String var9 = var6[var8]; + + if (CommandBase.doesStringStartWith(var5, var9)) { + var3.add(var9); + } + } + + return var3; + } + } + + /** + * Gets mcServer. + */ + public static MinecraftServer getServer() { + return mcServer; + } + + /** + * Gets the name of this command sender (usually username, but possibly "Rcon") + */ + public String getCommandSenderName() { + return "Server"; + } + + public void sendChatToPlayer(String par1Str) { + this.getLogAgent().func_98233_a(StringUtils.stripControlCodes(par1Str)); + } + + /** + * Returns true if the command sender is allowed to use the given command. + */ + public boolean canCommandSenderUseCommand(int par1, String par2Str) { + return true; + } + + /** + * Translates and formats the given string key with the given arguments. + */ + public String translateString(String par1Str, Object... par2ArrayOfObj) { + return StringTranslate.getInstance().translateKeyFormat(par1Str, par2ArrayOfObj); + } + + public ICommandManager getCommandManager() { + return this.commandManager; + } + + /** + * Gets KeyPair instanced in MinecraftServer. + */ + public KeyPair getKeyPair() { + return this.serverKeyPair; + } + + /** + * Gets serverPort. + */ + public int getServerPort() { + return this.serverPort; + } + + public void setServerPort(int par1) { + this.serverPort = par1; + } + + /** + * Returns the username of the server owner (for integrated servers) + */ + public String getServerOwner() { + return this.serverOwner; + } + + /** + * Sets the username of the owner of this server (in the case of an integrated + * server) + */ + public void setServerOwner(String par1Str) { + this.serverOwner = par1Str; + } + + public boolean isSinglePlayer() { + return this.serverOwner != null; + } + + public String getFolderName() { + return this.folderName; + } + + public void setFolderName(String par1Str) { + this.folderName = par1Str; + } + + public void setKeyPair(KeyPair par1KeyPair) { + this.serverKeyPair = par1KeyPair; + } + + public void setDifficultyForAllWorlds(int par1) { + for (int var2 = 0; var2 < this.worldServers.length; ++var2) { + WorldServer var3 = this.worldServers[var2]; + + if (var3 != null) { + if (var3.getWorldInfo().isHardcoreModeEnabled()) { + var3.difficultySetting = 3; + var3.setAllowedSpawnTypes(true, true); + } else if (this.isSinglePlayer()) { + var3.difficultySetting = par1; + var3.setAllowedSpawnTypes(var3.difficultySetting > 0, true); + } else { + var3.difficultySetting = par1; + var3.setAllowedSpawnTypes(this.allowSpawnMonsters(), this.canSpawnAnimals); + } + } + } + } + + protected boolean allowSpawnMonsters() { + return true; + } + + /** + * Gets whether this is a demo or not. + */ + public boolean isDemo() { + return this.isDemo; + } + + /** + * Sets whether this is a demo or not. + */ + public void setDemo(boolean par1) { + this.isDemo = par1; + } + + public void canCreateBonusChest(boolean par1) { + this.enableBonusChest = par1; + } + + public ISaveFormat getActiveAnvilConverter() { + return this.anvilConverterForAnvilFile; + } + + /** + * WARNING : directly calls + * getActiveAnvilConverter().deleteWorldDirectory(theWorldServer[0].getSaveHandler().getWorldDirectoryName()); + */ + public void deleteWorldAndStopServer() { + this.worldIsBeingDeleted = true; + this.getActiveAnvilConverter().flushCache(); + + for (int var1 = 0; var1 < this.worldServers.length; ++var1) { + WorldServer var2 = this.worldServers[var1]; + + if (var2 != null) { + var2.flush(); + } + } + + this.getActiveAnvilConverter() + .deleteWorldDirectory(this.worldServers[0].getSaveHandler().getWorldDirectoryName()); + this.initiateShutdown(); + } + + public String getTexturePack() { + return this.texturePack; + } + + public void setTexturePack(String par1Str) { + this.texturePack = par1Str; + } + + public void addServerStatsToSnooper(PlayerUsageSnooper par1PlayerUsageSnooper) { + par1PlayerUsageSnooper.addData("whitelist_enabled", Boolean.valueOf(false)); + par1PlayerUsageSnooper.addData("whitelist_count", Integer.valueOf(0)); + par1PlayerUsageSnooper.addData("players_current", Integer.valueOf(this.getCurrentPlayerCount())); + par1PlayerUsageSnooper.addData("players_max", Integer.valueOf(this.getMaxPlayers())); + par1PlayerUsageSnooper.addData("players_seen", + Integer.valueOf(this.serverConfigManager.getAvailablePlayerDat().length)); + par1PlayerUsageSnooper.addData("uses_auth", Boolean.valueOf(this.onlineMode)); + par1PlayerUsageSnooper.addData("gui_state", this.getGuiEnabled() ? "enabled" : "disabled"); + par1PlayerUsageSnooper.addData("avg_tick_ms", + Integer.valueOf((int) (MathHelper.average(this.tickTimeArray) * 1.0E-6D))); + par1PlayerUsageSnooper.addData("avg_sent_packet_count", + Integer.valueOf((int) MathHelper.average(this.sentPacketCountArray))); + par1PlayerUsageSnooper.addData("avg_sent_packet_size", + Integer.valueOf((int) MathHelper.average(this.sentPacketSizeArray))); + par1PlayerUsageSnooper.addData("avg_rec_packet_count", + Integer.valueOf((int) MathHelper.average(this.receivedPacketCountArray))); + par1PlayerUsageSnooper.addData("avg_rec_packet_size", + Integer.valueOf((int) MathHelper.average(this.receivedPacketSizeArray))); + int var2 = 0; + + for (int var3 = 0; var3 < this.worldServers.length; ++var3) { + if (this.worldServers[var3] != null) { + WorldServer var4 = this.worldServers[var3]; + WorldInfo var5 = var4.getWorldInfo(); + par1PlayerUsageSnooper.addData("world[" + var2 + "][dimension]", + Integer.valueOf(var4.provider.dimensionId)); + par1PlayerUsageSnooper.addData("world[" + var2 + "][mode]", var5.getGameType()); + par1PlayerUsageSnooper.addData("world[" + var2 + "][difficulty]", + Integer.valueOf(var4.difficultySetting)); + par1PlayerUsageSnooper.addData("world[" + var2 + "][hardcore]", + Boolean.valueOf(var5.isHardcoreModeEnabled())); + par1PlayerUsageSnooper.addData("world[" + var2 + "][generator_name]", + var5.getTerrainType().getWorldTypeName()); + par1PlayerUsageSnooper.addData("world[" + var2 + "][generator_version]", + Integer.valueOf(var5.getTerrainType().getGeneratorVersion())); + par1PlayerUsageSnooper.addData("world[" + var2 + "][height]", Integer.valueOf(this.buildLimit)); + par1PlayerUsageSnooper.addData("world[" + var2 + "][chunks_loaded]", + Integer.valueOf(var4.getChunkProvider().getLoadedChunkCount())); + ++var2; + } + } + + par1PlayerUsageSnooper.addData("worlds", Integer.valueOf(var2)); + } + + public void addServerTypeToSnooper(PlayerUsageSnooper par1PlayerUsageSnooper) { + par1PlayerUsageSnooper.addData("singleplayer", Boolean.valueOf(this.isSinglePlayer())); + par1PlayerUsageSnooper.addData("server_brand", this.getServerModName()); + par1PlayerUsageSnooper.addData("gui_supported", GraphicsEnvironment.isHeadless() ? "headless" : "supported"); + par1PlayerUsageSnooper.addData("dedicated", Boolean.valueOf(this.isDedicatedServer())); + } + + /** + * Returns whether snooping is enabled or not. + */ + public boolean isSnooperEnabled() { + return true; + } + + /** + * This is checked to be 16 upon receiving the packet, otherwise the packet is + * ignored. + */ + public int textureSize() { + return 16; + } + + public abstract boolean isDedicatedServer(); + + public boolean isServerInOnlineMode() { + return this.onlineMode; + } + + public void setOnlineMode(boolean par1) { + this.onlineMode = par1; + } + + public boolean getCanSpawnAnimals() { + return this.canSpawnAnimals; + } + + public void setCanSpawnAnimals(boolean par1) { + this.canSpawnAnimals = par1; + } + + public boolean getCanSpawnNPCs() { + return this.canSpawnNPCs; + } + + public void setCanSpawnNPCs(boolean par1) { + this.canSpawnNPCs = par1; + } + + public boolean isPVPEnabled() { + return this.pvpEnabled; + } + + public void setAllowPvp(boolean par1) { + this.pvpEnabled = par1; + } + + public boolean isFlightAllowed() { + return this.allowFlight; + } + + public void setAllowFlight(boolean par1) { + this.allowFlight = par1; + } + + /** + * Return whether command blocks are enabled. + */ + public abstract boolean isCommandBlockEnabled(); + + public String getMOTD() { + return this.motd; + } + + public void setMOTD(String par1Str) { + this.motd = par1Str; + } + + public int getBuildLimit() { + return this.buildLimit; + } + + public void setBuildLimit(int par1) { + this.buildLimit = par1; + } + + public boolean isServerStopped() { + return this.serverStopped; + } + + public ServerConfigurationManager getConfigurationManager() { + return this.serverConfigManager; + } + + public void setConfigurationManager(ServerConfigurationManager par1ServerConfigurationManager) { + this.serverConfigManager = par1ServerConfigurationManager; + } + + /** + * Sets the game type for all worlds. + */ + public void setGameType(EnumGameType par1EnumGameType) { + for (int var2 = 0; var2 < this.worldServers.length; ++var2) { + getServer().worldServers[var2].getWorldInfo().setGameType(par1EnumGameType); + } + } + + public abstract NetworkListenThread getNetworkThread(); + + public boolean getGuiEnabled() { + return false; + } + + /** + * On dedicated does nothing. On integrated, sets commandsAllowedForAll, + * gameType and allows external connections. + */ + public abstract String shareToLAN(EnumGameType var1, boolean var2); + + public int getTickCounter() { + return this.tickCounter; + } + + public void enableProfiling() { + this.startProfiling = true; + } + + /** + * Return the position for this command sender. + */ + public ChunkCoordinates getCommandSenderPosition() { + return new ChunkCoordinates(0, 0, 0); + } + + /** + * Return the spawn protection area's size. + */ + public int getSpawnProtectionSize() { + return 16; + } + + public boolean func_96290_a(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer) { + return false; + } + + public abstract ILogAgent getLogAgent(); + + public void func_104055_i(boolean par1) { + this.field_104057_T = par1; + } + + public boolean func_104056_am() { + return this.field_104057_T; + } + + /** + * Gets the current player count, maximum player count, and player entity list. + */ + public static ServerConfigurationManager getServerConfigurationManager(MinecraftServer par0MinecraftServer) { + return par0MinecraftServer.serverConfigManager; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/AABBLocalPool.java b/sp-server/src/main/java/net/minecraft/src/AABBLocalPool.java new file mode 100644 index 0000000..feed058 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/AABBLocalPool.java @@ -0,0 +1,11 @@ +package net.minecraft.src; + +final class AABBLocalPool extends ThreadLocal { + protected AABBPool createNewDefaultPool() { + return new AABBPool(300, 2000); + } + + protected Object initialValue() { + return this.createNewDefaultPool(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/AABBPool.java b/sp-server/src/main/java/net/minecraft/src/AABBPool.java new file mode 100644 index 0000000..0279dc1 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/AABBPool.java @@ -0,0 +1,86 @@ +package net.minecraft.src; + +import java.util.ArrayList; +import java.util.List; + +public class AABBPool { + /** + * Maximum number of times the pool can be "cleaned" before the list is shrunk + */ + private final int maxNumCleans; + + /** + * Number of Pool entries to remove when cleanPool is called maxNumCleans times. + */ + private final int numEntriesToRemove; + + /** List of AABB stored in this Pool */ + private final List listAABB = new ArrayList(); + + /** Next index to use when adding a Pool Entry. */ + private int nextPoolIndex = 0; + + /** + * Largest index reached by this Pool (can be reset to 0 upon calling cleanPool) + */ + private int maxPoolIndex = 0; + + /** Number of times this Pool has been cleaned */ + private int numCleans = 0; + + public AABBPool(int par1, int par2) { + this.maxNumCleans = par1; + this.numEntriesToRemove = par2; + } + + /** + * Creates a new AABB, or reuses one that's no longer in use. Parameters: minX, + * minY, minZ, maxX, maxY, maxZ. AABBs returned from this function should only + * be used for one frame or tick, as after that they will be reused. + */ + public AxisAlignedBB getAABB(double par1, double par3, double par5, double par7, double par9, double par11) { + AxisAlignedBB var13; + + if (this.nextPoolIndex >= this.listAABB.size()) { + var13 = new AxisAlignedBB(par1, par3, par5, par7, par9, par11); + this.listAABB.add(var13); + } else { + var13 = (AxisAlignedBB) this.listAABB.get(this.nextPoolIndex); + var13.setBounds(par1, par3, par5, par7, par9, par11); + } + + ++this.nextPoolIndex; + return var13; + } + + /** + * Marks the pool as "empty", starting over when adding new entries. If this is + * called maxNumCleans times, the list size is reduced + */ + public void cleanPool() { + if (this.nextPoolIndex > this.maxPoolIndex) { + this.maxPoolIndex = this.nextPoolIndex; + } + + if (this.numCleans++ == this.maxNumCleans) { + int var1 = Math.max(this.maxPoolIndex, this.listAABB.size() - this.numEntriesToRemove); + + while (this.listAABB.size() > var1) { + this.listAABB.remove(var1); + } + + this.maxPoolIndex = 0; + this.numCleans = 0; + } + + this.nextPoolIndex = 0; + } + + public int getlistAABBsize() { + return this.listAABB.size(); + } + + public int getnextPoolIndex() { + return this.nextPoolIndex; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/Achievement.java b/sp-server/src/main/java/net/minecraft/src/Achievement.java new file mode 100644 index 0000000..1ac36e0 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/Achievement.java @@ -0,0 +1,116 @@ +package net.minecraft.src; + +public class Achievement extends StatBase { + /** + * Is the column (related to center of achievement gui, in 24 pixels unit) that + * the achievement will be displayed. + */ + public final int displayColumn; + + /** + * Is the row (related to center of achievement gui, in 24 pixels unit) that the + * achievement will be displayed. + */ + public final int displayRow; + + /** + * Holds the parent achievement, that must be taken before this achievement is + * avaiable. + */ + public final Achievement parentAchievement; + + /** + * Holds the description of the achievement, ready to be formatted and/or + * displayed. + */ + private final String achievementDescription; + + /** + * Holds the ItemStack that will be used to draw the achievement into the GUI. + */ + public final ItemStack theItemStack; + + /** + * Special achievements have a 'spiked' (on normal texture pack) frame, special + * achievements are the hardest ones to achieve. + */ + private boolean isSpecial; + + public Achievement(int par1, String par2Str, int par3, int par4, Item par5Item, Achievement par6Achievement) { + this(par1, par2Str, par3, par4, new ItemStack(par5Item), par6Achievement); + } + + public Achievement(int par1, String par2Str, int par3, int par4, Block par5Block, Achievement par6Achievement) { + this(par1, par2Str, par3, par4, new ItemStack(par5Block), par6Achievement); + } + + public Achievement(int par1, String par2Str, int par3, int par4, ItemStack par5ItemStack, + Achievement par6Achievement) { + super(5242880 + par1, "achievement." + par2Str); + this.theItemStack = par5ItemStack; + this.achievementDescription = "achievement." + par2Str + ".desc"; + this.displayColumn = par3; + this.displayRow = par4; + + if (par3 < AchievementList.minDisplayColumn) { + AchievementList.minDisplayColumn = par3; + } + + if (par4 < AchievementList.minDisplayRow) { + AchievementList.minDisplayRow = par4; + } + + if (par3 > AchievementList.maxDisplayColumn) { + AchievementList.maxDisplayColumn = par3; + } + + if (par4 > AchievementList.maxDisplayRow) { + AchievementList.maxDisplayRow = par4; + } + + this.parentAchievement = par6Achievement; + } + + /** + * Indicates whether or not the given achievement or statistic is independent + * (i.e., lacks prerequisites for being update). + */ + public Achievement setIndependent() { + this.isIndependent = true; + return this; + } + + /** + * Special achievements have a 'spiked' (on normal texture pack) frame, special + * achievements are the hardest ones to achieve. + */ + public Achievement setSpecial() { + this.isSpecial = true; + return this; + } + + /** + * Adds the achievement on the internal list of registered achievements, also, + * it's check for duplicated id's. + */ + public Achievement registerAchievement() { + super.registerStat(); + AchievementList.achievementList.add(this); + return this; + } + + /** + * Register the stat into StatList. + */ + public StatBase registerStat() { + return this.registerAchievement(); + } + + /** + * Initializes the current stat as independent (i.e., lacking prerequisites for + * being updated) and returns the current instance. + */ + public StatBase initIndependentStat() { + return this.setIndependent(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/AchievementList.java b/sp-server/src/main/java/net/minecraft/src/AchievementList.java new file mode 100644 index 0000000..f6c8a60 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/AchievementList.java @@ -0,0 +1,137 @@ +package net.minecraft.src; + +import java.util.ArrayList; +import java.util.List; + +public class AchievementList { + /** Is the smallest column used to display a achievement on the GUI. */ + public static int minDisplayColumn; + + /** Is the smallest row used to display a achievement on the GUI. */ + public static int minDisplayRow; + + /** Is the biggest column used to display a achievement on the GUI. */ + public static int maxDisplayColumn; + + /** Is the biggest row used to display a achievement on the GUI. */ + public static int maxDisplayRow; + + /** The list holding all achievements */ + public static List achievementList = new ArrayList(); + + /** Is the 'open inventory' achievement. */ + public static Achievement openInventory = (new Achievement(0, "openInventory", 0, 0, Item.book, (Achievement) null)) + .setIndependent().registerAchievement(); + + /** Is the 'getting wood' achievement. */ + public static Achievement mineWood = (new Achievement(1, "mineWood", 2, 1, Block.wood, openInventory)) + .registerAchievement(); + + /** Is the 'benchmarking' achievement. */ + public static Achievement buildWorkBench = (new Achievement(2, "buildWorkBench", 4, -1, Block.workbench, mineWood)) + .registerAchievement(); + + /** Is the 'time to mine' achievement. */ + public static Achievement buildPickaxe = (new Achievement(3, "buildPickaxe", 4, 2, Item.pickaxeWood, + buildWorkBench)).registerAchievement(); + + /** Is the 'hot topic' achievement. */ + public static Achievement buildFurnace = (new Achievement(4, "buildFurnace", 3, 4, Block.furnaceIdle, buildPickaxe)) + .registerAchievement(); + + /** Is the 'acquire hardware' achievement. */ + public static Achievement acquireIron = (new Achievement(5, "acquireIron", 1, 4, Item.ingotIron, buildFurnace)) + .registerAchievement(); + + /** Is the 'time to farm' achievement. */ + public static Achievement buildHoe = (new Achievement(6, "buildHoe", 2, -3, Item.hoeWood, buildWorkBench)) + .registerAchievement(); + + /** Is the 'bake bread' achievement. */ + public static Achievement makeBread = (new Achievement(7, "makeBread", -1, -3, Item.bread, buildHoe)) + .registerAchievement(); + + /** Is the 'the lie' achievement. */ + public static Achievement bakeCake = (new Achievement(8, "bakeCake", 0, -5, Item.cake, buildHoe)) + .registerAchievement(); + + /** Is the 'getting a upgrade' achievement. */ + public static Achievement buildBetterPickaxe = (new Achievement(9, "buildBetterPickaxe", 6, 2, Item.pickaxeStone, + buildPickaxe)).registerAchievement(); + + /** Is the 'delicious fish' achievement. */ + public static Achievement cookFish = (new Achievement(10, "cookFish", 2, 6, Item.fishCooked, buildFurnace)) + .registerAchievement(); + + /** Is the 'on a rail' achievement */ + public static Achievement onARail = (new Achievement(11, "onARail", 2, 3, Block.rail, acquireIron)).setSpecial() + .registerAchievement(); + + /** Is the 'time to strike' achievement. */ + public static Achievement buildSword = (new Achievement(12, "buildSword", 6, -1, Item.swordWood, buildWorkBench)) + .registerAchievement(); + + /** Is the 'monster hunter' achievement. */ + public static Achievement killEnemy = (new Achievement(13, "killEnemy", 8, -1, Item.bone, buildSword)) + .registerAchievement(); + + /** is the 'cow tipper' achievement. */ + public static Achievement killCow = (new Achievement(14, "killCow", 7, -3, Item.leather, buildSword)) + .registerAchievement(); + + /** Is the 'when pig fly' achievement. */ + public static Achievement flyPig = (new Achievement(15, "flyPig", 8, -4, Item.saddle, killCow)).setSpecial() + .registerAchievement(); + + /** The achievement for killing a Skeleton from 50 meters aways. */ + public static Achievement snipeSkeleton = (new Achievement(16, "snipeSkeleton", 7, 0, Item.bow, killEnemy)) + .setSpecial().registerAchievement(); + + /** Is the 'DIAMONDS!' achievement */ + public static Achievement diamonds = (new Achievement(17, "diamonds", -1, 5, Item.diamond, acquireIron)) + .registerAchievement(); + + /** Is the 'We Need to Go Deeper' achievement */ + public static Achievement portal = (new Achievement(18, "portal", -1, 7, Block.obsidian, diamonds)) + .registerAchievement(); + + /** Is the 'Return to Sender' achievement */ + public static Achievement ghast = (new Achievement(19, "ghast", -4, 8, Item.ghastTear, portal)).setSpecial() + .registerAchievement(); + + /** Is the 'Into Fire' achievement */ + public static Achievement blazeRod = (new Achievement(20, "blazeRod", 0, 9, Item.blazeRod, portal)) + .registerAchievement(); + + /** Is the 'Local Brewery' achievement */ + public static Achievement potion = (new Achievement(21, "potion", 2, 8, Item.potion, blazeRod)) + .registerAchievement(); + + /** Is the 'The End?' achievement */ + public static Achievement theEnd = (new Achievement(22, "theEnd", 3, 10, Item.eyeOfEnder, blazeRod)).setSpecial() + .registerAchievement(); + + /** Is the 'The End.' achievement */ + public static Achievement theEnd2 = (new Achievement(23, "theEnd2", 4, 13, Block.dragonEgg, theEnd)).setSpecial() + .registerAchievement(); + + /** Is the 'Enchanter' achievement */ + public static Achievement enchantments = (new Achievement(24, "enchantments", -4, 4, Block.enchantmentTable, + diamonds)).registerAchievement(); + public static Achievement overkill = (new Achievement(25, "overkill", -4, 1, Item.swordDiamond, enchantments)) + .setSpecial().registerAchievement(); + + /** Is the 'Librarian' achievement */ + public static Achievement bookcase = (new Achievement(26, "bookcase", -3, 6, Block.bookShelf, enchantments)) + .registerAchievement(); + + /** + * A stub functions called to make the static initializer for this class run. + */ + public static void init() { + } + + static { + System.out.println(achievementList.size() + " achievements"); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/AchievementMap.java b/sp-server/src/main/java/net/minecraft/src/AchievementMap.java new file mode 100644 index 0000000..7a7cfa3 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/AchievementMap.java @@ -0,0 +1,39 @@ +package net.minecraft.src; + +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.util.HashMap; +import java.util.Map; + +public class AchievementMap { + /** Holds the singleton instance of AchievementMap. */ + public static AchievementMap instance = new AchievementMap(); + + /** Maps a achievement id with it's unique GUID. */ + private Map guidMap = new HashMap(); + + private AchievementMap() { + try { + BufferedReader var1 = new BufferedReader( + new InputStreamReader(AchievementMap.class.getResourceAsStream("/achievement/map.txt"))); + String var2; + + while ((var2 = var1.readLine()) != null) { + String[] var3 = var2.split(","); + int var4 = Integer.parseInt(var3[0]); + this.guidMap.put(Integer.valueOf(var4), var3[1]); + } + + var1.close(); + } catch (Exception var5) { + var5.printStackTrace(); + } + } + + /** + * Returns the unique GUID of a achievement id. + */ + public static String getGuid(int par0) { + return (String) instance.guidMap.get(Integer.valueOf(par0)); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/AnvilChunkLoader.java b/sp-server/src/main/java/net/minecraft/src/AnvilChunkLoader.java new file mode 100644 index 0000000..302a73d --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/AnvilChunkLoader.java @@ -0,0 +1,371 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +public class AnvilChunkLoader implements IChunkLoader, IThreadedFileIO { + private List chunksToRemove = new ArrayList(); + private Set pendingAnvilChunksCoordinates = new HashSet(); + private Object syncLockObject = new Object(); + + /** Save directory for chunks using the Anvil format */ + private final File chunkSaveLocation; + + public AnvilChunkLoader(File par1File) { + this.chunkSaveLocation = par1File; + } + + /** + * Loads the specified(XZ) chunk into the specified world. + */ + public Chunk loadChunk(World par1World, int par2, int par3) throws IOException { + NBTTagCompound var4 = null; + ChunkCoordIntPair var5 = new ChunkCoordIntPair(par2, par3); + Object var6 = this.syncLockObject; + + synchronized (this.syncLockObject) { + if (this.pendingAnvilChunksCoordinates.contains(var5)) { + for (int var7 = 0; var7 < this.chunksToRemove.size(); ++var7) { + if (((AnvilChunkLoaderPending) this.chunksToRemove.get(var7)).chunkCoordinate.equals(var5)) { + var4 = ((AnvilChunkLoaderPending) this.chunksToRemove.get(var7)).nbtTags; + break; + } + } + } + } + + if (var4 == null) { + DataInputStream var10 = RegionFileCache.getChunkInputStream(this.chunkSaveLocation, par2, par3); + + if (var10 == null) { + return null; + } + + var4 = CompressedStreamTools.read(var10); + } + + return this.checkedReadChunkFromNBT(par1World, par2, par3, var4); + } + + /** + * Wraps readChunkFromNBT. Checks the coordinates and several NBT tags. + */ + protected Chunk checkedReadChunkFromNBT(World par1World, int par2, int par3, NBTTagCompound par4NBTTagCompound) { + if (!par4NBTTagCompound.hasKey("Level")) { + par1World.getWorldLogAgent() + .logSevere("Chunk file at " + par2 + "," + par3 + " is missing level data, skipping"); + return null; + } else if (!par4NBTTagCompound.getCompoundTag("Level").hasKey("Sections")) { + par1World.getWorldLogAgent() + .logSevere("Chunk file at " + par2 + "," + par3 + " is missing block data, skipping"); + return null; + } else { + Chunk var5 = this.readChunkFromNBT(par1World, par4NBTTagCompound.getCompoundTag("Level")); + + if (!var5.isAtLocation(par2, par3)) { + par1World.getWorldLogAgent() + .logSevere("Chunk file at " + par2 + "," + par3 + + " is in the wrong location; relocating. (Expected " + par2 + ", " + par3 + ", got " + + var5.xPosition + ", " + var5.zPosition + ")"); + par4NBTTagCompound.setInteger("xPos", par2); + par4NBTTagCompound.setInteger("zPos", par3); + var5 = this.readChunkFromNBT(par1World, par4NBTTagCompound.getCompoundTag("Level")); + } + + return var5; + } + } + + public void saveChunk(World par1World, Chunk par2Chunk) throws MinecraftException, IOException { + par1World.checkSessionLock(); + + try { + NBTTagCompound var3 = new NBTTagCompound(); + NBTTagCompound var4 = new NBTTagCompound(); + var3.setTag("Level", var4); + this.writeChunkToNBT(par2Chunk, par1World, var4); + this.addChunkToPending(par2Chunk.getChunkCoordIntPair(), var3); + } catch (Exception var5) { + var5.printStackTrace(); + } + } + + protected void addChunkToPending(ChunkCoordIntPair par1ChunkCoordIntPair, NBTTagCompound par2NBTTagCompound) { + Object var3 = this.syncLockObject; + + synchronized (this.syncLockObject) { + if (this.pendingAnvilChunksCoordinates.contains(par1ChunkCoordIntPair)) { + for (int var4 = 0; var4 < this.chunksToRemove.size(); ++var4) { + if (((AnvilChunkLoaderPending) this.chunksToRemove.get(var4)).chunkCoordinate + .equals(par1ChunkCoordIntPair)) { + this.chunksToRemove.set(var4, + new AnvilChunkLoaderPending(par1ChunkCoordIntPair, par2NBTTagCompound)); + return; + } + } + } + + this.chunksToRemove.add(new AnvilChunkLoaderPending(par1ChunkCoordIntPair, par2NBTTagCompound)); + this.pendingAnvilChunksCoordinates.add(par1ChunkCoordIntPair); + ThreadedFileIOBase.threadedIOInstance.queueIO(this); + } + } + + /** + * Returns a boolean stating if the write was unsuccessful. + */ + public boolean writeNextIO() { + AnvilChunkLoaderPending var1 = null; + Object var2 = this.syncLockObject; + + synchronized (this.syncLockObject) { + if (this.chunksToRemove.isEmpty()) { + return false; + } + + var1 = (AnvilChunkLoaderPending) this.chunksToRemove.remove(0); + this.pendingAnvilChunksCoordinates.remove(var1.chunkCoordinate); + } + + if (var1 != null) { + try { + this.writeChunkNBTTags(var1); + } catch (Exception var4) { + var4.printStackTrace(); + } + } + + return true; + } + + private void writeChunkNBTTags(AnvilChunkLoaderPending par1AnvilChunkLoaderPending) throws IOException { + DataOutputStream var2 = RegionFileCache.getChunkOutputStream(this.chunkSaveLocation, + par1AnvilChunkLoaderPending.chunkCoordinate.chunkXPos, + par1AnvilChunkLoaderPending.chunkCoordinate.chunkZPos); + CompressedStreamTools.write(par1AnvilChunkLoaderPending.nbtTags, var2); + var2.close(); + } + + /** + * Save extra data associated with this Chunk not normally saved during + * autosave, only during chunk unload. Currently unused. + */ + public void saveExtraChunkData(World par1World, Chunk par2Chunk) { + } + + /** + * Called every World.tick() + */ + public void chunkTick() { + } + + /** + * Save extra data not associated with any Chunk. Not saved during autosave, + * only during world unload. Currently unused. + */ + public void saveExtraData() { + while (this.writeNextIO()) { + ; + } + } + + /** + * Writes the Chunk passed as an argument to the NBTTagCompound also passed, + * using the World argument to retrieve the Chunk's last update time. + */ + private void writeChunkToNBT(Chunk par1Chunk, World par2World, NBTTagCompound par3NBTTagCompound) { + par3NBTTagCompound.setInteger("xPos", par1Chunk.xPosition); + par3NBTTagCompound.setInteger("zPos", par1Chunk.zPosition); + par3NBTTagCompound.setLong("LastUpdate", par2World.getTotalWorldTime()); + par3NBTTagCompound.setIntArray("HeightMap", par1Chunk.heightMap); + par3NBTTagCompound.setBoolean("TerrainPopulated", par1Chunk.isTerrainPopulated); + ExtendedBlockStorage[] var4 = par1Chunk.getBlockStorageArray(); + NBTTagList var5 = new NBTTagList("Sections"); + boolean var6 = !par2World.provider.hasNoSky; + ExtendedBlockStorage[] var7 = var4; + int var8 = var4.length; + NBTTagCompound var11; + + for (int var9 = 0; var9 < var8; ++var9) { + ExtendedBlockStorage var10 = var7[var9]; + + if (var10 != null) { + var11 = new NBTTagCompound(); + var11.setByte("Y", (byte) (var10.getYLocation() >> 4 & 255)); + var11.setByteArray("Blocks", var10.getBlockLSBArray()); + + if (var10.getBlockMSBArray() != null) { + var11.setByteArray("Add", var10.getBlockMSBArray().data); + } + + var11.setByteArray("Data", var10.getMetadataArray().data); + var11.setByteArray("BlockLight", var10.getBlocklightArray().data); + + if (var6) { + var11.setByteArray("SkyLight", var10.getSkylightArray().data); + } else { + var11.setByteArray("SkyLight", new byte[var10.getBlocklightArray().data.length]); + } + + var5.appendTag(var11); + } + } + + par3NBTTagCompound.setTag("Sections", var5); + par3NBTTagCompound.setByteArray("Biomes", par1Chunk.getBiomeArray()); + par1Chunk.hasEntities = false; + NBTTagList var16 = new NBTTagList(); + Iterator var18; + + for (var8 = 0; var8 < par1Chunk.entityLists.length; ++var8) { + var18 = par1Chunk.entityLists[var8].iterator(); + + while (var18.hasNext()) { + Entity var20 = (Entity) var18.next(); + var11 = new NBTTagCompound(); + + if (var20.addEntityID(var11)) { + par1Chunk.hasEntities = true; + var16.appendTag(var11); + } + } + } + + par3NBTTagCompound.setTag("Entities", var16); + NBTTagList var17 = new NBTTagList(); + var18 = par1Chunk.chunkTileEntityMap.values().iterator(); + + while (var18.hasNext()) { + TileEntity var21 = (TileEntity) var18.next(); + var11 = new NBTTagCompound(); + var21.writeToNBT(var11); + var17.appendTag(var11); + } + + par3NBTTagCompound.setTag("TileEntities", var17); + List var19 = par2World.getPendingBlockUpdates(par1Chunk, false); + + if (var19 != null) { + long var22 = par2World.getTotalWorldTime(); + NBTTagList var12 = new NBTTagList(); + Iterator var13 = var19.iterator(); + + while (var13.hasNext()) { + NextTickListEntry var14 = (NextTickListEntry) var13.next(); + NBTTagCompound var15 = new NBTTagCompound(); + var15.setInteger("i", var14.blockID); + var15.setInteger("x", var14.xCoord); + var15.setInteger("y", var14.yCoord); + var15.setInteger("z", var14.zCoord); + var15.setInteger("t", (int) (var14.scheduledTime - var22)); + var15.setInteger("p", var14.field_82754_f); + var12.appendTag(var15); + } + + par3NBTTagCompound.setTag("TileTicks", var12); + } + } + + /** + * Reads the data stored in the passed NBTTagCompound and creates a Chunk with + * that data in the passed World. Returns the created Chunk. + */ + private Chunk readChunkFromNBT(World par1World, NBTTagCompound par2NBTTagCompound) { + int var3 = par2NBTTagCompound.getInteger("xPos"); + int var4 = par2NBTTagCompound.getInteger("zPos"); + Chunk var5 = new Chunk(par1World, var3, var4); + var5.heightMap = par2NBTTagCompound.getIntArray("HeightMap"); + var5.isTerrainPopulated = par2NBTTagCompound.getBoolean("TerrainPopulated"); + NBTTagList var6 = par2NBTTagCompound.getTagList("Sections"); + byte var7 = 16; + ExtendedBlockStorage[] var8 = new ExtendedBlockStorage[var7]; + boolean var9 = !par1World.provider.hasNoSky; + + for (int var10 = 0; var10 < var6.tagCount(); ++var10) { + NBTTagCompound var11 = (NBTTagCompound) var6.tagAt(var10); + byte var12 = var11.getByte("Y"); + ExtendedBlockStorage var13 = new ExtendedBlockStorage(var12 << 4, var9); + var13.setBlockLSBArray(var11.getByteArray("Blocks")); + + if (var11.hasKey("Add")) { + var13.setBlockMSBArray(new NibbleArray(var11.getByteArray("Add"), 4)); + } + + var13.setBlockMetadataArray(new NibbleArray(var11.getByteArray("Data"), 4)); + var13.setBlocklightArray(new NibbleArray(var11.getByteArray("BlockLight"), 4)); + + if (var9) { + var13.setSkylightArray(new NibbleArray(var11.getByteArray("SkyLight"), 4)); + } + + var13.removeInvalidBlocks(); + var8[var12] = var13; + } + + var5.setStorageArrays(var8); + + if (par2NBTTagCompound.hasKey("Biomes")) { + var5.setBiomeArray(par2NBTTagCompound.getByteArray("Biomes")); + } + + NBTTagList var17 = par2NBTTagCompound.getTagList("Entities"); + + if (var17 != null) { + for (int var18 = 0; var18 < var17.tagCount(); ++var18) { + NBTTagCompound var20 = (NBTTagCompound) var17.tagAt(var18); + Entity var22 = EntityList.createEntityFromNBT(var20, par1World); + var5.hasEntities = true; + + if (var22 != null) { + var5.addEntity(var22); + Entity var14 = var22; + + for (NBTTagCompound var15 = var20; var15.hasKey("Riding"); var15 = var15.getCompoundTag("Riding")) { + Entity var16 = EntityList.createEntityFromNBT(var15.getCompoundTag("Riding"), par1World); + + if (var16 != null) { + var5.addEntity(var16); + var14.mountEntity(var16); + } + + var14 = var16; + } + } + } + } + + NBTTagList var19 = par2NBTTagCompound.getTagList("TileEntities"); + + if (var19 != null) { + for (int var21 = 0; var21 < var19.tagCount(); ++var21) { + NBTTagCompound var24 = (NBTTagCompound) var19.tagAt(var21); + TileEntity var26 = TileEntity.createAndLoadEntity(var24); + + if (var26 != null) { + var5.addTileEntity(var26); + } + } + } + + if (par2NBTTagCompound.hasKey("TileTicks")) { + NBTTagList var23 = par2NBTTagCompound.getTagList("TileTicks"); + + if (var23 != null) { + for (int var25 = 0; var25 < var23.tagCount(); ++var25) { + NBTTagCompound var27 = (NBTTagCompound) var23.tagAt(var25); + par1World.scheduleBlockUpdateFromLoad(var27.getInteger("x"), var27.getInteger("y"), + var27.getInteger("z"), var27.getInteger("i"), var27.getInteger("t"), var27.getInteger("p")); + } + } + } + + return var5; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/AnvilChunkLoaderPending.java b/sp-server/src/main/java/net/minecraft/src/AnvilChunkLoaderPending.java new file mode 100644 index 0000000..df5d13d --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/AnvilChunkLoaderPending.java @@ -0,0 +1,11 @@ +package net.minecraft.src; + +class AnvilChunkLoaderPending { + public final ChunkCoordIntPair chunkCoordinate; + public final NBTTagCompound nbtTags; + + public AnvilChunkLoaderPending(ChunkCoordIntPair par1ChunkCoordIntPair, NBTTagCompound par2NBTTagCompound) { + this.chunkCoordinate = par1ChunkCoordIntPair; + this.nbtTags = par2NBTTagCompound; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/AnvilConverterData.java b/sp-server/src/main/java/net/minecraft/src/AnvilConverterData.java new file mode 100644 index 0000000..3b4f89e --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/AnvilConverterData.java @@ -0,0 +1,21 @@ +package net.minecraft.src; + +public class AnvilConverterData { + public long lastUpdated; + public boolean terrainPopulated; + public byte[] heightmap; + public NibbleArrayReader blockLight; + public NibbleArrayReader skyLight; + public NibbleArrayReader data; + public byte[] blocks; + public NBTTagList entities; + public NBTTagList tileEntities; + public NBTTagList tileTicks; + public final int x; + public final int z; + + public AnvilConverterData(int par1, int par2) { + this.x = par1; + this.z = par2; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/AnvilSaveConverter.java b/sp-server/src/main/java/net/minecraft/src/AnvilSaveConverter.java new file mode 100644 index 0000000..b1bcb2a --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/AnvilSaveConverter.java @@ -0,0 +1,191 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Iterator; +import net.minecraft.server.MinecraftServer; + +public class AnvilSaveConverter extends SaveFormatOld { + public AnvilSaveConverter(File par1File) { + super(par1File); + } + + protected int getSaveVersion() { + return 19133; + } + + public void flushCache() { + RegionFileCache.clearRegionFileReferences(); + } + + /** + * Returns back a loader for the specified save directory + */ + public ISaveHandler getSaveLoader(String par1Str, boolean par2) { + return new AnvilSaveHandler(this.savesDirectory, par1Str, par2); + } + + /** + * gets if the map is old chunk saving (true) or McRegion (false) + */ + public boolean isOldMapFormat(String par1Str) { + WorldInfo var2 = this.getWorldInfo(par1Str); + return var2 != null && var2.getSaveVersion() != this.getSaveVersion(); + } + + /** + * converts the map to mcRegion + */ + public boolean convertMapFormat(String par1Str, IProgressUpdate par2IProgressUpdate) { + par2IProgressUpdate.setLoadingProgress(0); + ArrayList var3 = new ArrayList(); + ArrayList var4 = new ArrayList(); + ArrayList var5 = new ArrayList(); + File var6 = new File(this.savesDirectory, par1Str); + File var7 = new File(var6, "DIM-1"); + File var8 = new File(var6, "DIM1"); + MinecraftServer.getServer().getLogAgent().func_98233_a("Scanning folders..."); + this.addRegionFilesToCollection(var6, var3); + + if (var7.exists()) { + this.addRegionFilesToCollection(var7, var4); + } + + if (var8.exists()) { + this.addRegionFilesToCollection(var8, var5); + } + + int var9 = var3.size() + var4.size() + var5.size(); + MinecraftServer.getServer().getLogAgent().func_98233_a("Total conversion count is " + var9); + WorldInfo var10 = this.getWorldInfo(par1Str); + Object var11 = null; + + if (var10.getTerrainType() == WorldType.FLAT) { + var11 = new WorldChunkManagerHell(BiomeGenBase.plains, 0.5F, 0.5F); + } else { + var11 = new WorldChunkManager(var10.getSeed(), var10.getTerrainType()); + } + + this.convertFile(new File(var6, "region"), var3, (WorldChunkManager) var11, 0, var9, par2IProgressUpdate); + this.convertFile(new File(var7, "region"), var4, new WorldChunkManagerHell(BiomeGenBase.hell, 1.0F, 0.0F), + var3.size(), var9, par2IProgressUpdate); + this.convertFile(new File(var8, "region"), var5, new WorldChunkManagerHell(BiomeGenBase.sky, 0.5F, 0.0F), + var3.size() + var4.size(), var9, par2IProgressUpdate); + var10.setSaveVersion(19133); + + if (var10.getTerrainType() == WorldType.DEFAULT_1_1) { + var10.setTerrainType(WorldType.DEFAULT); + } + + this.createFile(par1Str); + ISaveHandler var12 = this.getSaveLoader(par1Str, false); + var12.saveWorldInfo(var10); + return true; + } + + /** + * par: filename for the level.dat_mcr backup + */ + private void createFile(String par1Str) { + File var2 = new File(this.savesDirectory, par1Str); + + if (!var2.exists()) { + System.out.println("Warning: Unable to create level.dat_mcr backup"); + } else { + File var3 = new File(var2, "level.dat"); + + if (!var3.exists()) { + System.out.println("Warning: Unable to create level.dat_mcr backup"); + } else { + File var4 = new File(var2, "level.dat_mcr"); + + if (!var3.renameTo(var4)) { + System.out.println("Warning: Unable to create level.dat_mcr backup"); + } + } + } + } + + private void convertFile(File par1File, Iterable par2Iterable, WorldChunkManager par3WorldChunkManager, int par4, + int par5, IProgressUpdate par6IProgressUpdate) { + Iterator var7 = par2Iterable.iterator(); + + while (var7.hasNext()) { + File var8 = (File) var7.next(); + this.convertChunks(par1File, var8, par3WorldChunkManager, par4, par5, par6IProgressUpdate); + ++par4; + int var9 = (int) Math.round(100.0D * (double) par4 / (double) par5); + par6IProgressUpdate.setLoadingProgress(var9); + } + } + + /** + * copies a 32x32 chunk set from par2File to par1File, via AnvilConverterData + */ + private void convertChunks(File par1File, File par2File, WorldChunkManager par3WorldChunkManager, int par4, + int par5, IProgressUpdate par6IProgressUpdate) { + try { + String var7 = par2File.getName(); + RegionFile var8 = new RegionFile(par2File); + RegionFile var9 = new RegionFile( + new File(par1File, var7.substring(0, var7.length() - ".mcr".length()) + ".mca")); + + for (int var10 = 0; var10 < 32; ++var10) { + int var11; + + for (var11 = 0; var11 < 32; ++var11) { + if (var8.isChunkSaved(var10, var11) && !var9.isChunkSaved(var10, var11)) { + DataInputStream var12 = var8.getChunkDataInputStream(var10, var11); + + if (var12 == null) { + MinecraftServer.getServer().getLogAgent().func_98236_b("Failed to fetch input stream"); + } else { + NBTTagCompound var13 = CompressedStreamTools.read(var12); + var12.close(); + NBTTagCompound var14 = var13.getCompoundTag("Level"); + AnvilConverterData var15 = ChunkLoader.load(var14); + NBTTagCompound var16 = new NBTTagCompound(); + NBTTagCompound var17 = new NBTTagCompound(); + var16.setTag("Level", var17); + ChunkLoader.convertToAnvilFormat(var15, var17, par3WorldChunkManager); + DataOutputStream var18 = var9.getChunkDataOutputStream(var10, var11); + CompressedStreamTools.write(var16, var18); + var18.close(); + } + } + } + + var11 = (int) Math.round(100.0D * (double) (par4 * 1024) / (double) (par5 * 1024)); + int var20 = (int) Math + .round(100.0D * (double) ((var10 + 1) * 32 + par4 * 1024) / (double) (par5 * 1024)); + + if (var20 > var11) { + par6IProgressUpdate.setLoadingProgress(var20); + } + } + + var8.close(); + var9.close(); + } catch (IOException var19) { + var19.printStackTrace(); + } + } + + /** + * filters the files in the par1 directory, and adds them to the par2 + * collections + */ + private void addRegionFilesToCollection(File par1File, Collection par2Collection) { + File var3 = new File(par1File, "region"); + File[] var4 = var3.listFiles(new AnvilSaveConverterFileFilter(this)); + + if (var4 != null) { + Collections.addAll(par2Collection, var4); + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/AnvilSaveConverterFileFilter.java b/sp-server/src/main/java/net/minecraft/src/AnvilSaveConverterFileFilter.java new file mode 100644 index 0000000..9d6a70d --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/AnvilSaveConverterFileFilter.java @@ -0,0 +1,16 @@ +package net.minecraft.src; + +import java.io.File; +import java.io.FilenameFilter; + +class AnvilSaveConverterFileFilter implements FilenameFilter { + final AnvilSaveConverter parent; + + AnvilSaveConverterFileFilter(AnvilSaveConverter par1AnvilSaveConverter) { + this.parent = par1AnvilSaveConverter; + } + + public boolean accept(File par1File, String par2Str) { + return par2Str.endsWith(".mcr"); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/AnvilSaveHandler.java b/sp-server/src/main/java/net/minecraft/src/AnvilSaveHandler.java new file mode 100644 index 0000000..00334a8 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/AnvilSaveHandler.java @@ -0,0 +1,50 @@ +package net.minecraft.src; + +import java.io.File; + +public class AnvilSaveHandler extends SaveHandler { + public AnvilSaveHandler(File par1File, String par2Str, boolean par3) { + super(par1File, par2Str, par3); + } + + /** + * initializes and returns the chunk loader for the specified world provider + */ + public IChunkLoader getChunkLoader(WorldProvider par1WorldProvider) { + File var2 = this.getWorldDirectory(); + File var3; + + if (par1WorldProvider instanceof WorldProviderHell) { + var3 = new File(var2, "DIM-1"); + var3.mkdirs(); + return new AnvilChunkLoader(var3); + } else if (par1WorldProvider instanceof WorldProviderEnd) { + var3 = new File(var2, "DIM1"); + var3.mkdirs(); + return new AnvilChunkLoader(var3); + } else { + return new AnvilChunkLoader(var2); + } + } + + /** + * Saves the given World Info with the given NBTTagCompound as the Player. + */ + public void saveWorldInfoWithPlayer(WorldInfo par1WorldInfo, NBTTagCompound par2NBTTagCompound) { + par1WorldInfo.setSaveVersion(19133); + super.saveWorldInfoWithPlayer(par1WorldInfo, par2NBTTagCompound); + } + + /** + * Called to flush all changes to disk, waiting for them to complete. + */ + public void flush() { + try { + ThreadedFileIOBase.threadedIOInstance.waitForFinish(); + } catch (InterruptedException var2) { + var2.printStackTrace(); + } + + RegionFileCache.clearRegionFileReferences(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/AxisAlignedBB.java b/sp-server/src/main/java/net/minecraft/src/AxisAlignedBB.java new file mode 100644 index 0000000..6e1ea3e --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/AxisAlignedBB.java @@ -0,0 +1,425 @@ +package net.minecraft.src; + +public class AxisAlignedBB { + /** ThreadLocal AABBPool */ + private static final ThreadLocal theAABBLocalPool = new AABBLocalPool(); + public double minX; + public double minY; + public double minZ; + public double maxX; + public double maxY; + public double maxZ; + + /** + * Returns a bounding box with the specified bounds. Args: minX, minY, minZ, + * maxX, maxY, maxZ + */ + public static AxisAlignedBB getBoundingBox(double par0, double par2, double par4, double par6, double par8, + double par10) { + return new AxisAlignedBB(par0, par2, par4, par6, par8, par10); + } + + /** + * Gets the ThreadLocal AABBPool + */ + public static AABBPool getAABBPool() { + return (AABBPool) theAABBLocalPool.get(); + } + + protected AxisAlignedBB(double par1, double par3, double par5, double par7, double par9, double par11) { + this.minX = par1; + this.minY = par3; + this.minZ = par5; + this.maxX = par7; + this.maxY = par9; + this.maxZ = par11; + } + + /** + * Sets the bounds of the bounding box. Args: minX, minY, minZ, maxX, maxY, maxZ + */ + public AxisAlignedBB setBounds(double par1, double par3, double par5, double par7, double par9, double par11) { + this.minX = par1; + this.minY = par3; + this.minZ = par5; + this.maxX = par7; + this.maxY = par9; + this.maxZ = par11; + return this; + } + + /** + * Adds the coordinates to the bounding box extending it if the point lies + * outside the current ranges. Args: x, y, z + */ + public AxisAlignedBB addCoord(double par1, double par3, double par5) { + double var7 = this.minX; + double var9 = this.minY; + double var11 = this.minZ; + double var13 = this.maxX; + double var15 = this.maxY; + double var17 = this.maxZ; + + if (par1 < 0.0D) { + var7 += par1; + } + + if (par1 > 0.0D) { + var13 += par1; + } + + if (par3 < 0.0D) { + var9 += par3; + } + + if (par3 > 0.0D) { + var15 += par3; + } + + if (par5 < 0.0D) { + var11 += par5; + } + + if (par5 > 0.0D) { + var17 += par5; + } + + return getAABBPool().getAABB(var7, var9, var11, var13, var15, var17); + } + + /** + * Returns a bounding box expanded by the specified vector (if negative numbers + * are given it will shrink). Args: x, y, z + */ + public AxisAlignedBB expand(double par1, double par3, double par5) { + double var7 = this.minX - par1; + double var9 = this.minY - par3; + double var11 = this.minZ - par5; + double var13 = this.maxX + par1; + double var15 = this.maxY + par3; + double var17 = this.maxZ + par5; + return getAABBPool().getAABB(var7, var9, var11, var13, var15, var17); + } + + /** + * Returns a bounding box offseted by the specified vector (if negative numbers + * are given it will shrink). Args: x, y, z + */ + public AxisAlignedBB getOffsetBoundingBox(double par1, double par3, double par5) { + return getAABBPool().getAABB(this.minX + par1, this.minY + par3, this.minZ + par5, this.maxX + par1, + this.maxY + par3, this.maxZ + par5); + } + + /** + * if instance and the argument bounding boxes overlap in the Y and Z + * dimensions, calculate the offset between them in the X dimension. return var2 + * if the bounding boxes do not overlap or if var2 is closer to 0 then the + * calculated offset. Otherwise return the calculated offset. + */ + public double calculateXOffset(AxisAlignedBB par1AxisAlignedBB, double par2) { + if (par1AxisAlignedBB.maxY > this.minY && par1AxisAlignedBB.minY < this.maxY) { + if (par1AxisAlignedBB.maxZ > this.minZ && par1AxisAlignedBB.minZ < this.maxZ) { + double var4; + + if (par2 > 0.0D && par1AxisAlignedBB.maxX <= this.minX) { + var4 = this.minX - par1AxisAlignedBB.maxX; + + if (var4 < par2) { + par2 = var4; + } + } + + if (par2 < 0.0D && par1AxisAlignedBB.minX >= this.maxX) { + var4 = this.maxX - par1AxisAlignedBB.minX; + + if (var4 > par2) { + par2 = var4; + } + } + + return par2; + } else { + return par2; + } + } else { + return par2; + } + } + + /** + * if instance and the argument bounding boxes overlap in the X and Z + * dimensions, calculate the offset between them in the Y dimension. return var2 + * if the bounding boxes do not overlap or if var2 is closer to 0 then the + * calculated offset. Otherwise return the calculated offset. + */ + public double calculateYOffset(AxisAlignedBB par1AxisAlignedBB, double par2) { + if (par1AxisAlignedBB.maxX > this.minX && par1AxisAlignedBB.minX < this.maxX) { + if (par1AxisAlignedBB.maxZ > this.minZ && par1AxisAlignedBB.minZ < this.maxZ) { + double var4; + + if (par2 > 0.0D && par1AxisAlignedBB.maxY <= this.minY) { + var4 = this.minY - par1AxisAlignedBB.maxY; + + if (var4 < par2) { + par2 = var4; + } + } + + if (par2 < 0.0D && par1AxisAlignedBB.minY >= this.maxY) { + var4 = this.maxY - par1AxisAlignedBB.minY; + + if (var4 > par2) { + par2 = var4; + } + } + + return par2; + } else { + return par2; + } + } else { + return par2; + } + } + + /** + * if instance and the argument bounding boxes overlap in the Y and X + * dimensions, calculate the offset between them in the Z dimension. return var2 + * if the bounding boxes do not overlap or if var2 is closer to 0 then the + * calculated offset. Otherwise return the calculated offset. + */ + public double calculateZOffset(AxisAlignedBB par1AxisAlignedBB, double par2) { + if (par1AxisAlignedBB.maxX > this.minX && par1AxisAlignedBB.minX < this.maxX) { + if (par1AxisAlignedBB.maxY > this.minY && par1AxisAlignedBB.minY < this.maxY) { + double var4; + + if (par2 > 0.0D && par1AxisAlignedBB.maxZ <= this.minZ) { + var4 = this.minZ - par1AxisAlignedBB.maxZ; + + if (var4 < par2) { + par2 = var4; + } + } + + if (par2 < 0.0D && par1AxisAlignedBB.minZ >= this.maxZ) { + var4 = this.maxZ - par1AxisAlignedBB.minZ; + + if (var4 > par2) { + par2 = var4; + } + } + + return par2; + } else { + return par2; + } + } else { + return par2; + } + } + + /** + * Returns whether the given bounding box intersects with this one. Args: + * axisAlignedBB + */ + public boolean intersectsWith(AxisAlignedBB par1AxisAlignedBB) { + return par1AxisAlignedBB.maxX > this.minX && par1AxisAlignedBB.minX < this.maxX + ? (par1AxisAlignedBB.maxY > this.minY && par1AxisAlignedBB.minY < this.maxY + ? par1AxisAlignedBB.maxZ > this.minZ && par1AxisAlignedBB.minZ < this.maxZ + : false) + : false; + } + + /** + * Offsets the current bounding box by the specified coordinates. Args: x, y, z + */ + public AxisAlignedBB offset(double par1, double par3, double par5) { + this.minX += par1; + this.minY += par3; + this.minZ += par5; + this.maxX += par1; + this.maxY += par3; + this.maxZ += par5; + return this; + } + + /** + * Returns if the supplied Vec3D is completely inside the bounding box + */ + public boolean isVecInside(Vec3 par1Vec3) { + return par1Vec3.xCoord > this.minX && par1Vec3.xCoord < this.maxX + ? (par1Vec3.yCoord > this.minY && par1Vec3.yCoord < this.maxY + ? par1Vec3.zCoord > this.minZ && par1Vec3.zCoord < this.maxZ + : false) + : false; + } + + /** + * Returns the average length of the edges of the bounding box. + */ + public double getAverageEdgeLength() { + double var1 = this.maxX - this.minX; + double var3 = this.maxY - this.minY; + double var5 = this.maxZ - this.minZ; + return (var1 + var3 + var5) / 3.0D; + } + + /** + * Returns a bounding box that is inset by the specified amounts + */ + public AxisAlignedBB contract(double par1, double par3, double par5) { + double var7 = this.minX + par1; + double var9 = this.minY + par3; + double var11 = this.minZ + par5; + double var13 = this.maxX - par1; + double var15 = this.maxY - par3; + double var17 = this.maxZ - par5; + return getAABBPool().getAABB(var7, var9, var11, var13, var15, var17); + } + + /** + * Returns a copy of the bounding box. + */ + public AxisAlignedBB copy() { + return getAABBPool().getAABB(this.minX, this.minY, this.minZ, this.maxX, this.maxY, this.maxZ); + } + + public MovingObjectPosition calculateIntercept(Vec3 par1Vec3, Vec3 par2Vec3) { + Vec3 var3 = par1Vec3.getIntermediateWithXValue(par2Vec3, this.minX); + Vec3 var4 = par1Vec3.getIntermediateWithXValue(par2Vec3, this.maxX); + Vec3 var5 = par1Vec3.getIntermediateWithYValue(par2Vec3, this.minY); + Vec3 var6 = par1Vec3.getIntermediateWithYValue(par2Vec3, this.maxY); + Vec3 var7 = par1Vec3.getIntermediateWithZValue(par2Vec3, this.minZ); + Vec3 var8 = par1Vec3.getIntermediateWithZValue(par2Vec3, this.maxZ); + + if (!this.isVecInYZ(var3)) { + var3 = null; + } + + if (!this.isVecInYZ(var4)) { + var4 = null; + } + + if (!this.isVecInXZ(var5)) { + var5 = null; + } + + if (!this.isVecInXZ(var6)) { + var6 = null; + } + + if (!this.isVecInXY(var7)) { + var7 = null; + } + + if (!this.isVecInXY(var8)) { + var8 = null; + } + + Vec3 var9 = null; + + if (var3 != null && (var9 == null || par1Vec3.squareDistanceTo(var3) < par1Vec3.squareDistanceTo(var9))) { + var9 = var3; + } + + if (var4 != null && (var9 == null || par1Vec3.squareDistanceTo(var4) < par1Vec3.squareDistanceTo(var9))) { + var9 = var4; + } + + if (var5 != null && (var9 == null || par1Vec3.squareDistanceTo(var5) < par1Vec3.squareDistanceTo(var9))) { + var9 = var5; + } + + if (var6 != null && (var9 == null || par1Vec3.squareDistanceTo(var6) < par1Vec3.squareDistanceTo(var9))) { + var9 = var6; + } + + if (var7 != null && (var9 == null || par1Vec3.squareDistanceTo(var7) < par1Vec3.squareDistanceTo(var9))) { + var9 = var7; + } + + if (var8 != null && (var9 == null || par1Vec3.squareDistanceTo(var8) < par1Vec3.squareDistanceTo(var9))) { + var9 = var8; + } + + if (var9 == null) { + return null; + } else { + byte var10 = -1; + + if (var9 == var3) { + var10 = 4; + } + + if (var9 == var4) { + var10 = 5; + } + + if (var9 == var5) { + var10 = 0; + } + + if (var9 == var6) { + var10 = 1; + } + + if (var9 == var7) { + var10 = 2; + } + + if (var9 == var8) { + var10 = 3; + } + + return new MovingObjectPosition(0, 0, 0, var10, var9); + } + } + + /** + * Checks if the specified vector is within the YZ dimensions of the bounding + * box. Args: Vec3D + */ + private boolean isVecInYZ(Vec3 par1Vec3) { + return par1Vec3 == null ? false + : par1Vec3.yCoord >= this.minY && par1Vec3.yCoord <= this.maxY && par1Vec3.zCoord >= this.minZ + && par1Vec3.zCoord <= this.maxZ; + } + + /** + * Checks if the specified vector is within the XZ dimensions of the bounding + * box. Args: Vec3D + */ + private boolean isVecInXZ(Vec3 par1Vec3) { + return par1Vec3 == null ? false + : par1Vec3.xCoord >= this.minX && par1Vec3.xCoord <= this.maxX && par1Vec3.zCoord >= this.minZ + && par1Vec3.zCoord <= this.maxZ; + } + + /** + * Checks if the specified vector is within the XY dimensions of the bounding + * box. Args: Vec3D + */ + private boolean isVecInXY(Vec3 par1Vec3) { + return par1Vec3 == null ? false + : par1Vec3.xCoord >= this.minX && par1Vec3.xCoord <= this.maxX && par1Vec3.yCoord >= this.minY + && par1Vec3.yCoord <= this.maxY; + } + + /** + * Sets the bounding box to the same bounds as the bounding box passed in. Args: + * axisAlignedBB + */ + public void setBB(AxisAlignedBB par1AxisAlignedBB) { + this.minX = par1AxisAlignedBB.minX; + this.minY = par1AxisAlignedBB.minY; + this.minZ = par1AxisAlignedBB.minZ; + this.maxX = par1AxisAlignedBB.maxX; + this.maxY = par1AxisAlignedBB.maxY; + this.maxZ = par1AxisAlignedBB.maxZ; + } + + public String toString() { + return "box[" + this.minX + ", " + this.minY + ", " + this.minZ + " -> " + this.maxX + ", " + this.maxY + ", " + + this.maxZ + "]"; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BanEntry.java b/sp-server/src/main/java/net/minecraft/src/BanEntry.java new file mode 100644 index 0000000..8821187 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BanEntry.java @@ -0,0 +1,140 @@ +package net.minecraft.src; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.regex.Pattern; +import net.minecraft.server.MinecraftServer; + +public class BanEntry { + public static final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z"); + private final String username; + private Date banStartDate = new Date(); + private String bannedBy = "(Unknown)"; + private Date banEndDate = null; + private String reason = "Banned by an operator."; + + public BanEntry(String par1Str) { + this.username = par1Str; + } + + public String getBannedUsername() { + return this.username; + } + + public Date getBanStartDate() { + return this.banStartDate; + } + + /** + * null == start ban now + */ + public void setBanStartDate(Date par1Date) { + this.banStartDate = par1Date != null ? par1Date : new Date(); + } + + public String getBannedBy() { + return this.bannedBy; + } + + public void setBannedBy(String par1Str) { + this.bannedBy = par1Str; + } + + public Date getBanEndDate() { + return this.banEndDate; + } + + public void setBanEndDate(Date par1Date) { + this.banEndDate = par1Date; + } + + public boolean hasBanExpired() { + return this.banEndDate == null ? false : this.banEndDate.before(new Date()); + } + + public String getBanReason() { + return this.reason; + } + + public void setBanReason(String par1Str) { + this.reason = par1Str; + } + + public String buildBanString() { + StringBuilder var1 = new StringBuilder(); + var1.append(this.getBannedUsername()); + var1.append("|"); + var1.append(dateFormat.format(this.getBanStartDate())); + var1.append("|"); + var1.append(this.getBannedBy()); + var1.append("|"); + var1.append(this.getBanEndDate() == null ? "Forever" : dateFormat.format(this.getBanEndDate())); + var1.append("|"); + var1.append(this.getBanReason()); + return var1.toString(); + } + + public static BanEntry parse(String par0Str) { + if (par0Str.trim().length() < 2) { + return null; + } else { + String[] var1 = par0Str.trim().split(Pattern.quote("|"), 5); + BanEntry var2 = new BanEntry(var1[0].trim()); + byte var3 = 0; + int var10000 = var1.length; + int var7 = var3 + 1; + + if (var10000 <= var7) { + return var2; + } else { + try { + var2.setBanStartDate(dateFormat.parse(var1[var7].trim())); + } catch (ParseException var6) { + MinecraftServer.getServer().getLogAgent() + .logWarningException("Could not read creation date format for ban entry \'" + + var2.getBannedUsername() + "\' (was: \'" + var1[var7] + "\')", var6); + } + + var10000 = var1.length; + ++var7; + + if (var10000 <= var7) { + return var2; + } else { + var2.setBannedBy(var1[var7].trim()); + var10000 = var1.length; + ++var7; + + if (var10000 <= var7) { + return var2; + } else { + try { + String var4 = var1[var7].trim(); + + if (!var4.equalsIgnoreCase("Forever") && var4.length() > 0) { + var2.setBanEndDate(dateFormat.parse(var4)); + } + } catch (ParseException var5) { + MinecraftServer.getServer().getLogAgent() + .logWarningException( + "Could not read expiry date format for ban entry \'" + + var2.getBannedUsername() + "\' (was: \'" + var1[var7] + "\')", + var5); + } + + var10000 = var1.length; + ++var7; + + if (var10000 <= var7) { + return var2; + } else { + var2.setBanReason(var1[var7].trim()); + return var2; + } + } + } + } + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BanList.java b/sp-server/src/main/java/net/minecraft/src/BanList.java new file mode 100644 index 0000000..c797d06 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BanList.java @@ -0,0 +1,137 @@ +package net.minecraft.src; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.io.PrintWriter; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Iterator; +import java.util.Map; +import net.minecraft.server.MinecraftServer; + +public class BanList { + private final LowerStringMap theBanList = new LowerStringMap(); + private final File fileName; + + /** set to true if not singlePlayer */ + private boolean listActive = true; + + public BanList(File par1File) { + this.fileName = par1File; + } + + public boolean isListActive() { + return this.listActive; + } + + public void setListActive(boolean par1) { + this.listActive = par1; + } + + /** + * removes expired Bans before returning + */ + public Map getBannedList() { + this.removeExpiredBans(); + return this.theBanList; + } + + public boolean isBanned(String par1Str) { + if (!this.isListActive()) { + return false; + } else { + this.removeExpiredBans(); + return this.theBanList.containsKey(par1Str); + } + } + + public void put(BanEntry par1BanEntry) { + this.theBanList.putLower(par1BanEntry.getBannedUsername(), par1BanEntry); + this.saveToFileWithHeader(); + } + + public void remove(String par1Str) { + this.theBanList.remove(par1Str); + this.saveToFileWithHeader(); + } + + public void removeExpiredBans() { + Iterator var1 = this.theBanList.values().iterator(); + + while (var1.hasNext()) { + BanEntry var2 = (BanEntry) var1.next(); + + if (var2.hasBanExpired()) { + var1.remove(); + } + } + } + + /** + * Loads the ban list from the file (adds every entry, does not clear the + * current list). + */ + public void loadBanList() { + if (this.fileName.isFile()) { + BufferedReader var1; + + try { + var1 = new BufferedReader(new FileReader(this.fileName)); + } catch (FileNotFoundException var4) { + throw new Error(); + } + + String var2; + + try { + while ((var2 = var1.readLine()) != null) { + if (!var2.startsWith("#")) { + BanEntry var3 = BanEntry.parse(var2); + + if (var3 != null) { + this.theBanList.putLower(var3.getBannedUsername(), var3); + } + } + } + } catch (IOException var5) { + MinecraftServer.getServer().getLogAgent().logSevereException("Could not load ban list", var5); + } + } + } + + public void saveToFileWithHeader() { + this.saveToFile(true); + } + + /** + * par1: include header + */ + public void saveToFile(boolean par1) { + this.removeExpiredBans(); + + try { + PrintWriter var2 = new PrintWriter(new FileWriter(this.fileName, false)); + + if (par1) { + var2.println("# Updated " + (new SimpleDateFormat()).format(new Date()) + " by Minecraft " + "1.5.2"); + var2.println("# victim name | ban date | banned by | banned until | reason"); + var2.println(); + } + + Iterator var3 = this.theBanList.values().iterator(); + + while (var3.hasNext()) { + BanEntry var4 = (BanEntry) var3.next(); + var2.println(var4.buildBanString()); + } + + var2.close(); + } catch (IOException var5) { + MinecraftServer.getServer().getLogAgent().logSevereException("Could not save ban list", var5); + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BehaviorDefaultDispenseItem.java b/sp-server/src/main/java/net/minecraft/src/BehaviorDefaultDispenseItem.java new file mode 100644 index 0000000..cdbf256 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BehaviorDefaultDispenseItem.java @@ -0,0 +1,61 @@ +package net.minecraft.src; + +public class BehaviorDefaultDispenseItem implements IBehaviorDispenseItem { + /** + * Dispenses the specified ItemStack from a dispenser. + */ + public final ItemStack dispense(IBlockSource par1IBlockSource, ItemStack par2ItemStack) { + ItemStack var3 = this.dispenseStack(par1IBlockSource, par2ItemStack); + this.playDispenseSound(par1IBlockSource); + this.spawnDispenseParticles(par1IBlockSource, BlockDispenser.getFacing(par1IBlockSource.getBlockMetadata())); + return var3; + } + + /** + * Dispense the specified stack, play the dispense sound and spawn particles. + */ + protected ItemStack dispenseStack(IBlockSource par1IBlockSource, ItemStack par2ItemStack) { + EnumFacing var3 = BlockDispenser.getFacing(par1IBlockSource.getBlockMetadata()); + IPosition var4 = BlockDispenser.getIPositionFromBlockSource(par1IBlockSource); + ItemStack var5 = par2ItemStack.splitStack(1); + doDispense(par1IBlockSource.getWorld(), var5, 6, var3, var4); + return par2ItemStack; + } + + public static void doDispense(World par0World, ItemStack par1ItemStack, int par2, EnumFacing par3EnumFacing, + IPosition par4IPosition) { + double var5 = par4IPosition.getX(); + double var7 = par4IPosition.getY(); + double var9 = par4IPosition.getZ(); + EntityItem var11 = new EntityItem(par0World, var5, var7 - 0.3D, var9, par1ItemStack); + double var12 = par0World.rand.nextDouble() * 0.1D + 0.2D; + var11.motionX = (double) par3EnumFacing.getFrontOffsetX() * var12; + var11.motionY = 0.20000000298023224D; + var11.motionZ = (double) par3EnumFacing.getFrontOffsetZ() * var12; + var11.motionX += par0World.rand.nextGaussian() * 0.007499999832361937D * (double) par2; + var11.motionY += par0World.rand.nextGaussian() * 0.007499999832361937D * (double) par2; + var11.motionZ += par0World.rand.nextGaussian() * 0.007499999832361937D * (double) par2; + par0World.spawnEntityInWorld(var11); + } + + /** + * Play the dispense sound from the specified block. + */ + protected void playDispenseSound(IBlockSource par1IBlockSource) { + par1IBlockSource.getWorld().playAuxSFX(1000, par1IBlockSource.getXInt(), par1IBlockSource.getYInt(), + par1IBlockSource.getZInt(), 0); + } + + /** + * Order clients to display dispense particles from the specified block and + * facing. + */ + protected void spawnDispenseParticles(IBlockSource par1IBlockSource, EnumFacing par2EnumFacing) { + par1IBlockSource.getWorld().playAuxSFX(2000, par1IBlockSource.getXInt(), par1IBlockSource.getYInt(), + par1IBlockSource.getZInt(), this.func_82488_a(par2EnumFacing)); + } + + private int func_82488_a(EnumFacing par1EnumFacing) { + return par1EnumFacing.getFrontOffsetX() + 1 + (par1EnumFacing.getFrontOffsetZ() + 1) * 3; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BehaviorDispenseArmor.java b/sp-server/src/main/java/net/minecraft/src/BehaviorDispenseArmor.java new file mode 100644 index 0000000..3ac432c --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BehaviorDispenseArmor.java @@ -0,0 +1,33 @@ +package net.minecraft.src; + +import java.util.List; + +final class BehaviorDispenseArmor extends BehaviorDefaultDispenseItem { + /** + * Dispense the specified stack, play the dispense sound and spawn particles. + */ + protected ItemStack dispenseStack(IBlockSource par1IBlockSource, ItemStack par2ItemStack) { + EnumFacing var3 = BlockDispenser.getFacing(par1IBlockSource.getBlockMetadata()); + int var4 = par1IBlockSource.getXInt() + var3.getFrontOffsetX(); + int var5 = par1IBlockSource.getYInt() + var3.getFrontOffsetY(); + int var6 = par1IBlockSource.getZInt() + var3.getFrontOffsetZ(); + AxisAlignedBB var7 = AxisAlignedBB.getAABBPool().getAABB((double) var4, (double) var5, (double) var6, + (double) (var4 + 1), (double) (var5 + 1), (double) (var6 + 1)); + List var8 = par1IBlockSource.getWorld().selectEntitiesWithinAABB(EntityLiving.class, var7, + new EntitySelectorArmoredMob(par2ItemStack)); + + if (var8.size() > 0) { + EntityLiving var9 = (EntityLiving) var8.get(0); + int var10 = var9 instanceof EntityPlayer ? 1 : 0; + int var11 = EntityLiving.getArmorPosition(par2ItemStack); + ItemStack var12 = par2ItemStack.copy(); + var12.stackSize = 1; + var9.setCurrentItemOrArmor(var11 - var10, var12); + var9.func_96120_a(var11, 2.0F); + --par2ItemStack.stackSize; + return par2ItemStack; + } else { + return super.dispenseStack(par1IBlockSource, par2ItemStack); + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BehaviorDispenseItemProvider.java b/sp-server/src/main/java/net/minecraft/src/BehaviorDispenseItemProvider.java new file mode 100644 index 0000000..631a62f --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BehaviorDispenseItemProvider.java @@ -0,0 +1,10 @@ +package net.minecraft.src; + +final class BehaviorDispenseItemProvider implements IBehaviorDispenseItem { + /** + * Dispenses the specified ItemStack from a dispenser. + */ + public ItemStack dispense(IBlockSource par1IBlockSource, ItemStack par2ItemStack) { + return par2ItemStack; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BehaviorDispenseMinecart.java b/sp-server/src/main/java/net/minecraft/src/BehaviorDispenseMinecart.java new file mode 100644 index 0000000..a307cc1 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BehaviorDispenseMinecart.java @@ -0,0 +1,45 @@ +package net.minecraft.src; + +final class BehaviorDispenseMinecart extends BehaviorDefaultDispenseItem { + private final BehaviorDefaultDispenseItem field_96465_b = new BehaviorDefaultDispenseItem(); + + /** + * Dispense the specified stack, play the dispense sound and spawn particles. + */ + public ItemStack dispenseStack(IBlockSource par1IBlockSource, ItemStack par2ItemStack) { + EnumFacing var3 = BlockDispenser.getFacing(par1IBlockSource.getBlockMetadata()); + World var4 = par1IBlockSource.getWorld(); + double var5 = par1IBlockSource.getX() + (double) ((float) var3.getFrontOffsetX() * 1.125F); + double var7 = par1IBlockSource.getY() + (double) ((float) var3.getFrontOffsetY() * 1.125F); + double var9 = par1IBlockSource.getZ() + (double) ((float) var3.getFrontOffsetZ() * 1.125F); + int var11 = par1IBlockSource.getXInt() + var3.getFrontOffsetX(); + int var12 = par1IBlockSource.getYInt() + var3.getFrontOffsetY(); + int var13 = par1IBlockSource.getZInt() + var3.getFrontOffsetZ(); + int var14 = var4.getBlockId(var11, var12, var13); + double var15; + + if (BlockRailBase.isRailBlock(var14)) { + var15 = 0.0D; + } else { + if (var14 != 0 || !BlockRailBase.isRailBlock(var4.getBlockId(var11, var12 - 1, var13))) { + return this.field_96465_b.dispense(par1IBlockSource, par2ItemStack); + } + + var15 = -1.0D; + } + + EntityMinecart var17 = EntityMinecart.createMinecart(var4, var5, var7 + var15, var9, + ((ItemMinecart) par2ItemStack.getItem()).minecartType); + var4.spawnEntityInWorld(var17); + par2ItemStack.splitStack(1); + return par2ItemStack; + } + + /** + * Play the dispense sound from the specified block. + */ + protected void playDispenseSound(IBlockSource par1IBlockSource) { + par1IBlockSource.getWorld().playAuxSFX(1000, par1IBlockSource.getXInt(), par1IBlockSource.getYInt(), + par1IBlockSource.getZInt(), 0); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BehaviorProjectileDispense.java b/sp-server/src/main/java/net/minecraft/src/BehaviorProjectileDispense.java new file mode 100644 index 0000000..3fbd858 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BehaviorProjectileDispense.java @@ -0,0 +1,39 @@ +package net.minecraft.src; + +public abstract class BehaviorProjectileDispense extends BehaviorDefaultDispenseItem { + /** + * Dispense the specified stack, play the dispense sound and spawn particles. + */ + public ItemStack dispenseStack(IBlockSource par1IBlockSource, ItemStack par2ItemStack) { + World var3 = par1IBlockSource.getWorld(); + IPosition var4 = BlockDispenser.getIPositionFromBlockSource(par1IBlockSource); + EnumFacing var5 = BlockDispenser.getFacing(par1IBlockSource.getBlockMetadata()); + IProjectile var6 = this.getProjectileEntity(var3, var4); + var6.setThrowableHeading((double) var5.getFrontOffsetX(), (double) ((float) var5.getFrontOffsetY() + 0.1F), + (double) var5.getFrontOffsetZ(), this.func_82500_b(), this.func_82498_a()); + var3.spawnEntityInWorld((Entity) var6); + par2ItemStack.splitStack(1); + return par2ItemStack; + } + + /** + * Play the dispense sound from the specified block. + */ + protected void playDispenseSound(IBlockSource par1IBlockSource) { + par1IBlockSource.getWorld().playAuxSFX(1002, par1IBlockSource.getXInt(), par1IBlockSource.getYInt(), + par1IBlockSource.getZInt(), 0); + } + + /** + * Return the projectile entity spawned by this dispense behavior. + */ + protected abstract IProjectile getProjectileEntity(World var1, IPosition var2); + + protected float func_82498_a() { + return 6.0F; + } + + protected float func_82500_b() { + return 1.1F; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BiomeCache.java b/sp-server/src/main/java/net/minecraft/src/BiomeCache.java new file mode 100644 index 0000000..2b1493c --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BiomeCache.java @@ -0,0 +1,90 @@ +package net.minecraft.src; + +import java.util.ArrayList; +import java.util.List; + +public class BiomeCache { + /** Reference to the WorldChunkManager */ + private final WorldChunkManager chunkManager; + + /** The last time this BiomeCache was cleaned, in milliseconds. */ + private long lastCleanupTime = 0L; + + /** + * The map of keys to BiomeCacheBlocks. Keys are based on the chunk x, z + * coordinates as (x | z << 32). + */ + private LongHashMap cacheMap = new LongHashMap(); + + /** The list of cached BiomeCacheBlocks */ + private List cache = new ArrayList(); + + public BiomeCache(WorldChunkManager par1WorldChunkManager) { + this.chunkManager = par1WorldChunkManager; + } + + /** + * Returns a biome cache block at location specified. + */ + public BiomeCacheBlock getBiomeCacheBlock(int par1, int par2) { + par1 >>= 4; + par2 >>= 4; + long var3 = (long) par1 & 4294967295L | ((long) par2 & 4294967295L) << 32; + BiomeCacheBlock var5 = (BiomeCacheBlock) this.cacheMap.getValueByKey(var3); + + if (var5 == null) { + var5 = new BiomeCacheBlock(this, par1, par2); + this.cacheMap.add(var3, var5); + this.cache.add(var5); + } + + var5.lastAccessTime = System.currentTimeMillis(); + return var5; + } + + /** + * Returns the BiomeGenBase related to the x, z position from the cache. + */ + public BiomeGenBase getBiomeGenAt(int par1, int par2) { + return this.getBiomeCacheBlock(par1, par2).getBiomeGenAt(par1, par2); + } + + /** + * Removes BiomeCacheBlocks from this cache that haven't been accessed in at + * least 30 seconds. + */ + public void cleanupCache() { + long var1 = System.currentTimeMillis(); + long var3 = var1 - this.lastCleanupTime; + + if (var3 > 7500L || var3 < 0L) { + this.lastCleanupTime = var1; + + for (int var5 = 0; var5 < this.cache.size(); ++var5) { + BiomeCacheBlock var6 = (BiomeCacheBlock) this.cache.get(var5); + long var7 = var1 - var6.lastAccessTime; + + if (var7 > 30000L || var7 < 0L) { + this.cache.remove(var5--); + long var9 = (long) var6.xPosition & 4294967295L | ((long) var6.zPosition & 4294967295L) << 32; + this.cacheMap.remove(var9); + } + } + } + } + + /** + * Returns the array of cached biome types in the BiomeCacheBlock at the given + * location. + */ + public BiomeGenBase[] getCachedBiomes(int par1, int par2) { + return this.getBiomeCacheBlock(par1, par2).biomes; + } + + /** + * Get the world chunk manager object for a biome list. + */ + static WorldChunkManager getChunkManager(BiomeCache par0BiomeCache) { + return par0BiomeCache.chunkManager; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BiomeCacheBlock.java b/sp-server/src/main/java/net/minecraft/src/BiomeCacheBlock.java new file mode 100644 index 0000000..7a625d6 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BiomeCacheBlock.java @@ -0,0 +1,44 @@ +package net.minecraft.src; + +public class BiomeCacheBlock { + /** An array of chunk temperatures saved by this cache. */ + public float[] temperatureValues; + + /** An array of chunk rainfall values saved by this cache. */ + public float[] rainfallValues; + + /** The array of biome types stored in this BiomeCacheBlock. */ + public BiomeGenBase[] biomes; + + /** The x coordinate of the BiomeCacheBlock. */ + public int xPosition; + + /** The z coordinate of the BiomeCacheBlock. */ + public int zPosition; + + /** The last time this BiomeCacheBlock was accessed, in milliseconds. */ + public long lastAccessTime; + + /** The BiomeCache object that contains this BiomeCacheBlock */ + final BiomeCache theBiomeCache; + + public BiomeCacheBlock(BiomeCache par1BiomeCache, int par2, int par3) { + this.theBiomeCache = par1BiomeCache; + this.temperatureValues = new float[256]; + this.rainfallValues = new float[256]; + this.biomes = new BiomeGenBase[256]; + this.xPosition = par2; + this.zPosition = par3; + BiomeCache.getChunkManager(par1BiomeCache).getTemperatures(this.temperatureValues, par2 << 4, par3 << 4, 16, + 16); + BiomeCache.getChunkManager(par1BiomeCache).getRainfall(this.rainfallValues, par2 << 4, par3 << 4, 16, 16); + BiomeCache.getChunkManager(par1BiomeCache).getBiomeGenAt(this.biomes, par2 << 4, par3 << 4, 16, 16, false); + } + + /** + * Returns the BiomeGenBase related to the x, z position from the cache block. + */ + public BiomeGenBase getBiomeGenAt(int par1, int par2) { + return this.biomes[par1 & 15 | (par2 & 15) << 4]; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BiomeDecorator.java b/sp-server/src/main/java/net/minecraft/src/BiomeDecorator.java new file mode 100644 index 0000000..33d939f --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BiomeDecorator.java @@ -0,0 +1,405 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BiomeDecorator { + /** The world the BiomeDecorator is currently decorating */ + protected World currentWorld; + + /** The Biome Decorator's random number generator. */ + protected Random randomGenerator; + + /** The X-coordinate of the chunk currently being decorated */ + protected int chunk_X; + + /** The Z-coordinate of the chunk currently being decorated */ + protected int chunk_Z; + + /** The biome generator object. */ + protected BiomeGenBase biome; + + /** The clay generator. */ + protected WorldGenerator clayGen = new WorldGenClay(4); + + /** The sand generator. */ + protected WorldGenerator sandGen; + + /** The gravel generator. */ + protected WorldGenerator gravelAsSandGen; + + /** The dirt generator. */ + protected WorldGenerator dirtGen; + protected WorldGenerator gravelGen; + protected WorldGenerator coalGen; + protected WorldGenerator ironGen; + + /** Field that holds gold WorldGenMinable */ + protected WorldGenerator goldGen; + + /** Field that holds redstone WorldGenMinable */ + protected WorldGenerator redstoneGen; + + /** Field that holds diamond WorldGenMinable */ + protected WorldGenerator diamondGen; + + /** Field that holds Lapis WorldGenMinable */ + protected WorldGenerator lapisGen; + + /** Field that holds one of the plantYellow WorldGenFlowers */ + protected WorldGenerator plantYellowGen; + + /** Field that holds one of the plantRed WorldGenFlowers */ + protected WorldGenerator plantRedGen; + + /** Field that holds mushroomBrown WorldGenFlowers */ + protected WorldGenerator mushroomBrownGen; + + /** Field that holds mushroomRed WorldGenFlowers */ + protected WorldGenerator mushroomRedGen; + + /** Field that holds big mushroom generator */ + protected WorldGenerator bigMushroomGen; + + /** Field that holds WorldGenReed */ + protected WorldGenerator reedGen; + + /** Field that holds WorldGenCactus */ + protected WorldGenerator cactusGen; + + /** The water lily generation! */ + protected WorldGenerator waterlilyGen; + + /** Amount of waterlilys per chunk. */ + protected int waterlilyPerChunk; + + /** + * The number of trees to attempt to generate per chunk. Up to 10 in forests, + * none in deserts. + */ + protected int treesPerChunk; + + /** + * The number of yellow flower patches to generate per chunk. The game generates + * much less than this number, since it attempts to generate them at a random + * altitude. + */ + protected int flowersPerChunk; + + /** The amount of tall grass to generate per chunk. */ + protected int grassPerChunk; + + /** + * The number of dead bushes to generate per chunk. Used in deserts and swamps. + */ + protected int deadBushPerChunk; + + /** + * The number of extra mushroom patches per chunk. It generates 1/4 this number + * in brown mushroom patches, and 1/8 this number in red mushroom patches. These + * mushrooms go beyond the default base number of mushrooms. + */ + protected int mushroomsPerChunk; + + /** + * The number of reeds to generate per chunk. Reeds won't generate if the + * randomly selected placement is unsuitable. + */ + protected int reedsPerChunk; + + /** + * The number of cactus plants to generate per chunk. Cacti only work on sand. + */ + protected int cactiPerChunk; + + /** + * The number of sand patches to generate per chunk. Sand patches only generate + * when part of it is underwater. + */ + protected int sandPerChunk; + + /** + * The number of sand patches to generate per chunk. Sand patches only generate + * when part of it is underwater. There appear to be two separate fields for + * this. + */ + protected int sandPerChunk2; + + /** + * The number of clay patches to generate per chunk. Only generates when part of + * it is underwater. + */ + protected int clayPerChunk; + + /** Amount of big mushrooms per chunk */ + protected int bigMushroomsPerChunk; + + /** True if decorator should generate surface lava & water */ + public boolean generateLakes; + + public BiomeDecorator(BiomeGenBase par1BiomeGenBase) { + this.sandGen = new WorldGenSand(7, Block.sand.blockID); + this.gravelAsSandGen = new WorldGenSand(6, Block.gravel.blockID); + this.dirtGen = new WorldGenMinable(Block.dirt.blockID, 32); + this.gravelGen = new WorldGenMinable(Block.gravel.blockID, 32); + this.coalGen = new WorldGenMinable(Block.oreCoal.blockID, 16); + this.ironGen = new WorldGenMinable(Block.oreIron.blockID, 8); + this.goldGen = new WorldGenMinable(Block.oreGold.blockID, 8); + this.redstoneGen = new WorldGenMinable(Block.oreRedstone.blockID, 7); + this.diamondGen = new WorldGenMinable(Block.oreDiamond.blockID, 7); + this.lapisGen = new WorldGenMinable(Block.oreLapis.blockID, 6); + this.plantYellowGen = new WorldGenFlowers(Block.plantYellow.blockID); + this.plantRedGen = new WorldGenFlowers(Block.plantRed.blockID); + this.mushroomBrownGen = new WorldGenFlowers(Block.mushroomBrown.blockID); + this.mushroomRedGen = new WorldGenFlowers(Block.mushroomRed.blockID); + this.bigMushroomGen = new WorldGenBigMushroom(); + this.reedGen = new WorldGenReed(); + this.cactusGen = new WorldGenCactus(); + this.waterlilyGen = new WorldGenWaterlily(); + this.waterlilyPerChunk = 0; + this.treesPerChunk = 0; + this.flowersPerChunk = 2; + this.grassPerChunk = 1; + this.deadBushPerChunk = 0; + this.mushroomsPerChunk = 0; + this.reedsPerChunk = 0; + this.cactiPerChunk = 0; + this.sandPerChunk = 1; + this.sandPerChunk2 = 3; + this.clayPerChunk = 1; + this.bigMushroomsPerChunk = 0; + this.generateLakes = true; + this.biome = par1BiomeGenBase; + } + + /** + * Decorates the world. Calls code that was formerly (pre-1.8) in + * ChunkProviderGenerate.populate + */ + public void decorate(World par1World, Random par2Random, int par3, int par4) { + if (this.currentWorld != null) { + throw new RuntimeException("Already decorating!!"); + } else { + this.currentWorld = par1World; + this.randomGenerator = par2Random; + this.chunk_X = par3; + this.chunk_Z = par4; + this.decorate(); + this.currentWorld = null; + this.randomGenerator = null; + } + } + + /** + * The method that does the work of actually decorating chunks + */ + protected void decorate() { + this.generateOres(); + int var1; + int var2; + int var3; + + for (var1 = 0; var1 < this.sandPerChunk2; ++var1) { + var2 = this.chunk_X + this.randomGenerator.nextInt(16) + 8; + var3 = this.chunk_Z + this.randomGenerator.nextInt(16) + 8; + this.sandGen.generate(this.currentWorld, this.randomGenerator, var2, + this.currentWorld.getTopSolidOrLiquidBlock(var2, var3), var3); + } + + for (var1 = 0; var1 < this.clayPerChunk; ++var1) { + var2 = this.chunk_X + this.randomGenerator.nextInt(16) + 8; + var3 = this.chunk_Z + this.randomGenerator.nextInt(16) + 8; + this.clayGen.generate(this.currentWorld, this.randomGenerator, var2, + this.currentWorld.getTopSolidOrLiquidBlock(var2, var3), var3); + } + + for (var1 = 0; var1 < this.sandPerChunk; ++var1) { + var2 = this.chunk_X + this.randomGenerator.nextInt(16) + 8; + var3 = this.chunk_Z + this.randomGenerator.nextInt(16) + 8; + this.sandGen.generate(this.currentWorld, this.randomGenerator, var2, + this.currentWorld.getTopSolidOrLiquidBlock(var2, var3), var3); + } + + var1 = this.treesPerChunk; + + if (this.randomGenerator.nextInt(10) == 0) { + ++var1; + } + + int var4; + + for (var2 = 0; var2 < var1; ++var2) { + var3 = this.chunk_X + this.randomGenerator.nextInt(16) + 8; + var4 = this.chunk_Z + this.randomGenerator.nextInt(16) + 8; + WorldGenerator var5 = this.biome.getRandomWorldGenForTrees(this.randomGenerator); + var5.setScale(1.0D, 1.0D, 1.0D); + var5.generate(this.currentWorld, this.randomGenerator, var3, this.currentWorld.getHeightValue(var3, var4), + var4); + } + + for (var2 = 0; var2 < this.bigMushroomsPerChunk; ++var2) { + var3 = this.chunk_X + this.randomGenerator.nextInt(16) + 8; + var4 = this.chunk_Z + this.randomGenerator.nextInt(16) + 8; + this.bigMushroomGen.generate(this.currentWorld, this.randomGenerator, var3, + this.currentWorld.getHeightValue(var3, var4), var4); + } + + int var7; + + for (var2 = 0; var2 < this.flowersPerChunk; ++var2) { + var3 = this.chunk_X + this.randomGenerator.nextInt(16) + 8; + var4 = this.randomGenerator.nextInt(128); + var7 = this.chunk_Z + this.randomGenerator.nextInt(16) + 8; + this.plantYellowGen.generate(this.currentWorld, this.randomGenerator, var3, var4, var7); + + if (this.randomGenerator.nextInt(4) == 0) { + var3 = this.chunk_X + this.randomGenerator.nextInt(16) + 8; + var4 = this.randomGenerator.nextInt(128); + var7 = this.chunk_Z + this.randomGenerator.nextInt(16) + 8; + this.plantRedGen.generate(this.currentWorld, this.randomGenerator, var3, var4, var7); + } + } + + for (var2 = 0; var2 < this.grassPerChunk; ++var2) { + var3 = this.chunk_X + this.randomGenerator.nextInt(16) + 8; + var4 = this.randomGenerator.nextInt(128); + var7 = this.chunk_Z + this.randomGenerator.nextInt(16) + 8; + WorldGenerator var6 = this.biome.getRandomWorldGenForGrass(this.randomGenerator); + var6.generate(this.currentWorld, this.randomGenerator, var3, var4, var7); + } + + for (var2 = 0; var2 < this.deadBushPerChunk; ++var2) { + var3 = this.chunk_X + this.randomGenerator.nextInt(16) + 8; + var4 = this.randomGenerator.nextInt(128); + var7 = this.chunk_Z + this.randomGenerator.nextInt(16) + 8; + (new WorldGenDeadBush(Block.deadBush.blockID)).generate(this.currentWorld, this.randomGenerator, var3, var4, + var7); + } + + for (var2 = 0; var2 < this.waterlilyPerChunk; ++var2) { + var3 = this.chunk_X + this.randomGenerator.nextInt(16) + 8; + var4 = this.chunk_Z + this.randomGenerator.nextInt(16) + 8; + + for (var7 = this.randomGenerator.nextInt(128); var7 > 0 + && this.currentWorld.getBlockId(var3, var7 - 1, var4) == 0; --var7) { + ; + } + + this.waterlilyGen.generate(this.currentWorld, this.randomGenerator, var3, var7, var4); + } + + for (var2 = 0; var2 < this.mushroomsPerChunk; ++var2) { + if (this.randomGenerator.nextInt(4) == 0) { + var3 = this.chunk_X + this.randomGenerator.nextInt(16) + 8; + var4 = this.chunk_Z + this.randomGenerator.nextInt(16) + 8; + var7 = this.currentWorld.getHeightValue(var3, var4); + this.mushroomBrownGen.generate(this.currentWorld, this.randomGenerator, var3, var7, var4); + } + + if (this.randomGenerator.nextInt(8) == 0) { + var3 = this.chunk_X + this.randomGenerator.nextInt(16) + 8; + var4 = this.chunk_Z + this.randomGenerator.nextInt(16) + 8; + var7 = this.randomGenerator.nextInt(128); + this.mushroomRedGen.generate(this.currentWorld, this.randomGenerator, var3, var7, var4); + } + } + + if (this.randomGenerator.nextInt(4) == 0) { + var2 = this.chunk_X + this.randomGenerator.nextInt(16) + 8; + var3 = this.randomGenerator.nextInt(128); + var4 = this.chunk_Z + this.randomGenerator.nextInt(16) + 8; + this.mushroomBrownGen.generate(this.currentWorld, this.randomGenerator, var2, var3, var4); + } + + if (this.randomGenerator.nextInt(8) == 0) { + var2 = this.chunk_X + this.randomGenerator.nextInt(16) + 8; + var3 = this.randomGenerator.nextInt(128); + var4 = this.chunk_Z + this.randomGenerator.nextInt(16) + 8; + this.mushroomRedGen.generate(this.currentWorld, this.randomGenerator, var2, var3, var4); + } + + for (var2 = 0; var2 < this.reedsPerChunk; ++var2) { + var3 = this.chunk_X + this.randomGenerator.nextInt(16) + 8; + var4 = this.chunk_Z + this.randomGenerator.nextInt(16) + 8; + var7 = this.randomGenerator.nextInt(128); + this.reedGen.generate(this.currentWorld, this.randomGenerator, var3, var7, var4); + } + + for (var2 = 0; var2 < 10; ++var2) { + var3 = this.chunk_X + this.randomGenerator.nextInt(16) + 8; + var4 = this.randomGenerator.nextInt(128); + var7 = this.chunk_Z + this.randomGenerator.nextInt(16) + 8; + this.reedGen.generate(this.currentWorld, this.randomGenerator, var3, var4, var7); + } + + if (this.randomGenerator.nextInt(32) == 0) { + var2 = this.chunk_X + this.randomGenerator.nextInt(16) + 8; + var3 = this.randomGenerator.nextInt(128); + var4 = this.chunk_Z + this.randomGenerator.nextInt(16) + 8; + (new WorldGenPumpkin()).generate(this.currentWorld, this.randomGenerator, var2, var3, var4); + } + + for (var2 = 0; var2 < this.cactiPerChunk; ++var2) { + var3 = this.chunk_X + this.randomGenerator.nextInt(16) + 8; + var4 = this.randomGenerator.nextInt(128); + var7 = this.chunk_Z + this.randomGenerator.nextInt(16) + 8; + this.cactusGen.generate(this.currentWorld, this.randomGenerator, var3, var4, var7); + } + + if (this.generateLakes) { + for (var2 = 0; var2 < 50; ++var2) { + var3 = this.chunk_X + this.randomGenerator.nextInt(16) + 8; + var4 = this.randomGenerator.nextInt(this.randomGenerator.nextInt(120) + 8); + var7 = this.chunk_Z + this.randomGenerator.nextInt(16) + 8; + (new WorldGenLiquids(Block.waterMoving.blockID)).generate(this.currentWorld, this.randomGenerator, var3, + var4, var7); + } + + for (var2 = 0; var2 < 20; ++var2) { + var3 = this.chunk_X + this.randomGenerator.nextInt(16) + 8; + var4 = this.randomGenerator + .nextInt(this.randomGenerator.nextInt(this.randomGenerator.nextInt(112) + 8) + 8); + var7 = this.chunk_Z + this.randomGenerator.nextInt(16) + 8; + (new WorldGenLiquids(Block.lavaMoving.blockID)).generate(this.currentWorld, this.randomGenerator, var3, + var4, var7); + } + } + } + + /** + * Standard ore generation helper. Generates most ores. + */ + protected void genStandardOre1(int par1, WorldGenerator par2WorldGenerator, int par3, int par4) { + for (int var5 = 0; var5 < par1; ++var5) { + int var6 = this.chunk_X + this.randomGenerator.nextInt(16); + int var7 = this.randomGenerator.nextInt(par4 - par3) + par3; + int var8 = this.chunk_Z + this.randomGenerator.nextInt(16); + par2WorldGenerator.generate(this.currentWorld, this.randomGenerator, var6, var7, var8); + } + } + + /** + * Standard ore generation helper. Generates Lapis Lazuli. + */ + protected void genStandardOre2(int par1, WorldGenerator par2WorldGenerator, int par3, int par4) { + for (int var5 = 0; var5 < par1; ++var5) { + int var6 = this.chunk_X + this.randomGenerator.nextInt(16); + int var7 = this.randomGenerator.nextInt(par4) + this.randomGenerator.nextInt(par4) + (par3 - par4); + int var8 = this.chunk_Z + this.randomGenerator.nextInt(16); + par2WorldGenerator.generate(this.currentWorld, this.randomGenerator, var6, var7, var8); + } + } + + /** + * Generates ores in the current chunk + */ + protected void generateOres() { + this.genStandardOre1(20, this.dirtGen, 0, 128); + this.genStandardOre1(10, this.gravelGen, 0, 128); + this.genStandardOre1(20, this.coalGen, 0, 128); + this.genStandardOre1(20, this.ironGen, 0, 64); + this.genStandardOre1(2, this.goldGen, 0, 32); + this.genStandardOre1(8, this.redstoneGen, 0, 16); + this.genStandardOre1(1, this.diamondGen, 0, 16); + this.genStandardOre2(1, this.lapisGen, 16, 16); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BiomeEndDecorator.java b/sp-server/src/main/java/net/minecraft/src/BiomeEndDecorator.java new file mode 100644 index 0000000..ad21990 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BiomeEndDecorator.java @@ -0,0 +1,35 @@ +package net.minecraft.src; + +public class BiomeEndDecorator extends BiomeDecorator { + protected WorldGenerator spikeGen; + + public BiomeEndDecorator(BiomeGenBase par1BiomeGenBase) { + super(par1BiomeGenBase); + this.spikeGen = new WorldGenSpikes(Block.whiteStone.blockID); + } + + /** + * The method that does the work of actually decorating chunks + */ + protected void decorate() { + this.generateOres(); + + if (this.randomGenerator.nextInt(5) == 0) { + int var1 = this.chunk_X + this.randomGenerator.nextInt(16) + 8; + int var2 = this.chunk_Z + this.randomGenerator.nextInt(16) + 8; + int var3 = this.currentWorld.getTopSolidOrLiquidBlock(var1, var2); + + if (var3 > 0) { + ; + } + + this.spikeGen.generate(this.currentWorld, this.randomGenerator, var1, var3, var2); + } + + if (this.chunk_X == 0 && this.chunk_Z == 0) { + EntityDragon var4 = new EntityDragon(this.currentWorld); + var4.setLocationAndAngles(0.0D, 128.0D, 0.0D, this.randomGenerator.nextFloat() * 360.0F, 0.0F); + this.currentWorld.spawnEntityInWorld(var4); + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BiomeGenBase.java b/sp-server/src/main/java/net/minecraft/src/BiomeGenBase.java new file mode 100644 index 0000000..507d1cc --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BiomeGenBase.java @@ -0,0 +1,318 @@ +package net.minecraft.src; + +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +public abstract class BiomeGenBase { + /** An array of all the biomes, indexed by biome id. */ + public static final BiomeGenBase[] biomeList = new BiomeGenBase[256]; + public static final BiomeGenBase ocean = (new BiomeGenOcean(0)).setColor(112).setBiomeName("Ocean") + .setMinMaxHeight(-1.0F, 0.4F); + public static final BiomeGenBase plains = (new BiomeGenPlains(1)).setColor(9286496).setBiomeName("Plains") + .setTemperatureRainfall(0.8F, 0.4F); + public static final BiomeGenBase desert = (new BiomeGenDesert(2)).setColor(16421912).setBiomeName("Desert") + .setDisableRain().setTemperatureRainfall(2.0F, 0.0F).setMinMaxHeight(0.1F, 0.2F); + public static final BiomeGenBase extremeHills = (new BiomeGenHills(3)).setColor(6316128) + .setBiomeName("Extreme Hills").setMinMaxHeight(0.3F, 1.5F).setTemperatureRainfall(0.2F, 0.3F); + public static final BiomeGenBase forest = (new BiomeGenForest(4)).setColor(353825).setBiomeName("Forest") + .func_76733_a(5159473).setTemperatureRainfall(0.7F, 0.8F); + public static final BiomeGenBase taiga = (new BiomeGenTaiga(5)).setColor(747097).setBiomeName("Taiga") + .func_76733_a(5159473).setEnableSnow().setTemperatureRainfall(0.05F, 0.8F).setMinMaxHeight(0.1F, 0.4F); + public static final BiomeGenBase swampland = (new BiomeGenSwamp(6)).setColor(522674).setBiomeName("Swampland") + .func_76733_a(9154376).setMinMaxHeight(-0.2F, 0.1F).setTemperatureRainfall(0.8F, 0.9F); + public static final BiomeGenBase river = (new BiomeGenRiver(7)).setColor(255).setBiomeName("River") + .setMinMaxHeight(-0.5F, 0.0F); + public static final BiomeGenBase hell = (new BiomeGenHell(8)).setColor(16711680).setBiomeName("Hell") + .setDisableRain().setTemperatureRainfall(2.0F, 0.0F); + + /** Is the biome used for sky world. */ + public static final BiomeGenBase sky = (new BiomeGenEnd(9)).setColor(8421631).setBiomeName("Sky").setDisableRain(); + public static final BiomeGenBase frozenOcean = (new BiomeGenOcean(10)).setColor(9474208).setBiomeName("FrozenOcean") + .setEnableSnow().setMinMaxHeight(-1.0F, 0.5F).setTemperatureRainfall(0.0F, 0.5F); + public static final BiomeGenBase frozenRiver = (new BiomeGenRiver(11)).setColor(10526975) + .setBiomeName("FrozenRiver").setEnableSnow().setMinMaxHeight(-0.5F, 0.0F) + .setTemperatureRainfall(0.0F, 0.5F); + public static final BiomeGenBase icePlains = (new BiomeGenSnow(12)).setColor(16777215).setBiomeName("Ice Plains") + .setEnableSnow().setTemperatureRainfall(0.0F, 0.5F); + public static final BiomeGenBase iceMountains = (new BiomeGenSnow(13)).setColor(10526880) + .setBiomeName("Ice Mountains").setEnableSnow().setMinMaxHeight(0.3F, 1.3F) + .setTemperatureRainfall(0.0F, 0.5F); + public static final BiomeGenBase mushroomIsland = (new BiomeGenMushroomIsland(14)).setColor(16711935) + .setBiomeName("MushroomIsland").setTemperatureRainfall(0.9F, 1.0F).setMinMaxHeight(0.2F, 1.0F); + public static final BiomeGenBase mushroomIslandShore = (new BiomeGenMushroomIsland(15)).setColor(10486015) + .setBiomeName("MushroomIslandShore").setTemperatureRainfall(0.9F, 1.0F).setMinMaxHeight(-1.0F, 0.1F); + + /** Beach biome. */ + public static final BiomeGenBase beach = (new BiomeGenBeach(16)).setColor(16440917).setBiomeName("Beach") + .setTemperatureRainfall(0.8F, 0.4F).setMinMaxHeight(0.0F, 0.1F); + + /** Desert Hills biome. */ + public static final BiomeGenBase desertHills = (new BiomeGenDesert(17)).setColor(13786898) + .setBiomeName("DesertHills").setDisableRain().setTemperatureRainfall(2.0F, 0.0F) + .setMinMaxHeight(0.3F, 0.8F); + + /** Forest Hills biome. */ + public static final BiomeGenBase forestHills = (new BiomeGenForest(18)).setColor(2250012) + .setBiomeName("ForestHills").func_76733_a(5159473).setTemperatureRainfall(0.7F, 0.8F) + .setMinMaxHeight(0.3F, 0.7F); + + /** Taiga Hills biome. */ + public static final BiomeGenBase taigaHills = (new BiomeGenTaiga(19)).setColor(1456435).setBiomeName("TaigaHills") + .setEnableSnow().func_76733_a(5159473).setTemperatureRainfall(0.05F, 0.8F).setMinMaxHeight(0.3F, 0.8F); + + /** Extreme Hills Edge biome. */ + public static final BiomeGenBase extremeHillsEdge = (new BiomeGenHills(20)).setColor(7501978) + .setBiomeName("Extreme Hills Edge").setMinMaxHeight(0.2F, 0.8F).setTemperatureRainfall(0.2F, 0.3F); + + /** Jungle biome identifier */ + public static final BiomeGenBase jungle = (new BiomeGenJungle(21)).setColor(5470985).setBiomeName("Jungle") + .func_76733_a(5470985).setTemperatureRainfall(1.2F, 0.9F).setMinMaxHeight(0.2F, 0.4F); + public static final BiomeGenBase jungleHills = (new BiomeGenJungle(22)).setColor(2900485) + .setBiomeName("JungleHills").func_76733_a(5470985).setTemperatureRainfall(1.2F, 0.9F) + .setMinMaxHeight(1.8F, 0.5F); + public String biomeName; + public int color; + + /** The block expected to be on the top of this biome */ + public byte topBlock; + + /** The block to fill spots in when not on the top */ + public byte fillerBlock; + public int field_76754_C; + + /** The minimum height of this biome. Default 0.1. */ + public float minHeight; + + /** The maximum height of this biome. Default 0.3. */ + public float maxHeight; + + /** The temperature of this biome. */ + public float temperature; + + /** The rainfall in this biome. */ + public float rainfall; + + /** Color tint applied to water depending on biome */ + public int waterColorMultiplier; + + /** The biome decorator. */ + public BiomeDecorator theBiomeDecorator; + + /** + * Holds the classes of IMobs (hostile mobs) that can be spawned in the biome. + */ + protected List spawnableMonsterList; + + /** + * Holds the classes of any creature that can be spawned in the biome as + * friendly creature. + */ + protected List spawnableCreatureList; + + /** + * Holds the classes of any aquatic creature that can be spawned in the water of + * the biome. + */ + protected List spawnableWaterCreatureList; + protected List spawnableCaveCreatureList; + + /** Set to true if snow is enabled for this biome. */ + private boolean enableSnow; + + /** + * Is true (default) if the biome support rain (desert and nether can't have + * rain) + */ + private boolean enableRain; + + /** The id number to this biome, and its index in the biomeList array. */ + public final int biomeID; + + /** The tree generator. */ + protected WorldGenTrees worldGeneratorTrees; + + /** The big tree generator. */ + protected WorldGenBigTree worldGeneratorBigTree; + + /** The forest generator. */ + protected WorldGenForest worldGeneratorForest; + + /** The swamp tree generator. */ + protected WorldGenSwamp worldGeneratorSwamp; + + protected BiomeGenBase(int par1) { + this.topBlock = (byte) Block.grass.blockID; + this.fillerBlock = (byte) Block.dirt.blockID; + this.field_76754_C = 5169201; + this.minHeight = 0.1F; + this.maxHeight = 0.3F; + this.temperature = 0.5F; + this.rainfall = 0.5F; + this.waterColorMultiplier = 16777215; + this.spawnableMonsterList = new ArrayList(); + this.spawnableCreatureList = new ArrayList(); + this.spawnableWaterCreatureList = new ArrayList(); + this.spawnableCaveCreatureList = new ArrayList(); + this.enableRain = true; + this.worldGeneratorTrees = new WorldGenTrees(false); + this.worldGeneratorBigTree = new WorldGenBigTree(false); + this.worldGeneratorForest = new WorldGenForest(false); + this.worldGeneratorSwamp = new WorldGenSwamp(); + this.biomeID = par1; + biomeList[par1] = this; + this.theBiomeDecorator = this.createBiomeDecorator(); + this.spawnableCreatureList.add(new SpawnListEntry(EntitySheep.class, 12, 4, 4)); + this.spawnableCreatureList.add(new SpawnListEntry(EntityPig.class, 10, 4, 4)); + this.spawnableCreatureList.add(new SpawnListEntry(EntityChicken.class, 10, 4, 4)); + this.spawnableCreatureList.add(new SpawnListEntry(EntityCow.class, 8, 4, 4)); + this.spawnableMonsterList.add(new SpawnListEntry(EntitySpider.class, 10, 4, 4)); + this.spawnableMonsterList.add(new SpawnListEntry(EntityZombie.class, 10, 4, 4)); + this.spawnableMonsterList.add(new SpawnListEntry(EntitySkeleton.class, 10, 4, 4)); + this.spawnableMonsterList.add(new SpawnListEntry(EntityCreeper.class, 10, 4, 4)); + this.spawnableMonsterList.add(new SpawnListEntry(EntitySlime.class, 10, 4, 4)); + this.spawnableMonsterList.add(new SpawnListEntry(EntityEnderman.class, 1, 1, 4)); + this.spawnableWaterCreatureList.add(new SpawnListEntry(EntitySquid.class, 10, 4, 4)); + this.spawnableCaveCreatureList.add(new SpawnListEntry(EntityBat.class, 10, 8, 8)); + } + + /** + * Allocate a new BiomeDecorator for this BiomeGenBase + */ + protected BiomeDecorator createBiomeDecorator() { + return new BiomeDecorator(this); + } + + /** + * Sets the temperature and rainfall of this biome. + */ + private BiomeGenBase setTemperatureRainfall(float par1, float par2) { + if (par1 > 0.1F && par1 < 0.2F) { + throw new IllegalArgumentException("Please avoid temperatures in the range 0.1 - 0.2 because of snow"); + } else { + this.temperature = par1; + this.rainfall = par2; + return this; + } + } + + /** + * Sets the minimum and maximum height of this biome. Seems to go from -2.0 to + * 2.0. + */ + private BiomeGenBase setMinMaxHeight(float par1, float par2) { + this.minHeight = par1; + this.maxHeight = par2; + return this; + } + + /** + * Disable the rain for the biome. + */ + private BiomeGenBase setDisableRain() { + this.enableRain = false; + return this; + } + + /** + * Gets a WorldGen appropriate for this biome. + */ + public WorldGenerator getRandomWorldGenForTrees(Random par1Random) { + return (WorldGenerator) (par1Random.nextInt(10) == 0 ? this.worldGeneratorBigTree : this.worldGeneratorTrees); + } + + /** + * Gets a WorldGen appropriate for this biome. + */ + public WorldGenerator getRandomWorldGenForGrass(Random par1Random) { + return new WorldGenTallGrass(Block.tallGrass.blockID, 1); + } + + /** + * sets enableSnow to true during biome initialization. returns BiomeGenBase. + */ + protected BiomeGenBase setEnableSnow() { + this.enableSnow = true; + return this; + } + + protected BiomeGenBase setBiomeName(String par1Str) { + this.biomeName = par1Str; + return this; + } + + protected BiomeGenBase func_76733_a(int par1) { + this.field_76754_C = par1; + return this; + } + + protected BiomeGenBase setColor(int par1) { + this.color = par1; + return this; + } + + /** + * Returns the correspondent list of the EnumCreatureType informed. + */ + public List getSpawnableList(EnumCreatureType par1EnumCreatureType) { + return par1EnumCreatureType == EnumCreatureType.monster ? this.spawnableMonsterList + : (par1EnumCreatureType == EnumCreatureType.creature ? this.spawnableCreatureList + : (par1EnumCreatureType == EnumCreatureType.waterCreature ? this.spawnableWaterCreatureList + : (par1EnumCreatureType == EnumCreatureType.ambient ? this.spawnableCaveCreatureList + : null))); + } + + /** + * Returns true if the biome have snowfall instead a normal rain. + */ + public boolean getEnableSnow() { + return this.enableSnow; + } + + /** + * Return true if the biome supports lightning bolt spawn, either by have the + * bolts enabled and have rain enabled. + */ + public boolean canSpawnLightningBolt() { + return this.enableSnow ? false : this.enableRain; + } + + /** + * Checks to see if the rainfall level of the biome is extremely high + */ + public boolean isHighHumidity() { + return this.rainfall > 0.85F; + } + + /** + * returns the chance a creature has to spawn. + */ + public float getSpawningChance() { + return 0.1F; + } + + /** + * Gets an integer representation of this biome's rainfall + */ + public final int getIntRainfall() { + return (int) (this.rainfall * 65536.0F); + } + + /** + * Gets an integer representation of this biome's temperature + */ + public final int getIntTemperature() { + return (int) (this.temperature * 65536.0F); + } + + /** + * Gets a floating point representation of this biome's temperature + */ + public final float getFloatTemperature() { + return this.temperature; + } + + public void decorate(World par1World, Random par2Random, int par3, int par4) { + this.theBiomeDecorator.decorate(par1World, par2Random, par3, par4); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BiomeGenBeach.java b/sp-server/src/main/java/net/minecraft/src/BiomeGenBeach.java new file mode 100644 index 0000000..7a53cfb --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BiomeGenBeach.java @@ -0,0 +1,14 @@ +package net.minecraft.src; + +public class BiomeGenBeach extends BiomeGenBase { + public BiomeGenBeach(int par1) { + super(par1); + this.spawnableCreatureList.clear(); + this.topBlock = (byte) Block.sand.blockID; + this.fillerBlock = (byte) Block.sand.blockID; + this.theBiomeDecorator.treesPerChunk = -999; + this.theBiomeDecorator.deadBushPerChunk = 0; + this.theBiomeDecorator.reedsPerChunk = 0; + this.theBiomeDecorator.cactiPerChunk = 0; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BiomeGenDesert.java b/sp-server/src/main/java/net/minecraft/src/BiomeGenDesert.java new file mode 100644 index 0000000..bcba73d --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BiomeGenDesert.java @@ -0,0 +1,27 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BiomeGenDesert extends BiomeGenBase { + public BiomeGenDesert(int par1) { + super(par1); + this.spawnableCreatureList.clear(); + this.topBlock = (byte) Block.sand.blockID; + this.fillerBlock = (byte) Block.sand.blockID; + this.theBiomeDecorator.treesPerChunk = -999; + this.theBiomeDecorator.deadBushPerChunk = 2; + this.theBiomeDecorator.reedsPerChunk = 50; + this.theBiomeDecorator.cactiPerChunk = 10; + } + + public void decorate(World par1World, Random par2Random, int par3, int par4) { + super.decorate(par1World, par2Random, par3, par4); + + if (par2Random.nextInt(1000) == 0) { + int var5 = par3 + par2Random.nextInt(16) + 8; + int var6 = par4 + par2Random.nextInt(16) + 8; + WorldGenDesertWells var7 = new WorldGenDesertWells(); + var7.generate(par1World, par2Random, var5, par1World.getHeightValue(var5, var6) + 1, var6); + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BiomeGenEnd.java b/sp-server/src/main/java/net/minecraft/src/BiomeGenEnd.java new file mode 100644 index 0000000..5bf4220 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BiomeGenEnd.java @@ -0,0 +1,15 @@ +package net.minecraft.src; + +public class BiomeGenEnd extends BiomeGenBase { + public BiomeGenEnd(int par1) { + super(par1); + this.spawnableMonsterList.clear(); + this.spawnableCreatureList.clear(); + this.spawnableWaterCreatureList.clear(); + this.spawnableCaveCreatureList.clear(); + this.spawnableMonsterList.add(new SpawnListEntry(EntityEnderman.class, 10, 4, 4)); + this.topBlock = (byte) Block.dirt.blockID; + this.fillerBlock = (byte) Block.dirt.blockID; + this.theBiomeDecorator = new BiomeEndDecorator(this); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BiomeGenForest.java b/sp-server/src/main/java/net/minecraft/src/BiomeGenForest.java new file mode 100644 index 0000000..bcf59a6 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BiomeGenForest.java @@ -0,0 +1,20 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BiomeGenForest extends BiomeGenBase { + public BiomeGenForest(int par1) { + super(par1); + this.spawnableCreatureList.add(new SpawnListEntry(EntityWolf.class, 5, 4, 4)); + this.theBiomeDecorator.treesPerChunk = 10; + this.theBiomeDecorator.grassPerChunk = 2; + } + + /** + * Gets a WorldGen appropriate for this biome. + */ + public WorldGenerator getRandomWorldGenForTrees(Random par1Random) { + return (WorldGenerator) (par1Random.nextInt(5) == 0 ? this.worldGeneratorForest + : (par1Random.nextInt(10) == 0 ? this.worldGeneratorBigTree : this.worldGeneratorTrees)); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BiomeGenHell.java b/sp-server/src/main/java/net/minecraft/src/BiomeGenHell.java new file mode 100644 index 0000000..f4c5874 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BiomeGenHell.java @@ -0,0 +1,14 @@ +package net.minecraft.src; + +public class BiomeGenHell extends BiomeGenBase { + public BiomeGenHell(int par1) { + super(par1); + this.spawnableMonsterList.clear(); + this.spawnableCreatureList.clear(); + this.spawnableWaterCreatureList.clear(); + this.spawnableCaveCreatureList.clear(); + this.spawnableMonsterList.add(new SpawnListEntry(EntityGhast.class, 50, 4, 4)); + this.spawnableMonsterList.add(new SpawnListEntry(EntityPigZombie.class, 100, 4, 4)); + this.spawnableMonsterList.add(new SpawnListEntry(EntityMagmaCube.class, 1, 4, 4)); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BiomeGenHills.java b/sp-server/src/main/java/net/minecraft/src/BiomeGenHills.java new file mode 100644 index 0000000..b8de504 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BiomeGenHills.java @@ -0,0 +1,38 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BiomeGenHills extends BiomeGenBase { + private WorldGenerator theWorldGenerator; + + protected BiomeGenHills(int par1) { + super(par1); + this.theWorldGenerator = new WorldGenMinable(Block.silverfish.blockID, 8); + } + + public void decorate(World par1World, Random par2Random, int par3, int par4) { + super.decorate(par1World, par2Random, par3, par4); + int var5 = 3 + par2Random.nextInt(6); + int var6; + int var7; + int var8; + + for (var6 = 0; var6 < var5; ++var6) { + var7 = par3 + par2Random.nextInt(16); + var8 = par2Random.nextInt(28) + 4; + int var9 = par4 + par2Random.nextInt(16); + int var10 = par1World.getBlockId(var7, var8, var9); + + if (var10 == Block.stone.blockID) { + par1World.setBlock(var7, var8, var9, Block.oreEmerald.blockID, 0, 2); + } + } + + for (var5 = 0; var5 < 7; ++var5) { + var6 = par3 + par2Random.nextInt(16); + var7 = par2Random.nextInt(64); + var8 = par4 + par2Random.nextInt(16); + this.theWorldGenerator.generate(par1World, par2Random, var6, var7, var8); + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BiomeGenJungle.java b/sp-server/src/main/java/net/minecraft/src/BiomeGenJungle.java new file mode 100644 index 0000000..49b98d2 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BiomeGenJungle.java @@ -0,0 +1,44 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BiomeGenJungle extends BiomeGenBase { + public BiomeGenJungle(int par1) { + super(par1); + this.theBiomeDecorator.treesPerChunk = 50; + this.theBiomeDecorator.grassPerChunk = 25; + this.theBiomeDecorator.flowersPerChunk = 4; + this.spawnableMonsterList.add(new SpawnListEntry(EntityOcelot.class, 2, 1, 1)); + this.spawnableCreatureList.add(new SpawnListEntry(EntityChicken.class, 10, 4, 4)); + } + + /** + * Gets a WorldGen appropriate for this biome. + */ + public WorldGenerator getRandomWorldGenForTrees(Random par1Random) { + return (WorldGenerator) (par1Random.nextInt(10) == 0 ? this.worldGeneratorBigTree + : (par1Random.nextInt(2) == 0 ? new WorldGenShrub(3, 0) + : (par1Random.nextInt(3) == 0 ? new WorldGenHugeTrees(false, 10 + par1Random.nextInt(20), 3, 3) + : new WorldGenTrees(false, 4 + par1Random.nextInt(7), 3, 3, true)))); + } + + /** + * Gets a WorldGen appropriate for this biome. + */ + public WorldGenerator getRandomWorldGenForGrass(Random par1Random) { + return par1Random.nextInt(4) == 0 ? new WorldGenTallGrass(Block.tallGrass.blockID, 2) + : new WorldGenTallGrass(Block.tallGrass.blockID, 1); + } + + public void decorate(World par1World, Random par2Random, int par3, int par4) { + super.decorate(par1World, par2Random, par3, par4); + WorldGenVines var5 = new WorldGenVines(); + + for (int var6 = 0; var6 < 50; ++var6) { + int var7 = par3 + par2Random.nextInt(16) + 8; + byte var8 = 64; + int var9 = par4 + par2Random.nextInt(16) + 8; + var5.generate(par1World, par2Random, var7, var8, var9); + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BiomeGenMushroomIsland.java b/sp-server/src/main/java/net/minecraft/src/BiomeGenMushroomIsland.java new file mode 100644 index 0000000..5918fae --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BiomeGenMushroomIsland.java @@ -0,0 +1,17 @@ +package net.minecraft.src; + +public class BiomeGenMushroomIsland extends BiomeGenBase { + public BiomeGenMushroomIsland(int par1) { + super(par1); + this.theBiomeDecorator.treesPerChunk = -100; + this.theBiomeDecorator.flowersPerChunk = -100; + this.theBiomeDecorator.grassPerChunk = -100; + this.theBiomeDecorator.mushroomsPerChunk = 1; + this.theBiomeDecorator.bigMushroomsPerChunk = 1; + this.topBlock = (byte) Block.mycelium.blockID; + this.spawnableMonsterList.clear(); + this.spawnableCreatureList.clear(); + this.spawnableWaterCreatureList.clear(); + this.spawnableCreatureList.add(new SpawnListEntry(EntityMooshroom.class, 8, 4, 8)); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BiomeGenOcean.java b/sp-server/src/main/java/net/minecraft/src/BiomeGenOcean.java new file mode 100644 index 0000000..01ac387 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BiomeGenOcean.java @@ -0,0 +1,8 @@ +package net.minecraft.src; + +public class BiomeGenOcean extends BiomeGenBase { + public BiomeGenOcean(int par1) { + super(par1); + this.spawnableCreatureList.clear(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BiomeGenPlains.java b/sp-server/src/main/java/net/minecraft/src/BiomeGenPlains.java new file mode 100644 index 0000000..36e649f --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BiomeGenPlains.java @@ -0,0 +1,10 @@ +package net.minecraft.src; + +public class BiomeGenPlains extends BiomeGenBase { + protected BiomeGenPlains(int par1) { + super(par1); + this.theBiomeDecorator.treesPerChunk = -999; + this.theBiomeDecorator.flowersPerChunk = 4; + this.theBiomeDecorator.grassPerChunk = 10; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BiomeGenRiver.java b/sp-server/src/main/java/net/minecraft/src/BiomeGenRiver.java new file mode 100644 index 0000000..19f823d --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BiomeGenRiver.java @@ -0,0 +1,8 @@ +package net.minecraft.src; + +public class BiomeGenRiver extends BiomeGenBase { + public BiomeGenRiver(int par1) { + super(par1); + this.spawnableCreatureList.clear(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BiomeGenSnow.java b/sp-server/src/main/java/net/minecraft/src/BiomeGenSnow.java new file mode 100644 index 0000000..1352017 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BiomeGenSnow.java @@ -0,0 +1,7 @@ +package net.minecraft.src; + +public class BiomeGenSnow extends BiomeGenBase { + public BiomeGenSnow(int par1) { + super(par1); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BiomeGenSwamp.java b/sp-server/src/main/java/net/minecraft/src/BiomeGenSwamp.java new file mode 100644 index 0000000..dd5a0f8 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BiomeGenSwamp.java @@ -0,0 +1,25 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BiomeGenSwamp extends BiomeGenBase { + protected BiomeGenSwamp(int par1) { + super(par1); + this.theBiomeDecorator.treesPerChunk = 2; + this.theBiomeDecorator.flowersPerChunk = -999; + this.theBiomeDecorator.deadBushPerChunk = 1; + this.theBiomeDecorator.mushroomsPerChunk = 8; + this.theBiomeDecorator.reedsPerChunk = 10; + this.theBiomeDecorator.clayPerChunk = 1; + this.theBiomeDecorator.waterlilyPerChunk = 4; + this.waterColorMultiplier = 14745518; + this.spawnableMonsterList.add(new SpawnListEntry(EntitySlime.class, 1, 1, 1)); + } + + /** + * Gets a WorldGen appropriate for this biome. + */ + public WorldGenerator getRandomWorldGenForTrees(Random par1Random) { + return this.worldGeneratorSwamp; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BiomeGenTaiga.java b/sp-server/src/main/java/net/minecraft/src/BiomeGenTaiga.java new file mode 100644 index 0000000..f89b7fb --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BiomeGenTaiga.java @@ -0,0 +1,19 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BiomeGenTaiga extends BiomeGenBase { + public BiomeGenTaiga(int par1) { + super(par1); + this.spawnableCreatureList.add(new SpawnListEntry(EntityWolf.class, 8, 4, 4)); + this.theBiomeDecorator.treesPerChunk = 10; + this.theBiomeDecorator.grassPerChunk = 1; + } + + /** + * Gets a WorldGen appropriate for this biome. + */ + public WorldGenerator getRandomWorldGenForTrees(Random par1Random) { + return (WorldGenerator) (par1Random.nextInt(3) == 0 ? new WorldGenTaiga1() : new WorldGenTaiga2(false)); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/Block.java b/sp-server/src/main/java/net/minecraft/src/Block.java new file mode 100644 index 0000000..4aabf1d --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/Block.java @@ -0,0 +1,1345 @@ +package net.minecraft.src; + +import java.util.List; +import java.util.Random; + +public class Block { + /** + * used as foreach item, if item.tab = current tab, display it on the screen + */ + private CreativeTabs displayOnCreativeTab; + public static final StepSound soundPowderFootstep = new StepSound("stone", 1.0F, 1.0F); + public static final StepSound soundWoodFootstep = new StepSound("wood", 1.0F, 1.0F); + public static final StepSound soundGravelFootstep = new StepSound("gravel", 1.0F, 1.0F); + public static final StepSound soundGrassFootstep = new StepSound("grass", 1.0F, 1.0F); + public static final StepSound soundStoneFootstep = new StepSound("stone", 1.0F, 1.0F); + public static final StepSound soundMetalFootstep = new StepSound("stone", 1.0F, 1.5F); + public static final StepSound soundGlassFootstep = new StepSoundStone("stone", 1.0F, 1.0F); + public static final StepSound soundClothFootstep = new StepSound("cloth", 1.0F, 1.0F); + public static final StepSound soundSandFootstep = new StepSound("sand", 1.0F, 1.0F); + public static final StepSound soundSnowFootstep = new StepSound("snow", 1.0F, 1.0F); + public static final StepSound soundLadderFootstep = new StepSoundSand("ladder", 1.0F, 1.0F); + public static final StepSound soundAnvilFootstep = new StepSoundAnvil("anvil", 0.3F, 1.0F); + + /** List of ly/ff (BlockType) containing the already registered blocks. */ + public static final Block[] blocksList = new Block[4096]; + + /** + * An array of 4096 booleans corresponding to the result of the isOpaqueCube() + * method for each block ID + */ + public static final boolean[] opaqueCubeLookup = new boolean[4096]; + + /** How much light is subtracted for going through this block */ + public static final int[] lightOpacity = new int[4096]; + + /** Array of booleans that tells if a block can grass */ + public static final boolean[] canBlockGrass = new boolean[4096]; + + /** Amount of light emitted */ + public static final int[] lightValue = new int[4096]; + + /** + * Flag if block ID should use the brightest neighbor light value as its own + */ + public static boolean[] useNeighborBrightness = new boolean[4096]; + public static final Block stone = (new BlockStone(1)).setHardness(1.5F).setResistance(10.0F) + .setStepSound(soundStoneFootstep).setUnlocalizedName("stone"); + public static final BlockGrass grass = (BlockGrass) (new BlockGrass(2)).setHardness(0.6F) + .setStepSound(soundGrassFootstep).setUnlocalizedName("grass"); + public static final Block dirt = (new BlockDirt(3)).setHardness(0.5F).setStepSound(soundGravelFootstep) + .setUnlocalizedName("dirt"); + public static final Block cobblestone = (new Block(4, Material.rock)).setHardness(2.0F).setResistance(10.0F) + .setStepSound(soundStoneFootstep).setUnlocalizedName("stonebrick").setCreativeTab(CreativeTabs.tabBlock); + public static final Block planks = (new BlockWood(5)).setHardness(2.0F).setResistance(5.0F) + .setStepSound(soundWoodFootstep).setUnlocalizedName("wood"); + public static final Block sapling = (new BlockSapling(6)).setHardness(0.0F).setStepSound(soundGrassFootstep) + .setUnlocalizedName("sapling"); + public static final Block bedrock = (new Block(7, Material.rock)).setBlockUnbreakable().setResistance(6000000.0F) + .setStepSound(soundStoneFootstep).setUnlocalizedName("bedrock").disableStats() + .setCreativeTab(CreativeTabs.tabBlock); + public static final BlockFluid waterMoving = (BlockFluid) (new BlockFlowing(8, Material.water)).setHardness(100.0F) + .setLightOpacity(3).setUnlocalizedName("water").disableStats(); + public static final Block waterStill = (new BlockStationary(9, Material.water)).setHardness(100.0F) + .setLightOpacity(3).setUnlocalizedName("water").disableStats(); + public static final BlockFluid lavaMoving = (BlockFluid) (new BlockFlowing(10, Material.lava)).setHardness(0.0F) + .setLightValue(1.0F).setUnlocalizedName("lava").disableStats(); + + /** Stationary lava source block */ + public static final Block lavaStill = (new BlockStationary(11, Material.lava)).setHardness(100.0F) + .setLightValue(1.0F).setUnlocalizedName("lava").disableStats(); + public static final Block sand = (new BlockSand(12)).setHardness(0.5F).setStepSound(soundSandFootstep) + .setUnlocalizedName("sand"); + public static final Block gravel = (new BlockGravel(13)).setHardness(0.6F).setStepSound(soundGravelFootstep) + .setUnlocalizedName("gravel"); + public static final Block oreGold = (new BlockOre(14)).setHardness(3.0F).setResistance(5.0F) + .setStepSound(soundStoneFootstep).setUnlocalizedName("oreGold"); + public static final Block oreIron = (new BlockOre(15)).setHardness(3.0F).setResistance(5.0F) + .setStepSound(soundStoneFootstep).setUnlocalizedName("oreIron"); + public static final Block oreCoal = (new BlockOre(16)).setHardness(3.0F).setResistance(5.0F) + .setStepSound(soundStoneFootstep).setUnlocalizedName("oreCoal"); + public static final Block wood = (new BlockLog(17)).setHardness(2.0F).setStepSound(soundWoodFootstep) + .setUnlocalizedName("log"); + public static final BlockLeaves leaves = (BlockLeaves) (new BlockLeaves(18)).setHardness(0.2F).setLightOpacity(1) + .setStepSound(soundGrassFootstep).setUnlocalizedName("leaves"); + public static final Block sponge = (new BlockSponge(19)).setHardness(0.6F).setStepSound(soundGrassFootstep) + .setUnlocalizedName("sponge"); + public static final Block glass = (new BlockGlass(20, Material.glass, false)).setHardness(0.3F) + .setStepSound(soundGlassFootstep).setUnlocalizedName("glass"); + public static final Block oreLapis = (new BlockOre(21)).setHardness(3.0F).setResistance(5.0F) + .setStepSound(soundStoneFootstep).setUnlocalizedName("oreLapis"); + public static final Block blockLapis = (new Block(22, Material.rock)).setHardness(3.0F).setResistance(5.0F) + .setStepSound(soundStoneFootstep).setUnlocalizedName("blockLapis").setCreativeTab(CreativeTabs.tabBlock); + public static final Block dispenser = (new BlockDispenser(23)).setHardness(3.5F).setStepSound(soundStoneFootstep) + .setUnlocalizedName("dispenser"); + public static final Block sandStone = (new BlockSandStone(24)).setStepSound(soundStoneFootstep).setHardness(0.8F) + .setUnlocalizedName("sandStone"); + public static final Block music = (new BlockNote(25)).setHardness(0.8F).setUnlocalizedName("musicBlock"); + public static final Block bed = (new BlockBed(26)).setHardness(0.2F).setUnlocalizedName("bed").disableStats(); + public static final Block railPowered = (new BlockRailPowered(27)).setHardness(0.7F) + .setStepSound(soundMetalFootstep).setUnlocalizedName("goldenRail"); + public static final Block railDetector = (new BlockDetectorRail(28)).setHardness(0.7F) + .setStepSound(soundMetalFootstep).setUnlocalizedName("detectorRail"); + public static final BlockPistonBase pistonStickyBase = (BlockPistonBase) (new BlockPistonBase(29, true)) + .setUnlocalizedName("pistonStickyBase"); + public static final Block web = (new BlockWeb(30)).setLightOpacity(1).setHardness(4.0F).setUnlocalizedName("web"); + public static final BlockTallGrass tallGrass = (BlockTallGrass) (new BlockTallGrass(31)).setHardness(0.0F) + .setStepSound(soundGrassFootstep).setUnlocalizedName("tallgrass"); + public static final BlockDeadBush deadBush = (BlockDeadBush) (new BlockDeadBush(32)).setHardness(0.0F) + .setStepSound(soundGrassFootstep).setUnlocalizedName("deadbush"); + public static final BlockPistonBase pistonBase = (BlockPistonBase) (new BlockPistonBase(33, false)) + .setUnlocalizedName("pistonBase"); + public static final BlockPistonExtension pistonExtension = new BlockPistonExtension(34); + public static final Block cloth = (new BlockCloth()).setHardness(0.8F).setStepSound(soundClothFootstep) + .setUnlocalizedName("cloth"); + public static final BlockPistonMoving pistonMoving = new BlockPistonMoving(36); + public static final BlockFlower plantYellow = (BlockFlower) (new BlockFlower(37)).setHardness(0.0F) + .setStepSound(soundGrassFootstep).setUnlocalizedName("flower"); + public static final BlockFlower plantRed = (BlockFlower) (new BlockFlower(38)).setHardness(0.0F) + .setStepSound(soundGrassFootstep).setUnlocalizedName("rose"); + public static final BlockFlower mushroomBrown = (BlockFlower) (new BlockMushroom(39, "mushroom_brown")) + .setHardness(0.0F).setStepSound(soundGrassFootstep).setLightValue(0.125F).setUnlocalizedName("mushroom"); + public static final BlockFlower mushroomRed = (BlockFlower) (new BlockMushroom(40, "mushroom_red")) + .setHardness(0.0F).setStepSound(soundGrassFootstep).setUnlocalizedName("mushroom"); + public static final Block blockGold = (new BlockOreStorage(41)).setHardness(3.0F).setResistance(10.0F) + .setStepSound(soundMetalFootstep).setUnlocalizedName("blockGold"); + public static final Block blockIron = (new BlockOreStorage(42)).setHardness(5.0F).setResistance(10.0F) + .setStepSound(soundMetalFootstep).setUnlocalizedName("blockIron"); + + /** stoneDoubleSlab */ + public static final BlockHalfSlab stoneDoubleSlab = (BlockHalfSlab) (new BlockStep(43, true)).setHardness(2.0F) + .setResistance(10.0F).setStepSound(soundStoneFootstep).setUnlocalizedName("stoneSlab"); + + /** stoneSingleSlab */ + public static final BlockHalfSlab stoneSingleSlab = (BlockHalfSlab) (new BlockStep(44, false)).setHardness(2.0F) + .setResistance(10.0F).setStepSound(soundStoneFootstep).setUnlocalizedName("stoneSlab"); + public static final Block brick = (new Block(45, Material.rock)).setHardness(2.0F).setResistance(10.0F) + .setStepSound(soundStoneFootstep).setUnlocalizedName("brick").setCreativeTab(CreativeTabs.tabBlock); + public static final Block tnt = (new BlockTNT(46)).setHardness(0.0F).setStepSound(soundGrassFootstep) + .setUnlocalizedName("tnt"); + public static final Block bookShelf = (new BlockBookshelf(47)).setHardness(1.5F).setStepSound(soundWoodFootstep) + .setUnlocalizedName("bookshelf"); + public static final Block cobblestoneMossy = (new Block(48, Material.rock)).setHardness(2.0F).setResistance(10.0F) + .setStepSound(soundStoneFootstep).setUnlocalizedName("stoneMoss").setCreativeTab(CreativeTabs.tabBlock); + public static final Block obsidian = (new BlockObsidian(49)).setHardness(50.0F).setResistance(2000.0F) + .setStepSound(soundStoneFootstep).setUnlocalizedName("obsidian"); + public static final Block torchWood = (new BlockTorch(50)).setHardness(0.0F).setLightValue(0.9375F) + .setStepSound(soundWoodFootstep).setUnlocalizedName("torch"); + public static final BlockFire fire = (BlockFire) (new BlockFire(51)).setHardness(0.0F).setLightValue(1.0F) + .setStepSound(soundWoodFootstep).setUnlocalizedName("fire").disableStats(); + public static final Block mobSpawner = (new BlockMobSpawner(52)).setHardness(5.0F).setStepSound(soundMetalFootstep) + .setUnlocalizedName("mobSpawner").disableStats(); + public static final Block stairsWoodOak = (new BlockStairs(53, planks, 0)).setUnlocalizedName("stairsWood"); + public static final BlockChest chest = (BlockChest) (new BlockChest(54, 0)).setHardness(2.5F) + .setStepSound(soundWoodFootstep).setUnlocalizedName("chest"); + public static final BlockRedstoneWire redstoneWire = (BlockRedstoneWire) (new BlockRedstoneWire(55)) + .setHardness(0.0F).setStepSound(soundPowderFootstep).setUnlocalizedName("redstoneDust").disableStats(); + public static final Block oreDiamond = (new BlockOre(56)).setHardness(3.0F).setResistance(5.0F) + .setStepSound(soundStoneFootstep).setUnlocalizedName("oreDiamond"); + public static final Block blockDiamond = (new BlockOreStorage(57)).setHardness(5.0F).setResistance(10.0F) + .setStepSound(soundMetalFootstep).setUnlocalizedName("blockDiamond"); + public static final Block workbench = (new BlockWorkbench(58)).setHardness(2.5F).setStepSound(soundWoodFootstep) + .setUnlocalizedName("workbench"); + public static final Block crops = (new BlockCrops(59)).setUnlocalizedName("crops"); + public static final Block tilledField = (new BlockFarmland(60)).setHardness(0.6F).setStepSound(soundGravelFootstep) + .setUnlocalizedName("farmland"); + public static final Block furnaceIdle = (new BlockFurnace(61, false)).setHardness(3.5F) + .setStepSound(soundStoneFootstep).setUnlocalizedName("furnace").setCreativeTab(CreativeTabs.tabDecorations); + public static final Block furnaceBurning = (new BlockFurnace(62, true)).setHardness(3.5F) + .setStepSound(soundStoneFootstep).setLightValue(0.875F).setUnlocalizedName("furnace"); + public static final Block signPost = (new BlockSign(63, TileEntitySign.class, true)).setHardness(1.0F) + .setStepSound(soundWoodFootstep).setUnlocalizedName("sign").disableStats(); + public static final Block doorWood = (new BlockDoor(64, Material.wood)).setHardness(3.0F) + .setStepSound(soundWoodFootstep).setUnlocalizedName("doorWood").disableStats(); + public static final Block ladder = (new BlockLadder(65)).setHardness(0.4F).setStepSound(soundLadderFootstep) + .setUnlocalizedName("ladder"); + public static final Block rail = (new BlockRail(66)).setHardness(0.7F).setStepSound(soundMetalFootstep) + .setUnlocalizedName("rail"); + public static final Block stairsCobblestone = (new BlockStairs(67, cobblestone, 0)) + .setUnlocalizedName("stairsStone"); + public static final Block signWall = (new BlockSign(68, TileEntitySign.class, false)).setHardness(1.0F) + .setStepSound(soundWoodFootstep).setUnlocalizedName("sign").disableStats(); + public static final Block lever = (new BlockLever(69)).setHardness(0.5F).setStepSound(soundWoodFootstep) + .setUnlocalizedName("lever"); + public static final Block pressurePlateStone = (new BlockPressurePlate(70, "stone", Material.rock, + EnumMobType.mobs)).setHardness(0.5F).setStepSound(soundStoneFootstep).setUnlocalizedName("pressurePlate"); + public static final Block doorIron = (new BlockDoor(71, Material.iron)).setHardness(5.0F) + .setStepSound(soundMetalFootstep).setUnlocalizedName("doorIron").disableStats(); + public static final Block pressurePlatePlanks = (new BlockPressurePlate(72, "wood", Material.wood, + EnumMobType.everything)).setHardness(0.5F).setStepSound(soundWoodFootstep) + .setUnlocalizedName("pressurePlate"); + public static final Block oreRedstone = (new BlockRedstoneOre(73, false)).setHardness(3.0F).setResistance(5.0F) + .setStepSound(soundStoneFootstep).setUnlocalizedName("oreRedstone").setCreativeTab(CreativeTabs.tabBlock); + public static final Block oreRedstoneGlowing = (new BlockRedstoneOre(74, true)).setLightValue(0.625F) + .setHardness(3.0F).setResistance(5.0F).setStepSound(soundStoneFootstep).setUnlocalizedName("oreRedstone"); + public static final Block torchRedstoneIdle = (new BlockRedstoneTorch(75, false)).setHardness(0.0F) + .setStepSound(soundWoodFootstep).setUnlocalizedName("notGate"); + public static final Block torchRedstoneActive = (new BlockRedstoneTorch(76, true)).setHardness(0.0F) + .setLightValue(0.5F).setStepSound(soundWoodFootstep).setUnlocalizedName("notGate") + .setCreativeTab(CreativeTabs.tabRedstone); + public static final Block stoneButton = (new BlockButtonStone(77)).setHardness(0.5F) + .setStepSound(soundStoneFootstep).setUnlocalizedName("button"); + public static final Block snow = (new BlockSnow(78)).setHardness(0.1F).setStepSound(soundSnowFootstep) + .setUnlocalizedName("snow").setLightOpacity(0); + public static final Block ice = (new BlockIce(79)).setHardness(0.5F).setLightOpacity(3) + .setStepSound(soundGlassFootstep).setUnlocalizedName("ice"); + public static final Block blockSnow = (new BlockSnowBlock(80)).setHardness(0.2F).setStepSound(soundSnowFootstep) + .setUnlocalizedName("snow"); + public static final Block cactus = (new BlockCactus(81)).setHardness(0.4F).setStepSound(soundClothFootstep) + .setUnlocalizedName("cactus"); + public static final Block blockClay = (new BlockClay(82)).setHardness(0.6F).setStepSound(soundGravelFootstep) + .setUnlocalizedName("clay"); + public static final Block reed = (new BlockReed(83)).setHardness(0.0F).setStepSound(soundGrassFootstep) + .setUnlocalizedName("reeds").disableStats(); + public static final Block jukebox = (new BlockJukeBox(84)).setHardness(2.0F).setResistance(10.0F) + .setStepSound(soundStoneFootstep).setUnlocalizedName("jukebox"); + public static final Block fence = (new BlockFence(85, "wood", Material.wood)).setHardness(2.0F).setResistance(5.0F) + .setStepSound(soundWoodFootstep).setUnlocalizedName("fence"); + public static final Block pumpkin = (new BlockPumpkin(86, false)).setHardness(1.0F).setStepSound(soundWoodFootstep) + .setUnlocalizedName("pumpkin"); + public static final Block netherrack = (new BlockNetherrack(87)).setHardness(0.4F).setStepSound(soundStoneFootstep) + .setUnlocalizedName("hellrock"); + public static final Block slowSand = (new BlockSoulSand(88)).setHardness(0.5F).setStepSound(soundSandFootstep) + .setUnlocalizedName("hellsand"); + public static final Block glowStone = (new BlockGlowStone(89, Material.glass)).setHardness(0.3F) + .setStepSound(soundGlassFootstep).setLightValue(1.0F).setUnlocalizedName("lightgem"); + + /** The purple teleport blocks inside the obsidian circle */ + public static final BlockPortal portal = (BlockPortal) (new BlockPortal(90)).setHardness(-1.0F) + .setStepSound(soundGlassFootstep).setLightValue(0.75F).setUnlocalizedName("portal"); + public static final Block pumpkinLantern = (new BlockPumpkin(91, true)).setHardness(1.0F) + .setStepSound(soundWoodFootstep).setLightValue(1.0F).setUnlocalizedName("litpumpkin"); + public static final Block cake = (new BlockCake(92)).setHardness(0.5F).setStepSound(soundClothFootstep) + .setUnlocalizedName("cake").disableStats(); + public static final BlockRedstoneRepeater redstoneRepeaterIdle = (BlockRedstoneRepeater) (new BlockRedstoneRepeater( + 93, false)).setHardness(0.0F).setStepSound(soundWoodFootstep).setUnlocalizedName("diode").disableStats(); + public static final BlockRedstoneRepeater redstoneRepeaterActive = (BlockRedstoneRepeater) (new BlockRedstoneRepeater( + 94, true)).setHardness(0.0F).setLightValue(0.625F).setStepSound(soundWoodFootstep) + .setUnlocalizedName("diode").disableStats(); + + /** + * April fools secret locked chest, only spawns on new chunks on 1st April. + */ + public static final Block lockedChest = (new BlockLockedChest(95)).setHardness(0.0F).setLightValue(1.0F) + .setStepSound(soundWoodFootstep).setUnlocalizedName("lockedchest").setTickRandomly(true); + public static final Block trapdoor = (new BlockTrapDoor(96, Material.wood)).setHardness(3.0F) + .setStepSound(soundWoodFootstep).setUnlocalizedName("trapdoor").disableStats(); + public static final Block silverfish = (new BlockSilverfish(97)).setHardness(0.75F) + .setUnlocalizedName("monsterStoneEgg"); + public static final Block stoneBrick = (new BlockStoneBrick(98)).setHardness(1.5F).setResistance(10.0F) + .setStepSound(soundStoneFootstep).setUnlocalizedName("stonebricksmooth"); + public static final Block mushroomCapBrown = (new BlockMushroomCap(99, Material.wood, 0)).setHardness(0.2F) + .setStepSound(soundWoodFootstep).setUnlocalizedName("mushroom"); + public static final Block mushroomCapRed = (new BlockMushroomCap(100, Material.wood, 1)).setHardness(0.2F) + .setStepSound(soundWoodFootstep).setUnlocalizedName("mushroom"); + public static final Block fenceIron = (new BlockPane(101, "fenceIron", "fenceIron", Material.iron, true)) + .setHardness(5.0F).setResistance(10.0F).setStepSound(soundMetalFootstep).setUnlocalizedName("fenceIron"); + public static final Block thinGlass = (new BlockPane(102, "glass", "thinglass_top", Material.glass, false)) + .setHardness(0.3F).setStepSound(soundGlassFootstep).setUnlocalizedName("thinGlass"); + public static final Block melon = (new BlockMelon(103)).setHardness(1.0F).setStepSound(soundWoodFootstep) + .setUnlocalizedName("melon"); + public static final Block pumpkinStem = (new BlockStem(104, pumpkin)).setHardness(0.0F) + .setStepSound(soundWoodFootstep).setUnlocalizedName("pumpkinStem"); + public static final Block melonStem = (new BlockStem(105, melon)).setHardness(0.0F).setStepSound(soundWoodFootstep) + .setUnlocalizedName("pumpkinStem"); + public static final Block vine = (new BlockVine(106)).setHardness(0.2F).setStepSound(soundGrassFootstep) + .setUnlocalizedName("vine"); + public static final Block fenceGate = (new BlockFenceGate(107)).setHardness(2.0F).setResistance(5.0F) + .setStepSound(soundWoodFootstep).setUnlocalizedName("fenceGate"); + public static final Block stairsBrick = (new BlockStairs(108, brick, 0)).setUnlocalizedName("stairsBrick"); + public static final Block stairsStoneBrick = (new BlockStairs(109, stoneBrick, 0)) + .setUnlocalizedName("stairsStoneBrickSmooth"); + public static final BlockMycelium mycelium = (BlockMycelium) (new BlockMycelium(110)).setHardness(0.6F) + .setStepSound(soundGrassFootstep).setUnlocalizedName("mycel"); + public static final Block waterlily = (new BlockLilyPad(111)).setHardness(0.0F).setStepSound(soundGrassFootstep) + .setUnlocalizedName("waterlily"); + public static final Block netherBrick = (new Block(112, Material.rock)).setHardness(2.0F).setResistance(10.0F) + .setStepSound(soundStoneFootstep).setUnlocalizedName("netherBrick").setCreativeTab(CreativeTabs.tabBlock); + public static final Block netherFence = (new BlockFence(113, "netherBrick", Material.rock)).setHardness(2.0F) + .setResistance(10.0F).setStepSound(soundStoneFootstep).setUnlocalizedName("netherFence"); + public static final Block stairsNetherBrick = (new BlockStairs(114, netherBrick, 0)) + .setUnlocalizedName("stairsNetherBrick"); + public static final Block netherStalk = (new BlockNetherStalk(115)).setUnlocalizedName("netherStalk"); + public static final Block enchantmentTable = (new BlockEnchantmentTable(116)).setHardness(5.0F) + .setResistance(2000.0F).setUnlocalizedName("enchantmentTable"); + public static final Block brewingStand = (new BlockBrewingStand(117)).setHardness(0.5F).setLightValue(0.125F) + .setUnlocalizedName("brewingStand"); + public static final BlockCauldron cauldron = (BlockCauldron) (new BlockCauldron(118)).setHardness(2.0F) + .setUnlocalizedName("cauldron"); + public static final Block endPortal = (new BlockEndPortal(119, Material.portal)).setHardness(-1.0F) + .setResistance(6000000.0F); + public static final Block endPortalFrame = (new BlockEndPortalFrame(120)).setStepSound(soundGlassFootstep) + .setLightValue(0.125F).setHardness(-1.0F).setUnlocalizedName("endPortalFrame").setResistance(6000000.0F) + .setCreativeTab(CreativeTabs.tabDecorations); + public static final Block whiteStone = (new Block(121, Material.rock)).setHardness(3.0F).setResistance(15.0F) + .setStepSound(soundStoneFootstep).setUnlocalizedName("whiteStone").setCreativeTab(CreativeTabs.tabBlock); + public static final Block dragonEgg = (new BlockDragonEgg(122)).setHardness(3.0F).setResistance(15.0F) + .setStepSound(soundStoneFootstep).setLightValue(0.125F).setUnlocalizedName("dragonEgg"); + public static final Block redstoneLampIdle = (new BlockRedstoneLight(123, false)).setHardness(0.3F) + .setStepSound(soundGlassFootstep).setUnlocalizedName("redstoneLight") + .setCreativeTab(CreativeTabs.tabRedstone); + public static final Block redstoneLampActive = (new BlockRedstoneLight(124, true)).setHardness(0.3F) + .setStepSound(soundGlassFootstep).setUnlocalizedName("redstoneLight"); + public static final BlockHalfSlab woodDoubleSlab = (BlockHalfSlab) (new BlockWoodSlab(125, true)).setHardness(2.0F) + .setResistance(5.0F).setStepSound(soundWoodFootstep).setUnlocalizedName("woodSlab"); + public static final BlockHalfSlab woodSingleSlab = (BlockHalfSlab) (new BlockWoodSlab(126, false)).setHardness(2.0F) + .setResistance(5.0F).setStepSound(soundWoodFootstep).setUnlocalizedName("woodSlab"); + public static final Block cocoaPlant = (new BlockCocoa(127)).setHardness(0.2F).setResistance(5.0F) + .setStepSound(soundWoodFootstep).setUnlocalizedName("cocoa"); + public static final Block stairsSandStone = (new BlockStairs(128, sandStone, 0)) + .setUnlocalizedName("stairsSandStone"); + public static final Block oreEmerald = (new BlockOre(129)).setHardness(3.0F).setResistance(5.0F) + .setStepSound(soundStoneFootstep).setUnlocalizedName("oreEmerald"); + public static final Block enderChest = (new BlockEnderChest(130)).setHardness(22.5F).setResistance(1000.0F) + .setStepSound(soundStoneFootstep).setUnlocalizedName("enderChest").setLightValue(0.5F); + public static final BlockTripWireSource tripWireSource = (BlockTripWireSource) (new BlockTripWireSource(131)) + .setUnlocalizedName("tripWireSource"); + public static final Block tripWire = (new BlockTripWire(132)).setUnlocalizedName("tripWire"); + public static final Block blockEmerald = (new BlockOreStorage(133)).setHardness(5.0F).setResistance(10.0F) + .setStepSound(soundMetalFootstep).setUnlocalizedName("blockEmerald"); + public static final Block stairsWoodSpruce = (new BlockStairs(134, planks, 1)) + .setUnlocalizedName("stairsWoodSpruce"); + public static final Block stairsWoodBirch = (new BlockStairs(135, planks, 2)).setUnlocalizedName("stairsWoodBirch"); + public static final Block stairsWoodJungle = (new BlockStairs(136, planks, 3)) + .setUnlocalizedName("stairsWoodJungle"); + public static final Block commandBlock = (new BlockCommandBlock(137)).setUnlocalizedName("commandBlock"); + public static final BlockBeacon beacon = (BlockBeacon) (new BlockBeacon(138)).setUnlocalizedName("beacon") + .setLightValue(1.0F); + public static final Block cobblestoneWall = (new BlockWall(139, cobblestone)).setUnlocalizedName("cobbleWall"); + public static final Block flowerPot = (new BlockFlowerPot(140)).setHardness(0.0F).setStepSound(soundPowderFootstep) + .setUnlocalizedName("flowerPot"); + public static final Block carrot = (new BlockCarrot(141)).setUnlocalizedName("carrots"); + public static final Block potato = (new BlockPotato(142)).setUnlocalizedName("potatoes"); + public static final Block woodenButton = (new BlockButtonWood(143)).setHardness(0.5F) + .setStepSound(soundWoodFootstep).setUnlocalizedName("button"); + public static final Block skull = (new BlockSkull(144)).setHardness(1.0F).setStepSound(soundStoneFootstep) + .setUnlocalizedName("skull"); + public static final Block anvil = (new BlockAnvil(145)).setHardness(5.0F).setStepSound(soundAnvilFootstep) + .setResistance(2000.0F).setUnlocalizedName("anvil"); + public static final Block chestTrapped = (new BlockChest(146, 1)).setHardness(2.5F).setStepSound(soundWoodFootstep) + .setUnlocalizedName("chestTrap"); + public static final Block pressurePlateGold = (new BlockPressurePlateWeighted(147, "blockGold", Material.iron, 64)) + .setHardness(0.5F).setStepSound(soundWoodFootstep).setUnlocalizedName("weightedPlate_light"); + public static final Block pressurePlateIron = (new BlockPressurePlateWeighted(148, "blockIron", Material.iron, 640)) + .setHardness(0.5F).setStepSound(soundWoodFootstep).setUnlocalizedName("weightedPlate_heavy"); + public static final BlockComparator redstoneComparatorIdle = (BlockComparator) (new BlockComparator(149, false)) + .setHardness(0.0F).setStepSound(soundWoodFootstep).setUnlocalizedName("comparator").disableStats(); + public static final BlockComparator redstoneComparatorActive = (BlockComparator) (new BlockComparator(150, true)) + .setHardness(0.0F).setLightValue(0.625F).setStepSound(soundWoodFootstep).setUnlocalizedName("comparator") + .disableStats(); + public static final BlockDaylightDetector daylightSensor = (BlockDaylightDetector) (new BlockDaylightDetector(151)) + .setHardness(0.2F).setStepSound(soundWoodFootstep).setUnlocalizedName("daylightDetector"); + public static final Block blockRedstone = (new BlockPoweredOre(152)).setHardness(5.0F).setResistance(10.0F) + .setStepSound(soundMetalFootstep).setUnlocalizedName("blockRedstone"); + public static final Block oreNetherQuartz = (new BlockOre(153)).setHardness(3.0F).setResistance(5.0F) + .setStepSound(soundStoneFootstep).setUnlocalizedName("netherquartz"); + public static final BlockHopper hopperBlock = (BlockHopper) (new BlockHopper(154)).setHardness(3.0F) + .setResistance(8.0F).setStepSound(soundWoodFootstep).setUnlocalizedName("hopper"); + public static final Block blockNetherQuartz = (new BlockQuartz(155)).setStepSound(soundStoneFootstep) + .setHardness(0.8F).setUnlocalizedName("quartzBlock"); + public static final Block stairsNetherQuartz = (new BlockStairs(156, blockNetherQuartz, 0)) + .setUnlocalizedName("stairsQuartz"); + public static final Block railActivator = (new BlockRailPowered(157)).setHardness(0.7F) + .setStepSound(soundMetalFootstep).setUnlocalizedName("activatorRail"); + public static final Block dropper = (new BlockDropper(158)).setHardness(3.5F).setStepSound(soundStoneFootstep) + .setUnlocalizedName("dropper"); + + /** ID of the block. */ + public final int blockID; + + /** Indicates how many hits it takes to break a block. */ + protected float blockHardness; + + /** Indicates the blocks resistance to explosions. */ + protected float blockResistance; + + /** + * set to true when Block's constructor is called through the chain of + * super()'s. Note: Never used + */ + protected boolean blockConstructorCalled = true; + + /** + * If this field is true, the block is counted for statistics (mined or placed) + */ + protected boolean enableStats = true; + + /** + * Flags whether or not this block is of a type that needs random ticking. + * Ref-counted by ExtendedBlockStorage in order to broadly cull a chunk from the + * random chunk update list for efficiency's sake. + */ + protected boolean needsRandomTick; + + /** true if the Block contains a Tile Entity */ + protected boolean isBlockContainer; + + /** minimum X for the block bounds (local coordinates) */ + protected double minX; + + /** minimum Y for the block bounds (local coordinates) */ + protected double minY; + + /** minimum Z for the block bounds (local coordinates) */ + protected double minZ; + + /** maximum X for the block bounds (local coordinates) */ + protected double maxX; + + /** maximum Y for the block bounds (local coordinates) */ + protected double maxY; + + /** maximum Z for the block bounds (local coordinates) */ + protected double maxZ; + + /** Sound of stepping on the block */ + public StepSound stepSound; + public float blockParticleGravity; + + /** Block material definition. */ + public final Material blockMaterial; + + /** + * Determines how much velocity is maintained while moving on top of this block + */ + public float slipperiness; + + /** The unlocalized name of this block. */ + private String unlocalizedName; + + protected Block(int par1, Material par2Material) { + this.stepSound = soundPowderFootstep; + this.blockParticleGravity = 1.0F; + this.slipperiness = 0.6F; + + if (blocksList[par1] != null) { + throw new IllegalArgumentException( + "Slot " + par1 + " is already occupied by " + blocksList[par1] + " when adding " + this); + } else { + this.blockMaterial = par2Material; + blocksList[par1] = this; + this.blockID = par1; + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + opaqueCubeLookup[par1] = this.isOpaqueCube(); + lightOpacity[par1] = this.isOpaqueCube() ? 255 : 0; + canBlockGrass[par1] = !par2Material.getCanBlockGrass(); + } + } + + /** + * This method is called on a block after all other blocks gets already created. + * You can use it to reference and configure something on the block that needs + * the others ones. + */ + protected void initializeBlock() { + } + + /** + * Sets the footstep sound for the block. Returns the object for convenience in + * constructing. + */ + protected Block setStepSound(StepSound par1StepSound) { + this.stepSound = par1StepSound; + return this; + } + + /** + * Sets how much light is blocked going through this block. Returns the object + * for convenience in constructing. + */ + protected Block setLightOpacity(int par1) { + lightOpacity[this.blockID] = par1; + return this; + } + + /** + * Sets the amount of light emitted by a block from 0.0f to 1.0f (converts + * internally to 0-15). Returns the object for convenience in constructing. + */ + protected Block setLightValue(float par1) { + lightValue[this.blockID] = (int) (15.0F * par1); + return this; + } + + /** + * Sets the the blocks resistance to explosions. Returns the object for + * convenience in constructing. + */ + protected Block setResistance(float par1) { + this.blockResistance = par1 * 3.0F; + return this; + } + + public static boolean isNormalCube(int par0) { + Block var1 = blocksList[par0]; + return var1 == null ? false + : var1.blockMaterial.isOpaque() && var1.renderAsNormalBlock() && !var1.canProvidePower(); + } + + /** + * If this block doesn't render as an ordinary block it will return False + * (examples: signs, buttons, stairs, etc) + */ + public boolean renderAsNormalBlock() { + return true; + } + + public boolean getBlocksMovement(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + return !this.blockMaterial.blocksMovement(); + } + + /** + * The type of render function that is called for this block + */ + public int getRenderType() { + return 0; + } + + /** + * Sets how many hits it takes to break a block. + */ + protected Block setHardness(float par1) { + this.blockHardness = par1; + + if (this.blockResistance < par1 * 5.0F) { + this.blockResistance = par1 * 5.0F; + } + + return this; + } + + /** + * This method will make the hardness of the block equals to -1, and the block + * is indestructible. + */ + protected Block setBlockUnbreakable() { + this.setHardness(-1.0F); + return this; + } + + /** + * Returns the block hardness at a location. Args: world, x, y, z + */ + public float getBlockHardness(World par1World, int par2, int par3, int par4) { + return this.blockHardness; + } + + /** + * Sets whether this block type will receive random update ticks + */ + protected Block setTickRandomly(boolean par1) { + this.needsRandomTick = par1; + return this; + } + + /** + * Returns whether or not this block is of a type that needs random ticking. + * Called for ref-counting purposes by ExtendedBlockStorage in order to broadly + * cull a chunk from the random chunk update list for efficiency's sake. + */ + public boolean getTickRandomly() { + return this.needsRandomTick; + } + + public boolean hasTileEntity() { + return this.isBlockContainer; + } + + /** + * Sets the bounds of the block. minX, minY, minZ, maxX, maxY, maxZ + */ + protected final void setBlockBounds(float par1, float par2, float par3, float par4, float par5, float par6) { + this.minX = (double) par1; + this.minY = (double) par2; + this.minZ = (double) par3; + this.maxX = (double) par4; + this.maxY = (double) par5; + this.maxZ = (double) par6; + } + + /** + * Returns Returns true if the given side of this block type should be rendered + * (if it's solid or not), if the adjacent block is at the given coordinates. + * Args: blockAccess, x, y, z, side + */ + public boolean isBlockSolid(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5) { + return par1IBlockAccess.getBlockMaterial(par2, par3, par4).isSolid(); + } + + /** + * Adds all intersecting collision boxes to a list. (Be sure to only add boxes + * to the list if they intersect the mask.) Parameters: World, X, Y, Z, mask, + * list, colliding entity + */ + public void addCollisionBoxesToList(World par1World, int par2, int par3, int par4, AxisAlignedBB par5AxisAlignedBB, + List par6List, Entity par7Entity) { + AxisAlignedBB var8 = this.getCollisionBoundingBoxFromPool(par1World, par2, par3, par4); + + if (var8 != null && par5AxisAlignedBB.intersectsWith(var8)) { + par6List.add(var8); + } + } + + /** + * Returns a bounding box from the pool of bounding boxes (this means this box + * can change after the pool has been cleared to be reused) + */ + public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int par4) { + return AxisAlignedBB.getAABBPool().getAABB((double) par2 + this.minX, (double) par3 + this.minY, + (double) par4 + this.minZ, (double) par2 + this.maxX, (double) par3 + this.maxY, + (double) par4 + this.maxZ); + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return true; + } + + /** + * Returns whether this block is collideable based on the arguments passed in + * Args: blockMetaData, unknownFlag + */ + public boolean canCollideCheck(int par1, boolean par2) { + return this.isCollidable(); + } + + /** + * Returns if this block is collidable (only used by Fire). Args: x, y, z + */ + public boolean isCollidable() { + return true; + } + + /** + * Ticks the block if it's been scheduled + */ + public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random) { + } + + /** + * Called right before the block is destroyed by a player. Args: world, x, y, z, + * metaData + */ + public void onBlockDestroyedByPlayer(World par1World, int par2, int par3, int par4, int par5) { + } + + /** + * Lets the block know when one of its neighbor changes. Doesn't know which + * neighbor changed (coordinates passed are their own) Args: x, y, z, neighbor + * blockID + */ + public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5) { + } + + /** + * How many world ticks before ticking + */ + public int tickRate(World par1World) { + return 10; + } + + /** + * Called whenever the block is added into the world. Args: world, x, y, z + */ + public void onBlockAdded(World par1World, int par2, int par3, int par4) { + } + + /** + * ejects contained items into the world, and notifies neighbours of an update, + * as appropriate + */ + public void breakBlock(World par1World, int par2, int par3, int par4, int par5, int par6) { + } + + /** + * Returns the quantity of items to drop on block destruction. + */ + public int quantityDropped(Random par1Random) { + return 1; + } + + /** + * Returns the ID of the items to drop on destruction. + */ + public int idDropped(int par1, Random par2Random, int par3) { + return this.blockID; + } + + /** + * Gets the hardness of block at the given coordinates in the given world, + * relative to the ability of the given EntityPlayer. + */ + public float getPlayerRelativeBlockHardness(EntityPlayer par1EntityPlayer, World par2World, int par3, int par4, + int par5) { + float var6 = this.getBlockHardness(par2World, par3, par4, par5); + return var6 < 0.0F ? 0.0F + : (!par1EntityPlayer.canHarvestBlock(this) + ? par1EntityPlayer.getCurrentPlayerStrVsBlock(this, false) / var6 / 100.0F + : par1EntityPlayer.getCurrentPlayerStrVsBlock(this, true) / var6 / 30.0F); + } + + /** + * Drops the specified block items + */ + public final void dropBlockAsItem(World par1World, int par2, int par3, int par4, int par5, int par6) { + this.dropBlockAsItemWithChance(par1World, par2, par3, par4, par5, 1.0F, par6); + } + + /** + * Drops the block items with a specified chance of dropping the specified items + */ + public void dropBlockAsItemWithChance(World par1World, int par2, int par3, int par4, int par5, float par6, + int par7) { + if (!par1World.isRemote) { + int var8 = this.quantityDroppedWithBonus(par7, par1World.rand); + + for (int var9 = 0; var9 < var8; ++var9) { + if (par1World.rand.nextFloat() <= par6) { + int var10 = this.idDropped(par5, par1World.rand, par7); + + if (var10 > 0) { + this.dropBlockAsItem_do(par1World, par2, par3, par4, + new ItemStack(var10, 1, this.damageDropped(par5))); + } + } + } + } + } + + /** + * Spawns EntityItem in the world for the given ItemStack if the world is not + * remote. + */ + protected void dropBlockAsItem_do(World par1World, int par2, int par3, int par4, ItemStack par5ItemStack) { + if (!par1World.isRemote && par1World.getGameRules().getGameRuleBooleanValue("doTileDrops")) { + float var6 = 0.7F; + double var7 = (double) (par1World.rand.nextFloat() * var6) + (double) (1.0F - var6) * 0.5D; + double var9 = (double) (par1World.rand.nextFloat() * var6) + (double) (1.0F - var6) * 0.5D; + double var11 = (double) (par1World.rand.nextFloat() * var6) + (double) (1.0F - var6) * 0.5D; + EntityItem var13 = new EntityItem(par1World, (double) par2 + var7, (double) par3 + var9, + (double) par4 + var11, par5ItemStack); + var13.delayBeforeCanPickup = 10; + par1World.spawnEntityInWorld(var13); + } + } + + /** + * called by spawner, ore, redstoneOre blocks + */ + protected void dropXpOnBlockBreak(World par1World, int par2, int par3, int par4, int par5) { + if (!par1World.isRemote) { + while (par5 > 0) { + int var6 = EntityXPOrb.getXPSplit(par5); + par5 -= var6; + par1World.spawnEntityInWorld(new EntityXPOrb(par1World, (double) par2 + 0.5D, (double) par3 + 0.5D, + (double) par4 + 0.5D, var6)); + } + } + } + + /** + * Determines the damage on the item the block drops. Used in cloth and wood. + */ + public int damageDropped(int par1) { + return 0; + } + + /** + * Returns how much this block can resist explosions from the passed in entity. + */ + public float getExplosionResistance(Entity par1Entity) { + return this.blockResistance / 5.0F; + } + + /** + * Ray traces through the blocks collision from start vector to end vector + * returning a ray trace hit. Args: world, x, y, z, startVec, endVec + */ + public MovingObjectPosition collisionRayTrace(World par1World, int par2, int par3, int par4, Vec3 par5Vec3, + Vec3 par6Vec3) { + this.setBlockBoundsBasedOnState(par1World, par2, par3, par4); + par5Vec3 = par5Vec3.addVector((double) (-par2), (double) (-par3), (double) (-par4)); + par6Vec3 = par6Vec3.addVector((double) (-par2), (double) (-par3), (double) (-par4)); + Vec3 var7 = par5Vec3.getIntermediateWithXValue(par6Vec3, this.minX); + Vec3 var8 = par5Vec3.getIntermediateWithXValue(par6Vec3, this.maxX); + Vec3 var9 = par5Vec3.getIntermediateWithYValue(par6Vec3, this.minY); + Vec3 var10 = par5Vec3.getIntermediateWithYValue(par6Vec3, this.maxY); + Vec3 var11 = par5Vec3.getIntermediateWithZValue(par6Vec3, this.minZ); + Vec3 var12 = par5Vec3.getIntermediateWithZValue(par6Vec3, this.maxZ); + + if (!this.isVecInsideYZBounds(var7)) { + var7 = null; + } + + if (!this.isVecInsideYZBounds(var8)) { + var8 = null; + } + + if (!this.isVecInsideXZBounds(var9)) { + var9 = null; + } + + if (!this.isVecInsideXZBounds(var10)) { + var10 = null; + } + + if (!this.isVecInsideXYBounds(var11)) { + var11 = null; + } + + if (!this.isVecInsideXYBounds(var12)) { + var12 = null; + } + + Vec3 var13 = null; + + if (var7 != null && (var13 == null || par5Vec3.squareDistanceTo(var7) < par5Vec3.squareDistanceTo(var13))) { + var13 = var7; + } + + if (var8 != null && (var13 == null || par5Vec3.squareDistanceTo(var8) < par5Vec3.squareDistanceTo(var13))) { + var13 = var8; + } + + if (var9 != null && (var13 == null || par5Vec3.squareDistanceTo(var9) < par5Vec3.squareDistanceTo(var13))) { + var13 = var9; + } + + if (var10 != null && (var13 == null || par5Vec3.squareDistanceTo(var10) < par5Vec3.squareDistanceTo(var13))) { + var13 = var10; + } + + if (var11 != null && (var13 == null || par5Vec3.squareDistanceTo(var11) < par5Vec3.squareDistanceTo(var13))) { + var13 = var11; + } + + if (var12 != null && (var13 == null || par5Vec3.squareDistanceTo(var12) < par5Vec3.squareDistanceTo(var13))) { + var13 = var12; + } + + if (var13 == null) { + return null; + } else { + byte var14 = -1; + + if (var13 == var7) { + var14 = 4; + } + + if (var13 == var8) { + var14 = 5; + } + + if (var13 == var9) { + var14 = 0; + } + + if (var13 == var10) { + var14 = 1; + } + + if (var13 == var11) { + var14 = 2; + } + + if (var13 == var12) { + var14 = 3; + } + + return new MovingObjectPosition(par2, par3, par4, var14, + var13.addVector((double) par2, (double) par3, (double) par4)); + } + } + + /** + * Checks if a vector is within the Y and Z bounds of the block. + */ + private boolean isVecInsideYZBounds(Vec3 par1Vec3) { + return par1Vec3 == null ? false + : par1Vec3.yCoord >= this.minY && par1Vec3.yCoord <= this.maxY && par1Vec3.zCoord >= this.minZ + && par1Vec3.zCoord <= this.maxZ; + } + + /** + * Checks if a vector is within the X and Z bounds of the block. + */ + private boolean isVecInsideXZBounds(Vec3 par1Vec3) { + return par1Vec3 == null ? false + : par1Vec3.xCoord >= this.minX && par1Vec3.xCoord <= this.maxX && par1Vec3.zCoord >= this.minZ + && par1Vec3.zCoord <= this.maxZ; + } + + /** + * Checks if a vector is within the X and Y bounds of the block. + */ + private boolean isVecInsideXYBounds(Vec3 par1Vec3) { + return par1Vec3 == null ? false + : par1Vec3.xCoord >= this.minX && par1Vec3.xCoord <= this.maxX && par1Vec3.yCoord >= this.minY + && par1Vec3.yCoord <= this.maxY; + } + + /** + * Called upon the block being destroyed by an explosion + */ + public void onBlockDestroyedByExplosion(World par1World, int par2, int par3, int par4, Explosion par5Explosion) { + } + + public boolean canPlaceBlockOnSide(World par1World, int par2, int par3, int par4, int par5, + ItemStack par6ItemStack) { + return this.canPlaceBlockOnSide(par1World, par2, par3, par4, par5); + } + + /** + * checks to see if you can place this block can be placed on that side of a + * block: BlockLever overrides + */ + public boolean canPlaceBlockOnSide(World par1World, int par2, int par3, int par4, int par5) { + return this.canPlaceBlockAt(par1World, par2, par3, par4); + } + + /** + * Checks to see if its valid to put this block at the specified coordinates. + * Args: world, x, y, z + */ + public boolean canPlaceBlockAt(World par1World, int par2, int par3, int par4) { + int var5 = par1World.getBlockId(par2, par3, par4); + return var5 == 0 || blocksList[var5].blockMaterial.isReplaceable(); + } + + /** + * Called upon block activation (right click on the block.) + */ + public boolean onBlockActivated(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer, + int par6, float par7, float par8, float par9) { + return false; + } + + /** + * Called whenever an entity is walking on top of this block. Args: world, x, y, + * z, entity + */ + public void onEntityWalking(World par1World, int par2, int par3, int par4, Entity par5Entity) { + } + + /** + * Called when a block is placed using its ItemBlock. Args: World, X, Y, Z, + * side, hitX, hitY, hitZ, block metadata + */ + public int onBlockPlaced(World par1World, int par2, int par3, int par4, int par5, float par6, float par7, + float par8, int par9) { + return par9; + } + + /** + * Called when the block is clicked by a player. Args: x, y, z, entityPlayer + */ + public void onBlockClicked(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer) { + } + + /** + * Can add to the passed in vector for a movement vector to be applied to the + * entity. Args: x, y, z, entity, vec3d + */ + public void velocityToAddToEntity(World par1World, int par2, int par3, int par4, Entity par5Entity, Vec3 par6Vec3) { + } + + /** + * Updates the blocks bounds based on its current state. Args: world, x, y, z + */ + public void setBlockBoundsBasedOnState(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + } + + /** + * returns the block bounderies minX value + */ + public final double getMinX() { + return this.minX; + } + + /** + * returns the block bounderies maxX value + */ + public final double getBlockBoundsMaxX() { + return this.maxX; + } + + /** + * returns the block bounderies minY value + */ + public final double getBlockBoundsMinY() { + return this.minY; + } + + /** + * returns the block bounderies maxY value + */ + public final double getBlockBoundsMaxY() { + return this.maxY; + } + + /** + * returns the block bounderies minZ value + */ + public final double getBlockBoundsMinZ() { + return this.minZ; + } + + /** + * returns the block bounderies maxZ value + */ + public final double getBlockBoundsMaxZ() { + return this.maxZ; + } + + /** + * Returns true if the block is emitting indirect/weak redstone power on the + * specified side. If isBlockNormalCube returns true, standard redstone + * propagation rules will apply instead and this will not be called. Args: + * World, X, Y, Z, side. Note that the side is reversed - eg it is 1 (up) when + * checking the bottom of the block. + */ + public int isProvidingWeakPower(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5) { + return 0; + } + + /** + * Can this block provide power. Only wire currently seems to have this change + * based on its state. + */ + public boolean canProvidePower() { + return false; + } + + /** + * Triggered whenever an entity collides with this block (enters into the + * block). Args: world, x, y, z, entity + */ + public void onEntityCollidedWithBlock(World par1World, int par2, int par3, int par4, Entity par5Entity) { + } + + /** + * Returns true if the block is emitting direct/strong redstone power on the + * specified side. Args: World, X, Y, Z, side. Note that the side is reversed - + * eg it is 1 (up) when checking the bottom of the block. + */ + public int isProvidingStrongPower(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5) { + return 0; + } + + /** + * Sets the block's bounds for rendering it as an item + */ + public void setBlockBoundsForItemRender() { + } + + /** + * Called when the player destroys a block with an item that can harvest it. (i, + * j, k) are the coordinates of the block and l is the block's subtype/damage. + */ + public void harvestBlock(World par1World, EntityPlayer par2EntityPlayer, int par3, int par4, int par5, int par6) { + par2EntityPlayer.addStat(StatList.mineBlockStatArray[this.blockID], 1); + par2EntityPlayer.addExhaustion(0.025F); + + if (this.canSilkHarvest() && EnchantmentHelper.getSilkTouchModifier(par2EntityPlayer)) { + ItemStack var8 = this.createStackedBlock(par6); + + if (var8 != null) { + this.dropBlockAsItem_do(par1World, par3, par4, par5, var8); + } + } else { + int var7 = EnchantmentHelper.getFortuneModifier(par2EntityPlayer); + this.dropBlockAsItem(par1World, par3, par4, par5, par6, var7); + } + } + + /** + * Return true if a player with Silk Touch can harvest this block directly, and + * not its normal drops. + */ + protected boolean canSilkHarvest() { + return this.renderAsNormalBlock() && !this.isBlockContainer; + } + + /** + * Returns an item stack containing a single instance of the current block type. + * 'i' is the block's subtype/damage and is ignored for blocks which do not + * support subtypes. Blocks which cannot be harvested should return null. + */ + protected ItemStack createStackedBlock(int par1) { + int var2 = 0; + + if (this.blockID >= 0 && this.blockID < Item.itemsList.length + && Item.itemsList[this.blockID].getHasSubtypes()) { + var2 = par1; + } + + return new ItemStack(this.blockID, 1, var2); + } + + /** + * Returns the usual quantity dropped by the block plus a bonus of 1 to 'i' + * (inclusive). + */ + public int quantityDroppedWithBonus(int par1, Random par2Random) { + return this.quantityDropped(par2Random); + } + + /** + * Can this block stay at this position. Similar to canPlaceBlockAt except gets + * checked often with plants. + */ + public boolean canBlockStay(World par1World, int par2, int par3, int par4) { + return true; + } + + /** + * Called when the block is placed in the world. + */ + public void onBlockPlacedBy(World par1World, int par2, int par3, int par4, EntityLiving par5EntityLiving, + ItemStack par6ItemStack) { + } + + /** + * Called after a block is placed + */ + public void onPostBlockPlaced(World par1World, int par2, int par3, int par4, int par5) { + } + + public Block setUnlocalizedName(String par1Str) { + this.unlocalizedName = par1Str; + return this; + } + + /** + * Gets the localized name of this block. Used for the statistics page. + */ + public String getLocalizedName() { + return StatCollector.translateToLocal(this.getUnlocalizedName() + ".name"); + } + + /** + * Returns the unlocalized name of this block. + */ + public String getUnlocalizedName() { + return "tile." + this.unlocalizedName; + } + + /** + * Called when the block receives a BlockEvent - see World.addBlockEvent. By + * default, passes it on to the tile entity at this location. Args: world, x, y, + * z, blockID, EventID, event parameter + */ + public boolean onBlockEventReceived(World par1World, int par2, int par3, int par4, int par5, int par6) { + return false; + } + + /** + * Return the state of blocks statistics flags - if the block is counted for + * mined and placed. + */ + public boolean getEnableStats() { + return this.enableStats; + } + + /** + * Disable statistics for the block, the block will no count for mined or + * placed. + */ + protected Block disableStats() { + this.enableStats = false; + return this; + } + + /** + * Returns the mobility information of the block, 0 = free, 1 = can't push but + * can move over, 2 = total immobility and stop pistons + */ + public int getMobilityFlag() { + return this.blockMaterial.getMaterialMobility(); + } + + /** + * Block's chance to react to an entity falling on it. + */ + public void onFallenUpon(World par1World, int par2, int par3, int par4, Entity par5Entity, float par6) { + } + + /** + * Get the block's damage value (for use with pick block). + */ + public int getDamageValue(World par1World, int par2, int par3, int par4) { + return this.damageDropped(par1World.getBlockMetadata(par2, par3, par4)); + } + + /** + * Sets the CreativeTab to display this block on. + */ + public Block setCreativeTab(CreativeTabs par1CreativeTabs) { + this.displayOnCreativeTab = par1CreativeTabs; + return this; + } + + /** + * Called when the block is attempted to be harvested + */ + public void onBlockHarvested(World par1World, int par2, int par3, int par4, int par5, + EntityPlayer par6EntityPlayer) { + } + + /** + * Called when this block is set (with meta data). + */ + public void onSetBlockIDWithMetaData(World par1World, int par2, int par3, int par4, int par5) { + } + + /** + * currently only used by BlockCauldron to incrament meta-data during rain + */ + public void fillWithRain(World par1World, int par2, int par3, int par4) { + } + + public boolean func_82506_l() { + return true; + } + + /** + * Return whether this block can drop from an explosion. + */ + public boolean canDropFromExplosion(Explosion par1Explosion) { + return true; + } + + /** + * Returns true if the given block ID is equivalent to this one. Example: + * redstoneTorchOn matches itself and redstoneTorchOff, and vice versa. Most + * blocks only match themselves. + */ + public boolean isAssociatedBlockID(int par1) { + return this.blockID == par1; + } + + /** + * Static version of isAssociatedBlockID. + */ + public static boolean isAssociatedBlockID(int par0, int par1) { + return par0 == par1 ? true + : (par0 != 0 && par1 != 0 && blocksList[par0] != null && blocksList[par1] != null + ? blocksList[par0].isAssociatedBlockID(par1) + : false); + } + + /** + * If this returns true, then comparators facing away from this block will use + * the value from getComparatorInputOverride instead of the actual redstone + * signal strength. + */ + public boolean hasComparatorInputOverride() { + return false; + } + + /** + * If hasComparatorInputOverride returns true, the return value from this is + * used instead of the redstone signal strength when this block inputs to a + * comparator. + */ + public int getComparatorInputOverride(World par1World, int par2, int par3, int par4, int par5) { + return 0; + } + + static { + Item.itemsList[cloth.blockID] = (new ItemCloth(cloth.blockID - 256)).setUnlocalizedName("cloth"); + Item.itemsList[wood.blockID] = (new ItemMultiTextureTile(wood.blockID - 256, wood, BlockLog.woodType)) + .setUnlocalizedName("log"); + Item.itemsList[planks.blockID] = (new ItemMultiTextureTile(planks.blockID - 256, planks, BlockWood.woodType)) + .setUnlocalizedName("wood"); + Item.itemsList[silverfish.blockID] = (new ItemMultiTextureTile(silverfish.blockID - 256, silverfish, + BlockSilverfish.silverfishStoneTypes)).setUnlocalizedName("monsterStoneEgg"); + Item.itemsList[stoneBrick.blockID] = (new ItemMultiTextureTile(stoneBrick.blockID - 256, stoneBrick, + BlockStoneBrick.STONE_BRICK_TYPES)).setUnlocalizedName("stonebricksmooth"); + Item.itemsList[sandStone.blockID] = (new ItemMultiTextureTile(sandStone.blockID - 256, sandStone, + BlockSandStone.SAND_STONE_TYPES)).setUnlocalizedName("sandStone"); + Item.itemsList[blockNetherQuartz.blockID] = (new ItemMultiTextureTile(blockNetherQuartz.blockID - 256, + blockNetherQuartz, BlockQuartz.quartzBlockTypes)).setUnlocalizedName("quartzBlock"); + Item.itemsList[stoneSingleSlab.blockID] = (new ItemSlab(stoneSingleSlab.blockID - 256, stoneSingleSlab, + stoneDoubleSlab, false)).setUnlocalizedName("stoneSlab"); + Item.itemsList[stoneDoubleSlab.blockID] = (new ItemSlab(stoneDoubleSlab.blockID - 256, stoneSingleSlab, + stoneDoubleSlab, true)).setUnlocalizedName("stoneSlab"); + Item.itemsList[woodSingleSlab.blockID] = (new ItemSlab(woodSingleSlab.blockID - 256, woodSingleSlab, + woodDoubleSlab, false)).setUnlocalizedName("woodSlab"); + Item.itemsList[woodDoubleSlab.blockID] = (new ItemSlab(woodDoubleSlab.blockID - 256, woodSingleSlab, + woodDoubleSlab, true)).setUnlocalizedName("woodSlab"); + Item.itemsList[sapling.blockID] = (new ItemMultiTextureTile(sapling.blockID - 256, sapling, + BlockSapling.WOOD_TYPES)).setUnlocalizedName("sapling"); + Item.itemsList[leaves.blockID] = (new ItemLeaves(leaves.blockID - 256)).setUnlocalizedName("leaves"); + Item.itemsList[vine.blockID] = new ItemColored(vine.blockID - 256, false); + Item.itemsList[tallGrass.blockID] = (new ItemColored(tallGrass.blockID - 256, true)) + .setBlockNames(new String[] { "shrub", "grass", "fern" }); + Item.itemsList[snow.blockID] = new ItemSnow(snow.blockID - 256, snow); + Item.itemsList[waterlily.blockID] = new ItemLilyPad(waterlily.blockID - 256); + Item.itemsList[pistonBase.blockID] = new ItemPiston(pistonBase.blockID - 256); + Item.itemsList[pistonStickyBase.blockID] = new ItemPiston(pistonStickyBase.blockID - 256); + Item.itemsList[cobblestoneWall.blockID] = (new ItemMultiTextureTile(cobblestoneWall.blockID - 256, + cobblestoneWall, BlockWall.types)).setUnlocalizedName("cobbleWall"); + Item.itemsList[anvil.blockID] = (new ItemAnvilBlock(anvil)).setUnlocalizedName("anvil"); + + for (int var0 = 0; var0 < 256; ++var0) { + if (blocksList[var0] != null) { + if (Item.itemsList[var0] == null) { + Item.itemsList[var0] = new ItemBlock(var0 - 256); + blocksList[var0].initializeBlock(); + } + + boolean var1 = false; + + if (var0 > 0 && blocksList[var0].getRenderType() == 10) { + var1 = true; + } + + if (var0 > 0 && blocksList[var0] instanceof BlockHalfSlab) { + var1 = true; + } + + if (var0 == tilledField.blockID) { + var1 = true; + } + + if (canBlockGrass[var0]) { + var1 = true; + } + + if (lightOpacity[var0] == 0) { + var1 = true; + } + + useNeighborBrightness[var0] = var1; + } + } + + canBlockGrass[0] = true; + StatList.initBreakableStats(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockAnvil.java b/sp-server/src/main/java/net/minecraft/src/BlockAnvil.java new file mode 100644 index 0000000..6fe2ec2 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockAnvil.java @@ -0,0 +1,114 @@ +package net.minecraft.src; + +public class BlockAnvil extends BlockSand { + /** List of types/statues the Anvil can be in. */ + public static final String[] statuses = new String[] { "intact", "slightlyDamaged", "veryDamaged" }; + private static final String[] anvilIconNames = new String[] { "anvil_top", "anvil_top_damaged_1", + "anvil_top_damaged_2" }; + public int field_82521_b = 0; + + protected BlockAnvil(int par1) { + super(par1, Material.anvil); + this.setLightOpacity(0); + this.setCreativeTab(CreativeTabs.tabDecorations); + } + + /** + * If this block doesn't render as an ordinary block it will return False + * (examples: signs, buttons, stairs, etc) + */ + public boolean renderAsNormalBlock() { + return false; + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return false; + } + + /** + * Called when the block is placed in the world. + */ + public void onBlockPlacedBy(World par1World, int par2, int par3, int par4, EntityLiving par5EntityLiving, + ItemStack par6ItemStack) { + int var7 = MathHelper.floor_double((double) (par5EntityLiving.rotationYaw * 4.0F / 360.0F) + 0.5D) & 3; + int var8 = par1World.getBlockMetadata(par2, par3, par4) >> 2; + ++var7; + var7 %= 4; + + if (var7 == 0) { + par1World.setBlockMetadata(par2, par3, par4, 2 | var8 << 2, 2); + } + + if (var7 == 1) { + par1World.setBlockMetadata(par2, par3, par4, 3 | var8 << 2, 2); + } + + if (var7 == 2) { + par1World.setBlockMetadata(par2, par3, par4, 0 | var8 << 2, 2); + } + + if (var7 == 3) { + par1World.setBlockMetadata(par2, par3, par4, 1 | var8 << 2, 2); + } + } + + /** + * Called upon block activation (right click on the block.) + */ + public boolean onBlockActivated(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer, + int par6, float par7, float par8, float par9) { + if (par1World.isRemote) { + return true; + } else { + par5EntityPlayer.displayGUIAnvil(par2, par3, par4); + return true; + } + } + + /** + * The type of render function that is called for this block + */ + public int getRenderType() { + return 35; + } + + /** + * Determines the damage on the item the block drops. Used in cloth and wood. + */ + public int damageDropped(int par1) { + return par1 >> 2; + } + + /** + * Updates the blocks bounds based on its current state. Args: world, x, y, z + */ + public void setBlockBoundsBasedOnState(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + int var5 = par1IBlockAccess.getBlockMetadata(par2, par3, par4) & 3; + + if (var5 != 3 && var5 != 1) { + this.setBlockBounds(0.125F, 0.0F, 0.0F, 0.875F, 1.0F, 1.0F); + } else { + this.setBlockBounds(0.0F, 0.0F, 0.125F, 1.0F, 1.0F, 0.875F); + } + } + + /** + * Called when the falling block entity for this block is created + */ + protected void onStartFalling(EntityFallingSand par1EntityFallingSand) { + par1EntityFallingSand.setIsAnvil(true); + } + + /** + * Called when the falling block entity for this block hits the ground and turns + * back into a block + */ + public void onFinishFalling(World par1World, int par2, int par3, int par4, int par5) { + par1World.playAuxSFX(1022, par2, par3, par4, 0); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockBasePressurePlate.java b/sp-server/src/main/java/net/minecraft/src/BlockBasePressurePlate.java new file mode 100644 index 0000000..9f005bb --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockBasePressurePlate.java @@ -0,0 +1,238 @@ +package net.minecraft.src; + +import java.util.Random; + +public abstract class BlockBasePressurePlate extends Block { + private String pressurePlateIconName; + + protected BlockBasePressurePlate(int par1, String par2Str, Material par3Material) { + super(par1, par3Material); + this.pressurePlateIconName = par2Str; + this.setCreativeTab(CreativeTabs.tabRedstone); + this.setTickRandomly(true); + this.func_94353_c_(this.getMetaFromWeight(15)); + } + + /** + * Updates the blocks bounds based on its current state. Args: world, x, y, z + */ + public void setBlockBoundsBasedOnState(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + this.func_94353_c_(par1IBlockAccess.getBlockMetadata(par2, par3, par4)); + } + + protected void func_94353_c_(int par1) { + boolean var2 = this.getPowerSupply(par1) > 0; + float var3 = 0.0625F; + + if (var2) { + this.setBlockBounds(var3, 0.0F, var3, 1.0F - var3, 0.03125F, 1.0F - var3); + } else { + this.setBlockBounds(var3, 0.0F, var3, 1.0F - var3, 0.0625F, 1.0F - var3); + } + } + + /** + * How many world ticks before ticking + */ + public int tickRate(World par1World) { + return 20; + } + + /** + * Returns a bounding box from the pool of bounding boxes (this means this box + * can change after the pool has been cleared to be reused) + */ + public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int par4) { + return null; + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return false; + } + + /** + * If this block doesn't render as an ordinary block it will return False + * (examples: signs, buttons, stairs, etc) + */ + public boolean renderAsNormalBlock() { + return false; + } + + public boolean getBlocksMovement(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + return true; + } + + /** + * Checks to see if its valid to put this block at the specified coordinates. + * Args: world, x, y, z + */ + public boolean canPlaceBlockAt(World par1World, int par2, int par3, int par4) { + return par1World.doesBlockHaveSolidTopSurface(par2, par3 - 1, par4) + || BlockFence.isIdAFence(par1World.getBlockId(par2, par3 - 1, par4)); + } + + /** + * Lets the block know when one of its neighbor changes. Doesn't know which + * neighbor changed (coordinates passed are their own) Args: x, y, z, neighbor + * blockID + */ + public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5) { + boolean var6 = false; + + if (!par1World.doesBlockHaveSolidTopSurface(par2, par3 - 1, par4) + && !BlockFence.isIdAFence(par1World.getBlockId(par2, par3 - 1, par4))) { + var6 = true; + } + + if (var6) { + this.dropBlockAsItem(par1World, par2, par3, par4, par1World.getBlockMetadata(par2, par3, par4), 0); + par1World.setBlockToAir(par2, par3, par4); + } + } + + /** + * Ticks the block if it's been scheduled + */ + public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random) { + if (!par1World.isRemote) { + int var6 = this.getPowerSupply(par1World.getBlockMetadata(par2, par3, par4)); + + if (var6 > 0) { + this.setStateIfMobInteractsWithPlate(par1World, par2, par3, par4, var6); + } + } + } + + /** + * Triggered whenever an entity collides with this block (enters into the + * block). Args: world, x, y, z, entity + */ + public void onEntityCollidedWithBlock(World par1World, int par2, int par3, int par4, Entity par5Entity) { + if (!par1World.isRemote) { + int var6 = this.getPowerSupply(par1World.getBlockMetadata(par2, par3, par4)); + + if (var6 == 0) { + this.setStateIfMobInteractsWithPlate(par1World, par2, par3, par4, var6); + } + } + } + + /** + * Checks if there are mobs on the plate. If a mob is on the plate and it is + * off, it turns it on, and vice versa. + */ + protected void setStateIfMobInteractsWithPlate(World par1World, int par2, int par3, int par4, int par5) { + int var6 = this.getPlateState(par1World, par2, par3, par4); + boolean var7 = par5 > 0; + boolean var8 = var6 > 0; + + if (par5 != var6) { + par1World.setBlockMetadata(par2, par3, par4, this.getMetaFromWeight(var6), 2); + this.func_94354_b_(par1World, par2, par3, par4); + par1World.markBlockRangeForRenderUpdate(par2, par3, par4, par2, par3, par4); + } + + if (!var8 && var7) { + par1World.playSoundEffect((double) par2 + 0.5D, (double) par3 + 0.1D, (double) par4 + 0.5D, "random.click", + 0.3F, 0.5F); + } else if (var8 && !var7) { + par1World.playSoundEffect((double) par2 + 0.5D, (double) par3 + 0.1D, (double) par4 + 0.5D, "random.click", + 0.3F, 0.6F); + } + + if (var8) { + par1World.scheduleBlockUpdate(par2, par3, par4, this.blockID, this.tickRate(par1World)); + } + } + + protected AxisAlignedBB getSensitiveAABB(int par1, int par2, int par3) { + float var4 = 0.125F; + return AxisAlignedBB.getAABBPool().getAABB((double) ((float) par1 + var4), (double) par2, + (double) ((float) par3 + var4), (double) ((float) (par1 + 1) - var4), (double) par2 + 0.25D, + (double) ((float) (par3 + 1) - var4)); + } + + /** + * ejects contained items into the world, and notifies neighbours of an update, + * as appropriate + */ + public void breakBlock(World par1World, int par2, int par3, int par4, int par5, int par6) { + if (this.getPowerSupply(par6) > 0) { + this.func_94354_b_(par1World, par2, par3, par4); + } + + super.breakBlock(par1World, par2, par3, par4, par5, par6); + } + + protected void func_94354_b_(World par1World, int par2, int par3, int par4) { + par1World.notifyBlocksOfNeighborChange(par2, par3, par4, this.blockID); + par1World.notifyBlocksOfNeighborChange(par2, par3 - 1, par4, this.blockID); + } + + /** + * Returns true if the block is emitting indirect/weak redstone power on the + * specified side. If isBlockNormalCube returns true, standard redstone + * propagation rules will apply instead and this will not be called. Args: + * World, X, Y, Z, side. Note that the side is reversed - eg it is 1 (up) when + * checking the bottom of the block. + */ + public int isProvidingWeakPower(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5) { + return this.getPowerSupply(par1IBlockAccess.getBlockMetadata(par2, par3, par4)); + } + + /** + * Returns true if the block is emitting direct/strong redstone power on the + * specified side. Args: World, X, Y, Z, side. Note that the side is reversed - + * eg it is 1 (up) when checking the bottom of the block. + */ + public int isProvidingStrongPower(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5) { + return par5 == 1 ? this.getPowerSupply(par1IBlockAccess.getBlockMetadata(par2, par3, par4)) : 0; + } + + /** + * Can this block provide power. Only wire currently seems to have this change + * based on its state. + */ + public boolean canProvidePower() { + return true; + } + + /** + * Sets the block's bounds for rendering it as an item + */ + public void setBlockBoundsForItemRender() { + float var1 = 0.5F; + float var2 = 0.125F; + float var3 = 0.5F; + this.setBlockBounds(0.5F - var1, 0.5F - var2, 0.5F - var3, 0.5F + var1, 0.5F + var2, 0.5F + var3); + } + + /** + * Returns the mobility information of the block, 0 = free, 1 = can't push but + * can move over, 2 = total immobility and stop pistons + */ + public int getMobilityFlag() { + return 1; + } + + /** + * Returns the current state of the pressure plate. Returns a value between 0 + * and 15 based on the number of items on it. + */ + protected abstract int getPlateState(World var1, int var2, int var3, int var4); + + /** + * Argument is metadata. Returns power level (0-15) + */ + protected abstract int getPowerSupply(int var1); + + /** + * Argument is weight (0-15). Return the metadata to be set because of it. + */ + protected abstract int getMetaFromWeight(int var1); +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockBaseRailLogic.java b/sp-server/src/main/java/net/minecraft/src/BlockBaseRailLogic.java new file mode 100644 index 0000000..005e908 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockBaseRailLogic.java @@ -0,0 +1,368 @@ +package net.minecraft.src; + +import java.util.ArrayList; +import java.util.List; + +public class BlockBaseRailLogic { + private World logicWorld; + private int railX; + private int railY; + private int railZ; + private final boolean isStraightRail; + + /** The positions of connected rails */ + private List connectedTracks; + + final BlockRailBase theRail; + + public BlockBaseRailLogic(BlockRailBase par1, World par2, int par3, int par4, int par5) { + this.theRail = par1; + this.connectedTracks = new ArrayList(); + this.logicWorld = par2; + this.railX = par3; + this.railY = par4; + this.railZ = par5; + int var6 = par2.getBlockId(par3, par4, par5); + int var7 = par2.getBlockMetadata(par3, par4, par5); + + if (((BlockRailBase) Block.blocksList[var6]).isPowered) { + this.isStraightRail = true; + var7 &= -9; + } else { + this.isStraightRail = false; + } + + this.setBasicRail(var7); + } + + private void setBasicRail(int par1) { + this.connectedTracks.clear(); + + if (par1 == 0) { + this.connectedTracks.add(new ChunkPosition(this.railX, this.railY, this.railZ - 1)); + this.connectedTracks.add(new ChunkPosition(this.railX, this.railY, this.railZ + 1)); + } else if (par1 == 1) { + this.connectedTracks.add(new ChunkPosition(this.railX - 1, this.railY, this.railZ)); + this.connectedTracks.add(new ChunkPosition(this.railX + 1, this.railY, this.railZ)); + } else if (par1 == 2) { + this.connectedTracks.add(new ChunkPosition(this.railX - 1, this.railY, this.railZ)); + this.connectedTracks.add(new ChunkPosition(this.railX + 1, this.railY + 1, this.railZ)); + } else if (par1 == 3) { + this.connectedTracks.add(new ChunkPosition(this.railX - 1, this.railY + 1, this.railZ)); + this.connectedTracks.add(new ChunkPosition(this.railX + 1, this.railY, this.railZ)); + } else if (par1 == 4) { + this.connectedTracks.add(new ChunkPosition(this.railX, this.railY + 1, this.railZ - 1)); + this.connectedTracks.add(new ChunkPosition(this.railX, this.railY, this.railZ + 1)); + } else if (par1 == 5) { + this.connectedTracks.add(new ChunkPosition(this.railX, this.railY, this.railZ - 1)); + this.connectedTracks.add(new ChunkPosition(this.railX, this.railY + 1, this.railZ + 1)); + } else if (par1 == 6) { + this.connectedTracks.add(new ChunkPosition(this.railX + 1, this.railY, this.railZ)); + this.connectedTracks.add(new ChunkPosition(this.railX, this.railY, this.railZ + 1)); + } else if (par1 == 7) { + this.connectedTracks.add(new ChunkPosition(this.railX - 1, this.railY, this.railZ)); + this.connectedTracks.add(new ChunkPosition(this.railX, this.railY, this.railZ + 1)); + } else if (par1 == 8) { + this.connectedTracks.add(new ChunkPosition(this.railX - 1, this.railY, this.railZ)); + this.connectedTracks.add(new ChunkPosition(this.railX, this.railY, this.railZ - 1)); + } else if (par1 == 9) { + this.connectedTracks.add(new ChunkPosition(this.railX + 1, this.railY, this.railZ)); + this.connectedTracks.add(new ChunkPosition(this.railX, this.railY, this.railZ - 1)); + } + } + + private void refreshConnectedTracks() { + for (int var1 = 0; var1 < this.connectedTracks.size(); ++var1) { + BlockBaseRailLogic var2 = this.getRailLogic((ChunkPosition) this.connectedTracks.get(var1)); + + if (var2 != null && var2.isRailChunkPositionCorrect(this)) { + this.connectedTracks.set(var1, new ChunkPosition(var2.railX, var2.railY, var2.railZ)); + } else { + this.connectedTracks.remove(var1--); + } + } + } + + private boolean isMinecartTrack(int par1, int par2, int par3) { + return BlockRailBase.isRailBlockAt(this.logicWorld, par1, par2, par3) ? true + : (BlockRailBase.isRailBlockAt(this.logicWorld, par1, par2 + 1, par3) ? true + : BlockRailBase.isRailBlockAt(this.logicWorld, par1, par2 - 1, par3)); + } + + private BlockBaseRailLogic getRailLogic(ChunkPosition par1ChunkPosition) { + return BlockRailBase.isRailBlockAt(this.logicWorld, par1ChunkPosition.x, par1ChunkPosition.y, + par1ChunkPosition.z) + ? new BlockBaseRailLogic(this.theRail, this.logicWorld, par1ChunkPosition.x, + par1ChunkPosition.y, par1ChunkPosition.z) + : (BlockRailBase.isRailBlockAt(this.logicWorld, par1ChunkPosition.x, par1ChunkPosition.y + 1, + par1ChunkPosition.z) + ? new BlockBaseRailLogic(this.theRail, this.logicWorld, par1ChunkPosition.x, + par1ChunkPosition.y + 1, par1ChunkPosition.z) + : (BlockRailBase.isRailBlockAt(this.logicWorld, par1ChunkPosition.x, + par1ChunkPosition.y - 1, par1ChunkPosition.z) + ? new BlockBaseRailLogic(this.theRail, this.logicWorld, + par1ChunkPosition.x, par1ChunkPosition.y - 1, + par1ChunkPosition.z) + : null)); + } + + /** + * Checks if the rail is at the chunk position it is expected to be. + */ + private boolean isRailChunkPositionCorrect(BlockBaseRailLogic par1BlockBaseRailLogic) { + for (int var2 = 0; var2 < this.connectedTracks.size(); ++var2) { + ChunkPosition var3 = (ChunkPosition) this.connectedTracks.get(var2); + + if (var3.x == par1BlockBaseRailLogic.railX && var3.z == par1BlockBaseRailLogic.railZ) { + return true; + } + } + + return false; + } + + private boolean isPartOfTrack(int par1, int par2, int par3) { + for (int var4 = 0; var4 < this.connectedTracks.size(); ++var4) { + ChunkPosition var5 = (ChunkPosition) this.connectedTracks.get(var4); + + if (var5.x == par1 && var5.z == par3) { + return true; + } + } + + return false; + } + + protected int getNumberOfAdjacentTracks() { + int var1 = 0; + + if (this.isMinecartTrack(this.railX, this.railY, this.railZ - 1)) { + ++var1; + } + + if (this.isMinecartTrack(this.railX, this.railY, this.railZ + 1)) { + ++var1; + } + + if (this.isMinecartTrack(this.railX - 1, this.railY, this.railZ)) { + ++var1; + } + + if (this.isMinecartTrack(this.railX + 1, this.railY, this.railZ)) { + ++var1; + } + + return var1; + } + + private boolean canConnectTo(BlockBaseRailLogic par1BlockBaseRailLogic) { + return this.isRailChunkPositionCorrect(par1BlockBaseRailLogic) ? true + : (this.connectedTracks.size() == 2 ? false : (this.connectedTracks.isEmpty() ? true : true)); + } + + private void connectToNeighbor(BlockBaseRailLogic par1BlockBaseRailLogic) { + this.connectedTracks.add(new ChunkPosition(par1BlockBaseRailLogic.railX, par1BlockBaseRailLogic.railY, + par1BlockBaseRailLogic.railZ)); + boolean var2 = this.isPartOfTrack(this.railX, this.railY, this.railZ - 1); + boolean var3 = this.isPartOfTrack(this.railX, this.railY, this.railZ + 1); + boolean var4 = this.isPartOfTrack(this.railX - 1, this.railY, this.railZ); + boolean var5 = this.isPartOfTrack(this.railX + 1, this.railY, this.railZ); + byte var6 = -1; + + if (var2 || var3) { + var6 = 0; + } + + if (var4 || var5) { + var6 = 1; + } + + if (!this.isStraightRail) { + if (var3 && var5 && !var2 && !var4) { + var6 = 6; + } + + if (var3 && var4 && !var2 && !var5) { + var6 = 7; + } + + if (var2 && var4 && !var3 && !var5) { + var6 = 8; + } + + if (var2 && var5 && !var3 && !var4) { + var6 = 9; + } + } + + if (var6 == 0) { + if (BlockRailBase.isRailBlockAt(this.logicWorld, this.railX, this.railY + 1, this.railZ - 1)) { + var6 = 4; + } + + if (BlockRailBase.isRailBlockAt(this.logicWorld, this.railX, this.railY + 1, this.railZ + 1)) { + var6 = 5; + } + } + + if (var6 == 1) { + if (BlockRailBase.isRailBlockAt(this.logicWorld, this.railX + 1, this.railY + 1, this.railZ)) { + var6 = 2; + } + + if (BlockRailBase.isRailBlockAt(this.logicWorld, this.railX - 1, this.railY + 1, this.railZ)) { + var6 = 3; + } + } + + if (var6 < 0) { + var6 = 0; + } + + int var7 = var6; + + if (this.isStraightRail) { + var7 = this.logicWorld.getBlockMetadata(this.railX, this.railY, this.railZ) & 8 | var6; + } + + this.logicWorld.setBlockMetadata(this.railX, this.railY, this.railZ, var7, 3); + } + + private boolean canConnectFrom(int par1, int par2, int par3) { + BlockBaseRailLogic var4 = this.getRailLogic(new ChunkPosition(par1, par2, par3)); + + if (var4 == null) { + return false; + } else { + var4.refreshConnectedTracks(); + return var4.canConnectTo(this); + } + } + + public void func_94511_a(boolean par1, boolean par2) { + boolean var3 = this.canConnectFrom(this.railX, this.railY, this.railZ - 1); + boolean var4 = this.canConnectFrom(this.railX, this.railY, this.railZ + 1); + boolean var5 = this.canConnectFrom(this.railX - 1, this.railY, this.railZ); + boolean var6 = this.canConnectFrom(this.railX + 1, this.railY, this.railZ); + byte var7 = -1; + + if ((var3 || var4) && !var5 && !var6) { + var7 = 0; + } + + if ((var5 || var6) && !var3 && !var4) { + var7 = 1; + } + + if (!this.isStraightRail) { + if (var4 && var6 && !var3 && !var5) { + var7 = 6; + } + + if (var4 && var5 && !var3 && !var6) { + var7 = 7; + } + + if (var3 && var5 && !var4 && !var6) { + var7 = 8; + } + + if (var3 && var6 && !var4 && !var5) { + var7 = 9; + } + } + + if (var7 == -1) { + if (var3 || var4) { + var7 = 0; + } + + if (var5 || var6) { + var7 = 1; + } + + if (!this.isStraightRail) { + if (par1) { + if (var4 && var6) { + var7 = 6; + } + + if (var5 && var4) { + var7 = 7; + } + + if (var6 && var3) { + var7 = 9; + } + + if (var3 && var5) { + var7 = 8; + } + } else { + if (var3 && var5) { + var7 = 8; + } + + if (var6 && var3) { + var7 = 9; + } + + if (var5 && var4) { + var7 = 7; + } + + if (var4 && var6) { + var7 = 6; + } + } + } + } + + if (var7 == 0) { + if (BlockRailBase.isRailBlockAt(this.logicWorld, this.railX, this.railY + 1, this.railZ - 1)) { + var7 = 4; + } + + if (BlockRailBase.isRailBlockAt(this.logicWorld, this.railX, this.railY + 1, this.railZ + 1)) { + var7 = 5; + } + } + + if (var7 == 1) { + if (BlockRailBase.isRailBlockAt(this.logicWorld, this.railX + 1, this.railY + 1, this.railZ)) { + var7 = 2; + } + + if (BlockRailBase.isRailBlockAt(this.logicWorld, this.railX - 1, this.railY + 1, this.railZ)) { + var7 = 3; + } + } + + if (var7 < 0) { + var7 = 0; + } + + this.setBasicRail(var7); + int var8 = var7; + + if (this.isStraightRail) { + var8 = this.logicWorld.getBlockMetadata(this.railX, this.railY, this.railZ) & 8 | var7; + } + + if (par2 || this.logicWorld.getBlockMetadata(this.railX, this.railY, this.railZ) != var8) { + this.logicWorld.setBlockMetadata(this.railX, this.railY, this.railZ, var8, 3); + + for (int var9 = 0; var9 < this.connectedTracks.size(); ++var9) { + BlockBaseRailLogic var10 = this.getRailLogic((ChunkPosition) this.connectedTracks.get(var9)); + + if (var10 != null) { + var10.refreshConnectedTracks(); + + if (var10.canConnectTo(this)) { + var10.connectToNeighbor(this); + } + } + } + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockBeacon.java b/sp-server/src/main/java/net/minecraft/src/BlockBeacon.java new file mode 100644 index 0000000..28c0402 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockBeacon.java @@ -0,0 +1,72 @@ +package net.minecraft.src; + +public class BlockBeacon extends BlockContainer { + public BlockBeacon(int par1) { + super(par1, Material.glass); + this.setHardness(3.0F); + this.setCreativeTab(CreativeTabs.tabMisc); + } + + /** + * Returns a new instance of a block's tile entity class. Called on placing the + * block. + */ + public TileEntity createNewTileEntity(World par1World) { + return new TileEntityBeacon(); + } + + /** + * Called upon block activation (right click on the block.) + */ + public boolean onBlockActivated(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer, + int par6, float par7, float par8, float par9) { + if (par1World.isRemote) { + return true; + } else { + TileEntityBeacon var10 = (TileEntityBeacon) par1World.getBlockTileEntity(par2, par3, par4); + + if (var10 != null) { + par5EntityPlayer.displayGUIBeacon(var10); + } + + return true; + } + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return false; + } + + /** + * If this block doesn't render as an ordinary block it will return False + * (examples: signs, buttons, stairs, etc) + */ + public boolean renderAsNormalBlock() { + return false; + } + + /** + * The type of render function that is called for this block + */ + public int getRenderType() { + return 34; + } + + /** + * Called when the block is placed in the world. + */ + public void onBlockPlacedBy(World par1World, int par2, int par3, int par4, EntityLiving par5EntityLiving, + ItemStack par6ItemStack) { + super.onBlockPlacedBy(par1World, par2, par3, par4, par5EntityLiving, par6ItemStack); + + if (par6ItemStack.hasDisplayName()) { + ((TileEntityBeacon) par1World.getBlockTileEntity(par2, par3, par4)) + .func_94047_a(par6ItemStack.getDisplayName()); + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockBed.java b/sp-server/src/main/java/net/minecraft/src/BlockBed.java new file mode 100644 index 0000000..7a4fd7e --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockBed.java @@ -0,0 +1,264 @@ +package net.minecraft.src; + +import java.util.Iterator; +import java.util.Random; + +public class BlockBed extends BlockDirectional { + /** Maps the foot-of-bed block to the head-of-bed block. */ + public static final int[][] footBlockToHeadBlockMap = new int[][] { { 0, 1 }, { -1, 0 }, { 0, -1 }, { 1, 0 } }; + + public BlockBed(int par1) { + super(par1, Material.cloth); + this.setBounds(); + } + + /** + * Called upon block activation (right click on the block.) + */ + public boolean onBlockActivated(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer, + int par6, float par7, float par8, float par9) { + if (par1World.isRemote) { + return true; + } else { + int var10 = par1World.getBlockMetadata(par2, par3, par4); + + if (!isBlockHeadOfBed(var10)) { + int var11 = getDirection(var10); + par2 += footBlockToHeadBlockMap[var11][0]; + par4 += footBlockToHeadBlockMap[var11][1]; + + if (par1World.getBlockId(par2, par3, par4) != this.blockID) { + return true; + } + + var10 = par1World.getBlockMetadata(par2, par3, par4); + } + + if (par1World.provider.canRespawnHere() + && par1World.getBiomeGenForCoords(par2, par4) != BiomeGenBase.hell) { + if (isBedOccupied(var10)) { + EntityPlayer var19 = null; + Iterator var12 = par1World.playerEntities.iterator(); + + while (var12.hasNext()) { + EntityPlayer var21 = (EntityPlayer) var12.next(); + + if (var21.isPlayerSleeping()) { + ChunkCoordinates var14 = var21.playerLocation; + + if (var14.posX == par2 && var14.posY == par3 && var14.posZ == par4) { + var19 = var21; + } + } + } + + if (var19 != null) { + par5EntityPlayer.addChatMessage("tile.bed.occupied"); + return true; + } + + setBedOccupied(par1World, par2, par3, par4, false); + } + + EnumStatus var20 = par5EntityPlayer.sleepInBedAt(par2, par3, par4); + + if (var20 == EnumStatus.OK) { + setBedOccupied(par1World, par2, par3, par4, true); + return true; + } else { + if (var20 == EnumStatus.NOT_POSSIBLE_NOW) { + par5EntityPlayer.addChatMessage("tile.bed.noSleep"); + } else if (var20 == EnumStatus.NOT_SAFE) { + par5EntityPlayer.addChatMessage("tile.bed.notSafe"); + } + + return true; + } + } else { + double var18 = (double) par2 + 0.5D; + double var13 = (double) par3 + 0.5D; + double var15 = (double) par4 + 0.5D; + par1World.setBlockToAir(par2, par3, par4); + int var17 = getDirection(var10); + par2 += footBlockToHeadBlockMap[var17][0]; + par4 += footBlockToHeadBlockMap[var17][1]; + + if (par1World.getBlockId(par2, par3, par4) == this.blockID) { + par1World.setBlockToAir(par2, par3, par4); + var18 = (var18 + (double) par2 + 0.5D) / 2.0D; + var13 = (var13 + (double) par3 + 0.5D) / 2.0D; + var15 = (var15 + (double) par4 + 0.5D) / 2.0D; + } + + par1World.newExplosion((Entity) null, (double) ((float) par2 + 0.5F), (double) ((float) par3 + 0.5F), + (double) ((float) par4 + 0.5F), 5.0F, true, true); + return true; + } + } + } + + /** + * The type of render function that is called for this block + */ + public int getRenderType() { + return 14; + } + + /** + * If this block doesn't render as an ordinary block it will return False + * (examples: signs, buttons, stairs, etc) + */ + public boolean renderAsNormalBlock() { + return false; + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return false; + } + + /** + * Updates the blocks bounds based on its current state. Args: world, x, y, z + */ + public void setBlockBoundsBasedOnState(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + this.setBounds(); + } + + /** + * Lets the block know when one of its neighbor changes. Doesn't know which + * neighbor changed (coordinates passed are their own) Args: x, y, z, neighbor + * blockID + */ + public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5) { + int var6 = par1World.getBlockMetadata(par2, par3, par4); + int var7 = getDirection(var6); + + if (isBlockHeadOfBed(var6)) { + if (par1World.getBlockId(par2 - footBlockToHeadBlockMap[var7][0], par3, + par4 - footBlockToHeadBlockMap[var7][1]) != this.blockID) { + par1World.setBlockToAir(par2, par3, par4); + } + } else if (par1World.getBlockId(par2 + footBlockToHeadBlockMap[var7][0], par3, + par4 + footBlockToHeadBlockMap[var7][1]) != this.blockID) { + par1World.setBlockToAir(par2, par3, par4); + + if (!par1World.isRemote) { + this.dropBlockAsItem(par1World, par2, par3, par4, var6, 0); + } + } + } + + /** + * Returns the ID of the items to drop on destruction. + */ + public int idDropped(int par1, Random par2Random, int par3) { + return isBlockHeadOfBed(par1) ? 0 : Item.bed.itemID; + } + + /** + * Set the bounds of the bed block. + */ + private void setBounds() { + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.5625F, 1.0F); + } + + /** + * Returns whether or not this bed block is the head of the bed. + */ + public static boolean isBlockHeadOfBed(int par0) { + return (par0 & 8) != 0; + } + + /** + * Return whether or not the bed is occupied. + */ + public static boolean isBedOccupied(int par0) { + return (par0 & 4) != 0; + } + + /** + * Sets whether or not the bed is occupied. + */ + public static void setBedOccupied(World par0World, int par1, int par2, int par3, boolean par4) { + int var5 = par0World.getBlockMetadata(par1, par2, par3); + + if (par4) { + var5 |= 4; + } else { + var5 &= -5; + } + + par0World.setBlockMetadata(par1, par2, par3, var5, 4); + } + + /** + * Gets the nearest empty chunk coordinates for the player to wake up from a bed + * into. + */ + public static ChunkCoordinates getNearestEmptyChunkCoordinates(World par0World, int par1, int par2, int par3, + int par4) { + int var5 = par0World.getBlockMetadata(par1, par2, par3); + int var6 = BlockDirectional.getDirection(var5); + + for (int var7 = 0; var7 <= 1; ++var7) { + int var8 = par1 - footBlockToHeadBlockMap[var6][0] * var7 - 1; + int var9 = par3 - footBlockToHeadBlockMap[var6][1] * var7 - 1; + int var10 = var8 + 2; + int var11 = var9 + 2; + + for (int var12 = var8; var12 <= var10; ++var12) { + for (int var13 = var9; var13 <= var11; ++var13) { + if (par0World.doesBlockHaveSolidTopSurface(var12, par2 - 1, var13) + && par0World.isAirBlock(var12, par2, var13) + && par0World.isAirBlock(var12, par2 + 1, var13)) { + if (par4 <= 0) { + return new ChunkCoordinates(var12, par2, var13); + } + + --par4; + } + } + } + } + + return null; + } + + /** + * Drops the block items with a specified chance of dropping the specified items + */ + public void dropBlockAsItemWithChance(World par1World, int par2, int par3, int par4, int par5, float par6, + int par7) { + if (!isBlockHeadOfBed(par5)) { + super.dropBlockAsItemWithChance(par1World, par2, par3, par4, par5, par6, 0); + } + } + + /** + * Returns the mobility information of the block, 0 = free, 1 = can't push but + * can move over, 2 = total immobility and stop pistons + */ + public int getMobilityFlag() { + return 1; + } + + /** + * Called when the block is attempted to be harvested + */ + public void onBlockHarvested(World par1World, int par2, int par3, int par4, int par5, + EntityPlayer par6EntityPlayer) { + if (par6EntityPlayer.capabilities.isCreativeMode && isBlockHeadOfBed(par5)) { + int var7 = getDirection(par5); + par2 -= footBlockToHeadBlockMap[var7][0]; + par4 -= footBlockToHeadBlockMap[var7][1]; + + if (par1World.getBlockId(par2, par3, par4) == this.blockID) { + par1World.setBlockToAir(par2, par3, par4); + } + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockBookshelf.java b/sp-server/src/main/java/net/minecraft/src/BlockBookshelf.java new file mode 100644 index 0000000..96d8082 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockBookshelf.java @@ -0,0 +1,24 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockBookshelf extends Block { + public BlockBookshelf(int par1) { + super(par1, Material.wood); + this.setCreativeTab(CreativeTabs.tabBlock); + } + + /** + * Returns the quantity of items to drop on block destruction. + */ + public int quantityDropped(Random par1Random) { + return 3; + } + + /** + * Returns the ID of the items to drop on destruction. + */ + public int idDropped(int par1, Random par2Random, int par3) { + return Item.book.itemID; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockBreakable.java b/sp-server/src/main/java/net/minecraft/src/BlockBreakable.java new file mode 100644 index 0000000..a125733 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockBreakable.java @@ -0,0 +1,21 @@ +package net.minecraft.src; + +public class BlockBreakable extends Block { + private boolean localFlag; + private String breakableBlockIcon; + + protected BlockBreakable(int par1, String par2Str, Material par3Material, boolean par4) { + super(par1, par3Material); + this.localFlag = par4; + this.breakableBlockIcon = par2Str; + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return false; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockBrewingStand.java b/sp-server/src/main/java/net/minecraft/src/BlockBrewingStand.java new file mode 100644 index 0000000..08f9eee --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockBrewingStand.java @@ -0,0 +1,160 @@ +package net.minecraft.src; + +import java.util.List; +import java.util.Random; + +public class BlockBrewingStand extends BlockContainer { + private Random rand = new Random(); + + public BlockBrewingStand(int par1) { + super(par1, Material.iron); + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return false; + } + + /** + * The type of render function that is called for this block + */ + public int getRenderType() { + return 25; + } + + /** + * Returns a new instance of a block's tile entity class. Called on placing the + * block. + */ + public TileEntity createNewTileEntity(World par1World) { + return new TileEntityBrewingStand(); + } + + /** + * If this block doesn't render as an ordinary block it will return False + * (examples: signs, buttons, stairs, etc) + */ + public boolean renderAsNormalBlock() { + return false; + } + + /** + * Adds all intersecting collision boxes to a list. (Be sure to only add boxes + * to the list if they intersect the mask.) Parameters: World, X, Y, Z, mask, + * list, colliding entity + */ + public void addCollisionBoxesToList(World par1World, int par2, int par3, int par4, AxisAlignedBB par5AxisAlignedBB, + List par6List, Entity par7Entity) { + this.setBlockBounds(0.4375F, 0.0F, 0.4375F, 0.5625F, 0.875F, 0.5625F); + super.addCollisionBoxesToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity); + this.setBlockBoundsForItemRender(); + super.addCollisionBoxesToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity); + } + + /** + * Sets the block's bounds for rendering it as an item + */ + public void setBlockBoundsForItemRender() { + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.125F, 1.0F); + } + + /** + * Called upon block activation (right click on the block.) + */ + public boolean onBlockActivated(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer, + int par6, float par7, float par8, float par9) { + if (par1World.isRemote) { + return true; + } else { + TileEntityBrewingStand var10 = (TileEntityBrewingStand) par1World.getBlockTileEntity(par2, par3, par4); + + if (var10 != null) { + par5EntityPlayer.displayGUIBrewingStand(var10); + } + + return true; + } + } + + /** + * Called when the block is placed in the world. + */ + public void onBlockPlacedBy(World par1World, int par2, int par3, int par4, EntityLiving par5EntityLiving, + ItemStack par6ItemStack) { + if (par6ItemStack.hasDisplayName()) { + ((TileEntityBrewingStand) par1World.getBlockTileEntity(par2, par3, par4)) + .func_94131_a(par6ItemStack.getDisplayName()); + } + } + + /** + * ejects contained items into the world, and notifies neighbours of an update, + * as appropriate + */ + public void breakBlock(World par1World, int par2, int par3, int par4, int par5, int par6) { + TileEntity var7 = par1World.getBlockTileEntity(par2, par3, par4); + + if (var7 instanceof TileEntityBrewingStand) { + TileEntityBrewingStand var8 = (TileEntityBrewingStand) var7; + + for (int var9 = 0; var9 < var8.getSizeInventory(); ++var9) { + ItemStack var10 = var8.getStackInSlot(var9); + + if (var10 != null) { + float var11 = this.rand.nextFloat() * 0.8F + 0.1F; + float var12 = this.rand.nextFloat() * 0.8F + 0.1F; + float var13 = this.rand.nextFloat() * 0.8F + 0.1F; + + while (var10.stackSize > 0) { + int var14 = this.rand.nextInt(21) + 10; + + if (var14 > var10.stackSize) { + var14 = var10.stackSize; + } + + var10.stackSize -= var14; + EntityItem var15 = new EntityItem(par1World, (double) ((float) par2 + var11), + (double) ((float) par3 + var12), (double) ((float) par4 + var13), + new ItemStack(var10.itemID, var14, var10.getItemDamage())); + float var16 = 0.05F; + var15.motionX = (double) ((float) this.rand.nextGaussian() * var16); + var15.motionY = (double) ((float) this.rand.nextGaussian() * var16 + 0.2F); + var15.motionZ = (double) ((float) this.rand.nextGaussian() * var16); + par1World.spawnEntityInWorld(var15); + } + } + } + } + + super.breakBlock(par1World, par2, par3, par4, par5, par6); + } + + /** + * Returns the ID of the items to drop on destruction. + */ + public int idDropped(int par1, Random par2Random, int par3) { + return Item.brewingStand.itemID; + } + + /** + * If this returns true, then comparators facing away from this block will use + * the value from getComparatorInputOverride instead of the actual redstone + * signal strength. + */ + public boolean hasComparatorInputOverride() { + return true; + } + + /** + * If hasComparatorInputOverride returns true, the return value from this is + * used instead of the redstone signal strength when this block inputs to a + * comparator. + */ + public int getComparatorInputOverride(World par1World, int par2, int par3, int par4, int par5) { + return Container.calcRedstoneFromInventory((IInventory) par1World.getBlockTileEntity(par2, par3, par4)); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockButton.java b/sp-server/src/main/java/net/minecraft/src/BlockButton.java new file mode 100644 index 0000000..e5217e5 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockButton.java @@ -0,0 +1,355 @@ +package net.minecraft.src; + +import java.util.List; +import java.util.Random; + +public abstract class BlockButton extends Block { + /** Whether this button is sensible to arrows, used by wooden buttons. */ + private final boolean sensible; + + protected BlockButton(int par1, boolean par2) { + super(par1, Material.circuits); + this.setTickRandomly(true); + this.setCreativeTab(CreativeTabs.tabRedstone); + this.sensible = par2; + } + + /** + * Returns a bounding box from the pool of bounding boxes (this means this box + * can change after the pool has been cleared to be reused) + */ + public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int par4) { + return null; + } + + /** + * How many world ticks before ticking + */ + public int tickRate(World par1World) { + return this.sensible ? 30 : 20; + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return false; + } + + /** + * If this block doesn't render as an ordinary block it will return False + * (examples: signs, buttons, stairs, etc) + */ + public boolean renderAsNormalBlock() { + return false; + } + + /** + * checks to see if you can place this block can be placed on that side of a + * block: BlockLever overrides + */ + public boolean canPlaceBlockOnSide(World par1World, int par2, int par3, int par4, int par5) { + return par5 == 2 && par1World.isBlockNormalCube(par2, par3, par4 + 1) ? true + : (par5 == 3 && par1World.isBlockNormalCube(par2, par3, par4 - 1) ? true + : (par5 == 4 && par1World.isBlockNormalCube(par2 + 1, par3, par4) ? true + : par5 == 5 && par1World.isBlockNormalCube(par2 - 1, par3, par4))); + } + + /** + * Checks to see if its valid to put this block at the specified coordinates. + * Args: world, x, y, z + */ + public boolean canPlaceBlockAt(World par1World, int par2, int par3, int par4) { + return par1World.isBlockNormalCube(par2 - 1, par3, par4) ? true + : (par1World.isBlockNormalCube(par2 + 1, par3, par4) ? true + : (par1World.isBlockNormalCube(par2, par3, par4 - 1) ? true + : par1World.isBlockNormalCube(par2, par3, par4 + 1))); + } + + /** + * Called when a block is placed using its ItemBlock. Args: World, X, Y, Z, + * side, hitX, hitY, hitZ, block metadata + */ + public int onBlockPlaced(World par1World, int par2, int par3, int par4, int par5, float par6, float par7, + float par8, int par9) { + int var10 = par1World.getBlockMetadata(par2, par3, par4); + int var11 = var10 & 8; + var10 &= 7; + + if (par5 == 2 && par1World.isBlockNormalCube(par2, par3, par4 + 1)) { + var10 = 4; + } else if (par5 == 3 && par1World.isBlockNormalCube(par2, par3, par4 - 1)) { + var10 = 3; + } else if (par5 == 4 && par1World.isBlockNormalCube(par2 + 1, par3, par4)) { + var10 = 2; + } else if (par5 == 5 && par1World.isBlockNormalCube(par2 - 1, par3, par4)) { + var10 = 1; + } else { + var10 = this.getOrientation(par1World, par2, par3, par4); + } + + return var10 + var11; + } + + /** + * Get side which this button is facing. + */ + private int getOrientation(World par1World, int par2, int par3, int par4) { + return par1World.isBlockNormalCube(par2 - 1, par3, par4) ? 1 + : (par1World.isBlockNormalCube(par2 + 1, par3, par4) ? 2 + : (par1World.isBlockNormalCube(par2, par3, par4 - 1) ? 3 + : (par1World.isBlockNormalCube(par2, par3, par4 + 1) ? 4 : 1))); + } + + /** + * Lets the block know when one of its neighbor changes. Doesn't know which + * neighbor changed (coordinates passed are their own) Args: x, y, z, neighbor + * blockID + */ + public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5) { + if (this.redundantCanPlaceBlockAt(par1World, par2, par3, par4)) { + int var6 = par1World.getBlockMetadata(par2, par3, par4) & 7; + boolean var7 = false; + + if (!par1World.isBlockNormalCube(par2 - 1, par3, par4) && var6 == 1) { + var7 = true; + } + + if (!par1World.isBlockNormalCube(par2 + 1, par3, par4) && var6 == 2) { + var7 = true; + } + + if (!par1World.isBlockNormalCube(par2, par3, par4 - 1) && var6 == 3) { + var7 = true; + } + + if (!par1World.isBlockNormalCube(par2, par3, par4 + 1) && var6 == 4) { + var7 = true; + } + + if (var7) { + this.dropBlockAsItem(par1World, par2, par3, par4, par1World.getBlockMetadata(par2, par3, par4), 0); + par1World.setBlockToAir(par2, par3, par4); + } + } + } + + /** + * This method is redundant, check it out... + */ + private boolean redundantCanPlaceBlockAt(World par1World, int par2, int par3, int par4) { + if (!this.canPlaceBlockAt(par1World, par2, par3, par4)) { + this.dropBlockAsItem(par1World, par2, par3, par4, par1World.getBlockMetadata(par2, par3, par4), 0); + par1World.setBlockToAir(par2, par3, par4); + return false; + } else { + return true; + } + } + + /** + * Updates the blocks bounds based on its current state. Args: world, x, y, z + */ + public void setBlockBoundsBasedOnState(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + int var5 = par1IBlockAccess.getBlockMetadata(par2, par3, par4); + this.func_82534_e(var5); + } + + private void func_82534_e(int par1) { + int var2 = par1 & 7; + boolean var3 = (par1 & 8) > 0; + float var4 = 0.375F; + float var5 = 0.625F; + float var6 = 0.1875F; + float var7 = 0.125F; + + if (var3) { + var7 = 0.0625F; + } + + if (var2 == 1) { + this.setBlockBounds(0.0F, var4, 0.5F - var6, var7, var5, 0.5F + var6); + } else if (var2 == 2) { + this.setBlockBounds(1.0F - var7, var4, 0.5F - var6, 1.0F, var5, 0.5F + var6); + } else if (var2 == 3) { + this.setBlockBounds(0.5F - var6, var4, 0.0F, 0.5F + var6, var5, var7); + } else if (var2 == 4) { + this.setBlockBounds(0.5F - var6, var4, 1.0F - var7, 0.5F + var6, var5, 1.0F); + } + } + + /** + * Called when the block is clicked by a player. Args: x, y, z, entityPlayer + */ + public void onBlockClicked(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer) { + } + + /** + * Called upon block activation (right click on the block.) + */ + public boolean onBlockActivated(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer, + int par6, float par7, float par8, float par9) { + int var10 = par1World.getBlockMetadata(par2, par3, par4); + int var11 = var10 & 7; + int var12 = 8 - (var10 & 8); + + if (var12 == 0) { + return true; + } else { + par1World.setBlockMetadata(par2, par3, par4, var11 + var12, 3); + par1World.markBlockRangeForRenderUpdate(par2, par3, par4, par2, par3, par4); + par1World.playSoundEffect((double) par2 + 0.5D, (double) par3 + 0.5D, (double) par4 + 0.5D, "random.click", + 0.3F, 0.6F); + this.func_82536_d(par1World, par2, par3, par4, var11); + par1World.scheduleBlockUpdate(par2, par3, par4, this.blockID, this.tickRate(par1World)); + return true; + } + } + + /** + * ejects contained items into the world, and notifies neighbours of an update, + * as appropriate + */ + public void breakBlock(World par1World, int par2, int par3, int par4, int par5, int par6) { + if ((par6 & 8) > 0) { + int var7 = par6 & 7; + this.func_82536_d(par1World, par2, par3, par4, var7); + } + + super.breakBlock(par1World, par2, par3, par4, par5, par6); + } + + /** + * Returns true if the block is emitting indirect/weak redstone power on the + * specified side. If isBlockNormalCube returns true, standard redstone + * propagation rules will apply instead and this will not be called. Args: + * World, X, Y, Z, side. Note that the side is reversed - eg it is 1 (up) when + * checking the bottom of the block. + */ + public int isProvidingWeakPower(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5) { + return (par1IBlockAccess.getBlockMetadata(par2, par3, par4) & 8) > 0 ? 15 : 0; + } + + /** + * Returns true if the block is emitting direct/strong redstone power on the + * specified side. Args: World, X, Y, Z, side. Note that the side is reversed - + * eg it is 1 (up) when checking the bottom of the block. + */ + public int isProvidingStrongPower(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5) { + int var6 = par1IBlockAccess.getBlockMetadata(par2, par3, par4); + + if ((var6 & 8) == 0) { + return 0; + } else { + int var7 = var6 & 7; + return var7 == 5 && par5 == 1 ? 15 + : (var7 == 4 && par5 == 2 ? 15 + : (var7 == 3 && par5 == 3 ? 15 + : (var7 == 2 && par5 == 4 ? 15 : (var7 == 1 && par5 == 5 ? 15 : 0)))); + } + } + + /** + * Can this block provide power. Only wire currently seems to have this change + * based on its state. + */ + public boolean canProvidePower() { + return true; + } + + /** + * Ticks the block if it's been scheduled + */ + public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random) { + if (!par1World.isRemote) { + int var6 = par1World.getBlockMetadata(par2, par3, par4); + + if ((var6 & 8) != 0) { + if (this.sensible) { + this.func_82535_o(par1World, par2, par3, par4); + } else { + par1World.setBlockMetadata(par2, par3, par4, var6 & 7, 3); + int var7 = var6 & 7; + this.func_82536_d(par1World, par2, par3, par4, var7); + par1World.playSoundEffect((double) par2 + 0.5D, (double) par3 + 0.5D, (double) par4 + 0.5D, + "random.click", 0.3F, 0.5F); + par1World.markBlockRangeForRenderUpdate(par2, par3, par4, par2, par3, par4); + } + } + } + } + + /** + * Sets the block's bounds for rendering it as an item + */ + public void setBlockBoundsForItemRender() { + float var1 = 0.1875F; + float var2 = 0.125F; + float var3 = 0.125F; + this.setBlockBounds(0.5F - var1, 0.5F - var2, 0.5F - var3, 0.5F + var1, 0.5F + var2, 0.5F + var3); + } + + /** + * Triggered whenever an entity collides with this block (enters into the + * block). Args: world, x, y, z, entity + */ + public void onEntityCollidedWithBlock(World par1World, int par2, int par3, int par4, Entity par5Entity) { + if (!par1World.isRemote) { + if (this.sensible) { + if ((par1World.getBlockMetadata(par2, par3, par4) & 8) == 0) { + this.func_82535_o(par1World, par2, par3, par4); + } + } + } + } + + private void func_82535_o(World par1World, int par2, int par3, int par4) { + int var5 = par1World.getBlockMetadata(par2, par3, par4); + int var6 = var5 & 7; + boolean var7 = (var5 & 8) != 0; + this.func_82534_e(var5); + List var9 = par1World.getEntitiesWithinAABB(EntityArrow.class, + AxisAlignedBB.getAABBPool().getAABB((double) par2 + this.minX, (double) par3 + this.minY, + (double) par4 + this.minZ, (double) par2 + this.maxX, (double) par3 + this.maxY, + (double) par4 + this.maxZ)); + boolean var8 = !var9.isEmpty(); + + if (var8 && !var7) { + par1World.setBlockMetadata(par2, par3, par4, var6 | 8, 3); + this.func_82536_d(par1World, par2, par3, par4, var6); + par1World.markBlockRangeForRenderUpdate(par2, par3, par4, par2, par3, par4); + par1World.playSoundEffect((double) par2 + 0.5D, (double) par3 + 0.5D, (double) par4 + 0.5D, "random.click", + 0.3F, 0.6F); + } + + if (!var8 && var7) { + par1World.setBlockMetadata(par2, par3, par4, var6, 3); + this.func_82536_d(par1World, par2, par3, par4, var6); + par1World.markBlockRangeForRenderUpdate(par2, par3, par4, par2, par3, par4); + par1World.playSoundEffect((double) par2 + 0.5D, (double) par3 + 0.5D, (double) par4 + 0.5D, "random.click", + 0.3F, 0.5F); + } + + if (var8) { + par1World.scheduleBlockUpdate(par2, par3, par4, this.blockID, this.tickRate(par1World)); + } + } + + private void func_82536_d(World par1World, int par2, int par3, int par4, int par5) { + par1World.notifyBlocksOfNeighborChange(par2, par3, par4, this.blockID); + + if (par5 == 1) { + par1World.notifyBlocksOfNeighborChange(par2 - 1, par3, par4, this.blockID); + } else if (par5 == 2) { + par1World.notifyBlocksOfNeighborChange(par2 + 1, par3, par4, this.blockID); + } else if (par5 == 3) { + par1World.notifyBlocksOfNeighborChange(par2, par3, par4 - 1, this.blockID); + } else if (par5 == 4) { + par1World.notifyBlocksOfNeighborChange(par2, par3, par4 + 1, this.blockID); + } else { + par1World.notifyBlocksOfNeighborChange(par2, par3 - 1, par4, this.blockID); + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockButtonStone.java b/sp-server/src/main/java/net/minecraft/src/BlockButtonStone.java new file mode 100644 index 0000000..4472d13 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockButtonStone.java @@ -0,0 +1,7 @@ +package net.minecraft.src; + +public class BlockButtonStone extends BlockButton { + protected BlockButtonStone(int par1) { + super(par1, false); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockButtonWood.java b/sp-server/src/main/java/net/minecraft/src/BlockButtonWood.java new file mode 100644 index 0000000..071daf5 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockButtonWood.java @@ -0,0 +1,7 @@ +package net.minecraft.src; + +public class BlockButtonWood extends BlockButton { + protected BlockButtonWood(int par1) { + super(par1, true); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockCactus.java b/sp-server/src/main/java/net/minecraft/src/BlockCactus.java new file mode 100644 index 0000000..6f7bf81 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockCactus.java @@ -0,0 +1,118 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockCactus extends Block { + protected BlockCactus(int par1) { + super(par1, Material.cactus); + this.setTickRandomly(true); + this.setCreativeTab(CreativeTabs.tabDecorations); + } + + /** + * Ticks the block if it's been scheduled + */ + public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random) { + if (par1World.isAirBlock(par2, par3 + 1, par4)) { + int var6; + + for (var6 = 1; par1World.getBlockId(par2, par3 - var6, par4) == this.blockID; ++var6) { + ; + } + + if (var6 < 3) { + int var7 = par1World.getBlockMetadata(par2, par3, par4); + + if (var7 == 15) { + par1World.setBlock(par2, par3 + 1, par4, this.blockID); + par1World.setBlockMetadata(par2, par3, par4, 0, 4); + this.onNeighborBlockChange(par1World, par2, par3 + 1, par4, this.blockID); + } else { + par1World.setBlockMetadata(par2, par3, par4, var7 + 1, 4); + } + } + } + } + + /** + * Returns a bounding box from the pool of bounding boxes (this means this box + * can change after the pool has been cleared to be reused) + */ + public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int par4) { + float var5 = 0.0625F; + return AxisAlignedBB.getAABBPool().getAABB((double) ((float) par2 + var5), (double) par3, + (double) ((float) par4 + var5), (double) ((float) (par2 + 1) - var5), + (double) ((float) (par3 + 1) - var5), (double) ((float) (par4 + 1) - var5)); + } + + /** + * If this block doesn't render as an ordinary block it will return False + * (examples: signs, buttons, stairs, etc) + */ + public boolean renderAsNormalBlock() { + return false; + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return false; + } + + /** + * The type of render function that is called for this block + */ + public int getRenderType() { + return 13; + } + + /** + * Checks to see if its valid to put this block at the specified coordinates. + * Args: world, x, y, z + */ + public boolean canPlaceBlockAt(World par1World, int par2, int par3, int par4) { + return !super.canPlaceBlockAt(par1World, par2, par3, par4) ? false + : this.canBlockStay(par1World, par2, par3, par4); + } + + /** + * Lets the block know when one of its neighbor changes. Doesn't know which + * neighbor changed (coordinates passed are their own) Args: x, y, z, neighbor + * blockID + */ + public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5) { + if (!this.canBlockStay(par1World, par2, par3, par4)) { + par1World.destroyBlock(par2, par3, par4, true); + } + } + + /** + * Can this block stay at this position. Similar to canPlaceBlockAt except gets + * checked often with plants. + */ + public boolean canBlockStay(World par1World, int par2, int par3, int par4) { + if (par1World.getBlockMaterial(par2 - 1, par3, par4).isSolid()) { + return false; + } else if (par1World.getBlockMaterial(par2 + 1, par3, par4).isSolid()) { + return false; + } else if (par1World.getBlockMaterial(par2, par3, par4 - 1).isSolid()) { + return false; + } else if (par1World.getBlockMaterial(par2, par3, par4 + 1).isSolid()) { + return false; + } else { + int var5 = par1World.getBlockId(par2, par3 - 1, par4); + return var5 == Block.cactus.blockID || var5 == Block.sand.blockID; + } + } + + /** + * Triggered whenever an entity collides with this block (enters into the + * block). Args: world, x, y, z, entity + */ + public void onEntityCollidedWithBlock(World par1World, int par2, int par3, int par4, Entity par5Entity) { + par5Entity.attackEntityFrom(DamageSource.cactus, 1); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockCake.java b/sp-server/src/main/java/net/minecraft/src/BlockCake.java new file mode 100644 index 0000000..53fbda7 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockCake.java @@ -0,0 +1,135 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockCake extends Block { + protected BlockCake(int par1) { + super(par1, Material.cake); + this.setTickRandomly(true); + } + + /** + * Updates the blocks bounds based on its current state. Args: world, x, y, z + */ + public void setBlockBoundsBasedOnState(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + int var5 = par1IBlockAccess.getBlockMetadata(par2, par3, par4); + float var6 = 0.0625F; + float var7 = (float) (1 + var5 * 2) / 16.0F; + float var8 = 0.5F; + this.setBlockBounds(var7, 0.0F, var6, 1.0F - var6, var8, 1.0F - var6); + } + + /** + * Sets the block's bounds for rendering it as an item + */ + public void setBlockBoundsForItemRender() { + float var1 = 0.0625F; + float var2 = 0.5F; + this.setBlockBounds(var1, 0.0F, var1, 1.0F - var1, var2, 1.0F - var1); + } + + /** + * Returns a bounding box from the pool of bounding boxes (this means this box + * can change after the pool has been cleared to be reused) + */ + public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int par4) { + int var5 = par1World.getBlockMetadata(par2, par3, par4); + float var6 = 0.0625F; + float var7 = (float) (1 + var5 * 2) / 16.0F; + float var8 = 0.5F; + return AxisAlignedBB.getAABBPool().getAABB((double) ((float) par2 + var7), (double) par3, + (double) ((float) par4 + var6), (double) ((float) (par2 + 1) - var6), + (double) ((float) par3 + var8 - var6), (double) ((float) (par4 + 1) - var6)); + } + + /** + * If this block doesn't render as an ordinary block it will return False + * (examples: signs, buttons, stairs, etc) + */ + public boolean renderAsNormalBlock() { + return false; + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return false; + } + + /** + * Called upon block activation (right click on the block.) + */ + public boolean onBlockActivated(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer, + int par6, float par7, float par8, float par9) { + this.eatCakeSlice(par1World, par2, par3, par4, par5EntityPlayer); + return true; + } + + /** + * Called when the block is clicked by a player. Args: x, y, z, entityPlayer + */ + public void onBlockClicked(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer) { + this.eatCakeSlice(par1World, par2, par3, par4, par5EntityPlayer); + } + + /** + * Heals the player and removes a slice from the cake. + */ + private void eatCakeSlice(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer) { + if (par5EntityPlayer.canEat(false)) { + par5EntityPlayer.getFoodStats().addStats(2, 0.1F); + int var6 = par1World.getBlockMetadata(par2, par3, par4) + 1; + + if (var6 >= 6) { + par1World.setBlockToAir(par2, par3, par4); + } else { + par1World.setBlockMetadata(par2, par3, par4, var6, 2); + } + } + } + + /** + * Checks to see if its valid to put this block at the specified coordinates. + * Args: world, x, y, z + */ + public boolean canPlaceBlockAt(World par1World, int par2, int par3, int par4) { + return !super.canPlaceBlockAt(par1World, par2, par3, par4) ? false + : this.canBlockStay(par1World, par2, par3, par4); + } + + /** + * Lets the block know when one of its neighbor changes. Doesn't know which + * neighbor changed (coordinates passed are their own) Args: x, y, z, neighbor + * blockID + */ + public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5) { + if (!this.canBlockStay(par1World, par2, par3, par4)) { + par1World.setBlockToAir(par2, par3, par4); + } + } + + /** + * Can this block stay at this position. Similar to canPlaceBlockAt except gets + * checked often with plants. + */ + public boolean canBlockStay(World par1World, int par2, int par3, int par4) { + return par1World.getBlockMaterial(par2, par3 - 1, par4).isSolid(); + } + + /** + * Returns the quantity of items to drop on block destruction. + */ + public int quantityDropped(Random par1Random) { + return 0; + } + + /** + * Returns the ID of the items to drop on destruction. + */ + public int idDropped(int par1, Random par2Random, int par3) { + return 0; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockCarrot.java b/sp-server/src/main/java/net/minecraft/src/BlockCarrot.java new file mode 100644 index 0000000..b93b5b3 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockCarrot.java @@ -0,0 +1,21 @@ +package net.minecraft.src; + +public class BlockCarrot extends BlockCrops { + public BlockCarrot(int par1) { + super(par1); + } + + /** + * Generate a seed ItemStack for this crop. + */ + protected int getSeedItem() { + return Item.carrot.itemID; + } + + /** + * Generate a crop produce ItemStack for this crop. + */ + protected int getCropItem() { + return Item.carrot.itemID; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockCauldron.java b/sp-server/src/main/java/net/minecraft/src/BlockCauldron.java new file mode 100644 index 0000000..d590df7 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockCauldron.java @@ -0,0 +1,144 @@ +package net.minecraft.src; + +import java.util.List; +import java.util.Random; + +public class BlockCauldron extends Block { + public BlockCauldron(int par1) { + super(par1, Material.iron); + } + + /** + * Adds all intersecting collision boxes to a list. (Be sure to only add boxes + * to the list if they intersect the mask.) Parameters: World, X, Y, Z, mask, + * list, colliding entity + */ + public void addCollisionBoxesToList(World par1World, int par2, int par3, int par4, AxisAlignedBB par5AxisAlignedBB, + List par6List, Entity par7Entity) { + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.3125F, 1.0F); + super.addCollisionBoxesToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity); + float var8 = 0.125F; + this.setBlockBounds(0.0F, 0.0F, 0.0F, var8, 1.0F, 1.0F); + super.addCollisionBoxesToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity); + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, var8); + super.addCollisionBoxesToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity); + this.setBlockBounds(1.0F - var8, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + super.addCollisionBoxesToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity); + this.setBlockBounds(0.0F, 0.0F, 1.0F - var8, 1.0F, 1.0F, 1.0F); + super.addCollisionBoxesToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity); + this.setBlockBoundsForItemRender(); + } + + /** + * Sets the block's bounds for rendering it as an item + */ + public void setBlockBoundsForItemRender() { + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return false; + } + + /** + * The type of render function that is called for this block + */ + public int getRenderType() { + return 24; + } + + /** + * If this block doesn't render as an ordinary block it will return False + * (examples: signs, buttons, stairs, etc) + */ + public boolean renderAsNormalBlock() { + return false; + } + + /** + * Called upon block activation (right click on the block.) + */ + public boolean onBlockActivated(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer, + int par6, float par7, float par8, float par9) { + if (par1World.isRemote) { + return true; + } else { + ItemStack var10 = par5EntityPlayer.inventory.getCurrentItem(); + + if (var10 == null) { + return true; + } else { + int var11 = par1World.getBlockMetadata(par2, par3, par4); + + if (var10.itemID == Item.bucketWater.itemID) { + if (var11 < 3) { + if (!par5EntityPlayer.capabilities.isCreativeMode) { + par5EntityPlayer.inventory.setInventorySlotContents(par5EntityPlayer.inventory.currentItem, + new ItemStack(Item.bucketEmpty)); + } + + par1World.setBlockMetadata(par2, par3, par4, 3, 2); + } + + return true; + } else { + if (var10.itemID == Item.glassBottle.itemID) { + if (var11 > 0) { + ItemStack var12 = new ItemStack(Item.potion, 1, 0); + + if (!par5EntityPlayer.inventory.addItemStackToInventory(var12)) { + par1World.spawnEntityInWorld(new EntityItem(par1World, (double) par2 + 0.5D, + (double) par3 + 1.5D, (double) par4 + 0.5D, var12)); + } else if (par5EntityPlayer instanceof EntityPlayerMP) { + ((EntityPlayerMP) par5EntityPlayer) + .sendContainerToPlayer(par5EntityPlayer.inventoryContainer); + } + + --var10.stackSize; + + if (var10.stackSize <= 0) { + par5EntityPlayer.inventory.setInventorySlotContents( + par5EntityPlayer.inventory.currentItem, (ItemStack) null); + } + + par1World.setBlockMetadata(par2, par3, par4, var11 - 1, 2); + } + } else if (var11 > 0 && var10.getItem() instanceof ItemArmor + && ((ItemArmor) var10.getItem()).getArmorMaterial() == EnumArmorMaterial.CLOTH) { + ItemArmor var13 = (ItemArmor) var10.getItem(); + var13.removeColor(var10); + par1World.setBlockMetadata(par2, par3, par4, var11 - 1, 2); + return true; + } + + return true; + } + } + } + } + + /** + * currently only used by BlockCauldron to incrament meta-data during rain + */ + public void fillWithRain(World par1World, int par2, int par3, int par4) { + if (par1World.rand.nextInt(20) == 1) { + int var5 = par1World.getBlockMetadata(par2, par3, par4); + + if (var5 < 3) { + par1World.setBlockMetadata(par2, par3, par4, var5 + 1, 2); + } + } + } + + /** + * Returns the ID of the items to drop on destruction. + */ + public int idDropped(int par1, Random par2Random, int par3) { + return Item.cauldron.itemID; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockChest.java b/sp-server/src/main/java/net/minecraft/src/BlockChest.java new file mode 100644 index 0000000..fdba700 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockChest.java @@ -0,0 +1,494 @@ +package net.minecraft.src; + +import java.util.Iterator; +import java.util.Random; + +public class BlockChest extends BlockContainer { + private final Random random = new Random(); + + /** Determines whether of not the chest is trapped. */ + public final int isTrapped; + + protected BlockChest(int par1, int par2) { + super(par1, Material.wood); + this.isTrapped = par2; + this.setCreativeTab(CreativeTabs.tabDecorations); + this.setBlockBounds(0.0625F, 0.0F, 0.0625F, 0.9375F, 0.875F, 0.9375F); + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return false; + } + + /** + * If this block doesn't render as an ordinary block it will return False + * (examples: signs, buttons, stairs, etc) + */ + public boolean renderAsNormalBlock() { + return false; + } + + /** + * The type of render function that is called for this block + */ + public int getRenderType() { + return 22; + } + + /** + * Updates the blocks bounds based on its current state. Args: world, x, y, z + */ + public void setBlockBoundsBasedOnState(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + if (par1IBlockAccess.getBlockId(par2, par3, par4 - 1) == this.blockID) { + this.setBlockBounds(0.0625F, 0.0F, 0.0F, 0.9375F, 0.875F, 0.9375F); + } else if (par1IBlockAccess.getBlockId(par2, par3, par4 + 1) == this.blockID) { + this.setBlockBounds(0.0625F, 0.0F, 0.0625F, 0.9375F, 0.875F, 1.0F); + } else if (par1IBlockAccess.getBlockId(par2 - 1, par3, par4) == this.blockID) { + this.setBlockBounds(0.0F, 0.0F, 0.0625F, 0.9375F, 0.875F, 0.9375F); + } else if (par1IBlockAccess.getBlockId(par2 + 1, par3, par4) == this.blockID) { + this.setBlockBounds(0.0625F, 0.0F, 0.0625F, 1.0F, 0.875F, 0.9375F); + } else { + this.setBlockBounds(0.0625F, 0.0F, 0.0625F, 0.9375F, 0.875F, 0.9375F); + } + } + + /** + * Called whenever the block is added into the world. Args: world, x, y, z + */ + public void onBlockAdded(World par1World, int par2, int par3, int par4) { + super.onBlockAdded(par1World, par2, par3, par4); + this.unifyAdjacentChests(par1World, par2, par3, par4); + int var5 = par1World.getBlockId(par2, par3, par4 - 1); + int var6 = par1World.getBlockId(par2, par3, par4 + 1); + int var7 = par1World.getBlockId(par2 - 1, par3, par4); + int var8 = par1World.getBlockId(par2 + 1, par3, par4); + + if (var5 == this.blockID) { + this.unifyAdjacentChests(par1World, par2, par3, par4 - 1); + } + + if (var6 == this.blockID) { + this.unifyAdjacentChests(par1World, par2, par3, par4 + 1); + } + + if (var7 == this.blockID) { + this.unifyAdjacentChests(par1World, par2 - 1, par3, par4); + } + + if (var8 == this.blockID) { + this.unifyAdjacentChests(par1World, par2 + 1, par3, par4); + } + } + + /** + * Called when the block is placed in the world. + */ + public void onBlockPlacedBy(World par1World, int par2, int par3, int par4, EntityLiving par5EntityLiving, + ItemStack par6ItemStack) { + int var7 = par1World.getBlockId(par2, par3, par4 - 1); + int var8 = par1World.getBlockId(par2, par3, par4 + 1); + int var9 = par1World.getBlockId(par2 - 1, par3, par4); + int var10 = par1World.getBlockId(par2 + 1, par3, par4); + byte var11 = 0; + int var12 = MathHelper.floor_double((double) (par5EntityLiving.rotationYaw * 4.0F / 360.0F) + 0.5D) & 3; + + if (var12 == 0) { + var11 = 2; + } + + if (var12 == 1) { + var11 = 5; + } + + if (var12 == 2) { + var11 = 3; + } + + if (var12 == 3) { + var11 = 4; + } + + if (var7 != this.blockID && var8 != this.blockID && var9 != this.blockID && var10 != this.blockID) { + par1World.setBlockMetadata(par2, par3, par4, var11, 3); + } else { + if ((var7 == this.blockID || var8 == this.blockID) && (var11 == 4 || var11 == 5)) { + if (var7 == this.blockID) { + par1World.setBlockMetadata(par2, par3, par4 - 1, var11, 3); + } else { + par1World.setBlockMetadata(par2, par3, par4 + 1, var11, 3); + } + + par1World.setBlockMetadata(par2, par3, par4, var11, 3); + } + + if ((var9 == this.blockID || var10 == this.blockID) && (var11 == 2 || var11 == 3)) { + if (var9 == this.blockID) { + par1World.setBlockMetadata(par2 - 1, par3, par4, var11, 3); + } else { + par1World.setBlockMetadata(par2 + 1, par3, par4, var11, 3); + } + + par1World.setBlockMetadata(par2, par3, par4, var11, 3); + } + } + + if (par6ItemStack.hasDisplayName()) { + ((TileEntityChest) par1World.getBlockTileEntity(par2, par3, par4)) + .func_94043_a(par6ItemStack.getDisplayName()); + } + } + + /** + * Turns the adjacent chests to a double chest. + */ + public void unifyAdjacentChests(World par1World, int par2, int par3, int par4) { + if (!par1World.isRemote) { + int var5 = par1World.getBlockId(par2, par3, par4 - 1); + int var6 = par1World.getBlockId(par2, par3, par4 + 1); + int var7 = par1World.getBlockId(par2 - 1, par3, par4); + int var8 = par1World.getBlockId(par2 + 1, par3, par4); + boolean var9 = true; + int var10; + int var11; + boolean var12; + byte var13; + int var14; + + if (var5 != this.blockID && var6 != this.blockID) { + if (var7 != this.blockID && var8 != this.blockID) { + var13 = 3; + + if (Block.opaqueCubeLookup[var5] && !Block.opaqueCubeLookup[var6]) { + var13 = 3; + } + + if (Block.opaqueCubeLookup[var6] && !Block.opaqueCubeLookup[var5]) { + var13 = 2; + } + + if (Block.opaqueCubeLookup[var7] && !Block.opaqueCubeLookup[var8]) { + var13 = 5; + } + + if (Block.opaqueCubeLookup[var8] && !Block.opaqueCubeLookup[var7]) { + var13 = 4; + } + } else { + var10 = par1World.getBlockId(var7 == this.blockID ? par2 - 1 : par2 + 1, par3, par4 - 1); + var11 = par1World.getBlockId(var7 == this.blockID ? par2 - 1 : par2 + 1, par3, par4 + 1); + var13 = 3; + var12 = true; + + if (var7 == this.blockID) { + var14 = par1World.getBlockMetadata(par2 - 1, par3, par4); + } else { + var14 = par1World.getBlockMetadata(par2 + 1, par3, par4); + } + + if (var14 == 2) { + var13 = 2; + } + + if ((Block.opaqueCubeLookup[var5] || Block.opaqueCubeLookup[var10]) && !Block.opaqueCubeLookup[var6] + && !Block.opaqueCubeLookup[var11]) { + var13 = 3; + } + + if ((Block.opaqueCubeLookup[var6] || Block.opaqueCubeLookup[var11]) && !Block.opaqueCubeLookup[var5] + && !Block.opaqueCubeLookup[var10]) { + var13 = 2; + } + } + } else { + var10 = par1World.getBlockId(par2 - 1, par3, var5 == this.blockID ? par4 - 1 : par4 + 1); + var11 = par1World.getBlockId(par2 + 1, par3, var5 == this.blockID ? par4 - 1 : par4 + 1); + var13 = 5; + var12 = true; + + if (var5 == this.blockID) { + var14 = par1World.getBlockMetadata(par2, par3, par4 - 1); + } else { + var14 = par1World.getBlockMetadata(par2, par3, par4 + 1); + } + + if (var14 == 4) { + var13 = 4; + } + + if ((Block.opaqueCubeLookup[var7] || Block.opaqueCubeLookup[var10]) && !Block.opaqueCubeLookup[var8] + && !Block.opaqueCubeLookup[var11]) { + var13 = 5; + } + + if ((Block.opaqueCubeLookup[var8] || Block.opaqueCubeLookup[var11]) && !Block.opaqueCubeLookup[var7] + && !Block.opaqueCubeLookup[var10]) { + var13 = 4; + } + } + + par1World.setBlockMetadata(par2, par3, par4, var13, 3); + } + } + + /** + * Checks to see if its valid to put this block at the specified coordinates. + * Args: world, x, y, z + */ + public boolean canPlaceBlockAt(World par1World, int par2, int par3, int par4) { + int var5 = 0; + + if (par1World.getBlockId(par2 - 1, par3, par4) == this.blockID) { + ++var5; + } + + if (par1World.getBlockId(par2 + 1, par3, par4) == this.blockID) { + ++var5; + } + + if (par1World.getBlockId(par2, par3, par4 - 1) == this.blockID) { + ++var5; + } + + if (par1World.getBlockId(par2, par3, par4 + 1) == this.blockID) { + ++var5; + } + + return var5 > 1 ? false + : (this.isThereANeighborChest(par1World, par2 - 1, par3, par4) ? false + : (this.isThereANeighborChest(par1World, par2 + 1, par3, par4) ? false + : (this.isThereANeighborChest(par1World, par2, par3, par4 - 1) ? false + : !this.isThereANeighborChest(par1World, par2, par3, par4 + 1)))); + } + + /** + * Checks the neighbor blocks to see if there is a chest there. Args: world, x, + * y, z + */ + private boolean isThereANeighborChest(World par1World, int par2, int par3, int par4) { + return par1World.getBlockId(par2, par3, par4) != this.blockID ? false + : (par1World.getBlockId(par2 - 1, par3, par4) == this.blockID ? true + : (par1World.getBlockId(par2 + 1, par3, par4) == this.blockID ? true + : (par1World.getBlockId(par2, par3, par4 - 1) == this.blockID ? true + : par1World.getBlockId(par2, par3, par4 + 1) == this.blockID))); + } + + /** + * Lets the block know when one of its neighbor changes. Doesn't know which + * neighbor changed (coordinates passed are their own) Args: x, y, z, neighbor + * blockID + */ + public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5) { + super.onNeighborBlockChange(par1World, par2, par3, par4, par5); + TileEntityChest var6 = (TileEntityChest) par1World.getBlockTileEntity(par2, par3, par4); + + if (var6 != null) { + var6.updateContainingBlockInfo(); + } + } + + /** + * ejects contained items into the world, and notifies neighbours of an update, + * as appropriate + */ + public void breakBlock(World par1World, int par2, int par3, int par4, int par5, int par6) { + TileEntityChest var7 = (TileEntityChest) par1World.getBlockTileEntity(par2, par3, par4); + + if (var7 != null) { + for (int var8 = 0; var8 < var7.getSizeInventory(); ++var8) { + ItemStack var9 = var7.getStackInSlot(var8); + + if (var9 != null) { + float var10 = this.random.nextFloat() * 0.8F + 0.1F; + float var11 = this.random.nextFloat() * 0.8F + 0.1F; + EntityItem var14; + + for (float var12 = this.random.nextFloat() * 0.8F + 0.1F; var9.stackSize > 0; par1World + .spawnEntityInWorld(var14)) { + int var13 = this.random.nextInt(21) + 10; + + if (var13 > var9.stackSize) { + var13 = var9.stackSize; + } + + var9.stackSize -= var13; + var14 = new EntityItem(par1World, (double) ((float) par2 + var10), + (double) ((float) par3 + var11), (double) ((float) par4 + var12), + new ItemStack(var9.itemID, var13, var9.getItemDamage())); + float var15 = 0.05F; + var14.motionX = (double) ((float) this.random.nextGaussian() * var15); + var14.motionY = (double) ((float) this.random.nextGaussian() * var15 + 0.2F); + var14.motionZ = (double) ((float) this.random.nextGaussian() * var15); + + if (var9.hasTagCompound()) { + var14.getEntityItem().setTagCompound((NBTTagCompound) var9.getTagCompound().copy()); + } + } + } + } + + par1World.func_96440_m(par2, par3, par4, par5); + } + + super.breakBlock(par1World, par2, par3, par4, par5, par6); + } + + /** + * Called upon block activation (right click on the block.) + */ + public boolean onBlockActivated(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer, + int par6, float par7, float par8, float par9) { + if (par1World.isRemote) { + return true; + } else { + IInventory var10 = this.getInventory(par1World, par2, par3, par4); + + if (var10 != null) { + par5EntityPlayer.displayGUIChest(var10); + } + + return true; + } + } + + /** + * Gets the inventory of the chest at the specified coords, accounting for + * blocks or ocelots on top of the chest, and double chests. + */ + public IInventory getInventory(World par1World, int par2, int par3, int par4) { + Object var5 = (TileEntityChest) par1World.getBlockTileEntity(par2, par3, par4); + + if (var5 == null) { + return null; + } else if (par1World.isBlockNormalCube(par2, par3 + 1, par4)) { + return null; + } else if (isOcelotBlockingChest(par1World, par2, par3, par4)) { + return null; + } else if (par1World.getBlockId(par2 - 1, par3, par4) == this.blockID + && (par1World.isBlockNormalCube(par2 - 1, par3 + 1, par4) + || isOcelotBlockingChest(par1World, par2 - 1, par3, par4))) { + return null; + } else if (par1World.getBlockId(par2 + 1, par3, par4) == this.blockID + && (par1World.isBlockNormalCube(par2 + 1, par3 + 1, par4) + || isOcelotBlockingChest(par1World, par2 + 1, par3, par4))) { + return null; + } else if (par1World.getBlockId(par2, par3, par4 - 1) == this.blockID + && (par1World.isBlockNormalCube(par2, par3 + 1, par4 - 1) + || isOcelotBlockingChest(par1World, par2, par3, par4 - 1))) { + return null; + } else if (par1World.getBlockId(par2, par3, par4 + 1) == this.blockID + && (par1World.isBlockNormalCube(par2, par3 + 1, par4 + 1) + || isOcelotBlockingChest(par1World, par2, par3, par4 + 1))) { + return null; + } else { + if (par1World.getBlockId(par2 - 1, par3, par4) == this.blockID) { + var5 = new InventoryLargeChest("container.chestDouble", + (TileEntityChest) par1World.getBlockTileEntity(par2 - 1, par3, par4), (IInventory) var5); + } + + if (par1World.getBlockId(par2 + 1, par3, par4) == this.blockID) { + var5 = new InventoryLargeChest("container.chestDouble", (IInventory) var5, + (TileEntityChest) par1World.getBlockTileEntity(par2 + 1, par3, par4)); + } + + if (par1World.getBlockId(par2, par3, par4 - 1) == this.blockID) { + var5 = new InventoryLargeChest("container.chestDouble", + (TileEntityChest) par1World.getBlockTileEntity(par2, par3, par4 - 1), (IInventory) var5); + } + + if (par1World.getBlockId(par2, par3, par4 + 1) == this.blockID) { + var5 = new InventoryLargeChest("container.chestDouble", (IInventory) var5, + (TileEntityChest) par1World.getBlockTileEntity(par2, par3, par4 + 1)); + } + + return (IInventory) var5; + } + } + + /** + * Returns a new instance of a block's tile entity class. Called on placing the + * block. + */ + public TileEntity createNewTileEntity(World par1World) { + TileEntityChest var2 = new TileEntityChest(); + return var2; + } + + /** + * Can this block provide power. Only wire currently seems to have this change + * based on its state. + */ + public boolean canProvidePower() { + return this.isTrapped == 1; + } + + /** + * Returns true if the block is emitting indirect/weak redstone power on the + * specified side. If isBlockNormalCube returns true, standard redstone + * propagation rules will apply instead and this will not be called. Args: + * World, X, Y, Z, side. Note that the side is reversed - eg it is 1 (up) when + * checking the bottom of the block. + */ + public int isProvidingWeakPower(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5) { + if (!this.canProvidePower()) { + return 0; + } else { + int var6 = ((TileEntityChest) par1IBlockAccess.getBlockTileEntity(par2, par3, par4)).numUsingPlayers; + return MathHelper.clamp_int(var6, 0, 15); + } + } + + /** + * Returns true if the block is emitting direct/strong redstone power on the + * specified side. Args: World, X, Y, Z, side. Note that the side is reversed - + * eg it is 1 (up) when checking the bottom of the block. + */ + public int isProvidingStrongPower(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5) { + return par5 == 1 ? this.isProvidingWeakPower(par1IBlockAccess, par2, par3, par4, par5) : 0; + } + + /** + * Looks for a sitting ocelot within certain bounds. Such an ocelot is + * considered to be blocking access to the chest. + */ + private static boolean isOcelotBlockingChest(World par0World, int par1, int par2, int par3) { + Iterator var4 = par0World.getEntitiesWithinAABB(EntityOcelot.class, + AxisAlignedBB.getAABBPool().getAABB((double) par1, (double) (par2 + 1), (double) par3, + (double) (par1 + 1), (double) (par2 + 2), (double) (par3 + 1))) + .iterator(); + EntityOcelot var6; + + do { + if (!var4.hasNext()) { + return false; + } + + EntityOcelot var5 = (EntityOcelot) var4.next(); + var6 = (EntityOcelot) var5; + } while (!var6.isSitting()); + + return true; + } + + /** + * If this returns true, then comparators facing away from this block will use + * the value from getComparatorInputOverride instead of the actual redstone + * signal strength. + */ + public boolean hasComparatorInputOverride() { + return true; + } + + /** + * If hasComparatorInputOverride returns true, the return value from this is + * used instead of the redstone signal strength when this block inputs to a + * comparator. + */ + public int getComparatorInputOverride(World par1World, int par2, int par3, int par4, int par5) { + return Container.calcRedstoneFromInventory(this.getInventory(par1World, par2, par3, par4)); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockClay.java b/sp-server/src/main/java/net/minecraft/src/BlockClay.java new file mode 100644 index 0000000..ddab3b6 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockClay.java @@ -0,0 +1,24 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockClay extends Block { + public BlockClay(int par1) { + super(par1, Material.clay); + this.setCreativeTab(CreativeTabs.tabBlock); + } + + /** + * Returns the ID of the items to drop on destruction. + */ + public int idDropped(int par1, Random par2Random, int par3) { + return Item.clay.itemID; + } + + /** + * Returns the quantity of items to drop on block destruction. + */ + public int quantityDropped(Random par1Random) { + return 4; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockCloth.java b/sp-server/src/main/java/net/minecraft/src/BlockCloth.java new file mode 100644 index 0000000..8ccd498 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockCloth.java @@ -0,0 +1,29 @@ +package net.minecraft.src; + +public class BlockCloth extends Block { + public BlockCloth() { + super(35, Material.cloth); + this.setCreativeTab(CreativeTabs.tabBlock); + } + + /** + * Determines the damage on the item the block drops. Used in cloth and wood. + */ + public int damageDropped(int par1) { + return par1; + } + + /** + * Takes a dye damage value and returns the block damage value to match + */ + public static int getBlockFromDye(int par0) { + return ~par0 & 15; + } + + /** + * Takes a block damage value and returns the dye damage value to match + */ + public static int getDyeFromBlock(int par0) { + return ~par0 & 15; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockCocoa.java b/sp-server/src/main/java/net/minecraft/src/BlockCocoa.java new file mode 100644 index 0000000..97d287a --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockCocoa.java @@ -0,0 +1,172 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockCocoa extends BlockDirectional { + public static final String[] cocoaIcons = new String[] { "cocoa_0", "cocoa_1", "cocoa_2" }; + + public BlockCocoa(int par1) { + super(par1, Material.plants); + this.setTickRandomly(true); + } + + /** + * Ticks the block if it's been scheduled + */ + public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random) { + if (!this.canBlockStay(par1World, par2, par3, par4)) { + this.dropBlockAsItem(par1World, par2, par3, par4, par1World.getBlockMetadata(par2, par3, par4), 0); + par1World.setBlockToAir(par2, par3, par4); + } else if (par1World.rand.nextInt(5) == 0) { + int var6 = par1World.getBlockMetadata(par2, par3, par4); + int var7 = func_72219_c(var6); + + if (var7 < 2) { + ++var7; + par1World.setBlockMetadata(par2, par3, par4, var7 << 2 | getDirection(var6), 2); + } + } + } + + /** + * Can this block stay at this position. Similar to canPlaceBlockAt except gets + * checked often with plants. + */ + public boolean canBlockStay(World par1World, int par2, int par3, int par4) { + int var5 = getDirection(par1World.getBlockMetadata(par2, par3, par4)); + par2 += Direction.offsetX[var5]; + par4 += Direction.offsetZ[var5]; + int var6 = par1World.getBlockId(par2, par3, par4); + return var6 == Block.wood.blockID + && BlockLog.limitToValidMetadata(par1World.getBlockMetadata(par2, par3, par4)) == 3; + } + + /** + * The type of render function that is called for this block + */ + public int getRenderType() { + return 28; + } + + /** + * If this block doesn't render as an ordinary block it will return False + * (examples: signs, buttons, stairs, etc) + */ + public boolean renderAsNormalBlock() { + return false; + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return false; + } + + /** + * Returns a bounding box from the pool of bounding boxes (this means this box + * can change after the pool has been cleared to be reused) + */ + public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int par4) { + this.setBlockBoundsBasedOnState(par1World, par2, par3, par4); + return super.getCollisionBoundingBoxFromPool(par1World, par2, par3, par4); + } + + /** + * Updates the blocks bounds based on its current state. Args: world, x, y, z + */ + public void setBlockBoundsBasedOnState(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + int var5 = par1IBlockAccess.getBlockMetadata(par2, par3, par4); + int var6 = getDirection(var5); + int var7 = func_72219_c(var5); + int var8 = 4 + var7 * 2; + int var9 = 5 + var7 * 2; + float var10 = (float) var8 / 2.0F; + + switch (var6) { + case 0: + this.setBlockBounds((8.0F - var10) / 16.0F, (12.0F - (float) var9) / 16.0F, (15.0F - (float) var8) / 16.0F, + (8.0F + var10) / 16.0F, 0.75F, 0.9375F); + break; + + case 1: + this.setBlockBounds(0.0625F, (12.0F - (float) var9) / 16.0F, (8.0F - var10) / 16.0F, + (1.0F + (float) var8) / 16.0F, 0.75F, (8.0F + var10) / 16.0F); + break; + + case 2: + this.setBlockBounds((8.0F - var10) / 16.0F, (12.0F - (float) var9) / 16.0F, 0.0625F, (8.0F + var10) / 16.0F, + 0.75F, (1.0F + (float) var8) / 16.0F); + break; + + case 3: + this.setBlockBounds((15.0F - (float) var8) / 16.0F, (12.0F - (float) var9) / 16.0F, (8.0F - var10) / 16.0F, + 0.9375F, 0.75F, (8.0F + var10) / 16.0F); + } + } + + /** + * Called when the block is placed in the world. + */ + public void onBlockPlacedBy(World par1World, int par2, int par3, int par4, EntityLiving par5EntityLiving, + ItemStack par6ItemStack) { + int var7 = ((MathHelper.floor_double((double) (par5EntityLiving.rotationYaw * 4.0F / 360.0F) + 0.5D) & 3) + 0) + % 4; + par1World.setBlockMetadata(par2, par3, par4, var7, 2); + } + + /** + * Called when a block is placed using its ItemBlock. Args: World, X, Y, Z, + * side, hitX, hitY, hitZ, block metadata + */ + public int onBlockPlaced(World par1World, int par2, int par3, int par4, int par5, float par6, float par7, + float par8, int par9) { + if (par5 == 1 || par5 == 0) { + par5 = 2; + } + + return Direction.footInvisibleFaceRemap[Direction.facingToDirection[par5]]; + } + + /** + * Lets the block know when one of its neighbor changes. Doesn't know which + * neighbor changed (coordinates passed are their own) Args: x, y, z, neighbor + * blockID + */ + public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5) { + if (!this.canBlockStay(par1World, par2, par3, par4)) { + this.dropBlockAsItem(par1World, par2, par3, par4, par1World.getBlockMetadata(par2, par3, par4), 0); + par1World.setBlockToAir(par2, par3, par4); + } + } + + public static int func_72219_c(int par0) { + return (par0 & 12) >> 2; + } + + /** + * Drops the block items with a specified chance of dropping the specified items + */ + public void dropBlockAsItemWithChance(World par1World, int par2, int par3, int par4, int par5, float par6, + int par7) { + int var8 = func_72219_c(par5); + byte var9 = 1; + + if (var8 >= 2) { + var9 = 3; + } + + for (int var10 = 0; var10 < var9; ++var10) { + this.dropBlockAsItem_do(par1World, par2, par3, par4, new ItemStack(Item.dyePowder, 1, 3)); + } + } + + /** + * Get the block's damage value (for use with pick block). + */ + public int getDamageValue(World par1World, int par2, int par3, int par4) { + return 3; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockCommandBlock.java b/sp-server/src/main/java/net/minecraft/src/BlockCommandBlock.java new file mode 100644 index 0000000..b287065 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockCommandBlock.java @@ -0,0 +1,103 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockCommandBlock extends BlockContainer { + public BlockCommandBlock(int par1) { + super(par1, Material.iron); + } + + /** + * Returns a new instance of a block's tile entity class. Called on placing the + * block. + */ + public TileEntity createNewTileEntity(World par1World) { + return new TileEntityCommandBlock(); + } + + /** + * Lets the block know when one of its neighbor changes. Doesn't know which + * neighbor changed (coordinates passed are their own) Args: x, y, z, neighbor + * blockID + */ + public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5) { + if (!par1World.isRemote) { + boolean var6 = par1World.isBlockIndirectlyGettingPowered(par2, par3, par4); + int var7 = par1World.getBlockMetadata(par2, par3, par4); + boolean var8 = (var7 & 1) != 0; + + if (var6 && !var8) { + par1World.setBlockMetadata(par2, par3, par4, var7 | 1, 4); + par1World.scheduleBlockUpdate(par2, par3, par4, this.blockID, this.tickRate(par1World)); + } else if (!var6 && var8) { + par1World.setBlockMetadata(par2, par3, par4, var7 & -2, 4); + } + } + } + + /** + * Ticks the block if it's been scheduled + */ + public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random) { + TileEntity var6 = par1World.getBlockTileEntity(par2, par3, par4); + + if (var6 != null && var6 instanceof TileEntityCommandBlock) { + TileEntityCommandBlock var7 = (TileEntityCommandBlock) var6; + var7.func_96102_a(var7.executeCommandOnPowered(par1World)); + par1World.func_96440_m(par2, par3, par4, this.blockID); + } + } + + /** + * How many world ticks before ticking + */ + public int tickRate(World par1World) { + return 1; + } + + /** + * Called upon block activation (right click on the block.) + */ + public boolean onBlockActivated(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer, + int par6, float par7, float par8, float par9) { + TileEntityCommandBlock var10 = (TileEntityCommandBlock) par1World.getBlockTileEntity(par2, par3, par4); + + if (var10 != null) { + par5EntityPlayer.displayGUIEditSign(var10); + } + + return true; + } + + /** + * If this returns true, then comparators facing away from this block will use + * the value from getComparatorInputOverride instead of the actual redstone + * signal strength. + */ + public boolean hasComparatorInputOverride() { + return true; + } + + /** + * If hasComparatorInputOverride returns true, the return value from this is + * used instead of the redstone signal strength when this block inputs to a + * comparator. + */ + public int getComparatorInputOverride(World par1World, int par2, int par3, int par4, int par5) { + TileEntity var6 = par1World.getBlockTileEntity(par2, par3, par4); + return var6 != null && var6 instanceof TileEntityCommandBlock ? ((TileEntityCommandBlock) var6).func_96103_d() + : 0; + } + + /** + * Called when the block is placed in the world. + */ + public void onBlockPlacedBy(World par1World, int par2, int par3, int par4, EntityLiving par5EntityLiving, + ItemStack par6ItemStack) { + TileEntityCommandBlock var7 = (TileEntityCommandBlock) par1World.getBlockTileEntity(par2, par3, par4); + + if (par6ItemStack.hasDisplayName()) { + var7.setCommandSenderName(par6ItemStack.getDisplayName()); + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockComparator.java b/sp-server/src/main/java/net/minecraft/src/BlockComparator.java new file mode 100644 index 0000000..43bc41f --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockComparator.java @@ -0,0 +1,206 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockComparator extends BlockRedstoneLogic implements ITileEntityProvider { + public BlockComparator(int par1, boolean par2) { + super(par1, par2); + this.isBlockContainer = true; + } + + /** + * Returns the ID of the items to drop on destruction. + */ + public int idDropped(int par1, Random par2Random, int par3) { + return Item.comparator.itemID; + } + + protected int func_94481_j_(int par1) { + return 2; + } + + protected BlockRedstoneLogic func_94485_e() { + return Block.redstoneComparatorActive; + } + + protected BlockRedstoneLogic func_94484_i() { + return Block.redstoneComparatorIdle; + } + + /** + * The type of render function that is called for this block + */ + public int getRenderType() { + return 37; + } + + protected boolean func_96470_c(int par1) { + return this.isRepeaterPowered || (par1 & 8) != 0; + } + + protected int func_94480_d(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5) { + return this.getTileEntityComparator(par1IBlockAccess, par2, par3, par4).func_96100_a(); + } + + private int func_94491_m(World par1World, int par2, int par3, int par4, int par5) { + return !this.func_94490_c(par5) ? this.getInputStrength(par1World, par2, par3, par4, par5) + : Math.max(this.getInputStrength(par1World, par2, par3, par4, par5) + - this.func_94482_f(par1World, par2, par3, par4, par5), 0); + } + + public boolean func_94490_c(int par1) { + return (par1 & 4) == 4; + } + + protected boolean func_94478_d(World par1World, int par2, int par3, int par4, int par5) { + int var6 = this.getInputStrength(par1World, par2, par3, par4, par5); + + if (var6 >= 15) { + return true; + } else if (var6 == 0) { + return false; + } else { + int var7 = this.func_94482_f(par1World, par2, par3, par4, par5); + return var7 == 0 ? true : var6 >= var7; + } + } + + /** + * Returns the signal strength at one input of the block. Args: world, X, Y, Z, + * side + */ + protected int getInputStrength(World par1World, int par2, int par3, int par4, int par5) { + int var6 = super.getInputStrength(par1World, par2, par3, par4, par5); + int var7 = getDirection(par5); + int var8 = par2 + Direction.offsetX[var7]; + int var9 = par4 + Direction.offsetZ[var7]; + int var10 = par1World.getBlockId(var8, par3, var9); + + if (var10 > 0) { + if (Block.blocksList[var10].hasComparatorInputOverride()) { + var6 = Block.blocksList[var10].getComparatorInputOverride(par1World, var8, par3, var9, + Direction.footInvisibleFaceRemap[var7]); + } else if (var6 < 15 && Block.isNormalCube(var10)) { + var8 += Direction.offsetX[var7]; + var9 += Direction.offsetZ[var7]; + var10 = par1World.getBlockId(var8, par3, var9); + + if (var10 > 0 && Block.blocksList[var10].hasComparatorInputOverride()) { + var6 = Block.blocksList[var10].getComparatorInputOverride(par1World, var8, par3, var9, + Direction.footInvisibleFaceRemap[var7]); + } + } + } + + return var6; + } + + /** + * Returns the blockTileEntity at given coordinates. + */ + public TileEntityComparator getTileEntityComparator(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + return (TileEntityComparator) par1IBlockAccess.getBlockTileEntity(par2, par3, par4); + } + + /** + * Called upon block activation (right click on the block.) + */ + public boolean onBlockActivated(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer, + int par6, float par7, float par8, float par9) { + int var10 = par1World.getBlockMetadata(par2, par3, par4); + boolean var11 = this.isRepeaterPowered | (var10 & 8) != 0; + boolean var12 = !this.func_94490_c(var10); + int var13 = var12 ? 4 : 0; + var13 |= var11 ? 8 : 0; + par1World.playSoundEffect((double) par2 + 0.5D, (double) par3 + 0.5D, (double) par4 + 0.5D, "random.click", + 0.3F, var12 ? 0.55F : 0.5F); + par1World.setBlockMetadata(par2, par3, par4, var13 | var10 & 3, 2); + this.func_96476_c(par1World, par2, par3, par4, par1World.rand); + return true; + } + + protected void func_94479_f(World par1World, int par2, int par3, int par4, int par5) { + if (!par1World.isBlockTickScheduled(par2, par3, par4, this.blockID)) { + int var6 = par1World.getBlockMetadata(par2, par3, par4); + int var7 = this.func_94491_m(par1World, par2, par3, par4, var6); + int var8 = this.getTileEntityComparator(par1World, par2, par3, par4).func_96100_a(); + + if (var7 != var8 || this.func_96470_c(var6) != this.func_94478_d(par1World, par2, par3, par4, var6)) { + if (this.func_83011_d(par1World, par2, par3, par4, var6)) { + par1World.func_82740_a(par2, par3, par4, this.blockID, this.func_94481_j_(0), -1); + } else { + par1World.func_82740_a(par2, par3, par4, this.blockID, this.func_94481_j_(0), 0); + } + } + } + } + + private void func_96476_c(World par1World, int par2, int par3, int par4, Random par5Random) { + int var6 = par1World.getBlockMetadata(par2, par3, par4); + int var7 = this.func_94491_m(par1World, par2, par3, par4, var6); + int var8 = this.getTileEntityComparator(par1World, par2, par3, par4).func_96100_a(); + this.getTileEntityComparator(par1World, par2, par3, par4).func_96099_a(var7); + + if (var8 != var7 || !this.func_94490_c(var6)) { + boolean var9 = this.func_94478_d(par1World, par2, par3, par4, var6); + boolean var10 = this.isRepeaterPowered || (var6 & 8) != 0; + + if (var10 && !var9) { + par1World.setBlockMetadata(par2, par3, par4, var6 & -9, 2); + } else if (!var10 && var9) { + par1World.setBlockMetadata(par2, par3, par4, var6 | 8, 2); + } + + this.func_94483_i_(par1World, par2, par3, par4); + } + } + + /** + * Ticks the block if it's been scheduled + */ + public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random) { + if (this.isRepeaterPowered) { + int var6 = par1World.getBlockMetadata(par2, par3, par4); + par1World.setBlock(par2, par3, par4, this.func_94484_i().blockID, var6 | 8, 4); + } + + this.func_96476_c(par1World, par2, par3, par4, par5Random); + } + + /** + * Called whenever the block is added into the world. Args: world, x, y, z + */ + public void onBlockAdded(World par1World, int par2, int par3, int par4) { + super.onBlockAdded(par1World, par2, par3, par4); + par1World.setBlockTileEntity(par2, par3, par4, this.createNewTileEntity(par1World)); + } + + /** + * ejects contained items into the world, and notifies neighbours of an update, + * as appropriate + */ + public void breakBlock(World par1World, int par2, int par3, int par4, int par5, int par6) { + super.breakBlock(par1World, par2, par3, par4, par5, par6); + par1World.removeBlockTileEntity(par2, par3, par4); + this.func_94483_i_(par1World, par2, par3, par4); + } + + /** + * Called when the block receives a BlockEvent - see World.addBlockEvent. By + * default, passes it on to the tile entity at this location. Args: world, x, y, + * z, blockID, EventID, event parameter + */ + public boolean onBlockEventReceived(World par1World, int par2, int par3, int par4, int par5, int par6) { + super.onBlockEventReceived(par1World, par2, par3, par4, par5, par6); + TileEntity var7 = par1World.getBlockTileEntity(par2, par3, par4); + return var7 != null ? var7.receiveClientEvent(par5, par6) : false; + } + + /** + * Returns a new instance of a block's tile entity class. Called on placing the + * block. + */ + public TileEntity createNewTileEntity(World par1World) { + return new TileEntityComparator(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockContainer.java b/sp-server/src/main/java/net/minecraft/src/BlockContainer.java new file mode 100644 index 0000000..2eff4d3 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockContainer.java @@ -0,0 +1,35 @@ +package net.minecraft.src; + +public abstract class BlockContainer extends Block implements ITileEntityProvider { + protected BlockContainer(int par1, Material par2Material) { + super(par1, par2Material); + this.isBlockContainer = true; + } + + /** + * Called whenever the block is added into the world. Args: world, x, y, z + */ + public void onBlockAdded(World par1World, int par2, int par3, int par4) { + super.onBlockAdded(par1World, par2, par3, par4); + } + + /** + * ejects contained items into the world, and notifies neighbours of an update, + * as appropriate + */ + public void breakBlock(World par1World, int par2, int par3, int par4, int par5, int par6) { + super.breakBlock(par1World, par2, par3, par4, par5, par6); + par1World.removeBlockTileEntity(par2, par3, par4); + } + + /** + * Called when the block receives a BlockEvent - see World.addBlockEvent. By + * default, passes it on to the tile entity at this location. Args: world, x, y, + * z, blockID, EventID, event parameter + */ + public boolean onBlockEventReceived(World par1World, int par2, int par3, int par4, int par5, int par6) { + super.onBlockEventReceived(par1World, par2, par3, par4, par5, par6); + TileEntity var7 = par1World.getBlockTileEntity(par2, par3, par4); + return var7 != null ? var7.receiveClientEvent(par5, par6) : false; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockCrops.java b/sp-server/src/main/java/net/minecraft/src/BlockCrops.java new file mode 100644 index 0000000..2638bbc --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockCrops.java @@ -0,0 +1,162 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockCrops extends BlockFlower { + protected BlockCrops(int par1) { + super(par1); + this.setTickRandomly(true); + float var2 = 0.5F; + this.setBlockBounds(0.5F - var2, 0.0F, 0.5F - var2, 0.5F + var2, 0.25F, 0.5F + var2); + this.setCreativeTab((CreativeTabs) null); + this.setHardness(0.0F); + this.setStepSound(soundGrassFootstep); + this.disableStats(); + } + + /** + * Gets passed in the blockID of the block below and supposed to return true if + * its allowed to grow on the type of blockID passed in. Args: blockID + */ + protected boolean canThisPlantGrowOnThisBlockID(int par1) { + return par1 == Block.tilledField.blockID; + } + + /** + * Ticks the block if it's been scheduled + */ + public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random) { + super.updateTick(par1World, par2, par3, par4, par5Random); + + if (par1World.getBlockLightValue(par2, par3 + 1, par4) >= 9) { + int var6 = par1World.getBlockMetadata(par2, par3, par4); + + if (var6 < 7) { + float var7 = this.getGrowthRate(par1World, par2, par3, par4); + + if (par5Random.nextInt((int) (25.0F / var7) + 1) == 0) { + ++var6; + par1World.setBlockMetadata(par2, par3, par4, var6, 2); + } + } + } + } + + /** + * Apply bonemeal to the crops. + */ + public void fertilize(World par1World, int par2, int par3, int par4) { + int var5 = par1World.getBlockMetadata(par2, par3, par4) + + MathHelper.getRandomIntegerInRange(par1World.rand, 2, 5); + + if (var5 > 7) { + var5 = 7; + } + + par1World.setBlockMetadata(par2, par3, par4, var5, 2); + } + + /** + * Gets the growth rate for the crop. Setup to encourage rows by halving growth + * rate if there is diagonals, crops on different sides that aren't opposing, + * and by adding growth for every crop next to this one (and for crop below this + * one). Args: x, y, z + */ + private float getGrowthRate(World par1World, int par2, int par3, int par4) { + float var5 = 1.0F; + int var6 = par1World.getBlockId(par2, par3, par4 - 1); + int var7 = par1World.getBlockId(par2, par3, par4 + 1); + int var8 = par1World.getBlockId(par2 - 1, par3, par4); + int var9 = par1World.getBlockId(par2 + 1, par3, par4); + int var10 = par1World.getBlockId(par2 - 1, par3, par4 - 1); + int var11 = par1World.getBlockId(par2 + 1, par3, par4 - 1); + int var12 = par1World.getBlockId(par2 + 1, par3, par4 + 1); + int var13 = par1World.getBlockId(par2 - 1, par3, par4 + 1); + boolean var14 = var8 == this.blockID || var9 == this.blockID; + boolean var15 = var6 == this.blockID || var7 == this.blockID; + boolean var16 = var10 == this.blockID || var11 == this.blockID || var12 == this.blockID + || var13 == this.blockID; + + for (int var17 = par2 - 1; var17 <= par2 + 1; ++var17) { + for (int var18 = par4 - 1; var18 <= par4 + 1; ++var18) { + int var19 = par1World.getBlockId(var17, par3 - 1, var18); + float var20 = 0.0F; + + if (var19 == Block.tilledField.blockID) { + var20 = 1.0F; + + if (par1World.getBlockMetadata(var17, par3 - 1, var18) > 0) { + var20 = 3.0F; + } + } + + if (var17 != par2 || var18 != par4) { + var20 /= 4.0F; + } + + var5 += var20; + } + } + + if (var16 || var14 && var15) { + var5 /= 2.0F; + } + + return var5; + } + + /** + * The type of render function that is called for this block + */ + public int getRenderType() { + return 6; + } + + /** + * Generate a seed ItemStack for this crop. + */ + protected int getSeedItem() { + return Item.seeds.itemID; + } + + /** + * Generate a crop produce ItemStack for this crop. + */ + protected int getCropItem() { + return Item.wheat.itemID; + } + + /** + * Drops the block items with a specified chance of dropping the specified items + */ + public void dropBlockAsItemWithChance(World par1World, int par2, int par3, int par4, int par5, float par6, + int par7) { + super.dropBlockAsItemWithChance(par1World, par2, par3, par4, par5, par6, 0); + + if (!par1World.isRemote) { + if (par5 >= 7) { + int var8 = 3 + par7; + + for (int var9 = 0; var9 < var8; ++var9) { + if (par1World.rand.nextInt(15) <= par5) { + this.dropBlockAsItem_do(par1World, par2, par3, par4, new ItemStack(this.getSeedItem(), 1, 0)); + } + } + } + } + } + + /** + * Returns the ID of the items to drop on destruction. + */ + public int idDropped(int par1, Random par2Random, int par3) { + return par1 == 7 ? this.getCropItem() : this.getSeedItem(); + } + + /** + * Returns the quantity of items to drop on block destruction. + */ + public int quantityDropped(Random par1Random) { + return 1; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockDaylightDetector.java b/sp-server/src/main/java/net/minecraft/src/BlockDaylightDetector.java new file mode 100644 index 0000000..29f14c5 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockDaylightDetector.java @@ -0,0 +1,112 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockDaylightDetector extends BlockContainer { + private Icon[] iconArray = new Icon[2]; + + public BlockDaylightDetector(int par1) { + super(par1, Material.wood); + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.375F, 1.0F); + this.setCreativeTab(CreativeTabs.tabRedstone); + } + + /** + * Updates the blocks bounds based on its current state. Args: world, x, y, z + */ + public void setBlockBoundsBasedOnState(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.375F, 1.0F); + } + + /** + * Returns true if the block is emitting indirect/weak redstone power on the + * specified side. If isBlockNormalCube returns true, standard redstone + * propagation rules will apply instead and this will not be called. Args: + * World, X, Y, Z, side. Note that the side is reversed - eg it is 1 (up) when + * checking the bottom of the block. + */ + public int isProvidingWeakPower(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5) { + return par1IBlockAccess.getBlockMetadata(par2, par3, par4); + } + + /** + * Ticks the block if it's been scheduled + */ + public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random) { + } + + /** + * Lets the block know when one of its neighbor changes. Doesn't know which + * neighbor changed (coordinates passed are their own) Args: x, y, z, neighbor + * blockID + */ + public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5) { + } + + /** + * Called whenever the block is added into the world. Args: world, x, y, z + */ + public void onBlockAdded(World par1World, int par2, int par3, int par4) { + } + + public void updateLightLevel(World par1World, int par2, int par3, int par4) { + if (!par1World.provider.hasNoSky) { + int var5 = par1World.getBlockMetadata(par2, par3, par4); + int var6 = par1World.getSavedLightValue(EnumSkyBlock.Sky, par2, par3, par4) - par1World.skylightSubtracted; + float var7 = par1World.getCelestialAngleRadians(1.0F); + + if (var7 < (float) Math.PI) { + var7 += (0.0F - var7) * 0.2F; + } else { + var7 += (((float) Math.PI * 2F) - var7) * 0.2F; + } + + var6 = Math.round((float) var6 * MathHelper.cos(var7)); + + if (var6 < 0) { + var6 = 0; + } + + if (var6 > 15) { + var6 = 15; + } + + if (var5 != var6) { + par1World.setBlockMetadata(par2, par3, par4, var6, 3); + } + } + } + + /** + * If this block doesn't render as an ordinary block it will return False + * (examples: signs, buttons, stairs, etc) + */ + public boolean renderAsNormalBlock() { + return false; + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return false; + } + + /** + * Can this block provide power. Only wire currently seems to have this change + * based on its state. + */ + public boolean canProvidePower() { + return true; + } + + /** + * Returns a new instance of a block's tile entity class. Called on placing the + * block. + */ + public TileEntity createNewTileEntity(World par1World) { + return new TileEntityDaylightDetector(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockDeadBush.java b/sp-server/src/main/java/net/minecraft/src/BlockDeadBush.java new file mode 100644 index 0000000..68c3c9f --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockDeadBush.java @@ -0,0 +1,40 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockDeadBush extends BlockFlower { + protected BlockDeadBush(int par1) { + super(par1, Material.vine); + float var2 = 0.4F; + this.setBlockBounds(0.5F - var2, 0.0F, 0.5F - var2, 0.5F + var2, 0.8F, 0.5F + var2); + } + + /** + * Gets passed in the blockID of the block below and supposed to return true if + * its allowed to grow on the type of blockID passed in. Args: blockID + */ + protected boolean canThisPlantGrowOnThisBlockID(int par1) { + return par1 == Block.sand.blockID; + } + + /** + * Returns the ID of the items to drop on destruction. + */ + public int idDropped(int par1, Random par2Random, int par3) { + return -1; + } + + /** + * Called when the player destroys a block with an item that can harvest it. (i, + * j, k) are the coordinates of the block and l is the block's subtype/damage. + */ + public void harvestBlock(World par1World, EntityPlayer par2EntityPlayer, int par3, int par4, int par5, int par6) { + if (!par1World.isRemote && par2EntityPlayer.getCurrentEquippedItem() != null + && par2EntityPlayer.getCurrentEquippedItem().itemID == Item.shears.itemID) { + par2EntityPlayer.addStat(StatList.mineBlockStatArray[this.blockID], 1); + this.dropBlockAsItem_do(par1World, par3, par4, par5, new ItemStack(Block.deadBush, 1, par6)); + } else { + super.harvestBlock(par1World, par2EntityPlayer, par3, par4, par5, par6); + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockDetectorRail.java b/sp-server/src/main/java/net/minecraft/src/BlockDetectorRail.java new file mode 100644 index 0000000..80c9358 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockDetectorRail.java @@ -0,0 +1,151 @@ +package net.minecraft.src; + +import java.util.List; +import java.util.Random; + +public class BlockDetectorRail extends BlockRailBase { + public BlockDetectorRail(int par1) { + super(par1, true); + this.setTickRandomly(true); + } + + /** + * How many world ticks before ticking + */ + public int tickRate(World par1World) { + return 20; + } + + /** + * Can this block provide power. Only wire currently seems to have this change + * based on its state. + */ + public boolean canProvidePower() { + return true; + } + + /** + * Triggered whenever an entity collides with this block (enters into the + * block). Args: world, x, y, z, entity + */ + public void onEntityCollidedWithBlock(World par1World, int par2, int par3, int par4, Entity par5Entity) { + if (!par1World.isRemote) { + int var6 = par1World.getBlockMetadata(par2, par3, par4); + + if ((var6 & 8) == 0) { + this.setStateIfMinecartInteractsWithRail(par1World, par2, par3, par4, var6); + } + } + } + + /** + * Ticks the block if it's been scheduled + */ + public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random) { + if (!par1World.isRemote) { + int var6 = par1World.getBlockMetadata(par2, par3, par4); + + if ((var6 & 8) != 0) { + this.setStateIfMinecartInteractsWithRail(par1World, par2, par3, par4, var6); + } + } + } + + /** + * Returns true if the block is emitting indirect/weak redstone power on the + * specified side. If isBlockNormalCube returns true, standard redstone + * propagation rules will apply instead and this will not be called. Args: + * World, X, Y, Z, side. Note that the side is reversed - eg it is 1 (up) when + * checking the bottom of the block. + */ + public int isProvidingWeakPower(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5) { + return (par1IBlockAccess.getBlockMetadata(par2, par3, par4) & 8) != 0 ? 15 : 0; + } + + /** + * Returns true if the block is emitting direct/strong redstone power on the + * specified side. Args: World, X, Y, Z, side. Note that the side is reversed - + * eg it is 1 (up) when checking the bottom of the block. + */ + public int isProvidingStrongPower(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5) { + return (par1IBlockAccess.getBlockMetadata(par2, par3, par4) & 8) == 0 ? 0 : (par5 == 1 ? 15 : 0); + } + + /** + * Update the detector rail power state if a minecart enter, stays or leave the + * block. + */ + private void setStateIfMinecartInteractsWithRail(World par1World, int par2, int par3, int par4, int par5) { + boolean var6 = (par5 & 8) != 0; + boolean var7 = false; + float var8 = 0.125F; + List var9 = par1World.getEntitiesWithinAABB(EntityMinecart.class, + AxisAlignedBB.getAABBPool().getAABB((double) ((float) par2 + var8), (double) par3, + (double) ((float) par4 + var8), (double) ((float) (par2 + 1) - var8), + (double) ((float) (par3 + 1) - var8), (double) ((float) (par4 + 1) - var8))); + + if (!var9.isEmpty()) { + var7 = true; + } + + if (var7 && !var6) { + par1World.setBlockMetadata(par2, par3, par4, par5 | 8, 3); + par1World.notifyBlocksOfNeighborChange(par2, par3, par4, this.blockID); + par1World.notifyBlocksOfNeighborChange(par2, par3 - 1, par4, this.blockID); + par1World.markBlockRangeForRenderUpdate(par2, par3, par4, par2, par3, par4); + } + + if (!var7 && var6) { + par1World.setBlockMetadata(par2, par3, par4, par5 & 7, 3); + par1World.notifyBlocksOfNeighborChange(par2, par3, par4, this.blockID); + par1World.notifyBlocksOfNeighborChange(par2, par3 - 1, par4, this.blockID); + par1World.markBlockRangeForRenderUpdate(par2, par3, par4, par2, par3, par4); + } + + if (var7) { + par1World.scheduleBlockUpdate(par2, par3, par4, this.blockID, this.tickRate(par1World)); + } + + par1World.func_96440_m(par2, par3, par4, this.blockID); + } + + /** + * Called whenever the block is added into the world. Args: world, x, y, z + */ + public void onBlockAdded(World par1World, int par2, int par3, int par4) { + super.onBlockAdded(par1World, par2, par3, par4); + this.setStateIfMinecartInteractsWithRail(par1World, par2, par3, par4, + par1World.getBlockMetadata(par2, par3, par4)); + } + + /** + * If this returns true, then comparators facing away from this block will use + * the value from getComparatorInputOverride instead of the actual redstone + * signal strength. + */ + public boolean hasComparatorInputOverride() { + return true; + } + + /** + * If hasComparatorInputOverride returns true, the return value from this is + * used instead of the redstone signal strength when this block inputs to a + * comparator. + */ + public int getComparatorInputOverride(World par1World, int par2, int par3, int par4, int par5) { + if ((par1World.getBlockMetadata(par2, par3, par4) & 8) > 0) { + float var6 = 0.125F; + List var7 = par1World.selectEntitiesWithinAABB(EntityMinecart.class, + AxisAlignedBB.getAABBPool().getAABB((double) ((float) par2 + var6), (double) par3, + (double) ((float) par4 + var6), (double) ((float) (par2 + 1) - var6), + (double) ((float) (par3 + 1) - var6), (double) ((float) (par4 + 1) - var6)), + IEntitySelector.selectInventories); + + if (var7.size() > 0) { + return Container.calcRedstoneFromInventory((IInventory) var7.get(0)); + } + } + + return 0; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockDirectional.java b/sp-server/src/main/java/net/minecraft/src/BlockDirectional.java new file mode 100644 index 0000000..947c9b5 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockDirectional.java @@ -0,0 +1,14 @@ +package net.minecraft.src; + +public abstract class BlockDirectional extends Block { + protected BlockDirectional(int par1, Material par2Material) { + super(par1, par2Material); + } + + /** + * Returns the orentation value from the specified metadata + */ + public static int getDirection(int par0) { + return par0 & 3; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockDirt.java b/sp-server/src/main/java/net/minecraft/src/BlockDirt.java new file mode 100644 index 0000000..59e228d --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockDirt.java @@ -0,0 +1,8 @@ +package net.minecraft.src; + +public class BlockDirt extends Block { + protected BlockDirt(int par1) { + super(par1, Material.ground); + this.setCreativeTab(CreativeTabs.tabBlock); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockDispenser.java b/sp-server/src/main/java/net/minecraft/src/BlockDispenser.java new file mode 100644 index 0000000..80205c3 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockDispenser.java @@ -0,0 +1,234 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockDispenser extends BlockContainer { + /** Registry for all dispense behaviors. */ + public static final IRegistry dispenseBehaviorRegistry = new RegistryDefaulted(new BehaviorDefaultDispenseItem()); + protected Random random = new Random(); + + protected BlockDispenser(int par1) { + super(par1, Material.rock); + this.setCreativeTab(CreativeTabs.tabRedstone); + } + + /** + * How many world ticks before ticking + */ + public int tickRate(World par1World) { + return 4; + } + + /** + * Called whenever the block is added into the world. Args: world, x, y, z + */ + public void onBlockAdded(World par1World, int par2, int par3, int par4) { + super.onBlockAdded(par1World, par2, par3, par4); + this.setDispenserDefaultDirection(par1World, par2, par3, par4); + } + + /** + * sets Dispenser block direction so that the front faces an non-opaque block; + * chooses west to be direction if all surrounding blocks are opaque. + */ + private void setDispenserDefaultDirection(World par1World, int par2, int par3, int par4) { + if (!par1World.isRemote) { + int var5 = par1World.getBlockId(par2, par3, par4 - 1); + int var6 = par1World.getBlockId(par2, par3, par4 + 1); + int var7 = par1World.getBlockId(par2 - 1, par3, par4); + int var8 = par1World.getBlockId(par2 + 1, par3, par4); + byte var9 = 3; + + if (Block.opaqueCubeLookup[var5] && !Block.opaqueCubeLookup[var6]) { + var9 = 3; + } + + if (Block.opaqueCubeLookup[var6] && !Block.opaqueCubeLookup[var5]) { + var9 = 2; + } + + if (Block.opaqueCubeLookup[var7] && !Block.opaqueCubeLookup[var8]) { + var9 = 5; + } + + if (Block.opaqueCubeLookup[var8] && !Block.opaqueCubeLookup[var7]) { + var9 = 4; + } + + par1World.setBlockMetadata(par2, par3, par4, var9, 2); + } + } + + /** + * Called upon block activation (right click on the block.) + */ + public boolean onBlockActivated(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer, + int par6, float par7, float par8, float par9) { + if (par1World.isRemote) { + return true; + } else { + TileEntityDispenser var10 = (TileEntityDispenser) par1World.getBlockTileEntity(par2, par3, par4); + + if (var10 != null) { + par5EntityPlayer.displayGUIDispenser(var10); + } + + return true; + } + } + + protected void dispense(World par1World, int par2, int par3, int par4) { + BlockSourceImpl var5 = new BlockSourceImpl(par1World, par2, par3, par4); + TileEntityDispenser var6 = (TileEntityDispenser) var5.getBlockTileEntity(); + + if (var6 != null) { + int var7 = var6.getRandomStackFromInventory(); + + if (var7 < 0) { + par1World.playAuxSFX(1001, par2, par3, par4, 0); + } else { + ItemStack var8 = var6.getStackInSlot(var7); + IBehaviorDispenseItem var9 = this.getBehaviorForItemStack(var8); + + if (var9 != IBehaviorDispenseItem.itemDispenseBehaviorProvider) { + ItemStack var10 = var9.dispense(var5, var8); + var6.setInventorySlotContents(var7, var10.stackSize == 0 ? null : var10); + } + } + } + } + + /** + * Returns the behavior for the given ItemStack. + */ + protected IBehaviorDispenseItem getBehaviorForItemStack(ItemStack par1ItemStack) { + return (IBehaviorDispenseItem) dispenseBehaviorRegistry.func_82594_a(par1ItemStack.getItem()); + } + + /** + * Lets the block know when one of its neighbor changes. Doesn't know which + * neighbor changed (coordinates passed are their own) Args: x, y, z, neighbor + * blockID + */ + public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5) { + boolean var6 = par1World.isBlockIndirectlyGettingPowered(par2, par3, par4) + || par1World.isBlockIndirectlyGettingPowered(par2, par3 + 1, par4); + int var7 = par1World.getBlockMetadata(par2, par3, par4); + boolean var8 = (var7 & 8) != 0; + + if (var6 && !var8) { + par1World.scheduleBlockUpdate(par2, par3, par4, this.blockID, this.tickRate(par1World)); + par1World.setBlockMetadata(par2, par3, par4, var7 | 8, 4); + } else if (!var6 && var8) { + par1World.setBlockMetadata(par2, par3, par4, var7 & -9, 4); + } + } + + /** + * Ticks the block if it's been scheduled + */ + public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random) { + if (!par1World.isRemote) { + this.dispense(par1World, par2, par3, par4); + } + } + + /** + * Returns a new instance of a block's tile entity class. Called on placing the + * block. + */ + public TileEntity createNewTileEntity(World par1World) { + return new TileEntityDispenser(); + } + + /** + * Called when the block is placed in the world. + */ + public void onBlockPlacedBy(World par1World, int par2, int par3, int par4, EntityLiving par5EntityLiving, + ItemStack par6ItemStack) { + int var7 = BlockPistonBase.determineOrientation(par1World, par2, par3, par4, par5EntityLiving); + par1World.setBlockMetadata(par2, par3, par4, var7, 2); + + if (par6ItemStack.hasDisplayName()) { + ((TileEntityDispenser) par1World.getBlockTileEntity(par2, par3, par4)) + .func_94049_a(par6ItemStack.getDisplayName()); + } + } + + /** + * ejects contained items into the world, and notifies neighbours of an update, + * as appropriate + */ + public void breakBlock(World par1World, int par2, int par3, int par4, int par5, int par6) { + TileEntityDispenser var7 = (TileEntityDispenser) par1World.getBlockTileEntity(par2, par3, par4); + + if (var7 != null) { + for (int var8 = 0; var8 < var7.getSizeInventory(); ++var8) { + ItemStack var9 = var7.getStackInSlot(var8); + + if (var9 != null) { + float var10 = this.random.nextFloat() * 0.8F + 0.1F; + float var11 = this.random.nextFloat() * 0.8F + 0.1F; + float var12 = this.random.nextFloat() * 0.8F + 0.1F; + + while (var9.stackSize > 0) { + int var13 = this.random.nextInt(21) + 10; + + if (var13 > var9.stackSize) { + var13 = var9.stackSize; + } + + var9.stackSize -= var13; + EntityItem var14 = new EntityItem(par1World, (double) ((float) par2 + var10), + (double) ((float) par3 + var11), (double) ((float) par4 + var12), + new ItemStack(var9.itemID, var13, var9.getItemDamage())); + + if (var9.hasTagCompound()) { + var14.getEntityItem().setTagCompound((NBTTagCompound) var9.getTagCompound().copy()); + } + + float var15 = 0.05F; + var14.motionX = (double) ((float) this.random.nextGaussian() * var15); + var14.motionY = (double) ((float) this.random.nextGaussian() * var15 + 0.2F); + var14.motionZ = (double) ((float) this.random.nextGaussian() * var15); + par1World.spawnEntityInWorld(var14); + } + } + } + + par1World.func_96440_m(par2, par3, par4, par5); + } + + super.breakBlock(par1World, par2, par3, par4, par5, par6); + } + + public static IPosition getIPositionFromBlockSource(IBlockSource par0IBlockSource) { + EnumFacing var1 = getFacing(par0IBlockSource.getBlockMetadata()); + double var2 = par0IBlockSource.getX() + 0.7D * (double) var1.getFrontOffsetX(); + double var4 = par0IBlockSource.getY() + 0.7D * (double) var1.getFrontOffsetY(); + double var6 = par0IBlockSource.getZ() + 0.7D * (double) var1.getFrontOffsetZ(); + return new PositionImpl(var2, var4, var6); + } + + public static EnumFacing getFacing(int par0) { + return EnumFacing.getFront(par0 & 7); + } + + /** + * If this returns true, then comparators facing away from this block will use + * the value from getComparatorInputOverride instead of the actual redstone + * signal strength. + */ + public boolean hasComparatorInputOverride() { + return true; + } + + /** + * If hasComparatorInputOverride returns true, the return value from this is + * used instead of the redstone signal strength when this block inputs to a + * comparator. + */ + public int getComparatorInputOverride(World par1World, int par2, int par3, int par4, int par5) { + return Container.calcRedstoneFromInventory((IInventory) par1World.getBlockTileEntity(par2, par3, par4)); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockDoor.java b/sp-server/src/main/java/net/minecraft/src/BlockDoor.java new file mode 100644 index 0000000..c63286b --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockDoor.java @@ -0,0 +1,303 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockDoor extends Block { + private static final String[] doorIconNames = new String[] { "doorWood_lower", "doorWood_upper", "doorIron_lower", + "doorIron_upper" }; + + /** Used for pointing at icon names. */ + private final int doorTypeForIcon; + + protected BlockDoor(int par1, Material par2Material) { + super(par1, par2Material); + + if (par2Material == Material.iron) { + this.doorTypeForIcon = 2; + } else { + this.doorTypeForIcon = 0; + } + + float var3 = 0.5F; + float var4 = 1.0F; + this.setBlockBounds(0.5F - var3, 0.0F, 0.5F - var3, 0.5F + var3, var4, 0.5F + var3); + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return false; + } + + public boolean getBlocksMovement(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + int var5 = this.getFullMetadata(par1IBlockAccess, par2, par3, par4); + return (var5 & 4) != 0; + } + + /** + * If this block doesn't render as an ordinary block it will return False + * (examples: signs, buttons, stairs, etc) + */ + public boolean renderAsNormalBlock() { + return false; + } + + /** + * The type of render function that is called for this block + */ + public int getRenderType() { + return 7; + } + + /** + * Returns a bounding box from the pool of bounding boxes (this means this box + * can change after the pool has been cleared to be reused) + */ + public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int par4) { + this.setBlockBoundsBasedOnState(par1World, par2, par3, par4); + return super.getCollisionBoundingBoxFromPool(par1World, par2, par3, par4); + } + + /** + * Updates the blocks bounds based on its current state. Args: world, x, y, z + */ + public void setBlockBoundsBasedOnState(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + this.setDoorRotation(this.getFullMetadata(par1IBlockAccess, par2, par3, par4)); + } + + /** + * Returns 0, 1, 2 or 3 depending on where the hinge is. + */ + public int getDoorOrientation(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + return this.getFullMetadata(par1IBlockAccess, par2, par3, par4) & 3; + } + + public boolean isDoorOpen(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + return (this.getFullMetadata(par1IBlockAccess, par2, par3, par4) & 4) != 0; + } + + private void setDoorRotation(int par1) { + float var2 = 0.1875F; + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 2.0F, 1.0F); + int var3 = par1 & 3; + boolean var4 = (par1 & 4) != 0; + boolean var5 = (par1 & 16) != 0; + + if (var3 == 0) { + if (var4) { + if (!var5) { + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, var2); + } else { + this.setBlockBounds(0.0F, 0.0F, 1.0F - var2, 1.0F, 1.0F, 1.0F); + } + } else { + this.setBlockBounds(0.0F, 0.0F, 0.0F, var2, 1.0F, 1.0F); + } + } else if (var3 == 1) { + if (var4) { + if (!var5) { + this.setBlockBounds(1.0F - var2, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + } else { + this.setBlockBounds(0.0F, 0.0F, 0.0F, var2, 1.0F, 1.0F); + } + } else { + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, var2); + } + } else if (var3 == 2) { + if (var4) { + if (!var5) { + this.setBlockBounds(0.0F, 0.0F, 1.0F - var2, 1.0F, 1.0F, 1.0F); + } else { + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, var2); + } + } else { + this.setBlockBounds(1.0F - var2, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + } + } else if (var3 == 3) { + if (var4) { + if (!var5) { + this.setBlockBounds(0.0F, 0.0F, 0.0F, var2, 1.0F, 1.0F); + } else { + this.setBlockBounds(1.0F - var2, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + } + } else { + this.setBlockBounds(0.0F, 0.0F, 1.0F - var2, 1.0F, 1.0F, 1.0F); + } + } + } + + /** + * Called when the block is clicked by a player. Args: x, y, z, entityPlayer + */ + public void onBlockClicked(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer) { + } + + /** + * Called upon block activation (right click on the block.) + */ + public boolean onBlockActivated(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer, + int par6, float par7, float par8, float par9) { + if (this.blockMaterial == Material.iron) { + return true; + } else { + int var10 = this.getFullMetadata(par1World, par2, par3, par4); + int var11 = var10 & 7; + var11 ^= 4; + + if ((var10 & 8) == 0) { + par1World.setBlockMetadata(par2, par3, par4, var11, 2); + par1World.markBlockRangeForRenderUpdate(par2, par3, par4, par2, par3, par4); + } else { + par1World.setBlockMetadata(par2, par3 - 1, par4, var11, 2); + par1World.markBlockRangeForRenderUpdate(par2, par3 - 1, par4, par2, par3, par4); + } + + par1World.playAuxSFXAtEntity(par5EntityPlayer, 1003, par2, par3, par4, 0); + return true; + } + } + + /** + * A function to open a door. + */ + public void onPoweredBlockChange(World par1World, int par2, int par3, int par4, boolean par5) { + int var6 = this.getFullMetadata(par1World, par2, par3, par4); + boolean var7 = (var6 & 4) != 0; + + if (var7 != par5) { + int var8 = var6 & 7; + var8 ^= 4; + + if ((var6 & 8) == 0) { + par1World.setBlockMetadata(par2, par3, par4, var8, 2); + par1World.markBlockRangeForRenderUpdate(par2, par3, par4, par2, par3, par4); + } else { + par1World.setBlockMetadata(par2, par3 - 1, par4, var8, 2); + par1World.markBlockRangeForRenderUpdate(par2, par3 - 1, par4, par2, par3, par4); + } + + par1World.playAuxSFXAtEntity((EntityPlayer) null, 1003, par2, par3, par4, 0); + } + } + + /** + * Lets the block know when one of its neighbor changes. Doesn't know which + * neighbor changed (coordinates passed are their own) Args: x, y, z, neighbor + * blockID + */ + public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5) { + int var6 = par1World.getBlockMetadata(par2, par3, par4); + + if ((var6 & 8) == 0) { + boolean var7 = false; + + if (par1World.getBlockId(par2, par3 + 1, par4) != this.blockID) { + par1World.setBlockToAir(par2, par3, par4); + var7 = true; + } + + if (!par1World.doesBlockHaveSolidTopSurface(par2, par3 - 1, par4)) { + par1World.setBlockToAir(par2, par3, par4); + var7 = true; + + if (par1World.getBlockId(par2, par3 + 1, par4) == this.blockID) { + par1World.setBlockToAir(par2, par3 + 1, par4); + } + } + + if (var7) { + if (!par1World.isRemote) { + this.dropBlockAsItem(par1World, par2, par3, par4, var6, 0); + } + } else { + boolean var8 = par1World.isBlockIndirectlyGettingPowered(par2, par3, par4) + || par1World.isBlockIndirectlyGettingPowered(par2, par3 + 1, par4); + + if ((var8 || par5 > 0 && Block.blocksList[par5].canProvidePower()) && par5 != this.blockID) { + this.onPoweredBlockChange(par1World, par2, par3, par4, var8); + } + } + } else { + if (par1World.getBlockId(par2, par3 - 1, par4) != this.blockID) { + par1World.setBlockToAir(par2, par3, par4); + } + + if (par5 > 0 && par5 != this.blockID) { + this.onNeighborBlockChange(par1World, par2, par3 - 1, par4, par5); + } + } + } + + /** + * Returns the ID of the items to drop on destruction. + */ + public int idDropped(int par1, Random par2Random, int par3) { + return (par1 & 8) != 0 ? 0 + : (this.blockMaterial == Material.iron ? Item.doorIron.itemID : Item.doorWood.itemID); + } + + /** + * Ray traces through the blocks collision from start vector to end vector + * returning a ray trace hit. Args: world, x, y, z, startVec, endVec + */ + public MovingObjectPosition collisionRayTrace(World par1World, int par2, int par3, int par4, Vec3 par5Vec3, + Vec3 par6Vec3) { + this.setBlockBoundsBasedOnState(par1World, par2, par3, par4); + return super.collisionRayTrace(par1World, par2, par3, par4, par5Vec3, par6Vec3); + } + + /** + * Checks to see if its valid to put this block at the specified coordinates. + * Args: world, x, y, z + */ + public boolean canPlaceBlockAt(World par1World, int par2, int par3, int par4) { + return par3 >= 255 ? false + : par1World.doesBlockHaveSolidTopSurface(par2, par3 - 1, par4) + && super.canPlaceBlockAt(par1World, par2, par3, par4) + && super.canPlaceBlockAt(par1World, par2, par3 + 1, par4); + } + + /** + * Returns the mobility information of the block, 0 = free, 1 = can't push but + * can move over, 2 = total immobility and stop pistons + */ + public int getMobilityFlag() { + return 1; + } + + /** + * Returns the full metadata value created by combining the metadata of both + * blocks the door takes up. + */ + public int getFullMetadata(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + int var5 = par1IBlockAccess.getBlockMetadata(par2, par3, par4); + boolean var6 = (var5 & 8) != 0; + int var7; + int var8; + + if (var6) { + var7 = par1IBlockAccess.getBlockMetadata(par2, par3 - 1, par4); + var8 = var5; + } else { + var7 = var5; + var8 = par1IBlockAccess.getBlockMetadata(par2, par3 + 1, par4); + } + + boolean var9 = (var8 & 1) != 0; + return var7 & 7 | (var6 ? 8 : 0) | (var9 ? 16 : 0); + } + + /** + * Called when the block is attempted to be harvested + */ + public void onBlockHarvested(World par1World, int par2, int par3, int par4, int par5, + EntityPlayer par6EntityPlayer) { + if (par6EntityPlayer.capabilities.isCreativeMode && (par5 & 8) != 0 + && par1World.getBlockId(par2, par3 - 1, par4) == this.blockID) { + par1World.setBlockToAir(par2, par3 - 1, par4); + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockDragonEgg.java b/sp-server/src/main/java/net/minecraft/src/BlockDragonEgg.java new file mode 100644 index 0000000..9546571 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockDragonEgg.java @@ -0,0 +1,147 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockDragonEgg extends Block { + public BlockDragonEgg(int par1) { + super(par1, Material.dragonEgg); + this.setBlockBounds(0.0625F, 0.0F, 0.0625F, 0.9375F, 1.0F, 0.9375F); + } + + /** + * Called whenever the block is added into the world. Args: world, x, y, z + */ + public void onBlockAdded(World par1World, int par2, int par3, int par4) { + par1World.scheduleBlockUpdate(par2, par3, par4, this.blockID, this.tickRate(par1World)); + } + + /** + * Lets the block know when one of its neighbor changes. Doesn't know which + * neighbor changed (coordinates passed are their own) Args: x, y, z, neighbor + * blockID + */ + public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5) { + par1World.scheduleBlockUpdate(par2, par3, par4, this.blockID, this.tickRate(par1World)); + } + + /** + * Ticks the block if it's been scheduled + */ + public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random) { + this.fallIfPossible(par1World, par2, par3, par4); + } + + /** + * Checks if the dragon egg can fall down, and if so, makes it fall. + */ + private void fallIfPossible(World par1World, int par2, int par3, int par4) { + if (BlockSand.canFallBelow(par1World, par2, par3 - 1, par4) && par3 >= 0) { + byte var5 = 32; + + if (!BlockSand.fallInstantly && par1World.checkChunksExist(par2 - var5, par3 - var5, par4 - var5, + par2 + var5, par3 + var5, par4 + var5)) { + EntityFallingSand var6 = new EntityFallingSand(par1World, (double) ((float) par2 + 0.5F), + (double) ((float) par3 + 0.5F), (double) ((float) par4 + 0.5F), this.blockID); + par1World.spawnEntityInWorld(var6); + } else { + par1World.setBlockToAir(par2, par3, par4); + + while (BlockSand.canFallBelow(par1World, par2, par3 - 1, par4) && par3 > 0) { + --par3; + } + + if (par3 > 0) { + par1World.setBlock(par2, par3, par4, this.blockID, 0, 2); + } + } + } + } + + /** + * Called upon block activation (right click on the block.) + */ + public boolean onBlockActivated(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer, + int par6, float par7, float par8, float par9) { + this.teleportNearby(par1World, par2, par3, par4); + return true; + } + + /** + * Called when the block is clicked by a player. Args: x, y, z, entityPlayer + */ + public void onBlockClicked(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer) { + this.teleportNearby(par1World, par2, par3, par4); + } + + /** + * Teleports the dragon egg somewhere else in a 31x19x31 area centered on the + * egg. + */ + private void teleportNearby(World par1World, int par2, int par3, int par4) { + if (par1World.getBlockId(par2, par3, par4) == this.blockID) { + for (int var5 = 0; var5 < 1000; ++var5) { + int var6 = par2 + par1World.rand.nextInt(16) - par1World.rand.nextInt(16); + int var7 = par3 + par1World.rand.nextInt(8) - par1World.rand.nextInt(8); + int var8 = par4 + par1World.rand.nextInt(16) - par1World.rand.nextInt(16); + + if (par1World.getBlockId(var6, var7, var8) == 0) { + if (!par1World.isRemote) { + par1World.setBlock(var6, var7, var8, this.blockID, par1World.getBlockMetadata(par2, par3, par4), + 2); + par1World.setBlockToAir(par2, par3, par4); + } else { + short var9 = 128; + + for (int var10 = 0; var10 < var9; ++var10) { + double var11 = par1World.rand.nextDouble(); + float var13 = (par1World.rand.nextFloat() - 0.5F) * 0.2F; + float var14 = (par1World.rand.nextFloat() - 0.5F) * 0.2F; + float var15 = (par1World.rand.nextFloat() - 0.5F) * 0.2F; + double var16 = (double) var6 + (double) (par2 - var6) * var11 + + (par1World.rand.nextDouble() - 0.5D) * 1.0D + 0.5D; + double var18 = (double) var7 + (double) (par3 - var7) * var11 + + par1World.rand.nextDouble() * 1.0D - 0.5D; + double var20 = (double) var8 + (double) (par4 - var8) * var11 + + (par1World.rand.nextDouble() - 0.5D) * 1.0D + 0.5D; + par1World.spawnParticle("portal", var16, var18, var20, (double) var13, (double) var14, + (double) var15); + } + } + + return; + } + } + } + } + + /** + * How many world ticks before ticking + */ + public int tickRate(World par1World) { + return 5; + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return false; + } + + /** + * If this block doesn't render as an ordinary block it will return False + * (examples: signs, buttons, stairs, etc) + */ + public boolean renderAsNormalBlock() { + return false; + } + + /** + * The type of render function that is called for this block + */ + public int getRenderType() { + return 27; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockDropper.java b/sp-server/src/main/java/net/minecraft/src/BlockDropper.java new file mode 100644 index 0000000..0b96a5c --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockDropper.java @@ -0,0 +1,66 @@ +package net.minecraft.src; + +public class BlockDropper extends BlockDispenser { + private final IBehaviorDispenseItem dropperDefaultBehaviour = new BehaviorDefaultDispenseItem(); + + protected BlockDropper(int par1) { + super(par1); + } + + /** + * Returns the behavior for the given ItemStack. + */ + protected IBehaviorDispenseItem getBehaviorForItemStack(ItemStack par1ItemStack) { + return this.dropperDefaultBehaviour; + } + + /** + * Returns a new instance of a block's tile entity class. Called on placing the + * block. + */ + public TileEntity createNewTileEntity(World par1World) { + return new TileEntityDropper(); + } + + protected void dispense(World par1World, int par2, int par3, int par4) { + BlockSourceImpl var5 = new BlockSourceImpl(par1World, par2, par3, par4); + TileEntityDispenser var6 = (TileEntityDispenser) var5.getBlockTileEntity(); + + if (var6 != null) { + int var7 = var6.getRandomStackFromInventory(); + + if (var7 < 0) { + par1World.playAuxSFX(1001, par2, par3, par4, 0); + } else { + ItemStack var8 = var6.getStackInSlot(var7); + int var9 = par1World.getBlockMetadata(par2, par3, par4) & 7; + IInventory var10 = TileEntityHopper.getInventoryAtLocation(par1World, + (double) (par2 + Facing.offsetsXForSide[var9]), (double) (par3 + Facing.offsetsYForSide[var9]), + (double) (par4 + Facing.offsetsZForSide[var9])); + ItemStack var11; + + if (var10 != null) { + var11 = TileEntityHopper.insertStack(var10, var8.copy().splitStack(1), Facing.oppositeSide[var9]); + + if (var11 == null) { + var11 = var8.copy(); + + if (--var11.stackSize == 0) { + var11 = null; + } + } else { + var11 = var8.copy(); + } + } else { + var11 = this.dropperDefaultBehaviour.dispense(var5, var8); + + if (var11 != null && var11.stackSize == 0) { + var11 = null; + } + } + + var6.setInventorySlotContents(var7, var11); + } + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockEnchantmentTable.java b/sp-server/src/main/java/net/minecraft/src/BlockEnchantmentTable.java new file mode 100644 index 0000000..4ac17dd --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockEnchantmentTable.java @@ -0,0 +1,64 @@ +package net.minecraft.src; + +public class BlockEnchantmentTable extends BlockContainer { + protected BlockEnchantmentTable(int par1) { + super(par1, Material.rock); + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.75F, 1.0F); + this.setLightOpacity(0); + this.setCreativeTab(CreativeTabs.tabDecorations); + } + + /** + * If this block doesn't render as an ordinary block it will return False + * (examples: signs, buttons, stairs, etc) + */ + public boolean renderAsNormalBlock() { + return false; + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return false; + } + + /** + * Returns a new instance of a block's tile entity class. Called on placing the + * block. + */ + public TileEntity createNewTileEntity(World par1World) { + return new TileEntityEnchantmentTable(); + } + + /** + * Called upon block activation (right click on the block.) + */ + public boolean onBlockActivated(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer, + int par6, float par7, float par8, float par9) { + if (par1World.isRemote) { + return true; + } else { + TileEntityEnchantmentTable var10 = (TileEntityEnchantmentTable) par1World.getBlockTileEntity(par2, par3, + par4); + par5EntityPlayer.displayGUIEnchantment(par2, par3, par4, + var10.func_94135_b() ? var10.func_94133_a() : null); + return true; + } + } + + /** + * Called when the block is placed in the world. + */ + public void onBlockPlacedBy(World par1World, int par2, int par3, int par4, EntityLiving par5EntityLiving, + ItemStack par6ItemStack) { + super.onBlockPlacedBy(par1World, par2, par3, par4, par5EntityLiving, par6ItemStack); + + if (par6ItemStack.hasDisplayName()) { + ((TileEntityEnchantmentTable) par1World.getBlockTileEntity(par2, par3, par4)) + .func_94134_a(par6ItemStack.getDisplayName()); + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockEndPortal.java b/sp-server/src/main/java/net/minecraft/src/BlockEndPortal.java new file mode 100644 index 0000000..29f8a8e --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockEndPortal.java @@ -0,0 +1,94 @@ +package net.minecraft.src; + +import java.util.List; +import java.util.Random; + +public class BlockEndPortal extends BlockContainer { + /** + * true if the enderdragon has been killed - allows end portal blocks to be + * created in the end + */ + public static boolean bossDefeated = false; + + protected BlockEndPortal(int par1, Material par2Material) { + super(par1, par2Material); + this.setLightValue(1.0F); + } + + /** + * Returns a new instance of a block's tile entity class. Called on placing the + * block. + */ + public TileEntity createNewTileEntity(World par1World) { + return new TileEntityEndPortal(); + } + + /** + * Updates the blocks bounds based on its current state. Args: world, x, y, z + */ + public void setBlockBoundsBasedOnState(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + float var5 = 0.0625F; + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, var5, 1.0F); + } + + /** + * Adds all intersecting collision boxes to a list. (Be sure to only add boxes + * to the list if they intersect the mask.) Parameters: World, X, Y, Z, mask, + * list, colliding entity + */ + public void addCollisionBoxesToList(World par1World, int par2, int par3, int par4, AxisAlignedBB par5AxisAlignedBB, + List par6List, Entity par7Entity) { + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return false; + } + + /** + * If this block doesn't render as an ordinary block it will return False + * (examples: signs, buttons, stairs, etc) + */ + public boolean renderAsNormalBlock() { + return false; + } + + /** + * Returns the quantity of items to drop on block destruction. + */ + public int quantityDropped(Random par1Random) { + return 0; + } + + /** + * Triggered whenever an entity collides with this block (enters into the + * block). Args: world, x, y, z, entity + */ + public void onEntityCollidedWithBlock(World par1World, int par2, int par3, int par4, Entity par5Entity) { + if (par5Entity.ridingEntity == null && par5Entity.riddenByEntity == null && !par1World.isRemote) { + par5Entity.travelToTheEnd(1); + } + } + + /** + * The type of render function that is called for this block + */ + public int getRenderType() { + return -1; + } + + /** + * Called whenever the block is added into the world. Args: world, x, y, z + */ + public void onBlockAdded(World par1World, int par2, int par3, int par4) { + if (!bossDefeated) { + if (par1World.provider.dimensionId != 0) { + par1World.setBlockToAir(par2, par3, par4); + } + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockEndPortalFrame.java b/sp-server/src/main/java/net/minecraft/src/BlockEndPortalFrame.java new file mode 100644 index 0000000..bdc00fc --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockEndPortalFrame.java @@ -0,0 +1,77 @@ +package net.minecraft.src; + +import java.util.List; +import java.util.Random; + +public class BlockEndPortalFrame extends Block { + public BlockEndPortalFrame(int par1) { + super(par1, Material.rock); + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return false; + } + + /** + * The type of render function that is called for this block + */ + public int getRenderType() { + return 26; + } + + /** + * Sets the block's bounds for rendering it as an item + */ + public void setBlockBoundsForItemRender() { + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.8125F, 1.0F); + } + + /** + * Adds all intersecting collision boxes to a list. (Be sure to only add boxes + * to the list if they intersect the mask.) Parameters: World, X, Y, Z, mask, + * list, colliding entity + */ + public void addCollisionBoxesToList(World par1World, int par2, int par3, int par4, AxisAlignedBB par5AxisAlignedBB, + List par6List, Entity par7Entity) { + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.8125F, 1.0F); + super.addCollisionBoxesToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity); + int var8 = par1World.getBlockMetadata(par2, par3, par4); + + if (isEnderEyeInserted(var8)) { + this.setBlockBounds(0.3125F, 0.8125F, 0.3125F, 0.6875F, 1.0F, 0.6875F); + super.addCollisionBoxesToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity); + } + + this.setBlockBoundsForItemRender(); + } + + /** + * checks if an ender eye has been inserted into the frame block. parameters: + * metadata + */ + public static boolean isEnderEyeInserted(int par0) { + return (par0 & 4) != 0; + } + + /** + * Returns the ID of the items to drop on destruction. + */ + public int idDropped(int par1, Random par2Random, int par3) { + return 0; + } + + /** + * Called when the block is placed in the world. + */ + public void onBlockPlacedBy(World par1World, int par2, int par3, int par4, EntityLiving par5EntityLiving, + ItemStack par6ItemStack) { + int var7 = ((MathHelper.floor_double((double) (par5EntityLiving.rotationYaw * 4.0F / 360.0F) + 0.5D) & 3) + 2) + % 4; + par1World.setBlockMetadata(par2, par3, par4, var7, 2); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockEnderChest.java b/sp-server/src/main/java/net/minecraft/src/BlockEnderChest.java new file mode 100644 index 0000000..619a41b --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockEnderChest.java @@ -0,0 +1,115 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockEnderChest extends BlockContainer { + protected BlockEnderChest(int par1) { + super(par1, Material.rock); + this.setCreativeTab(CreativeTabs.tabDecorations); + this.setBlockBounds(0.0625F, 0.0F, 0.0625F, 0.9375F, 0.875F, 0.9375F); + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return false; + } + + /** + * If this block doesn't render as an ordinary block it will return False + * (examples: signs, buttons, stairs, etc) + */ + public boolean renderAsNormalBlock() { + return false; + } + + /** + * The type of render function that is called for this block + */ + public int getRenderType() { + return 22; + } + + /** + * Returns the ID of the items to drop on destruction. + */ + public int idDropped(int par1, Random par2Random, int par3) { + return Block.obsidian.blockID; + } + + /** + * Returns the quantity of items to drop on block destruction. + */ + public int quantityDropped(Random par1Random) { + return 8; + } + + /** + * Return true if a player with Silk Touch can harvest this block directly, and + * not its normal drops. + */ + protected boolean canSilkHarvest() { + return true; + } + + /** + * Called when the block is placed in the world. + */ + public void onBlockPlacedBy(World par1World, int par2, int par3, int par4, EntityLiving par5EntityLiving, + ItemStack par6ItemStack) { + byte var7 = 0; + int var8 = MathHelper.floor_double((double) (par5EntityLiving.rotationYaw * 4.0F / 360.0F) + 0.5D) & 3; + + if (var8 == 0) { + var7 = 2; + } + + if (var8 == 1) { + var7 = 5; + } + + if (var8 == 2) { + var7 = 3; + } + + if (var8 == 3) { + var7 = 4; + } + + par1World.setBlockMetadata(par2, par3, par4, var7, 2); + } + + /** + * Called upon block activation (right click on the block.) + */ + public boolean onBlockActivated(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer, + int par6, float par7, float par8, float par9) { + InventoryEnderChest var10 = par5EntityPlayer.getInventoryEnderChest(); + TileEntityEnderChest var11 = (TileEntityEnderChest) par1World.getBlockTileEntity(par2, par3, par4); + + if (var10 != null && var11 != null) { + if (par1World.isBlockNormalCube(par2, par3 + 1, par4)) { + return true; + } else if (par1World.isRemote) { + return true; + } else { + var10.setAssociatedChest(var11); + par5EntityPlayer.displayGUIChest(var10); + return true; + } + } else { + return true; + } + } + + /** + * Returns a new instance of a block's tile entity class. Called on placing the + * block. + */ + public TileEntity createNewTileEntity(World par1World) { + return new TileEntityEnderChest(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockEventData.java b/sp-server/src/main/java/net/minecraft/src/BlockEventData.java new file mode 100644 index 0000000..0d27391 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockEventData.java @@ -0,0 +1,81 @@ +package net.minecraft.src; + +public class BlockEventData { + private int coordX; + private int coordY; + private int coordZ; + private int blockID; + + /** Different for each blockID */ + private int eventID; + + /** Different for each blockID, eventID */ + private int eventParameter; + + public BlockEventData(int par1, int par2, int par3, int par4, int par5, int par6) { + this.coordX = par1; + this.coordY = par2; + this.coordZ = par3; + this.eventID = par5; + this.eventParameter = par6; + this.blockID = par4; + } + + /** + * Get the X coordinate. + */ + public int getX() { + return this.coordX; + } + + /** + * Get the Y coordinate. + */ + public int getY() { + return this.coordY; + } + + /** + * Get the Z coordinate. + */ + public int getZ() { + return this.coordZ; + } + + /** + * Get the Event ID (different for each BlockID) + */ + public int getEventID() { + return this.eventID; + } + + /** + * Get the Event Parameter (different for each BlockID,EventID) + */ + public int getEventParameter() { + return this.eventParameter; + } + + /** + * Gets the BlockID for this BlockEventData + */ + public int getBlockID() { + return this.blockID; + } + + public boolean equals(Object par1Obj) { + if (!(par1Obj instanceof BlockEventData)) { + return false; + } else { + BlockEventData var2 = (BlockEventData) par1Obj; + return this.coordX == var2.coordX && this.coordY == var2.coordY && this.coordZ == var2.coordZ + && this.eventID == var2.eventID && this.eventParameter == var2.eventParameter + && this.blockID == var2.blockID; + } + } + + public String toString() { + return "TE(" + this.coordX + "," + this.coordY + "," + this.coordZ + ")," + this.eventID + "," + + this.eventParameter + "," + this.blockID; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockFarmland.java b/sp-server/src/main/java/net/minecraft/src/BlockFarmland.java new file mode 100644 index 0000000..b3ef61b --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockFarmland.java @@ -0,0 +1,128 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockFarmland extends Block { + protected BlockFarmland(int par1) { + super(par1, Material.ground); + this.setTickRandomly(true); + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.9375F, 1.0F); + this.setLightOpacity(255); + } + + /** + * Returns a bounding box from the pool of bounding boxes (this means this box + * can change after the pool has been cleared to be reused) + */ + public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int par4) { + return AxisAlignedBB.getAABBPool().getAABB((double) (par2 + 0), (double) (par3 + 0), (double) (par4 + 0), + (double) (par2 + 1), (double) (par3 + 1), (double) (par4 + 1)); + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return false; + } + + /** + * If this block doesn't render as an ordinary block it will return False + * (examples: signs, buttons, stairs, etc) + */ + public boolean renderAsNormalBlock() { + return false; + } + + /** + * Ticks the block if it's been scheduled + */ + public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random) { + if (!this.isWaterNearby(par1World, par2, par3, par4) && !par1World.canLightningStrikeAt(par2, par3 + 1, par4)) { + int var6 = par1World.getBlockMetadata(par2, par3, par4); + + if (var6 > 0) { + par1World.setBlockMetadata(par2, par3, par4, var6 - 1, 2); + } else if (!this.isCropsNearby(par1World, par2, par3, par4)) { + par1World.setBlock(par2, par3, par4, Block.dirt.blockID); + } + } else { + par1World.setBlockMetadata(par2, par3, par4, 7, 2); + } + } + + /** + * Block's chance to react to an entity falling on it. + */ + public void onFallenUpon(World par1World, int par2, int par3, int par4, Entity par5Entity, float par6) { + if (!par1World.isRemote && par1World.rand.nextFloat() < par6 - 0.5F) { + if (!(par5Entity instanceof EntityPlayer) + && !par1World.getGameRules().getGameRuleBooleanValue("mobGriefing")) { + return; + } + + par1World.setBlock(par2, par3, par4, Block.dirt.blockID); + } + } + + /** + * returns true if there is at least one cropblock nearby (x-1 to x+1, y+1, z-1 + * to z+1) + */ + private boolean isCropsNearby(World par1World, int par2, int par3, int par4) { + byte var5 = 0; + + for (int var6 = par2 - var5; var6 <= par2 + var5; ++var6) { + for (int var7 = par4 - var5; var7 <= par4 + var5; ++var7) { + int var8 = par1World.getBlockId(var6, par3 + 1, var7); + + if (var8 == Block.crops.blockID || var8 == Block.melonStem.blockID || var8 == Block.pumpkinStem.blockID + || var8 == Block.potato.blockID || var8 == Block.carrot.blockID) { + return true; + } + } + } + + return false; + } + + /** + * returns true if there's water nearby (x-4 to x+4, y to y+1, k-4 to k+4) + */ + private boolean isWaterNearby(World par1World, int par2, int par3, int par4) { + for (int var5 = par2 - 4; var5 <= par2 + 4; ++var5) { + for (int var6 = par3; var6 <= par3 + 1; ++var6) { + for (int var7 = par4 - 4; var7 <= par4 + 4; ++var7) { + if (par1World.getBlockMaterial(var5, var6, var7) == Material.water) { + return true; + } + } + } + } + + return false; + } + + /** + * Lets the block know when one of its neighbor changes. Doesn't know which + * neighbor changed (coordinates passed are their own) Args: x, y, z, neighbor + * blockID + */ + public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5) { + super.onNeighborBlockChange(par1World, par2, par3, par4, par5); + Material var6 = par1World.getBlockMaterial(par2, par3 + 1, par4); + + if (var6.isSolid()) { + par1World.setBlock(par2, par3, par4, Block.dirt.blockID); + } + } + + /** + * Returns the ID of the items to drop on destruction. + */ + public int idDropped(int par1, Random par2Random, int par3) { + return Block.dirt.idDropped(0, par2Random, par3); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockFence.java b/sp-server/src/main/java/net/minecraft/src/BlockFence.java new file mode 100644 index 0000000..e7271b1 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockFence.java @@ -0,0 +1,149 @@ +package net.minecraft.src; + +import java.util.List; + +public class BlockFence extends Block { + private final String field_94464_a; + + public BlockFence(int par1, String par2Str, Material par3Material) { + super(par1, par3Material); + this.field_94464_a = par2Str; + this.setCreativeTab(CreativeTabs.tabDecorations); + } + + /** + * Adds all intersecting collision boxes to a list. (Be sure to only add boxes + * to the list if they intersect the mask.) Parameters: World, X, Y, Z, mask, + * list, colliding entity + */ + public void addCollisionBoxesToList(World par1World, int par2, int par3, int par4, AxisAlignedBB par5AxisAlignedBB, + List par6List, Entity par7Entity) { + boolean var8 = this.canConnectFenceTo(par1World, par2, par3, par4 - 1); + boolean var9 = this.canConnectFenceTo(par1World, par2, par3, par4 + 1); + boolean var10 = this.canConnectFenceTo(par1World, par2 - 1, par3, par4); + boolean var11 = this.canConnectFenceTo(par1World, par2 + 1, par3, par4); + float var12 = 0.375F; + float var13 = 0.625F; + float var14 = 0.375F; + float var15 = 0.625F; + + if (var8) { + var14 = 0.0F; + } + + if (var9) { + var15 = 1.0F; + } + + if (var8 || var9) { + this.setBlockBounds(var12, 0.0F, var14, var13, 1.5F, var15); + super.addCollisionBoxesToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity); + } + + var14 = 0.375F; + var15 = 0.625F; + + if (var10) { + var12 = 0.0F; + } + + if (var11) { + var13 = 1.0F; + } + + if (var10 || var11 || !var8 && !var9) { + this.setBlockBounds(var12, 0.0F, var14, var13, 1.5F, var15); + super.addCollisionBoxesToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity); + } + + if (var8) { + var14 = 0.0F; + } + + if (var9) { + var15 = 1.0F; + } + + this.setBlockBounds(var12, 0.0F, var14, var13, 1.0F, var15); + } + + /** + * Updates the blocks bounds based on its current state. Args: world, x, y, z + */ + public void setBlockBoundsBasedOnState(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + boolean var5 = this.canConnectFenceTo(par1IBlockAccess, par2, par3, par4 - 1); + boolean var6 = this.canConnectFenceTo(par1IBlockAccess, par2, par3, par4 + 1); + boolean var7 = this.canConnectFenceTo(par1IBlockAccess, par2 - 1, par3, par4); + boolean var8 = this.canConnectFenceTo(par1IBlockAccess, par2 + 1, par3, par4); + float var9 = 0.375F; + float var10 = 0.625F; + float var11 = 0.375F; + float var12 = 0.625F; + + if (var5) { + var11 = 0.0F; + } + + if (var6) { + var12 = 1.0F; + } + + if (var7) { + var9 = 0.0F; + } + + if (var8) { + var10 = 1.0F; + } + + this.setBlockBounds(var9, 0.0F, var11, var10, 1.0F, var12); + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return false; + } + + /** + * If this block doesn't render as an ordinary block it will return False + * (examples: signs, buttons, stairs, etc) + */ + public boolean renderAsNormalBlock() { + return false; + } + + public boolean getBlocksMovement(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + return false; + } + + /** + * The type of render function that is called for this block + */ + public int getRenderType() { + return 11; + } + + /** + * Returns true if the specified block can be connected by a fence + */ + public boolean canConnectFenceTo(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + int var5 = par1IBlockAccess.getBlockId(par2, par3, par4); + + if (var5 != this.blockID && var5 != Block.fenceGate.blockID) { + Block var6 = Block.blocksList[var5]; + return var6 != null && var6.blockMaterial.isOpaque() && var6.renderAsNormalBlock() + ? var6.blockMaterial != Material.pumpkin + : false; + } else { + return true; + } + } + + public static boolean isIdAFence(int par0) { + return par0 == Block.fence.blockID || par0 == Block.netherFence.blockID; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockFenceGate.java b/sp-server/src/main/java/net/minecraft/src/BlockFenceGate.java new file mode 100644 index 0000000..cf4b67b --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockFenceGate.java @@ -0,0 +1,137 @@ +package net.minecraft.src; + +public class BlockFenceGate extends BlockDirectional { + public BlockFenceGate(int par1) { + super(par1, Material.wood); + this.setCreativeTab(CreativeTabs.tabRedstone); + } + + /** + * Checks to see if its valid to put this block at the specified coordinates. + * Args: world, x, y, z + */ + public boolean canPlaceBlockAt(World par1World, int par2, int par3, int par4) { + return !par1World.getBlockMaterial(par2, par3 - 1, par4).isSolid() ? false + : super.canPlaceBlockAt(par1World, par2, par3, par4); + } + + /** + * Returns a bounding box from the pool of bounding boxes (this means this box + * can change after the pool has been cleared to be reused) + */ + public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int par4) { + int var5 = par1World.getBlockMetadata(par2, par3, par4); + return isFenceGateOpen(var5) ? null + : (var5 != 2 && var5 != 0 + ? AxisAlignedBB.getAABBPool().getAABB((double) ((float) par2 + 0.375F), (double) par3, + (double) par4, (double) ((float) par2 + 0.625F), (double) ((float) par3 + 1.5F), + (double) (par4 + 1)) + : AxisAlignedBB.getAABBPool().getAABB((double) par2, (double) par3, + (double) ((float) par4 + 0.375F), (double) (par2 + 1), (double) ((float) par3 + 1.5F), + (double) ((float) par4 + 0.625F))); + } + + /** + * Updates the blocks bounds based on its current state. Args: world, x, y, z + */ + public void setBlockBoundsBasedOnState(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + int var5 = getDirection(par1IBlockAccess.getBlockMetadata(par2, par3, par4)); + + if (var5 != 2 && var5 != 0) { + this.setBlockBounds(0.375F, 0.0F, 0.0F, 0.625F, 1.0F, 1.0F); + } else { + this.setBlockBounds(0.0F, 0.0F, 0.375F, 1.0F, 1.0F, 0.625F); + } + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return false; + } + + /** + * If this block doesn't render as an ordinary block it will return False + * (examples: signs, buttons, stairs, etc) + */ + public boolean renderAsNormalBlock() { + return false; + } + + public boolean getBlocksMovement(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + return isFenceGateOpen(par1IBlockAccess.getBlockMetadata(par2, par3, par4)); + } + + /** + * The type of render function that is called for this block + */ + public int getRenderType() { + return 21; + } + + /** + * Called when the block is placed in the world. + */ + public void onBlockPlacedBy(World par1World, int par2, int par3, int par4, EntityLiving par5EntityLiving, + ItemStack par6ItemStack) { + int var7 = (MathHelper.floor_double((double) (par5EntityLiving.rotationYaw * 4.0F / 360.0F) + 0.5D) & 3) % 4; + par1World.setBlockMetadata(par2, par3, par4, var7, 2); + } + + /** + * Called upon block activation (right click on the block.) + */ + public boolean onBlockActivated(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer, + int par6, float par7, float par8, float par9) { + int var10 = par1World.getBlockMetadata(par2, par3, par4); + + if (isFenceGateOpen(var10)) { + par1World.setBlockMetadata(par2, par3, par4, var10 & -5, 2); + } else { + int var11 = (MathHelper.floor_double((double) (par5EntityPlayer.rotationYaw * 4.0F / 360.0F) + 0.5D) & 3) + % 4; + int var12 = getDirection(var10); + + if (var12 == (var11 + 2) % 4) { + var10 = var11; + } + + par1World.setBlockMetadata(par2, par3, par4, var10 | 4, 2); + } + + par1World.playAuxSFXAtEntity(par5EntityPlayer, 1003, par2, par3, par4, 0); + return true; + } + + /** + * Lets the block know when one of its neighbor changes. Doesn't know which + * neighbor changed (coordinates passed are their own) Args: x, y, z, neighbor + * blockID + */ + public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5) { + if (!par1World.isRemote) { + int var6 = par1World.getBlockMetadata(par2, par3, par4); + boolean var7 = par1World.isBlockIndirectlyGettingPowered(par2, par3, par4); + + if (var7 || par5 > 0 && Block.blocksList[par5].canProvidePower()) { + if (var7 && !isFenceGateOpen(var6)) { + par1World.setBlockMetadata(par2, par3, par4, var6 | 4, 2); + par1World.playAuxSFXAtEntity((EntityPlayer) null, 1003, par2, par3, par4, 0); + } else if (!var7 && isFenceGateOpen(var6)) { + par1World.setBlockMetadata(par2, par3, par4, var6 & -5, 2); + par1World.playAuxSFXAtEntity((EntityPlayer) null, 1003, par2, par3, par4, 0); + } + } + } + } + + /** + * Returns if the fence gate is open according to its metadata. + */ + public static boolean isFenceGateOpen(int par0) { + return (par0 & 4) != 0; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockFire.java b/sp-server/src/main/java/net/minecraft/src/BlockFire.java new file mode 100644 index 0000000..5986378 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockFire.java @@ -0,0 +1,323 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockFire extends Block { + /** The chance this block will encourage nearby blocks to catch on fire */ + private int[] chanceToEncourageFire = new int[256]; + + /** + * This is an array indexed by block ID the larger the number in the array the + * more likely a block type will catch fires + */ + private int[] abilityToCatchFire = new int[256]; + + protected BlockFire(int par1) { + super(par1, Material.fire); + this.setTickRandomly(true); + } + + /** + * This method is called on a block after all other blocks gets already created. + * You can use it to reference and configure something on the block that needs + * the others ones. + */ + public void initializeBlock() { + this.setBurnRate(Block.planks.blockID, 5, 20); + this.setBurnRate(Block.woodDoubleSlab.blockID, 5, 20); + this.setBurnRate(Block.woodSingleSlab.blockID, 5, 20); + this.setBurnRate(Block.fence.blockID, 5, 20); + this.setBurnRate(Block.stairsWoodOak.blockID, 5, 20); + this.setBurnRate(Block.stairsWoodBirch.blockID, 5, 20); + this.setBurnRate(Block.stairsWoodSpruce.blockID, 5, 20); + this.setBurnRate(Block.stairsWoodJungle.blockID, 5, 20); + this.setBurnRate(Block.wood.blockID, 5, 5); + this.setBurnRate(Block.leaves.blockID, 30, 60); + this.setBurnRate(Block.bookShelf.blockID, 30, 20); + this.setBurnRate(Block.tnt.blockID, 15, 100); + this.setBurnRate(Block.tallGrass.blockID, 60, 100); + this.setBurnRate(Block.cloth.blockID, 30, 60); + this.setBurnRate(Block.vine.blockID, 15, 100); + } + + /** + * Sets the burn rate for a block. The larger abilityToCatchFire the more easily + * it will catch. The larger chanceToEncourageFire the faster it will burn and + * spread to other blocks. Args: blockID, chanceToEncourageFire, + * abilityToCatchFire + */ + private void setBurnRate(int par1, int par2, int par3) { + this.chanceToEncourageFire[par1] = par2; + this.abilityToCatchFire[par1] = par3; + } + + /** + * Returns a bounding box from the pool of bounding boxes (this means this box + * can change after the pool has been cleared to be reused) + */ + public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int par4) { + return null; + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return false; + } + + /** + * If this block doesn't render as an ordinary block it will return False + * (examples: signs, buttons, stairs, etc) + */ + public boolean renderAsNormalBlock() { + return false; + } + + /** + * The type of render function that is called for this block + */ + public int getRenderType() { + return 3; + } + + /** + * Returns the quantity of items to drop on block destruction. + */ + public int quantityDropped(Random par1Random) { + return 0; + } + + /** + * How many world ticks before ticking + */ + public int tickRate(World par1World) { + return 30; + } + + /** + * Ticks the block if it's been scheduled + */ + public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random) { + if (par1World.getGameRules().getGameRuleBooleanValue("doFireTick")) { + boolean var6 = par1World.getBlockId(par2, par3 - 1, par4) == Block.netherrack.blockID; + + if (par1World.provider instanceof WorldProviderEnd + && par1World.getBlockId(par2, par3 - 1, par4) == Block.bedrock.blockID) { + var6 = true; + } + + if (!this.canPlaceBlockAt(par1World, par2, par3, par4)) { + par1World.setBlockToAir(par2, par3, par4); + } + + if (!var6 && par1World.isRaining() + && (par1World.canLightningStrikeAt(par2, par3, par4) + || par1World.canLightningStrikeAt(par2 - 1, par3, par4) + || par1World.canLightningStrikeAt(par2 + 1, par3, par4) + || par1World.canLightningStrikeAt(par2, par3, par4 - 1) + || par1World.canLightningStrikeAt(par2, par3, par4 + 1))) { + par1World.setBlockToAir(par2, par3, par4); + } else { + int var7 = par1World.getBlockMetadata(par2, par3, par4); + + if (var7 < 15) { + par1World.setBlockMetadata(par2, par3, par4, var7 + par5Random.nextInt(3) / 2, 4); + } + + par1World.scheduleBlockUpdate(par2, par3, par4, this.blockID, + this.tickRate(par1World) + par5Random.nextInt(10)); + + if (!var6 && !this.canNeighborBurn(par1World, par2, par3, par4)) { + if (!par1World.doesBlockHaveSolidTopSurface(par2, par3 - 1, par4) || var7 > 3) { + par1World.setBlockToAir(par2, par3, par4); + } + } else if (!var6 && !this.canBlockCatchFire(par1World, par2, par3 - 1, par4) && var7 == 15 + && par5Random.nextInt(4) == 0) { + par1World.setBlockToAir(par2, par3, par4); + } else { + boolean var8 = par1World.isBlockHighHumidity(par2, par3, par4); + byte var9 = 0; + + if (var8) { + var9 = -50; + } + + this.tryToCatchBlockOnFire(par1World, par2 + 1, par3, par4, 300 + var9, par5Random, var7); + this.tryToCatchBlockOnFire(par1World, par2 - 1, par3, par4, 300 + var9, par5Random, var7); + this.tryToCatchBlockOnFire(par1World, par2, par3 - 1, par4, 250 + var9, par5Random, var7); + this.tryToCatchBlockOnFire(par1World, par2, par3 + 1, par4, 250 + var9, par5Random, var7); + this.tryToCatchBlockOnFire(par1World, par2, par3, par4 - 1, 300 + var9, par5Random, var7); + this.tryToCatchBlockOnFire(par1World, par2, par3, par4 + 1, 300 + var9, par5Random, var7); + + for (int var10 = par2 - 1; var10 <= par2 + 1; ++var10) { + for (int var11 = par4 - 1; var11 <= par4 + 1; ++var11) { + for (int var12 = par3 - 1; var12 <= par3 + 4; ++var12) { + if (var10 != par2 || var12 != par3 || var11 != par4) { + int var13 = 100; + + if (var12 > par3 + 1) { + var13 += (var12 - (par3 + 1)) * 100; + } + + int var14 = this.getChanceOfNeighborsEncouragingFire(par1World, var10, var12, + var11); + + if (var14 > 0) { + int var15 = (var14 + 40 + par1World.difficultySetting * 7) / (var7 + 30); + + if (var8) { + var15 /= 2; + } + + if (var15 > 0 && par5Random.nextInt(var13) <= var15 + && (!par1World.isRaining() + || !par1World.canLightningStrikeAt(var10, var12, var11)) + && !par1World.canLightningStrikeAt(var10 - 1, var12, par4) + && !par1World.canLightningStrikeAt(var10 + 1, var12, var11) + && !par1World.canLightningStrikeAt(var10, var12, var11 - 1) + && !par1World.canLightningStrikeAt(var10, var12, var11 + 1)) { + int var16 = var7 + par5Random.nextInt(5) / 4; + + if (var16 > 15) { + var16 = 15; + } + + par1World.setBlock(var10, var12, var11, this.blockID, var16, 3); + } + } + } + } + } + } + } + } + } + } + + public boolean func_82506_l() { + return false; + } + + private void tryToCatchBlockOnFire(World par1World, int par2, int par3, int par4, int par5, Random par6Random, + int par7) { + int var8 = this.abilityToCatchFire[par1World.getBlockId(par2, par3, par4)]; + + if (par6Random.nextInt(par5) < var8) { + boolean var9 = par1World.getBlockId(par2, par3, par4) == Block.tnt.blockID; + + if (par6Random.nextInt(par7 + 10) < 5 && !par1World.canLightningStrikeAt(par2, par3, par4)) { + int var10 = par7 + par6Random.nextInt(5) / 4; + + if (var10 > 15) { + var10 = 15; + } + + par1World.setBlock(par2, par3, par4, this.blockID, var10, 3); + } else { + par1World.setBlockToAir(par2, par3, par4); + } + + if (var9) { + Block.tnt.onBlockDestroyedByPlayer(par1World, par2, par3, par4, 1); + } + } + } + + /** + * Returns true if at least one block next to this one can burn. + */ + private boolean canNeighborBurn(World par1World, int par2, int par3, int par4) { + return this.canBlockCatchFire(par1World, par2 + 1, par3, par4) ? true + : (this.canBlockCatchFire(par1World, par2 - 1, par3, par4) ? true + : (this.canBlockCatchFire(par1World, par2, par3 - 1, par4) ? true + : (this.canBlockCatchFire(par1World, par2, par3 + 1, par4) ? true + : (this.canBlockCatchFire(par1World, par2, par3, par4 - 1) ? true + : this.canBlockCatchFire(par1World, par2, par3, par4 + 1))))); + } + + /** + * Gets the highest chance of a neighbor block encouraging this block to catch + * fire + */ + private int getChanceOfNeighborsEncouragingFire(World par1World, int par2, int par3, int par4) { + byte var5 = 0; + + if (!par1World.isAirBlock(par2, par3, par4)) { + return 0; + } else { + int var6 = this.getChanceToEncourageFire(par1World, par2 + 1, par3, par4, var5); + var6 = this.getChanceToEncourageFire(par1World, par2 - 1, par3, par4, var6); + var6 = this.getChanceToEncourageFire(par1World, par2, par3 - 1, par4, var6); + var6 = this.getChanceToEncourageFire(par1World, par2, par3 + 1, par4, var6); + var6 = this.getChanceToEncourageFire(par1World, par2, par3, par4 - 1, var6); + var6 = this.getChanceToEncourageFire(par1World, par2, par3, par4 + 1, var6); + return var6; + } + } + + /** + * Returns if this block is collidable (only used by Fire). Args: x, y, z + */ + public boolean isCollidable() { + return false; + } + + /** + * Checks the specified block coordinate to see if it can catch fire. Args: + * blockAccess, x, y, z + */ + public boolean canBlockCatchFire(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + return this.chanceToEncourageFire[par1IBlockAccess.getBlockId(par2, par3, par4)] > 0; + } + + /** + * Retrieves a specified block's chance to encourage their neighbors to burn and + * if the number is greater than the current number passed in it will return its + * number instead of the passed in one. Args: world, x, y, z, + * curChanceToEncourageFire + */ + public int getChanceToEncourageFire(World par1World, int par2, int par3, int par4, int par5) { + int var6 = this.chanceToEncourageFire[par1World.getBlockId(par2, par3, par4)]; + return var6 > par5 ? var6 : par5; + } + + /** + * Checks to see if its valid to put this block at the specified coordinates. + * Args: world, x, y, z + */ + public boolean canPlaceBlockAt(World par1World, int par2, int par3, int par4) { + return par1World.doesBlockHaveSolidTopSurface(par2, par3 - 1, par4) + || this.canNeighborBurn(par1World, par2, par3, par4); + } + + /** + * Lets the block know when one of its neighbor changes. Doesn't know which + * neighbor changed (coordinates passed are their own) Args: x, y, z, neighbor + * blockID + */ + public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5) { + if (!par1World.doesBlockHaveSolidTopSurface(par2, par3 - 1, par4) + && !this.canNeighborBurn(par1World, par2, par3, par4)) { + par1World.setBlockToAir(par2, par3, par4); + } + } + + /** + * Called whenever the block is added into the world. Args: world, x, y, z + */ + public void onBlockAdded(World par1World, int par2, int par3, int par4) { + if (par1World.provider.dimensionId > 0 || par1World.getBlockId(par2, par3 - 1, par4) != Block.obsidian.blockID + || !Block.portal.tryToCreatePortal(par1World, par2, par3, par4)) { + if (!par1World.doesBlockHaveSolidTopSurface(par2, par3 - 1, par4) + && !this.canNeighborBurn(par1World, par2, par3, par4)) { + par1World.setBlockToAir(par2, par3, par4); + } else { + par1World.scheduleBlockUpdate(par2, par3, par4, this.blockID, + this.tickRate(par1World) + par1World.rand.nextInt(10)); + } + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockFlower.java b/sp-server/src/main/java/net/minecraft/src/BlockFlower.java new file mode 100644 index 0000000..bde6ed0 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockFlower.java @@ -0,0 +1,100 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockFlower extends Block { + protected BlockFlower(int par1, Material par2Material) { + super(par1, par2Material); + this.setTickRandomly(true); + float var3 = 0.2F; + this.setBlockBounds(0.5F - var3, 0.0F, 0.5F - var3, 0.5F + var3, var3 * 3.0F, 0.5F + var3); + this.setCreativeTab(CreativeTabs.tabDecorations); + } + + protected BlockFlower(int par1) { + this(par1, Material.plants); + } + + /** + * Checks to see if its valid to put this block at the specified coordinates. + * Args: world, x, y, z + */ + public boolean canPlaceBlockAt(World par1World, int par2, int par3, int par4) { + return super.canPlaceBlockAt(par1World, par2, par3, par4) + && this.canThisPlantGrowOnThisBlockID(par1World.getBlockId(par2, par3 - 1, par4)); + } + + /** + * Gets passed in the blockID of the block below and supposed to return true if + * its allowed to grow on the type of blockID passed in. Args: blockID + */ + protected boolean canThisPlantGrowOnThisBlockID(int par1) { + return par1 == Block.grass.blockID || par1 == Block.dirt.blockID || par1 == Block.tilledField.blockID; + } + + /** + * Lets the block know when one of its neighbor changes. Doesn't know which + * neighbor changed (coordinates passed are their own) Args: x, y, z, neighbor + * blockID + */ + public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5) { + super.onNeighborBlockChange(par1World, par2, par3, par4, par5); + this.checkFlowerChange(par1World, par2, par3, par4); + } + + /** + * Ticks the block if it's been scheduled + */ + public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random) { + this.checkFlowerChange(par1World, par2, par3, par4); + } + + protected final void checkFlowerChange(World par1World, int par2, int par3, int par4) { + if (!this.canBlockStay(par1World, par2, par3, par4)) { + this.dropBlockAsItem(par1World, par2, par3, par4, par1World.getBlockMetadata(par2, par3, par4), 0); + par1World.setBlockToAir(par2, par3, par4); + } + } + + /** + * Can this block stay at this position. Similar to canPlaceBlockAt except gets + * checked often with plants. + */ + public boolean canBlockStay(World par1World, int par2, int par3, int par4) { + return (par1World.getFullBlockLightValue(par2, par3, par4) >= 8 + || par1World.canBlockSeeTheSky(par2, par3, par4)) + && this.canThisPlantGrowOnThisBlockID(par1World.getBlockId(par2, par3 - 1, par4)); + } + + /** + * Returns a bounding box from the pool of bounding boxes (this means this box + * can change after the pool has been cleared to be reused) + */ + public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int par4) { + return null; + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return false; + } + + /** + * If this block doesn't render as an ordinary block it will return False + * (examples: signs, buttons, stairs, etc) + */ + public boolean renderAsNormalBlock() { + return false; + } + + /** + * The type of render function that is called for this block + */ + public int getRenderType() { + return 1; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockFlowerPot.java b/sp-server/src/main/java/net/minecraft/src/BlockFlowerPot.java new file mode 100644 index 0000000..2080596 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockFlowerPot.java @@ -0,0 +1,213 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockFlowerPot extends Block { + public BlockFlowerPot(int par1) { + super(par1, Material.circuits); + this.setBlockBoundsForItemRender(); + } + + /** + * Sets the block's bounds for rendering it as an item + */ + public void setBlockBoundsForItemRender() { + float var1 = 0.375F; + float var2 = var1 / 2.0F; + this.setBlockBounds(0.5F - var2, 0.0F, 0.5F - var2, 0.5F + var2, var1, 0.5F + var2); + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return false; + } + + /** + * The type of render function that is called for this block + */ + public int getRenderType() { + return 33; + } + + /** + * If this block doesn't render as an ordinary block it will return False + * (examples: signs, buttons, stairs, etc) + */ + public boolean renderAsNormalBlock() { + return false; + } + + /** + * Called upon block activation (right click on the block.) + */ + public boolean onBlockActivated(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer, + int par6, float par7, float par8, float par9) { + ItemStack var10 = par5EntityPlayer.inventory.getCurrentItem(); + + if (var10 == null) { + return false; + } else if (par1World.getBlockMetadata(par2, par3, par4) != 0) { + return false; + } else { + int var11 = getMetaForPlant(var10); + + if (var11 > 0) { + par1World.setBlockMetadata(par2, par3, par4, var11, 2); + + if (!par5EntityPlayer.capabilities.isCreativeMode && --var10.stackSize <= 0) { + par5EntityPlayer.inventory.setInventorySlotContents(par5EntityPlayer.inventory.currentItem, + (ItemStack) null); + } + + return true; + } else { + return false; + } + } + } + + /** + * Get the block's damage value (for use with pick block). + */ + public int getDamageValue(World par1World, int par2, int par3, int par4) { + ItemStack var5 = getPlantForMeta(par1World.getBlockMetadata(par2, par3, par4)); + return var5 == null ? Item.flowerPot.itemID : var5.getItemDamage(); + } + + /** + * Checks to see if its valid to put this block at the specified coordinates. + * Args: world, x, y, z + */ + public boolean canPlaceBlockAt(World par1World, int par2, int par3, int par4) { + return super.canPlaceBlockAt(par1World, par2, par3, par4) + && par1World.doesBlockHaveSolidTopSurface(par2, par3 - 1, par4); + } + + /** + * Lets the block know when one of its neighbor changes. Doesn't know which + * neighbor changed (coordinates passed are their own) Args: x, y, z, neighbor + * blockID + */ + public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5) { + if (!par1World.doesBlockHaveSolidTopSurface(par2, par3 - 1, par4)) { + this.dropBlockAsItem(par1World, par2, par3, par4, par1World.getBlockMetadata(par2, par3, par4), 0); + par1World.setBlockToAir(par2, par3, par4); + } + } + + /** + * Drops the block items with a specified chance of dropping the specified items + */ + public void dropBlockAsItemWithChance(World par1World, int par2, int par3, int par4, int par5, float par6, + int par7) { + super.dropBlockAsItemWithChance(par1World, par2, par3, par4, par5, par6, par7); + + if (par5 > 0) { + ItemStack var8 = getPlantForMeta(par5); + + if (var8 != null) { + this.dropBlockAsItem_do(par1World, par2, par3, par4, var8); + } + } + } + + /** + * Returns the ID of the items to drop on destruction. + */ + public int idDropped(int par1, Random par2Random, int par3) { + return Item.flowerPot.itemID; + } + + /** + * Return the item associated with the specified flower pot metadata value. + */ + public static ItemStack getPlantForMeta(int par0) { + switch (par0) { + case 1: + return new ItemStack(Block.plantRed); + + case 2: + return new ItemStack(Block.plantYellow); + + case 3: + return new ItemStack(Block.sapling, 1, 0); + + case 4: + return new ItemStack(Block.sapling, 1, 1); + + case 5: + return new ItemStack(Block.sapling, 1, 2); + + case 6: + return new ItemStack(Block.sapling, 1, 3); + + case 7: + return new ItemStack(Block.mushroomRed); + + case 8: + return new ItemStack(Block.mushroomBrown); + + case 9: + return new ItemStack(Block.cactus); + + case 10: + return new ItemStack(Block.deadBush); + + case 11: + return new ItemStack(Block.tallGrass, 1, 2); + + default: + return null; + } + } + + /** + * Return the flower pot metadata value associated with the specified item. + */ + public static int getMetaForPlant(ItemStack par0ItemStack) { + int var1 = par0ItemStack.getItem().itemID; + + if (var1 == Block.plantRed.blockID) { + return 1; + } else if (var1 == Block.plantYellow.blockID) { + return 2; + } else if (var1 == Block.cactus.blockID) { + return 9; + } else if (var1 == Block.mushroomBrown.blockID) { + return 8; + } else if (var1 == Block.mushroomRed.blockID) { + return 7; + } else if (var1 == Block.deadBush.blockID) { + return 10; + } else { + if (var1 == Block.sapling.blockID) { + switch (par0ItemStack.getItemDamage()) { + case 0: + return 3; + + case 1: + return 4; + + case 2: + return 5; + + case 3: + return 6; + } + } + + if (var1 == Block.tallGrass.blockID) { + switch (par0ItemStack.getItemDamage()) { + case 2: + return 11; + } + } + + return 0; + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockFlowing.java b/sp-server/src/main/java/net/minecraft/src/BlockFlowing.java new file mode 100644 index 0000000..5ce3aa0 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockFlowing.java @@ -0,0 +1,353 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockFlowing extends BlockFluid { + /** + * Number of horizontally adjacent liquid source blocks. Diagonal doesn't count. + * Only source blocks of the same liquid as the block using the field are + * counted. + */ + int numAdjacentSources = 0; + + /** + * Indicates whether the flow direction is optimal. Each array index corresponds + * to one of the four cardinal directions. + */ + boolean[] isOptimalFlowDirection = new boolean[4]; + + /** + * The estimated cost to flow in a given direction from the current point. Each + * array index corresponds to one of the four cardinal directions. + */ + int[] flowCost = new int[4]; + + protected BlockFlowing(int par1, Material par2Material) { + super(par1, par2Material); + } + + /** + * Updates the flow for the BlockFlowing object. + */ + private void updateFlow(World par1World, int par2, int par3, int par4) { + int var5 = par1World.getBlockMetadata(par2, par3, par4); + par1World.setBlock(par2, par3, par4, this.blockID + 1, var5, 2); + } + + public boolean getBlocksMovement(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + return this.blockMaterial != Material.lava; + } + + /** + * Ticks the block if it's been scheduled + */ + public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random) { + int var6 = this.getFlowDecay(par1World, par2, par3, par4); + byte var7 = 1; + + if (this.blockMaterial == Material.lava && !par1World.provider.isHellWorld) { + var7 = 2; + } + + boolean var8 = true; + int var10; + + if (var6 > 0) { + byte var9 = -100; + this.numAdjacentSources = 0; + int var12 = this.getSmallestFlowDecay(par1World, par2 - 1, par3, par4, var9); + var12 = this.getSmallestFlowDecay(par1World, par2 + 1, par3, par4, var12); + var12 = this.getSmallestFlowDecay(par1World, par2, par3, par4 - 1, var12); + var12 = this.getSmallestFlowDecay(par1World, par2, par3, par4 + 1, var12); + var10 = var12 + var7; + + if (var10 >= 8 || var12 < 0) { + var10 = -1; + } + + if (this.getFlowDecay(par1World, par2, par3 + 1, par4) >= 0) { + int var11 = this.getFlowDecay(par1World, par2, par3 + 1, par4); + + if (var11 >= 8) { + var10 = var11; + } else { + var10 = var11 + 8; + } + } + + if (this.numAdjacentSources >= 2 && this.blockMaterial == Material.water) { + if (par1World.getBlockMaterial(par2, par3 - 1, par4).isSolid()) { + var10 = 0; + } else if (par1World.getBlockMaterial(par2, par3 - 1, par4) == this.blockMaterial + && par1World.getBlockMetadata(par2, par3 - 1, par4) == 0) { + var10 = 0; + } + } + + if (this.blockMaterial == Material.lava && var6 < 8 && var10 < 8 && var10 > var6 + && par5Random.nextInt(4) != 0) { + var10 = var6; + var8 = false; + } + + if (var10 == var6) { + if (var8) { + this.updateFlow(par1World, par2, par3, par4); + } + } else { + var6 = var10; + + if (var10 < 0) { + par1World.setBlockToAir(par2, par3, par4); + } else { + par1World.setBlockMetadata(par2, par3, par4, var10, 2); + par1World.scheduleBlockUpdate(par2, par3, par4, this.blockID, this.tickRate(par1World)); + par1World.notifyBlocksOfNeighborChange(par2, par3, par4, this.blockID); + } + } + } else { + this.updateFlow(par1World, par2, par3, par4); + } + + if (this.liquidCanDisplaceBlock(par1World, par2, par3 - 1, par4)) { + if (this.blockMaterial == Material.lava + && par1World.getBlockMaterial(par2, par3 - 1, par4) == Material.water) { + par1World.setBlock(par2, par3 - 1, par4, Block.stone.blockID); + this.triggerLavaMixEffects(par1World, par2, par3 - 1, par4); + return; + } + + if (var6 >= 8) { + this.flowIntoBlock(par1World, par2, par3 - 1, par4, var6); + } else { + this.flowIntoBlock(par1World, par2, par3 - 1, par4, var6 + 8); + } + } else if (var6 >= 0 && (var6 == 0 || this.blockBlocksFlow(par1World, par2, par3 - 1, par4))) { + boolean[] var13 = this.getOptimalFlowDirections(par1World, par2, par3, par4); + var10 = var6 + var7; + + if (var6 >= 8) { + var10 = 1; + } + + if (var10 >= 8) { + return; + } + + if (var13[0]) { + this.flowIntoBlock(par1World, par2 - 1, par3, par4, var10); + } + + if (var13[1]) { + this.flowIntoBlock(par1World, par2 + 1, par3, par4, var10); + } + + if (var13[2]) { + this.flowIntoBlock(par1World, par2, par3, par4 - 1, var10); + } + + if (var13[3]) { + this.flowIntoBlock(par1World, par2, par3, par4 + 1, var10); + } + } + } + + /** + * flowIntoBlock(World world, int x, int y, int z, int newFlowDecay) - Flows + * into the block at the coordinates and changes the block type to the liquid. + */ + private void flowIntoBlock(World par1World, int par2, int par3, int par4, int par5) { + if (this.liquidCanDisplaceBlock(par1World, par2, par3, par4)) { + int var6 = par1World.getBlockId(par2, par3, par4); + + if (var6 > 0) { + if (this.blockMaterial == Material.lava) { + this.triggerLavaMixEffects(par1World, par2, par3, par4); + } else { + Block.blocksList[var6].dropBlockAsItem(par1World, par2, par3, par4, + par1World.getBlockMetadata(par2, par3, par4), 0); + } + } + + par1World.setBlock(par2, par3, par4, this.blockID, par5, 3); + } + } + + /** + * calculateFlowCost(World world, int x, int y, int z, int accumulatedCost, int + * previousDirectionOfFlow) - Used to determine the path of least resistance, + * this method returns the lowest possible flow cost for the direction of flow + * indicated. Each necessary horizontal flow adds to the flow cost. + */ + private int calculateFlowCost(World par1World, int par2, int par3, int par4, int par5, int par6) { + int var7 = 1000; + + for (int var8 = 0; var8 < 4; ++var8) { + if ((var8 != 0 || par6 != 1) && (var8 != 1 || par6 != 0) && (var8 != 2 || par6 != 3) + && (var8 != 3 || par6 != 2)) { + int var9 = par2; + int var11 = par4; + + if (var8 == 0) { + var9 = par2 - 1; + } + + if (var8 == 1) { + ++var9; + } + + if (var8 == 2) { + var11 = par4 - 1; + } + + if (var8 == 3) { + ++var11; + } + + if (!this.blockBlocksFlow(par1World, var9, par3, var11) + && (par1World.getBlockMaterial(var9, par3, var11) != this.blockMaterial + || par1World.getBlockMetadata(var9, par3, var11) != 0)) { + if (!this.blockBlocksFlow(par1World, var9, par3 - 1, var11)) { + return par5; + } + + if (par5 < 4) { + int var12 = this.calculateFlowCost(par1World, var9, par3, var11, par5 + 1, var8); + + if (var12 < var7) { + var7 = var12; + } + } + } + } + } + + return var7; + } + + /** + * Returns a boolean array indicating which flow directions are optimal based on + * each direction's calculated flow cost. Each array index corresponds to one of + * the four cardinal directions. A value of true indicates the direction is + * optimal. + */ + private boolean[] getOptimalFlowDirections(World par1World, int par2, int par3, int par4) { + int var5; + int var6; + + for (var5 = 0; var5 < 4; ++var5) { + this.flowCost[var5] = 1000; + var6 = par2; + int var8 = par4; + + if (var5 == 0) { + var6 = par2 - 1; + } + + if (var5 == 1) { + ++var6; + } + + if (var5 == 2) { + var8 = par4 - 1; + } + + if (var5 == 3) { + ++var8; + } + + if (!this.blockBlocksFlow(par1World, var6, par3, var8) + && (par1World.getBlockMaterial(var6, par3, var8) != this.blockMaterial + || par1World.getBlockMetadata(var6, par3, var8) != 0)) { + if (this.blockBlocksFlow(par1World, var6, par3 - 1, var8)) { + this.flowCost[var5] = this.calculateFlowCost(par1World, var6, par3, var8, 1, var5); + } else { + this.flowCost[var5] = 0; + } + } + } + + var5 = this.flowCost[0]; + + for (var6 = 1; var6 < 4; ++var6) { + if (this.flowCost[var6] < var5) { + var5 = this.flowCost[var6]; + } + } + + for (var6 = 0; var6 < 4; ++var6) { + this.isOptimalFlowDirection[var6] = this.flowCost[var6] == var5; + } + + return this.isOptimalFlowDirection; + } + + /** + * Returns true if block at coords blocks fluids + */ + private boolean blockBlocksFlow(World par1World, int par2, int par3, int par4) { + int var5 = par1World.getBlockId(par2, par3, par4); + + if (var5 != Block.doorWood.blockID && var5 != Block.doorIron.blockID && var5 != Block.signPost.blockID + && var5 != Block.ladder.blockID && var5 != Block.reed.blockID) { + if (var5 == 0) { + return false; + } else { + Material var6 = Block.blocksList[var5].blockMaterial; + return var6 == Material.portal ? true : var6.blocksMovement(); + } + } else { + return true; + } + } + + /** + * getSmallestFlowDecay(World world, intx, int y, int z, int + * currentSmallestFlowDecay) - Looks up the flow decay at the coordinates given + * and returns the smaller of this value or the provided + * currentSmallestFlowDecay. If one value is valid and the other isn't, the + * valid value will be returned. Valid values are >= 0. Flow decay is the amount + * that a liquid has dissipated. 0 indicates a source block. + */ + protected int getSmallestFlowDecay(World par1World, int par2, int par3, int par4, int par5) { + int var6 = this.getFlowDecay(par1World, par2, par3, par4); + + if (var6 < 0) { + return par5; + } else { + if (var6 == 0) { + ++this.numAdjacentSources; + } + + if (var6 >= 8) { + var6 = 0; + } + + return par5 >= 0 && var6 >= par5 ? par5 : var6; + } + } + + /** + * Returns true if the block at the coordinates can be displaced by the liquid. + */ + private boolean liquidCanDisplaceBlock(World par1World, int par2, int par3, int par4) { + Material var5 = par1World.getBlockMaterial(par2, par3, par4); + return var5 == this.blockMaterial ? false + : (var5 == Material.lava ? false : !this.blockBlocksFlow(par1World, par2, par3, par4)); + } + + /** + * Called whenever the block is added into the world. Args: world, x, y, z + */ + public void onBlockAdded(World par1World, int par2, int par3, int par4) { + super.onBlockAdded(par1World, par2, par3, par4); + + if (par1World.getBlockId(par2, par3, par4) == this.blockID) { + par1World.scheduleBlockUpdate(par2, par3, par4, this.blockID, this.tickRate(par1World)); + } + } + + public boolean func_82506_l() { + return false; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockFluid.java b/sp-server/src/main/java/net/minecraft/src/BlockFluid.java new file mode 100644 index 0000000..994f875 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockFluid.java @@ -0,0 +1,309 @@ +package net.minecraft.src; + +import java.util.Random; + +public abstract class BlockFluid extends Block { + protected BlockFluid(int par1, Material par2Material) { + super(par1, par2Material); + float var3 = 0.0F; + float var4 = 0.0F; + this.setBlockBounds(0.0F + var4, 0.0F + var3, 0.0F + var4, 1.0F + var4, 1.0F + var3, 1.0F + var4); + this.setTickRandomly(true); + } + + public boolean getBlocksMovement(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + return this.blockMaterial != Material.lava; + } + + /** + * Returns the percentage of the fluid block that is air, based on the given + * flow decay of the fluid. + */ + public static float getFluidHeightPercent(int par0) { + if (par0 >= 8) { + par0 = 0; + } + + return (float) (par0 + 1) / 9.0F; + } + + /** + * Returns the amount of fluid decay at the coordinates, or -1 if the block at + * the coordinates is not the same material as the fluid. + */ + protected int getFlowDecay(World par1World, int par2, int par3, int par4) { + return par1World.getBlockMaterial(par2, par3, par4) == this.blockMaterial + ? par1World.getBlockMetadata(par2, par3, par4) + : -1; + } + + /** + * Returns the flow decay but converts values indicating falling liquid (values + * >=8) to their effective source block value of zero. + */ + protected int getEffectiveFlowDecay(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + if (par1IBlockAccess.getBlockMaterial(par2, par3, par4) != this.blockMaterial) { + return -1; + } else { + int var5 = par1IBlockAccess.getBlockMetadata(par2, par3, par4); + + if (var5 >= 8) { + var5 = 0; + } + + return var5; + } + } + + /** + * If this block doesn't render as an ordinary block it will return False + * (examples: signs, buttons, stairs, etc) + */ + public boolean renderAsNormalBlock() { + return false; + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return false; + } + + /** + * Returns whether this block is collideable based on the arguments passed in + * Args: blockMetaData, unknownFlag + */ + public boolean canCollideCheck(int par1, boolean par2) { + return par2 && par1 == 0; + } + + /** + * Returns Returns true if the given side of this block type should be rendered + * (if it's solid or not), if the adjacent block is at the given coordinates. + * Args: blockAccess, x, y, z, side + */ + public boolean isBlockSolid(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5) { + Material var6 = par1IBlockAccess.getBlockMaterial(par2, par3, par4); + return var6 == this.blockMaterial ? false + : (par5 == 1 ? true + : (var6 == Material.ice ? false + : super.isBlockSolid(par1IBlockAccess, par2, par3, par4, par5))); + } + + /** + * Returns a bounding box from the pool of bounding boxes (this means this box + * can change after the pool has been cleared to be reused) + */ + public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int par4) { + return null; + } + + /** + * The type of render function that is called for this block + */ + public int getRenderType() { + return 4; + } + + /** + * Returns the ID of the items to drop on destruction. + */ + public int idDropped(int par1, Random par2Random, int par3) { + return 0; + } + + /** + * Returns the quantity of items to drop on block destruction. + */ + public int quantityDropped(Random par1Random) { + return 0; + } + + /** + * Returns a vector indicating the direction and intensity of fluid flow. + */ + private Vec3 getFlowVector(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + Vec3 var5 = par1IBlockAccess.getWorldVec3Pool().getVecFromPool(0.0D, 0.0D, 0.0D); + int var6 = this.getEffectiveFlowDecay(par1IBlockAccess, par2, par3, par4); + + for (int var7 = 0; var7 < 4; ++var7) { + int var8 = par2; + int var10 = par4; + + if (var7 == 0) { + var8 = par2 - 1; + } + + if (var7 == 1) { + var10 = par4 - 1; + } + + if (var7 == 2) { + ++var8; + } + + if (var7 == 3) { + ++var10; + } + + int var11 = this.getEffectiveFlowDecay(par1IBlockAccess, var8, par3, var10); + int var12; + + if (var11 < 0) { + if (!par1IBlockAccess.getBlockMaterial(var8, par3, var10).blocksMovement()) { + var11 = this.getEffectiveFlowDecay(par1IBlockAccess, var8, par3 - 1, var10); + + if (var11 >= 0) { + var12 = var11 - (var6 - 8); + var5 = var5.addVector((double) ((var8 - par2) * var12), (double) ((par3 - par3) * var12), + (double) ((var10 - par4) * var12)); + } + } + } else if (var11 >= 0) { + var12 = var11 - var6; + var5 = var5.addVector((double) ((var8 - par2) * var12), (double) ((par3 - par3) * var12), + (double) ((var10 - par4) * var12)); + } + } + + if (par1IBlockAccess.getBlockMetadata(par2, par3, par4) >= 8) { + boolean var13 = false; + + if (var13 || this.isBlockSolid(par1IBlockAccess, par2, par3, par4 - 1, 2)) { + var13 = true; + } + + if (var13 || this.isBlockSolid(par1IBlockAccess, par2, par3, par4 + 1, 3)) { + var13 = true; + } + + if (var13 || this.isBlockSolid(par1IBlockAccess, par2 - 1, par3, par4, 4)) { + var13 = true; + } + + if (var13 || this.isBlockSolid(par1IBlockAccess, par2 + 1, par3, par4, 5)) { + var13 = true; + } + + if (var13 || this.isBlockSolid(par1IBlockAccess, par2, par3 + 1, par4 - 1, 2)) { + var13 = true; + } + + if (var13 || this.isBlockSolid(par1IBlockAccess, par2, par3 + 1, par4 + 1, 3)) { + var13 = true; + } + + if (var13 || this.isBlockSolid(par1IBlockAccess, par2 - 1, par3 + 1, par4, 4)) { + var13 = true; + } + + if (var13 || this.isBlockSolid(par1IBlockAccess, par2 + 1, par3 + 1, par4, 5)) { + var13 = true; + } + + if (var13) { + var5 = var5.normalize().addVector(0.0D, -6.0D, 0.0D); + } + } + + var5 = var5.normalize(); + return var5; + } + + /** + * Can add to the passed in vector for a movement vector to be applied to the + * entity. Args: x, y, z, entity, vec3d + */ + public void velocityToAddToEntity(World par1World, int par2, int par3, int par4, Entity par5Entity, Vec3 par6Vec3) { + Vec3 var7 = this.getFlowVector(par1World, par2, par3, par4); + par6Vec3.xCoord += var7.xCoord; + par6Vec3.yCoord += var7.yCoord; + par6Vec3.zCoord += var7.zCoord; + } + + /** + * How many world ticks before ticking + */ + public int tickRate(World par1World) { + return this.blockMaterial == Material.water ? 5 + : (this.blockMaterial == Material.lava ? (par1World.provider.hasNoSky ? 10 : 30) : 0); + } + + /** + * Called whenever the block is added into the world. Args: world, x, y, z + */ + public void onBlockAdded(World par1World, int par2, int par3, int par4) { + this.checkForHarden(par1World, par2, par3, par4); + } + + /** + * Lets the block know when one of its neighbor changes. Doesn't know which + * neighbor changed (coordinates passed are their own) Args: x, y, z, neighbor + * blockID + */ + public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5) { + this.checkForHarden(par1World, par2, par3, par4); + } + + /** + * Forces lava to check to see if it is colliding with water, and then decide + * what it should harden to. + */ + private void checkForHarden(World par1World, int par2, int par3, int par4) { + if (par1World.getBlockId(par2, par3, par4) == this.blockID) { + if (this.blockMaterial == Material.lava) { + boolean var5 = false; + + if (var5 || par1World.getBlockMaterial(par2, par3, par4 - 1) == Material.water) { + var5 = true; + } + + if (var5 || par1World.getBlockMaterial(par2, par3, par4 + 1) == Material.water) { + var5 = true; + } + + if (var5 || par1World.getBlockMaterial(par2 - 1, par3, par4) == Material.water) { + var5 = true; + } + + if (var5 || par1World.getBlockMaterial(par2 + 1, par3, par4) == Material.water) { + var5 = true; + } + + if (var5 || par1World.getBlockMaterial(par2, par3 + 1, par4) == Material.water) { + var5 = true; + } + + if (var5) { + int var6 = par1World.getBlockMetadata(par2, par3, par4); + + if (var6 == 0) { + par1World.setBlock(par2, par3, par4, Block.obsidian.blockID); + } else if (var6 <= 4) { + par1World.setBlock(par2, par3, par4, Block.cobblestone.blockID); + } + + this.triggerLavaMixEffects(par1World, par2, par3, par4); + } + } + } + } + + /** + * Creates fizzing sound and smoke. Used when lava flows over block or mixes + * with water. + */ + protected void triggerLavaMixEffects(World par1World, int par2, int par3, int par4) { + par1World.playSoundEffect((double) ((float) par2 + 0.5F), (double) ((float) par3 + 0.5F), + (double) ((float) par4 + 0.5F), "random.fizz", 0.5F, + 2.6F + (par1World.rand.nextFloat() - par1World.rand.nextFloat()) * 0.8F); + + for (int var5 = 0; var5 < 8; ++var5) { + par1World.spawnParticle("largesmoke", (double) par2 + Math.random(), (double) par3 + 1.2D, + (double) par4 + Math.random(), 0.0D, 0.0D, 0.0D); + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockFurnace.java b/sp-server/src/main/java/net/minecraft/src/BlockFurnace.java new file mode 100644 index 0000000..f3ff2a6 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockFurnace.java @@ -0,0 +1,218 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockFurnace extends BlockContainer { + /** + * Is the random generator used by furnace to drop the inventory contents in + * random directions. + */ + private final Random furnaceRand = new Random(); + + /** True if this is an active furnace, false if idle */ + private final boolean isActive; + + /** + * This flag is used to prevent the furnace inventory to be dropped upon block + * removal, is used internally when the furnace block changes from idle to + * active and vice-versa. + */ + private static boolean keepFurnaceInventory = false; + + protected BlockFurnace(int par1, boolean par2) { + super(par1, Material.rock); + this.isActive = par2; + } + + /** + * Returns the ID of the items to drop on destruction. + */ + public int idDropped(int par1, Random par2Random, int par3) { + return Block.furnaceIdle.blockID; + } + + /** + * Called whenever the block is added into the world. Args: world, x, y, z + */ + public void onBlockAdded(World par1World, int par2, int par3, int par4) { + super.onBlockAdded(par1World, par2, par3, par4); + this.setDefaultDirection(par1World, par2, par3, par4); + } + + /** + * set a blocks direction + */ + private void setDefaultDirection(World par1World, int par2, int par3, int par4) { + if (!par1World.isRemote) { + int var5 = par1World.getBlockId(par2, par3, par4 - 1); + int var6 = par1World.getBlockId(par2, par3, par4 + 1); + int var7 = par1World.getBlockId(par2 - 1, par3, par4); + int var8 = par1World.getBlockId(par2 + 1, par3, par4); + byte var9 = 3; + + if (Block.opaqueCubeLookup[var5] && !Block.opaqueCubeLookup[var6]) { + var9 = 3; + } + + if (Block.opaqueCubeLookup[var6] && !Block.opaqueCubeLookup[var5]) { + var9 = 2; + } + + if (Block.opaqueCubeLookup[var7] && !Block.opaqueCubeLookup[var8]) { + var9 = 5; + } + + if (Block.opaqueCubeLookup[var8] && !Block.opaqueCubeLookup[var7]) { + var9 = 4; + } + + par1World.setBlockMetadata(par2, par3, par4, var9, 2); + } + } + + /** + * Called upon block activation (right click on the block.) + */ + public boolean onBlockActivated(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer, + int par6, float par7, float par8, float par9) { + if (par1World.isRemote) { + return true; + } else { + TileEntityFurnace var10 = (TileEntityFurnace) par1World.getBlockTileEntity(par2, par3, par4); + + if (var10 != null) { + par5EntityPlayer.displayGUIFurnace(var10); + } + + return true; + } + } + + /** + * Update which block ID the furnace is using depending on whether or not it is + * burning + */ + public static void updateFurnaceBlockState(boolean par0, World par1World, int par2, int par3, int par4) { + int var5 = par1World.getBlockMetadata(par2, par3, par4); + TileEntity var6 = par1World.getBlockTileEntity(par2, par3, par4); + keepFurnaceInventory = true; + + if (par0) { + par1World.setBlock(par2, par3, par4, Block.furnaceBurning.blockID); + } else { + par1World.setBlock(par2, par3, par4, Block.furnaceIdle.blockID); + } + + keepFurnaceInventory = false; + par1World.setBlockMetadata(par2, par3, par4, var5, 2); + + if (var6 != null) { + var6.validate(); + par1World.setBlockTileEntity(par2, par3, par4, var6); + } + } + + /** + * Returns a new instance of a block's tile entity class. Called on placing the + * block. + */ + public TileEntity createNewTileEntity(World par1World) { + return new TileEntityFurnace(); + } + + /** + * Called when the block is placed in the world. + */ + public void onBlockPlacedBy(World par1World, int par2, int par3, int par4, EntityLiving par5EntityLiving, + ItemStack par6ItemStack) { + int var7 = MathHelper.floor_double((double) (par5EntityLiving.rotationYaw * 4.0F / 360.0F) + 0.5D) & 3; + + if (var7 == 0) { + par1World.setBlockMetadata(par2, par3, par4, 2, 2); + } + + if (var7 == 1) { + par1World.setBlockMetadata(par2, par3, par4, 5, 2); + } + + if (var7 == 2) { + par1World.setBlockMetadata(par2, par3, par4, 3, 2); + } + + if (var7 == 3) { + par1World.setBlockMetadata(par2, par3, par4, 4, 2); + } + + if (par6ItemStack.hasDisplayName()) { + ((TileEntityFurnace) par1World.getBlockTileEntity(par2, par3, par4)) + .func_94129_a(par6ItemStack.getDisplayName()); + } + } + + /** + * ejects contained items into the world, and notifies neighbours of an update, + * as appropriate + */ + public void breakBlock(World par1World, int par2, int par3, int par4, int par5, int par6) { + if (!keepFurnaceInventory) { + TileEntityFurnace var7 = (TileEntityFurnace) par1World.getBlockTileEntity(par2, par3, par4); + + if (var7 != null) { + for (int var8 = 0; var8 < var7.getSizeInventory(); ++var8) { + ItemStack var9 = var7.getStackInSlot(var8); + + if (var9 != null) { + float var10 = this.furnaceRand.nextFloat() * 0.8F + 0.1F; + float var11 = this.furnaceRand.nextFloat() * 0.8F + 0.1F; + float var12 = this.furnaceRand.nextFloat() * 0.8F + 0.1F; + + while (var9.stackSize > 0) { + int var13 = this.furnaceRand.nextInt(21) + 10; + + if (var13 > var9.stackSize) { + var13 = var9.stackSize; + } + + var9.stackSize -= var13; + EntityItem var14 = new EntityItem(par1World, (double) ((float) par2 + var10), + (double) ((float) par3 + var11), (double) ((float) par4 + var12), + new ItemStack(var9.itemID, var13, var9.getItemDamage())); + + if (var9.hasTagCompound()) { + var14.getEntityItem().setTagCompound((NBTTagCompound) var9.getTagCompound().copy()); + } + + float var15 = 0.05F; + var14.motionX = (double) ((float) this.furnaceRand.nextGaussian() * var15); + var14.motionY = (double) ((float) this.furnaceRand.nextGaussian() * var15 + 0.2F); + var14.motionZ = (double) ((float) this.furnaceRand.nextGaussian() * var15); + par1World.spawnEntityInWorld(var14); + } + } + } + + par1World.func_96440_m(par2, par3, par4, par5); + } + } + + super.breakBlock(par1World, par2, par3, par4, par5, par6); + } + + /** + * If this returns true, then comparators facing away from this block will use + * the value from getComparatorInputOverride instead of the actual redstone + * signal strength. + */ + public boolean hasComparatorInputOverride() { + return true; + } + + /** + * If hasComparatorInputOverride returns true, the return value from this is + * used instead of the redstone signal strength when this block inputs to a + * comparator. + */ + public int getComparatorInputOverride(World par1World, int par2, int par3, int par4, int par5) { + return Container.calcRedstoneFromInventory((IInventory) par1World.getBlockTileEntity(par2, par3, par4)); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockGlass.java b/sp-server/src/main/java/net/minecraft/src/BlockGlass.java new file mode 100644 index 0000000..47f5ad5 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockGlass.java @@ -0,0 +1,42 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockGlass extends BlockBreakable { + public BlockGlass(int par1, Material par2Material, boolean par3) { + super(par1, "glass", par2Material, par3); + this.setCreativeTab(CreativeTabs.tabBlock); + } + + /** + * Returns the quantity of items to drop on block destruction. + */ + public int quantityDropped(Random par1Random) { + return 0; + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return false; + } + + /** + * If this block doesn't render as an ordinary block it will return False + * (examples: signs, buttons, stairs, etc) + */ + public boolean renderAsNormalBlock() { + return false; + } + + /** + * Return true if a player with Silk Touch can harvest this block directly, and + * not its normal drops. + */ + protected boolean canSilkHarvest() { + return true; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockGlowStone.java b/sp-server/src/main/java/net/minecraft/src/BlockGlowStone.java new file mode 100644 index 0000000..4fd0569 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockGlowStone.java @@ -0,0 +1,32 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockGlowStone extends Block { + public BlockGlowStone(int par1, Material par2Material) { + super(par1, par2Material); + this.setCreativeTab(CreativeTabs.tabBlock); + } + + /** + * Returns the usual quantity dropped by the block plus a bonus of 1 to 'i' + * (inclusive). + */ + public int quantityDroppedWithBonus(int par1, Random par2Random) { + return MathHelper.clamp_int(this.quantityDropped(par2Random) + par2Random.nextInt(par1 + 1), 1, 4); + } + + /** + * Returns the quantity of items to drop on block destruction. + */ + public int quantityDropped(Random par1Random) { + return 2 + par1Random.nextInt(3); + } + + /** + * Returns the ID of the items to drop on destruction. + */ + public int idDropped(int par1, Random par2Random, int par3) { + return Item.lightStoneDust.itemID; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockGrass.java b/sp-server/src/main/java/net/minecraft/src/BlockGrass.java new file mode 100644 index 0000000..aa46a18 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockGrass.java @@ -0,0 +1,43 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockGrass extends Block { + protected BlockGrass(int par1) { + super(par1, Material.grass); + this.setTickRandomly(true); + this.setCreativeTab(CreativeTabs.tabBlock); + } + + /** + * Ticks the block if it's been scheduled + */ + public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random) { + if (!par1World.isRemote) { + if (par1World.getBlockLightValue(par2, par3 + 1, par4) < 4 + && Block.lightOpacity[par1World.getBlockId(par2, par3 + 1, par4)] > 2) { + par1World.setBlock(par2, par3, par4, Block.dirt.blockID); + } else if (par1World.getBlockLightValue(par2, par3 + 1, par4) >= 9) { + for (int var6 = 0; var6 < 4; ++var6) { + int var7 = par2 + par5Random.nextInt(3) - 1; + int var8 = par3 + par5Random.nextInt(5) - 3; + int var9 = par4 + par5Random.nextInt(3) - 1; + int var10 = par1World.getBlockId(var7, var8 + 1, var9); + + if (par1World.getBlockId(var7, var8, var9) == Block.dirt.blockID + && par1World.getBlockLightValue(var7, var8 + 1, var9) >= 4 + && Block.lightOpacity[var10] <= 2) { + par1World.setBlock(var7, var8, var9, Block.grass.blockID); + } + } + } + } + } + + /** + * Returns the ID of the items to drop on destruction. + */ + public int idDropped(int par1, Random par2Random, int par3) { + return Block.dirt.idDropped(0, par2Random, par3); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockGravel.java b/sp-server/src/main/java/net/minecraft/src/BlockGravel.java new file mode 100644 index 0000000..7011d34 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockGravel.java @@ -0,0 +1,20 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockGravel extends BlockSand { + public BlockGravel(int par1) { + super(par1); + } + + /** + * Returns the ID of the items to drop on destruction. + */ + public int idDropped(int par1, Random par2Random, int par3) { + if (par3 > 3) { + par3 = 3; + } + + return par2Random.nextInt(10 - par3 * 3) == 0 ? Item.flint.itemID : this.blockID; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockHalfSlab.java b/sp-server/src/main/java/net/minecraft/src/BlockHalfSlab.java new file mode 100644 index 0000000..af8eb93 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockHalfSlab.java @@ -0,0 +1,112 @@ +package net.minecraft.src; + +import java.util.List; +import java.util.Random; + +public abstract class BlockHalfSlab extends Block { + protected final boolean isDoubleSlab; + + public BlockHalfSlab(int par1, boolean par2, Material par3Material) { + super(par1, par3Material); + this.isDoubleSlab = par2; + + if (par2) { + opaqueCubeLookup[par1] = true; + } else { + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.5F, 1.0F); + } + + this.setLightOpacity(255); + } + + /** + * Updates the blocks bounds based on its current state. Args: world, x, y, z + */ + public void setBlockBoundsBasedOnState(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + if (this.isDoubleSlab) { + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + } else { + boolean var5 = (par1IBlockAccess.getBlockMetadata(par2, par3, par4) & 8) != 0; + + if (var5) { + this.setBlockBounds(0.0F, 0.5F, 0.0F, 1.0F, 1.0F, 1.0F); + } else { + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.5F, 1.0F); + } + } + } + + /** + * Sets the block's bounds for rendering it as an item + */ + public void setBlockBoundsForItemRender() { + if (this.isDoubleSlab) { + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + } else { + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.5F, 1.0F); + } + } + + /** + * Adds all intersecting collision boxes to a list. (Be sure to only add boxes + * to the list if they intersect the mask.) Parameters: World, X, Y, Z, mask, + * list, colliding entity + */ + public void addCollisionBoxesToList(World par1World, int par2, int par3, int par4, AxisAlignedBB par5AxisAlignedBB, + List par6List, Entity par7Entity) { + this.setBlockBoundsBasedOnState(par1World, par2, par3, par4); + super.addCollisionBoxesToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity); + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return this.isDoubleSlab; + } + + /** + * Called when a block is placed using its ItemBlock. Args: World, X, Y, Z, + * side, hitX, hitY, hitZ, block metadata + */ + public int onBlockPlaced(World par1World, int par2, int par3, int par4, int par5, float par6, float par7, + float par8, int par9) { + return this.isDoubleSlab ? par9 : (par5 != 0 && (par5 == 1 || (double) par7 <= 0.5D) ? par9 : par9 | 8); + } + + /** + * Returns the quantity of items to drop on block destruction. + */ + public int quantityDropped(Random par1Random) { + return this.isDoubleSlab ? 2 : 1; + } + + /** + * Determines the damage on the item the block drops. Used in cloth and wood. + */ + public int damageDropped(int par1) { + return par1 & 7; + } + + /** + * If this block doesn't render as an ordinary block it will return False + * (examples: signs, buttons, stairs, etc) + */ + public boolean renderAsNormalBlock() { + return this.isDoubleSlab; + } + + /** + * Returns the slab block name with step type. + */ + public abstract String getFullSlabName(int var1); + + /** + * Get the block's damage value (for use with pick block). + */ + public int getDamageValue(World par1World, int par2, int par3, int par4) { + return super.getDamageValue(par1World, par2, par3, par4) & 7; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockHopper.java b/sp-server/src/main/java/net/minecraft/src/BlockHopper.java new file mode 100644 index 0000000..43ff62e --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockHopper.java @@ -0,0 +1,228 @@ +package net.minecraft.src; + +import java.util.List; +import java.util.Random; + +public class BlockHopper extends BlockContainer { + private final Random field_94457_a = new Random(); + + public BlockHopper(int par1) { + super(par1, Material.iron); + this.setCreativeTab(CreativeTabs.tabRedstone); + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + } + + /** + * Updates the blocks bounds based on its current state. Args: world, x, y, z + */ + public void setBlockBoundsBasedOnState(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + } + + /** + * Adds all intersecting collision boxes to a list. (Be sure to only add boxes + * to the list if they intersect the mask.) Parameters: World, X, Y, Z, mask, + * list, colliding entity + */ + public void addCollisionBoxesToList(World par1World, int par2, int par3, int par4, AxisAlignedBB par5AxisAlignedBB, + List par6List, Entity par7Entity) { + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.625F, 1.0F); + super.addCollisionBoxesToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity); + float var8 = 0.125F; + this.setBlockBounds(0.0F, 0.0F, 0.0F, var8, 1.0F, 1.0F); + super.addCollisionBoxesToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity); + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, var8); + super.addCollisionBoxesToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity); + this.setBlockBounds(1.0F - var8, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + super.addCollisionBoxesToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity); + this.setBlockBounds(0.0F, 0.0F, 1.0F - var8, 1.0F, 1.0F, 1.0F); + super.addCollisionBoxesToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity); + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + } + + /** + * Called when a block is placed using its ItemBlock. Args: World, X, Y, Z, + * side, hitX, hitY, hitZ, block metadata + */ + public int onBlockPlaced(World par1World, int par2, int par3, int par4, int par5, float par6, float par7, + float par8, int par9) { + int var10 = Facing.oppositeSide[par5]; + + if (var10 == 1) { + var10 = 0; + } + + return var10; + } + + /** + * Returns a new instance of a block's tile entity class. Called on placing the + * block. + */ + public TileEntity createNewTileEntity(World par1World) { + return new TileEntityHopper(); + } + + /** + * Called when the block is placed in the world. + */ + public void onBlockPlacedBy(World par1World, int par2, int par3, int par4, EntityLiving par5EntityLiving, + ItemStack par6ItemStack) { + super.onBlockPlacedBy(par1World, par2, par3, par4, par5EntityLiving, par6ItemStack); + + if (par6ItemStack.hasDisplayName()) { + TileEntityHopper var7 = getHopperTile(par1World, par2, par3, par4); + var7.setInventoryName(par6ItemStack.getDisplayName()); + } + } + + /** + * Called whenever the block is added into the world. Args: world, x, y, z + */ + public void onBlockAdded(World par1World, int par2, int par3, int par4) { + super.onBlockAdded(par1World, par2, par3, par4); + this.updateMetadata(par1World, par2, par3, par4); + } + + /** + * Called upon block activation (right click on the block.) + */ + public boolean onBlockActivated(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer, + int par6, float par7, float par8, float par9) { + if (par1World.isRemote) { + return true; + } else { + TileEntityHopper var10 = getHopperTile(par1World, par2, par3, par4); + + if (var10 != null) { + par5EntityPlayer.displayGUIHopper(var10); + } + + return true; + } + } + + /** + * Lets the block know when one of its neighbor changes. Doesn't know which + * neighbor changed (coordinates passed are their own) Args: x, y, z, neighbor + * blockID + */ + public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5) { + this.updateMetadata(par1World, par2, par3, par4); + } + + /** + * Updates the Metadata to include if the Hopper gets powered by Redstone or not + */ + private void updateMetadata(World par1World, int par2, int par3, int par4) { + int var5 = par1World.getBlockMetadata(par2, par3, par4); + int var6 = getDirectionFromMetadata(var5); + boolean var7 = !par1World.isBlockIndirectlyGettingPowered(par2, par3, par4); + boolean var8 = getIsBlockNotPoweredFromMetadata(var5); + + if (var7 != var8) { + par1World.setBlockMetadata(par2, par3, par4, var6 | (var7 ? 0 : 8), 4); + } + } + + /** + * ejects contained items into the world, and notifies neighbours of an update, + * as appropriate + */ + public void breakBlock(World par1World, int par2, int par3, int par4, int par5, int par6) { + TileEntityHopper var7 = (TileEntityHopper) par1World.getBlockTileEntity(par2, par3, par4); + + if (var7 != null) { + for (int var8 = 0; var8 < var7.getSizeInventory(); ++var8) { + ItemStack var9 = var7.getStackInSlot(var8); + + if (var9 != null) { + float var10 = this.field_94457_a.nextFloat() * 0.8F + 0.1F; + float var11 = this.field_94457_a.nextFloat() * 0.8F + 0.1F; + float var12 = this.field_94457_a.nextFloat() * 0.8F + 0.1F; + + while (var9.stackSize > 0) { + int var13 = this.field_94457_a.nextInt(21) + 10; + + if (var13 > var9.stackSize) { + var13 = var9.stackSize; + } + + var9.stackSize -= var13; + EntityItem var14 = new EntityItem(par1World, (double) ((float) par2 + var10), + (double) ((float) par3 + var11), (double) ((float) par4 + var12), + new ItemStack(var9.itemID, var13, var9.getItemDamage())); + + if (var9.hasTagCompound()) { + var14.getEntityItem().setTagCompound((NBTTagCompound) var9.getTagCompound().copy()); + } + + float var15 = 0.05F; + var14.motionX = (double) ((float) this.field_94457_a.nextGaussian() * var15); + var14.motionY = (double) ((float) this.field_94457_a.nextGaussian() * var15 + 0.2F); + var14.motionZ = (double) ((float) this.field_94457_a.nextGaussian() * var15); + par1World.spawnEntityInWorld(var14); + } + } + } + + par1World.func_96440_m(par2, par3, par4, par5); + } + + super.breakBlock(par1World, par2, par3, par4, par5, par6); + } + + /** + * The type of render function that is called for this block + */ + public int getRenderType() { + return 38; + } + + /** + * If this block doesn't render as an ordinary block it will return False + * (examples: signs, buttons, stairs, etc) + */ + public boolean renderAsNormalBlock() { + return false; + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return false; + } + + public static int getDirectionFromMetadata(int par0) { + return par0 & 7; + } + + public static boolean getIsBlockNotPoweredFromMetadata(int par0) { + return (par0 & 8) != 8; + } + + /** + * If this returns true, then comparators facing away from this block will use + * the value from getComparatorInputOverride instead of the actual redstone + * signal strength. + */ + public boolean hasComparatorInputOverride() { + return true; + } + + /** + * If hasComparatorInputOverride returns true, the return value from this is + * used instead of the redstone signal strength when this block inputs to a + * comparator. + */ + public int getComparatorInputOverride(World par1World, int par2, int par3, int par4, int par5) { + return Container.calcRedstoneFromInventory(getHopperTile(par1World, par2, par3, par4)); + } + + public static TileEntityHopper getHopperTile(IBlockAccess par0IBlockAccess, int par1, int par2, int par3) { + return (TileEntityHopper) par0IBlockAccess.getBlockTileEntity(par1, par2, par3); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockIce.java b/sp-server/src/main/java/net/minecraft/src/BlockIce.java new file mode 100644 index 0000000..6b931b2 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockIce.java @@ -0,0 +1,73 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockIce extends BlockBreakable { + public BlockIce(int par1) { + super(par1, "ice", Material.ice, false); + this.slipperiness = 0.98F; + this.setTickRandomly(true); + this.setCreativeTab(CreativeTabs.tabBlock); + } + + /** + * Called when the player destroys a block with an item that can harvest it. (i, + * j, k) are the coordinates of the block and l is the block's subtype/damage. + */ + public void harvestBlock(World par1World, EntityPlayer par2EntityPlayer, int par3, int par4, int par5, int par6) { + par2EntityPlayer.addStat(StatList.mineBlockStatArray[this.blockID], 1); + par2EntityPlayer.addExhaustion(0.025F); + + if (this.canSilkHarvest() && EnchantmentHelper.getSilkTouchModifier(par2EntityPlayer)) { + ItemStack var9 = this.createStackedBlock(par6); + + if (var9 != null) { + this.dropBlockAsItem_do(par1World, par3, par4, par5, var9); + } + } else { + if (par1World.provider.isHellWorld) { + par1World.setBlockToAir(par3, par4, par5); + return; + } + + int var7 = EnchantmentHelper.getFortuneModifier(par2EntityPlayer); + this.dropBlockAsItem(par1World, par3, par4, par5, par6, var7); + Material var8 = par1World.getBlockMaterial(par3, par4 - 1, par5); + + if (var8.blocksMovement() || var8.isLiquid()) { + par1World.setBlock(par3, par4, par5, Block.waterMoving.blockID); + } + } + } + + /** + * Returns the quantity of items to drop on block destruction. + */ + public int quantityDropped(Random par1Random) { + return 0; + } + + /** + * Ticks the block if it's been scheduled + */ + public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random) { + if (par1World.getSavedLightValue(EnumSkyBlock.Block, par2, par3, par4) > 11 + - Block.lightOpacity[this.blockID]) { + if (par1World.provider.isHellWorld) { + par1World.setBlockToAir(par2, par3, par4); + return; + } + + this.dropBlockAsItem(par1World, par2, par3, par4, par1World.getBlockMetadata(par2, par3, par4), 0); + par1World.setBlock(par2, par3, par4, Block.waterStill.blockID); + } + } + + /** + * Returns the mobility information of the block, 0 = free, 1 = can't push but + * can move over, 2 = total immobility and stop pistons + */ + public int getMobilityFlag() { + return 0; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockJukeBox.java b/sp-server/src/main/java/net/minecraft/src/BlockJukeBox.java new file mode 100644 index 0000000..48e3427 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockJukeBox.java @@ -0,0 +1,110 @@ +package net.minecraft.src; + +public class BlockJukeBox extends BlockContainer { + protected BlockJukeBox(int par1) { + super(par1, Material.wood); + this.setCreativeTab(CreativeTabs.tabDecorations); + } + + /** + * Called upon block activation (right click on the block.) + */ + public boolean onBlockActivated(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer, + int par6, float par7, float par8, float par9) { + if (par1World.getBlockMetadata(par2, par3, par4) == 0) { + return false; + } else { + this.ejectRecord(par1World, par2, par3, par4); + return true; + } + } + + /** + * Insert the specified music disc in the jukebox at the given coordinates + */ + public void insertRecord(World par1World, int par2, int par3, int par4, ItemStack par5ItemStack) { + if (!par1World.isRemote) { + TileEntityRecordPlayer var6 = (TileEntityRecordPlayer) par1World.getBlockTileEntity(par2, par3, par4); + + if (var6 != null) { + var6.func_96098_a(par5ItemStack.copy()); + par1World.setBlockMetadata(par2, par3, par4, 1, 2); + } + } + } + + /** + * Ejects the current record inside of the jukebox. + */ + public void ejectRecord(World par1World, int par2, int par3, int par4) { + if (!par1World.isRemote) { + TileEntityRecordPlayer var5 = (TileEntityRecordPlayer) par1World.getBlockTileEntity(par2, par3, par4); + + if (var5 != null) { + ItemStack var6 = var5.func_96097_a(); + + if (var6 != null) { + par1World.playAuxSFX(1005, par2, par3, par4, 0); + par1World.playRecord((String) null, par2, par3, par4); + var5.func_96098_a((ItemStack) null); + par1World.setBlockMetadata(par2, par3, par4, 0, 2); + float var7 = 0.7F; + double var8 = (double) (par1World.rand.nextFloat() * var7) + (double) (1.0F - var7) * 0.5D; + double var10 = (double) (par1World.rand.nextFloat() * var7) + (double) (1.0F - var7) * 0.2D + 0.6D; + double var12 = (double) (par1World.rand.nextFloat() * var7) + (double) (1.0F - var7) * 0.5D; + ItemStack var14 = var6.copy(); + EntityItem var15 = new EntityItem(par1World, (double) par2 + var8, (double) par3 + var10, + (double) par4 + var12, var14); + var15.delayBeforeCanPickup = 10; + par1World.spawnEntityInWorld(var15); + } + } + } + } + + /** + * ejects contained items into the world, and notifies neighbours of an update, + * as appropriate + */ + public void breakBlock(World par1World, int par2, int par3, int par4, int par5, int par6) { + this.ejectRecord(par1World, par2, par3, par4); + super.breakBlock(par1World, par2, par3, par4, par5, par6); + } + + /** + * Drops the block items with a specified chance of dropping the specified items + */ + public void dropBlockAsItemWithChance(World par1World, int par2, int par3, int par4, int par5, float par6, + int par7) { + if (!par1World.isRemote) { + super.dropBlockAsItemWithChance(par1World, par2, par3, par4, par5, par6, 0); + } + } + + /** + * Returns a new instance of a block's tile entity class. Called on placing the + * block. + */ + public TileEntity createNewTileEntity(World par1World) { + return new TileEntityRecordPlayer(); + } + + /** + * If this returns true, then comparators facing away from this block will use + * the value from getComparatorInputOverride instead of the actual redstone + * signal strength. + */ + public boolean hasComparatorInputOverride() { + return true; + } + + /** + * If hasComparatorInputOverride returns true, the return value from this is + * used instead of the redstone signal strength when this block inputs to a + * comparator. + */ + public int getComparatorInputOverride(World par1World, int par2, int par3, int par4, int par5) { + ItemStack var6 = ((TileEntityRecordPlayer) par1World.getBlockTileEntity(par2, par3, par4)).func_96097_a(); + return var6 == null ? 0 : var6.itemID + 1 - Item.record13.itemID; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockLadder.java b/sp-server/src/main/java/net/minecraft/src/BlockLadder.java new file mode 100644 index 0000000..b116c71 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockLadder.java @@ -0,0 +1,151 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockLadder extends Block { + protected BlockLadder(int par1) { + super(par1, Material.circuits); + this.setCreativeTab(CreativeTabs.tabDecorations); + } + + /** + * Returns a bounding box from the pool of bounding boxes (this means this box + * can change after the pool has been cleared to be reused) + */ + public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int par4) { + this.setBlockBoundsBasedOnState(par1World, par2, par3, par4); + return super.getCollisionBoundingBoxFromPool(par1World, par2, par3, par4); + } + + /** + * Updates the blocks bounds based on its current state. Args: world, x, y, z + */ + public void setBlockBoundsBasedOnState(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + this.updateLadderBounds(par1IBlockAccess.getBlockMetadata(par2, par3, par4)); + } + + /** + * Update the ladder block bounds based on the given metadata value. + */ + public void updateLadderBounds(int par1) { + float var3 = 0.125F; + + if (par1 == 2) { + this.setBlockBounds(0.0F, 0.0F, 1.0F - var3, 1.0F, 1.0F, 1.0F); + } + + if (par1 == 3) { + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, var3); + } + + if (par1 == 4) { + this.setBlockBounds(1.0F - var3, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + } + + if (par1 == 5) { + this.setBlockBounds(0.0F, 0.0F, 0.0F, var3, 1.0F, 1.0F); + } + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return false; + } + + /** + * If this block doesn't render as an ordinary block it will return False + * (examples: signs, buttons, stairs, etc) + */ + public boolean renderAsNormalBlock() { + return false; + } + + /** + * The type of render function that is called for this block + */ + public int getRenderType() { + return 8; + } + + /** + * Checks to see if its valid to put this block at the specified coordinates. + * Args: world, x, y, z + */ + public boolean canPlaceBlockAt(World par1World, int par2, int par3, int par4) { + return par1World.isBlockNormalCube(par2 - 1, par3, par4) ? true + : (par1World.isBlockNormalCube(par2 + 1, par3, par4) ? true + : (par1World.isBlockNormalCube(par2, par3, par4 - 1) ? true + : par1World.isBlockNormalCube(par2, par3, par4 + 1))); + } + + /** + * Called when a block is placed using its ItemBlock. Args: World, X, Y, Z, + * side, hitX, hitY, hitZ, block metadata + */ + public int onBlockPlaced(World par1World, int par2, int par3, int par4, int par5, float par6, float par7, + float par8, int par9) { + int var10 = par9; + + if ((par9 == 0 || par5 == 2) && par1World.isBlockNormalCube(par2, par3, par4 + 1)) { + var10 = 2; + } + + if ((var10 == 0 || par5 == 3) && par1World.isBlockNormalCube(par2, par3, par4 - 1)) { + var10 = 3; + } + + if ((var10 == 0 || par5 == 4) && par1World.isBlockNormalCube(par2 + 1, par3, par4)) { + var10 = 4; + } + + if ((var10 == 0 || par5 == 5) && par1World.isBlockNormalCube(par2 - 1, par3, par4)) { + var10 = 5; + } + + return var10; + } + + /** + * Lets the block know when one of its neighbor changes. Doesn't know which + * neighbor changed (coordinates passed are their own) Args: x, y, z, neighbor + * blockID + */ + public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5) { + int var6 = par1World.getBlockMetadata(par2, par3, par4); + boolean var7 = false; + + if (var6 == 2 && par1World.isBlockNormalCube(par2, par3, par4 + 1)) { + var7 = true; + } + + if (var6 == 3 && par1World.isBlockNormalCube(par2, par3, par4 - 1)) { + var7 = true; + } + + if (var6 == 4 && par1World.isBlockNormalCube(par2 + 1, par3, par4)) { + var7 = true; + } + + if (var6 == 5 && par1World.isBlockNormalCube(par2 - 1, par3, par4)) { + var7 = true; + } + + if (!var7) { + this.dropBlockAsItem(par1World, par2, par3, par4, var6, 0); + par1World.setBlockToAir(par2, par3, par4); + } + + super.onNeighborBlockChange(par1World, par2, par3, par4, par5); + } + + /** + * Returns the quantity of items to drop on block destruction. + */ + public int quantityDropped(Random par1Random) { + return 1; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockLeaves.java b/sp-server/src/main/java/net/minecraft/src/BlockLeaves.java new file mode 100644 index 0000000..6d24eea --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockLeaves.java @@ -0,0 +1,245 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockLeaves extends BlockLeavesBase { + public static final String[] LEAF_TYPES = new String[] { "oak", "spruce", "birch", "jungle" }; + public static final String[][] field_94396_b = new String[][] { + { "leaves", "leaves_spruce", "leaves", "leaves_jungle" }, + { "leaves_opaque", "leaves_spruce_opaque", "leaves_opaque", "leaves_jungle_opaque" } }; + private Icon[][] iconArray = new Icon[2][]; + int[] adjacentTreeBlocks; + + protected BlockLeaves(int par1) { + super(par1, Material.leaves, false); + this.setTickRandomly(true); + this.setCreativeTab(CreativeTabs.tabDecorations); + } + + /** + * ejects contained items into the world, and notifies neighbours of an update, + * as appropriate + */ + public void breakBlock(World par1World, int par2, int par3, int par4, int par5, int par6) { + byte var7 = 1; + int var8 = var7 + 1; + + if (par1World.checkChunksExist(par2 - var8, par3 - var8, par4 - var8, par2 + var8, par3 + var8, par4 + var8)) { + for (int var9 = -var7; var9 <= var7; ++var9) { + for (int var10 = -var7; var10 <= var7; ++var10) { + for (int var11 = -var7; var11 <= var7; ++var11) { + int var12 = par1World.getBlockId(par2 + var9, par3 + var10, par4 + var11); + + if (var12 == Block.leaves.blockID) { + int var13 = par1World.getBlockMetadata(par2 + var9, par3 + var10, par4 + var11); + par1World.setBlockMetadata(par2 + var9, par3 + var10, par4 + var11, var13 | 8, 4); + } + } + } + } + } + } + + /** + * Ticks the block if it's been scheduled + */ + public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random) { + if (!par1World.isRemote) { + int var6 = par1World.getBlockMetadata(par2, par3, par4); + + if ((var6 & 8) != 0 && (var6 & 4) == 0) { + byte var7 = 4; + int var8 = var7 + 1; + byte var9 = 32; + int var10 = var9 * var9; + int var11 = var9 / 2; + + if (this.adjacentTreeBlocks == null) { + this.adjacentTreeBlocks = new int[var9 * var9 * var9]; + } + + int var12; + + if (par1World.checkChunksExist(par2 - var8, par3 - var8, par4 - var8, par2 + var8, par3 + var8, + par4 + var8)) { + int var13; + int var14; + int var15; + + for (var12 = -var7; var12 <= var7; ++var12) { + for (var13 = -var7; var13 <= var7; ++var13) { + for (var14 = -var7; var14 <= var7; ++var14) { + var15 = par1World.getBlockId(par2 + var12, par3 + var13, par4 + var14); + + if (var15 == Block.wood.blockID) { + this.adjacentTreeBlocks[(var12 + var11) * var10 + (var13 + var11) * var9 + var14 + + var11] = 0; + } else if (var15 == Block.leaves.blockID) { + this.adjacentTreeBlocks[(var12 + var11) * var10 + (var13 + var11) * var9 + var14 + + var11] = -2; + } else { + this.adjacentTreeBlocks[(var12 + var11) * var10 + (var13 + var11) * var9 + var14 + + var11] = -1; + } + } + } + } + + for (var12 = 1; var12 <= 4; ++var12) { + for (var13 = -var7; var13 <= var7; ++var13) { + for (var14 = -var7; var14 <= var7; ++var14) { + for (var15 = -var7; var15 <= var7; ++var15) { + if (this.adjacentTreeBlocks[(var13 + var11) * var10 + (var14 + var11) * var9 + var15 + + var11] == var12 - 1) { + if (this.adjacentTreeBlocks[(var13 + var11 - 1) * var10 + (var14 + var11) * var9 + + var15 + var11] == -2) { + this.adjacentTreeBlocks[(var13 + var11 - 1) * var10 + (var14 + var11) * var9 + + var15 + var11] = var12; + } + + if (this.adjacentTreeBlocks[(var13 + var11 + 1) * var10 + (var14 + var11) * var9 + + var15 + var11] == -2) { + this.adjacentTreeBlocks[(var13 + var11 + 1) * var10 + (var14 + var11) * var9 + + var15 + var11] = var12; + } + + if (this.adjacentTreeBlocks[(var13 + var11) * var10 + (var14 + var11 - 1) * var9 + + var15 + var11] == -2) { + this.adjacentTreeBlocks[(var13 + var11) * var10 + (var14 + var11 - 1) * var9 + + var15 + var11] = var12; + } + + if (this.adjacentTreeBlocks[(var13 + var11) * var10 + (var14 + var11 + 1) * var9 + + var15 + var11] == -2) { + this.adjacentTreeBlocks[(var13 + var11) * var10 + (var14 + var11 + 1) * var9 + + var15 + var11] = var12; + } + + if (this.adjacentTreeBlocks[(var13 + var11) * var10 + (var14 + var11) * var9 + + (var15 + var11 - 1)] == -2) { + this.adjacentTreeBlocks[(var13 + var11) * var10 + (var14 + var11) * var9 + + (var15 + var11 - 1)] = var12; + } + + if (this.adjacentTreeBlocks[(var13 + var11) * var10 + (var14 + var11) * var9 + + var15 + var11 + 1] == -2) { + this.adjacentTreeBlocks[(var13 + var11) * var10 + (var14 + var11) * var9 + + var15 + var11 + 1] = var12; + } + } + } + } + } + } + } + + var12 = this.adjacentTreeBlocks[var11 * var10 + var11 * var9 + var11]; + + if (var12 >= 0) { + par1World.setBlockMetadata(par2, par3, par4, var6 & -9, 4); + } else { + this.removeLeaves(par1World, par2, par3, par4); + } + } + } + } + + private void removeLeaves(World par1World, int par2, int par3, int par4) { + this.dropBlockAsItem(par1World, par2, par3, par4, par1World.getBlockMetadata(par2, par3, par4), 0); + par1World.setBlockToAir(par2, par3, par4); + } + + /** + * Returns the quantity of items to drop on block destruction. + */ + public int quantityDropped(Random par1Random) { + return par1Random.nextInt(20) == 0 ? 1 : 0; + } + + /** + * Returns the ID of the items to drop on destruction. + */ + public int idDropped(int par1, Random par2Random, int par3) { + return Block.sapling.blockID; + } + + /** + * Drops the block items with a specified chance of dropping the specified items + */ + public void dropBlockAsItemWithChance(World par1World, int par2, int par3, int par4, int par5, float par6, + int par7) { + if (!par1World.isRemote) { + int var8 = 20; + + if ((par5 & 3) == 3) { + var8 = 40; + } + + if (par7 > 0) { + var8 -= 2 << par7; + + if (var8 < 10) { + var8 = 10; + } + } + + if (par1World.rand.nextInt(var8) == 0) { + int var9 = this.idDropped(par5, par1World.rand, par7); + this.dropBlockAsItem_do(par1World, par2, par3, par4, new ItemStack(var9, 1, this.damageDropped(par5))); + } + + var8 = 200; + + if (par7 > 0) { + var8 -= 10 << par7; + + if (var8 < 40) { + var8 = 40; + } + } + + if ((par5 & 3) == 0 && par1World.rand.nextInt(var8) == 0) { + this.dropBlockAsItem_do(par1World, par2, par3, par4, new ItemStack(Item.appleRed, 1, 0)); + } + } + } + + /** + * Called when the player destroys a block with an item that can harvest it. (i, + * j, k) are the coordinates of the block and l is the block's subtype/damage. + */ + public void harvestBlock(World par1World, EntityPlayer par2EntityPlayer, int par3, int par4, int par5, int par6) { + if (!par1World.isRemote && par2EntityPlayer.getCurrentEquippedItem() != null + && par2EntityPlayer.getCurrentEquippedItem().itemID == Item.shears.itemID) { + par2EntityPlayer.addStat(StatList.mineBlockStatArray[this.blockID], 1); + this.dropBlockAsItem_do(par1World, par3, par4, par5, new ItemStack(Block.leaves.blockID, 1, par6 & 3)); + } else { + super.harvestBlock(par1World, par2EntityPlayer, par3, par4, par5, par6); + } + } + + /** + * Determines the damage on the item the block drops. Used in cloth and wood. + */ + public int damageDropped(int par1) { + return par1 & 3; + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return !this.graphicsLevel; + } + + /** + * Returns an item stack containing a single instance of the current block type. + * 'i' is the block's subtype/damage and is ignored for blocks which do not + * support subtypes. Blocks which cannot be harvested should return null. + */ + protected ItemStack createStackedBlock(int par1) { + return new ItemStack(this.blockID, 1, par1 & 3); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockLeavesBase.java b/sp-server/src/main/java/net/minecraft/src/BlockLeavesBase.java new file mode 100644 index 0000000..a9af609 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockLeavesBase.java @@ -0,0 +1,23 @@ +package net.minecraft.src; + +public class BlockLeavesBase extends Block { + /** + * Used to determine how to display leaves based on the graphics level. May also + * be used in rendering for transparency, not sure. + */ + protected boolean graphicsLevel; + + protected BlockLeavesBase(int par1, Material par2Material, boolean par3) { + super(par1, par2Material); + this.graphicsLevel = par3; + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return false; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockLever.java b/sp-server/src/main/java/net/minecraft/src/BlockLever.java new file mode 100644 index 0000000..50a6b7e --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockLever.java @@ -0,0 +1,356 @@ +package net.minecraft.src; + +public class BlockLever extends Block { + protected BlockLever(int par1) { + super(par1, Material.circuits); + this.setCreativeTab(CreativeTabs.tabRedstone); + } + + /** + * Returns a bounding box from the pool of bounding boxes (this means this box + * can change after the pool has been cleared to be reused) + */ + public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int par4) { + return null; + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return false; + } + + /** + * If this block doesn't render as an ordinary block it will return False + * (examples: signs, buttons, stairs, etc) + */ + public boolean renderAsNormalBlock() { + return false; + } + + /** + * The type of render function that is called for this block + */ + public int getRenderType() { + return 12; + } + + /** + * checks to see if you can place this block can be placed on that side of a + * block: BlockLever overrides + */ + public boolean canPlaceBlockOnSide(World par1World, int par2, int par3, int par4, int par5) { + return par5 == 0 && par1World.isBlockNormalCube(par2, par3 + 1, par4) ? true + : (par5 == 1 && par1World.doesBlockHaveSolidTopSurface(par2, par3 - 1, par4) ? true + : (par5 == 2 && par1World.isBlockNormalCube(par2, par3, par4 + 1) ? true + : (par5 == 3 && par1World.isBlockNormalCube(par2, par3, par4 - 1) ? true + : (par5 == 4 && par1World.isBlockNormalCube(par2 + 1, par3, par4) ? true + : par5 == 5 && par1World.isBlockNormalCube(par2 - 1, par3, par4))))); + } + + /** + * Checks to see if its valid to put this block at the specified coordinates. + * Args: world, x, y, z + */ + public boolean canPlaceBlockAt(World par1World, int par2, int par3, int par4) { + return par1World + .isBlockNormalCube(par2 - 1, par3, par4) + ? true + : (par1World + .isBlockNormalCube(par2 + 1, par3, par4) + ? true + : (par1World.isBlockNormalCube(par2, par3, par4 - 1) ? true + : (par1World.isBlockNormalCube(par2, par3, par4 + 1) ? true + : (par1World.doesBlockHaveSolidTopSurface(par2, par3 - 1, par4) + ? true + : par1World.isBlockNormalCube(par2, par3 + 1, par4))))); + } + + /** + * Called when a block is placed using its ItemBlock. Args: World, X, Y, Z, + * side, hitX, hitY, hitZ, block metadata + */ + public int onBlockPlaced(World par1World, int par2, int par3, int par4, int par5, float par6, float par7, + float par8, int par9) { + int var11 = par9 & 8; + int var10 = par9 & 7; + byte var12 = -1; + + if (par5 == 0 && par1World.isBlockNormalCube(par2, par3 + 1, par4)) { + var12 = 0; + } + + if (par5 == 1 && par1World.doesBlockHaveSolidTopSurface(par2, par3 - 1, par4)) { + var12 = 5; + } + + if (par5 == 2 && par1World.isBlockNormalCube(par2, par3, par4 + 1)) { + var12 = 4; + } + + if (par5 == 3 && par1World.isBlockNormalCube(par2, par3, par4 - 1)) { + var12 = 3; + } + + if (par5 == 4 && par1World.isBlockNormalCube(par2 + 1, par3, par4)) { + var12 = 2; + } + + if (par5 == 5 && par1World.isBlockNormalCube(par2 - 1, par3, par4)) { + var12 = 1; + } + + return var12 + var11; + } + + /** + * Called when the block is placed in the world. + */ + public void onBlockPlacedBy(World par1World, int par2, int par3, int par4, EntityLiving par5EntityLiving, + ItemStack par6ItemStack) { + int var7 = par1World.getBlockMetadata(par2, par3, par4); + int var8 = var7 & 7; + int var9 = var7 & 8; + + if (var8 == invertMetadata(1)) { + if ((MathHelper.floor_double((double) (par5EntityLiving.rotationYaw * 4.0F / 360.0F) + 0.5D) & 1) == 0) { + par1World.setBlockMetadata(par2, par3, par4, 5 | var9, 2); + } else { + par1World.setBlockMetadata(par2, par3, par4, 6 | var9, 2); + } + } else if (var8 == invertMetadata(0)) { + if ((MathHelper.floor_double((double) (par5EntityLiving.rotationYaw * 4.0F / 360.0F) + 0.5D) & 1) == 0) { + par1World.setBlockMetadata(par2, par3, par4, 7 | var9, 2); + } else { + par1World.setBlockMetadata(par2, par3, par4, 0 | var9, 2); + } + } + } + + /** + * only used in ComponentScatteredFeatureJunglePyramid.addComponentParts" + */ + public static int invertMetadata(int par0) { + switch (par0) { + case 0: + return 0; + + case 1: + return 5; + + case 2: + return 4; + + case 3: + return 3; + + case 4: + return 2; + + case 5: + return 1; + + default: + return -1; + } + } + + /** + * Lets the block know when one of its neighbor changes. Doesn't know which + * neighbor changed (coordinates passed are their own) Args: x, y, z, neighbor + * blockID + */ + public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5) { + if (this.checkIfAttachedToBlock(par1World, par2, par3, par4)) { + int var6 = par1World.getBlockMetadata(par2, par3, par4) & 7; + boolean var7 = false; + + if (!par1World.isBlockNormalCube(par2 - 1, par3, par4) && var6 == 1) { + var7 = true; + } + + if (!par1World.isBlockNormalCube(par2 + 1, par3, par4) && var6 == 2) { + var7 = true; + } + + if (!par1World.isBlockNormalCube(par2, par3, par4 - 1) && var6 == 3) { + var7 = true; + } + + if (!par1World.isBlockNormalCube(par2, par3, par4 + 1) && var6 == 4) { + var7 = true; + } + + if (!par1World.doesBlockHaveSolidTopSurface(par2, par3 - 1, par4) && var6 == 5) { + var7 = true; + } + + if (!par1World.doesBlockHaveSolidTopSurface(par2, par3 - 1, par4) && var6 == 6) { + var7 = true; + } + + if (!par1World.isBlockNormalCube(par2, par3 + 1, par4) && var6 == 0) { + var7 = true; + } + + if (!par1World.isBlockNormalCube(par2, par3 + 1, par4) && var6 == 7) { + var7 = true; + } + + if (var7) { + this.dropBlockAsItem(par1World, par2, par3, par4, par1World.getBlockMetadata(par2, par3, par4), 0); + par1World.setBlockToAir(par2, par3, par4); + } + } + } + + /** + * Checks if the block is attached to another block. If it is not, it returns + * false and drops the block as an item. If it is it returns true. + */ + private boolean checkIfAttachedToBlock(World par1World, int par2, int par3, int par4) { + if (!this.canPlaceBlockAt(par1World, par2, par3, par4)) { + this.dropBlockAsItem(par1World, par2, par3, par4, par1World.getBlockMetadata(par2, par3, par4), 0); + par1World.setBlockToAir(par2, par3, par4); + return false; + } else { + return true; + } + } + + /** + * Updates the blocks bounds based on its current state. Args: world, x, y, z + */ + public void setBlockBoundsBasedOnState(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + int var5 = par1IBlockAccess.getBlockMetadata(par2, par3, par4) & 7; + float var6 = 0.1875F; + + if (var5 == 1) { + this.setBlockBounds(0.0F, 0.2F, 0.5F - var6, var6 * 2.0F, 0.8F, 0.5F + var6); + } else if (var5 == 2) { + this.setBlockBounds(1.0F - var6 * 2.0F, 0.2F, 0.5F - var6, 1.0F, 0.8F, 0.5F + var6); + } else if (var5 == 3) { + this.setBlockBounds(0.5F - var6, 0.2F, 0.0F, 0.5F + var6, 0.8F, var6 * 2.0F); + } else if (var5 == 4) { + this.setBlockBounds(0.5F - var6, 0.2F, 1.0F - var6 * 2.0F, 0.5F + var6, 0.8F, 1.0F); + } else if (var5 != 5 && var5 != 6) { + if (var5 == 0 || var5 == 7) { + var6 = 0.25F; + this.setBlockBounds(0.5F - var6, 0.4F, 0.5F - var6, 0.5F + var6, 1.0F, 0.5F + var6); + } + } else { + var6 = 0.25F; + this.setBlockBounds(0.5F - var6, 0.0F, 0.5F - var6, 0.5F + var6, 0.6F, 0.5F + var6); + } + } + + /** + * Called upon block activation (right click on the block.) + */ + public boolean onBlockActivated(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer, + int par6, float par7, float par8, float par9) { + if (par1World.isRemote) { + return true; + } else { + int var10 = par1World.getBlockMetadata(par2, par3, par4); + int var11 = var10 & 7; + int var12 = 8 - (var10 & 8); + par1World.setBlockMetadata(par2, par3, par4, var11 + var12, 3); + par1World.playSoundEffect((double) par2 + 0.5D, (double) par3 + 0.5D, (double) par4 + 0.5D, "random.click", + 0.3F, var12 > 0 ? 0.6F : 0.5F); + par1World.notifyBlocksOfNeighborChange(par2, par3, par4, this.blockID); + + if (var11 == 1) { + par1World.notifyBlocksOfNeighborChange(par2 - 1, par3, par4, this.blockID); + } else if (var11 == 2) { + par1World.notifyBlocksOfNeighborChange(par2 + 1, par3, par4, this.blockID); + } else if (var11 == 3) { + par1World.notifyBlocksOfNeighborChange(par2, par3, par4 - 1, this.blockID); + } else if (var11 == 4) { + par1World.notifyBlocksOfNeighborChange(par2, par3, par4 + 1, this.blockID); + } else if (var11 != 5 && var11 != 6) { + if (var11 == 0 || var11 == 7) { + par1World.notifyBlocksOfNeighborChange(par2, par3 + 1, par4, this.blockID); + } + } else { + par1World.notifyBlocksOfNeighborChange(par2, par3 - 1, par4, this.blockID); + } + + return true; + } + } + + /** + * ejects contained items into the world, and notifies neighbours of an update, + * as appropriate + */ + public void breakBlock(World par1World, int par2, int par3, int par4, int par5, int par6) { + if ((par6 & 8) > 0) { + par1World.notifyBlocksOfNeighborChange(par2, par3, par4, this.blockID); + int var7 = par6 & 7; + + if (var7 == 1) { + par1World.notifyBlocksOfNeighborChange(par2 - 1, par3, par4, this.blockID); + } else if (var7 == 2) { + par1World.notifyBlocksOfNeighborChange(par2 + 1, par3, par4, this.blockID); + } else if (var7 == 3) { + par1World.notifyBlocksOfNeighborChange(par2, par3, par4 - 1, this.blockID); + } else if (var7 == 4) { + par1World.notifyBlocksOfNeighborChange(par2, par3, par4 + 1, this.blockID); + } else if (var7 != 5 && var7 != 6) { + if (var7 == 0 || var7 == 7) { + par1World.notifyBlocksOfNeighborChange(par2, par3 + 1, par4, this.blockID); + } + } else { + par1World.notifyBlocksOfNeighborChange(par2, par3 - 1, par4, this.blockID); + } + } + + super.breakBlock(par1World, par2, par3, par4, par5, par6); + } + + /** + * Returns true if the block is emitting indirect/weak redstone power on the + * specified side. If isBlockNormalCube returns true, standard redstone + * propagation rules will apply instead and this will not be called. Args: + * World, X, Y, Z, side. Note that the side is reversed - eg it is 1 (up) when + * checking the bottom of the block. + */ + public int isProvidingWeakPower(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5) { + return (par1IBlockAccess.getBlockMetadata(par2, par3, par4) & 8) > 0 ? 15 : 0; + } + + /** + * Returns true if the block is emitting direct/strong redstone power on the + * specified side. Args: World, X, Y, Z, side. Note that the side is reversed - + * eg it is 1 (up) when checking the bottom of the block. + */ + public int isProvidingStrongPower(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5) { + int var6 = par1IBlockAccess.getBlockMetadata(par2, par3, par4); + + if ((var6 & 8) == 0) { + return 0; + } else { + int var7 = var6 & 7; + return var7 == 0 && par5 == 0 ? 15 + : (var7 == 7 && par5 == 0 ? 15 + : (var7 == 6 && par5 == 1 ? 15 + : (var7 == 5 && par5 == 1 ? 15 + : (var7 == 4 && par5 == 2 ? 15 + : (var7 == 3 && par5 == 3 ? 15 + : (var7 == 2 && par5 == 4 ? 15 + : (var7 == 1 && par5 == 5 ? 15 : 0))))))); + } + } + + /** + * Can this block provide power. Only wire currently seems to have this change + * based on its state. + */ + public boolean canProvidePower() { + return true; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockLilyPad.java b/sp-server/src/main/java/net/minecraft/src/BlockLilyPad.java new file mode 100644 index 0000000..020903a --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockLilyPad.java @@ -0,0 +1,61 @@ +package net.minecraft.src; + +import java.util.List; + +public class BlockLilyPad extends BlockFlower { + protected BlockLilyPad(int par1) { + super(par1); + float var2 = 0.5F; + float var3 = 0.015625F; + this.setBlockBounds(0.5F - var2, 0.0F, 0.5F - var2, 0.5F + var2, var3, 0.5F + var2); + this.setCreativeTab(CreativeTabs.tabDecorations); + } + + /** + * The type of render function that is called for this block + */ + public int getRenderType() { + return 23; + } + + /** + * Adds all intersecting collision boxes to a list. (Be sure to only add boxes + * to the list if they intersect the mask.) Parameters: World, X, Y, Z, mask, + * list, colliding entity + */ + public void addCollisionBoxesToList(World par1World, int par2, int par3, int par4, AxisAlignedBB par5AxisAlignedBB, + List par6List, Entity par7Entity) { + if (par7Entity == null || !(par7Entity instanceof EntityBoat)) { + super.addCollisionBoxesToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity); + } + } + + /** + * Returns a bounding box from the pool of bounding boxes (this means this box + * can change after the pool has been cleared to be reused) + */ + public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int par4) { + return AxisAlignedBB.getAABBPool().getAABB((double) par2 + this.minX, (double) par3 + this.minY, + (double) par4 + this.minZ, (double) par2 + this.maxX, (double) par3 + this.maxY, + (double) par4 + this.maxZ); + } + + /** + * Gets passed in the blockID of the block below and supposed to return true if + * its allowed to grow on the type of blockID passed in. Args: blockID + */ + protected boolean canThisPlantGrowOnThisBlockID(int par1) { + return par1 == Block.waterStill.blockID; + } + + /** + * Can this block stay at this position. Similar to canPlaceBlockAt except gets + * checked often with plants. + */ + public boolean canBlockStay(World par1World, int par2, int par3, int par4) { + return par3 >= 0 && par3 < 256 + ? par1World.getBlockMaterial(par2, par3 - 1, par4) == Material.water + && par1World.getBlockMetadata(par2, par3 - 1, par4) == 0 + : false; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockLockedChest.java b/sp-server/src/main/java/net/minecraft/src/BlockLockedChest.java new file mode 100644 index 0000000..097ad6f --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockLockedChest.java @@ -0,0 +1,24 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockLockedChest extends Block { + protected BlockLockedChest(int par1) { + super(par1, Material.wood); + } + + /** + * Checks to see if its valid to put this block at the specified coordinates. + * Args: world, x, y, z + */ + public boolean canPlaceBlockAt(World par1World, int par2, int par3, int par4) { + return true; + } + + /** + * Ticks the block if it's been scheduled + */ + public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random) { + par1World.setBlockToAir(par2, par3, par4); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockLog.java b/sp-server/src/main/java/net/minecraft/src/BlockLog.java new file mode 100644 index 0000000..f10f234 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockLog.java @@ -0,0 +1,114 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockLog extends Block { + /** The type of tree this log came from. */ + public static final String[] woodType = new String[] { "oak", "spruce", "birch", "jungle" }; + public static final String[] treeTextureTypes = new String[] { "tree_side", "tree_spruce", "tree_birch", + "tree_jungle" }; + + protected BlockLog(int par1) { + super(par1, Material.wood); + this.setCreativeTab(CreativeTabs.tabBlock); + } + + /** + * The type of render function that is called for this block + */ + public int getRenderType() { + return 31; + } + + /** + * Returns the quantity of items to drop on block destruction. + */ + public int quantityDropped(Random par1Random) { + return 1; + } + + /** + * Returns the ID of the items to drop on destruction. + */ + public int idDropped(int par1, Random par2Random, int par3) { + return Block.wood.blockID; + } + + /** + * ejects contained items into the world, and notifies neighbours of an update, + * as appropriate + */ + public void breakBlock(World par1World, int par2, int par3, int par4, int par5, int par6) { + byte var7 = 4; + int var8 = var7 + 1; + + if (par1World.checkChunksExist(par2 - var8, par3 - var8, par4 - var8, par2 + var8, par3 + var8, par4 + var8)) { + for (int var9 = -var7; var9 <= var7; ++var9) { + for (int var10 = -var7; var10 <= var7; ++var10) { + for (int var11 = -var7; var11 <= var7; ++var11) { + int var12 = par1World.getBlockId(par2 + var9, par3 + var10, par4 + var11); + + if (var12 == Block.leaves.blockID) { + int var13 = par1World.getBlockMetadata(par2 + var9, par3 + var10, par4 + var11); + + if ((var13 & 8) == 0) { + par1World.setBlockMetadata(par2 + var9, par3 + var10, par4 + var11, var13 | 8, 4); + } + } + } + } + } + } + } + + /** + * Called when a block is placed using its ItemBlock. Args: World, X, Y, Z, + * side, hitX, hitY, hitZ, block metadata + */ + public int onBlockPlaced(World par1World, int par2, int par3, int par4, int par5, float par6, float par7, + float par8, int par9) { + int var10 = par9 & 3; + byte var11 = 0; + + switch (par5) { + case 0: + case 1: + var11 = 0; + break; + + case 2: + case 3: + var11 = 8; + break; + + case 4: + case 5: + var11 = 4; + } + + return var10 | var11; + } + + /** + * Determines the damage on the item the block drops. Used in cloth and wood. + */ + public int damageDropped(int par1) { + return par1 & 3; + } + + /** + * returns a number between 0 and 3 + */ + public static int limitToValidMetadata(int par0) { + return par0 & 3; + } + + /** + * Returns an item stack containing a single instance of the current block type. + * 'i' is the block's subtype/damage and is ignored for blocks which do not + * support subtypes. Blocks which cannot be harvested should return null. + */ + protected ItemStack createStackedBlock(int par1) { + return new ItemStack(this.blockID, 1, limitToValidMetadata(par1)); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockMelon.java b/sp-server/src/main/java/net/minecraft/src/BlockMelon.java new file mode 100644 index 0000000..771b453 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockMelon.java @@ -0,0 +1,38 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockMelon extends Block { + protected BlockMelon(int par1) { + super(par1, Material.pumpkin); + this.setCreativeTab(CreativeTabs.tabBlock); + } + + /** + * Returns the ID of the items to drop on destruction. + */ + public int idDropped(int par1, Random par2Random, int par3) { + return Item.melon.itemID; + } + + /** + * Returns the quantity of items to drop on block destruction. + */ + public int quantityDropped(Random par1Random) { + return 3 + par1Random.nextInt(5); + } + + /** + * Returns the usual quantity dropped by the block plus a bonus of 1 to 'i' + * (inclusive). + */ + public int quantityDroppedWithBonus(int par1, Random par2Random) { + int var3 = this.quantityDropped(par2Random) + par2Random.nextInt(1 + par1); + + if (var3 > 9) { + var3 = 9; + } + + return var3; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockMobSpawner.java b/sp-server/src/main/java/net/minecraft/src/BlockMobSpawner.java new file mode 100644 index 0000000..c02ef4e --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockMobSpawner.java @@ -0,0 +1,50 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockMobSpawner extends BlockContainer { + protected BlockMobSpawner(int par1) { + super(par1, Material.rock); + } + + /** + * Returns a new instance of a block's tile entity class. Called on placing the + * block. + */ + public TileEntity createNewTileEntity(World par1World) { + return new TileEntityMobSpawner(); + } + + /** + * Returns the ID of the items to drop on destruction. + */ + public int idDropped(int par1, Random par2Random, int par3) { + return 0; + } + + /** + * Returns the quantity of items to drop on block destruction. + */ + public int quantityDropped(Random par1Random) { + return 0; + } + + /** + * Drops the block items with a specified chance of dropping the specified items + */ + public void dropBlockAsItemWithChance(World par1World, int par2, int par3, int par4, int par5, float par6, + int par7) { + super.dropBlockAsItemWithChance(par1World, par2, par3, par4, par5, par6, par7); + int var8 = 15 + par1World.rand.nextInt(15) + par1World.rand.nextInt(15); + this.dropXpOnBlockBreak(par1World, par2, par3, par4, var8); + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return false; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockMushroom.java b/sp-server/src/main/java/net/minecraft/src/BlockMushroom.java new file mode 100644 index 0000000..60eda60 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockMushroom.java @@ -0,0 +1,114 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockMushroom extends BlockFlower { + private final String field_94374_a; + + protected BlockMushroom(int par1, String par2Str) { + super(par1); + this.field_94374_a = par2Str; + float var3 = 0.2F; + this.setBlockBounds(0.5F - var3, 0.0F, 0.5F - var3, 0.5F + var3, var3 * 2.0F, 0.5F + var3); + this.setTickRandomly(true); + } + + /** + * Ticks the block if it's been scheduled + */ + public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random) { + if (par5Random.nextInt(25) == 0) { + byte var6 = 4; + int var7 = 5; + int var8; + int var9; + int var10; + + for (var8 = par2 - var6; var8 <= par2 + var6; ++var8) { + for (var9 = par4 - var6; var9 <= par4 + var6; ++var9) { + for (var10 = par3 - 1; var10 <= par3 + 1; ++var10) { + if (par1World.getBlockId(var8, var10, var9) == this.blockID) { + --var7; + + if (var7 <= 0) { + return; + } + } + } + } + } + + var8 = par2 + par5Random.nextInt(3) - 1; + var9 = par3 + par5Random.nextInt(2) - par5Random.nextInt(2); + var10 = par4 + par5Random.nextInt(3) - 1; + + for (int var11 = 0; var11 < 4; ++var11) { + if (par1World.isAirBlock(var8, var9, var10) && this.canBlockStay(par1World, var8, var9, var10)) { + par2 = var8; + par3 = var9; + par4 = var10; + } + + var8 = par2 + par5Random.nextInt(3) - 1; + var9 = par3 + par5Random.nextInt(2) - par5Random.nextInt(2); + var10 = par4 + par5Random.nextInt(3) - 1; + } + + if (par1World.isAirBlock(var8, var9, var10) && this.canBlockStay(par1World, var8, var9, var10)) { + par1World.setBlock(var8, var9, var10, this.blockID); + } + } + } + + /** + * Checks to see if its valid to put this block at the specified coordinates. + * Args: world, x, y, z + */ + public boolean canPlaceBlockAt(World par1World, int par2, int par3, int par4) { + return super.canPlaceBlockAt(par1World, par2, par3, par4) && this.canBlockStay(par1World, par2, par3, par4); + } + + /** + * Gets passed in the blockID of the block below and supposed to return true if + * its allowed to grow on the type of blockID passed in. Args: blockID + */ + protected boolean canThisPlantGrowOnThisBlockID(int par1) { + return Block.opaqueCubeLookup[par1]; + } + + /** + * Can this block stay at this position. Similar to canPlaceBlockAt except gets + * checked often with plants. + */ + public boolean canBlockStay(World par1World, int par2, int par3, int par4) { + if (par3 >= 0 && par3 < 256) { + int var5 = par1World.getBlockId(par2, par3 - 1, par4); + return var5 == Block.mycelium.blockID || par1World.getFullBlockLightValue(par2, par3, par4) < 13 + && this.canThisPlantGrowOnThisBlockID(var5); + } else { + return false; + } + } + + /** + * Fertilize the mushroom. + */ + public boolean fertilizeMushroom(World par1World, int par2, int par3, int par4, Random par5Random) { + int var6 = par1World.getBlockMetadata(par2, par3, par4); + par1World.setBlockToAir(par2, par3, par4); + WorldGenBigMushroom var7 = null; + + if (this.blockID == Block.mushroomBrown.blockID) { + var7 = new WorldGenBigMushroom(0); + } else if (this.blockID == Block.mushroomRed.blockID) { + var7 = new WorldGenBigMushroom(1); + } + + if (var7 != null && var7.generate(par1World, par5Random, par2, par3, par4)) { + return true; + } else { + par1World.setBlock(par2, par3, par4, this.blockID, var6, 3); + return false; + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockMushroomCap.java b/sp-server/src/main/java/net/minecraft/src/BlockMushroomCap.java new file mode 100644 index 0000000..d7ce5cb --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockMushroomCap.java @@ -0,0 +1,35 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockMushroomCap extends Block { + private static final String[] field_94429_a = new String[] { "mushroom_skin_brown", "mushroom_skin_red" }; + + /** The mushroom type. 0 for brown, 1 for red. */ + private final int mushroomType; + + public BlockMushroomCap(int par1, Material par2Material, int par3) { + super(par1, par2Material); + this.mushroomType = par3; + } + + /** + * Returns the quantity of items to drop on block destruction. + */ + public int quantityDropped(Random par1Random) { + int var2 = par1Random.nextInt(10) - 7; + + if (var2 < 0) { + var2 = 0; + } + + return var2; + } + + /** + * Returns the ID of the items to drop on destruction. + */ + public int idDropped(int par1, Random par2Random, int par3) { + return Block.mushroomBrown.blockID + this.mushroomType; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockMycelium.java b/sp-server/src/main/java/net/minecraft/src/BlockMycelium.java new file mode 100644 index 0000000..b1b30ce --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockMycelium.java @@ -0,0 +1,43 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockMycelium extends Block { + protected BlockMycelium(int par1) { + super(par1, Material.grass); + this.setTickRandomly(true); + this.setCreativeTab(CreativeTabs.tabBlock); + } + + /** + * Ticks the block if it's been scheduled + */ + public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random) { + if (!par1World.isRemote) { + if (par1World.getBlockLightValue(par2, par3 + 1, par4) < 4 + && Block.lightOpacity[par1World.getBlockId(par2, par3 + 1, par4)] > 2) { + par1World.setBlock(par2, par3, par4, Block.dirt.blockID); + } else if (par1World.getBlockLightValue(par2, par3 + 1, par4) >= 9) { + for (int var6 = 0; var6 < 4; ++var6) { + int var7 = par2 + par5Random.nextInt(3) - 1; + int var8 = par3 + par5Random.nextInt(5) - 3; + int var9 = par4 + par5Random.nextInt(3) - 1; + int var10 = par1World.getBlockId(var7, var8 + 1, var9); + + if (par1World.getBlockId(var7, var8, var9) == Block.dirt.blockID + && par1World.getBlockLightValue(var7, var8 + 1, var9) >= 4 + && Block.lightOpacity[var10] <= 2) { + par1World.setBlock(var7, var8, var9, this.blockID); + } + } + } + } + } + + /** + * Returns the ID of the items to drop on destruction. + */ + public int idDropped(int par1, Random par2Random, int par3) { + return Block.dirt.idDropped(0, par2Random, par3); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockNetherStalk.java b/sp-server/src/main/java/net/minecraft/src/BlockNetherStalk.java new file mode 100644 index 0000000..8213218 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockNetherStalk.java @@ -0,0 +1,88 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockNetherStalk extends BlockFlower { + private static final String[] field_94373_a = new String[] { "netherStalk_0", "netherStalk_1", "netherStalk_2" }; + + protected BlockNetherStalk(int par1) { + super(par1); + this.setTickRandomly(true); + float var2 = 0.5F; + this.setBlockBounds(0.5F - var2, 0.0F, 0.5F - var2, 0.5F + var2, 0.25F, 0.5F + var2); + this.setCreativeTab((CreativeTabs) null); + } + + /** + * Gets passed in the blockID of the block below and supposed to return true if + * its allowed to grow on the type of blockID passed in. Args: blockID + */ + protected boolean canThisPlantGrowOnThisBlockID(int par1) { + return par1 == Block.slowSand.blockID; + } + + /** + * Can this block stay at this position. Similar to canPlaceBlockAt except gets + * checked often with plants. + */ + public boolean canBlockStay(World par1World, int par2, int par3, int par4) { + return this.canThisPlantGrowOnThisBlockID(par1World.getBlockId(par2, par3 - 1, par4)); + } + + /** + * Ticks the block if it's been scheduled + */ + public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random) { + int var6 = par1World.getBlockMetadata(par2, par3, par4); + + if (var6 < 3 && par5Random.nextInt(10) == 0) { + ++var6; + par1World.setBlockMetadata(par2, par3, par4, var6, 2); + } + + super.updateTick(par1World, par2, par3, par4, par5Random); + } + + /** + * The type of render function that is called for this block + */ + public int getRenderType() { + return 6; + } + + /** + * Drops the block items with a specified chance of dropping the specified items + */ + public void dropBlockAsItemWithChance(World par1World, int par2, int par3, int par4, int par5, float par6, + int par7) { + if (!par1World.isRemote) { + int var8 = 1; + + if (par5 >= 3) { + var8 = 2 + par1World.rand.nextInt(3); + + if (par7 > 0) { + var8 += par1World.rand.nextInt(par7 + 1); + } + } + + for (int var9 = 0; var9 < var8; ++var9) { + this.dropBlockAsItem_do(par1World, par2, par3, par4, new ItemStack(Item.netherStalkSeeds)); + } + } + } + + /** + * Returns the ID of the items to drop on destruction. + */ + public int idDropped(int par1, Random par2Random, int par3) { + return 0; + } + + /** + * Returns the quantity of items to drop on block destruction. + */ + public int quantityDropped(Random par1Random) { + return 0; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockNetherrack.java b/sp-server/src/main/java/net/minecraft/src/BlockNetherrack.java new file mode 100644 index 0000000..f4df058 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockNetherrack.java @@ -0,0 +1,8 @@ +package net.minecraft.src; + +public class BlockNetherrack extends Block { + public BlockNetherrack(int par1) { + super(par1, Material.rock); + this.setCreativeTab(CreativeTabs.tabBlock); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockNote.java b/sp-server/src/main/java/net/minecraft/src/BlockNote.java new file mode 100644 index 0000000..ed38179 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockNote.java @@ -0,0 +1,98 @@ +package net.minecraft.src; + +public class BlockNote extends BlockContainer { + public BlockNote(int par1) { + super(par1, Material.wood); + this.setCreativeTab(CreativeTabs.tabRedstone); + } + + /** + * Lets the block know when one of its neighbor changes. Doesn't know which + * neighbor changed (coordinates passed are their own) Args: x, y, z, neighbor + * blockID + */ + public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5) { + boolean var6 = par1World.isBlockIndirectlyGettingPowered(par2, par3, par4); + TileEntityNote var7 = (TileEntityNote) par1World.getBlockTileEntity(par2, par3, par4); + + if (var7 != null && var7.previousRedstoneState != var6) { + if (var6) { + var7.triggerNote(par1World, par2, par3, par4); + } + + var7.previousRedstoneState = var6; + } + } + + /** + * Called upon block activation (right click on the block.) + */ + public boolean onBlockActivated(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer, + int par6, float par7, float par8, float par9) { + if (par1World.isRemote) { + return true; + } else { + TileEntityNote var10 = (TileEntityNote) par1World.getBlockTileEntity(par2, par3, par4); + + if (var10 != null) { + var10.changePitch(); + var10.triggerNote(par1World, par2, par3, par4); + } + + return true; + } + } + + /** + * Called when the block is clicked by a player. Args: x, y, z, entityPlayer + */ + public void onBlockClicked(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer) { + if (!par1World.isRemote) { + TileEntityNote var6 = (TileEntityNote) par1World.getBlockTileEntity(par2, par3, par4); + + if (var6 != null) { + var6.triggerNote(par1World, par2, par3, par4); + } + } + } + + /** + * Returns a new instance of a block's tile entity class. Called on placing the + * block. + */ + public TileEntity createNewTileEntity(World par1World) { + return new TileEntityNote(); + } + + /** + * Called when the block receives a BlockEvent - see World.addBlockEvent. By + * default, passes it on to the tile entity at this location. Args: world, x, y, + * z, blockID, EventID, event parameter + */ + public boolean onBlockEventReceived(World par1World, int par2, int par3, int par4, int par5, int par6) { + float var7 = (float) Math.pow(2.0D, (double) (par6 - 12) / 12.0D); + String var8 = "harp"; + + if (par5 == 1) { + var8 = "bd"; + } + + if (par5 == 2) { + var8 = "snare"; + } + + if (par5 == 3) { + var8 = "hat"; + } + + if (par5 == 4) { + var8 = "bassattack"; + } + + par1World.playSoundEffect((double) par2 + 0.5D, (double) par3 + 0.5D, (double) par4 + 0.5D, "note." + var8, + 3.0F, var7); + par1World.spawnParticle("note", (double) par2 + 0.5D, (double) par3 + 1.2D, (double) par4 + 0.5D, + (double) par6 / 24.0D, 0.0D, 0.0D); + return true; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockObsidian.java b/sp-server/src/main/java/net/minecraft/src/BlockObsidian.java new file mode 100644 index 0000000..4662b11 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockObsidian.java @@ -0,0 +1,23 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockObsidian extends BlockStone { + public BlockObsidian(int par1) { + super(par1); + } + + /** + * Returns the quantity of items to drop on block destruction. + */ + public int quantityDropped(Random par1Random) { + return 1; + } + + /** + * Returns the ID of the items to drop on destruction. + */ + public int idDropped(int par1, Random par2Random, int par3) { + return Block.obsidian.blockID; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockOre.java b/sp-server/src/main/java/net/minecraft/src/BlockOre.java new file mode 100644 index 0000000..12edd30 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockOre.java @@ -0,0 +1,80 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockOre extends Block { + public BlockOre(int par1) { + super(par1, Material.rock); + this.setCreativeTab(CreativeTabs.tabBlock); + } + + /** + * Returns the ID of the items to drop on destruction. + */ + public int idDropped(int par1, Random par2Random, int par3) { + return this.blockID == Block.oreCoal.blockID ? Item.coal.itemID + : (this.blockID == Block.oreDiamond.blockID ? Item.diamond.itemID + : (this.blockID == Block.oreLapis.blockID ? Item.dyePowder.itemID + : (this.blockID == Block.oreEmerald.blockID ? Item.emerald.itemID + : (this.blockID == Block.oreNetherQuartz.blockID ? Item.netherQuartz.itemID + : this.blockID)))); + } + + /** + * Returns the quantity of items to drop on block destruction. + */ + public int quantityDropped(Random par1Random) { + return this.blockID == Block.oreLapis.blockID ? 4 + par1Random.nextInt(5) : 1; + } + + /** + * Returns the usual quantity dropped by the block plus a bonus of 1 to 'i' + * (inclusive). + */ + public int quantityDroppedWithBonus(int par1, Random par2Random) { + if (par1 > 0 && this.blockID != this.idDropped(0, par2Random, par1)) { + int var3 = par2Random.nextInt(par1 + 2) - 1; + + if (var3 < 0) { + var3 = 0; + } + + return this.quantityDropped(par2Random) * (var3 + 1); + } else { + return this.quantityDropped(par2Random); + } + } + + /** + * Drops the block items with a specified chance of dropping the specified items + */ + public void dropBlockAsItemWithChance(World par1World, int par2, int par3, int par4, int par5, float par6, + int par7) { + super.dropBlockAsItemWithChance(par1World, par2, par3, par4, par5, par6, par7); + + if (this.idDropped(par5, par1World.rand, par7) != this.blockID) { + int var8 = 0; + + if (this.blockID == Block.oreCoal.blockID) { + var8 = MathHelper.getRandomIntegerInRange(par1World.rand, 0, 2); + } else if (this.blockID == Block.oreDiamond.blockID) { + var8 = MathHelper.getRandomIntegerInRange(par1World.rand, 3, 7); + } else if (this.blockID == Block.oreEmerald.blockID) { + var8 = MathHelper.getRandomIntegerInRange(par1World.rand, 3, 7); + } else if (this.blockID == Block.oreLapis.blockID) { + var8 = MathHelper.getRandomIntegerInRange(par1World.rand, 2, 5); + } else if (this.blockID == Block.oreNetherQuartz.blockID) { + var8 = MathHelper.getRandomIntegerInRange(par1World.rand, 2, 5); + } + + this.dropXpOnBlockBreak(par1World, par2, par3, par4, var8); + } + } + + /** + * Determines the damage on the item the block drops. Used in cloth and wood. + */ + public int damageDropped(int par1) { + return this.blockID == Block.oreLapis.blockID ? 4 : 0; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockOreStorage.java b/sp-server/src/main/java/net/minecraft/src/BlockOreStorage.java new file mode 100644 index 0000000..a9d647e --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockOreStorage.java @@ -0,0 +1,8 @@ +package net.minecraft.src; + +public class BlockOreStorage extends Block { + public BlockOreStorage(int par1) { + super(par1, Material.iron); + this.setCreativeTab(CreativeTabs.tabBlock); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockPane.java b/sp-server/src/main/java/net/minecraft/src/BlockPane.java new file mode 100644 index 0000000..5900d31 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockPane.java @@ -0,0 +1,166 @@ +package net.minecraft.src; + +import java.util.List; +import java.util.Random; + +public class BlockPane extends Block { + /** + * Holds the texture index of the side of the pane (the thin lateral side) + */ + private final String sideTextureIndex; + + /** + * If this field is true, the pane block drops itself when destroyed (like the + * iron fences), otherwise, it's just destroyed (like glass panes) + */ + private final boolean canDropItself; + private final String field_94402_c; + + protected BlockPane(int par1, String par2Str, String par3Str, Material par4Material, boolean par5) { + super(par1, par4Material); + this.sideTextureIndex = par3Str; + this.canDropItself = par5; + this.field_94402_c = par2Str; + this.setCreativeTab(CreativeTabs.tabDecorations); + } + + /** + * Returns the ID of the items to drop on destruction. + */ + public int idDropped(int par1, Random par2Random, int par3) { + return !this.canDropItself ? 0 : super.idDropped(par1, par2Random, par3); + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return false; + } + + /** + * If this block doesn't render as an ordinary block it will return False + * (examples: signs, buttons, stairs, etc) + */ + public boolean renderAsNormalBlock() { + return false; + } + + /** + * The type of render function that is called for this block + */ + public int getRenderType() { + return 18; + } + + /** + * Adds all intersecting collision boxes to a list. (Be sure to only add boxes + * to the list if they intersect the mask.) Parameters: World, X, Y, Z, mask, + * list, colliding entity + */ + public void addCollisionBoxesToList(World par1World, int par2, int par3, int par4, AxisAlignedBB par5AxisAlignedBB, + List par6List, Entity par7Entity) { + boolean var8 = this.canThisPaneConnectToThisBlockID(par1World.getBlockId(par2, par3, par4 - 1)); + boolean var9 = this.canThisPaneConnectToThisBlockID(par1World.getBlockId(par2, par3, par4 + 1)); + boolean var10 = this.canThisPaneConnectToThisBlockID(par1World.getBlockId(par2 - 1, par3, par4)); + boolean var11 = this.canThisPaneConnectToThisBlockID(par1World.getBlockId(par2 + 1, par3, par4)); + + if ((!var10 || !var11) && (var10 || var11 || var8 || var9)) { + if (var10 && !var11) { + this.setBlockBounds(0.0F, 0.0F, 0.4375F, 0.5F, 1.0F, 0.5625F); + super.addCollisionBoxesToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity); + } else if (!var10 && var11) { + this.setBlockBounds(0.5F, 0.0F, 0.4375F, 1.0F, 1.0F, 0.5625F); + super.addCollisionBoxesToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity); + } + } else { + this.setBlockBounds(0.0F, 0.0F, 0.4375F, 1.0F, 1.0F, 0.5625F); + super.addCollisionBoxesToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity); + } + + if ((!var8 || !var9) && (var10 || var11 || var8 || var9)) { + if (var8 && !var9) { + this.setBlockBounds(0.4375F, 0.0F, 0.0F, 0.5625F, 1.0F, 0.5F); + super.addCollisionBoxesToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity); + } else if (!var8 && var9) { + this.setBlockBounds(0.4375F, 0.0F, 0.5F, 0.5625F, 1.0F, 1.0F); + super.addCollisionBoxesToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity); + } + } else { + this.setBlockBounds(0.4375F, 0.0F, 0.0F, 0.5625F, 1.0F, 1.0F); + super.addCollisionBoxesToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity); + } + } + + /** + * Sets the block's bounds for rendering it as an item + */ + public void setBlockBoundsForItemRender() { + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + } + + /** + * Updates the blocks bounds based on its current state. Args: world, x, y, z + */ + public void setBlockBoundsBasedOnState(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + float var5 = 0.4375F; + float var6 = 0.5625F; + float var7 = 0.4375F; + float var8 = 0.5625F; + boolean var9 = this.canThisPaneConnectToThisBlockID(par1IBlockAccess.getBlockId(par2, par3, par4 - 1)); + boolean var10 = this.canThisPaneConnectToThisBlockID(par1IBlockAccess.getBlockId(par2, par3, par4 + 1)); + boolean var11 = this.canThisPaneConnectToThisBlockID(par1IBlockAccess.getBlockId(par2 - 1, par3, par4)); + boolean var12 = this.canThisPaneConnectToThisBlockID(par1IBlockAccess.getBlockId(par2 + 1, par3, par4)); + + if ((!var11 || !var12) && (var11 || var12 || var9 || var10)) { + if (var11 && !var12) { + var5 = 0.0F; + } else if (!var11 && var12) { + var6 = 1.0F; + } + } else { + var5 = 0.0F; + var6 = 1.0F; + } + + if ((!var9 || !var10) && (var11 || var12 || var9 || var10)) { + if (var9 && !var10) { + var7 = 0.0F; + } else if (!var9 && var10) { + var8 = 1.0F; + } + } else { + var7 = 0.0F; + var8 = 1.0F; + } + + this.setBlockBounds(var5, 0.0F, var7, var6, 1.0F, var8); + } + + /** + * Gets passed in the blockID of the block adjacent and supposed to return true + * if its allowed to connect to the type of blockID passed in. Args: blockID + */ + public final boolean canThisPaneConnectToThisBlockID(int par1) { + return Block.opaqueCubeLookup[par1] || par1 == this.blockID || par1 == Block.glass.blockID; + } + + /** + * Return true if a player with Silk Touch can harvest this block directly, and + * not its normal drops. + */ + protected boolean canSilkHarvest() { + return true; + } + + /** + * Returns an item stack containing a single instance of the current block type. + * 'i' is the block's subtype/damage and is ignored for blocks which do not + * support subtypes. Blocks which cannot be harvested should return null. + */ + protected ItemStack createStackedBlock(int par1) { + return new ItemStack(this.blockID, 1, par1); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockPistonBase.java b/sp-server/src/main/java/net/minecraft/src/BlockPistonBase.java new file mode 100644 index 0000000..2d1b13d --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockPistonBase.java @@ -0,0 +1,492 @@ +package net.minecraft.src; + +import java.util.List; + +public class BlockPistonBase extends Block { + /** This pistons is the sticky one? */ + private final boolean isSticky; + + public BlockPistonBase(int par1, boolean par2) { + super(par1, Material.piston); + this.isSticky = par2; + this.setStepSound(soundStoneFootstep); + this.setHardness(0.5F); + this.setCreativeTab(CreativeTabs.tabRedstone); + } + + /** + * The type of render function that is called for this block + */ + public int getRenderType() { + return 16; + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return false; + } + + /** + * Called upon block activation (right click on the block.) + */ + public boolean onBlockActivated(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer, + int par6, float par7, float par8, float par9) { + return false; + } + + /** + * Called when the block is placed in the world. + */ + public void onBlockPlacedBy(World par1World, int par2, int par3, int par4, EntityLiving par5EntityLiving, + ItemStack par6ItemStack) { + int var7 = determineOrientation(par1World, par2, par3, par4, par5EntityLiving); + par1World.setBlockMetadata(par2, par3, par4, var7, 2); + + if (!par1World.isRemote) { + this.updatePistonState(par1World, par2, par3, par4); + } + } + + /** + * Lets the block know when one of its neighbor changes. Doesn't know which + * neighbor changed (coordinates passed are their own) Args: x, y, z, neighbor + * blockID + */ + public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5) { + if (!par1World.isRemote) { + this.updatePistonState(par1World, par2, par3, par4); + } + } + + /** + * Called whenever the block is added into the world. Args: world, x, y, z + */ + public void onBlockAdded(World par1World, int par2, int par3, int par4) { + if (!par1World.isRemote && par1World.getBlockTileEntity(par2, par3, par4) == null) { + this.updatePistonState(par1World, par2, par3, par4); + } + } + + /** + * handles attempts to extend or retract the piston. + */ + private void updatePistonState(World par1World, int par2, int par3, int par4) { + int var5 = par1World.getBlockMetadata(par2, par3, par4); + int var6 = getOrientation(var5); + + if (var6 != 7) { + boolean var7 = this.isIndirectlyPowered(par1World, par2, par3, par4, var6); + + if (var7 && !isExtended(var5)) { + if (canExtend(par1World, par2, par3, par4, var6)) { + par1World.addBlockEvent(par2, par3, par4, this.blockID, 0, var6); + } + } else if (!var7 && isExtended(var5)) { + par1World.setBlockMetadata(par2, par3, par4, var6, 2); + par1World.addBlockEvent(par2, par3, par4, this.blockID, 1, var6); + } + } + } + + /** + * checks the block to that side to see if it is indirectly powered. + */ + private boolean isIndirectlyPowered(World par1World, int par2, int par3, int par4, int par5) { + return par5 != 0 && par1World.getIndirectPowerOutput(par2, par3 - 1, par4, 0) ? true + : (par5 != 1 && par1World.getIndirectPowerOutput(par2, par3 + 1, par4, 1) ? true + : (par5 != 2 && par1World.getIndirectPowerOutput(par2, par3, par4 - 1, 2) ? true + : (par5 != 3 && par1World.getIndirectPowerOutput(par2, par3, par4 + 1, 3) ? true + : (par5 != 5 && par1World.getIndirectPowerOutput(par2 + 1, par3, par4, 5) ? true + : (par5 != 4 + && par1World.getIndirectPowerOutput(par2 - 1, par3, par4, 4) + ? true + : (par1World.getIndirectPowerOutput(par2, par3, par4, 0) + ? true + : (par1World.getIndirectPowerOutput(par2, + par3 + 2, par4, 1) + ? true + : (par1World + .getIndirectPowerOutput( + par2, par3 + 1, + par4 - 1, 2) + ? true + : (par1World + .getIndirectPowerOutput( + par2, + par3 + 1, + par4 + 1, + 3) ? true + : (par1World + .getIndirectPowerOutput( + par2 - 1, + par3 + 1, + par4, + 4) ? true + : par1World + .getIndirectPowerOutput( + par2 + 1, + par3 + 1, + par4, + 5))))))))))); + } + + /** + * Called when the block receives a BlockEvent - see World.addBlockEvent. By + * default, passes it on to the tile entity at this location. Args: world, x, y, + * z, blockID, EventID, event parameter + */ + public boolean onBlockEventReceived(World par1World, int par2, int par3, int par4, int par5, int par6) { + if (!par1World.isRemote) { + boolean var7 = this.isIndirectlyPowered(par1World, par2, par3, par4, par6); + + if (var7 && par5 == 1) { + par1World.setBlockMetadata(par2, par3, par4, par6 | 8, 2); + return false; + } + + if (!var7 && par5 == 0) { + return false; + } + } + + if (par5 == 0) { + if (!this.tryExtend(par1World, par2, par3, par4, par6)) { + return false; + } + + par1World.setBlockMetadata(par2, par3, par4, par6 | 8, 2); + par1World.playSoundEffect((double) par2 + 0.5D, (double) par3 + 0.5D, (double) par4 + 0.5D, + "tile.piston.out", 0.5F, par1World.rand.nextFloat() * 0.25F + 0.6F); + } else if (par5 == 1) { + TileEntity var16 = par1World.getBlockTileEntity(par2 + Facing.offsetsXForSide[par6], + par3 + Facing.offsetsYForSide[par6], par4 + Facing.offsetsZForSide[par6]); + + if (var16 instanceof TileEntityPiston) { + ((TileEntityPiston) var16).clearPistonTileEntity(); + } + + par1World.setBlock(par2, par3, par4, Block.pistonMoving.blockID, par6, 3); + par1World.setBlockTileEntity(par2, par3, par4, + BlockPistonMoving.getTileEntity(this.blockID, par6, par6, false, true)); + + if (this.isSticky) { + int var8 = par2 + Facing.offsetsXForSide[par6] * 2; + int var9 = par3 + Facing.offsetsYForSide[par6] * 2; + int var10 = par4 + Facing.offsetsZForSide[par6] * 2; + int var11 = par1World.getBlockId(var8, var9, var10); + int var12 = par1World.getBlockMetadata(var8, var9, var10); + boolean var13 = false; + + if (var11 == Block.pistonMoving.blockID) { + TileEntity var14 = par1World.getBlockTileEntity(var8, var9, var10); + + if (var14 instanceof TileEntityPiston) { + TileEntityPiston var15 = (TileEntityPiston) var14; + + if (var15.getPistonOrientation() == par6 && var15.isExtending()) { + var15.clearPistonTileEntity(); + var11 = var15.getStoredBlockID(); + var12 = var15.getBlockMetadata(); + var13 = true; + } + } + } + + if (!var13 && var11 > 0 && canPushBlock(var11, par1World, var8, var9, var10, false) + && (Block.blocksList[var11].getMobilityFlag() == 0 || var11 == Block.pistonBase.blockID + || var11 == Block.pistonStickyBase.blockID)) { + par2 += Facing.offsetsXForSide[par6]; + par3 += Facing.offsetsYForSide[par6]; + par4 += Facing.offsetsZForSide[par6]; + par1World.setBlock(par2, par3, par4, Block.pistonMoving.blockID, var12, 3); + par1World.setBlockTileEntity(par2, par3, par4, + BlockPistonMoving.getTileEntity(var11, var12, par6, false, false)); + par1World.setBlockToAir(var8, var9, var10); + } else if (!var13) { + par1World.setBlockToAir(par2 + Facing.offsetsXForSide[par6], par3 + Facing.offsetsYForSide[par6], + par4 + Facing.offsetsZForSide[par6]); + } + } else { + par1World.setBlockToAir(par2 + Facing.offsetsXForSide[par6], par3 + Facing.offsetsYForSide[par6], + par4 + Facing.offsetsZForSide[par6]); + } + + par1World.playSoundEffect((double) par2 + 0.5D, (double) par3 + 0.5D, (double) par4 + 0.5D, + "tile.piston.in", 0.5F, par1World.rand.nextFloat() * 0.15F + 0.6F); + } + + return true; + } + + /** + * Updates the blocks bounds based on its current state. Args: world, x, y, z + */ + public void setBlockBoundsBasedOnState(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + int var5 = par1IBlockAccess.getBlockMetadata(par2, par3, par4); + + if (isExtended(var5)) { + switch (getOrientation(var5)) { + case 0: + this.setBlockBounds(0.0F, 0.25F, 0.0F, 1.0F, 1.0F, 1.0F); + break; + + case 1: + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.75F, 1.0F); + break; + + case 2: + this.setBlockBounds(0.0F, 0.0F, 0.25F, 1.0F, 1.0F, 1.0F); + break; + + case 3: + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 0.75F); + break; + + case 4: + this.setBlockBounds(0.25F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + break; + + case 5: + this.setBlockBounds(0.0F, 0.0F, 0.0F, 0.75F, 1.0F, 1.0F); + } + } else { + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + } + } + + /** + * Sets the block's bounds for rendering it as an item + */ + public void setBlockBoundsForItemRender() { + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + } + + /** + * Adds all intersecting collision boxes to a list. (Be sure to only add boxes + * to the list if they intersect the mask.) Parameters: World, X, Y, Z, mask, + * list, colliding entity + */ + public void addCollisionBoxesToList(World par1World, int par2, int par3, int par4, AxisAlignedBB par5AxisAlignedBB, + List par6List, Entity par7Entity) { + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + super.addCollisionBoxesToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity); + } + + /** + * Returns a bounding box from the pool of bounding boxes (this means this box + * can change after the pool has been cleared to be reused) + */ + public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int par4) { + this.setBlockBoundsBasedOnState(par1World, par2, par3, par4); + return super.getCollisionBoundingBoxFromPool(par1World, par2, par3, par4); + } + + /** + * If this block doesn't render as an ordinary block it will return False + * (examples: signs, buttons, stairs, etc) + */ + public boolean renderAsNormalBlock() { + return false; + } + + /** + * returns an int which describes the direction the piston faces + */ + public static int getOrientation(int par0) { + return par0 & 7; + } + + /** + * Determine if the metadata is related to something powered. + */ + public static boolean isExtended(int par0) { + return (par0 & 8) != 0; + } + + /** + * gets the way this piston should face for that entity that placed it. + */ + public static int determineOrientation(World par0World, int par1, int par2, int par3, + EntityLiving par4EntityLiving) { + if (MathHelper.abs((float) par4EntityLiving.posX - (float) par1) < 2.0F + && MathHelper.abs((float) par4EntityLiving.posZ - (float) par3) < 2.0F) { + double var5 = par4EntityLiving.posY + 1.82D - (double) par4EntityLiving.yOffset; + + if (var5 - (double) par2 > 2.0D) { + return 1; + } + + if ((double) par2 - var5 > 0.0D) { + return 0; + } + } + + int var7 = MathHelper.floor_double((double) (par4EntityLiving.rotationYaw * 4.0F / 360.0F) + 0.5D) & 3; + return var7 == 0 ? 2 : (var7 == 1 ? 5 : (var7 == 2 ? 3 : (var7 == 3 ? 4 : 0))); + } + + /** + * returns true if the piston can push the specified block + */ + private static boolean canPushBlock(int par0, World par1World, int par2, int par3, int par4, boolean par5) { + if (par0 == Block.obsidian.blockID) { + return false; + } else { + if (par0 != Block.pistonBase.blockID && par0 != Block.pistonStickyBase.blockID) { + if (Block.blocksList[par0].getBlockHardness(par1World, par2, par3, par4) == -1.0F) { + return false; + } + + if (Block.blocksList[par0].getMobilityFlag() == 2) { + return false; + } + + if (Block.blocksList[par0].getMobilityFlag() == 1) { + if (!par5) { + return false; + } + + return true; + } + } else if (isExtended(par1World.getBlockMetadata(par2, par3, par4))) { + return false; + } + + return !(Block.blocksList[par0] instanceof ITileEntityProvider); + } + } + + /** + * checks to see if this piston could push the blocks in front of it. + */ + private static boolean canExtend(World par0World, int par1, int par2, int par3, int par4) { + int var5 = par1 + Facing.offsetsXForSide[par4]; + int var6 = par2 + Facing.offsetsYForSide[par4]; + int var7 = par3 + Facing.offsetsZForSide[par4]; + int var8 = 0; + + while (true) { + if (var8 < 13) { + if (var6 <= 0 || var6 >= 255) { + return false; + } + + int var9 = par0World.getBlockId(var5, var6, var7); + + if (var9 != 0) { + if (!canPushBlock(var9, par0World, var5, var6, var7, true)) { + return false; + } + + if (Block.blocksList[var9].getMobilityFlag() != 1) { + if (var8 == 12) { + return false; + } + + var5 += Facing.offsetsXForSide[par4]; + var6 += Facing.offsetsYForSide[par4]; + var7 += Facing.offsetsZForSide[par4]; + ++var8; + continue; + } + } + } + + return true; + } + } + + /** + * attempts to extend the piston. returns false if impossible. + */ + private boolean tryExtend(World par1World, int par2, int par3, int par4, int par5) { + int var6 = par2 + Facing.offsetsXForSide[par5]; + int var7 = par3 + Facing.offsetsYForSide[par5]; + int var8 = par4 + Facing.offsetsZForSide[par5]; + int var9 = 0; + + while (true) { + int var10; + + if (var9 < 13) { + if (var7 <= 0 || var7 >= 255) { + return false; + } + + var10 = par1World.getBlockId(var6, var7, var8); + + if (var10 != 0) { + if (!canPushBlock(var10, par1World, var6, var7, var8, true)) { + return false; + } + + if (Block.blocksList[var10].getMobilityFlag() != 1) { + if (var9 == 12) { + return false; + } + + var6 += Facing.offsetsXForSide[par5]; + var7 += Facing.offsetsYForSide[par5]; + var8 += Facing.offsetsZForSide[par5]; + ++var9; + continue; + } + + Block.blocksList[var10].dropBlockAsItem(par1World, var6, var7, var8, + par1World.getBlockMetadata(var6, var7, var8), 0); + par1World.setBlockToAir(var6, var7, var8); + } + } + + var9 = var6; + var10 = var7; + int var11 = var8; + int var12 = 0; + int[] var13; + int var14; + int var15; + int var16; + + for (var13 = new int[13]; var6 != par2 || var7 != par3 || var8 != par4; var8 = var16) { + var14 = var6 - Facing.offsetsXForSide[par5]; + var15 = var7 - Facing.offsetsYForSide[par5]; + var16 = var8 - Facing.offsetsZForSide[par5]; + int var17 = par1World.getBlockId(var14, var15, var16); + int var18 = par1World.getBlockMetadata(var14, var15, var16); + + if (var17 == this.blockID && var14 == par2 && var15 == par3 && var16 == par4) { + par1World.setBlock(var6, var7, var8, Block.pistonMoving.blockID, par5 | (this.isSticky ? 8 : 0), 4); + par1World.setBlockTileEntity(var6, var7, var8, BlockPistonMoving.getTileEntity( + Block.pistonExtension.blockID, par5 | (this.isSticky ? 8 : 0), par5, true, false)); + } else { + par1World.setBlock(var6, var7, var8, Block.pistonMoving.blockID, var18, 4); + par1World.setBlockTileEntity(var6, var7, var8, + BlockPistonMoving.getTileEntity(var17, var18, par5, true, false)); + } + + var13[var12++] = var17; + var6 = var14; + var7 = var15; + } + + var6 = var9; + var7 = var10; + var8 = var11; + + for (var12 = 0; var6 != par2 || var7 != par3 || var8 != par4; var8 = var16) { + var14 = var6 - Facing.offsetsXForSide[par5]; + var15 = var7 - Facing.offsetsYForSide[par5]; + var16 = var8 - Facing.offsetsZForSide[par5]; + par1World.notifyBlocksOfNeighborChange(var14, var15, var16, var13[var12++]); + var6 = var14; + var7 = var15; + } + + return true; + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockPistonExtension.java b/sp-server/src/main/java/net/minecraft/src/BlockPistonExtension.java new file mode 100644 index 0000000..a7de88f --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockPistonExtension.java @@ -0,0 +1,193 @@ +package net.minecraft.src; + +import java.util.List; +import java.util.Random; + +public class BlockPistonExtension extends Block { + /** The texture for the 'head' of the piston. Sticky or normal. */ + private Icon headTexture = null; + + public BlockPistonExtension(int par1) { + super(par1, Material.piston); + this.setStepSound(soundStoneFootstep); + this.setHardness(0.5F); + } + + /** + * ejects contained items into the world, and notifies neighbours of an update, + * as appropriate + */ + public void breakBlock(World par1World, int par2, int par3, int par4, int par5, int par6) { + super.breakBlock(par1World, par2, par3, par4, par5, par6); + int var7 = Facing.oppositeSide[getDirectionMeta(par6)]; + par2 += Facing.offsetsXForSide[var7]; + par3 += Facing.offsetsYForSide[var7]; + par4 += Facing.offsetsZForSide[var7]; + int var8 = par1World.getBlockId(par2, par3, par4); + + if (var8 == Block.pistonBase.blockID || var8 == Block.pistonStickyBase.blockID) { + par6 = par1World.getBlockMetadata(par2, par3, par4); + + if (BlockPistonBase.isExtended(par6)) { + Block.blocksList[var8].dropBlockAsItem(par1World, par2, par3, par4, par6, 0); + par1World.setBlockToAir(par2, par3, par4); + } + } + } + + /** + * The type of render function that is called for this block + */ + public int getRenderType() { + return 17; + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return false; + } + + /** + * If this block doesn't render as an ordinary block it will return False + * (examples: signs, buttons, stairs, etc) + */ + public boolean renderAsNormalBlock() { + return false; + } + + /** + * Checks to see if its valid to put this block at the specified coordinates. + * Args: world, x, y, z + */ + public boolean canPlaceBlockAt(World par1World, int par2, int par3, int par4) { + return false; + } + + /** + * checks to see if you can place this block can be placed on that side of a + * block: BlockLever overrides + */ + public boolean canPlaceBlockOnSide(World par1World, int par2, int par3, int par4, int par5) { + return false; + } + + /** + * Returns the quantity of items to drop on block destruction. + */ + public int quantityDropped(Random par1Random) { + return 0; + } + + /** + * Adds all intersecting collision boxes to a list. (Be sure to only add boxes + * to the list if they intersect the mask.) Parameters: World, X, Y, Z, mask, + * list, colliding entity + */ + public void addCollisionBoxesToList(World par1World, int par2, int par3, int par4, AxisAlignedBB par5AxisAlignedBB, + List par6List, Entity par7Entity) { + int var8 = par1World.getBlockMetadata(par2, par3, par4); + + switch (getDirectionMeta(var8)) { + case 0: + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.25F, 1.0F); + super.addCollisionBoxesToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity); + this.setBlockBounds(0.375F, 0.25F, 0.375F, 0.625F, 1.0F, 0.625F); + super.addCollisionBoxesToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity); + break; + + case 1: + this.setBlockBounds(0.0F, 0.75F, 0.0F, 1.0F, 1.0F, 1.0F); + super.addCollisionBoxesToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity); + this.setBlockBounds(0.375F, 0.0F, 0.375F, 0.625F, 0.75F, 0.625F); + super.addCollisionBoxesToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity); + break; + + case 2: + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 0.25F); + super.addCollisionBoxesToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity); + this.setBlockBounds(0.25F, 0.375F, 0.25F, 0.75F, 0.625F, 1.0F); + super.addCollisionBoxesToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity); + break; + + case 3: + this.setBlockBounds(0.0F, 0.0F, 0.75F, 1.0F, 1.0F, 1.0F); + super.addCollisionBoxesToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity); + this.setBlockBounds(0.25F, 0.375F, 0.0F, 0.75F, 0.625F, 0.75F); + super.addCollisionBoxesToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity); + break; + + case 4: + this.setBlockBounds(0.0F, 0.0F, 0.0F, 0.25F, 1.0F, 1.0F); + super.addCollisionBoxesToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity); + this.setBlockBounds(0.375F, 0.25F, 0.25F, 0.625F, 0.75F, 1.0F); + super.addCollisionBoxesToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity); + break; + + case 5: + this.setBlockBounds(0.75F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + super.addCollisionBoxesToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity); + this.setBlockBounds(0.0F, 0.375F, 0.25F, 0.75F, 0.625F, 0.75F); + super.addCollisionBoxesToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity); + } + + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + } + + /** + * Updates the blocks bounds based on its current state. Args: world, x, y, z + */ + public void setBlockBoundsBasedOnState(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + int var5 = par1IBlockAccess.getBlockMetadata(par2, par3, par4); + + switch (getDirectionMeta(var5)) { + case 0: + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.25F, 1.0F); + break; + + case 1: + this.setBlockBounds(0.0F, 0.75F, 0.0F, 1.0F, 1.0F, 1.0F); + break; + + case 2: + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 0.25F); + break; + + case 3: + this.setBlockBounds(0.0F, 0.0F, 0.75F, 1.0F, 1.0F, 1.0F); + break; + + case 4: + this.setBlockBounds(0.0F, 0.0F, 0.0F, 0.25F, 1.0F, 1.0F); + break; + + case 5: + this.setBlockBounds(0.75F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + } + } + + /** + * Lets the block know when one of its neighbor changes. Doesn't know which + * neighbor changed (coordinates passed are their own) Args: x, y, z, neighbor + * blockID + */ + public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5) { + int var6 = getDirectionMeta(par1World.getBlockMetadata(par2, par3, par4)); + int var7 = par1World.getBlockId(par2 - Facing.offsetsXForSide[var6], par3 - Facing.offsetsYForSide[var6], + par4 - Facing.offsetsZForSide[var6]); + + if (var7 != Block.pistonBase.blockID && var7 != Block.pistonStickyBase.blockID) { + par1World.setBlockToAir(par2, par3, par4); + } else { + Block.blocksList[var7].onNeighborBlockChange(par1World, par2 - Facing.offsetsXForSide[var6], + par3 - Facing.offsetsYForSide[var6], par4 - Facing.offsetsZForSide[var6], par5); + } + } + + public static int getDirectionMeta(int par0) { + return par0 & 7; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockPistonMoving.java b/sp-server/src/main/java/net/minecraft/src/BlockPistonMoving.java new file mode 100644 index 0000000..7841be9 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockPistonMoving.java @@ -0,0 +1,223 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockPistonMoving extends BlockContainer { + public BlockPistonMoving(int par1) { + super(par1, Material.piston); + this.setHardness(-1.0F); + } + + /** + * Returns a new instance of a block's tile entity class. Called on placing the + * block. + */ + public TileEntity createNewTileEntity(World par1World) { + return null; + } + + /** + * Called whenever the block is added into the world. Args: world, x, y, z + */ + public void onBlockAdded(World par1World, int par2, int par3, int par4) { + } + + /** + * ejects contained items into the world, and notifies neighbours of an update, + * as appropriate + */ + public void breakBlock(World par1World, int par2, int par3, int par4, int par5, int par6) { + TileEntity var7 = par1World.getBlockTileEntity(par2, par3, par4); + + if (var7 instanceof TileEntityPiston) { + ((TileEntityPiston) var7).clearPistonTileEntity(); + } else { + super.breakBlock(par1World, par2, par3, par4, par5, par6); + } + } + + /** + * Checks to see if its valid to put this block at the specified coordinates. + * Args: world, x, y, z + */ + public boolean canPlaceBlockAt(World par1World, int par2, int par3, int par4) { + return false; + } + + /** + * checks to see if you can place this block can be placed on that side of a + * block: BlockLever overrides + */ + public boolean canPlaceBlockOnSide(World par1World, int par2, int par3, int par4, int par5) { + return false; + } + + /** + * The type of render function that is called for this block + */ + public int getRenderType() { + return -1; + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return false; + } + + /** + * If this block doesn't render as an ordinary block it will return False + * (examples: signs, buttons, stairs, etc) + */ + public boolean renderAsNormalBlock() { + return false; + } + + /** + * Called upon block activation (right click on the block.) + */ + public boolean onBlockActivated(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer, + int par6, float par7, float par8, float par9) { + if (!par1World.isRemote && par1World.getBlockTileEntity(par2, par3, par4) == null) { + par1World.setBlockToAir(par2, par3, par4); + return true; + } else { + return false; + } + } + + /** + * Returns the ID of the items to drop on destruction. + */ + public int idDropped(int par1, Random par2Random, int par3) { + return 0; + } + + /** + * Drops the block items with a specified chance of dropping the specified items + */ + public void dropBlockAsItemWithChance(World par1World, int par2, int par3, int par4, int par5, float par6, + int par7) { + if (!par1World.isRemote) { + TileEntityPiston var8 = this.getTileEntityAtLocation(par1World, par2, par3, par4); + + if (var8 != null) { + Block.blocksList[var8.getStoredBlockID()].dropBlockAsItem(par1World, par2, par3, par4, + var8.getBlockMetadata(), 0); + } + } + } + + /** + * Lets the block know when one of its neighbor changes. Doesn't know which + * neighbor changed (coordinates passed are their own) Args: x, y, z, neighbor + * blockID + */ + public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5) { + if (!par1World.isRemote && par1World.getBlockTileEntity(par2, par3, par4) == null) { + ; + } + } + + /** + * gets a new TileEntityPiston created with the arguments provided. + */ + public static TileEntity getTileEntity(int par0, int par1, int par2, boolean par3, boolean par4) { + return new TileEntityPiston(par0, par1, par2, par3, par4); + } + + /** + * Returns a bounding box from the pool of bounding boxes (this means this box + * can change after the pool has been cleared to be reused) + */ + public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int par4) { + TileEntityPiston var5 = this.getTileEntityAtLocation(par1World, par2, par3, par4); + + if (var5 == null) { + return null; + } else { + float var6 = var5.getProgress(0.0F); + + if (var5.isExtending()) { + var6 = 1.0F - var6; + } + + return this.getAxisAlignedBB(par1World, par2, par3, par4, var5.getStoredBlockID(), var6, + var5.getPistonOrientation()); + } + } + + /** + * Updates the blocks bounds based on its current state. Args: world, x, y, z + */ + public void setBlockBoundsBasedOnState(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + TileEntityPiston var5 = this.getTileEntityAtLocation(par1IBlockAccess, par2, par3, par4); + + if (var5 != null) { + Block var6 = Block.blocksList[var5.getStoredBlockID()]; + + if (var6 == null || var6 == this) { + return; + } + + var6.setBlockBoundsBasedOnState(par1IBlockAccess, par2, par3, par4); + float var7 = var5.getProgress(0.0F); + + if (var5.isExtending()) { + var7 = 1.0F - var7; + } + + int var8 = var5.getPistonOrientation(); + this.minX = var6.getMinX() - (double) ((float) Facing.offsetsXForSide[var8] * var7); + this.minY = var6.getBlockBoundsMinY() - (double) ((float) Facing.offsetsYForSide[var8] * var7); + this.minZ = var6.getBlockBoundsMinZ() - (double) ((float) Facing.offsetsZForSide[var8] * var7); + this.maxX = var6.getBlockBoundsMaxX() - (double) ((float) Facing.offsetsXForSide[var8] * var7); + this.maxY = var6.getBlockBoundsMaxY() - (double) ((float) Facing.offsetsYForSide[var8] * var7); + this.maxZ = var6.getBlockBoundsMaxZ() - (double) ((float) Facing.offsetsZForSide[var8] * var7); + } + } + + public AxisAlignedBB getAxisAlignedBB(World par1World, int par2, int par3, int par4, int par5, float par6, + int par7) { + if (par5 != 0 && par5 != this.blockID) { + AxisAlignedBB var8 = Block.blocksList[par5].getCollisionBoundingBoxFromPool(par1World, par2, par3, par4); + + if (var8 == null) { + return null; + } else { + if (Facing.offsetsXForSide[par7] < 0) { + var8.minX -= (double) ((float) Facing.offsetsXForSide[par7] * par6); + } else { + var8.maxX -= (double) ((float) Facing.offsetsXForSide[par7] * par6); + } + + if (Facing.offsetsYForSide[par7] < 0) { + var8.minY -= (double) ((float) Facing.offsetsYForSide[par7] * par6); + } else { + var8.maxY -= (double) ((float) Facing.offsetsYForSide[par7] * par6); + } + + if (Facing.offsetsZForSide[par7] < 0) { + var8.minZ -= (double) ((float) Facing.offsetsZForSide[par7] * par6); + } else { + var8.maxZ -= (double) ((float) Facing.offsetsZForSide[par7] * par6); + } + + return var8; + } + } else { + return null; + } + } + + /** + * gets the piston tile entity at the specified location + */ + private TileEntityPiston getTileEntityAtLocation(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + TileEntity var5 = par1IBlockAccess.getBlockTileEntity(par2, par3, par4); + return var5 instanceof TileEntityPiston ? (TileEntityPiston) var5 : null; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockPortal.java b/sp-server/src/main/java/net/minecraft/src/BlockPortal.java new file mode 100644 index 0000000..4aa6663 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockPortal.java @@ -0,0 +1,204 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockPortal extends BlockBreakable { + public BlockPortal(int par1) { + super(par1, "portal", Material.portal, false); + this.setTickRandomly(true); + } + + /** + * Ticks the block if it's been scheduled + */ + public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random) { + super.updateTick(par1World, par2, par3, par4, par5Random); + + if (par1World.provider.isSurfaceWorld() && par5Random.nextInt(2000) < par1World.difficultySetting) { + int var6; + + for (var6 = par3; !par1World.doesBlockHaveSolidTopSurface(par2, var6, par4) && var6 > 0; --var6) { + ; + } + + if (var6 > 0 && !par1World.isBlockNormalCube(par2, var6 + 1, par4)) { + Entity var7 = ItemMonsterPlacer.spawnCreature(par1World, 57, (double) par2 + 0.5D, (double) var6 + 1.1D, + (double) par4 + 0.5D); + + if (var7 != null) { + var7.timeUntilPortal = var7.getPortalCooldown(); + } + } + } + } + + /** + * Returns a bounding box from the pool of bounding boxes (this means this box + * can change after the pool has been cleared to be reused) + */ + public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int par4) { + return null; + } + + /** + * Updates the blocks bounds based on its current state. Args: world, x, y, z + */ + public void setBlockBoundsBasedOnState(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + float var5; + float var6; + + if (par1IBlockAccess.getBlockId(par2 - 1, par3, par4) != this.blockID + && par1IBlockAccess.getBlockId(par2 + 1, par3, par4) != this.blockID) { + var5 = 0.125F; + var6 = 0.5F; + this.setBlockBounds(0.5F - var5, 0.0F, 0.5F - var6, 0.5F + var5, 1.0F, 0.5F + var6); + } else { + var5 = 0.5F; + var6 = 0.125F; + this.setBlockBounds(0.5F - var5, 0.0F, 0.5F - var6, 0.5F + var5, 1.0F, 0.5F + var6); + } + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return false; + } + + /** + * If this block doesn't render as an ordinary block it will return False + * (examples: signs, buttons, stairs, etc) + */ + public boolean renderAsNormalBlock() { + return false; + } + + /** + * Checks to see if this location is valid to create a portal and will return + * True if it does. Args: world, x, y, z + */ + public boolean tryToCreatePortal(World par1World, int par2, int par3, int par4) { + byte var5 = 0; + byte var6 = 0; + + if (par1World.getBlockId(par2 - 1, par3, par4) == Block.obsidian.blockID + || par1World.getBlockId(par2 + 1, par3, par4) == Block.obsidian.blockID) { + var5 = 1; + } + + if (par1World.getBlockId(par2, par3, par4 - 1) == Block.obsidian.blockID + || par1World.getBlockId(par2, par3, par4 + 1) == Block.obsidian.blockID) { + var6 = 1; + } + + if (var5 == var6) { + return false; + } else { + if (par1World.getBlockId(par2 - var5, par3, par4 - var6) == 0) { + par2 -= var5; + par4 -= var6; + } + + int var7; + int var8; + + for (var7 = -1; var7 <= 2; ++var7) { + for (var8 = -1; var8 <= 3; ++var8) { + boolean var9 = var7 == -1 || var7 == 2 || var8 == -1 || var8 == 3; + + if (var7 != -1 && var7 != 2 || var8 != -1 && var8 != 3) { + int var10 = par1World.getBlockId(par2 + var5 * var7, par3 + var8, par4 + var6 * var7); + + if (var9) { + if (var10 != Block.obsidian.blockID) { + return false; + } + } else if (var10 != 0 && var10 != Block.fire.blockID) { + return false; + } + } + } + } + + for (var7 = 0; var7 < 2; ++var7) { + for (var8 = 0; var8 < 3; ++var8) { + par1World.setBlock(par2 + var5 * var7, par3 + var8, par4 + var6 * var7, Block.portal.blockID, 0, 2); + } + } + + return true; + } + } + + /** + * Lets the block know when one of its neighbor changes. Doesn't know which + * neighbor changed (coordinates passed are their own) Args: x, y, z, neighbor + * blockID + */ + public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5) { + byte var6 = 0; + byte var7 = 1; + + if (par1World.getBlockId(par2 - 1, par3, par4) == this.blockID + || par1World.getBlockId(par2 + 1, par3, par4) == this.blockID) { + var6 = 1; + var7 = 0; + } + + int var8; + + for (var8 = par3; par1World.getBlockId(par2, var8 - 1, par4) == this.blockID; --var8) { + ; + } + + if (par1World.getBlockId(par2, var8 - 1, par4) != Block.obsidian.blockID) { + par1World.setBlockToAir(par2, par3, par4); + } else { + int var9; + + for (var9 = 1; var9 < 4 && par1World.getBlockId(par2, var8 + var9, par4) == this.blockID; ++var9) { + ; + } + + if (var9 == 3 && par1World.getBlockId(par2, var8 + var9, par4) == Block.obsidian.blockID) { + boolean var10 = par1World.getBlockId(par2 - 1, par3, par4) == this.blockID + || par1World.getBlockId(par2 + 1, par3, par4) == this.blockID; + boolean var11 = par1World.getBlockId(par2, par3, par4 - 1) == this.blockID + || par1World.getBlockId(par2, par3, par4 + 1) == this.blockID; + + if (var10 && var11) { + par1World.setBlockToAir(par2, par3, par4); + } else { + if ((par1World.getBlockId(par2 + var6, par3, par4 + var7) != Block.obsidian.blockID + || par1World.getBlockId(par2 - var6, par3, par4 - var7) != this.blockID) + && (par1World.getBlockId(par2 - var6, par3, par4 - var7) != Block.obsidian.blockID + || par1World.getBlockId(par2 + var6, par3, par4 + var7) != this.blockID)) { + par1World.setBlockToAir(par2, par3, par4); + } + } + } else { + par1World.setBlockToAir(par2, par3, par4); + } + } + } + + /** + * Returns the quantity of items to drop on block destruction. + */ + public int quantityDropped(Random par1Random) { + return 0; + } + + /** + * Triggered whenever an entity collides with this block (enters into the + * block). Args: world, x, y, z, entity + */ + public void onEntityCollidedWithBlock(World par1World, int par2, int par3, int par4, Entity par5Entity) { + if (par5Entity.ridingEntity == null && par5Entity.riddenByEntity == null) { + par5Entity.setInPortal(); + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockPotato.java b/sp-server/src/main/java/net/minecraft/src/BlockPotato.java new file mode 100644 index 0000000..2bd6d9f --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockPotato.java @@ -0,0 +1,35 @@ +package net.minecraft.src; + +public class BlockPotato extends BlockCrops { + public BlockPotato(int par1) { + super(par1); + } + + /** + * Generate a seed ItemStack for this crop. + */ + protected int getSeedItem() { + return Item.potato.itemID; + } + + /** + * Generate a crop produce ItemStack for this crop. + */ + protected int getCropItem() { + return Item.potato.itemID; + } + + /** + * Drops the block items with a specified chance of dropping the specified items + */ + public void dropBlockAsItemWithChance(World par1World, int par2, int par3, int par4, int par5, float par6, + int par7) { + super.dropBlockAsItemWithChance(par1World, par2, par3, par4, par5, par6, par7); + + if (!par1World.isRemote) { + if (par5 >= 7 && par1World.rand.nextInt(50) == 0) { + this.dropBlockAsItem_do(par1World, par2, par3, par4, new ItemStack(Item.poisonousPotato)); + } + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockPoweredOre.java b/sp-server/src/main/java/net/minecraft/src/BlockPoweredOre.java new file mode 100644 index 0000000..fba795c --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockPoweredOre.java @@ -0,0 +1,27 @@ +package net.minecraft.src; + +public class BlockPoweredOre extends BlockOreStorage { + public BlockPoweredOre(int par1) { + super(par1); + this.setCreativeTab(CreativeTabs.tabRedstone); + } + + /** + * Can this block provide power. Only wire currently seems to have this change + * based on its state. + */ + public boolean canProvidePower() { + return true; + } + + /** + * Returns true if the block is emitting indirect/weak redstone power on the + * specified side. If isBlockNormalCube returns true, standard redstone + * propagation rules will apply instead and this will not be called. Args: + * World, X, Y, Z, side. Note that the side is reversed - eg it is 1 (up) when + * checking the bottom of the block. + */ + public int isProvidingWeakPower(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5) { + return 15; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockPressurePlate.java b/sp-server/src/main/java/net/minecraft/src/BlockPressurePlate.java new file mode 100644 index 0000000..0ff7df0 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockPressurePlate.java @@ -0,0 +1,63 @@ +package net.minecraft.src; + +import java.util.Iterator; +import java.util.List; + +public class BlockPressurePlate extends BlockBasePressurePlate { + /** The mob type that can trigger this pressure plate. */ + private EnumMobType triggerMobType; + + protected BlockPressurePlate(int par1, String par2Str, Material par3Material, EnumMobType par4EnumMobType) { + super(par1, par2Str, par3Material); + this.triggerMobType = par4EnumMobType; + } + + /** + * Argument is weight (0-15). Return the metadata to be set because of it. + */ + protected int getMetaFromWeight(int par1) { + return par1 > 0 ? 1 : 0; + } + + /** + * Argument is metadata. Returns power level (0-15) + */ + protected int getPowerSupply(int par1) { + return par1 == 1 ? 15 : 0; + } + + /** + * Returns the current state of the pressure plate. Returns a value between 0 + * and 15 based on the number of items on it. + */ + protected int getPlateState(World par1World, int par2, int par3, int par4) { + List var5 = null; + + if (this.triggerMobType == EnumMobType.everything) { + var5 = par1World.getEntitiesWithinAABBExcludingEntity((Entity) null, + this.getSensitiveAABB(par2, par3, par4)); + } + + if (this.triggerMobType == EnumMobType.mobs) { + var5 = par1World.getEntitiesWithinAABB(EntityLiving.class, this.getSensitiveAABB(par2, par3, par4)); + } + + if (this.triggerMobType == EnumMobType.players) { + var5 = par1World.getEntitiesWithinAABB(EntityPlayer.class, this.getSensitiveAABB(par2, par3, par4)); + } + + if (!var5.isEmpty()) { + Iterator var6 = var5.iterator(); + + while (var6.hasNext()) { + Entity var7 = (Entity) var6.next(); + + if (!var7.doesEntityNotTriggerPressurePlate()) { + return 15; + } + } + } + + return 0; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockPressurePlateWeighted.java b/sp-server/src/main/java/net/minecraft/src/BlockPressurePlateWeighted.java new file mode 100644 index 0000000..3aa341c --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockPressurePlateWeighted.java @@ -0,0 +1,60 @@ +package net.minecraft.src; + +import java.util.Iterator; + +public class BlockPressurePlateWeighted extends BlockBasePressurePlate { + /** The maximum number of items the plate weights. */ + private final int maxItemsWeighted; + + protected BlockPressurePlateWeighted(int par1, String par2Str, Material par3Material, int par4) { + super(par1, par2Str, par3Material); + this.maxItemsWeighted = par4; + } + + /** + * Returns the current state of the pressure plate. Returns a value between 0 + * and 15 based on the number of items on it. + */ + protected int getPlateState(World par1World, int par2, int par3, int par4) { + int var5 = 0; + Iterator var6 = par1World.getEntitiesWithinAABB(EntityItem.class, this.getSensitiveAABB(par2, par3, par4)) + .iterator(); + + while (var6.hasNext()) { + EntityItem var7 = (EntityItem) var6.next(); + var5 += var7.getEntityItem().stackSize; + + if (var5 >= this.maxItemsWeighted) { + break; + } + } + + if (var5 <= 0) { + return 0; + } else { + float var8 = (float) Math.min(this.maxItemsWeighted, var5) / (float) this.maxItemsWeighted; + return MathHelper.ceiling_float_int(var8 * 15.0F); + } + } + + /** + * Argument is metadata. Returns power level (0-15) + */ + protected int getPowerSupply(int par1) { + return par1; + } + + /** + * Argument is weight (0-15). Return the metadata to be set because of it. + */ + protected int getMetaFromWeight(int par1) { + return par1; + } + + /** + * How many world ticks before ticking + */ + public int tickRate(World par1World) { + return 10; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockPumpkin.java b/sp-server/src/main/java/net/minecraft/src/BlockPumpkin.java new file mode 100644 index 0000000..5347c58 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockPumpkin.java @@ -0,0 +1,105 @@ +package net.minecraft.src; + +public class BlockPumpkin extends BlockDirectional { + /** Boolean used to seperate different states of blocks */ + private boolean blockType; + + protected BlockPumpkin(int par1, boolean par2) { + super(par1, Material.pumpkin); + this.setTickRandomly(true); + this.blockType = par2; + this.setCreativeTab(CreativeTabs.tabBlock); + } + + /** + * Called whenever the block is added into the world. Args: world, x, y, z + */ + public void onBlockAdded(World par1World, int par2, int par3, int par4) { + super.onBlockAdded(par1World, par2, par3, par4); + + if (par1World.getBlockId(par2, par3 - 1, par4) == Block.blockSnow.blockID + && par1World.getBlockId(par2, par3 - 2, par4) == Block.blockSnow.blockID) { + if (!par1World.isRemote) { + par1World.setBlock(par2, par3, par4, 0, 0, 2); + par1World.setBlock(par2, par3 - 1, par4, 0, 0, 2); + par1World.setBlock(par2, par3 - 2, par4, 0, 0, 2); + EntitySnowman var9 = new EntitySnowman(par1World); + var9.setLocationAndAngles((double) par2 + 0.5D, (double) par3 - 1.95D, (double) par4 + 0.5D, 0.0F, + 0.0F); + par1World.spawnEntityInWorld(var9); + par1World.notifyBlockChange(par2, par3, par4, 0); + par1World.notifyBlockChange(par2, par3 - 1, par4, 0); + par1World.notifyBlockChange(par2, par3 - 2, par4, 0); + } + + for (int var10 = 0; var10 < 120; ++var10) { + par1World.spawnParticle("snowshovel", (double) par2 + par1World.rand.nextDouble(), + (double) (par3 - 2) + par1World.rand.nextDouble() * 2.5D, + (double) par4 + par1World.rand.nextDouble(), 0.0D, 0.0D, 0.0D); + } + } else if (par1World.getBlockId(par2, par3 - 1, par4) == Block.blockIron.blockID + && par1World.getBlockId(par2, par3 - 2, par4) == Block.blockIron.blockID) { + boolean var5 = par1World.getBlockId(par2 - 1, par3 - 1, par4) == Block.blockIron.blockID + && par1World.getBlockId(par2 + 1, par3 - 1, par4) == Block.blockIron.blockID; + boolean var6 = par1World.getBlockId(par2, par3 - 1, par4 - 1) == Block.blockIron.blockID + && par1World.getBlockId(par2, par3 - 1, par4 + 1) == Block.blockIron.blockID; + + if (var5 || var6) { + par1World.setBlock(par2, par3, par4, 0, 0, 2); + par1World.setBlock(par2, par3 - 1, par4, 0, 0, 2); + par1World.setBlock(par2, par3 - 2, par4, 0, 0, 2); + + if (var5) { + par1World.setBlock(par2 - 1, par3 - 1, par4, 0, 0, 2); + par1World.setBlock(par2 + 1, par3 - 1, par4, 0, 0, 2); + } else { + par1World.setBlock(par2, par3 - 1, par4 - 1, 0, 0, 2); + par1World.setBlock(par2, par3 - 1, par4 + 1, 0, 0, 2); + } + + EntityIronGolem var7 = new EntityIronGolem(par1World); + var7.setPlayerCreated(true); + var7.setLocationAndAngles((double) par2 + 0.5D, (double) par3 - 1.95D, (double) par4 + 0.5D, 0.0F, + 0.0F); + par1World.spawnEntityInWorld(var7); + + for (int var8 = 0; var8 < 120; ++var8) { + par1World.spawnParticle("snowballpoof", (double) par2 + par1World.rand.nextDouble(), + (double) (par3 - 2) + par1World.rand.nextDouble() * 3.9D, + (double) par4 + par1World.rand.nextDouble(), 0.0D, 0.0D, 0.0D); + } + + par1World.notifyBlockChange(par2, par3, par4, 0); + par1World.notifyBlockChange(par2, par3 - 1, par4, 0); + par1World.notifyBlockChange(par2, par3 - 2, par4, 0); + + if (var5) { + par1World.notifyBlockChange(par2 - 1, par3 - 1, par4, 0); + par1World.notifyBlockChange(par2 + 1, par3 - 1, par4, 0); + } else { + par1World.notifyBlockChange(par2, par3 - 1, par4 - 1, 0); + par1World.notifyBlockChange(par2, par3 - 1, par4 + 1, 0); + } + } + } + } + + /** + * Checks to see if its valid to put this block at the specified coordinates. + * Args: world, x, y, z + */ + public boolean canPlaceBlockAt(World par1World, int par2, int par3, int par4) { + int var5 = par1World.getBlockId(par2, par3, par4); + return (var5 == 0 || Block.blocksList[var5].blockMaterial.isReplaceable()) + && par1World.doesBlockHaveSolidTopSurface(par2, par3 - 1, par4); + } + + /** + * Called when the block is placed in the world. + */ + public void onBlockPlacedBy(World par1World, int par2, int par3, int par4, EntityLiving par5EntityLiving, + ItemStack par6ItemStack) { + int var7 = MathHelper.floor_double((double) (par5EntityLiving.rotationYaw * 4.0F / 360.0F) + 2.5D) & 3; + par1World.setBlockMetadata(par2, par3, par4, var7, 2); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockQuartz.java b/sp-server/src/main/java/net/minecraft/src/BlockQuartz.java new file mode 100644 index 0000000..4328897 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockQuartz.java @@ -0,0 +1,62 @@ +package net.minecraft.src; + +public class BlockQuartz extends Block { + public static final String[] quartzBlockTypes = new String[] { "default", "chiseled", "lines" }; + private static final String[] quartzBlockTextureTypes = new String[] { "quartzblock_side", "quartzblock_chiseled", + "quartzblock_lines", null, null }; + + public BlockQuartz(int par1) { + super(par1, Material.rock); + this.setCreativeTab(CreativeTabs.tabBlock); + } + + /** + * Called when a block is placed using its ItemBlock. Args: World, X, Y, Z, + * side, hitX, hitY, hitZ, block metadata + */ + public int onBlockPlaced(World par1World, int par2, int par3, int par4, int par5, float par6, float par7, + float par8, int par9) { + if (par9 == 2) { + switch (par5) { + case 0: + case 1: + par9 = 2; + break; + + case 2: + case 3: + par9 = 4; + break; + + case 4: + case 5: + par9 = 3; + } + } + + return par9; + } + + /** + * Determines the damage on the item the block drops. Used in cloth and wood. + */ + public int damageDropped(int par1) { + return par1 != 3 && par1 != 4 ? par1 : 2; + } + + /** + * Returns an item stack containing a single instance of the current block type. + * 'i' is the block's subtype/damage and is ignored for blocks which do not + * support subtypes. Blocks which cannot be harvested should return null. + */ + protected ItemStack createStackedBlock(int par1) { + return par1 != 3 && par1 != 4 ? super.createStackedBlock(par1) : new ItemStack(this.blockID, 1, 2); + } + + /** + * The type of render function that is called for this block + */ + public int getRenderType() { + return 39; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockRail.java b/sp-server/src/main/java/net/minecraft/src/BlockRail.java new file mode 100644 index 0000000..fc997fb --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockRail.java @@ -0,0 +1,14 @@ +package net.minecraft.src; + +public class BlockRail extends BlockRailBase { + protected BlockRail(int par1) { + super(par1, false); + } + + protected void func_94358_a(World par1World, int par2, int par3, int par4, int par5, int par6, int par7) { + if (par7 > 0 && Block.blocksList[par7].canProvidePower() + && (new BlockBaseRailLogic(this, par1World, par2, par3, par4)).getNumberOfAdjacentTracks() == 3) { + this.refreshTrackShape(par1World, par2, par3, par4, false); + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockRailBase.java b/sp-server/src/main/java/net/minecraft/src/BlockRailBase.java new file mode 100644 index 0000000..171ff10 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockRailBase.java @@ -0,0 +1,211 @@ +package net.minecraft.src; + +import java.util.Random; + +public abstract class BlockRailBase extends Block { + /** Power related rails have this field at true. */ + protected final boolean isPowered; + + /** + * Returns true if the block at the coordinates of world passed is a valid rail + * block (current is rail, powered or detector). + */ + public static final boolean isRailBlockAt(World par0World, int par1, int par2, int par3) { + return isRailBlock(par0World.getBlockId(par1, par2, par3)); + } + + /** + * Return true if the parameter is a blockID for a valid rail block (current is + * rail, powered or detector). + */ + public static final boolean isRailBlock(int par0) { + return par0 == Block.rail.blockID || par0 == Block.railPowered.blockID || par0 == Block.railDetector.blockID + || par0 == Block.railActivator.blockID; + } + + protected BlockRailBase(int par1, boolean par2) { + super(par1, Material.circuits); + this.isPowered = par2; + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.125F, 1.0F); + this.setCreativeTab(CreativeTabs.tabTransport); + } + + /** + * Returns true if the block is power related rail. + */ + public boolean isPowered() { + return this.isPowered; + } + + /** + * Returns a bounding box from the pool of bounding boxes (this means this box + * can change after the pool has been cleared to be reused) + */ + public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int par4) { + return null; + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return false; + } + + /** + * Ray traces through the blocks collision from start vector to end vector + * returning a ray trace hit. Args: world, x, y, z, startVec, endVec + */ + public MovingObjectPosition collisionRayTrace(World par1World, int par2, int par3, int par4, Vec3 par5Vec3, + Vec3 par6Vec3) { + this.setBlockBoundsBasedOnState(par1World, par2, par3, par4); + return super.collisionRayTrace(par1World, par2, par3, par4, par5Vec3, par6Vec3); + } + + /** + * Updates the blocks bounds based on its current state. Args: world, x, y, z + */ + public void setBlockBoundsBasedOnState(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + int var5 = par1IBlockAccess.getBlockMetadata(par2, par3, par4); + + if (var5 >= 2 && var5 <= 5) { + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.625F, 1.0F); + } else { + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.125F, 1.0F); + } + } + + /** + * If this block doesn't render as an ordinary block it will return False + * (examples: signs, buttons, stairs, etc) + */ + public boolean renderAsNormalBlock() { + return false; + } + + /** + * The type of render function that is called for this block + */ + public int getRenderType() { + return 9; + } + + /** + * Returns the quantity of items to drop on block destruction. + */ + public int quantityDropped(Random par1Random) { + return 1; + } + + /** + * Checks to see if its valid to put this block at the specified coordinates. + * Args: world, x, y, z + */ + public boolean canPlaceBlockAt(World par1World, int par2, int par3, int par4) { + return par1World.doesBlockHaveSolidTopSurface(par2, par3 - 1, par4); + } + + /** + * Called whenever the block is added into the world. Args: world, x, y, z + */ + public void onBlockAdded(World par1World, int par2, int par3, int par4) { + if (!par1World.isRemote) { + this.refreshTrackShape(par1World, par2, par3, par4, true); + + if (this.isPowered) { + this.onNeighborBlockChange(par1World, par2, par3, par4, this.blockID); + } + } + } + + /** + * Lets the block know when one of its neighbor changes. Doesn't know which + * neighbor changed (coordinates passed are their own) Args: x, y, z, neighbor + * blockID + */ + public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5) { + if (!par1World.isRemote) { + int var6 = par1World.getBlockMetadata(par2, par3, par4); + int var7 = var6; + + if (this.isPowered) { + var7 = var6 & 7; + } + + boolean var8 = false; + + if (!par1World.doesBlockHaveSolidTopSurface(par2, par3 - 1, par4)) { + var8 = true; + } + + if (var7 == 2 && !par1World.doesBlockHaveSolidTopSurface(par2 + 1, par3, par4)) { + var8 = true; + } + + if (var7 == 3 && !par1World.doesBlockHaveSolidTopSurface(par2 - 1, par3, par4)) { + var8 = true; + } + + if (var7 == 4 && !par1World.doesBlockHaveSolidTopSurface(par2, par3, par4 - 1)) { + var8 = true; + } + + if (var7 == 5 && !par1World.doesBlockHaveSolidTopSurface(par2, par3, par4 + 1)) { + var8 = true; + } + + if (var8) { + this.dropBlockAsItem(par1World, par2, par3, par4, par1World.getBlockMetadata(par2, par3, par4), 0); + par1World.setBlockToAir(par2, par3, par4); + } else { + this.func_94358_a(par1World, par2, par3, par4, var6, var7, par5); + } + } + } + + protected void func_94358_a(World par1World, int par2, int par3, int par4, int par5, int par6, int par7) { + } + + /** + * Completely recalculates the track shape based on neighboring tracks + */ + protected void refreshTrackShape(World par1World, int par2, int par3, int par4, boolean par5) { + if (!par1World.isRemote) { + (new BlockBaseRailLogic(this, par1World, par2, par3, par4)) + .func_94511_a(par1World.isBlockIndirectlyGettingPowered(par2, par3, par4), par5); + } + } + + /** + * Returns the mobility information of the block, 0 = free, 1 = can't push but + * can move over, 2 = total immobility and stop pistons + */ + public int getMobilityFlag() { + return 0; + } + + /** + * ejects contained items into the world, and notifies neighbours of an update, + * as appropriate + */ + public void breakBlock(World par1World, int par2, int par3, int par4, int par5, int par6) { + int var7 = par6; + + if (this.isPowered) { + var7 = par6 & 7; + } + + super.breakBlock(par1World, par2, par3, par4, par5, par6); + + if (var7 == 2 || var7 == 3 || var7 == 4 || var7 == 5) { + par1World.notifyBlocksOfNeighborChange(par2, par3 + 1, par4, par5); + } + + if (this.isPowered) { + par1World.notifyBlocksOfNeighborChange(par2, par3, par4, par5); + par1World.notifyBlocksOfNeighborChange(par2, par3 - 1, par4, par5); + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockRailPowered.java b/sp-server/src/main/java/net/minecraft/src/BlockRailPowered.java new file mode 100644 index 0000000..da42353 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockRailPowered.java @@ -0,0 +1,136 @@ +package net.minecraft.src; + +public class BlockRailPowered extends BlockRailBase { + protected BlockRailPowered(int par1) { + super(par1, true); + } + + protected boolean func_94360_a(World par1World, int par2, int par3, int par4, int par5, boolean par6, int par7) { + if (par7 >= 8) { + return false; + } else { + int var8 = par5 & 7; + boolean var9 = true; + + switch (var8) { + case 0: + if (par6) { + ++par4; + } else { + --par4; + } + + break; + + case 1: + if (par6) { + --par2; + } else { + ++par2; + } + + break; + + case 2: + if (par6) { + --par2; + } else { + ++par2; + ++par3; + var9 = false; + } + + var8 = 1; + break; + + case 3: + if (par6) { + --par2; + ++par3; + var9 = false; + } else { + ++par2; + } + + var8 = 1; + break; + + case 4: + if (par6) { + ++par4; + } else { + --par4; + ++par3; + var9 = false; + } + + var8 = 0; + break; + + case 5: + if (par6) { + ++par4; + ++par3; + var9 = false; + } else { + --par4; + } + + var8 = 0; + } + + return this.func_94361_a(par1World, par2, par3, par4, par6, par7, var8) ? true + : var9 && this.func_94361_a(par1World, par2, par3 - 1, par4, par6, par7, var8); + } + } + + protected boolean func_94361_a(World par1World, int par2, int par3, int par4, boolean par5, int par6, int par7) { + int var8 = par1World.getBlockId(par2, par3, par4); + + if (var8 == this.blockID) { + int var9 = par1World.getBlockMetadata(par2, par3, par4); + int var10 = var9 & 7; + + if (par7 == 1 && (var10 == 0 || var10 == 4 || var10 == 5)) { + return false; + } + + if (par7 == 0 && (var10 == 1 || var10 == 2 || var10 == 3)) { + return false; + } + + if ((var9 & 8) != 0) { + if (par1World.isBlockIndirectlyGettingPowered(par2, par3, par4)) { + return true; + } + + return this.func_94360_a(par1World, par2, par3, par4, var9, par5, par6 + 1); + } + } + + return false; + } + + protected void func_94358_a(World par1World, int par2, int par3, int par4, int par5, int par6, int par7) { + boolean var8 = par1World.isBlockIndirectlyGettingPowered(par2, par3, par4); + var8 = var8 || this.func_94360_a(par1World, par2, par3, par4, par5, true, 0) + || this.func_94360_a(par1World, par2, par3, par4, par5, false, 0); + boolean var9 = false; + + if (var8 && (par5 & 8) == 0) { + par1World.setBlockMetadata(par2, par3, par4, par6 | 8, 3); + var9 = true; + } else if (!var8 && (par5 & 8) != 0) { + par1World.setBlockMetadata(par2, par3, par4, par6, 3); + var9 = true; + } + + if (var9) { + par1World.notifyBlocksOfNeighborChange(par2, par3 - 1, par4, this.blockID); + + if (par6 == 2 || par6 == 3 || par6 == 4 || par6 == 5) { + par1World.notifyBlocksOfNeighborChange(par2, par3 + 1, par4, this.blockID); + } + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockRedstoneLight.java b/sp-server/src/main/java/net/minecraft/src/BlockRedstoneLight.java new file mode 100644 index 0000000..7288718 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockRedstoneLight.java @@ -0,0 +1,61 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockRedstoneLight extends Block { + /** Whether this lamp block is the powered version. */ + private final boolean powered; + + public BlockRedstoneLight(int par1, boolean par2) { + super(par1, Material.redstoneLight); + this.powered = par2; + + if (par2) { + this.setLightValue(1.0F); + } + } + + /** + * Called whenever the block is added into the world. Args: world, x, y, z + */ + public void onBlockAdded(World par1World, int par2, int par3, int par4) { + if (!par1World.isRemote) { + if (this.powered && !par1World.isBlockIndirectlyGettingPowered(par2, par3, par4)) { + par1World.scheduleBlockUpdate(par2, par3, par4, this.blockID, 4); + } else if (!this.powered && par1World.isBlockIndirectlyGettingPowered(par2, par3, par4)) { + par1World.setBlock(par2, par3, par4, Block.redstoneLampActive.blockID, 0, 2); + } + } + } + + /** + * Lets the block know when one of its neighbor changes. Doesn't know which + * neighbor changed (coordinates passed are their own) Args: x, y, z, neighbor + * blockID + */ + public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5) { + if (!par1World.isRemote) { + if (this.powered && !par1World.isBlockIndirectlyGettingPowered(par2, par3, par4)) { + par1World.scheduleBlockUpdate(par2, par3, par4, this.blockID, 4); + } else if (!this.powered && par1World.isBlockIndirectlyGettingPowered(par2, par3, par4)) { + par1World.setBlock(par2, par3, par4, Block.redstoneLampActive.blockID, 0, 2); + } + } + } + + /** + * Ticks the block if it's been scheduled + */ + public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random) { + if (!par1World.isRemote && this.powered && !par1World.isBlockIndirectlyGettingPowered(par2, par3, par4)) { + par1World.setBlock(par2, par3, par4, Block.redstoneLampIdle.blockID, 0, 2); + } + } + + /** + * Returns the ID of the items to drop on destruction. + */ + public int idDropped(int par1, Random par2Random, int par3) { + return Block.redstoneLampIdle.blockID; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockRedstoneLogic.java b/sp-server/src/main/java/net/minecraft/src/BlockRedstoneLogic.java new file mode 100644 index 0000000..20087af --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockRedstoneLogic.java @@ -0,0 +1,325 @@ +package net.minecraft.src; + +import java.util.Random; + +public abstract class BlockRedstoneLogic extends BlockDirectional { + /** Tells whether the repeater is powered or not */ + protected final boolean isRepeaterPowered; + + protected BlockRedstoneLogic(int par1, boolean par2) { + super(par1, Material.circuits); + this.isRepeaterPowered = par2; + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.125F, 1.0F); + } + + /** + * If this block doesn't render as an ordinary block it will return False + * (examples: signs, buttons, stairs, etc) + */ + public boolean renderAsNormalBlock() { + return false; + } + + /** + * Checks to see if its valid to put this block at the specified coordinates. + * Args: world, x, y, z + */ + public boolean canPlaceBlockAt(World par1World, int par2, int par3, int par4) { + return !par1World.doesBlockHaveSolidTopSurface(par2, par3 - 1, par4) ? false + : super.canPlaceBlockAt(par1World, par2, par3, par4); + } + + /** + * Can this block stay at this position. Similar to canPlaceBlockAt except gets + * checked often with plants. + */ + public boolean canBlockStay(World par1World, int par2, int par3, int par4) { + return !par1World.doesBlockHaveSolidTopSurface(par2, par3 - 1, par4) ? false + : super.canBlockStay(par1World, par2, par3, par4); + } + + /** + * Ticks the block if it's been scheduled + */ + public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random) { + int var6 = par1World.getBlockMetadata(par2, par3, par4); + + if (!this.func_94476_e(par1World, par2, par3, par4, var6)) { + boolean var7 = this.func_94478_d(par1World, par2, par3, par4, var6); + + if (this.isRepeaterPowered && !var7) { + par1World.setBlock(par2, par3, par4, this.func_94484_i().blockID, var6, 2); + } else if (!this.isRepeaterPowered) { + par1World.setBlock(par2, par3, par4, this.func_94485_e().blockID, var6, 2); + + if (!var7) { + par1World.func_82740_a(par2, par3, par4, this.func_94485_e().blockID, this.func_94486_g(var6), -1); + } + } + } + } + + /** + * The type of render function that is called for this block + */ + public int getRenderType() { + return 36; + } + + protected boolean func_96470_c(int par1) { + return this.isRepeaterPowered; + } + + /** + * Returns true if the block is emitting direct/strong redstone power on the + * specified side. Args: World, X, Y, Z, side. Note that the side is reversed - + * eg it is 1 (up) when checking the bottom of the block. + */ + public int isProvidingStrongPower(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5) { + return this.isProvidingWeakPower(par1IBlockAccess, par2, par3, par4, par5); + } + + /** + * Returns true if the block is emitting indirect/weak redstone power on the + * specified side. If isBlockNormalCube returns true, standard redstone + * propagation rules will apply instead and this will not be called. Args: + * World, X, Y, Z, side. Note that the side is reversed - eg it is 1 (up) when + * checking the bottom of the block. + */ + public int isProvidingWeakPower(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5) { + int var6 = par1IBlockAccess.getBlockMetadata(par2, par3, par4); + + if (!this.func_96470_c(var6)) { + return 0; + } else { + int var7 = getDirection(var6); + return var7 == 0 && par5 == 3 ? this.func_94480_d(par1IBlockAccess, par2, par3, par4, var6) + : (var7 == 1 && par5 == 4 ? this.func_94480_d(par1IBlockAccess, par2, par3, par4, var6) + : (var7 == 2 && par5 == 2 ? this.func_94480_d(par1IBlockAccess, par2, par3, par4, var6) + : (var7 == 3 && par5 == 5 + ? this.func_94480_d(par1IBlockAccess, par2, par3, par4, var6) + : 0))); + } + } + + /** + * Lets the block know when one of its neighbor changes. Doesn't know which + * neighbor changed (coordinates passed are their own) Args: x, y, z, neighbor + * blockID + */ + public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5) { + if (!this.canBlockStay(par1World, par2, par3, par4)) { + this.dropBlockAsItem(par1World, par2, par3, par4, par1World.getBlockMetadata(par2, par3, par4), 0); + par1World.setBlockToAir(par2, par3, par4); + par1World.notifyBlocksOfNeighborChange(par2 + 1, par3, par4, this.blockID); + par1World.notifyBlocksOfNeighborChange(par2 - 1, par3, par4, this.blockID); + par1World.notifyBlocksOfNeighborChange(par2, par3, par4 + 1, this.blockID); + par1World.notifyBlocksOfNeighborChange(par2, par3, par4 - 1, this.blockID); + par1World.notifyBlocksOfNeighborChange(par2, par3 - 1, par4, this.blockID); + par1World.notifyBlocksOfNeighborChange(par2, par3 + 1, par4, this.blockID); + } else { + this.func_94479_f(par1World, par2, par3, par4, par5); + } + } + + protected void func_94479_f(World par1World, int par2, int par3, int par4, int par5) { + int var6 = par1World.getBlockMetadata(par2, par3, par4); + + if (!this.func_94476_e(par1World, par2, par3, par4, var6)) { + boolean var7 = this.func_94478_d(par1World, par2, par3, par4, var6); + + if ((this.isRepeaterPowered && !var7 || !this.isRepeaterPowered && var7) + && !par1World.isBlockTickScheduled(par2, par3, par4, this.blockID)) { + byte var8 = -1; + + if (this.func_83011_d(par1World, par2, par3, par4, var6)) { + var8 = -3; + } else if (this.isRepeaterPowered) { + var8 = -2; + } + + par1World.func_82740_a(par2, par3, par4, this.blockID, this.func_94481_j_(var6), var8); + } + } + } + + public boolean func_94476_e(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5) { + return false; + } + + protected boolean func_94478_d(World par1World, int par2, int par3, int par4, int par5) { + return this.getInputStrength(par1World, par2, par3, par4, par5) > 0; + } + + /** + * Returns the signal strength at one input of the block. Args: world, X, Y, Z, + * side + */ + protected int getInputStrength(World par1World, int par2, int par3, int par4, int par5) { + int var6 = getDirection(par5); + int var7 = par2 + Direction.offsetX[var6]; + int var8 = par4 + Direction.offsetZ[var6]; + int var9 = par1World.getIndirectPowerLevelTo(var7, par3, var8, Direction.directionToFacing[var6]); + return var9 >= 15 ? var9 + : Math.max(var9, + par1World.getBlockId(var7, par3, var8) == Block.redstoneWire.blockID + ? par1World.getBlockMetadata(var7, par3, var8) + : 0); + } + + protected int func_94482_f(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5) { + int var6 = getDirection(par5); + + switch (var6) { + case 0: + case 2: + return Math.max(this.func_94488_g(par1IBlockAccess, par2 - 1, par3, par4, 4), + this.func_94488_g(par1IBlockAccess, par2 + 1, par3, par4, 5)); + + case 1: + case 3: + return Math.max(this.func_94488_g(par1IBlockAccess, par2, par3, par4 + 1, 3), + this.func_94488_g(par1IBlockAccess, par2, par3, par4 - 1, 2)); + + default: + return 0; + } + } + + protected int func_94488_g(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5) { + int var6 = par1IBlockAccess.getBlockId(par2, par3, par4); + return this.func_94477_d(var6) + ? (var6 == Block.redstoneWire.blockID ? par1IBlockAccess.getBlockMetadata(par2, par3, par4) + : par1IBlockAccess.isBlockProvidingPowerTo(par2, par3, par4, par5)) + : 0; + } + + /** + * Can this block provide power. Only wire currently seems to have this change + * based on its state. + */ + public boolean canProvidePower() { + return true; + } + + /** + * Called when the block is placed in the world. + */ + public void onBlockPlacedBy(World par1World, int par2, int par3, int par4, EntityLiving par5EntityLiving, + ItemStack par6ItemStack) { + int var7 = ((MathHelper.floor_double((double) (par5EntityLiving.rotationYaw * 4.0F / 360.0F) + 0.5D) & 3) + 2) + % 4; + par1World.setBlockMetadata(par2, par3, par4, var7, 3); + boolean var8 = this.func_94478_d(par1World, par2, par3, par4, var7); + + if (var8) { + par1World.scheduleBlockUpdate(par2, par3, par4, this.blockID, 1); + } + } + + /** + * Called whenever the block is added into the world. Args: world, x, y, z + */ + public void onBlockAdded(World par1World, int par2, int par3, int par4) { + this.func_94483_i_(par1World, par2, par3, par4); + } + + protected void func_94483_i_(World par1World, int par2, int par3, int par4) { + int var5 = getDirection(par1World.getBlockMetadata(par2, par3, par4)); + + if (var5 == 1) { + par1World.notifyBlockOfNeighborChange(par2 + 1, par3, par4, this.blockID); + par1World.notifyBlocksOfNeighborChange(par2 + 1, par3, par4, this.blockID, 4); + } + + if (var5 == 3) { + par1World.notifyBlockOfNeighborChange(par2 - 1, par3, par4, this.blockID); + par1World.notifyBlocksOfNeighborChange(par2 - 1, par3, par4, this.blockID, 5); + } + + if (var5 == 2) { + par1World.notifyBlockOfNeighborChange(par2, par3, par4 + 1, this.blockID); + par1World.notifyBlocksOfNeighborChange(par2, par3, par4 + 1, this.blockID, 2); + } + + if (var5 == 0) { + par1World.notifyBlockOfNeighborChange(par2, par3, par4 - 1, this.blockID); + par1World.notifyBlocksOfNeighborChange(par2, par3, par4 - 1, this.blockID, 3); + } + } + + /** + * Called right before the block is destroyed by a player. Args: world, x, y, z, + * metaData + */ + public void onBlockDestroyedByPlayer(World par1World, int par2, int par3, int par4, int par5) { + if (this.isRepeaterPowered) { + par1World.notifyBlocksOfNeighborChange(par2 + 1, par3, par4, this.blockID); + par1World.notifyBlocksOfNeighborChange(par2 - 1, par3, par4, this.blockID); + par1World.notifyBlocksOfNeighborChange(par2, par3, par4 + 1, this.blockID); + par1World.notifyBlocksOfNeighborChange(par2, par3, par4 - 1, this.blockID); + par1World.notifyBlocksOfNeighborChange(par2, par3 - 1, par4, this.blockID); + par1World.notifyBlocksOfNeighborChange(par2, par3 + 1, par4, this.blockID); + } + + super.onBlockDestroyedByPlayer(par1World, par2, par3, par4, par5); + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return false; + } + + protected boolean func_94477_d(int par1) { + Block var2 = Block.blocksList[par1]; + return var2 != null && var2.canProvidePower(); + } + + protected int func_94480_d(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5) { + return 15; + } + + public static boolean isRedstoneRepeaterBlockID(int par0) { + return Block.redstoneRepeaterIdle.func_94487_f(par0) || Block.redstoneComparatorIdle.func_94487_f(par0); + } + + public boolean func_94487_f(int par1) { + return par1 == this.func_94485_e().blockID || par1 == this.func_94484_i().blockID; + } + + public boolean func_83011_d(World par1World, int par2, int par3, int par4, int par5) { + int var6 = getDirection(par5); + + if (isRedstoneRepeaterBlockID( + par1World.getBlockId(par2 - Direction.offsetX[var6], par3, par4 - Direction.offsetZ[var6]))) { + int var7 = par1World.getBlockMetadata(par2 - Direction.offsetX[var6], par3, par4 - Direction.offsetZ[var6]); + int var8 = getDirection(var7); + return var8 != var6; + } else { + return false; + } + } + + protected int func_94486_g(int par1) { + return this.func_94481_j_(par1); + } + + protected abstract int func_94481_j_(int var1); + + protected abstract BlockRedstoneLogic func_94485_e(); + + protected abstract BlockRedstoneLogic func_94484_i(); + + /** + * Returns true if the given block ID is equivalent to this one. Example: + * redstoneTorchOn matches itself and redstoneTorchOff, and vice versa. Most + * blocks only match themselves. + */ + public boolean isAssociatedBlockID(int par1) { + return this.func_94487_f(par1); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockRedstoneOre.java b/sp-server/src/main/java/net/minecraft/src/BlockRedstoneOre.java new file mode 100644 index 0000000..8d12bce --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockRedstoneOre.java @@ -0,0 +1,157 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockRedstoneOre extends Block { + private boolean glowing; + + public BlockRedstoneOre(int par1, boolean par2) { + super(par1, Material.rock); + + if (par2) { + this.setTickRandomly(true); + } + + this.glowing = par2; + } + + /** + * How many world ticks before ticking + */ + public int tickRate(World par1World) { + return 30; + } + + /** + * Called when the block is clicked by a player. Args: x, y, z, entityPlayer + */ + public void onBlockClicked(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer) { + this.glow(par1World, par2, par3, par4); + super.onBlockClicked(par1World, par2, par3, par4, par5EntityPlayer); + } + + /** + * Called whenever an entity is walking on top of this block. Args: world, x, y, + * z, entity + */ + public void onEntityWalking(World par1World, int par2, int par3, int par4, Entity par5Entity) { + this.glow(par1World, par2, par3, par4); + super.onEntityWalking(par1World, par2, par3, par4, par5Entity); + } + + /** + * Called upon block activation (right click on the block.) + */ + public boolean onBlockActivated(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer, + int par6, float par7, float par8, float par9) { + this.glow(par1World, par2, par3, par4); + return super.onBlockActivated(par1World, par2, par3, par4, par5EntityPlayer, par6, par7, par8, par9); + } + + /** + * The redstone ore glows. + */ + private void glow(World par1World, int par2, int par3, int par4) { + this.sparkle(par1World, par2, par3, par4); + + if (this.blockID == Block.oreRedstone.blockID) { + par1World.setBlock(par2, par3, par4, Block.oreRedstoneGlowing.blockID); + } + } + + /** + * Ticks the block if it's been scheduled + */ + public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random) { + if (this.blockID == Block.oreRedstoneGlowing.blockID) { + par1World.setBlock(par2, par3, par4, Block.oreRedstone.blockID); + } + } + + /** + * Returns the ID of the items to drop on destruction. + */ + public int idDropped(int par1, Random par2Random, int par3) { + return Item.redstone.itemID; + } + + /** + * Returns the usual quantity dropped by the block plus a bonus of 1 to 'i' + * (inclusive). + */ + public int quantityDroppedWithBonus(int par1, Random par2Random) { + return this.quantityDropped(par2Random) + par2Random.nextInt(par1 + 1); + } + + /** + * Returns the quantity of items to drop on block destruction. + */ + public int quantityDropped(Random par1Random) { + return 4 + par1Random.nextInt(2); + } + + /** + * Drops the block items with a specified chance of dropping the specified items + */ + public void dropBlockAsItemWithChance(World par1World, int par2, int par3, int par4, int par5, float par6, + int par7) { + super.dropBlockAsItemWithChance(par1World, par2, par3, par4, par5, par6, par7); + + if (this.idDropped(par5, par1World.rand, par7) != this.blockID) { + int var8 = 1 + par1World.rand.nextInt(5); + this.dropXpOnBlockBreak(par1World, par2, par3, par4, var8); + } + } + + /** + * The redstone ore sparkles. + */ + private void sparkle(World par1World, int par2, int par3, int par4) { + Random var5 = par1World.rand; + double var6 = 0.0625D; + + for (int var8 = 0; var8 < 6; ++var8) { + double var9 = (double) ((float) par2 + var5.nextFloat()); + double var11 = (double) ((float) par3 + var5.nextFloat()); + double var13 = (double) ((float) par4 + var5.nextFloat()); + + if (var8 == 0 && !par1World.isBlockOpaqueCube(par2, par3 + 1, par4)) { + var11 = (double) (par3 + 1) + var6; + } + + if (var8 == 1 && !par1World.isBlockOpaqueCube(par2, par3 - 1, par4)) { + var11 = (double) (par3 + 0) - var6; + } + + if (var8 == 2 && !par1World.isBlockOpaqueCube(par2, par3, par4 + 1)) { + var13 = (double) (par4 + 1) + var6; + } + + if (var8 == 3 && !par1World.isBlockOpaqueCube(par2, par3, par4 - 1)) { + var13 = (double) (par4 + 0) - var6; + } + + if (var8 == 4 && !par1World.isBlockOpaqueCube(par2 + 1, par3, par4)) { + var9 = (double) (par2 + 1) + var6; + } + + if (var8 == 5 && !par1World.isBlockOpaqueCube(par2 - 1, par3, par4)) { + var9 = (double) (par2 + 0) - var6; + } + + if (var9 < (double) par2 || var9 > (double) (par2 + 1) || var11 < 0.0D || var11 > (double) (par3 + 1) + || var13 < (double) par4 || var13 > (double) (par4 + 1)) { + par1World.spawnParticle("reddust", var9, var11, var13, 0.0D, 0.0D, 0.0D); + } + } + } + + /** + * Returns an item stack containing a single instance of the current block type. + * 'i' is the block's subtype/damage and is ignored for blocks which do not + * support subtypes. Blocks which cannot be harvested should return null. + */ + protected ItemStack createStackedBlock(int par1) { + return new ItemStack(Block.oreRedstone); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockRedstoneRepeater.java b/sp-server/src/main/java/net/minecraft/src/BlockRedstoneRepeater.java new file mode 100644 index 0000000..8fa6467 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockRedstoneRepeater.java @@ -0,0 +1,70 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockRedstoneRepeater extends BlockRedstoneLogic { + /** The offsets for the two torches in redstone repeater blocks. */ + public static final double[] repeaterTorchOffset = new double[] { -0.0625D, 0.0625D, 0.1875D, 0.3125D }; + + /** The states in which the redstone repeater blocks can be. */ + private static final int[] repeaterState = new int[] { 1, 2, 3, 4 }; + + protected BlockRedstoneRepeater(int par1, boolean par2) { + super(par1, par2); + } + + /** + * Called upon block activation (right click on the block.) + */ + public boolean onBlockActivated(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer, + int par6, float par7, float par8, float par9) { + int var10 = par1World.getBlockMetadata(par2, par3, par4); + int var11 = (var10 & 12) >> 2; + var11 = var11 + 1 << 2 & 12; + par1World.setBlockMetadata(par2, par3, par4, var11 | var10 & 3, 3); + return true; + } + + protected int func_94481_j_(int par1) { + return repeaterState[(par1 & 12) >> 2] * 2; + } + + protected BlockRedstoneLogic func_94485_e() { + return Block.redstoneRepeaterActive; + } + + protected BlockRedstoneLogic func_94484_i() { + return Block.redstoneRepeaterIdle; + } + + /** + * Returns the ID of the items to drop on destruction. + */ + public int idDropped(int par1, Random par2Random, int par3) { + return Item.redstoneRepeater.itemID; + } + + /** + * The type of render function that is called for this block + */ + public int getRenderType() { + return 15; + } + + public boolean func_94476_e(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5) { + return this.func_94482_f(par1IBlockAccess, par2, par3, par4, par5) > 0; + } + + protected boolean func_94477_d(int par1) { + return isRedstoneRepeaterBlockID(par1); + } + + /** + * ejects contained items into the world, and notifies neighbours of an update, + * as appropriate + */ + public void breakBlock(World par1World, int par2, int par3, int par4, int par5, int par6) { + super.breakBlock(par1World, par2, par3, par4, par5, par6); + this.func_94483_i_(par1World, par2, par3, par4); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockRedstoneTorch.java b/sp-server/src/main/java/net/minecraft/src/BlockRedstoneTorch.java new file mode 100644 index 0000000..06391c3 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockRedstoneTorch.java @@ -0,0 +1,206 @@ +package net.minecraft.src; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Random; + +public class BlockRedstoneTorch extends BlockTorch { + /** Whether the redstone torch is currently active or not. */ + private boolean torchActive = false; + + /** Map of ArrayLists of RedstoneUpdateInfo. Key of map is World. */ + private static Map redstoneUpdateInfoCache = new HashMap(); + + private boolean checkForBurnout(World par1World, int par2, int par3, int par4, boolean par5) { + if (!redstoneUpdateInfoCache.containsKey(par1World)) { + redstoneUpdateInfoCache.put(par1World, new ArrayList()); + } + + List var6 = (List) redstoneUpdateInfoCache.get(par1World); + + if (par5) { + var6.add(new RedstoneUpdateInfo(par2, par3, par4, par1World.getTotalWorldTime())); + } + + int var7 = 0; + + for (int var8 = 0; var8 < var6.size(); ++var8) { + RedstoneUpdateInfo var9 = (RedstoneUpdateInfo) var6.get(var8); + + if (var9.x == par2 && var9.y == par3 && var9.z == par4) { + ++var7; + + if (var7 >= 8) { + return true; + } + } + } + + return false; + } + + protected BlockRedstoneTorch(int par1, boolean par2) { + super(par1); + this.torchActive = par2; + this.setTickRandomly(true); + this.setCreativeTab((CreativeTabs) null); + } + + /** + * How many world ticks before ticking + */ + public int tickRate(World par1World) { + return 2; + } + + /** + * Called whenever the block is added into the world. Args: world, x, y, z + */ + public void onBlockAdded(World par1World, int par2, int par3, int par4) { + if (par1World.getBlockMetadata(par2, par3, par4) == 0) { + super.onBlockAdded(par1World, par2, par3, par4); + } + + if (this.torchActive) { + par1World.notifyBlocksOfNeighborChange(par2, par3 - 1, par4, this.blockID); + par1World.notifyBlocksOfNeighborChange(par2, par3 + 1, par4, this.blockID); + par1World.notifyBlocksOfNeighborChange(par2 - 1, par3, par4, this.blockID); + par1World.notifyBlocksOfNeighborChange(par2 + 1, par3, par4, this.blockID); + par1World.notifyBlocksOfNeighborChange(par2, par3, par4 - 1, this.blockID); + par1World.notifyBlocksOfNeighborChange(par2, par3, par4 + 1, this.blockID); + } + } + + /** + * ejects contained items into the world, and notifies neighbours of an update, + * as appropriate + */ + public void breakBlock(World par1World, int par2, int par3, int par4, int par5, int par6) { + if (this.torchActive) { + par1World.notifyBlocksOfNeighborChange(par2, par3 - 1, par4, this.blockID); + par1World.notifyBlocksOfNeighborChange(par2, par3 + 1, par4, this.blockID); + par1World.notifyBlocksOfNeighborChange(par2 - 1, par3, par4, this.blockID); + par1World.notifyBlocksOfNeighborChange(par2 + 1, par3, par4, this.blockID); + par1World.notifyBlocksOfNeighborChange(par2, par3, par4 - 1, this.blockID); + par1World.notifyBlocksOfNeighborChange(par2, par3, par4 + 1, this.blockID); + } + } + + /** + * Returns true if the block is emitting indirect/weak redstone power on the + * specified side. If isBlockNormalCube returns true, standard redstone + * propagation rules will apply instead and this will not be called. Args: + * World, X, Y, Z, side. Note that the side is reversed - eg it is 1 (up) when + * checking the bottom of the block. + */ + public int isProvidingWeakPower(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5) { + if (!this.torchActive) { + return 0; + } else { + int var6 = par1IBlockAccess.getBlockMetadata(par2, par3, par4); + return var6 == 5 && par5 == 1 ? 0 + : (var6 == 3 && par5 == 3 ? 0 + : (var6 == 4 && par5 == 2 ? 0 + : (var6 == 1 && par5 == 5 ? 0 : (var6 == 2 && par5 == 4 ? 0 : 15)))); + } + } + + /** + * Returns true or false based on whether the block the torch is attached to is + * providing indirect power. + */ + private boolean isIndirectlyPowered(World par1World, int par2, int par3, int par4) { + int var5 = par1World.getBlockMetadata(par2, par3, par4); + return var5 == 5 && par1World.getIndirectPowerOutput(par2, par3 - 1, par4, 0) ? true + : (var5 == 3 && par1World.getIndirectPowerOutput(par2, par3, par4 - 1, 2) ? true + : (var5 == 4 && par1World.getIndirectPowerOutput(par2, par3, par4 + 1, 3) ? true + : (var5 == 1 && par1World.getIndirectPowerOutput(par2 - 1, par3, par4, 4) ? true + : var5 == 2 && par1World.getIndirectPowerOutput(par2 + 1, par3, par4, 5)))); + } + + /** + * Ticks the block if it's been scheduled + */ + public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random) { + boolean var6 = this.isIndirectlyPowered(par1World, par2, par3, par4); + List var7 = (List) redstoneUpdateInfoCache.get(par1World); + + while (var7 != null && !var7.isEmpty() + && par1World.getTotalWorldTime() - ((RedstoneUpdateInfo) var7.get(0)).updateTime > 60L) { + var7.remove(0); + } + + if (this.torchActive) { + if (var6) { + par1World.setBlock(par2, par3, par4, Block.torchRedstoneIdle.blockID, + par1World.getBlockMetadata(par2, par3, par4), 3); + + if (this.checkForBurnout(par1World, par2, par3, par4, true)) { + par1World.playSoundEffect((double) ((float) par2 + 0.5F), (double) ((float) par3 + 0.5F), + (double) ((float) par4 + 0.5F), "random.fizz", 0.5F, + 2.6F + (par1World.rand.nextFloat() - par1World.rand.nextFloat()) * 0.8F); + + for (int var8 = 0; var8 < 5; ++var8) { + double var9 = (double) par2 + par5Random.nextDouble() * 0.6D + 0.2D; + double var11 = (double) par3 + par5Random.nextDouble() * 0.6D + 0.2D; + double var13 = (double) par4 + par5Random.nextDouble() * 0.6D + 0.2D; + par1World.spawnParticle("smoke", var9, var11, var13, 0.0D, 0.0D, 0.0D); + } + } + } + } else if (!var6 && !this.checkForBurnout(par1World, par2, par3, par4, false)) { + par1World.setBlock(par2, par3, par4, Block.torchRedstoneActive.blockID, + par1World.getBlockMetadata(par2, par3, par4), 3); + } + } + + /** + * Lets the block know when one of its neighbor changes. Doesn't know which + * neighbor changed (coordinates passed are their own) Args: x, y, z, neighbor + * blockID + */ + public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5) { + if (!this.func_94397_d(par1World, par2, par3, par4, par5)) { + boolean var6 = this.isIndirectlyPowered(par1World, par2, par3, par4); + + if (this.torchActive && var6 || !this.torchActive && !var6) { + par1World.scheduleBlockUpdate(par2, par3, par4, this.blockID, this.tickRate(par1World)); + } + } + } + + /** + * Returns true if the block is emitting direct/strong redstone power on the + * specified side. Args: World, X, Y, Z, side. Note that the side is reversed - + * eg it is 1 (up) when checking the bottom of the block. + */ + public int isProvidingStrongPower(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5) { + return par5 == 0 ? this.isProvidingWeakPower(par1IBlockAccess, par2, par3, par4, par5) : 0; + } + + /** + * Returns the ID of the items to drop on destruction. + */ + public int idDropped(int par1, Random par2Random, int par3) { + return Block.torchRedstoneActive.blockID; + } + + /** + * Can this block provide power. Only wire currently seems to have this change + * based on its state. + */ + public boolean canProvidePower() { + return true; + } + + /** + * Returns true if the given block ID is equivalent to this one. Example: + * redstoneTorchOn matches itself and redstoneTorchOff, and vice versa. Most + * blocks only match themselves. + */ + public boolean isAssociatedBlockID(int par1) { + return par1 == Block.torchRedstoneIdle.blockID || par1 == Block.torchRedstoneActive.blockID; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockRedstoneWire.java b/sp-server/src/main/java/net/minecraft/src/BlockRedstoneWire.java new file mode 100644 index 0000000..7a53950 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockRedstoneWire.java @@ -0,0 +1,409 @@ +package net.minecraft.src; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Random; +import java.util.Set; + +public class BlockRedstoneWire extends Block { + /** + * When false, power transmission methods do not look at other redstone wires. + * Used internally during updateCurrentStrength. + */ + private boolean wiresProvidePower = true; + private Set blocksNeedingUpdate = new HashSet(); + + public BlockRedstoneWire(int par1) { + super(par1, Material.circuits); + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.0625F, 1.0F); + } + + /** + * Returns a bounding box from the pool of bounding boxes (this means this box + * can change after the pool has been cleared to be reused) + */ + public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int par4) { + return null; + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return false; + } + + /** + * If this block doesn't render as an ordinary block it will return False + * (examples: signs, buttons, stairs, etc) + */ + public boolean renderAsNormalBlock() { + return false; + } + + /** + * The type of render function that is called for this block + */ + public int getRenderType() { + return 5; + } + + /** + * Checks to see if its valid to put this block at the specified coordinates. + * Args: world, x, y, z + */ + public boolean canPlaceBlockAt(World par1World, int par2, int par3, int par4) { + return par1World.doesBlockHaveSolidTopSurface(par2, par3 - 1, par4) + || par1World.getBlockId(par2, par3 - 1, par4) == Block.glowStone.blockID; + } + + /** + * Sets the strength of the wire current (0-15) for this block based on + * neighboring blocks and propagates to neighboring redstone wires + */ + private void updateAndPropagateCurrentStrength(World par1World, int par2, int par3, int par4) { + this.calculateCurrentChanges(par1World, par2, par3, par4, par2, par3, par4); + ArrayList var5 = new ArrayList(this.blocksNeedingUpdate); + this.blocksNeedingUpdate.clear(); + + for (int var6 = 0; var6 < var5.size(); ++var6) { + ChunkPosition var7 = (ChunkPosition) var5.get(var6); + par1World.notifyBlocksOfNeighborChange(var7.x, var7.y, var7.z, this.blockID); + } + } + + private void calculateCurrentChanges(World par1World, int par2, int par3, int par4, int par5, int par6, int par7) { + int var8 = par1World.getBlockMetadata(par2, par3, par4); + byte var9 = 0; + int var15 = this.getMaxCurrentStrength(par1World, par5, par6, par7, var9); + this.wiresProvidePower = false; + int var10 = par1World.getStrongestIndirectPower(par2, par3, par4); + this.wiresProvidePower = true; + + if (var10 > 0 && var10 > var15 - 1) { + var15 = var10; + } + + int var11 = 0; + + for (int var12 = 0; var12 < 4; ++var12) { + int var13 = par2; + int var14 = par4; + + if (var12 == 0) { + var13 = par2 - 1; + } + + if (var12 == 1) { + ++var13; + } + + if (var12 == 2) { + var14 = par4 - 1; + } + + if (var12 == 3) { + ++var14; + } + + if (var13 != par5 || var14 != par7) { + var11 = this.getMaxCurrentStrength(par1World, var13, par3, var14, var11); + } + + if (par1World.isBlockNormalCube(var13, par3, var14) && !par1World.isBlockNormalCube(par2, par3 + 1, par4)) { + if ((var13 != par5 || var14 != par7) && par3 >= par6) { + var11 = this.getMaxCurrentStrength(par1World, var13, par3 + 1, var14, var11); + } + } else if (!par1World.isBlockNormalCube(var13, par3, var14) && (var13 != par5 || var14 != par7) + && par3 <= par6) { + var11 = this.getMaxCurrentStrength(par1World, var13, par3 - 1, var14, var11); + } + } + + if (var11 > var15) { + var15 = var11 - 1; + } else if (var15 > 0) { + --var15; + } else { + var15 = 0; + } + + if (var10 > var15 - 1) { + var15 = var10; + } + + if (var8 != var15) { + par1World.setBlockMetadata(par2, par3, par4, var15, 2); + this.blocksNeedingUpdate.add(new ChunkPosition(par2, par3, par4)); + this.blocksNeedingUpdate.add(new ChunkPosition(par2 - 1, par3, par4)); + this.blocksNeedingUpdate.add(new ChunkPosition(par2 + 1, par3, par4)); + this.blocksNeedingUpdate.add(new ChunkPosition(par2, par3 - 1, par4)); + this.blocksNeedingUpdate.add(new ChunkPosition(par2, par3 + 1, par4)); + this.blocksNeedingUpdate.add(new ChunkPosition(par2, par3, par4 - 1)); + this.blocksNeedingUpdate.add(new ChunkPosition(par2, par3, par4 + 1)); + } + } + + /** + * Calls World.notifyBlocksOfNeighborChange() for all neighboring blocks, but + * only if the given block is a redstone wire. + */ + private void notifyWireNeighborsOfNeighborChange(World par1World, int par2, int par3, int par4) { + if (par1World.getBlockId(par2, par3, par4) == this.blockID) { + par1World.notifyBlocksOfNeighborChange(par2, par3, par4, this.blockID); + par1World.notifyBlocksOfNeighborChange(par2 - 1, par3, par4, this.blockID); + par1World.notifyBlocksOfNeighborChange(par2 + 1, par3, par4, this.blockID); + par1World.notifyBlocksOfNeighborChange(par2, par3, par4 - 1, this.blockID); + par1World.notifyBlocksOfNeighborChange(par2, par3, par4 + 1, this.blockID); + par1World.notifyBlocksOfNeighborChange(par2, par3 - 1, par4, this.blockID); + par1World.notifyBlocksOfNeighborChange(par2, par3 + 1, par4, this.blockID); + } + } + + /** + * Called whenever the block is added into the world. Args: world, x, y, z + */ + public void onBlockAdded(World par1World, int par2, int par3, int par4) { + super.onBlockAdded(par1World, par2, par3, par4); + + if (!par1World.isRemote) { + this.updateAndPropagateCurrentStrength(par1World, par2, par3, par4); + par1World.notifyBlocksOfNeighborChange(par2, par3 + 1, par4, this.blockID); + par1World.notifyBlocksOfNeighborChange(par2, par3 - 1, par4, this.blockID); + this.notifyWireNeighborsOfNeighborChange(par1World, par2 - 1, par3, par4); + this.notifyWireNeighborsOfNeighborChange(par1World, par2 + 1, par3, par4); + this.notifyWireNeighborsOfNeighborChange(par1World, par2, par3, par4 - 1); + this.notifyWireNeighborsOfNeighborChange(par1World, par2, par3, par4 + 1); + + if (par1World.isBlockNormalCube(par2 - 1, par3, par4)) { + this.notifyWireNeighborsOfNeighborChange(par1World, par2 - 1, par3 + 1, par4); + } else { + this.notifyWireNeighborsOfNeighborChange(par1World, par2 - 1, par3 - 1, par4); + } + + if (par1World.isBlockNormalCube(par2 + 1, par3, par4)) { + this.notifyWireNeighborsOfNeighborChange(par1World, par2 + 1, par3 + 1, par4); + } else { + this.notifyWireNeighborsOfNeighborChange(par1World, par2 + 1, par3 - 1, par4); + } + + if (par1World.isBlockNormalCube(par2, par3, par4 - 1)) { + this.notifyWireNeighborsOfNeighborChange(par1World, par2, par3 + 1, par4 - 1); + } else { + this.notifyWireNeighborsOfNeighborChange(par1World, par2, par3 - 1, par4 - 1); + } + + if (par1World.isBlockNormalCube(par2, par3, par4 + 1)) { + this.notifyWireNeighborsOfNeighborChange(par1World, par2, par3 + 1, par4 + 1); + } else { + this.notifyWireNeighborsOfNeighborChange(par1World, par2, par3 - 1, par4 + 1); + } + } + } + + /** + * ejects contained items into the world, and notifies neighbours of an update, + * as appropriate + */ + public void breakBlock(World par1World, int par2, int par3, int par4, int par5, int par6) { + super.breakBlock(par1World, par2, par3, par4, par5, par6); + + if (!par1World.isRemote) { + par1World.notifyBlocksOfNeighborChange(par2, par3 + 1, par4, this.blockID); + par1World.notifyBlocksOfNeighborChange(par2, par3 - 1, par4, this.blockID); + par1World.notifyBlocksOfNeighborChange(par2 + 1, par3, par4, this.blockID); + par1World.notifyBlocksOfNeighborChange(par2 - 1, par3, par4, this.blockID); + par1World.notifyBlocksOfNeighborChange(par2, par3, par4 + 1, this.blockID); + par1World.notifyBlocksOfNeighborChange(par2, par3, par4 - 1, this.blockID); + this.updateAndPropagateCurrentStrength(par1World, par2, par3, par4); + this.notifyWireNeighborsOfNeighborChange(par1World, par2 - 1, par3, par4); + this.notifyWireNeighborsOfNeighborChange(par1World, par2 + 1, par3, par4); + this.notifyWireNeighborsOfNeighborChange(par1World, par2, par3, par4 - 1); + this.notifyWireNeighborsOfNeighborChange(par1World, par2, par3, par4 + 1); + + if (par1World.isBlockNormalCube(par2 - 1, par3, par4)) { + this.notifyWireNeighborsOfNeighborChange(par1World, par2 - 1, par3 + 1, par4); + } else { + this.notifyWireNeighborsOfNeighborChange(par1World, par2 - 1, par3 - 1, par4); + } + + if (par1World.isBlockNormalCube(par2 + 1, par3, par4)) { + this.notifyWireNeighborsOfNeighborChange(par1World, par2 + 1, par3 + 1, par4); + } else { + this.notifyWireNeighborsOfNeighborChange(par1World, par2 + 1, par3 - 1, par4); + } + + if (par1World.isBlockNormalCube(par2, par3, par4 - 1)) { + this.notifyWireNeighborsOfNeighborChange(par1World, par2, par3 + 1, par4 - 1); + } else { + this.notifyWireNeighborsOfNeighborChange(par1World, par2, par3 - 1, par4 - 1); + } + + if (par1World.isBlockNormalCube(par2, par3, par4 + 1)) { + this.notifyWireNeighborsOfNeighborChange(par1World, par2, par3 + 1, par4 + 1); + } else { + this.notifyWireNeighborsOfNeighborChange(par1World, par2, par3 - 1, par4 + 1); + } + } + } + + /** + * Returns the current strength at the specified block if it is greater than the + * passed value, or the passed value otherwise. Signature: (world, x, y, z, + * strength) + */ + private int getMaxCurrentStrength(World par1World, int par2, int par3, int par4, int par5) { + if (par1World.getBlockId(par2, par3, par4) != this.blockID) { + return par5; + } else { + int var6 = par1World.getBlockMetadata(par2, par3, par4); + return var6 > par5 ? var6 : par5; + } + } + + /** + * Lets the block know when one of its neighbor changes. Doesn't know which + * neighbor changed (coordinates passed are their own) Args: x, y, z, neighbor + * blockID + */ + public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5) { + if (!par1World.isRemote) { + boolean var6 = this.canPlaceBlockAt(par1World, par2, par3, par4); + + if (var6) { + this.updateAndPropagateCurrentStrength(par1World, par2, par3, par4); + } else { + this.dropBlockAsItem(par1World, par2, par3, par4, 0, 0); + par1World.setBlockToAir(par2, par3, par4); + } + + super.onNeighborBlockChange(par1World, par2, par3, par4, par5); + } + } + + /** + * Returns the ID of the items to drop on destruction. + */ + public int idDropped(int par1, Random par2Random, int par3) { + return Item.redstone.itemID; + } + + /** + * Returns true if the block is emitting direct/strong redstone power on the + * specified side. Args: World, X, Y, Z, side. Note that the side is reversed - + * eg it is 1 (up) when checking the bottom of the block. + */ + public int isProvidingStrongPower(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5) { + return !this.wiresProvidePower ? 0 : this.isProvidingWeakPower(par1IBlockAccess, par2, par3, par4, par5); + } + + /** + * Returns true if the block is emitting indirect/weak redstone power on the + * specified side. If isBlockNormalCube returns true, standard redstone + * propagation rules will apply instead and this will not be called. Args: + * World, X, Y, Z, side. Note that the side is reversed - eg it is 1 (up) when + * checking the bottom of the block. + */ + public int isProvidingWeakPower(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5) { + if (!this.wiresProvidePower) { + return 0; + } else { + int var6 = par1IBlockAccess.getBlockMetadata(par2, par3, par4); + + if (var6 == 0) { + return 0; + } else if (par5 == 1) { + return var6; + } else { + boolean var7 = isPoweredOrRepeater(par1IBlockAccess, par2 - 1, par3, par4, 1) + || !par1IBlockAccess.isBlockNormalCube(par2 - 1, par3, par4) + && isPoweredOrRepeater(par1IBlockAccess, par2 - 1, par3 - 1, par4, -1); + boolean var8 = isPoweredOrRepeater(par1IBlockAccess, par2 + 1, par3, par4, 3) + || !par1IBlockAccess.isBlockNormalCube(par2 + 1, par3, par4) + && isPoweredOrRepeater(par1IBlockAccess, par2 + 1, par3 - 1, par4, -1); + boolean var9 = isPoweredOrRepeater(par1IBlockAccess, par2, par3, par4 - 1, 2) + || !par1IBlockAccess.isBlockNormalCube(par2, par3, par4 - 1) + && isPoweredOrRepeater(par1IBlockAccess, par2, par3 - 1, par4 - 1, -1); + boolean var10 = isPoweredOrRepeater(par1IBlockAccess, par2, par3, par4 + 1, 0) + || !par1IBlockAccess.isBlockNormalCube(par2, par3, par4 + 1) + && isPoweredOrRepeater(par1IBlockAccess, par2, par3 - 1, par4 + 1, -1); + + if (!par1IBlockAccess.isBlockNormalCube(par2, par3 + 1, par4)) { + if (par1IBlockAccess.isBlockNormalCube(par2 - 1, par3, par4) + && isPoweredOrRepeater(par1IBlockAccess, par2 - 1, par3 + 1, par4, -1)) { + var7 = true; + } + + if (par1IBlockAccess.isBlockNormalCube(par2 + 1, par3, par4) + && isPoweredOrRepeater(par1IBlockAccess, par2 + 1, par3 + 1, par4, -1)) { + var8 = true; + } + + if (par1IBlockAccess.isBlockNormalCube(par2, par3, par4 - 1) + && isPoweredOrRepeater(par1IBlockAccess, par2, par3 + 1, par4 - 1, -1)) { + var9 = true; + } + + if (par1IBlockAccess.isBlockNormalCube(par2, par3, par4 + 1) + && isPoweredOrRepeater(par1IBlockAccess, par2, par3 + 1, par4 + 1, -1)) { + var10 = true; + } + } + + return !var9 && !var8 && !var7 && !var10 && par5 >= 2 && par5 <= 5 ? var6 + : (par5 == 2 && var9 && !var7 && !var8 ? var6 + : (par5 == 3 && var10 && !var7 && !var8 ? var6 + : (par5 == 4 && var7 && !var9 && !var10 ? var6 + : (par5 == 5 && var8 && !var9 && !var10 ? var6 : 0)))); + } + } + } + + /** + * Can this block provide power. Only wire currently seems to have this change + * based on its state. + */ + public boolean canProvidePower() { + return this.wiresProvidePower; + } + + /** + * Returns true if redstone wire can connect to the specified block. Params: + * World, X, Y, Z, side (not a normal notch-side, this can be 0, 1, 2, 3 or -1) + */ + public static boolean isPowerProviderOrWire(IBlockAccess par0IBlockAccess, int par1, int par2, int par3, int par4) { + int var5 = par0IBlockAccess.getBlockId(par1, par2, par3); + + if (var5 == Block.redstoneWire.blockID) { + return true; + } else if (var5 == 0) { + return false; + } else if (!Block.redstoneRepeaterIdle.func_94487_f(var5)) { + return Block.blocksList[var5].canProvidePower() && par4 != -1; + } else { + int var6 = par0IBlockAccess.getBlockMetadata(par1, par2, par3); + return par4 == (var6 & 3) || par4 == Direction.footInvisibleFaceRemap[var6 & 3]; + } + } + + /** + * Returns true if the block coordinate passed can provide power, or is a + * redstone wire, or if its a repeater that is powered. + */ + public static boolean isPoweredOrRepeater(IBlockAccess par0IBlockAccess, int par1, int par2, int par3, int par4) { + if (isPowerProviderOrWire(par0IBlockAccess, par1, par2, par3, par4)) { + return true; + } else { + int var5 = par0IBlockAccess.getBlockId(par1, par2, par3); + + if (var5 == Block.redstoneRepeaterActive.blockID) { + int var6 = par0IBlockAccess.getBlockMetadata(par1, par2, par3); + return par4 == (var6 & 3); + } else { + return false; + } + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockReed.java b/sp-server/src/main/java/net/minecraft/src/BlockReed.java new file mode 100644 index 0000000..2f9b2db --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockReed.java @@ -0,0 +1,118 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockReed extends Block { + protected BlockReed(int par1) { + super(par1, Material.plants); + float var2 = 0.375F; + this.setBlockBounds(0.5F - var2, 0.0F, 0.5F - var2, 0.5F + var2, 1.0F, 0.5F + var2); + this.setTickRandomly(true); + } + + /** + * Ticks the block if it's been scheduled + */ + public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random) { + if (par1World.isAirBlock(par2, par3 + 1, par4)) { + int var6; + + for (var6 = 1; par1World.getBlockId(par2, par3 - var6, par4) == this.blockID; ++var6) { + ; + } + + if (var6 < 3) { + int var7 = par1World.getBlockMetadata(par2, par3, par4); + + if (var7 == 15) { + par1World.setBlock(par2, par3 + 1, par4, this.blockID); + par1World.setBlockMetadata(par2, par3, par4, 0, 4); + } else { + par1World.setBlockMetadata(par2, par3, par4, var7 + 1, 4); + } + } + } + } + + /** + * Checks to see if its valid to put this block at the specified coordinates. + * Args: world, x, y, z + */ + public boolean canPlaceBlockAt(World par1World, int par2, int par3, int par4) { + int var5 = par1World.getBlockId(par2, par3 - 1, par4); + return var5 == this.blockID ? true + : (var5 != Block.grass.blockID && var5 != Block.dirt.blockID && var5 != Block.sand.blockID ? false + : (par1World.getBlockMaterial(par2 - 1, par3 - 1, par4) == Material.water ? true + : (par1World.getBlockMaterial(par2 + 1, par3 - 1, par4) == Material.water ? true + : (par1World.getBlockMaterial(par2, par3 - 1, par4 - 1) == Material.water ? true + : par1World.getBlockMaterial(par2, par3 - 1, + par4 + 1) == Material.water)))); + } + + /** + * Lets the block know when one of its neighbor changes. Doesn't know which + * neighbor changed (coordinates passed are their own) Args: x, y, z, neighbor + * blockID + */ + public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5) { + this.checkBlockCoordValid(par1World, par2, par3, par4); + } + + /** + * Checks if current block pos is valid, if not, breaks the block as dropable + * item. Used for reed and cactus. + */ + protected final void checkBlockCoordValid(World par1World, int par2, int par3, int par4) { + if (!this.canBlockStay(par1World, par2, par3, par4)) { + this.dropBlockAsItem(par1World, par2, par3, par4, par1World.getBlockMetadata(par2, par3, par4), 0); + par1World.setBlockToAir(par2, par3, par4); + } + } + + /** + * Can this block stay at this position. Similar to canPlaceBlockAt except gets + * checked often with plants. + */ + public boolean canBlockStay(World par1World, int par2, int par3, int par4) { + return this.canPlaceBlockAt(par1World, par2, par3, par4); + } + + /** + * Returns a bounding box from the pool of bounding boxes (this means this box + * can change after the pool has been cleared to be reused) + */ + public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int par4) { + return null; + } + + /** + * Returns the ID of the items to drop on destruction. + */ + public int idDropped(int par1, Random par2Random, int par3) { + return Item.reed.itemID; + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return false; + } + + /** + * If this block doesn't render as an ordinary block it will return False + * (examples: signs, buttons, stairs, etc) + */ + public boolean renderAsNormalBlock() { + return false; + } + + /** + * The type of render function that is called for this block + */ + public int getRenderType() { + return 1; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockSand.java b/sp-server/src/main/java/net/minecraft/src/BlockSand.java new file mode 100644 index 0000000..7390885 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockSand.java @@ -0,0 +1,108 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockSand extends Block { + /** Do blocks fall instantly to where they stop or do they fall over time */ + public static boolean fallInstantly = false; + + public BlockSand(int par1) { + super(par1, Material.sand); + this.setCreativeTab(CreativeTabs.tabBlock); + } + + public BlockSand(int par1, Material par2Material) { + super(par1, par2Material); + } + + /** + * Called whenever the block is added into the world. Args: world, x, y, z + */ + public void onBlockAdded(World par1World, int par2, int par3, int par4) { + par1World.scheduleBlockUpdate(par2, par3, par4, this.blockID, this.tickRate(par1World)); + } + + /** + * Lets the block know when one of its neighbor changes. Doesn't know which + * neighbor changed (coordinates passed are their own) Args: x, y, z, neighbor + * blockID + */ + public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5) { + par1World.scheduleBlockUpdate(par2, par3, par4, this.blockID, this.tickRate(par1World)); + } + + /** + * Ticks the block if it's been scheduled + */ + public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random) { + if (!par1World.isRemote) { + this.tryToFall(par1World, par2, par3, par4); + } + } + + /** + * If there is space to fall below will start this block falling + */ + private void tryToFall(World par1World, int par2, int par3, int par4) { + if (canFallBelow(par1World, par2, par3 - 1, par4) && par3 >= 0) { + byte var8 = 32; + + if (!fallInstantly && par1World.checkChunksExist(par2 - var8, par3 - var8, par4 - var8, par2 + var8, + par3 + var8, par4 + var8)) { + if (!par1World.isRemote) { + EntityFallingSand var9 = new EntityFallingSand(par1World, (double) ((float) par2 + 0.5F), + (double) ((float) par3 + 0.5F), (double) ((float) par4 + 0.5F), this.blockID, + par1World.getBlockMetadata(par2, par3, par4)); + this.onStartFalling(var9); + par1World.spawnEntityInWorld(var9); + } + } else { + par1World.setBlockToAir(par2, par3, par4); + + while (canFallBelow(par1World, par2, par3 - 1, par4) && par3 > 0) { + --par3; + } + + if (par3 > 0) { + par1World.setBlock(par2, par3, par4, this.blockID); + } + } + } + } + + /** + * Called when the falling block entity for this block is created + */ + protected void onStartFalling(EntityFallingSand par1EntityFallingSand) { + } + + /** + * How many world ticks before ticking + */ + public int tickRate(World par1World) { + return 2; + } + + /** + * Checks to see if the sand can fall into the block below it + */ + public static boolean canFallBelow(World par0World, int par1, int par2, int par3) { + int var4 = par0World.getBlockId(par1, par2, par3); + + if (var4 == 0) { + return true; + } else if (var4 == Block.fire.blockID) { + return true; + } else { + Material var5 = Block.blocksList[var4].blockMaterial; + return var5 == Material.water ? true : var5 == Material.lava; + } + } + + /** + * Called when the falling block entity for this block hits the ground and turns + * back into a block + */ + public void onFinishFalling(World par1World, int par2, int par3, int par4, int par5) { + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockSandStone.java b/sp-server/src/main/java/net/minecraft/src/BlockSandStone.java new file mode 100644 index 0000000..32b26d4 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockSandStone.java @@ -0,0 +1,19 @@ +package net.minecraft.src; + +public class BlockSandStone extends Block { + public static final String[] SAND_STONE_TYPES = new String[] { "default", "chiseled", "smooth" }; + private static final String[] field_94405_b = new String[] { "sandstone_side", "sandstone_carved", + "sandstone_smooth" }; + + public BlockSandStone(int par1) { + super(par1, Material.rock); + this.setCreativeTab(CreativeTabs.tabBlock); + } + + /** + * Determines the damage on the item the block drops. Used in cloth and wood. + */ + public int damageDropped(int par1) { + return par1; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockSapling.java b/sp-server/src/main/java/net/minecraft/src/BlockSapling.java new file mode 100644 index 0000000..8c39e9a --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockSapling.java @@ -0,0 +1,120 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockSapling extends BlockFlower { + public static final String[] WOOD_TYPES = new String[] { "oak", "spruce", "birch", "jungle" }; + private static final String[] field_94370_b = new String[] { "sapling", "sapling_spruce", "sapling_birch", + "sapling_jungle" }; + + protected BlockSapling(int par1) { + super(par1); + float var2 = 0.4F; + this.setBlockBounds(0.5F - var2, 0.0F, 0.5F - var2, 0.5F + var2, var2 * 2.0F, 0.5F + var2); + this.setCreativeTab(CreativeTabs.tabDecorations); + } + + /** + * Ticks the block if it's been scheduled + */ + public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random) { + if (!par1World.isRemote) { + super.updateTick(par1World, par2, par3, par4, par5Random); + + if (par1World.getBlockLightValue(par2, par3 + 1, par4) >= 9 && par5Random.nextInt(7) == 0) { + this.markOrGrowMarked(par1World, par2, par3, par4, par5Random); + } + } + } + + public void markOrGrowMarked(World par1World, int par2, int par3, int par4, Random par5Random) { + int var6 = par1World.getBlockMetadata(par2, par3, par4); + + if ((var6 & 8) == 0) { + par1World.setBlockMetadata(par2, par3, par4, var6 | 8, 4); + } else { + this.growTree(par1World, par2, par3, par4, par5Random); + } + } + + /** + * Attempts to grow a sapling into a tree + */ + public void growTree(World par1World, int par2, int par3, int par4, Random par5Random) { + int var6 = par1World.getBlockMetadata(par2, par3, par4) & 3; + Object var7 = null; + int var8 = 0; + int var9 = 0; + boolean var10 = false; + + if (var6 == 1) { + var7 = new WorldGenTaiga2(true); + } else if (var6 == 2) { + var7 = new WorldGenForest(true); + } else if (var6 == 3) { + for (var8 = 0; var8 >= -1; --var8) { + for (var9 = 0; var9 >= -1; --var9) { + if (this.isSameSapling(par1World, par2 + var8, par3, par4 + var9, 3) + && this.isSameSapling(par1World, par2 + var8 + 1, par3, par4 + var9, 3) + && this.isSameSapling(par1World, par2 + var8, par3, par4 + var9 + 1, 3) + && this.isSameSapling(par1World, par2 + var8 + 1, par3, par4 + var9 + 1, 3)) { + var7 = new WorldGenHugeTrees(true, 10 + par5Random.nextInt(20), 3, 3); + var10 = true; + break; + } + } + + if (var7 != null) { + break; + } + } + + if (var7 == null) { + var9 = 0; + var8 = 0; + var7 = new WorldGenTrees(true, 4 + par5Random.nextInt(7), 3, 3, false); + } + } else { + var7 = new WorldGenTrees(true); + + if (par5Random.nextInt(10) == 0) { + var7 = new WorldGenBigTree(true); + } + } + + if (var10) { + par1World.setBlock(par2 + var8, par3, par4 + var9, 0, 0, 4); + par1World.setBlock(par2 + var8 + 1, par3, par4 + var9, 0, 0, 4); + par1World.setBlock(par2 + var8, par3, par4 + var9 + 1, 0, 0, 4); + par1World.setBlock(par2 + var8 + 1, par3, par4 + var9 + 1, 0, 0, 4); + } else { + par1World.setBlock(par2, par3, par4, 0, 0, 4); + } + + if (!((WorldGenerator) var7).generate(par1World, par5Random, par2 + var8, par3, par4 + var9)) { + if (var10) { + par1World.setBlock(par2 + var8, par3, par4 + var9, this.blockID, var6, 4); + par1World.setBlock(par2 + var8 + 1, par3, par4 + var9, this.blockID, var6, 4); + par1World.setBlock(par2 + var8, par3, par4 + var9 + 1, this.blockID, var6, 4); + par1World.setBlock(par2 + var8 + 1, par3, par4 + var9 + 1, this.blockID, var6, 4); + } else { + par1World.setBlock(par2, par3, par4, this.blockID, var6, 4); + } + } + } + + /** + * Determines if the same sapling is present at the given location. + */ + public boolean isSameSapling(World par1World, int par2, int par3, int par4, int par5) { + return par1World.getBlockId(par2, par3, par4) == this.blockID + && (par1World.getBlockMetadata(par2, par3, par4) & 3) == par5; + } + + /** + * Determines the damage on the item the block drops. Used in cloth and wood. + */ + public int damageDropped(int par1) { + return par1 & 3; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockSign.java b/sp-server/src/main/java/net/minecraft/src/BlockSign.java new file mode 100644 index 0000000..bdc8b08 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockSign.java @@ -0,0 +1,146 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockSign extends BlockContainer { + private Class signEntityClass; + + /** Whether this is a freestanding sign or a wall-mounted sign */ + private boolean isFreestanding; + + protected BlockSign(int par1, Class par2Class, boolean par3) { + super(par1, Material.wood); + this.isFreestanding = par3; + this.signEntityClass = par2Class; + float var4 = 0.25F; + float var5 = 1.0F; + this.setBlockBounds(0.5F - var4, 0.0F, 0.5F - var4, 0.5F + var4, var5, 0.5F + var4); + } + + /** + * Returns a bounding box from the pool of bounding boxes (this means this box + * can change after the pool has been cleared to be reused) + */ + public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int par4) { + return null; + } + + /** + * Updates the blocks bounds based on its current state. Args: world, x, y, z + */ + public void setBlockBoundsBasedOnState(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + if (!this.isFreestanding) { + int var5 = par1IBlockAccess.getBlockMetadata(par2, par3, par4); + float var6 = 0.28125F; + float var7 = 0.78125F; + float var8 = 0.0F; + float var9 = 1.0F; + float var10 = 0.125F; + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + + if (var5 == 2) { + this.setBlockBounds(var8, var6, 1.0F - var10, var9, var7, 1.0F); + } + + if (var5 == 3) { + this.setBlockBounds(var8, var6, 0.0F, var9, var7, var10); + } + + if (var5 == 4) { + this.setBlockBounds(1.0F - var10, var6, var8, 1.0F, var7, var9); + } + + if (var5 == 5) { + this.setBlockBounds(0.0F, var6, var8, var10, var7, var9); + } + } + } + + /** + * The type of render function that is called for this block + */ + public int getRenderType() { + return -1; + } + + /** + * If this block doesn't render as an ordinary block it will return False + * (examples: signs, buttons, stairs, etc) + */ + public boolean renderAsNormalBlock() { + return false; + } + + public boolean getBlocksMovement(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + return true; + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return false; + } + + /** + * Returns a new instance of a block's tile entity class. Called on placing the + * block. + */ + public TileEntity createNewTileEntity(World par1World) { + try { + return (TileEntity) this.signEntityClass.newInstance(); + } catch (Exception var3) { + throw new RuntimeException(var3); + } + } + + /** + * Returns the ID of the items to drop on destruction. + */ + public int idDropped(int par1, Random par2Random, int par3) { + return Item.sign.itemID; + } + + /** + * Lets the block know when one of its neighbor changes. Doesn't know which + * neighbor changed (coordinates passed are their own) Args: x, y, z, neighbor + * blockID + */ + public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5) { + boolean var6 = false; + + if (this.isFreestanding) { + if (!par1World.getBlockMaterial(par2, par3 - 1, par4).isSolid()) { + var6 = true; + } + } else { + int var7 = par1World.getBlockMetadata(par2, par3, par4); + var6 = true; + + if (var7 == 2 && par1World.getBlockMaterial(par2, par3, par4 + 1).isSolid()) { + var6 = false; + } + + if (var7 == 3 && par1World.getBlockMaterial(par2, par3, par4 - 1).isSolid()) { + var6 = false; + } + + if (var7 == 4 && par1World.getBlockMaterial(par2 + 1, par3, par4).isSolid()) { + var6 = false; + } + + if (var7 == 5 && par1World.getBlockMaterial(par2 - 1, par3, par4).isSolid()) { + var6 = false; + } + } + + if (var6) { + this.dropBlockAsItem(par1World, par2, par3, par4, par1World.getBlockMetadata(par2, par3, par4), 0); + par1World.setBlockToAir(par2, par3, par4); + } + + super.onNeighborBlockChange(par1World, par2, par3, par4, par5); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockSilverfish.java b/sp-server/src/main/java/net/minecraft/src/BlockSilverfish.java new file mode 100644 index 0000000..a615478 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockSilverfish.java @@ -0,0 +1,79 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockSilverfish extends Block { + /** Block names that can be a silverfish stone. */ + public static final String[] silverfishStoneTypes = new String[] { "stone", "cobble", "brick" }; + + public BlockSilverfish(int par1) { + super(par1, Material.clay); + this.setHardness(0.0F); + this.setCreativeTab(CreativeTabs.tabDecorations); + } + + /** + * Called right before the block is destroyed by a player. Args: world, x, y, z, + * metaData + */ + public void onBlockDestroyedByPlayer(World par1World, int par2, int par3, int par4, int par5) { + if (!par1World.isRemote) { + EntitySilverfish var6 = new EntitySilverfish(par1World); + var6.setLocationAndAngles((double) par2 + 0.5D, (double) par3, (double) par4 + 0.5D, 0.0F, 0.0F); + par1World.spawnEntityInWorld(var6); + var6.spawnExplosionParticle(); + } + + super.onBlockDestroyedByPlayer(par1World, par2, par3, par4, par5); + } + + /** + * Returns the quantity of items to drop on block destruction. + */ + public int quantityDropped(Random par1Random) { + return 0; + } + + /** + * Gets the blockID of the block this block is pretending to be according to + * this block's metadata. + */ + public static boolean getPosingIdByMetadata(int par0) { + return par0 == Block.stone.blockID || par0 == Block.cobblestone.blockID || par0 == Block.stoneBrick.blockID; + } + + /** + * Returns the metadata to use when a Silverfish hides in the block. Sets the + * block to BlockSilverfish with this metadata. It changes the displayed texture + * client side to look like a normal block. + */ + public static int getMetadataForBlockType(int par0) { + return par0 == Block.cobblestone.blockID ? 1 : (par0 == Block.stoneBrick.blockID ? 2 : 0); + } + + /** + * Returns an item stack containing a single instance of the current block type. + * 'i' is the block's subtype/damage and is ignored for blocks which do not + * support subtypes. Blocks which cannot be harvested should return null. + */ + protected ItemStack createStackedBlock(int par1) { + Block var2 = Block.stone; + + if (par1 == 1) { + var2 = Block.cobblestone; + } + + if (par1 == 2) { + var2 = Block.stoneBrick; + } + + return new ItemStack(var2); + } + + /** + * Get the block's damage value (for use with pick block). + */ + public int getDamageValue(World par1World, int par2, int par3, int par4) { + return par1World.getBlockMetadata(par2, par3, par4); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockSkull.java b/sp-server/src/main/java/net/minecraft/src/BlockSkull.java new file mode 100644 index 0000000..7baf26a --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockSkull.java @@ -0,0 +1,267 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockSkull extends BlockContainer { + protected BlockSkull(int par1) { + super(par1, Material.circuits); + this.setBlockBounds(0.25F, 0.0F, 0.25F, 0.75F, 0.5F, 0.75F); + } + + /** + * The type of render function that is called for this block + */ + public int getRenderType() { + return -1; + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return false; + } + + /** + * If this block doesn't render as an ordinary block it will return False + * (examples: signs, buttons, stairs, etc) + */ + public boolean renderAsNormalBlock() { + return false; + } + + /** + * Updates the blocks bounds based on its current state. Args: world, x, y, z + */ + public void setBlockBoundsBasedOnState(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + int var5 = par1IBlockAccess.getBlockMetadata(par2, par3, par4) & 7; + + switch (var5) { + case 1: + default: + this.setBlockBounds(0.25F, 0.0F, 0.25F, 0.75F, 0.5F, 0.75F); + break; + + case 2: + this.setBlockBounds(0.25F, 0.25F, 0.5F, 0.75F, 0.75F, 1.0F); + break; + + case 3: + this.setBlockBounds(0.25F, 0.25F, 0.0F, 0.75F, 0.75F, 0.5F); + break; + + case 4: + this.setBlockBounds(0.5F, 0.25F, 0.25F, 1.0F, 0.75F, 0.75F); + break; + + case 5: + this.setBlockBounds(0.0F, 0.25F, 0.25F, 0.5F, 0.75F, 0.75F); + } + } + + /** + * Returns a bounding box from the pool of bounding boxes (this means this box + * can change after the pool has been cleared to be reused) + */ + public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int par4) { + this.setBlockBoundsBasedOnState(par1World, par2, par3, par4); + return super.getCollisionBoundingBoxFromPool(par1World, par2, par3, par4); + } + + /** + * Called when the block is placed in the world. + */ + public void onBlockPlacedBy(World par1World, int par2, int par3, int par4, EntityLiving par5EntityLiving, + ItemStack par6ItemStack) { + int var7 = MathHelper.floor_double((double) (par5EntityLiving.rotationYaw * 4.0F / 360.0F) + 2.5D) & 3; + par1World.setBlockMetadata(par2, par3, par4, var7, 2); + } + + /** + * Returns a new instance of a block's tile entity class. Called on placing the + * block. + */ + public TileEntity createNewTileEntity(World par1World) { + return new TileEntitySkull(); + } + + /** + * Get the block's damage value (for use with pick block). + */ + public int getDamageValue(World par1World, int par2, int par3, int par4) { + TileEntity var5 = par1World.getBlockTileEntity(par2, par3, par4); + return var5 != null && var5 instanceof TileEntitySkull ? ((TileEntitySkull) var5).getSkullType() + : super.getDamageValue(par1World, par2, par3, par4); + } + + /** + * Determines the damage on the item the block drops. Used in cloth and wood. + */ + public int damageDropped(int par1) { + return par1; + } + + /** + * Drops the block items with a specified chance of dropping the specified items + */ + public void dropBlockAsItemWithChance(World par1World, int par2, int par3, int par4, int par5, float par6, + int par7) { + } + + /** + * Called when the block is attempted to be harvested + */ + public void onBlockHarvested(World par1World, int par2, int par3, int par4, int par5, + EntityPlayer par6EntityPlayer) { + if (par6EntityPlayer.capabilities.isCreativeMode) { + par5 |= 8; + par1World.setBlockMetadata(par2, par3, par4, par5, 4); + } + + super.onBlockHarvested(par1World, par2, par3, par4, par5, par6EntityPlayer); + } + + /** + * ejects contained items into the world, and notifies neighbours of an update, + * as appropriate + */ + public void breakBlock(World par1World, int par2, int par3, int par4, int par5, int par6) { + if (!par1World.isRemote) { + if ((par6 & 8) == 0) { + ItemStack var7 = new ItemStack(Item.skull.itemID, 1, this.getDamageValue(par1World, par2, par3, par4)); + TileEntitySkull var8 = (TileEntitySkull) par1World.getBlockTileEntity(par2, par3, par4); + + if (var8.getSkullType() == 3 && var8.getExtraType() != null && var8.getExtraType().length() > 0) { + var7.setTagCompound(new NBTTagCompound()); + var7.getTagCompound().setString("SkullOwner", var8.getExtraType()); + } + + this.dropBlockAsItem_do(par1World, par2, par3, par4, var7); + } + + super.breakBlock(par1World, par2, par3, par4, par5, par6); + } + } + + /** + * Returns the ID of the items to drop on destruction. + */ + public int idDropped(int par1, Random par2Random, int par3) { + return Item.skull.itemID; + } + + /** + * This method attempts to create a wither at the given location and skull + */ + public void makeWither(World par1World, int par2, int par3, int par4, TileEntitySkull par5TileEntitySkull) { + if (par5TileEntitySkull.getSkullType() == 1 && par3 >= 2 && par1World.difficultySetting > 0 + && !par1World.isRemote) { + int var6 = Block.slowSand.blockID; + int var7; + EntityWither var8; + int var9; + + for (var7 = -2; var7 <= 0; ++var7) { + if (par1World.getBlockId(par2, par3 - 1, par4 + var7) == var6 + && par1World.getBlockId(par2, par3 - 1, par4 + var7 + 1) == var6 + && par1World.getBlockId(par2, par3 - 2, par4 + var7 + 1) == var6 + && par1World.getBlockId(par2, par3 - 1, par4 + var7 + 2) == var6 + && this.func_82528_d(par1World, par2, par3, par4 + var7, 1) + && this.func_82528_d(par1World, par2, par3, par4 + var7 + 1, 1) + && this.func_82528_d(par1World, par2, par3, par4 + var7 + 2, 1)) { + par1World.setBlockMetadata(par2, par3, par4 + var7, 8, 2); + par1World.setBlockMetadata(par2, par3, par4 + var7 + 1, 8, 2); + par1World.setBlockMetadata(par2, par3, par4 + var7 + 2, 8, 2); + par1World.setBlock(par2, par3, par4 + var7, 0, 0, 2); + par1World.setBlock(par2, par3, par4 + var7 + 1, 0, 0, 2); + par1World.setBlock(par2, par3, par4 + var7 + 2, 0, 0, 2); + par1World.setBlock(par2, par3 - 1, par4 + var7, 0, 0, 2); + par1World.setBlock(par2, par3 - 1, par4 + var7 + 1, 0, 0, 2); + par1World.setBlock(par2, par3 - 1, par4 + var7 + 2, 0, 0, 2); + par1World.setBlock(par2, par3 - 2, par4 + var7 + 1, 0, 0, 2); + + if (!par1World.isRemote) { + var8 = new EntityWither(par1World); + var8.setLocationAndAngles((double) par2 + 0.5D, (double) par3 - 1.45D, + (double) (par4 + var7) + 1.5D, 90.0F, 0.0F); + var8.renderYawOffset = 90.0F; + var8.func_82206_m(); + par1World.spawnEntityInWorld(var8); + } + + for (var9 = 0; var9 < 120; ++var9) { + par1World.spawnParticle("snowballpoof", (double) par2 + par1World.rand.nextDouble(), + (double) (par3 - 2) + par1World.rand.nextDouble() * 3.9D, + (double) (par4 + var7 + 1) + par1World.rand.nextDouble(), 0.0D, 0.0D, 0.0D); + } + + par1World.notifyBlockChange(par2, par3, par4 + var7, 0); + par1World.notifyBlockChange(par2, par3, par4 + var7 + 1, 0); + par1World.notifyBlockChange(par2, par3, par4 + var7 + 2, 0); + par1World.notifyBlockChange(par2, par3 - 1, par4 + var7, 0); + par1World.notifyBlockChange(par2, par3 - 1, par4 + var7 + 1, 0); + par1World.notifyBlockChange(par2, par3 - 1, par4 + var7 + 2, 0); + par1World.notifyBlockChange(par2, par3 - 2, par4 + var7 + 1, 0); + return; + } + } + + for (var7 = -2; var7 <= 0; ++var7) { + if (par1World.getBlockId(par2 + var7, par3 - 1, par4) == var6 + && par1World.getBlockId(par2 + var7 + 1, par3 - 1, par4) == var6 + && par1World.getBlockId(par2 + var7 + 1, par3 - 2, par4) == var6 + && par1World.getBlockId(par2 + var7 + 2, par3 - 1, par4) == var6 + && this.func_82528_d(par1World, par2 + var7, par3, par4, 1) + && this.func_82528_d(par1World, par2 + var7 + 1, par3, par4, 1) + && this.func_82528_d(par1World, par2 + var7 + 2, par3, par4, 1)) { + par1World.setBlockMetadata(par2 + var7, par3, par4, 8, 2); + par1World.setBlockMetadata(par2 + var7 + 1, par3, par4, 8, 2); + par1World.setBlockMetadata(par2 + var7 + 2, par3, par4, 8, 2); + par1World.setBlock(par2 + var7, par3, par4, 0, 0, 2); + par1World.setBlock(par2 + var7 + 1, par3, par4, 0, 0, 2); + par1World.setBlock(par2 + var7 + 2, par3, par4, 0, 0, 2); + par1World.setBlock(par2 + var7, par3 - 1, par4, 0, 0, 2); + par1World.setBlock(par2 + var7 + 1, par3 - 1, par4, 0, 0, 2); + par1World.setBlock(par2 + var7 + 2, par3 - 1, par4, 0, 0, 2); + par1World.setBlock(par2 + var7 + 1, par3 - 2, par4, 0, 0, 2); + + if (!par1World.isRemote) { + var8 = new EntityWither(par1World); + var8.setLocationAndAngles((double) (par2 + var7) + 1.5D, (double) par3 - 1.45D, + (double) par4 + 0.5D, 0.0F, 0.0F); + var8.func_82206_m(); + par1World.spawnEntityInWorld(var8); + } + + for (var9 = 0; var9 < 120; ++var9) { + par1World.spawnParticle("snowballpoof", + (double) (par2 + var7 + 1) + par1World.rand.nextDouble(), + (double) (par3 - 2) + par1World.rand.nextDouble() * 3.9D, + (double) par4 + par1World.rand.nextDouble(), 0.0D, 0.0D, 0.0D); + } + + par1World.notifyBlockChange(par2 + var7, par3, par4, 0); + par1World.notifyBlockChange(par2 + var7 + 1, par3, par4, 0); + par1World.notifyBlockChange(par2 + var7 + 2, par3, par4, 0); + par1World.notifyBlockChange(par2 + var7, par3 - 1, par4, 0); + par1World.notifyBlockChange(par2 + var7 + 1, par3 - 1, par4, 0); + par1World.notifyBlockChange(par2 + var7 + 2, par3 - 1, par4, 0); + par1World.notifyBlockChange(par2 + var7 + 1, par3 - 2, par4, 0); + return; + } + } + } + } + + private boolean func_82528_d(World par1World, int par2, int par3, int par4, int par5) { + if (par1World.getBlockId(par2, par3, par4) != this.blockID) { + return false; + } else { + TileEntity var6 = par1World.getBlockTileEntity(par2, par3, par4); + return var6 != null && var6 instanceof TileEntitySkull ? ((TileEntitySkull) var6).getSkullType() == par5 + : false; + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockSnow.java b/sp-server/src/main/java/net/minecraft/src/BlockSnow.java new file mode 100644 index 0000000..dc9886e --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockSnow.java @@ -0,0 +1,136 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockSnow extends Block { + protected BlockSnow(int par1) { + super(par1, Material.snow); + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.125F, 1.0F); + this.setTickRandomly(true); + this.setCreativeTab(CreativeTabs.tabDecorations); + this.setBlockBoundsForSnowDepth(0); + } + + /** + * Returns a bounding box from the pool of bounding boxes (this means this box + * can change after the pool has been cleared to be reused) + */ + public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int par4) { + int var5 = par1World.getBlockMetadata(par2, par3, par4) & 7; + float var6 = 0.125F; + return AxisAlignedBB.getAABBPool().getAABB((double) par2 + this.minX, (double) par3 + this.minY, + (double) par4 + this.minZ, (double) par2 + this.maxX, (double) ((float) par3 + (float) var5 * var6), + (double) par4 + this.maxZ); + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return false; + } + + /** + * If this block doesn't render as an ordinary block it will return False + * (examples: signs, buttons, stairs, etc) + */ + public boolean renderAsNormalBlock() { + return false; + } + + /** + * Sets the block's bounds for rendering it as an item + */ + public void setBlockBoundsForItemRender() { + this.setBlockBoundsForSnowDepth(0); + } + + /** + * Updates the blocks bounds based on its current state. Args: world, x, y, z + */ + public void setBlockBoundsBasedOnState(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + this.setBlockBoundsForSnowDepth(par1IBlockAccess.getBlockMetadata(par2, par3, par4)); + } + + /** + * calls setBlockBounds based on the depth of the snow. Int is any values + * 0x0-0x7, usually this blocks metadata. + */ + protected void setBlockBoundsForSnowDepth(int par1) { + int var2 = par1 & 7; + float var3 = (float) (2 * (1 + var2)) / 16.0F; + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, var3, 1.0F); + } + + /** + * Checks to see if its valid to put this block at the specified coordinates. + * Args: world, x, y, z + */ + public boolean canPlaceBlockAt(World par1World, int par2, int par3, int par4) { + int var5 = par1World.getBlockId(par2, par3 - 1, par4); + return var5 == 0 ? false + : (var5 == this.blockID && (par1World.getBlockMetadata(par2, par3 - 1, par4) & 7) == 7 ? true + : (var5 != Block.leaves.blockID && !Block.blocksList[var5].isOpaqueCube() ? false + : par1World.getBlockMaterial(par2, par3 - 1, par4).blocksMovement())); + } + + /** + * Lets the block know when one of its neighbor changes. Doesn't know which + * neighbor changed (coordinates passed are their own) Args: x, y, z, neighbor + * blockID + */ + public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5) { + this.canSnowStay(par1World, par2, par3, par4); + } + + /** + * Checks if this snow block can stay at this location. + */ + private boolean canSnowStay(World par1World, int par2, int par3, int par4) { + if (!this.canPlaceBlockAt(par1World, par2, par3, par4)) { + this.dropBlockAsItem(par1World, par2, par3, par4, par1World.getBlockMetadata(par2, par3, par4), 0); + par1World.setBlockToAir(par2, par3, par4); + return false; + } else { + return true; + } + } + + /** + * Called when the player destroys a block with an item that can harvest it. (i, + * j, k) are the coordinates of the block and l is the block's subtype/damage. + */ + public void harvestBlock(World par1World, EntityPlayer par2EntityPlayer, int par3, int par4, int par5, int par6) { + int var7 = Item.snowball.itemID; + int var8 = par6 & 7; + this.dropBlockAsItem_do(par1World, par3, par4, par5, new ItemStack(var7, var8 + 1, 0)); + par1World.setBlockToAir(par3, par4, par5); + par2EntityPlayer.addStat(StatList.mineBlockStatArray[this.blockID], 1); + } + + /** + * Returns the ID of the items to drop on destruction. + */ + public int idDropped(int par1, Random par2Random, int par3) { + return Item.snowball.itemID; + } + + /** + * Returns the quantity of items to drop on block destruction. + */ + public int quantityDropped(Random par1Random) { + return 0; + } + + /** + * Ticks the block if it's been scheduled + */ + public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random) { + if (par1World.getSavedLightValue(EnumSkyBlock.Block, par2, par3, par4) > 11) { + this.dropBlockAsItem(par1World, par2, par3, par4, par1World.getBlockMetadata(par2, par3, par4), 0); + par1World.setBlockToAir(par2, par3, par4); + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockSnowBlock.java b/sp-server/src/main/java/net/minecraft/src/BlockSnowBlock.java new file mode 100644 index 0000000..359d96e --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockSnowBlock.java @@ -0,0 +1,35 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockSnowBlock extends Block { + protected BlockSnowBlock(int par1) { + super(par1, Material.craftedSnow); + this.setTickRandomly(true); + this.setCreativeTab(CreativeTabs.tabBlock); + } + + /** + * Returns the ID of the items to drop on destruction. + */ + public int idDropped(int par1, Random par2Random, int par3) { + return Item.snowball.itemID; + } + + /** + * Returns the quantity of items to drop on block destruction. + */ + public int quantityDropped(Random par1Random) { + return 4; + } + + /** + * Ticks the block if it's been scheduled + */ + public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random) { + if (par1World.getSavedLightValue(EnumSkyBlock.Block, par2, par3, par4) > 11) { + this.dropBlockAsItem(par1World, par2, par3, par4, par1World.getBlockMetadata(par2, par3, par4), 0); + par1World.setBlockToAir(par2, par3, par4); + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockSoulSand.java b/sp-server/src/main/java/net/minecraft/src/BlockSoulSand.java new file mode 100644 index 0000000..a1f23cc --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockSoulSand.java @@ -0,0 +1,27 @@ +package net.minecraft.src; + +public class BlockSoulSand extends Block { + public BlockSoulSand(int par1) { + super(par1, Material.sand); + this.setCreativeTab(CreativeTabs.tabBlock); + } + + /** + * Returns a bounding box from the pool of bounding boxes (this means this box + * can change after the pool has been cleared to be reused) + */ + public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int par4) { + float var5 = 0.125F; + return AxisAlignedBB.getAABBPool().getAABB((double) par2, (double) par3, (double) par4, (double) (par2 + 1), + (double) ((float) (par3 + 1) - var5), (double) (par4 + 1)); + } + + /** + * Triggered whenever an entity collides with this block (enters into the + * block). Args: world, x, y, z, entity + */ + public void onEntityCollidedWithBlock(World par1World, int par2, int par3, int par4, Entity par5Entity) { + par5Entity.motionX *= 0.4D; + par5Entity.motionZ *= 0.4D; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockSourceImpl.java b/sp-server/src/main/java/net/minecraft/src/BlockSourceImpl.java new file mode 100644 index 0000000..f114e1a --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockSourceImpl.java @@ -0,0 +1,51 @@ +package net.minecraft.src; + +public class BlockSourceImpl implements IBlockSource { + private final World worldObj; + private final int xPos; + private final int yPos; + private final int zPos; + + public BlockSourceImpl(World par1World, int par2, int par3, int par4) { + this.worldObj = par1World; + this.xPos = par2; + this.yPos = par3; + this.zPos = par4; + } + + public World getWorld() { + return this.worldObj; + } + + public double getX() { + return (double) this.xPos + 0.5D; + } + + public double getY() { + return (double) this.yPos + 0.5D; + } + + public double getZ() { + return (double) this.zPos + 0.5D; + } + + public int getXInt() { + return this.xPos; + } + + public int getYInt() { + return this.yPos; + } + + public int getZInt() { + return this.zPos; + } + + public int getBlockMetadata() { + return this.worldObj.getBlockMetadata(this.xPos, this.yPos, this.zPos); + } + + public TileEntity getBlockTileEntity() { + return this.worldObj.getBlockTileEntity(this.xPos, this.yPos, this.zPos); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockSponge.java b/sp-server/src/main/java/net/minecraft/src/BlockSponge.java new file mode 100644 index 0000000..866c50f --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockSponge.java @@ -0,0 +1,8 @@ +package net.minecraft.src; + +public class BlockSponge extends Block { + protected BlockSponge(int par1) { + super(par1, Material.sponge); + this.setCreativeTab(CreativeTabs.tabBlock); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockStairs.java b/sp-server/src/main/java/net/minecraft/src/BlockStairs.java new file mode 100644 index 0000000..cde6287 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockStairs.java @@ -0,0 +1,495 @@ +package net.minecraft.src; + +import java.util.List; +import java.util.Random; + +public class BlockStairs extends Block { + private static final int[][] field_72159_a = new int[][] { { 2, 6 }, { 3, 7 }, { 2, 3 }, { 6, 7 }, { 0, 4 }, + { 1, 5 }, { 0, 1 }, { 4, 5 } }; + + /** The block that is used as model for the stair. */ + private final Block modelBlock; + private final int modelBlockMetadata; + private boolean field_72156_cr = false; + private int field_72160_cs = 0; + + protected BlockStairs(int par1, Block par2Block, int par3) { + super(par1, par2Block.blockMaterial); + this.modelBlock = par2Block; + this.modelBlockMetadata = par3; + this.setHardness(par2Block.blockHardness); + this.setResistance(par2Block.blockResistance / 3.0F); + this.setStepSound(par2Block.stepSound); + this.setLightOpacity(255); + this.setCreativeTab(CreativeTabs.tabBlock); + } + + /** + * Updates the blocks bounds based on its current state. Args: world, x, y, z + */ + public void setBlockBoundsBasedOnState(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + if (this.field_72156_cr) { + this.setBlockBounds(0.5F * (float) (this.field_72160_cs % 2), 0.5F * (float) (this.field_72160_cs / 2 % 2), + 0.5F * (float) (this.field_72160_cs / 4 % 2), 0.5F + 0.5F * (float) (this.field_72160_cs % 2), + 0.5F + 0.5F * (float) (this.field_72160_cs / 2 % 2), + 0.5F + 0.5F * (float) (this.field_72160_cs / 4 % 2)); + } else { + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + } + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return false; + } + + /** + * If this block doesn't render as an ordinary block it will return False + * (examples: signs, buttons, stairs, etc) + */ + public boolean renderAsNormalBlock() { + return false; + } + + /** + * The type of render function that is called for this block + */ + public int getRenderType() { + return 10; + } + + public void func_82541_d(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + int var5 = par1IBlockAccess.getBlockMetadata(par2, par3, par4); + + if ((var5 & 4) != 0) { + this.setBlockBounds(0.0F, 0.5F, 0.0F, 1.0F, 1.0F, 1.0F); + } else { + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.5F, 1.0F); + } + } + + /** + * Checks if supplied ID is one of a BlockStairs + */ + public static boolean isBlockStairsID(int par0) { + return par0 > 0 && Block.blocksList[par0] instanceof BlockStairs; + } + + private boolean func_82540_f(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5) { + int var6 = par1IBlockAccess.getBlockId(par2, par3, par4); + return isBlockStairsID(var6) && par1IBlockAccess.getBlockMetadata(par2, par3, par4) == par5; + } + + public boolean func_82542_g(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + int var5 = par1IBlockAccess.getBlockMetadata(par2, par3, par4); + int var6 = var5 & 3; + float var7 = 0.5F; + float var8 = 1.0F; + + if ((var5 & 4) != 0) { + var7 = 0.0F; + var8 = 0.5F; + } + + float var9 = 0.0F; + float var10 = 1.0F; + float var11 = 0.0F; + float var12 = 0.5F; + boolean var13 = true; + int var14; + int var15; + int var16; + + if (var6 == 0) { + var9 = 0.5F; + var12 = 1.0F; + var14 = par1IBlockAccess.getBlockId(par2 + 1, par3, par4); + var15 = par1IBlockAccess.getBlockMetadata(par2 + 1, par3, par4); + + if (isBlockStairsID(var14) && (var5 & 4) == (var15 & 4)) { + var16 = var15 & 3; + + if (var16 == 3 && !this.func_82540_f(par1IBlockAccess, par2, par3, par4 + 1, var5)) { + var12 = 0.5F; + var13 = false; + } else if (var16 == 2 && !this.func_82540_f(par1IBlockAccess, par2, par3, par4 - 1, var5)) { + var11 = 0.5F; + var13 = false; + } + } + } else if (var6 == 1) { + var10 = 0.5F; + var12 = 1.0F; + var14 = par1IBlockAccess.getBlockId(par2 - 1, par3, par4); + var15 = par1IBlockAccess.getBlockMetadata(par2 - 1, par3, par4); + + if (isBlockStairsID(var14) && (var5 & 4) == (var15 & 4)) { + var16 = var15 & 3; + + if (var16 == 3 && !this.func_82540_f(par1IBlockAccess, par2, par3, par4 + 1, var5)) { + var12 = 0.5F; + var13 = false; + } else if (var16 == 2 && !this.func_82540_f(par1IBlockAccess, par2, par3, par4 - 1, var5)) { + var11 = 0.5F; + var13 = false; + } + } + } else if (var6 == 2) { + var11 = 0.5F; + var12 = 1.0F; + var14 = par1IBlockAccess.getBlockId(par2, par3, par4 + 1); + var15 = par1IBlockAccess.getBlockMetadata(par2, par3, par4 + 1); + + if (isBlockStairsID(var14) && (var5 & 4) == (var15 & 4)) { + var16 = var15 & 3; + + if (var16 == 1 && !this.func_82540_f(par1IBlockAccess, par2 + 1, par3, par4, var5)) { + var10 = 0.5F; + var13 = false; + } else if (var16 == 0 && !this.func_82540_f(par1IBlockAccess, par2 - 1, par3, par4, var5)) { + var9 = 0.5F; + var13 = false; + } + } + } else if (var6 == 3) { + var14 = par1IBlockAccess.getBlockId(par2, par3, par4 - 1); + var15 = par1IBlockAccess.getBlockMetadata(par2, par3, par4 - 1); + + if (isBlockStairsID(var14) && (var5 & 4) == (var15 & 4)) { + var16 = var15 & 3; + + if (var16 == 1 && !this.func_82540_f(par1IBlockAccess, par2 + 1, par3, par4, var5)) { + var10 = 0.5F; + var13 = false; + } else if (var16 == 0 && !this.func_82540_f(par1IBlockAccess, par2 - 1, par3, par4, var5)) { + var9 = 0.5F; + var13 = false; + } + } + } + + this.setBlockBounds(var9, var7, var11, var10, var8, var12); + return var13; + } + + public boolean func_82544_h(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + int var5 = par1IBlockAccess.getBlockMetadata(par2, par3, par4); + int var6 = var5 & 3; + float var7 = 0.5F; + float var8 = 1.0F; + + if ((var5 & 4) != 0) { + var7 = 0.0F; + var8 = 0.5F; + } + + float var9 = 0.0F; + float var10 = 0.5F; + float var11 = 0.5F; + float var12 = 1.0F; + boolean var13 = false; + int var14; + int var15; + int var16; + + if (var6 == 0) { + var14 = par1IBlockAccess.getBlockId(par2 - 1, par3, par4); + var15 = par1IBlockAccess.getBlockMetadata(par2 - 1, par3, par4); + + if (isBlockStairsID(var14) && (var5 & 4) == (var15 & 4)) { + var16 = var15 & 3; + + if (var16 == 3 && !this.func_82540_f(par1IBlockAccess, par2, par3, par4 - 1, var5)) { + var11 = 0.0F; + var12 = 0.5F; + var13 = true; + } else if (var16 == 2 && !this.func_82540_f(par1IBlockAccess, par2, par3, par4 + 1, var5)) { + var11 = 0.5F; + var12 = 1.0F; + var13 = true; + } + } + } else if (var6 == 1) { + var14 = par1IBlockAccess.getBlockId(par2 + 1, par3, par4); + var15 = par1IBlockAccess.getBlockMetadata(par2 + 1, par3, par4); + + if (isBlockStairsID(var14) && (var5 & 4) == (var15 & 4)) { + var9 = 0.5F; + var10 = 1.0F; + var16 = var15 & 3; + + if (var16 == 3 && !this.func_82540_f(par1IBlockAccess, par2, par3, par4 - 1, var5)) { + var11 = 0.0F; + var12 = 0.5F; + var13 = true; + } else if (var16 == 2 && !this.func_82540_f(par1IBlockAccess, par2, par3, par4 + 1, var5)) { + var11 = 0.5F; + var12 = 1.0F; + var13 = true; + } + } + } else if (var6 == 2) { + var14 = par1IBlockAccess.getBlockId(par2, par3, par4 - 1); + var15 = par1IBlockAccess.getBlockMetadata(par2, par3, par4 - 1); + + if (isBlockStairsID(var14) && (var5 & 4) == (var15 & 4)) { + var11 = 0.0F; + var12 = 0.5F; + var16 = var15 & 3; + + if (var16 == 1 && !this.func_82540_f(par1IBlockAccess, par2 - 1, par3, par4, var5)) { + var13 = true; + } else if (var16 == 0 && !this.func_82540_f(par1IBlockAccess, par2 + 1, par3, par4, var5)) { + var9 = 0.5F; + var10 = 1.0F; + var13 = true; + } + } + } else if (var6 == 3) { + var14 = par1IBlockAccess.getBlockId(par2, par3, par4 + 1); + var15 = par1IBlockAccess.getBlockMetadata(par2, par3, par4 + 1); + + if (isBlockStairsID(var14) && (var5 & 4) == (var15 & 4)) { + var16 = var15 & 3; + + if (var16 == 1 && !this.func_82540_f(par1IBlockAccess, par2 - 1, par3, par4, var5)) { + var13 = true; + } else if (var16 == 0 && !this.func_82540_f(par1IBlockAccess, par2 + 1, par3, par4, var5)) { + var9 = 0.5F; + var10 = 1.0F; + var13 = true; + } + } + } + + if (var13) { + this.setBlockBounds(var9, var7, var11, var10, var8, var12); + } + + return var13; + } + + /** + * Adds all intersecting collision boxes to a list. (Be sure to only add boxes + * to the list if they intersect the mask.) Parameters: World, X, Y, Z, mask, + * list, colliding entity + */ + public void addCollisionBoxesToList(World par1World, int par2, int par3, int par4, AxisAlignedBB par5AxisAlignedBB, + List par6List, Entity par7Entity) { + this.func_82541_d(par1World, par2, par3, par4); + super.addCollisionBoxesToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity); + boolean var8 = this.func_82542_g(par1World, par2, par3, par4); + super.addCollisionBoxesToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity); + + if (var8 && this.func_82544_h(par1World, par2, par3, par4)) { + super.addCollisionBoxesToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity); + } + + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + } + + /** + * Called when the block is clicked by a player. Args: x, y, z, entityPlayer + */ + public void onBlockClicked(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer) { + this.modelBlock.onBlockClicked(par1World, par2, par3, par4, par5EntityPlayer); + } + + /** + * Called right before the block is destroyed by a player. Args: world, x, y, z, + * metaData + */ + public void onBlockDestroyedByPlayer(World par1World, int par2, int par3, int par4, int par5) { + this.modelBlock.onBlockDestroyedByPlayer(par1World, par2, par3, par4, par5); + } + + /** + * Returns how much this block can resist explosions from the passed in entity. + */ + public float getExplosionResistance(Entity par1Entity) { + return this.modelBlock.getExplosionResistance(par1Entity); + } + + /** + * How many world ticks before ticking + */ + public int tickRate(World par1World) { + return this.modelBlock.tickRate(par1World); + } + + /** + * Can add to the passed in vector for a movement vector to be applied to the + * entity. Args: x, y, z, entity, vec3d + */ + public void velocityToAddToEntity(World par1World, int par2, int par3, int par4, Entity par5Entity, Vec3 par6Vec3) { + this.modelBlock.velocityToAddToEntity(par1World, par2, par3, par4, par5Entity, par6Vec3); + } + + /** + * Returns if this block is collidable (only used by Fire). Args: x, y, z + */ + public boolean isCollidable() { + return this.modelBlock.isCollidable(); + } + + /** + * Returns whether this block is collideable based on the arguments passed in + * Args: blockMetaData, unknownFlag + */ + public boolean canCollideCheck(int par1, boolean par2) { + return this.modelBlock.canCollideCheck(par1, par2); + } + + /** + * Checks to see if its valid to put this block at the specified coordinates. + * Args: world, x, y, z + */ + public boolean canPlaceBlockAt(World par1World, int par2, int par3, int par4) { + return this.modelBlock.canPlaceBlockAt(par1World, par2, par3, par4); + } + + /** + * Called whenever the block is added into the world. Args: world, x, y, z + */ + public void onBlockAdded(World par1World, int par2, int par3, int par4) { + this.onNeighborBlockChange(par1World, par2, par3, par4, 0); + this.modelBlock.onBlockAdded(par1World, par2, par3, par4); + } + + /** + * ejects contained items into the world, and notifies neighbours of an update, + * as appropriate + */ + public void breakBlock(World par1World, int par2, int par3, int par4, int par5, int par6) { + this.modelBlock.breakBlock(par1World, par2, par3, par4, par5, par6); + } + + /** + * Called whenever an entity is walking on top of this block. Args: world, x, y, + * z, entity + */ + public void onEntityWalking(World par1World, int par2, int par3, int par4, Entity par5Entity) { + this.modelBlock.onEntityWalking(par1World, par2, par3, par4, par5Entity); + } + + /** + * Ticks the block if it's been scheduled + */ + public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random) { + this.modelBlock.updateTick(par1World, par2, par3, par4, par5Random); + } + + /** + * Called upon block activation (right click on the block.) + */ + public boolean onBlockActivated(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer, + int par6, float par7, float par8, float par9) { + return this.modelBlock.onBlockActivated(par1World, par2, par3, par4, par5EntityPlayer, 0, 0.0F, 0.0F, 0.0F); + } + + /** + * Called upon the block being destroyed by an explosion + */ + public void onBlockDestroyedByExplosion(World par1World, int par2, int par3, int par4, Explosion par5Explosion) { + this.modelBlock.onBlockDestroyedByExplosion(par1World, par2, par3, par4, par5Explosion); + } + + /** + * Called when the block is placed in the world. + */ + public void onBlockPlacedBy(World par1World, int par2, int par3, int par4, EntityLiving par5EntityLiving, + ItemStack par6ItemStack) { + int var7 = MathHelper.floor_double((double) (par5EntityLiving.rotationYaw * 4.0F / 360.0F) + 0.5D) & 3; + int var8 = par1World.getBlockMetadata(par2, par3, par4) & 4; + + if (var7 == 0) { + par1World.setBlockMetadata(par2, par3, par4, 2 | var8, 2); + } + + if (var7 == 1) { + par1World.setBlockMetadata(par2, par3, par4, 1 | var8, 2); + } + + if (var7 == 2) { + par1World.setBlockMetadata(par2, par3, par4, 3 | var8, 2); + } + + if (var7 == 3) { + par1World.setBlockMetadata(par2, par3, par4, 0 | var8, 2); + } + } + + /** + * Called when a block is placed using its ItemBlock. Args: World, X, Y, Z, + * side, hitX, hitY, hitZ, block metadata + */ + public int onBlockPlaced(World par1World, int par2, int par3, int par4, int par5, float par6, float par7, + float par8, int par9) { + return par5 != 0 && (par5 == 1 || (double) par7 <= 0.5D) ? par9 : par9 | 4; + } + + /** + * Ray traces through the blocks collision from start vector to end vector + * returning a ray trace hit. Args: world, x, y, z, startVec, endVec + */ + public MovingObjectPosition collisionRayTrace(World par1World, int par2, int par3, int par4, Vec3 par5Vec3, + Vec3 par6Vec3) { + MovingObjectPosition[] var7 = new MovingObjectPosition[8]; + int var8 = par1World.getBlockMetadata(par2, par3, par4); + int var9 = var8 & 3; + boolean var10 = (var8 & 4) == 4; + int[] var11 = field_72159_a[var9 + (var10 ? 4 : 0)]; + this.field_72156_cr = true; + int var14; + int var15; + int var16; + + for (int var12 = 0; var12 < 8; ++var12) { + this.field_72160_cs = var12; + int[] var13 = var11; + var14 = var11.length; + + for (var15 = 0; var15 < var14; ++var15) { + var16 = var13[var15]; + + if (var16 == var12) { + ; + } + } + + var7[var12] = super.collisionRayTrace(par1World, par2, par3, par4, par5Vec3, par6Vec3); + } + + int[] var21 = var11; + int var23 = var11.length; + + for (var14 = 0; var14 < var23; ++var14) { + var15 = var21[var14]; + var7[var15] = null; + } + + MovingObjectPosition var22 = null; + double var24 = 0.0D; + MovingObjectPosition[] var25 = var7; + var16 = var7.length; + + for (int var17 = 0; var17 < var16; ++var17) { + MovingObjectPosition var18 = var25[var17]; + + if (var18 != null) { + double var19 = var18.hitVec.squareDistanceTo(par6Vec3); + + if (var19 > var24) { + var22 = var18; + var24 = var19; + } + } + } + + return var22; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockStationary.java b/sp-server/src/main/java/net/minecraft/src/BlockStationary.java new file mode 100644 index 0000000..5d52ea5 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockStationary.java @@ -0,0 +1,93 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockStationary extends BlockFluid { + protected BlockStationary(int par1, Material par2Material) { + super(par1, par2Material); + this.setTickRandomly(false); + + if (par2Material == Material.lava) { + this.setTickRandomly(true); + } + } + + public boolean getBlocksMovement(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + return this.blockMaterial != Material.lava; + } + + /** + * Lets the block know when one of its neighbor changes. Doesn't know which + * neighbor changed (coordinates passed are their own) Args: x, y, z, neighbor + * blockID + */ + public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5) { + super.onNeighborBlockChange(par1World, par2, par3, par4, par5); + + if (par1World.getBlockId(par2, par3, par4) == this.blockID) { + this.setNotStationary(par1World, par2, par3, par4); + } + } + + /** + * Changes the block ID to that of an updating fluid. + */ + private void setNotStationary(World par1World, int par2, int par3, int par4) { + int var5 = par1World.getBlockMetadata(par2, par3, par4); + par1World.setBlock(par2, par3, par4, this.blockID - 1, var5, 2); + par1World.scheduleBlockUpdate(par2, par3, par4, this.blockID - 1, this.tickRate(par1World)); + } + + /** + * Ticks the block if it's been scheduled + */ + public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random) { + if (this.blockMaterial == Material.lava) { + int var6 = par5Random.nextInt(3); + int var7; + int var8; + + for (var7 = 0; var7 < var6; ++var7) { + par2 += par5Random.nextInt(3) - 1; + ++par3; + par4 += par5Random.nextInt(3) - 1; + var8 = par1World.getBlockId(par2, par3, par4); + + if (var8 == 0) { + if (this.isFlammable(par1World, par2 - 1, par3, par4) + || this.isFlammable(par1World, par2 + 1, par3, par4) + || this.isFlammable(par1World, par2, par3, par4 - 1) + || this.isFlammable(par1World, par2, par3, par4 + 1) + || this.isFlammable(par1World, par2, par3 - 1, par4) + || this.isFlammable(par1World, par2, par3 + 1, par4)) { + par1World.setBlock(par2, par3, par4, Block.fire.blockID); + return; + } + } else if (Block.blocksList[var8].blockMaterial.blocksMovement()) { + return; + } + } + + if (var6 == 0) { + var7 = par2; + var8 = par4; + + for (int var9 = 0; var9 < 3; ++var9) { + par2 = var7 + par5Random.nextInt(3) - 1; + par4 = var8 + par5Random.nextInt(3) - 1; + + if (par1World.isAirBlock(par2, par3 + 1, par4) && this.isFlammable(par1World, par2, par3, par4)) { + par1World.setBlock(par2, par3 + 1, par4, Block.fire.blockID); + } + } + } + } + } + + /** + * Checks to see if the block is flammable. + */ + private boolean isFlammable(World par1World, int par2, int par3, int par4) { + return par1World.getBlockMaterial(par2, par3, par4).getCanBurn(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockStem.java b/sp-server/src/main/java/net/minecraft/src/BlockStem.java new file mode 100644 index 0000000..16448b8 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockStem.java @@ -0,0 +1,206 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockStem extends BlockFlower { + /** Defines if it is a Melon or a Pumpkin that the stem is producing. */ + private final Block fruitType; + + protected BlockStem(int par1, Block par2Block) { + super(par1); + this.fruitType = par2Block; + this.setTickRandomly(true); + float var3 = 0.125F; + this.setBlockBounds(0.5F - var3, 0.0F, 0.5F - var3, 0.5F + var3, 0.25F, 0.5F + var3); + this.setCreativeTab((CreativeTabs) null); + } + + /** + * Gets passed in the blockID of the block below and supposed to return true if + * its allowed to grow on the type of blockID passed in. Args: blockID + */ + protected boolean canThisPlantGrowOnThisBlockID(int par1) { + return par1 == Block.tilledField.blockID; + } + + /** + * Ticks the block if it's been scheduled + */ + public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random) { + super.updateTick(par1World, par2, par3, par4, par5Random); + + if (par1World.getBlockLightValue(par2, par3 + 1, par4) >= 9) { + float var6 = this.getGrowthModifier(par1World, par2, par3, par4); + + if (par5Random.nextInt((int) (25.0F / var6) + 1) == 0) { + int var7 = par1World.getBlockMetadata(par2, par3, par4); + + if (var7 < 7) { + ++var7; + par1World.setBlockMetadata(par2, par3, par4, var7, 2); + } else { + if (par1World.getBlockId(par2 - 1, par3, par4) == this.fruitType.blockID) { + return; + } + + if (par1World.getBlockId(par2 + 1, par3, par4) == this.fruitType.blockID) { + return; + } + + if (par1World.getBlockId(par2, par3, par4 - 1) == this.fruitType.blockID) { + return; + } + + if (par1World.getBlockId(par2, par3, par4 + 1) == this.fruitType.blockID) { + return; + } + + int var8 = par5Random.nextInt(4); + int var9 = par2; + int var10 = par4; + + if (var8 == 0) { + var9 = par2 - 1; + } + + if (var8 == 1) { + ++var9; + } + + if (var8 == 2) { + var10 = par4 - 1; + } + + if (var8 == 3) { + ++var10; + } + + int var11 = par1World.getBlockId(var9, par3 - 1, var10); + + if (par1World.getBlockId(var9, par3, var10) == 0 && (var11 == Block.tilledField.blockID + || var11 == Block.dirt.blockID || var11 == Block.grass.blockID)) { + par1World.setBlock(var9, par3, var10, this.fruitType.blockID); + } + } + } + } + } + + public void fertilizeStem(World par1World, int par2, int par3, int par4) { + int var5 = par1World.getBlockMetadata(par2, par3, par4) + + MathHelper.getRandomIntegerInRange(par1World.rand, 2, 5); + + if (var5 > 7) { + var5 = 7; + } + + par1World.setBlockMetadata(par2, par3, par4, var5, 2); + } + + private float getGrowthModifier(World par1World, int par2, int par3, int par4) { + float var5 = 1.0F; + int var6 = par1World.getBlockId(par2, par3, par4 - 1); + int var7 = par1World.getBlockId(par2, par3, par4 + 1); + int var8 = par1World.getBlockId(par2 - 1, par3, par4); + int var9 = par1World.getBlockId(par2 + 1, par3, par4); + int var10 = par1World.getBlockId(par2 - 1, par3, par4 - 1); + int var11 = par1World.getBlockId(par2 + 1, par3, par4 - 1); + int var12 = par1World.getBlockId(par2 + 1, par3, par4 + 1); + int var13 = par1World.getBlockId(par2 - 1, par3, par4 + 1); + boolean var14 = var8 == this.blockID || var9 == this.blockID; + boolean var15 = var6 == this.blockID || var7 == this.blockID; + boolean var16 = var10 == this.blockID || var11 == this.blockID || var12 == this.blockID + || var13 == this.blockID; + + for (int var17 = par2 - 1; var17 <= par2 + 1; ++var17) { + for (int var18 = par4 - 1; var18 <= par4 + 1; ++var18) { + int var19 = par1World.getBlockId(var17, par3 - 1, var18); + float var20 = 0.0F; + + if (var19 == Block.tilledField.blockID) { + var20 = 1.0F; + + if (par1World.getBlockMetadata(var17, par3 - 1, var18) > 0) { + var20 = 3.0F; + } + } + + if (var17 != par2 || var18 != par4) { + var20 /= 4.0F; + } + + var5 += var20; + } + } + + if (var16 || var14 && var15) { + var5 /= 2.0F; + } + + return var5; + } + + /** + * Sets the block's bounds for rendering it as an item + */ + public void setBlockBoundsForItemRender() { + float var1 = 0.125F; + this.setBlockBounds(0.5F - var1, 0.0F, 0.5F - var1, 0.5F + var1, 0.25F, 0.5F + var1); + } + + /** + * Updates the blocks bounds based on its current state. Args: world, x, y, z + */ + public void setBlockBoundsBasedOnState(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + this.maxY = (double) ((float) (par1IBlockAccess.getBlockMetadata(par2, par3, par4) * 2 + 2) / 16.0F); + float var5 = 0.125F; + this.setBlockBounds(0.5F - var5, 0.0F, 0.5F - var5, 0.5F + var5, (float) this.maxY, 0.5F + var5); + } + + /** + * The type of render function that is called for this block + */ + public int getRenderType() { + return 19; + } + + /** + * Drops the block items with a specified chance of dropping the specified items + */ + public void dropBlockAsItemWithChance(World par1World, int par2, int par3, int par4, int par5, float par6, + int par7) { + super.dropBlockAsItemWithChance(par1World, par2, par3, par4, par5, par6, par7); + + if (!par1World.isRemote) { + Item var8 = null; + + if (this.fruitType == Block.pumpkin) { + var8 = Item.pumpkinSeeds; + } + + if (this.fruitType == Block.melon) { + var8 = Item.melonSeeds; + } + + for (int var9 = 0; var9 < 3; ++var9) { + if (par1World.rand.nextInt(15) <= par5) { + this.dropBlockAsItem_do(par1World, par2, par3, par4, new ItemStack(var8)); + } + } + } + } + + /** + * Returns the ID of the items to drop on destruction. + */ + public int idDropped(int par1, Random par2Random, int par3) { + return -1; + } + + /** + * Returns the quantity of items to drop on block destruction. + */ + public int quantityDropped(Random par1Random) { + return 1; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockStep.java b/sp-server/src/main/java/net/minecraft/src/BlockStep.java new file mode 100644 index 0000000..a6dc6e3 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockStep.java @@ -0,0 +1,41 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockStep extends BlockHalfSlab { + /** The list of the types of step blocks. */ + public static final String[] blockStepTypes = new String[] { "stone", "sand", "wood", "cobble", "brick", + "smoothStoneBrick", "netherBrick", "quartz" }; + + public BlockStep(int par1, boolean par2) { + super(par1, par2, Material.rock); + this.setCreativeTab(CreativeTabs.tabBlock); + } + + /** + * Returns the ID of the items to drop on destruction. + */ + public int idDropped(int par1, Random par2Random, int par3) { + return Block.stoneSingleSlab.blockID; + } + + /** + * Returns an item stack containing a single instance of the current block type. + * 'i' is the block's subtype/damage and is ignored for blocks which do not + * support subtypes. Blocks which cannot be harvested should return null. + */ + protected ItemStack createStackedBlock(int par1) { + return new ItemStack(Block.stoneSingleSlab.blockID, 2, par1 & 7); + } + + /** + * Returns the slab block name with step type. + */ + public String getFullSlabName(int par1) { + if (par1 < 0 || par1 >= blockStepTypes.length) { + par1 = 0; + } + + return super.getUnlocalizedName() + "." + blockStepTypes[par1]; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockStone.java b/sp-server/src/main/java/net/minecraft/src/BlockStone.java new file mode 100644 index 0000000..7544ef2 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockStone.java @@ -0,0 +1,17 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockStone extends Block { + public BlockStone(int par1) { + super(par1, Material.rock); + this.setCreativeTab(CreativeTabs.tabBlock); + } + + /** + * Returns the ID of the items to drop on destruction. + */ + public int idDropped(int par1, Random par2Random, int par3) { + return Block.cobblestone.blockID; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockStoneBrick.java b/sp-server/src/main/java/net/minecraft/src/BlockStoneBrick.java new file mode 100644 index 0000000..f716abc --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockStoneBrick.java @@ -0,0 +1,19 @@ +package net.minecraft.src; + +public class BlockStoneBrick extends Block { + public static final String[] STONE_BRICK_TYPES = new String[] { "default", "mossy", "cracked", "chiseled" }; + public static final String[] field_94407_b = new String[] { "stonebricksmooth", "stonebricksmooth_mossy", + "stonebricksmooth_cracked", "stonebricksmooth_carved" }; + + public BlockStoneBrick(int par1) { + super(par1, Material.rock); + this.setCreativeTab(CreativeTabs.tabBlock); + } + + /** + * Determines the damage on the item the block drops. Used in cloth and wood. + */ + public int damageDropped(int par1) { + return par1; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockTNT.java b/sp-server/src/main/java/net/minecraft/src/BlockTNT.java new file mode 100644 index 0000000..572f1ec --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockTNT.java @@ -0,0 +1,110 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockTNT extends Block { + public BlockTNT(int par1) { + super(par1, Material.tnt); + this.setCreativeTab(CreativeTabs.tabRedstone); + } + + /** + * Called whenever the block is added into the world. Args: world, x, y, z + */ + public void onBlockAdded(World par1World, int par2, int par3, int par4) { + super.onBlockAdded(par1World, par2, par3, par4); + + if (par1World.isBlockIndirectlyGettingPowered(par2, par3, par4)) { + this.onBlockDestroyedByPlayer(par1World, par2, par3, par4, 1); + par1World.setBlockToAir(par2, par3, par4); + } + } + + /** + * Lets the block know when one of its neighbor changes. Doesn't know which + * neighbor changed (coordinates passed are their own) Args: x, y, z, neighbor + * blockID + */ + public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5) { + if (par1World.isBlockIndirectlyGettingPowered(par2, par3, par4)) { + this.onBlockDestroyedByPlayer(par1World, par2, par3, par4, 1); + par1World.setBlockToAir(par2, par3, par4); + } + } + + /** + * Returns the quantity of items to drop on block destruction. + */ + public int quantityDropped(Random par1Random) { + return 1; + } + + /** + * Called upon the block being destroyed by an explosion + */ + public void onBlockDestroyedByExplosion(World par1World, int par2, int par3, int par4, Explosion par5Explosion) { + if (!par1World.isRemote) { + EntityTNTPrimed var6 = new EntityTNTPrimed(par1World, (double) ((float) par2 + 0.5F), + (double) ((float) par3 + 0.5F), (double) ((float) par4 + 0.5F), par5Explosion.func_94613_c()); + var6.fuse = par1World.rand.nextInt(var6.fuse / 4) + var6.fuse / 8; + par1World.spawnEntityInWorld(var6); + } + } + + /** + * Called right before the block is destroyed by a player. Args: world, x, y, z, + * metaData + */ + public void onBlockDestroyedByPlayer(World par1World, int par2, int par3, int par4, int par5) { + this.func_94391_a(par1World, par2, par3, par4, par5, (EntityLiving) null); + } + + public void func_94391_a(World par1World, int par2, int par3, int par4, int par5, EntityLiving par6EntityLiving) { + if (!par1World.isRemote) { + if ((par5 & 1) == 1) { + EntityTNTPrimed var7 = new EntityTNTPrimed(par1World, (double) ((float) par2 + 0.5F), + (double) ((float) par3 + 0.5F), (double) ((float) par4 + 0.5F), par6EntityLiving); + par1World.spawnEntityInWorld(var7); + par1World.playSoundAtEntity(var7, "random.fuse", 1.0F, 1.0F); + } + } + } + + /** + * Called upon block activation (right click on the block.) + */ + public boolean onBlockActivated(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer, + int par6, float par7, float par8, float par9) { + if (par5EntityPlayer.getCurrentEquippedItem() != null + && par5EntityPlayer.getCurrentEquippedItem().itemID == Item.flintAndSteel.itemID) { + this.func_94391_a(par1World, par2, par3, par4, 1, par5EntityPlayer); + par1World.setBlockToAir(par2, par3, par4); + return true; + } else { + return super.onBlockActivated(par1World, par2, par3, par4, par5EntityPlayer, par6, par7, par8, par9); + } + } + + /** + * Triggered whenever an entity collides with this block (enters into the + * block). Args: world, x, y, z, entity + */ + public void onEntityCollidedWithBlock(World par1World, int par2, int par3, int par4, Entity par5Entity) { + if (par5Entity instanceof EntityArrow && !par1World.isRemote) { + EntityArrow var6 = (EntityArrow) par5Entity; + + if (var6.isBurning()) { + this.func_94391_a(par1World, par2, par3, par4, 1, + var6.shootingEntity instanceof EntityLiving ? (EntityLiving) var6.shootingEntity : null); + par1World.setBlockToAir(par2, par3, par4); + } + } + } + + /** + * Return whether this block can drop from an explosion. + */ + public boolean canDropFromExplosion(Explosion par1Explosion) { + return false; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockTallGrass.java b/sp-server/src/main/java/net/minecraft/src/BlockTallGrass.java new file mode 100644 index 0000000..82440db --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockTallGrass.java @@ -0,0 +1,49 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockTallGrass extends BlockFlower { + private static final String[] grassTypes = new String[] { "deadbush", "tallgrass", "fern" }; + + protected BlockTallGrass(int par1) { + super(par1, Material.vine); + float var2 = 0.4F; + this.setBlockBounds(0.5F - var2, 0.0F, 0.5F - var2, 0.5F + var2, 0.8F, 0.5F + var2); + } + + /** + * Returns the ID of the items to drop on destruction. + */ + public int idDropped(int par1, Random par2Random, int par3) { + return par2Random.nextInt(8) == 0 ? Item.seeds.itemID : -1; + } + + /** + * Returns the usual quantity dropped by the block plus a bonus of 1 to 'i' + * (inclusive). + */ + public int quantityDroppedWithBonus(int par1, Random par2Random) { + return 1 + par2Random.nextInt(par1 * 2 + 1); + } + + /** + * Called when the player destroys a block with an item that can harvest it. (i, + * j, k) are the coordinates of the block and l is the block's subtype/damage. + */ + public void harvestBlock(World par1World, EntityPlayer par2EntityPlayer, int par3, int par4, int par5, int par6) { + if (!par1World.isRemote && par2EntityPlayer.getCurrentEquippedItem() != null + && par2EntityPlayer.getCurrentEquippedItem().itemID == Item.shears.itemID) { + par2EntityPlayer.addStat(StatList.mineBlockStatArray[this.blockID], 1); + this.dropBlockAsItem_do(par1World, par3, par4, par5, new ItemStack(Block.tallGrass, 1, par6)); + } else { + super.harvestBlock(par1World, par2EntityPlayer, par3, par4, par5, par6); + } + } + + /** + * Get the block's damage value (for use with pick block). + */ + public int getDamageValue(World par1World, int par2, int par3, int par4) { + return par1World.getBlockMetadata(par2, par3, par4); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockTorch.java b/sp-server/src/main/java/net/minecraft/src/BlockTorch.java new file mode 100644 index 0000000..302c0b0 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockTorch.java @@ -0,0 +1,220 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockTorch extends Block { + protected BlockTorch(int par1) { + super(par1, Material.circuits); + this.setTickRandomly(true); + this.setCreativeTab(CreativeTabs.tabDecorations); + } + + /** + * Returns a bounding box from the pool of bounding boxes (this means this box + * can change after the pool has been cleared to be reused) + */ + public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int par4) { + return null; + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return false; + } + + /** + * If this block doesn't render as an ordinary block it will return False + * (examples: signs, buttons, stairs, etc) + */ + public boolean renderAsNormalBlock() { + return false; + } + + /** + * The type of render function that is called for this block + */ + public int getRenderType() { + return 2; + } + + /** + * Gets if we can place a torch on a block. + */ + private boolean canPlaceTorchOn(World par1World, int par2, int par3, int par4) { + if (par1World.doesBlockHaveSolidTopSurface(par2, par3, par4)) { + return true; + } else { + int var5 = par1World.getBlockId(par2, par3, par4); + return var5 == Block.fence.blockID || var5 == Block.netherFence.blockID || var5 == Block.glass.blockID + || var5 == Block.cobblestoneWall.blockID; + } + } + + /** + * Checks to see if its valid to put this block at the specified coordinates. + * Args: world, x, y, z + */ + public boolean canPlaceBlockAt(World par1World, int par2, int par3, int par4) { + return par1World.isBlockNormalCubeDefault(par2 - 1, par3, par4, true) ? true + : (par1World.isBlockNormalCubeDefault(par2 + 1, par3, par4, true) ? true + : (par1World.isBlockNormalCubeDefault(par2, par3, par4 - 1, true) ? true + : (par1World.isBlockNormalCubeDefault(par2, par3, par4 + 1, true) ? true + : this.canPlaceTorchOn(par1World, par2, par3 - 1, par4)))); + } + + /** + * Called when a block is placed using its ItemBlock. Args: World, X, Y, Z, + * side, hitX, hitY, hitZ, block metadata + */ + public int onBlockPlaced(World par1World, int par2, int par3, int par4, int par5, float par6, float par7, + float par8, int par9) { + int var10 = par9; + + if (par5 == 1 && this.canPlaceTorchOn(par1World, par2, par3 - 1, par4)) { + var10 = 5; + } + + if (par5 == 2 && par1World.isBlockNormalCubeDefault(par2, par3, par4 + 1, true)) { + var10 = 4; + } + + if (par5 == 3 && par1World.isBlockNormalCubeDefault(par2, par3, par4 - 1, true)) { + var10 = 3; + } + + if (par5 == 4 && par1World.isBlockNormalCubeDefault(par2 + 1, par3, par4, true)) { + var10 = 2; + } + + if (par5 == 5 && par1World.isBlockNormalCubeDefault(par2 - 1, par3, par4, true)) { + var10 = 1; + } + + return var10; + } + + /** + * Ticks the block if it's been scheduled + */ + public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random) { + super.updateTick(par1World, par2, par3, par4, par5Random); + + if (par1World.getBlockMetadata(par2, par3, par4) == 0) { + this.onBlockAdded(par1World, par2, par3, par4); + } + } + + /** + * Called whenever the block is added into the world. Args: world, x, y, z + */ + public void onBlockAdded(World par1World, int par2, int par3, int par4) { + if (par1World.getBlockMetadata(par2, par3, par4) == 0) { + if (par1World.isBlockNormalCubeDefault(par2 - 1, par3, par4, true)) { + par1World.setBlockMetadata(par2, par3, par4, 1, 2); + } else if (par1World.isBlockNormalCubeDefault(par2 + 1, par3, par4, true)) { + par1World.setBlockMetadata(par2, par3, par4, 2, 2); + } else if (par1World.isBlockNormalCubeDefault(par2, par3, par4 - 1, true)) { + par1World.setBlockMetadata(par2, par3, par4, 3, 2); + } else if (par1World.isBlockNormalCubeDefault(par2, par3, par4 + 1, true)) { + par1World.setBlockMetadata(par2, par3, par4, 4, 2); + } else if (this.canPlaceTorchOn(par1World, par2, par3 - 1, par4)) { + par1World.setBlockMetadata(par2, par3, par4, 5, 2); + } + } + + this.dropTorchIfCantStay(par1World, par2, par3, par4); + } + + /** + * Lets the block know when one of its neighbor changes. Doesn't know which + * neighbor changed (coordinates passed are their own) Args: x, y, z, neighbor + * blockID + */ + public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5) { + this.func_94397_d(par1World, par2, par3, par4, par5); + } + + protected boolean func_94397_d(World par1World, int par2, int par3, int par4, int par5) { + if (this.dropTorchIfCantStay(par1World, par2, par3, par4)) { + int var6 = par1World.getBlockMetadata(par2, par3, par4); + boolean var7 = false; + + if (!par1World.isBlockNormalCubeDefault(par2 - 1, par3, par4, true) && var6 == 1) { + var7 = true; + } + + if (!par1World.isBlockNormalCubeDefault(par2 + 1, par3, par4, true) && var6 == 2) { + var7 = true; + } + + if (!par1World.isBlockNormalCubeDefault(par2, par3, par4 - 1, true) && var6 == 3) { + var7 = true; + } + + if (!par1World.isBlockNormalCubeDefault(par2, par3, par4 + 1, true) && var6 == 4) { + var7 = true; + } + + if (!this.canPlaceTorchOn(par1World, par2, par3 - 1, par4) && var6 == 5) { + var7 = true; + } + + if (var7) { + this.dropBlockAsItem(par1World, par2, par3, par4, par1World.getBlockMetadata(par2, par3, par4), 0); + par1World.setBlockToAir(par2, par3, par4); + return true; + } else { + return false; + } + } else { + return true; + } + } + + /** + * Tests if the block can remain at its current location and will drop as an + * item if it is unable to stay. Returns True if it can stay and False if it + * drops. Args: world, x, y, z + */ + protected boolean dropTorchIfCantStay(World par1World, int par2, int par3, int par4) { + if (!this.canPlaceBlockAt(par1World, par2, par3, par4)) { + if (par1World.getBlockId(par2, par3, par4) == this.blockID) { + this.dropBlockAsItem(par1World, par2, par3, par4, par1World.getBlockMetadata(par2, par3, par4), 0); + par1World.setBlockToAir(par2, par3, par4); + } + + return false; + } else { + return true; + } + } + + /** + * Ray traces through the blocks collision from start vector to end vector + * returning a ray trace hit. Args: world, x, y, z, startVec, endVec + */ + public MovingObjectPosition collisionRayTrace(World par1World, int par2, int par3, int par4, Vec3 par5Vec3, + Vec3 par6Vec3) { + int var7 = par1World.getBlockMetadata(par2, par3, par4) & 7; + float var8 = 0.15F; + + if (var7 == 1) { + this.setBlockBounds(0.0F, 0.2F, 0.5F - var8, var8 * 2.0F, 0.8F, 0.5F + var8); + } else if (var7 == 2) { + this.setBlockBounds(1.0F - var8 * 2.0F, 0.2F, 0.5F - var8, 1.0F, 0.8F, 0.5F + var8); + } else if (var7 == 3) { + this.setBlockBounds(0.5F - var8, 0.2F, 0.0F, 0.5F + var8, 0.8F, var8 * 2.0F); + } else if (var7 == 4) { + this.setBlockBounds(0.5F - var8, 0.2F, 1.0F - var8 * 2.0F, 0.5F + var8, 0.8F, 1.0F); + } else { + var8 = 0.1F; + this.setBlockBounds(0.5F - var8, 0.0F, 0.5F - var8, 0.5F + var8, 0.6F, 0.5F + var8); + } + + return super.collisionRayTrace(par1World, par2, par3, par4, par5Vec3, par6Vec3); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockTrapDoor.java b/sp-server/src/main/java/net/minecraft/src/BlockTrapDoor.java new file mode 100644 index 0000000..f2d83a7 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockTrapDoor.java @@ -0,0 +1,251 @@ +package net.minecraft.src; + +public class BlockTrapDoor extends Block { + protected BlockTrapDoor(int par1, Material par2Material) { + super(par1, par2Material); + float var3 = 0.5F; + float var4 = 1.0F; + this.setBlockBounds(0.5F - var3, 0.0F, 0.5F - var3, 0.5F + var3, var4, 0.5F + var3); + this.setCreativeTab(CreativeTabs.tabRedstone); + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return false; + } + + /** + * If this block doesn't render as an ordinary block it will return False + * (examples: signs, buttons, stairs, etc) + */ + public boolean renderAsNormalBlock() { + return false; + } + + public boolean getBlocksMovement(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + return !isTrapdoorOpen(par1IBlockAccess.getBlockMetadata(par2, par3, par4)); + } + + /** + * The type of render function that is called for this block + */ + public int getRenderType() { + return 0; + } + + /** + * Returns a bounding box from the pool of bounding boxes (this means this box + * can change after the pool has been cleared to be reused) + */ + public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int par4) { + this.setBlockBoundsBasedOnState(par1World, par2, par3, par4); + return super.getCollisionBoundingBoxFromPool(par1World, par2, par3, par4); + } + + /** + * Updates the blocks bounds based on its current state. Args: world, x, y, z + */ + public void setBlockBoundsBasedOnState(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + this.setBlockBoundsForBlockRender(par1IBlockAccess.getBlockMetadata(par2, par3, par4)); + } + + /** + * Sets the block's bounds for rendering it as an item + */ + public void setBlockBoundsForItemRender() { + float var1 = 0.1875F; + this.setBlockBounds(0.0F, 0.5F - var1 / 2.0F, 0.0F, 1.0F, 0.5F + var1 / 2.0F, 1.0F); + } + + public void setBlockBoundsForBlockRender(int par1) { + float var2 = 0.1875F; + + if ((par1 & 8) != 0) { + this.setBlockBounds(0.0F, 1.0F - var2, 0.0F, 1.0F, 1.0F, 1.0F); + } else { + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, var2, 1.0F); + } + + if (isTrapdoorOpen(par1)) { + if ((par1 & 3) == 0) { + this.setBlockBounds(0.0F, 0.0F, 1.0F - var2, 1.0F, 1.0F, 1.0F); + } + + if ((par1 & 3) == 1) { + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, var2); + } + + if ((par1 & 3) == 2) { + this.setBlockBounds(1.0F - var2, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + } + + if ((par1 & 3) == 3) { + this.setBlockBounds(0.0F, 0.0F, 0.0F, var2, 1.0F, 1.0F); + } + } + } + + /** + * Called when the block is clicked by a player. Args: x, y, z, entityPlayer + */ + public void onBlockClicked(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer) { + } + + /** + * Called upon block activation (right click on the block.) + */ + public boolean onBlockActivated(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer, + int par6, float par7, float par8, float par9) { + if (this.blockMaterial == Material.iron) { + return true; + } else { + int var10 = par1World.getBlockMetadata(par2, par3, par4); + par1World.setBlockMetadata(par2, par3, par4, var10 ^ 4, 2); + par1World.playAuxSFXAtEntity(par5EntityPlayer, 1003, par2, par3, par4, 0); + return true; + } + } + + public void onPoweredBlockChange(World par1World, int par2, int par3, int par4, boolean par5) { + int var6 = par1World.getBlockMetadata(par2, par3, par4); + boolean var7 = (var6 & 4) > 0; + + if (var7 != par5) { + par1World.setBlockMetadata(par2, par3, par4, var6 ^ 4, 2); + par1World.playAuxSFXAtEntity((EntityPlayer) null, 1003, par2, par3, par4, 0); + } + } + + /** + * Lets the block know when one of its neighbor changes. Doesn't know which + * neighbor changed (coordinates passed are their own) Args: x, y, z, neighbor + * blockID + */ + public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5) { + if (!par1World.isRemote) { + int var6 = par1World.getBlockMetadata(par2, par3, par4); + int var7 = par2; + int var8 = par4; + + if ((var6 & 3) == 0) { + var8 = par4 + 1; + } + + if ((var6 & 3) == 1) { + --var8; + } + + if ((var6 & 3) == 2) { + var7 = par2 + 1; + } + + if ((var6 & 3) == 3) { + --var7; + } + + if (!isValidSupportBlock(par1World.getBlockId(var7, par3, var8))) { + par1World.setBlockToAir(par2, par3, par4); + this.dropBlockAsItem(par1World, par2, par3, par4, var6, 0); + } + + boolean var9 = par1World.isBlockIndirectlyGettingPowered(par2, par3, par4); + + if (var9 || par5 > 0 && Block.blocksList[par5].canProvidePower()) { + this.onPoweredBlockChange(par1World, par2, par3, par4, var9); + } + } + } + + /** + * Ray traces through the blocks collision from start vector to end vector + * returning a ray trace hit. Args: world, x, y, z, startVec, endVec + */ + public MovingObjectPosition collisionRayTrace(World par1World, int par2, int par3, int par4, Vec3 par5Vec3, + Vec3 par6Vec3) { + this.setBlockBoundsBasedOnState(par1World, par2, par3, par4); + return super.collisionRayTrace(par1World, par2, par3, par4, par5Vec3, par6Vec3); + } + + /** + * Called when a block is placed using its ItemBlock. Args: World, X, Y, Z, + * side, hitX, hitY, hitZ, block metadata + */ + public int onBlockPlaced(World par1World, int par2, int par3, int par4, int par5, float par6, float par7, + float par8, int par9) { + int var10 = 0; + + if (par5 == 2) { + var10 = 0; + } + + if (par5 == 3) { + var10 = 1; + } + + if (par5 == 4) { + var10 = 2; + } + + if (par5 == 5) { + var10 = 3; + } + + if (par5 != 1 && par5 != 0 && par7 > 0.5F) { + var10 |= 8; + } + + return var10; + } + + /** + * checks to see if you can place this block can be placed on that side of a + * block: BlockLever overrides + */ + public boolean canPlaceBlockOnSide(World par1World, int par2, int par3, int par4, int par5) { + if (par5 == 0) { + return false; + } else if (par5 == 1) { + return false; + } else { + if (par5 == 2) { + ++par4; + } + + if (par5 == 3) { + --par4; + } + + if (par5 == 4) { + ++par2; + } + + if (par5 == 5) { + --par2; + } + + return isValidSupportBlock(par1World.getBlockId(par2, par3, par4)); + } + } + + public static boolean isTrapdoorOpen(int par0) { + return (par0 & 4) != 0; + } + + /** + * Checks if the block ID is a valid support block for the trap door to connect + * with. If it is not the trapdoor is dropped into the world. + */ + private static boolean isValidSupportBlock(int par0) { + if (par0 <= 0) { + return false; + } else { + Block var1 = Block.blocksList[par0]; + return var1 != null && var1.blockMaterial.isOpaque() && var1.renderAsNormalBlock() + || var1 == Block.glowStone || var1 instanceof BlockHalfSlab || var1 instanceof BlockStairs; + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockTripWire.java b/sp-server/src/main/java/net/minecraft/src/BlockTripWire.java new file mode 100644 index 0000000..7f0d9e6 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockTripWire.java @@ -0,0 +1,216 @@ +package net.minecraft.src; + +import java.util.Iterator; +import java.util.List; +import java.util.Random; + +public class BlockTripWire extends Block { + public BlockTripWire(int par1) { + super(par1, Material.circuits); + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.15625F, 1.0F); + this.setTickRandomly(true); + } + + /** + * How many world ticks before ticking + */ + public int tickRate(World par1World) { + return 10; + } + + /** + * Returns a bounding box from the pool of bounding boxes (this means this box + * can change after the pool has been cleared to be reused) + */ + public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int par4) { + return null; + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return false; + } + + /** + * If this block doesn't render as an ordinary block it will return False + * (examples: signs, buttons, stairs, etc) + */ + public boolean renderAsNormalBlock() { + return false; + } + + /** + * The type of render function that is called for this block + */ + public int getRenderType() { + return 30; + } + + /** + * Returns the ID of the items to drop on destruction. + */ + public int idDropped(int par1, Random par2Random, int par3) { + return Item.silk.itemID; + } + + /** + * Lets the block know when one of its neighbor changes. Doesn't know which + * neighbor changed (coordinates passed are their own) Args: x, y, z, neighbor + * blockID + */ + public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5) { + int var6 = par1World.getBlockMetadata(par2, par3, par4); + boolean var7 = (var6 & 2) == 2; + boolean var8 = !par1World.doesBlockHaveSolidTopSurface(par2, par3 - 1, par4); + + if (var7 != var8) { + this.dropBlockAsItem(par1World, par2, par3, par4, var6, 0); + par1World.setBlockToAir(par2, par3, par4); + } + } + + /** + * Updates the blocks bounds based on its current state. Args: world, x, y, z + */ + public void setBlockBoundsBasedOnState(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + int var5 = par1IBlockAccess.getBlockMetadata(par2, par3, par4); + boolean var6 = (var5 & 4) == 4; + boolean var7 = (var5 & 2) == 2; + + if (!var7) { + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.09375F, 1.0F); + } else if (!var6) { + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.5F, 1.0F); + } else { + this.setBlockBounds(0.0F, 0.0625F, 0.0F, 1.0F, 0.15625F, 1.0F); + } + } + + /** + * Called whenever the block is added into the world. Args: world, x, y, z + */ + public void onBlockAdded(World par1World, int par2, int par3, int par4) { + int var5 = par1World.doesBlockHaveSolidTopSurface(par2, par3 - 1, par4) ? 0 : 2; + par1World.setBlockMetadata(par2, par3, par4, var5, 3); + this.func_72149_e(par1World, par2, par3, par4, var5); + } + + /** + * ejects contained items into the world, and notifies neighbours of an update, + * as appropriate + */ + public void breakBlock(World par1World, int par2, int par3, int par4, int par5, int par6) { + this.func_72149_e(par1World, par2, par3, par4, par6 | 1); + } + + /** + * Called when the block is attempted to be harvested + */ + public void onBlockHarvested(World par1World, int par2, int par3, int par4, int par5, + EntityPlayer par6EntityPlayer) { + if (!par1World.isRemote) { + if (par6EntityPlayer.getCurrentEquippedItem() != null + && par6EntityPlayer.getCurrentEquippedItem().itemID == Item.shears.itemID) { + par1World.setBlockMetadata(par2, par3, par4, par5 | 8, 4); + } + } + } + + private void func_72149_e(World par1World, int par2, int par3, int par4, int par5) { + int var6 = 0; + + while (var6 < 2) { + int var7 = 1; + + while (true) { + if (var7 < 42) { + int var8 = par2 + Direction.offsetX[var6] * var7; + int var9 = par4 + Direction.offsetZ[var6] * var7; + int var10 = par1World.getBlockId(var8, par3, var9); + + if (var10 == Block.tripWireSource.blockID) { + int var11 = par1World.getBlockMetadata(var8, par3, var9) & 3; + + if (var11 == Direction.footInvisibleFaceRemap[var6]) { + Block.tripWireSource.func_72143_a(par1World, var8, par3, var9, var10, + par1World.getBlockMetadata(var8, par3, var9), true, var7, par5); + } + } else if (var10 == Block.tripWire.blockID) { + ++var7; + continue; + } + } + + ++var6; + break; + } + } + } + + /** + * Triggered whenever an entity collides with this block (enters into the + * block). Args: world, x, y, z, entity + */ + public void onEntityCollidedWithBlock(World par1World, int par2, int par3, int par4, Entity par5Entity) { + if (!par1World.isRemote) { + if ((par1World.getBlockMetadata(par2, par3, par4) & 1) != 1) { + this.updateTripWireState(par1World, par2, par3, par4); + } + } + } + + /** + * Ticks the block if it's been scheduled + */ + public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random) { + if (!par1World.isRemote) { + if ((par1World.getBlockMetadata(par2, par3, par4) & 1) == 1) { + this.updateTripWireState(par1World, par2, par3, par4); + } + } + } + + private void updateTripWireState(World par1World, int par2, int par3, int par4) { + int var5 = par1World.getBlockMetadata(par2, par3, par4); + boolean var6 = (var5 & 1) == 1; + boolean var7 = false; + List var8 = par1World.getEntitiesWithinAABBExcludingEntity((Entity) null, + AxisAlignedBB.getAABBPool().getAABB((double) par2 + this.minX, (double) par3 + this.minY, + (double) par4 + this.minZ, (double) par2 + this.maxX, (double) par3 + this.maxY, + (double) par4 + this.maxZ)); + + if (!var8.isEmpty()) { + Iterator var9 = var8.iterator(); + + while (var9.hasNext()) { + Entity var10 = (Entity) var9.next(); + + if (!var10.doesEntityNotTriggerPressurePlate()) { + var7 = true; + break; + } + } + } + + if (var7 && !var6) { + var5 |= 1; + } + + if (!var7 && var6) { + var5 &= -2; + } + + if (var7 != var6) { + par1World.setBlockMetadata(par2, par3, par4, var5, 3); + this.func_72149_e(par1World, par2, par3, par4, var5); + } + + if (var7) { + par1World.scheduleBlockUpdate(par2, par3, par4, this.blockID, this.tickRate(par1World)); + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockTripWireSource.java b/sp-server/src/main/java/net/minecraft/src/BlockTripWireSource.java new file mode 100644 index 0000000..583b225 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockTripWireSource.java @@ -0,0 +1,373 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockTripWireSource extends Block { + public BlockTripWireSource(int par1) { + super(par1, Material.circuits); + this.setCreativeTab(CreativeTabs.tabRedstone); + this.setTickRandomly(true); + } + + /** + * Returns a bounding box from the pool of bounding boxes (this means this box + * can change after the pool has been cleared to be reused) + */ + public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int par4) { + return null; + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return false; + } + + /** + * If this block doesn't render as an ordinary block it will return False + * (examples: signs, buttons, stairs, etc) + */ + public boolean renderAsNormalBlock() { + return false; + } + + /** + * The type of render function that is called for this block + */ + public int getRenderType() { + return 29; + } + + /** + * How many world ticks before ticking + */ + public int tickRate(World par1World) { + return 10; + } + + /** + * checks to see if you can place this block can be placed on that side of a + * block: BlockLever overrides + */ + public boolean canPlaceBlockOnSide(World par1World, int par2, int par3, int par4, int par5) { + return par5 == 2 && par1World.isBlockNormalCube(par2, par3, par4 + 1) ? true + : (par5 == 3 && par1World.isBlockNormalCube(par2, par3, par4 - 1) ? true + : (par5 == 4 && par1World.isBlockNormalCube(par2 + 1, par3, par4) ? true + : par5 == 5 && par1World.isBlockNormalCube(par2 - 1, par3, par4))); + } + + /** + * Checks to see if its valid to put this block at the specified coordinates. + * Args: world, x, y, z + */ + public boolean canPlaceBlockAt(World par1World, int par2, int par3, int par4) { + return par1World.isBlockNormalCube(par2 - 1, par3, par4) ? true + : (par1World.isBlockNormalCube(par2 + 1, par3, par4) ? true + : (par1World.isBlockNormalCube(par2, par3, par4 - 1) ? true + : par1World.isBlockNormalCube(par2, par3, par4 + 1))); + } + + /** + * Called when a block is placed using its ItemBlock. Args: World, X, Y, Z, + * side, hitX, hitY, hitZ, block metadata + */ + public int onBlockPlaced(World par1World, int par2, int par3, int par4, int par5, float par6, float par7, + float par8, int par9) { + byte var10 = 0; + + if (par5 == 2 && par1World.isBlockNormalCubeDefault(par2, par3, par4 + 1, true)) { + var10 = 2; + } + + if (par5 == 3 && par1World.isBlockNormalCubeDefault(par2, par3, par4 - 1, true)) { + var10 = 0; + } + + if (par5 == 4 && par1World.isBlockNormalCubeDefault(par2 + 1, par3, par4, true)) { + var10 = 1; + } + + if (par5 == 5 && par1World.isBlockNormalCubeDefault(par2 - 1, par3, par4, true)) { + var10 = 3; + } + + return var10; + } + + /** + * Called after a block is placed + */ + public void onPostBlockPlaced(World par1World, int par2, int par3, int par4, int par5) { + this.func_72143_a(par1World, par2, par3, par4, this.blockID, par5, false, -1, 0); + } + + /** + * Lets the block know when one of its neighbor changes. Doesn't know which + * neighbor changed (coordinates passed are their own) Args: x, y, z, neighbor + * blockID + */ + public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5) { + if (par5 != this.blockID) { + if (this.func_72144_l(par1World, par2, par3, par4)) { + int var6 = par1World.getBlockMetadata(par2, par3, par4); + int var7 = var6 & 3; + boolean var8 = false; + + if (!par1World.isBlockNormalCube(par2 - 1, par3, par4) && var7 == 3) { + var8 = true; + } + + if (!par1World.isBlockNormalCube(par2 + 1, par3, par4) && var7 == 1) { + var8 = true; + } + + if (!par1World.isBlockNormalCube(par2, par3, par4 - 1) && var7 == 0) { + var8 = true; + } + + if (!par1World.isBlockNormalCube(par2, par3, par4 + 1) && var7 == 2) { + var8 = true; + } + + if (var8) { + this.dropBlockAsItem(par1World, par2, par3, par4, var6, 0); + par1World.setBlockToAir(par2, par3, par4); + } + } + } + } + + public void func_72143_a(World par1World, int par2, int par3, int par4, int par5, int par6, boolean par7, int par8, + int par9) { + int var10 = par6 & 3; + boolean var11 = (par6 & 4) == 4; + boolean var12 = (par6 & 8) == 8; + boolean var13 = par5 == Block.tripWireSource.blockID; + boolean var14 = false; + boolean var15 = !par1World.doesBlockHaveSolidTopSurface(par2, par3 - 1, par4); + int var16 = Direction.offsetX[var10]; + int var17 = Direction.offsetZ[var10]; + int var18 = 0; + int[] var19 = new int[42]; + int var20; + int var21; + int var22; + int var23; + int var24; + + for (var20 = 1; var20 < 42; ++var20) { + var21 = par2 + var16 * var20; + var22 = par4 + var17 * var20; + var23 = par1World.getBlockId(var21, par3, var22); + + if (var23 == Block.tripWireSource.blockID) { + var24 = par1World.getBlockMetadata(var21, par3, var22); + + if ((var24 & 3) == Direction.footInvisibleFaceRemap[var10]) { + var18 = var20; + } + + break; + } + + if (var23 != Block.tripWire.blockID && var20 != par8) { + var19[var20] = -1; + var13 = false; + } else { + var24 = var20 == par8 ? par9 : par1World.getBlockMetadata(var21, par3, var22); + boolean var25 = (var24 & 8) != 8; + boolean var26 = (var24 & 1) == 1; + boolean var27 = (var24 & 2) == 2; + var13 &= var27 == var15; + var14 |= var25 && var26; + var19[var20] = var24; + + if (var20 == par8) { + par1World.scheduleBlockUpdate(par2, par3, par4, par5, this.tickRate(par1World)); + var13 &= var25; + } + } + } + + var13 &= var18 > 1; + var14 &= var13; + var20 = (var13 ? 4 : 0) | (var14 ? 8 : 0); + par6 = var10 | var20; + + if (var18 > 0) { + var21 = par2 + var16 * var18; + var22 = par4 + var17 * var18; + var23 = Direction.footInvisibleFaceRemap[var10]; + par1World.setBlockMetadata(var21, par3, var22, var23 | var20, 3); + this.notifyNeighborOfChange(par1World, var21, par3, var22, var23); + this.playSoundEffect(par1World, var21, par3, var22, var13, var14, var11, var12); + } + + this.playSoundEffect(par1World, par2, par3, par4, var13, var14, var11, var12); + + if (par5 > 0) { + par1World.setBlockMetadata(par2, par3, par4, par6, 3); + + if (par7) { + this.notifyNeighborOfChange(par1World, par2, par3, par4, var10); + } + } + + if (var11 != var13) { + for (var21 = 1; var21 < var18; ++var21) { + var22 = par2 + var16 * var21; + var23 = par4 + var17 * var21; + var24 = var19[var21]; + + if (var24 >= 0) { + if (var13) { + var24 |= 4; + } else { + var24 &= -5; + } + + par1World.setBlockMetadata(var22, par3, var23, var24, 3); + } + } + } + } + + /** + * Ticks the block if it's been scheduled + */ + public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random) { + this.func_72143_a(par1World, par2, par3, par4, this.blockID, par1World.getBlockMetadata(par2, par3, par4), true, + -1, 0); + } + + /** + * only of the conditions are right + */ + private void playSoundEffect(World par1World, int par2, int par3, int par4, boolean par5, boolean par6, + boolean par7, boolean par8) { + if (par6 && !par8) { + par1World.playSoundEffect((double) par2 + 0.5D, (double) par3 + 0.1D, (double) par4 + 0.5D, "random.click", + 0.4F, 0.6F); + } else if (!par6 && par8) { + par1World.playSoundEffect((double) par2 + 0.5D, (double) par3 + 0.1D, (double) par4 + 0.5D, "random.click", + 0.4F, 0.5F); + } else if (par5 && !par7) { + par1World.playSoundEffect((double) par2 + 0.5D, (double) par3 + 0.1D, (double) par4 + 0.5D, "random.click", + 0.4F, 0.7F); + } else if (!par5 && par7) { + par1World.playSoundEffect((double) par2 + 0.5D, (double) par3 + 0.1D, (double) par4 + 0.5D, "random.bowhit", + 0.4F, 1.2F / (par1World.rand.nextFloat() * 0.2F + 0.9F)); + } + } + + private void notifyNeighborOfChange(World par1World, int par2, int par3, int par4, int par5) { + par1World.notifyBlocksOfNeighborChange(par2, par3, par4, this.blockID); + + if (par5 == 3) { + par1World.notifyBlocksOfNeighborChange(par2 - 1, par3, par4, this.blockID); + } else if (par5 == 1) { + par1World.notifyBlocksOfNeighborChange(par2 + 1, par3, par4, this.blockID); + } else if (par5 == 0) { + par1World.notifyBlocksOfNeighborChange(par2, par3, par4 - 1, this.blockID); + } else if (par5 == 2) { + par1World.notifyBlocksOfNeighborChange(par2, par3, par4 + 1, this.blockID); + } + } + + private boolean func_72144_l(World par1World, int par2, int par3, int par4) { + if (!this.canPlaceBlockAt(par1World, par2, par3, par4)) { + this.dropBlockAsItem(par1World, par2, par3, par4, par1World.getBlockMetadata(par2, par3, par4), 0); + par1World.setBlockToAir(par2, par3, par4); + return false; + } else { + return true; + } + } + + /** + * Updates the blocks bounds based on its current state. Args: world, x, y, z + */ + public void setBlockBoundsBasedOnState(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + int var5 = par1IBlockAccess.getBlockMetadata(par2, par3, par4) & 3; + float var6 = 0.1875F; + + if (var5 == 3) { + this.setBlockBounds(0.0F, 0.2F, 0.5F - var6, var6 * 2.0F, 0.8F, 0.5F + var6); + } else if (var5 == 1) { + this.setBlockBounds(1.0F - var6 * 2.0F, 0.2F, 0.5F - var6, 1.0F, 0.8F, 0.5F + var6); + } else if (var5 == 0) { + this.setBlockBounds(0.5F - var6, 0.2F, 0.0F, 0.5F + var6, 0.8F, var6 * 2.0F); + } else if (var5 == 2) { + this.setBlockBounds(0.5F - var6, 0.2F, 1.0F - var6 * 2.0F, 0.5F + var6, 0.8F, 1.0F); + } + } + + /** + * ejects contained items into the world, and notifies neighbours of an update, + * as appropriate + */ + public void breakBlock(World par1World, int par2, int par3, int par4, int par5, int par6) { + boolean var7 = (par6 & 4) == 4; + boolean var8 = (par6 & 8) == 8; + + if (var7 || var8) { + this.func_72143_a(par1World, par2, par3, par4, 0, par6, false, -1, 0); + } + + if (var8) { + par1World.notifyBlocksOfNeighborChange(par2, par3, par4, this.blockID); + int var9 = par6 & 3; + + if (var9 == 3) { + par1World.notifyBlocksOfNeighborChange(par2 - 1, par3, par4, this.blockID); + } else if (var9 == 1) { + par1World.notifyBlocksOfNeighborChange(par2 + 1, par3, par4, this.blockID); + } else if (var9 == 0) { + par1World.notifyBlocksOfNeighborChange(par2, par3, par4 - 1, this.blockID); + } else if (var9 == 2) { + par1World.notifyBlocksOfNeighborChange(par2, par3, par4 + 1, this.blockID); + } + } + + super.breakBlock(par1World, par2, par3, par4, par5, par6); + } + + /** + * Returns true if the block is emitting indirect/weak redstone power on the + * specified side. If isBlockNormalCube returns true, standard redstone + * propagation rules will apply instead and this will not be called. Args: + * World, X, Y, Z, side. Note that the side is reversed - eg it is 1 (up) when + * checking the bottom of the block. + */ + public int isProvidingWeakPower(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5) { + return (par1IBlockAccess.getBlockMetadata(par2, par3, par4) & 8) == 8 ? 15 : 0; + } + + /** + * Returns true if the block is emitting direct/strong redstone power on the + * specified side. Args: World, X, Y, Z, side. Note that the side is reversed - + * eg it is 1 (up) when checking the bottom of the block. + */ + public int isProvidingStrongPower(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5) { + int var6 = par1IBlockAccess.getBlockMetadata(par2, par3, par4); + + if ((var6 & 8) != 8) { + return 0; + } else { + int var7 = var6 & 3; + return var7 == 2 && par5 == 2 ? 15 + : (var7 == 0 && par5 == 3 ? 15 : (var7 == 1 && par5 == 4 ? 15 : (var7 == 3 && par5 == 5 ? 15 : 0))); + } + } + + /** + * Can this block provide power. Only wire currently seems to have this change + * based on its state. + */ + public boolean canProvidePower() { + return true; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockVine.java b/sp-server/src/main/java/net/minecraft/src/BlockVine.java new file mode 100644 index 0000000..be0546b --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockVine.java @@ -0,0 +1,382 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockVine extends Block { + public BlockVine(int par1) { + super(par1, Material.vine); + this.setTickRandomly(true); + this.setCreativeTab(CreativeTabs.tabDecorations); + } + + /** + * Sets the block's bounds for rendering it as an item + */ + public void setBlockBoundsForItemRender() { + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + } + + /** + * The type of render function that is called for this block + */ + public int getRenderType() { + return 20; + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return false; + } + + /** + * If this block doesn't render as an ordinary block it will return False + * (examples: signs, buttons, stairs, etc) + */ + public boolean renderAsNormalBlock() { + return false; + } + + /** + * Updates the blocks bounds based on its current state. Args: world, x, y, z + */ + public void setBlockBoundsBasedOnState(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + int var6 = par1IBlockAccess.getBlockMetadata(par2, par3, par4); + float var7 = 1.0F; + float var8 = 1.0F; + float var9 = 1.0F; + float var10 = 0.0F; + float var11 = 0.0F; + float var12 = 0.0F; + boolean var13 = var6 > 0; + + if ((var6 & 2) != 0) { + var10 = Math.max(var10, 0.0625F); + var7 = 0.0F; + var8 = 0.0F; + var11 = 1.0F; + var9 = 0.0F; + var12 = 1.0F; + var13 = true; + } + + if ((var6 & 8) != 0) { + var7 = Math.min(var7, 0.9375F); + var10 = 1.0F; + var8 = 0.0F; + var11 = 1.0F; + var9 = 0.0F; + var12 = 1.0F; + var13 = true; + } + + if ((var6 & 4) != 0) { + var12 = Math.max(var12, 0.0625F); + var9 = 0.0F; + var7 = 0.0F; + var10 = 1.0F; + var8 = 0.0F; + var11 = 1.0F; + var13 = true; + } + + if ((var6 & 1) != 0) { + var9 = Math.min(var9, 0.9375F); + var12 = 1.0F; + var7 = 0.0F; + var10 = 1.0F; + var8 = 0.0F; + var11 = 1.0F; + var13 = true; + } + + if (!var13 && this.canBePlacedOn(par1IBlockAccess.getBlockId(par2, par3 + 1, par4))) { + var8 = Math.min(var8, 0.9375F); + var11 = 1.0F; + var7 = 0.0F; + var10 = 1.0F; + var9 = 0.0F; + var12 = 1.0F; + } + + this.setBlockBounds(var7, var8, var9, var10, var11, var12); + } + + /** + * Returns a bounding box from the pool of bounding boxes (this means this box + * can change after the pool has been cleared to be reused) + */ + public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int par4) { + return null; + } + + /** + * checks to see if you can place this block can be placed on that side of a + * block: BlockLever overrides + */ + public boolean canPlaceBlockOnSide(World par1World, int par2, int par3, int par4, int par5) { + switch (par5) { + case 1: + return this.canBePlacedOn(par1World.getBlockId(par2, par3 + 1, par4)); + + case 2: + return this.canBePlacedOn(par1World.getBlockId(par2, par3, par4 + 1)); + + case 3: + return this.canBePlacedOn(par1World.getBlockId(par2, par3, par4 - 1)); + + case 4: + return this.canBePlacedOn(par1World.getBlockId(par2 + 1, par3, par4)); + + case 5: + return this.canBePlacedOn(par1World.getBlockId(par2 - 1, par3, par4)); + + default: + return false; + } + } + + /** + * returns true if a vine can be placed on that block (checks for render as + * normal block and if it is solid) + */ + private boolean canBePlacedOn(int par1) { + if (par1 == 0) { + return false; + } else { + Block var2 = Block.blocksList[par1]; + return var2.renderAsNormalBlock() && var2.blockMaterial.blocksMovement(); + } + } + + /** + * Returns if the vine can stay in the world. It also changes the metadata + * according to neighboring blocks. + */ + private boolean canVineStay(World par1World, int par2, int par3, int par4) { + int var5 = par1World.getBlockMetadata(par2, par3, par4); + int var6 = var5; + + if (var5 > 0) { + for (int var7 = 0; var7 <= 3; ++var7) { + int var8 = 1 << var7; + + if ((var5 & var8) != 0 + && !this.canBePlacedOn(par1World.getBlockId(par2 + Direction.offsetX[var7], par3, + par4 + Direction.offsetZ[var7])) + && (par1World.getBlockId(par2, par3 + 1, par4) != this.blockID + || (par1World.getBlockMetadata(par2, par3 + 1, par4) & var8) == 0)) { + var6 &= ~var8; + } + } + } + + if (var6 == 0 && !this.canBePlacedOn(par1World.getBlockId(par2, par3 + 1, par4))) { + return false; + } else { + if (var6 != var5) { + par1World.setBlockMetadata(par2, par3, par4, var6, 2); + } + + return true; + } + } + + /** + * Lets the block know when one of its neighbor changes. Doesn't know which + * neighbor changed (coordinates passed are their own) Args: x, y, z, neighbor + * blockID + */ + public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5) { + if (!par1World.isRemote && !this.canVineStay(par1World, par2, par3, par4)) { + this.dropBlockAsItem(par1World, par2, par3, par4, par1World.getBlockMetadata(par2, par3, par4), 0); + par1World.setBlockToAir(par2, par3, par4); + } + } + + /** + * Ticks the block if it's been scheduled + */ + public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random) { + if (!par1World.isRemote && par1World.rand.nextInt(4) == 0) { + byte var6 = 4; + int var7 = 5; + boolean var8 = false; + int var9; + int var10; + int var11; + label138: + + for (var9 = par2 - var6; var9 <= par2 + var6; ++var9) { + for (var10 = par4 - var6; var10 <= par4 + var6; ++var10) { + for (var11 = par3 - 1; var11 <= par3 + 1; ++var11) { + if (par1World.getBlockId(var9, var11, var10) == this.blockID) { + --var7; + + if (var7 <= 0) { + var8 = true; + break label138; + } + } + } + } + } + + var9 = par1World.getBlockMetadata(par2, par3, par4); + var10 = par1World.rand.nextInt(6); + var11 = Direction.facingToDirection[var10]; + int var12; + int var13; + + if (var10 == 1 && par3 < 255 && par1World.isAirBlock(par2, par3 + 1, par4)) { + if (var8) { + return; + } + + var12 = par1World.rand.nextInt(16) & var9; + + if (var12 > 0) { + for (var13 = 0; var13 <= 3; ++var13) { + if (!this.canBePlacedOn(par1World.getBlockId(par2 + Direction.offsetX[var13], par3 + 1, + par4 + Direction.offsetZ[var13]))) { + var12 &= ~(1 << var13); + } + } + + if (var12 > 0) { + par1World.setBlock(par2, par3 + 1, par4, this.blockID, var12, 2); + } + } + } else { + int var14; + + if (var10 >= 2 && var10 <= 5 && (var9 & 1 << var11) == 0) { + if (var8) { + return; + } + + var12 = par1World.getBlockId(par2 + Direction.offsetX[var11], par3, + par4 + Direction.offsetZ[var11]); + + if (var12 != 0 && Block.blocksList[var12] != null) { + if (Block.blocksList[var12].blockMaterial.isOpaque() + && Block.blocksList[var12].renderAsNormalBlock()) { + par1World.setBlockMetadata(par2, par3, par4, var9 | 1 << var11, 2); + } + } else { + var13 = var11 + 1 & 3; + var14 = var11 + 3 & 3; + + if ((var9 & 1 << var13) != 0 && this.canBePlacedOn( + par1World.getBlockId(par2 + Direction.offsetX[var11] + Direction.offsetX[var13], par3, + par4 + Direction.offsetZ[var11] + Direction.offsetZ[var13]))) { + par1World.setBlock(par2 + Direction.offsetX[var11], par3, par4 + Direction.offsetZ[var11], + this.blockID, 1 << var13, 2); + } else if ((var9 & 1 << var14) != 0 && this.canBePlacedOn( + par1World.getBlockId(par2 + Direction.offsetX[var11] + Direction.offsetX[var14], par3, + par4 + Direction.offsetZ[var11] + Direction.offsetZ[var14]))) { + par1World.setBlock(par2 + Direction.offsetX[var11], par3, par4 + Direction.offsetZ[var11], + this.blockID, 1 << var14, 2); + } else if ((var9 & 1 << var13) != 0 + && par1World.isAirBlock(par2 + Direction.offsetX[var11] + Direction.offsetX[var13], + par3, par4 + Direction.offsetZ[var11] + Direction.offsetZ[var13]) + && this.canBePlacedOn(par1World.getBlockId(par2 + Direction.offsetX[var13], par3, + par4 + Direction.offsetZ[var13]))) { + par1World.setBlock(par2 + Direction.offsetX[var11] + Direction.offsetX[var13], par3, + par4 + Direction.offsetZ[var11] + Direction.offsetZ[var13], this.blockID, + 1 << (var11 + 2 & 3), 2); + } else if ((var9 & 1 << var14) != 0 + && par1World.isAirBlock(par2 + Direction.offsetX[var11] + Direction.offsetX[var14], + par3, par4 + Direction.offsetZ[var11] + Direction.offsetZ[var14]) + && this.canBePlacedOn(par1World.getBlockId(par2 + Direction.offsetX[var14], par3, + par4 + Direction.offsetZ[var14]))) { + par1World.setBlock(par2 + Direction.offsetX[var11] + Direction.offsetX[var14], par3, + par4 + Direction.offsetZ[var11] + Direction.offsetZ[var14], this.blockID, + 1 << (var11 + 2 & 3), 2); + } else if (this.canBePlacedOn(par1World.getBlockId(par2 + Direction.offsetX[var11], par3 + 1, + par4 + Direction.offsetZ[var11]))) { + par1World.setBlock(par2 + Direction.offsetX[var11], par3, par4 + Direction.offsetZ[var11], + this.blockID, 0, 2); + } + } + } else if (par3 > 1) { + var12 = par1World.getBlockId(par2, par3 - 1, par4); + + if (var12 == 0) { + var13 = par1World.rand.nextInt(16) & var9; + + if (var13 > 0) { + par1World.setBlock(par2, par3 - 1, par4, this.blockID, var13, 2); + } + } else if (var12 == this.blockID) { + var13 = par1World.rand.nextInt(16) & var9; + var14 = par1World.getBlockMetadata(par2, par3 - 1, par4); + + if (var14 != (var14 | var13)) { + par1World.setBlockMetadata(par2, par3 - 1, par4, var14 | var13, 2); + } + } + } + } + } + } + + /** + * Called when a block is placed using its ItemBlock. Args: World, X, Y, Z, + * side, hitX, hitY, hitZ, block metadata + */ + public int onBlockPlaced(World par1World, int par2, int par3, int par4, int par5, float par6, float par7, + float par8, int par9) { + byte var10 = 0; + + switch (par5) { + case 2: + var10 = 1; + break; + + case 3: + var10 = 4; + break; + + case 4: + var10 = 8; + break; + + case 5: + var10 = 2; + } + + return var10 != 0 ? var10 : par9; + } + + /** + * Returns the ID of the items to drop on destruction. + */ + public int idDropped(int par1, Random par2Random, int par3) { + return 0; + } + + /** + * Returns the quantity of items to drop on block destruction. + */ + public int quantityDropped(Random par1Random) { + return 0; + } + + /** + * Called when the player destroys a block with an item that can harvest it. (i, + * j, k) are the coordinates of the block and l is the block's subtype/damage. + */ + public void harvestBlock(World par1World, EntityPlayer par2EntityPlayer, int par3, int par4, int par5, int par6) { + if (!par1World.isRemote && par2EntityPlayer.getCurrentEquippedItem() != null + && par2EntityPlayer.getCurrentEquippedItem().itemID == Item.shears.itemID) { + par2EntityPlayer.addStat(StatList.mineBlockStatArray[this.blockID], 1); + this.dropBlockAsItem_do(par1World, par3, par4, par5, new ItemStack(Block.vine, 1, 0)); + } else { + super.harvestBlock(par1World, par2EntityPlayer, par3, par4, par5, par6); + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockWall.java b/sp-server/src/main/java/net/minecraft/src/BlockWall.java new file mode 100644 index 0000000..98a3d71 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockWall.java @@ -0,0 +1,118 @@ +package net.minecraft.src; + +public class BlockWall extends Block { + /** The types of the wall. */ + public static final String[] types = new String[] { "normal", "mossy" }; + + public BlockWall(int par1, Block par2Block) { + super(par1, par2Block.blockMaterial); + this.setHardness(par2Block.blockHardness); + this.setResistance(par2Block.blockResistance / 3.0F); + this.setStepSound(par2Block.stepSound); + this.setCreativeTab(CreativeTabs.tabBlock); + } + + /** + * The type of render function that is called for this block + */ + public int getRenderType() { + return 32; + } + + /** + * If this block doesn't render as an ordinary block it will return False + * (examples: signs, buttons, stairs, etc) + */ + public boolean renderAsNormalBlock() { + return false; + } + + public boolean getBlocksMovement(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + return false; + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return false; + } + + /** + * Updates the blocks bounds based on its current state. Args: world, x, y, z + */ + public void setBlockBoundsBasedOnState(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + boolean var5 = this.canConnectWallTo(par1IBlockAccess, par2, par3, par4 - 1); + boolean var6 = this.canConnectWallTo(par1IBlockAccess, par2, par3, par4 + 1); + boolean var7 = this.canConnectWallTo(par1IBlockAccess, par2 - 1, par3, par4); + boolean var8 = this.canConnectWallTo(par1IBlockAccess, par2 + 1, par3, par4); + float var9 = 0.25F; + float var10 = 0.75F; + float var11 = 0.25F; + float var12 = 0.75F; + float var13 = 1.0F; + + if (var5) { + var11 = 0.0F; + } + + if (var6) { + var12 = 1.0F; + } + + if (var7) { + var9 = 0.0F; + } + + if (var8) { + var10 = 1.0F; + } + + if (var5 && var6 && !var7 && !var8) { + var13 = 0.8125F; + var9 = 0.3125F; + var10 = 0.6875F; + } else if (!var5 && !var6 && var7 && var8) { + var13 = 0.8125F; + var11 = 0.3125F; + var12 = 0.6875F; + } + + this.setBlockBounds(var9, 0.0F, var11, var10, var13, var12); + } + + /** + * Returns a bounding box from the pool of bounding boxes (this means this box + * can change after the pool has been cleared to be reused) + */ + public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int par4) { + this.setBlockBoundsBasedOnState(par1World, par2, par3, par4); + this.maxY = 1.5D; + return super.getCollisionBoundingBoxFromPool(par1World, par2, par3, par4); + } + + /** + * Return whether an adjacent block can connect to a wall. + */ + public boolean canConnectWallTo(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) { + int var5 = par1IBlockAccess.getBlockId(par2, par3, par4); + + if (var5 != this.blockID && var5 != Block.fenceGate.blockID) { + Block var6 = Block.blocksList[var5]; + return var6 != null && var6.blockMaterial.isOpaque() && var6.renderAsNormalBlock() + ? var6.blockMaterial != Material.pumpkin + : false; + } else { + return true; + } + } + + /** + * Determines the damage on the item the block drops. Used in cloth and wood. + */ + public int damageDropped(int par1) { + return par1; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockWeb.java b/sp-server/src/main/java/net/minecraft/src/BlockWeb.java new file mode 100644 index 0000000..9e7a88d --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockWeb.java @@ -0,0 +1,65 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockWeb extends Block { + public BlockWeb(int par1) { + super(par1, Material.web); + this.setCreativeTab(CreativeTabs.tabDecorations); + } + + /** + * Triggered whenever an entity collides with this block (enters into the + * block). Args: world, x, y, z, entity + */ + public void onEntityCollidedWithBlock(World par1World, int par2, int par3, int par4, Entity par5Entity) { + par5Entity.setInWeb(); + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or + * not to render the shared face of two adjacent blocks and also whether the + * player can attach torches, redstone wire, etc to this block. + */ + public boolean isOpaqueCube() { + return false; + } + + /** + * Returns a bounding box from the pool of bounding boxes (this means this box + * can change after the pool has been cleared to be reused) + */ + public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int par4) { + return null; + } + + /** + * The type of render function that is called for this block + */ + public int getRenderType() { + return 1; + } + + /** + * If this block doesn't render as an ordinary block it will return False + * (examples: signs, buttons, stairs, etc) + */ + public boolean renderAsNormalBlock() { + return false; + } + + /** + * Returns the ID of the items to drop on destruction. + */ + public int idDropped(int par1, Random par2Random, int par3) { + return Item.silk.itemID; + } + + /** + * Return true if a player with Silk Touch can harvest this block directly, and + * not its normal drops. + */ + protected boolean canSilkHarvest() { + return true; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockWood.java b/sp-server/src/main/java/net/minecraft/src/BlockWood.java new file mode 100644 index 0000000..ee1b40b --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockWood.java @@ -0,0 +1,19 @@ +package net.minecraft.src; + +public class BlockWood extends Block { + /** The type of tree this block came from. */ + public static final String[] woodType = new String[] { "oak", "spruce", "birch", "jungle" }; + public static final String[] woodTextureTypes = new String[] { "wood", "wood_spruce", "wood_birch", "wood_jungle" }; + + public BlockWood(int par1) { + super(par1, Material.wood); + this.setCreativeTab(CreativeTabs.tabBlock); + } + + /** + * Determines the damage on the item the block drops. Used in cloth and wood. + */ + public int damageDropped(int par1) { + return par1; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockWoodSlab.java b/sp-server/src/main/java/net/minecraft/src/BlockWoodSlab.java new file mode 100644 index 0000000..3cdf721 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockWoodSlab.java @@ -0,0 +1,40 @@ +package net.minecraft.src; + +import java.util.Random; + +public class BlockWoodSlab extends BlockHalfSlab { + /** The type of tree this slab came from. */ + public static final String[] woodType = new String[] { "oak", "spruce", "birch", "jungle" }; + + public BlockWoodSlab(int par1, boolean par2) { + super(par1, par2, Material.wood); + this.setCreativeTab(CreativeTabs.tabBlock); + } + + /** + * Returns the ID of the items to drop on destruction. + */ + public int idDropped(int par1, Random par2Random, int par3) { + return Block.woodSingleSlab.blockID; + } + + /** + * Returns an item stack containing a single instance of the current block type. + * 'i' is the block's subtype/damage and is ignored for blocks which do not + * support subtypes. Blocks which cannot be harvested should return null. + */ + protected ItemStack createStackedBlock(int par1) { + return new ItemStack(Block.woodSingleSlab.blockID, 2, par1 & 7); + } + + /** + * Returns the slab block name with step type. + */ + public String getFullSlabName(int par1) { + if (par1 < 0 || par1 >= woodType.length) { + par1 = 0; + } + + return super.getUnlocalizedName() + "." + woodType[par1]; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/BlockWorkbench.java b/sp-server/src/main/java/net/minecraft/src/BlockWorkbench.java new file mode 100644 index 0000000..582da1e --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/BlockWorkbench.java @@ -0,0 +1,21 @@ +package net.minecraft.src; + +public class BlockWorkbench extends Block { + protected BlockWorkbench(int par1) { + super(par1, Material.wood); + this.setCreativeTab(CreativeTabs.tabDecorations); + } + + /** + * Called upon block activation (right click on the block.) + */ + public boolean onBlockActivated(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer, + int par6, float par7, float par8, float par9) { + if (par1World.isRemote) { + return true; + } else { + par5EntityPlayer.displayGUIWorkbench(par2, par3, par4); + return true; + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CallableBlockDataValue.java b/sp-server/src/main/java/net/minecraft/src/CallableBlockDataValue.java new file mode 100644 index 0000000..b4c879b --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CallableBlockDataValue.java @@ -0,0 +1,25 @@ +package net.minecraft.src; + +import java.util.concurrent.Callable; + +final class CallableBlockDataValue implements Callable { + final int field_85063_a; + + CallableBlockDataValue(int par1) { + this.field_85063_a = par1; + } + + public String callBlockDataValue() { + if (this.field_85063_a < 0) { + return "Unknown? (Got " + this.field_85063_a + ")"; + } else { + String var1 = String.format("%4s", new Object[] { Integer.toBinaryString(this.field_85063_a) }).replace(" ", + "0"); + return String.format("%1$d / 0x%1$X / 0b%2$s", new Object[] { Integer.valueOf(this.field_85063_a), var1 }); + } + } + + public Object call() { + return this.callBlockDataValue(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CallableBlockLocation.java b/sp-server/src/main/java/net/minecraft/src/CallableBlockLocation.java new file mode 100644 index 0000000..204247f --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CallableBlockLocation.java @@ -0,0 +1,25 @@ +package net.minecraft.src; + +import java.util.concurrent.Callable; + +final class CallableBlockLocation implements Callable { + final int blockXCoord; + + final int blockYCoord; + + final int blockZCoord; + + CallableBlockLocation(int par1, int par2, int par3) { + this.blockXCoord = par1; + this.blockYCoord = par2; + this.blockZCoord = par3; + } + + public String callBlockLocationInfo() { + return CrashReportCategory.getLocationInfo(this.blockXCoord, this.blockYCoord, this.blockZCoord); + } + + public Object call() { + return this.callBlockLocationInfo(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CallableBlockType.java b/sp-server/src/main/java/net/minecraft/src/CallableBlockType.java new file mode 100644 index 0000000..3da3b79 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CallableBlockType.java @@ -0,0 +1,25 @@ +package net.minecraft.src; + +import java.util.concurrent.Callable; + +final class CallableBlockType implements Callable { + final int blockID; + + CallableBlockType(int par1) { + this.blockID = par1; + } + + public String callBlockType() { + try { + return String.format("ID #%d (%s // %s)", + new Object[] { Integer.valueOf(this.blockID), Block.blocksList[this.blockID].getUnlocalizedName(), + Block.blocksList[this.blockID].getClass().getCanonicalName() }); + } catch (Throwable var2) { + return "ID #" + this.blockID; + } + } + + public Object call() { + return this.callBlockType(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CallableChunkPosHash.java b/sp-server/src/main/java/net/minecraft/src/CallableChunkPosHash.java new file mode 100644 index 0000000..bdde31d --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CallableChunkPosHash.java @@ -0,0 +1,25 @@ +package net.minecraft.src; + +import java.util.concurrent.Callable; + +class CallableChunkPosHash implements Callable { + final int field_85165_a; + + final int field_85163_b; + + final MapGenStructure theMapStructureGenerator; + + CallableChunkPosHash(MapGenStructure par1MapGenStructure, int par2, int par3) { + this.theMapStructureGenerator = par1MapGenStructure; + this.field_85165_a = par2; + this.field_85163_b = par3; + } + + public String callChunkPositionHash() { + return String.valueOf(ChunkCoordIntPair.chunkXZ2Int(this.field_85165_a, this.field_85163_b)); + } + + public Object call() { + return this.callChunkPositionHash(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CallableCrashMemoryReport.java b/sp-server/src/main/java/net/minecraft/src/CallableCrashMemoryReport.java new file mode 100644 index 0000000..c9bcf83 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CallableCrashMemoryReport.java @@ -0,0 +1,29 @@ +package net.minecraft.src; + +import java.util.concurrent.Callable; + +class CallableCrashMemoryReport implements Callable { + final CrashReport theCrashReport; + + CallableCrashMemoryReport(CrashReport par1CrashReport) { + this.theCrashReport = par1CrashReport; + } + + /** + * Returns a string with allocated and used memory. + */ + public String getMemoryReport() { + int var1 = AxisAlignedBB.getAABBPool().getlistAABBsize(); + int var2 = 56 * var1; + int var3 = var2 / 1024 / 1024; + int var4 = AxisAlignedBB.getAABBPool().getnextPoolIndex(); + int var5 = 56 * var4; + int var6 = var5 / 1024 / 1024; + return var1 + " (" + var2 + " bytes; " + var3 + " MB) allocated, " + var4 + " (" + var5 + " bytes; " + var6 + + " MB) used"; + } + + public Object call() { + return this.getMemoryReport(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CallableEffectAmplifier.java b/sp-server/src/main/java/net/minecraft/src/CallableEffectAmplifier.java new file mode 100644 index 0000000..89d10a7 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CallableEffectAmplifier.java @@ -0,0 +1,22 @@ +package net.minecraft.src; + +import java.util.concurrent.Callable; + +class CallableEffectAmplifier implements Callable { + final PotionEffect field_102040_a; + + final EntityLiving field_102039_b; + + CallableEffectAmplifier(EntityLiving par1EntityLiving, PotionEffect par2PotionEffect) { + this.field_102039_b = par1EntityLiving; + this.field_102040_a = par2PotionEffect; + } + + public String func_102038_a() { + return this.field_102040_a.getAmplifier() + ""; + } + + public Object call() { + return this.func_102038_a(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CallableEffectDuration.java b/sp-server/src/main/java/net/minecraft/src/CallableEffectDuration.java new file mode 100644 index 0000000..6f55a90 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CallableEffectDuration.java @@ -0,0 +1,22 @@ +package net.minecraft.src; + +import java.util.concurrent.Callable; + +class CallableEffectDuration implements Callable { + final PotionEffect field_102037_a; + + final EntityLiving field_102036_b; + + CallableEffectDuration(EntityLiving par1EntityLiving, PotionEffect par2PotionEffect) { + this.field_102036_b = par1EntityLiving; + this.field_102037_a = par2PotionEffect; + } + + public String func_102035_a() { + return this.field_102037_a.getDuration() + ""; + } + + public Object call() { + return this.func_102035_a(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CallableEffectID.java b/sp-server/src/main/java/net/minecraft/src/CallableEffectID.java new file mode 100644 index 0000000..cc0167a --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CallableEffectID.java @@ -0,0 +1,22 @@ +package net.minecraft.src; + +import java.util.concurrent.Callable; + +class CallableEffectID implements Callable { + final PotionEffect field_102034_a; + + final EntityLiving field_102033_b; + + CallableEffectID(EntityLiving par1EntityLiving, PotionEffect par2PotionEffect) { + this.field_102033_b = par1EntityLiving; + this.field_102034_a = par2PotionEffect; + } + + public String func_102032_a() { + return this.field_102034_a.getPotionID() + ""; + } + + public Object call() { + return this.func_102032_a(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CallableEffectIsAmbient.java b/sp-server/src/main/java/net/minecraft/src/CallableEffectIsAmbient.java new file mode 100644 index 0000000..e6b089b --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CallableEffectIsAmbient.java @@ -0,0 +1,22 @@ +package net.minecraft.src; + +import java.util.concurrent.Callable; + +class CallableEffectIsAmbient implements Callable { + final PotionEffect field_102046_a; + + final EntityLiving field_102045_b; + + CallableEffectIsAmbient(EntityLiving par1EntityLiving, PotionEffect par2PotionEffect) { + this.field_102045_b = par1EntityLiving; + this.field_102046_a = par2PotionEffect; + } + + public String func_102044_a() { + return this.field_102046_a.getIsAmbient() + ""; + } + + public Object call() { + return this.func_102044_a(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CallableEffectIsSplash.java b/sp-server/src/main/java/net/minecraft/src/CallableEffectIsSplash.java new file mode 100644 index 0000000..b31a701 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CallableEffectIsSplash.java @@ -0,0 +1,22 @@ +package net.minecraft.src; + +import java.util.concurrent.Callable; + +class CallableEffectIsSplash implements Callable { + final PotionEffect field_102043_a; + + final EntityLiving field_102042_b; + + CallableEffectIsSplash(EntityLiving par1EntityLiving, PotionEffect par2PotionEffect) { + this.field_102042_b = par1EntityLiving; + this.field_102043_a = par2PotionEffect; + } + + public String func_102041_a() { + return this.field_102043_a.isSplashPotionEffect() + ""; + } + + public Object call() { + return this.func_102041_a(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CallableEffectName.java b/sp-server/src/main/java/net/minecraft/src/CallableEffectName.java new file mode 100644 index 0000000..e9eb71a --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CallableEffectName.java @@ -0,0 +1,22 @@ +package net.minecraft.src; + +import java.util.concurrent.Callable; + +class CallableEffectName implements Callable { + final PotionEffect field_102031_a; + + final EntityLiving field_102030_b; + + CallableEffectName(EntityLiving par1EntityLiving, PotionEffect par2PotionEffect) { + this.field_102030_b = par1EntityLiving; + this.field_102031_a = par2PotionEffect; + } + + public String func_102029_a() { + return Potion.potionTypes[this.field_102031_a.getPotionID()].getName(); + } + + public Object call() { + return this.func_102029_a(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CallableEntityName.java b/sp-server/src/main/java/net/minecraft/src/CallableEntityName.java new file mode 100644 index 0000000..f9433f9 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CallableEntityName.java @@ -0,0 +1,19 @@ +package net.minecraft.src; + +import java.util.concurrent.Callable; + +class CallableEntityName implements Callable { + final Entity theEntity; + + CallableEntityName(Entity par1Entity) { + this.theEntity = par1Entity; + } + + public String callEntityName() { + return this.theEntity.getEntityName(); + } + + public Object call() { + return this.callEntityName(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CallableEntityTracker.java b/sp-server/src/main/java/net/minecraft/src/CallableEntityTracker.java new file mode 100644 index 0000000..c48cc6c --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CallableEntityTracker.java @@ -0,0 +1,28 @@ +package net.minecraft.src; + +import java.util.concurrent.Callable; + +class CallableEntityTracker implements Callable { + final int field_96570_a; + + final EntityTracker theEntityTracker; + + CallableEntityTracker(EntityTracker par1EntityTracker, int par2) { + this.theEntityTracker = par1EntityTracker; + this.field_96570_a = par2; + } + + public String func_96568_a() { + String var1 = "Once per " + this.field_96570_a + " ticks"; + + if (this.field_96570_a == Integer.MAX_VALUE) { + var1 = "Maximum (" + var1 + ")"; + } + + return var1; + } + + public Object call() { + return this.func_96568_a(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CallableEntityType.java b/sp-server/src/main/java/net/minecraft/src/CallableEntityType.java new file mode 100644 index 0000000..7f360a4 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CallableEntityType.java @@ -0,0 +1,20 @@ +package net.minecraft.src; + +import java.util.concurrent.Callable; + +class CallableEntityType implements Callable { + final Entity field_85155_a; + + CallableEntityType(Entity par1Entity) { + this.field_85155_a = par1Entity; + } + + public String callEntityType() { + return EntityList.getEntityString(this.field_85155_a) + " (" + this.field_85155_a.getClass().getCanonicalName() + + ")"; + } + + public Object call() { + return this.callEntityType(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CallableIntCache.java b/sp-server/src/main/java/net/minecraft/src/CallableIntCache.java new file mode 100644 index 0000000..2cf72dd --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CallableIntCache.java @@ -0,0 +1,19 @@ +package net.minecraft.src; + +import java.util.concurrent.Callable; + +class CallableIntCache implements Callable { + final CrashReport theCrashReport; + + CallableIntCache(CrashReport par1CrashReport) { + this.theCrashReport = par1CrashReport; + } + + public String func_85083_a() { + return IntCache.func_85144_b(); + } + + public Object call() { + return this.func_85083_a(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CallableIsFeatureChunk.java b/sp-server/src/main/java/net/minecraft/src/CallableIsFeatureChunk.java new file mode 100644 index 0000000..482e324 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CallableIsFeatureChunk.java @@ -0,0 +1,26 @@ +package net.minecraft.src; + +import java.util.concurrent.Callable; + +class CallableIsFeatureChunk implements Callable { + final int field_85169_a; + + final int field_85167_b; + + final MapGenStructure theMapStructureGenerator; + + CallableIsFeatureChunk(MapGenStructure par1MapGenStructure, int par2, int par3) { + this.theMapStructureGenerator = par1MapGenStructure; + this.field_85169_a = par2; + this.field_85167_b = par3; + } + + public String func_85166_a() { + return this.theMapStructureGenerator.canSpawnStructureAtCoords(this.field_85169_a, this.field_85167_b) ? "True" + : "False"; + } + + public Object call() { + return this.func_85166_a(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CallableIsServerModded.java b/sp-server/src/main/java/net/minecraft/src/CallableIsServerModded.java new file mode 100644 index 0000000..bd5174f --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CallableIsServerModded.java @@ -0,0 +1,22 @@ +package net.minecraft.src; + +import java.util.concurrent.Callable; +import net.minecraft.server.MinecraftServer; + +public class CallableIsServerModded implements Callable { + /** Reference to the MinecraftServer object. */ + final MinecraftServer mcServer; + + public CallableIsServerModded(MinecraftServer par1) { + this.mcServer = par1; + } + + public String func_96558_a() { + return this.mcServer.theProfiler.profilingEnabled ? this.mcServer.theProfiler.getNameOfLastSection() + : "N/A (disabled)"; + } + + public Object call() { + return this.func_96558_a(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CallableItemName.java b/sp-server/src/main/java/net/minecraft/src/CallableItemName.java new file mode 100644 index 0000000..4b904ce --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CallableItemName.java @@ -0,0 +1,22 @@ +package net.minecraft.src; + +import java.util.concurrent.Callable; + +class CallableItemName implements Callable { + final ItemStack theItemStack; + + final InventoryPlayer playerInventory; + + CallableItemName(InventoryPlayer par1InventoryPlayer, ItemStack par2ItemStack) { + this.playerInventory = par1InventoryPlayer; + this.theItemStack = par2ItemStack; + } + + public String callItemDisplayName() { + return this.theItemStack.getDisplayName(); + } + + public Object call() { + return this.callItemDisplayName(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CallableJVMFlags.java b/sp-server/src/main/java/net/minecraft/src/CallableJVMFlags.java new file mode 100644 index 0000000..9a029e6 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CallableJVMFlags.java @@ -0,0 +1,45 @@ +package net.minecraft.src; + +import java.lang.management.ManagementFactory; +import java.lang.management.RuntimeMXBean; +import java.util.Iterator; +import java.util.List; +import java.util.concurrent.Callable; + +class CallableJVMFlags implements Callable { + /** Reference to the CrashReport object. */ + final CrashReport theCrashReport; + + CallableJVMFlags(CrashReport par1CrashReport) { + this.theCrashReport = par1CrashReport; + } + + /** + * Returns the number of JVM Flags along with the passed JVM Flags. + */ + public String getJVMFlagsAsString() { + RuntimeMXBean var1 = ManagementFactory.getRuntimeMXBean(); + List var2 = var1.getInputArguments(); + int var3 = 0; + StringBuilder var4 = new StringBuilder(); + Iterator var5 = var2.iterator(); + + while (var5.hasNext()) { + String var6 = (String) var5.next(); + + if (var6.startsWith("-X")) { + if (var3++ > 0) { + var4.append(" "); + } + + var4.append(var6); + } + } + + return String.format("%d total; %s", new Object[] { Integer.valueOf(var3), var4.toString() }); + } + + public Object call() { + return this.getJVMFlagsAsString(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CallableJavaInfo.java b/sp-server/src/main/java/net/minecraft/src/CallableJavaInfo.java new file mode 100644 index 0000000..624fa27 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CallableJavaInfo.java @@ -0,0 +1,23 @@ +package net.minecraft.src; + +import java.util.concurrent.Callable; + +class CallableJavaInfo implements Callable { + /** Reference to the CrashReport object. */ + final CrashReport theCrashReport; + + CallableJavaInfo(CrashReport par1CrashReport) { + this.theCrashReport = par1CrashReport; + } + + /** + * Returns the Java VM Information as a String. Includes the Version and Vender. + */ + public String getJavaInfoAsString() { + return System.getProperty("java.version") + ", " + System.getProperty("java.vendor"); + } + + public Object call() { + return this.getJavaInfoAsString(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CallableJavaInfo2.java b/sp-server/src/main/java/net/minecraft/src/CallableJavaInfo2.java new file mode 100644 index 0000000..5d24f61 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CallableJavaInfo2.java @@ -0,0 +1,25 @@ +package net.minecraft.src; + +import java.util.concurrent.Callable; + +class CallableJavaInfo2 implements Callable { + /** Reference to the CrashReport object. */ + final CrashReport theCrashReport; + + CallableJavaInfo2(CrashReport par1CrashReport) { + this.theCrashReport = par1CrashReport; + } + + /** + * Retuns the Java VM Information as a String. Includes the VM Name, VM Info and + * VM Vendor. + */ + public String getJavaVMInfoAsString() { + return System.getProperty("java.vm.name") + " (" + System.getProperty("java.vm.info") + "), " + + System.getProperty("java.vm.vendor"); + } + + public Object call() { + return this.getJavaVMInfoAsString(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CallableLevelDimension.java b/sp-server/src/main/java/net/minecraft/src/CallableLevelDimension.java new file mode 100644 index 0000000..d82d870 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CallableLevelDimension.java @@ -0,0 +1,19 @@ +package net.minecraft.src; + +import java.util.concurrent.Callable; + +class CallableLevelDimension implements Callable { + final WorldInfo worldInfoInstance; + + CallableLevelDimension(WorldInfo par1WorldInfo) { + this.worldInfoInstance = par1WorldInfo; + } + + public String callLevelDimension() { + return String.valueOf(WorldInfo.func_85122_i(this.worldInfoInstance)); + } + + public Object call() { + return this.callLevelDimension(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CallableLevelGamemode.java b/sp-server/src/main/java/net/minecraft/src/CallableLevelGamemode.java new file mode 100644 index 0000000..f1157c1 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CallableLevelGamemode.java @@ -0,0 +1,23 @@ +package net.minecraft.src; + +import java.util.concurrent.Callable; + +class CallableLevelGamemode implements Callable { + final WorldInfo worldInfoInstance; + + CallableLevelGamemode(WorldInfo par1WorldInfo) { + this.worldInfoInstance = par1WorldInfo; + } + + public String callLevelGameModeInfo() { + return String.format("Game mode: %s (ID %d). Hardcore: %b. Cheats: %b", + new Object[] { WorldInfo.getGameType(this.worldInfoInstance).getName(), + Integer.valueOf(WorldInfo.getGameType(this.worldInfoInstance).getID()), + Boolean.valueOf(WorldInfo.func_85117_p(this.worldInfoInstance)), + Boolean.valueOf(WorldInfo.func_85131_q(this.worldInfoInstance)) }); + } + + public Object call() { + return this.callLevelGameModeInfo(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CallableLevelGenerator.java b/sp-server/src/main/java/net/minecraft/src/CallableLevelGenerator.java new file mode 100644 index 0000000..762538f --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CallableLevelGenerator.java @@ -0,0 +1,24 @@ +package net.minecraft.src; + +import java.util.concurrent.Callable; + +class CallableLevelGenerator implements Callable { + final WorldInfo worldInfoInstance; + + CallableLevelGenerator(WorldInfo par1WorldInfo) { + this.worldInfoInstance = par1WorldInfo; + } + + public String callLevelGeneratorInfo() { + return String.format("ID %02d - %s, ver %d. Features enabled: %b", + new Object[] { + Integer.valueOf(WorldInfo.getTerrainTypeOfWorld(this.worldInfoInstance).getWorldTypeID()), + WorldInfo.getTerrainTypeOfWorld(this.worldInfoInstance).getWorldTypeName(), + Integer.valueOf(WorldInfo.getTerrainTypeOfWorld(this.worldInfoInstance).getGeneratorVersion()), + Boolean.valueOf(WorldInfo.getMapFeaturesEnabled(this.worldInfoInstance)) }); + } + + public Object call() { + return this.callLevelGeneratorInfo(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CallableLevelGeneratorOptions.java b/sp-server/src/main/java/net/minecraft/src/CallableLevelGeneratorOptions.java new file mode 100644 index 0000000..ab99b41 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CallableLevelGeneratorOptions.java @@ -0,0 +1,19 @@ +package net.minecraft.src; + +import java.util.concurrent.Callable; + +class CallableLevelGeneratorOptions implements Callable { + final WorldInfo worldInfoInstance; + + CallableLevelGeneratorOptions(WorldInfo par1WorldInfo) { + this.worldInfoInstance = par1WorldInfo; + } + + public String callLevelGeneratorOptions() { + return WorldInfo.getWorldGeneratorOptions(this.worldInfoInstance); + } + + public Object call() { + return this.callLevelGeneratorOptions(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CallableLevelSeed.java b/sp-server/src/main/java/net/minecraft/src/CallableLevelSeed.java new file mode 100644 index 0000000..b17ba78 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CallableLevelSeed.java @@ -0,0 +1,19 @@ +package net.minecraft.src; + +import java.util.concurrent.Callable; + +class CallableLevelSeed implements Callable { + final WorldInfo worldInfoInstance; + + CallableLevelSeed(WorldInfo par1WorldInfo) { + this.worldInfoInstance = par1WorldInfo; + } + + public String callLevelSeed() { + return String.valueOf(this.worldInfoInstance.getSeed()); + } + + public Object call() { + return this.callLevelSeed(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CallableLevelSpawnLocation.java b/sp-server/src/main/java/net/minecraft/src/CallableLevelSpawnLocation.java new file mode 100644 index 0000000..0af2197 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CallableLevelSpawnLocation.java @@ -0,0 +1,21 @@ +package net.minecraft.src; + +import java.util.concurrent.Callable; + +class CallableLevelSpawnLocation implements Callable { + final WorldInfo worldInfoInstance; + + CallableLevelSpawnLocation(WorldInfo par1WorldInfo) { + this.worldInfoInstance = par1WorldInfo; + } + + public String callLevelSpawnLocation() { + return CrashReportCategory.getLocationInfo(WorldInfo.getSpawnXCoordinate(this.worldInfoInstance), + WorldInfo.getSpawnYCoordinate(this.worldInfoInstance), + WorldInfo.getSpawnZCoordinate(this.worldInfoInstance)); + } + + public Object call() { + return this.callLevelSpawnLocation(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CallableLevelStorageVersion.java b/sp-server/src/main/java/net/minecraft/src/CallableLevelStorageVersion.java new file mode 100644 index 0000000..269acf3 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CallableLevelStorageVersion.java @@ -0,0 +1,35 @@ +package net.minecraft.src; + +import java.util.concurrent.Callable; + +class CallableLevelStorageVersion implements Callable { + final WorldInfo worldInfoInstance; + + CallableLevelStorageVersion(WorldInfo par1WorldInfo) { + this.worldInfoInstance = par1WorldInfo; + } + + public String callLevelStorageFormat() { + String var1 = "Unknown?"; + + try { + switch (WorldInfo.getSaveVersion(this.worldInfoInstance)) { + case 19132: + var1 = "McRegion"; + break; + + case 19133: + var1 = "Anvil"; + } + } catch (Throwable var3) { + ; + } + + return String.format("0x%05X - %s", + new Object[] { Integer.valueOf(WorldInfo.getSaveVersion(this.worldInfoInstance)), var1 }); + } + + public Object call() { + return this.callLevelStorageFormat(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CallableLevelTime.java b/sp-server/src/main/java/net/minecraft/src/CallableLevelTime.java new file mode 100644 index 0000000..4c4c9e8 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CallableLevelTime.java @@ -0,0 +1,21 @@ +package net.minecraft.src; + +import java.util.concurrent.Callable; + +class CallableLevelTime implements Callable { + final WorldInfo worldInfoInstance; + + CallableLevelTime(WorldInfo par1WorldInfo) { + this.worldInfoInstance = par1WorldInfo; + } + + public String callLevelTime() { + return String.format("%d game time, %d day time", + new Object[] { Long.valueOf(WorldInfo.func_85126_g(this.worldInfoInstance)), + Long.valueOf(WorldInfo.getWorldTime(this.worldInfoInstance)) }); + } + + public Object call() { + return this.callLevelTime(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CallableLevelWeather.java b/sp-server/src/main/java/net/minecraft/src/CallableLevelWeather.java new file mode 100644 index 0000000..e48157b --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CallableLevelWeather.java @@ -0,0 +1,23 @@ +package net.minecraft.src; + +import java.util.concurrent.Callable; + +class CallableLevelWeather implements Callable { + final WorldInfo worldInfoInstance; + + CallableLevelWeather(WorldInfo par1WorldInfo) { + this.worldInfoInstance = par1WorldInfo; + } + + public String callLevelWeatherInfo() { + return String.format("Rain time: %d (now: %b), thunder time: %d (now: %b)", + new Object[] { Integer.valueOf(WorldInfo.getRainTime(this.worldInfoInstance)), + Boolean.valueOf(WorldInfo.getRaining(this.worldInfoInstance)), + Integer.valueOf(WorldInfo.getThunderTime(this.worldInfoInstance)), + Boolean.valueOf(WorldInfo.getThundering(this.worldInfoInstance)) }); + } + + public Object call() { + return this.callLevelWeatherInfo(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CallableLvl1.java b/sp-server/src/main/java/net/minecraft/src/CallableLvl1.java new file mode 100644 index 0000000..3e6ee64 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CallableLvl1.java @@ -0,0 +1,30 @@ +package net.minecraft.src; + +import java.util.concurrent.Callable; + +class CallableLvl1 implements Callable { + final int field_85179_a; + + /** Reference to the World object. */ + final World theWorld; + + CallableLvl1(World par1World, int par2) { + this.theWorld = par1World; + this.field_85179_a = par2; + } + + public String getWorldEntitiesAsString() { + try { + return String.format("ID #%d (%s // %s)", + new Object[] { Integer.valueOf(this.field_85179_a), + Block.blocksList[this.field_85179_a].getUnlocalizedName(), + Block.blocksList[this.field_85179_a].getClass().getCanonicalName() }); + } catch (Throwable var2) { + return "ID #" + this.field_85179_a; + } + } + + public Object call() { + return this.getWorldEntitiesAsString(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CallableLvl2.java b/sp-server/src/main/java/net/minecraft/src/CallableLvl2.java new file mode 100644 index 0000000..970ab7e --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CallableLvl2.java @@ -0,0 +1,23 @@ +package net.minecraft.src; + +import java.util.concurrent.Callable; + +class CallableLvl2 implements Callable { + /** Reference to the World object. */ + final World theWorld; + + CallableLvl2(World par1World) { + this.theWorld = par1World; + } + + /** + * Returns the size and contents of the player entity list. + */ + public String getPlayerEntities() { + return this.theWorld.playerEntities.size() + " total; " + this.theWorld.playerEntities.toString(); + } + + public Object call() { + return this.getPlayerEntities(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CallableLvl3.java b/sp-server/src/main/java/net/minecraft/src/CallableLvl3.java new file mode 100644 index 0000000..64f7d26 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CallableLvl3.java @@ -0,0 +1,23 @@ +package net.minecraft.src; + +import java.util.concurrent.Callable; + +class CallableLvl3 implements Callable { + /** Reference to the World object. */ + final World theWorld; + + CallableLvl3(World par1World) { + this.theWorld = par1World; + } + + /** + * Returns the result of the ChunkProvider's makeString + */ + public String getChunkProvider() { + return this.theWorld.chunkProvider.makeString(); + } + + public Object call() { + return this.getChunkProvider(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CallableMemoryInfo.java b/sp-server/src/main/java/net/minecraft/src/CallableMemoryInfo.java new file mode 100644 index 0000000..6597e6d --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CallableMemoryInfo.java @@ -0,0 +1,32 @@ +package net.minecraft.src; + +import java.util.concurrent.Callable; + +class CallableMemoryInfo implements Callable { + /** Reference to the CrashReport object. */ + final CrashReport theCrashReport; + + CallableMemoryInfo(CrashReport par1CrashReport) { + this.theCrashReport = par1CrashReport; + } + + /** + * Returns the memory information as a String. Includes the Free Memory in bytes + * and MB, Total Memory in bytes and MB, and Max Memory in Bytes and MB. + */ + public String getMemoryInfoAsString() { + Runtime var1 = Runtime.getRuntime(); + long var2 = var1.maxMemory(); + long var4 = var1.totalMemory(); + long var6 = var1.freeMemory(); + long var8 = var2 / 1024L / 1024L; + long var10 = var4 / 1024L / 1024L; + long var12 = var6 / 1024L / 1024L; + return var6 + " bytes (" + var12 + " MB) / " + var4 + " bytes (" + var10 + " MB) up to " + var2 + " bytes (" + + var8 + " MB)"; + } + + public Object call() { + return this.getMemoryInfoAsString(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CallableMinecraftVersion.java b/sp-server/src/main/java/net/minecraft/src/CallableMinecraftVersion.java new file mode 100644 index 0000000..9ed41e6 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CallableMinecraftVersion.java @@ -0,0 +1,23 @@ +package net.minecraft.src; + +import java.util.concurrent.Callable; + +class CallableMinecraftVersion implements Callable { + /** Reference to the CrashReport object. */ + final CrashReport theCrashReport; + + CallableMinecraftVersion(CrashReport par1CrashReport) { + this.theCrashReport = par1CrashReport; + } + + /** + * The current version of Minecraft + */ + public String minecraftVersion() { + return "1.5.2"; + } + + public Object call() { + return this.minecraftVersion(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CallableOSInfo.java b/sp-server/src/main/java/net/minecraft/src/CallableOSInfo.java new file mode 100644 index 0000000..e357828 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CallableOSInfo.java @@ -0,0 +1,21 @@ +package net.minecraft.src; + +import java.util.concurrent.Callable; + +class CallableOSInfo implements Callable { + /** Reference to the CrashReport object. */ + final CrashReport theCrashReport; + + CallableOSInfo(CrashReport par1CrashReport) { + this.theCrashReport = par1CrashReport; + } + + public String getOsAsString() { + return System.getProperty("os.name") + " (" + System.getProperty("os.arch") + ") version " + + System.getProperty("os.version"); + } + + public Object call() { + return this.getOsAsString(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CallablePacketClass.java b/sp-server/src/main/java/net/minecraft/src/CallablePacketClass.java new file mode 100644 index 0000000..11e5610 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CallablePacketClass.java @@ -0,0 +1,22 @@ +package net.minecraft.src; + +import java.util.concurrent.Callable; + +class CallablePacketClass implements Callable { + final Packet thePacket; + + final NetServerHandler theNetServerHandler; + + CallablePacketClass(NetServerHandler par1NetServerHandler, Packet par2Packet) { + this.theNetServerHandler = par1NetServerHandler; + this.thePacket = par2Packet; + } + + public String getPacketClass() { + return this.thePacket.getClass().getCanonicalName(); + } + + public Object call() { + return this.getPacketClass(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CallablePacketID.java b/sp-server/src/main/java/net/minecraft/src/CallablePacketID.java new file mode 100644 index 0000000..a709620 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CallablePacketID.java @@ -0,0 +1,22 @@ +package net.minecraft.src; + +import java.util.concurrent.Callable; + +class CallablePacketID implements Callable { + final Packet thePacket; + + final NetServerHandler theNetServerHandler; + + CallablePacketID(NetServerHandler par1NetServerHandler, Packet par2Packet) { + this.theNetServerHandler = par1NetServerHandler; + this.thePacket = par2Packet; + } + + public String callPacketID() { + return String.valueOf(this.thePacket.getPacketId()); + } + + public Object call() { + return this.callPacketID(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CallableServerMemoryStats.java b/sp-server/src/main/java/net/minecraft/src/CallableServerMemoryStats.java new file mode 100644 index 0000000..5b595d0 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CallableServerMemoryStats.java @@ -0,0 +1,23 @@ +package net.minecraft.src; + +import java.util.concurrent.Callable; +import net.minecraft.server.MinecraftServer; + +public class CallableServerMemoryStats implements Callable { + /** Reference to the MinecraftServer object. */ + final MinecraftServer mcServer; + + public CallableServerMemoryStats(MinecraftServer par1) { + this.mcServer = par1; + } + + public String callServerMemoryStats() { + return MinecraftServer.getServerConfigurationManager(this.mcServer).getCurrentPlayerCount() + " / " + + MinecraftServer.getServerConfigurationManager(this.mcServer).getMaxPlayers() + "; " + + MinecraftServer.getServerConfigurationManager(this.mcServer).playerEntityList; + } + + public Object call() { + return this.callServerMemoryStats(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CallableServerProfiler.java b/sp-server/src/main/java/net/minecraft/src/CallableServerProfiler.java new file mode 100644 index 0000000..1f8bee6 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CallableServerProfiler.java @@ -0,0 +1,28 @@ +package net.minecraft.src; + +import java.util.concurrent.Callable; +import net.minecraft.server.MinecraftServer; + +public class CallableServerProfiler implements Callable { + /** Reference to the MinecraftServer object. */ + final MinecraftServer mcServer; + + public CallableServerProfiler(MinecraftServer par1) { + this.mcServer = par1; + } + + public String callServerProfiler() { + int var1 = this.mcServer.worldServers[0].getWorldVec3Pool().getPoolSize(); + int var2 = 56 * var1; + int var3 = var2 / 1024 / 1024; + int var4 = this.mcServer.worldServers[0].getWorldVec3Pool().func_82590_d(); + int var5 = 56 * var4; + int var6 = var5 / 1024 / 1024; + return var1 + " (" + var2 + " bytes; " + var3 + " MB) allocated, " + var4 + " (" + var5 + " bytes; " + var6 + + " MB) used"; + } + + public Object call() { + return this.callServerProfiler(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CallableServerType.java b/sp-server/src/main/java/net/minecraft/src/CallableServerType.java new file mode 100644 index 0000000..787df5a --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CallableServerType.java @@ -0,0 +1,19 @@ +package net.minecraft.src; + +import java.util.concurrent.Callable; + +class CallableServerType implements Callable { + final DedicatedServer theDedicatedServer; + + CallableServerType(DedicatedServer par1DedicatedServer) { + this.theDedicatedServer = par1DedicatedServer; + } + + public String callServerType() { + return "Dedicated Server (map_server.txt)"; + } + + public Object call() { + return this.callServerType(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CallableStructureType.java b/sp-server/src/main/java/net/minecraft/src/CallableStructureType.java new file mode 100644 index 0000000..f12b200 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CallableStructureType.java @@ -0,0 +1,19 @@ +package net.minecraft.src; + +import java.util.concurrent.Callable; + +class CallableStructureType implements Callable { + final MapGenStructure theMapStructureGenerator; + + CallableStructureType(MapGenStructure par1MapGenStructure) { + this.theMapStructureGenerator = par1MapGenStructure; + } + + public String callStructureType() { + return this.theMapStructureGenerator.getClass().getCanonicalName(); + } + + public Object call() { + return this.callStructureType(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CallableSuspiciousClasses.java b/sp-server/src/main/java/net/minecraft/src/CallableSuspiciousClasses.java new file mode 100644 index 0000000..113529b --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CallableSuspiciousClasses.java @@ -0,0 +1,115 @@ +package net.minecraft.src; + +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Vector; +import java.util.concurrent.Callable; + +class CallableSuspiciousClasses implements Callable { + final CrashReport theCrashReport; + + CallableSuspiciousClasses(CrashReport par1CrashReport) { + this.theCrashReport = par1CrashReport; + } + + public String callSuspiciousClasses() { + StringBuilder var1 = new StringBuilder(); + ArrayList var3; + + try { + Field var2 = ClassLoader.class.getDeclaredField("classes"); + var2.setAccessible(true); + var3 = new ArrayList((Vector) var2.get(CrashReport.class.getClassLoader())); + } catch (Exception ex) { + return ""; + } + + boolean var4 = true; + boolean var5 = !CrashReport.class.getCanonicalName().equals("net.minecraft.CrashReport"); + HashMap var6 = new HashMap(); + String var7 = ""; + Collections.sort(var3, new ComparatorClassSorter(this)); + Iterator var8 = var3.iterator(); + + while (var8.hasNext()) { + Class var9 = (Class) var8.next(); + + if (var9 != null) { + String var10 = var9.getCanonicalName(); + + if (var10 != null && !var10.startsWith("org.lwjgl.") && !var10.startsWith("paulscode.") + && !var10.startsWith("org.bouncycastle.") && !var10.startsWith("argo.") + && !var10.startsWith("com.jcraft.") && !var10.startsWith("com.fasterxml.") + && !var10.equals("util.GLX")) { + if (var5) { + if (var10.length() <= 3 || var10.equals("net.minecraft.client.MinecraftApplet") + || var10.equals("net.minecraft.client.Minecraft") + || var10.equals("net.minecraft.client.ClientBrandRetriever") + || var10.equals("net.minecraft.server.MinecraftServer")) { + continue; + } + } else if (var10.startsWith("net.minecraft")) { + continue; + } + + Package var11 = var9.getPackage(); + String var12 = var11 == null ? "" : var11.getName(); + + if (var6.containsKey(var12)) { + int var13 = ((Integer) var6.get(var12)).intValue(); + var6.put(var12, Integer.valueOf(var13 + 1)); + + if (var13 == 3) { + if (!var4) { + var1.append(", "); + } + + var1.append("..."); + var4 = false; + continue; + } + + if (var13 > 3) { + continue; + } + } else { + var6.put(var12, Integer.valueOf(1)); + } + + if (var7 != var12 && var7.length() > 0) { + var1.append("], "); + } + + if (!var4 && var7 == var12) { + var1.append(", "); + } + + if (var7 != var12) { + var1.append("["); + var1.append(var12); + var1.append("."); + } + + var1.append(var9.getSimpleName()); + var7 = var12; + var4 = false; + } + } + } + + if (var4) { + var1.append("No suspicious classes found."); + } else { + var1.append("]"); + } + + return var1.toString(); + } + + public Object call() { + return this.callSuspiciousClasses(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CallableTagCompound1.java b/sp-server/src/main/java/net/minecraft/src/CallableTagCompound1.java new file mode 100644 index 0000000..2385588 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CallableTagCompound1.java @@ -0,0 +1,23 @@ +package net.minecraft.src; + +import java.util.concurrent.Callable; + +class CallableTagCompound1 implements Callable { + final String field_82585_a; + + final NBTTagCompound theNBTTagCompound; + + CallableTagCompound1(NBTTagCompound par1NBTTagCompound, String par2Str) { + this.theNBTTagCompound = par1NBTTagCompound; + this.field_82585_a = par2Str; + } + + public String func_82583_a() { + return NBTBase.NBTTypes[((NBTBase) NBTTagCompound.getTagMap(this.theNBTTagCompound).get(this.field_82585_a)) + .getId()]; + } + + public Object call() { + return this.func_82583_a(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CallableTagCompound2.java b/sp-server/src/main/java/net/minecraft/src/CallableTagCompound2.java new file mode 100644 index 0000000..e8eb5c1 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CallableTagCompound2.java @@ -0,0 +1,22 @@ +package net.minecraft.src; + +import java.util.concurrent.Callable; + +class CallableTagCompound2 implements Callable { + final int field_82588_a; + + final NBTTagCompound theNBTTagCompound; + + CallableTagCompound2(NBTTagCompound par1NBTTagCompound, int par2) { + this.theNBTTagCompound = par1NBTTagCompound; + this.field_82588_a = par2; + } + + public String func_82586_a() { + return NBTBase.NBTTypes[this.field_82588_a]; + } + + public Object call() { + return this.func_82586_a(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CallableTileEntityData.java b/sp-server/src/main/java/net/minecraft/src/CallableTileEntityData.java new file mode 100644 index 0000000..0628634 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CallableTileEntityData.java @@ -0,0 +1,27 @@ +package net.minecraft.src; + +import java.util.concurrent.Callable; + +class CallableTileEntityData implements Callable { + final TileEntity theTileEntity; + + CallableTileEntityData(TileEntity par1TileEntity) { + this.theTileEntity = par1TileEntity; + } + + public String callTileEntityDataInfo() { + int var1 = this.theTileEntity.worldObj.getBlockMetadata(this.theTileEntity.xCoord, this.theTileEntity.yCoord, + this.theTileEntity.zCoord); + + if (var1 < 0) { + return "Unknown? (Got " + var1 + ")"; + } else { + String var2 = String.format("%4s", new Object[] { Integer.toBinaryString(var1) }).replace(" ", "0"); + return String.format("%1$d / 0x%1$X / 0b%2$s", new Object[] { Integer.valueOf(var1), var2 }); + } + } + + public Object call() { + return this.callTileEntityDataInfo(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CallableTileEntityID.java b/sp-server/src/main/java/net/minecraft/src/CallableTileEntityID.java new file mode 100644 index 0000000..ea66084 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CallableTileEntityID.java @@ -0,0 +1,28 @@ +package net.minecraft.src; + +import java.util.concurrent.Callable; + +class CallableTileEntityID implements Callable { + final TileEntity theTileEntity; + + CallableTileEntityID(TileEntity par1TileEntity) { + this.theTileEntity = par1TileEntity; + } + + public String callTileEntityID() { + int var1 = this.theTileEntity.worldObj.getBlockId(this.theTileEntity.xCoord, this.theTileEntity.yCoord, + this.theTileEntity.zCoord); + + try { + return String.format("ID #%d (%s // %s)", + new Object[] { Integer.valueOf(var1), Block.blocksList[var1].getUnlocalizedName(), + Block.blocksList[var1].getClass().getCanonicalName() }); + } catch (Throwable var3) { + return "ID #" + var1; + } + } + + public Object call() { + return this.callTileEntityID(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CallableTileEntityName.java b/sp-server/src/main/java/net/minecraft/src/CallableTileEntityName.java new file mode 100644 index 0000000..0b45264 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CallableTileEntityName.java @@ -0,0 +1,20 @@ +package net.minecraft.src; + +import java.util.concurrent.Callable; + +class CallableTileEntityName implements Callable { + final TileEntity theTileEntity; + + CallableTileEntityName(TileEntity par1TileEntity) { + this.theTileEntity = par1TileEntity; + } + + public String callTileEntityName() { + return (String) TileEntity.getClassToNameMap().get(this.theTileEntity.getClass()) + " // " + + this.theTileEntity.getClass().getCanonicalName(); + } + + public Object call() { + return this.callTileEntityName(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CallableType.java b/sp-server/src/main/java/net/minecraft/src/CallableType.java new file mode 100644 index 0000000..24009c5 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CallableType.java @@ -0,0 +1,22 @@ +package net.minecraft.src; + +import java.util.concurrent.Callable; + +class CallableType implements Callable { + /** Reference to the DecitatedServer object. */ + final DedicatedServer theDecitatedServer; + + CallableType(DedicatedServer par1DedicatedServer) { + this.theDecitatedServer = par1DedicatedServer; + } + + public String getType() { + String var1 = this.theDecitatedServer.getServerModName(); + return !var1.equals("vanilla") ? "Definitely; Server brand changed to \'" + var1 + "\'" + : "Unknown (can\'t tell)"; + } + + public Object call() { + return this.getType(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ChatAllowedCharacters.java b/sp-server/src/main/java/net/minecraft/src/ChatAllowedCharacters.java new file mode 100644 index 0000000..cc13af7 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ChatAllowedCharacters.java @@ -0,0 +1,68 @@ +package net.minecraft.src; + +import java.io.BufferedReader; +import java.io.InputStreamReader; + +public class ChatAllowedCharacters { + /** + * This String have the characters allowed in any text drawing of minecraft. + */ + public static final String allowedCharacters = getAllowedCharacters(); + + /** + * Array of the special characters that are allowed in any text drawing of + * Minecraft. + */ + public static final char[] allowedCharactersArray = new char[] { '/', '\n', '\r', '\t', '\u0000', '\f', '`', '?', + '*', '\\', '<', '>', '|', '\"', ':' }; + + /** + * Load the font.txt resource file, that is on UTF-8 format. This file contains + * the characters that minecraft can render Strings on screen. + */ + private static String getAllowedCharacters() { + String var0 = ""; + + try { + BufferedReader var1 = new BufferedReader( + new InputStreamReader(ChatAllowedCharacters.class.getResourceAsStream("/font.txt"), "UTF-8")); + String var2 = ""; + + while ((var2 = var1.readLine()) != null) { + if (!var2.startsWith("#")) { + var0 = var0 + var2; + } + } + + var1.close(); + } catch (Exception var3) { + ; + } + + return var0; + } + + public static final boolean isAllowedCharacter(char par0) { + return par0 != 167 && (allowedCharacters.indexOf(par0) >= 0 || par0 > 32); + } + + /** + * Filter string by only keeping those characters for which isAllowedCharacter() + * returns true. + */ + public static String filerAllowedCharacters(String par0Str) { + StringBuilder var1 = new StringBuilder(); + char[] var2 = par0Str.toCharArray(); + int var3 = var2.length; + + for (int var4 = 0; var4 < var3; ++var4) { + char var5 = var2[var4]; + + if (isAllowedCharacter(var5)) { + var1.append(var5); + } + } + + return var1.toString(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/Chunk.java b/sp-server/src/main/java/net/minecraft/src/Chunk.java new file mode 100644 index 0000000..abef8cd --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/Chunk.java @@ -0,0 +1,1129 @@ +package net.minecraft.src; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Random; + +public class Chunk { + /** + * Determines if the chunk is lit or not at a light value greater than 0. + */ + public static boolean isLit; + + /** + * Used to store block IDs, block MSBs, Sky-light maps, Block-light maps, and + * metadata. Each entry corresponds to a logical segment of 16x16x16 blocks, + * stacked vertically. + */ + private ExtendedBlockStorage[] storageArrays; + + /** + * Contains a 16x16 mapping on the X/Z plane of the biome ID to which each colum + * belongs. + */ + private byte[] blockBiomeArray; + + /** + * A map, similar to heightMap, that tracks how far down precipitation can fall. + */ + public int[] precipitationHeightMap; + + /** Which columns need their skylightMaps updated. */ + public boolean[] updateSkylightColumns; + + /** Whether or not this Chunk is currently loaded into the World */ + public boolean isChunkLoaded; + + /** Reference to the World object. */ + public World worldObj; + public int[] heightMap; + + /** The x coordinate of the chunk. */ + public final int xPosition; + + /** The z coordinate of the chunk. */ + public final int zPosition; + private boolean isGapLightingUpdated; + + /** A Map of ChunkPositions to TileEntities in this chunk */ + public Map chunkTileEntityMap; + + /** + * Array of Lists containing the entities in this Chunk. Each List represents a + * 16 block subchunk. + */ + public List[] entityLists; + + /** Boolean value indicating if the terrain is populated. */ + public boolean isTerrainPopulated; + + /** + * Set to true if the chunk has been modified and needs to be updated + * internally. + */ + public boolean isModified; + + /** + * Whether this Chunk has any Entities and thus requires saving on every tick + */ + public boolean hasEntities; + + /** The time according to World.worldTime when this chunk was last saved */ + public long lastSaveTime; + + /** + * Updates to this chunk will not be sent to clients if this is false. This + * field is set to true the first time the chunk is sent to a client, and never + * set to false. + */ + public boolean sendUpdates; + + /** Lowest value in the heightmap. */ + public int heightMapMinimum; + + /** + * Contains the current round-robin relight check index, and is implied as the + * relight check location as well. + */ + private int queuedLightChecks; + boolean field_76653_p; + + public Chunk(World par1World, int par2, int par3) { + this.storageArrays = new ExtendedBlockStorage[16]; + this.blockBiomeArray = new byte[256]; + this.precipitationHeightMap = new int[256]; + this.updateSkylightColumns = new boolean[256]; + this.isGapLightingUpdated = false; + this.chunkTileEntityMap = new HashMap(); + this.isTerrainPopulated = false; + this.isModified = false; + this.hasEntities = false; + this.lastSaveTime = 0L; + this.sendUpdates = false; + this.heightMapMinimum = 0; + this.queuedLightChecks = 4096; + this.field_76653_p = false; + this.entityLists = new List[16]; + this.worldObj = par1World; + this.xPosition = par2; + this.zPosition = par3; + this.heightMap = new int[256]; + + for (int var4 = 0; var4 < this.entityLists.length; ++var4) { + this.entityLists[var4] = new ArrayList(); + } + + Arrays.fill(this.precipitationHeightMap, -999); + Arrays.fill(this.blockBiomeArray, (byte) -1); + } + + public Chunk(World par1World, byte[] par2ArrayOfByte, int par3, int par4) { + this(par1World, par3, par4); + int var5 = par2ArrayOfByte.length / 256; + + for (int var6 = 0; var6 < 16; ++var6) { + for (int var7 = 0; var7 < 16; ++var7) { + for (int var8 = 0; var8 < var5; ++var8) { + byte var9 = par2ArrayOfByte[var6 << 11 | var7 << 7 | var8]; + + if (var9 != 0) { + int var10 = var8 >> 4; + + if (this.storageArrays[var10] == null) { + this.storageArrays[var10] = new ExtendedBlockStorage(var10 << 4, + !par1World.provider.hasNoSky); + } + + this.storageArrays[var10].setExtBlockID(var6, var8 & 15, var7, var9); + } + } + } + } + } + + /** + * Checks whether the chunk is at the X/Z location specified + */ + public boolean isAtLocation(int par1, int par2) { + return par1 == this.xPosition && par2 == this.zPosition; + } + + /** + * Returns the value in the height map at this x, z coordinate in the chunk + */ + public int getHeightValue(int par1, int par2) { + return this.heightMap[par2 << 4 | par1]; + } + + /** + * Returns the topmost ExtendedBlockStorage instance for this Chunk that + * actually contains a block. + */ + public int getTopFilledSegment() { + for (int var1 = this.storageArrays.length - 1; var1 >= 0; --var1) { + if (this.storageArrays[var1] != null) { + return this.storageArrays[var1].getYLocation(); + } + } + + return 0; + } + + /** + * Returns the ExtendedBlockStorage array for this Chunk. + */ + public ExtendedBlockStorage[] getBlockStorageArray() { + return this.storageArrays; + } + + /** + * Generates the initial skylight map for the chunk upon generation or load. + */ + public void generateSkylightMap() { + int var1 = this.getTopFilledSegment(); + this.heightMapMinimum = Integer.MAX_VALUE; + int var2; + int var3; + + for (var2 = 0; var2 < 16; ++var2) { + var3 = 0; + + while (var3 < 16) { + this.precipitationHeightMap[var2 + (var3 << 4)] = -999; + int var4 = var1 + 16 - 1; + + while (true) { + if (var4 > 0) { + if (this.getBlockLightOpacity(var2, var4 - 1, var3) == 0) { + --var4; + continue; + } + + this.heightMap[var3 << 4 | var2] = var4; + + if (var4 < this.heightMapMinimum) { + this.heightMapMinimum = var4; + } + } + + if (!this.worldObj.provider.hasNoSky) { + var4 = 15; + int var5 = var1 + 16 - 1; + + do { + var4 -= this.getBlockLightOpacity(var2, var5, var3); + + if (var4 > 0) { + ExtendedBlockStorage var6 = this.storageArrays[var5 >> 4]; + + if (var6 != null) { + var6.setExtSkylightValue(var2, var5 & 15, var3, var4); + this.worldObj.markBlockForRenderUpdate((this.xPosition << 4) + var2, var5, + (this.zPosition << 4) + var3); + } + } + + --var5; + } while (var5 > 0 && var4 > 0); + } + + ++var3; + break; + } + } + } + + this.isModified = true; + + for (var2 = 0; var2 < 16; ++var2) { + for (var3 = 0; var3 < 16; ++var3) { + this.propagateSkylightOcclusion(var2, var3); + } + } + } + + /** + * Propagates a given sky-visible block's light value downward and upward to + * neighboring blocks as necessary. + */ + private void propagateSkylightOcclusion(int par1, int par2) { + this.updateSkylightColumns[par1 + par2 * 16] = true; + this.isGapLightingUpdated = true; + } + + /** + * Runs delayed skylight updates. + */ + private void updateSkylight_do() { + this.worldObj.theProfiler.startSection("recheckGaps"); + + if (this.worldObj.doChunksNearChunkExist(this.xPosition * 16 + 8, 0, this.zPosition * 16 + 8, 16)) { + for (int var1 = 0; var1 < 16; ++var1) { + for (int var2 = 0; var2 < 16; ++var2) { + if (this.updateSkylightColumns[var1 + var2 * 16]) { + this.updateSkylightColumns[var1 + var2 * 16] = false; + int var3 = this.getHeightValue(var1, var2); + int var4 = this.xPosition * 16 + var1; + int var5 = this.zPosition * 16 + var2; + int var6 = this.worldObj.getChunkHeightMapMinimum(var4 - 1, var5); + int var7 = this.worldObj.getChunkHeightMapMinimum(var4 + 1, var5); + int var8 = this.worldObj.getChunkHeightMapMinimum(var4, var5 - 1); + int var9 = this.worldObj.getChunkHeightMapMinimum(var4, var5 + 1); + + if (var7 < var6) { + var6 = var7; + } + + if (var8 < var6) { + var6 = var8; + } + + if (var9 < var6) { + var6 = var9; + } + + this.checkSkylightNeighborHeight(var4, var5, var6); + this.checkSkylightNeighborHeight(var4 - 1, var5, var3); + this.checkSkylightNeighborHeight(var4 + 1, var5, var3); + this.checkSkylightNeighborHeight(var4, var5 - 1, var3); + this.checkSkylightNeighborHeight(var4, var5 + 1, var3); + } + } + } + + this.isGapLightingUpdated = false; + } + + this.worldObj.theProfiler.endSection(); + } + + /** + * Checks the height of a block next to a sky-visible block and schedules a + * lighting update as necessary. + */ + private void checkSkylightNeighborHeight(int par1, int par2, int par3) { + int var4 = this.worldObj.getHeightValue(par1, par2); + + if (var4 > par3) { + this.updateSkylightNeighborHeight(par1, par2, par3, var4 + 1); + } else if (var4 < par3) { + this.updateSkylightNeighborHeight(par1, par2, var4, par3 + 1); + } + } + + private void updateSkylightNeighborHeight(int par1, int par2, int par3, int par4) { + if (par4 > par3 && this.worldObj.doChunksNearChunkExist(par1, 0, par2, 16)) { + for (int var5 = par3; var5 < par4; ++var5) { + this.worldObj.updateLightByType(EnumSkyBlock.Sky, par1, var5, par2); + } + + this.isModified = true; + } + } + + /** + * Initiates the recalculation of both the block-light and sky-light for a given + * block inside a chunk. + */ + private void relightBlock(int par1, int par2, int par3) { + int var4 = this.heightMap[par3 << 4 | par1] & 255; + int var5 = var4; + + if (par2 > var4) { + var5 = par2; + } + + while (var5 > 0 && this.getBlockLightOpacity(par1, var5 - 1, par3) == 0) { + --var5; + } + + if (var5 != var4) { + this.worldObj.markBlocksDirtyVertical(par1 + this.xPosition * 16, par3 + this.zPosition * 16, var5, var4); + this.heightMap[par3 << 4 | par1] = var5; + int var6 = this.xPosition * 16 + par1; + int var7 = this.zPosition * 16 + par3; + int var8; + int var12; + + if (!this.worldObj.provider.hasNoSky) { + ExtendedBlockStorage var9; + + if (var5 < var4) { + for (var8 = var5; var8 < var4; ++var8) { + var9 = this.storageArrays[var8 >> 4]; + + if (var9 != null) { + var9.setExtSkylightValue(par1, var8 & 15, par3, 15); + this.worldObj.markBlockForRenderUpdate((this.xPosition << 4) + par1, var8, + (this.zPosition << 4) + par3); + } + } + } else { + for (var8 = var4; var8 < var5; ++var8) { + var9 = this.storageArrays[var8 >> 4]; + + if (var9 != null) { + var9.setExtSkylightValue(par1, var8 & 15, par3, 0); + this.worldObj.markBlockForRenderUpdate((this.xPosition << 4) + par1, var8, + (this.zPosition << 4) + par3); + } + } + } + + var8 = 15; + + while (var5 > 0 && var8 > 0) { + --var5; + var12 = this.getBlockLightOpacity(par1, var5, par3); + + if (var12 == 0) { + var12 = 1; + } + + var8 -= var12; + + if (var8 < 0) { + var8 = 0; + } + + ExtendedBlockStorage var10 = this.storageArrays[var5 >> 4]; + + if (var10 != null) { + var10.setExtSkylightValue(par1, var5 & 15, par3, var8); + } + } + } + + var8 = this.heightMap[par3 << 4 | par1]; + var12 = var4; + int var13 = var8; + + if (var8 < var4) { + var12 = var8; + var13 = var4; + } + + if (var8 < this.heightMapMinimum) { + this.heightMapMinimum = var8; + } + + if (!this.worldObj.provider.hasNoSky) { + this.updateSkylightNeighborHeight(var6 - 1, var7, var12, var13); + this.updateSkylightNeighborHeight(var6 + 1, var7, var12, var13); + this.updateSkylightNeighborHeight(var6, var7 - 1, var12, var13); + this.updateSkylightNeighborHeight(var6, var7 + 1, var12, var13); + this.updateSkylightNeighborHeight(var6, var7, var12, var13); + } + + this.isModified = true; + } + } + + public int getBlockLightOpacity(int par1, int par2, int par3) { + return Block.lightOpacity[this.getBlockID(par1, par2, par3)]; + } + + /** + * Return the ID of a block in the chunk. + */ + public int getBlockID(int par1, int par2, int par3) { + if (par2 >> 4 >= this.storageArrays.length) { + return 0; + } else { + ExtendedBlockStorage var4 = this.storageArrays[par2 >> 4]; + return var4 != null ? var4.getExtBlockID(par1, par2 & 15, par3) : 0; + } + } + + /** + * Return the metadata corresponding to the given coordinates inside a chunk. + */ + public int getBlockMetadata(int par1, int par2, int par3) { + if (par2 >> 4 >= this.storageArrays.length) { + return 0; + } else { + ExtendedBlockStorage var4 = this.storageArrays[par2 >> 4]; + return var4 != null ? var4.getExtBlockMetadata(par1, par2 & 15, par3) : 0; + } + } + + /** + * Sets a blockID of a position within a chunk with metadata. Args: x, y, z, + * blockID, metadata + */ + public boolean setBlockIDWithMetadata(int par1, int par2, int par3, int par4, int par5) { + int var6 = par3 << 4 | par1; + + if (par2 >= this.precipitationHeightMap[var6] - 1) { + this.precipitationHeightMap[var6] = -999; + } + + int var7 = this.heightMap[var6]; + int var8 = this.getBlockID(par1, par2, par3); + int var9 = this.getBlockMetadata(par1, par2, par3); + + if (var8 == par4 && var9 == par5) { + return false; + } else { + ExtendedBlockStorage var10 = this.storageArrays[par2 >> 4]; + boolean var11 = false; + + if (var10 == null) { + if (par4 == 0) { + return false; + } + + var10 = this.storageArrays[par2 >> 4] = new ExtendedBlockStorage(par2 >> 4 << 4, + !this.worldObj.provider.hasNoSky); + var11 = par2 >= var7; + } + + int var12 = this.xPosition * 16 + par1; + int var13 = this.zPosition * 16 + par3; + + if (var8 != 0 && !this.worldObj.isRemote) { + Block.blocksList[var8].onSetBlockIDWithMetaData(this.worldObj, var12, par2, var13, var9); + } + + var10.setExtBlockID(par1, par2 & 15, par3, par4); + + if (var8 != 0) { + if (!this.worldObj.isRemote) { + Block.blocksList[var8].breakBlock(this.worldObj, var12, par2, var13, var8, var9); + } else if (Block.blocksList[var8] instanceof ITileEntityProvider && var8 != par4) { + this.worldObj.removeBlockTileEntity(var12, par2, var13); + } + } + + if (var10.getExtBlockID(par1, par2 & 15, par3) != par4) { + return false; + } else { + var10.setExtBlockMetadata(par1, par2 & 15, par3, par5); + + if (var11) { + this.generateSkylightMap(); + } else { + if (Block.lightOpacity[par4 & 4095] > 0) { + if (par2 >= var7) { + this.relightBlock(par1, par2 + 1, par3); + } + } else if (par2 == var7 - 1) { + this.relightBlock(par1, par2, par3); + } + + this.propagateSkylightOcclusion(par1, par3); + } + + TileEntity var14; + + if (par4 != 0) { + if (!this.worldObj.isRemote) { + Block.blocksList[par4].onBlockAdded(this.worldObj, var12, par2, var13); + } + + if (Block.blocksList[par4] instanceof ITileEntityProvider) { + var14 = this.getChunkBlockTileEntity(par1, par2, par3); + + if (var14 == null) { + var14 = ((ITileEntityProvider) Block.blocksList[par4]).createNewTileEntity(this.worldObj); + this.worldObj.setBlockTileEntity(var12, par2, var13, var14); + } + + if (var14 != null) { + var14.updateContainingBlockInfo(); + } + } + } else if (var8 > 0 && Block.blocksList[var8] instanceof ITileEntityProvider) { + var14 = this.getChunkBlockTileEntity(par1, par2, par3); + + if (var14 != null) { + var14.updateContainingBlockInfo(); + } + } + + this.isModified = true; + return true; + } + } + } + + /** + * Set the metadata of a block in the chunk + */ + public boolean setBlockMetadata(int par1, int par2, int par3, int par4) { + ExtendedBlockStorage var5 = this.storageArrays[par2 >> 4]; + + if (var5 == null) { + return false; + } else { + int var6 = var5.getExtBlockMetadata(par1, par2 & 15, par3); + + if (var6 == par4) { + return false; + } else { + this.isModified = true; + var5.setExtBlockMetadata(par1, par2 & 15, par3, par4); + int var7 = var5.getExtBlockID(par1, par2 & 15, par3); + + if (var7 > 0 && Block.blocksList[var7] instanceof ITileEntityProvider) { + TileEntity var8 = this.getChunkBlockTileEntity(par1, par2, par3); + + if (var8 != null) { + var8.updateContainingBlockInfo(); + var8.blockMetadata = par4; + } + } + + return true; + } + } + } + + /** + * Gets the amount of light saved in this block (doesn't adjust for daylight) + */ + public int getSavedLightValue(EnumSkyBlock par1EnumSkyBlock, int par2, int par3, int par4) { + ExtendedBlockStorage var5 = this.storageArrays[par3 >> 4]; + return var5 == null ? (this.canBlockSeeTheSky(par2, par3, par4) ? par1EnumSkyBlock.defaultLightValue : 0) + : (par1EnumSkyBlock == EnumSkyBlock.Sky + ? (this.worldObj.provider.hasNoSky ? 0 : var5.getExtSkylightValue(par2, par3 & 15, par4)) + : (par1EnumSkyBlock == EnumSkyBlock.Block ? var5.getExtBlocklightValue(par2, par3 & 15, par4) + : par1EnumSkyBlock.defaultLightValue)); + } + + /** + * Sets the light value at the coordinate. If enumskyblock is set to sky it sets + * it in the skylightmap and if its a block then into the blocklightmap. Args + * enumSkyBlock, x, y, z, lightValue + */ + public void setLightValue(EnumSkyBlock par1EnumSkyBlock, int par2, int par3, int par4, int par5) { + ExtendedBlockStorage var6 = this.storageArrays[par3 >> 4]; + + if (var6 == null) { + var6 = this.storageArrays[par3 >> 4] = new ExtendedBlockStorage(par3 >> 4 << 4, + !this.worldObj.provider.hasNoSky); + this.generateSkylightMap(); + } + + this.isModified = true; + + if (par1EnumSkyBlock == EnumSkyBlock.Sky) { + if (!this.worldObj.provider.hasNoSky) { + var6.setExtSkylightValue(par2, par3 & 15, par4, par5); + } + } else if (par1EnumSkyBlock == EnumSkyBlock.Block) { + var6.setExtBlocklightValue(par2, par3 & 15, par4, par5); + } + } + + /** + * Gets the amount of light on a block taking into account sunlight + */ + public int getBlockLightValue(int par1, int par2, int par3, int par4) { + ExtendedBlockStorage var5 = this.storageArrays[par2 >> 4]; + + if (var5 == null) { + return !this.worldObj.provider.hasNoSky && par4 < EnumSkyBlock.Sky.defaultLightValue + ? EnumSkyBlock.Sky.defaultLightValue - par4 + : 0; + } else { + int var6 = this.worldObj.provider.hasNoSky ? 0 : var5.getExtSkylightValue(par1, par2 & 15, par3); + + if (var6 > 0) { + isLit = true; + } + + var6 -= par4; + int var7 = var5.getExtBlocklightValue(par1, par2 & 15, par3); + + if (var7 > var6) { + var6 = var7; + } + + return var6; + } + } + + /** + * Adds an entity to the chunk. Args: entity + */ + public void addEntity(Entity par1Entity) { + this.hasEntities = true; + int var2 = MathHelper.floor_double(par1Entity.posX / 16.0D); + int var3 = MathHelper.floor_double(par1Entity.posZ / 16.0D); + + if (var2 != this.xPosition || var3 != this.zPosition) { + this.worldObj.getWorldLogAgent().logSevere("Wrong location! " + par1Entity); + Thread.dumpStack(); + } + + int var4 = MathHelper.floor_double(par1Entity.posY / 16.0D); + + if (var4 < 0) { + var4 = 0; + } + + if (var4 >= this.entityLists.length) { + var4 = this.entityLists.length - 1; + } + + par1Entity.addedToChunk = true; + par1Entity.chunkCoordX = this.xPosition; + par1Entity.chunkCoordY = var4; + par1Entity.chunkCoordZ = this.zPosition; + this.entityLists[var4].add(par1Entity); + } + + /** + * removes entity using its y chunk coordinate as its index + */ + public void removeEntity(Entity par1Entity) { + this.removeEntityAtIndex(par1Entity, par1Entity.chunkCoordY); + } + + /** + * Removes entity at the specified index from the entity array. + */ + public void removeEntityAtIndex(Entity par1Entity, int par2) { + if (par2 < 0) { + par2 = 0; + } + + if (par2 >= this.entityLists.length) { + par2 = this.entityLists.length - 1; + } + + this.entityLists[par2].remove(par1Entity); + } + + /** + * Returns whether is not a block above this one blocking sight to the sky (done + * via checking against the heightmap) + */ + public boolean canBlockSeeTheSky(int par1, int par2, int par3) { + return par2 >= this.heightMap[par3 << 4 | par1]; + } + + /** + * Gets the TileEntity for a given block in this chunk + */ + public TileEntity getChunkBlockTileEntity(int par1, int par2, int par3) { + ChunkPosition var4 = new ChunkPosition(par1, par2, par3); + TileEntity var5 = (TileEntity) this.chunkTileEntityMap.get(var4); + + if (var5 == null) { + int var6 = this.getBlockID(par1, par2, par3); + + if (var6 <= 0 || !Block.blocksList[var6].hasTileEntity()) { + return null; + } + + if (var5 == null) { + var5 = ((ITileEntityProvider) Block.blocksList[var6]).createNewTileEntity(this.worldObj); + this.worldObj.setBlockTileEntity(this.xPosition * 16 + par1, par2, this.zPosition * 16 + par3, var5); + } + + var5 = (TileEntity) this.chunkTileEntityMap.get(var4); + } + + if (var5 != null && var5.isInvalid()) { + this.chunkTileEntityMap.remove(var4); + return null; + } else { + return var5; + } + } + + /** + * Adds a TileEntity to a chunk + */ + public void addTileEntity(TileEntity par1TileEntity) { + int var2 = par1TileEntity.xCoord - this.xPosition * 16; + int var3 = par1TileEntity.yCoord; + int var4 = par1TileEntity.zCoord - this.zPosition * 16; + this.setChunkBlockTileEntity(var2, var3, var4, par1TileEntity); + + if (this.isChunkLoaded) { + this.worldObj.loadedTileEntityList.add(par1TileEntity); + } + } + + /** + * Sets the TileEntity for a given block in this chunk + */ + public void setChunkBlockTileEntity(int par1, int par2, int par3, TileEntity par4TileEntity) { + ChunkPosition var5 = new ChunkPosition(par1, par2, par3); + par4TileEntity.setWorldObj(this.worldObj); + par4TileEntity.xCoord = this.xPosition * 16 + par1; + par4TileEntity.yCoord = par2; + par4TileEntity.zCoord = this.zPosition * 16 + par3; + + if (this.getBlockID(par1, par2, par3) != 0 + && Block.blocksList[this.getBlockID(par1, par2, par3)] instanceof ITileEntityProvider) { + if (this.chunkTileEntityMap.containsKey(var5)) { + ((TileEntity) this.chunkTileEntityMap.get(var5)).invalidate(); + } + + par4TileEntity.validate(); + this.chunkTileEntityMap.put(var5, par4TileEntity); + } + } + + /** + * Removes the TileEntity for a given block in this chunk + */ + public void removeChunkBlockTileEntity(int par1, int par2, int par3) { + ChunkPosition var4 = new ChunkPosition(par1, par2, par3); + + if (this.isChunkLoaded) { + TileEntity var5 = (TileEntity) this.chunkTileEntityMap.remove(var4); + + if (var5 != null) { + var5.invalidate(); + } + } + } + + /** + * Called when this Chunk is loaded by the ChunkProvider + */ + public void onChunkLoad() { + this.isChunkLoaded = true; + this.worldObj.addTileEntity(this.chunkTileEntityMap.values()); + + for (int var1 = 0; var1 < this.entityLists.length; ++var1) { + this.worldObj.addLoadedEntities(this.entityLists[var1]); + } + } + + /** + * Called when this Chunk is unloaded by the ChunkProvider + */ + public void onChunkUnload() { + this.isChunkLoaded = false; + Iterator var1 = this.chunkTileEntityMap.values().iterator(); + + while (var1.hasNext()) { + TileEntity var2 = (TileEntity) var1.next(); + this.worldObj.markTileEntityForDespawn(var2); + } + + for (int var3 = 0; var3 < this.entityLists.length; ++var3) { + this.worldObj.unloadEntities(this.entityLists[var3]); + } + } + + /** + * Sets the isModified flag for this Chunk + */ + public void setChunkModified() { + this.isModified = true; + } + + /** + * Fills the given list of all entities that intersect within the given bounding + * box that aren't the passed entity Args: entity, aabb, listToFill + */ + public void getEntitiesWithinAABBForEntity(Entity par1Entity, AxisAlignedBB par2AxisAlignedBB, List par3List, + IEntitySelector par4IEntitySelector) { + int var5 = MathHelper.floor_double((par2AxisAlignedBB.minY - 2.0D) / 16.0D); + int var6 = MathHelper.floor_double((par2AxisAlignedBB.maxY + 2.0D) / 16.0D); + + if (var5 < 0) { + var5 = 0; + var6 = Math.max(var5, var6); + } + + if (var6 >= this.entityLists.length) { + var6 = this.entityLists.length - 1; + var5 = Math.min(var5, var6); + } + + for (int var7 = var5; var7 <= var6; ++var7) { + List var8 = this.entityLists[var7]; + + for (int var9 = 0; var9 < var8.size(); ++var9) { + Entity var10 = (Entity) var8.get(var9); + + if (var10 != par1Entity && var10.boundingBox.intersectsWith(par2AxisAlignedBB) + && (par4IEntitySelector == null || par4IEntitySelector.isEntityApplicable(var10))) { + par3List.add(var10); + Entity[] var11 = var10.getParts(); + + if (var11 != null) { + for (int var12 = 0; var12 < var11.length; ++var12) { + var10 = var11[var12]; + + if (var10 != par1Entity && var10.boundingBox.intersectsWith(par2AxisAlignedBB) + && (par4IEntitySelector == null || par4IEntitySelector.isEntityApplicable(var10))) { + par3List.add(var10); + } + } + } + } + } + } + } + + /** + * Gets all entities that can be assigned to the specified class. Args: + * entityClass, aabb, listToFill + */ + public void getEntitiesOfTypeWithinAAAB(Class par1Class, AxisAlignedBB par2AxisAlignedBB, List par3List, + IEntitySelector par4IEntitySelector) { + int var5 = MathHelper.floor_double((par2AxisAlignedBB.minY - 2.0D) / 16.0D); + int var6 = MathHelper.floor_double((par2AxisAlignedBB.maxY + 2.0D) / 16.0D); + + if (var5 < 0) { + var5 = 0; + } else if (var5 >= this.entityLists.length) { + var5 = this.entityLists.length - 1; + } + + if (var6 >= this.entityLists.length) { + var6 = this.entityLists.length - 1; + } else if (var6 < 0) { + var6 = 0; + } + + for (int var7 = var5; var7 <= var6; ++var7) { + List var8 = this.entityLists[var7]; + + for (int var9 = 0; var9 < var8.size(); ++var9) { + Entity var10 = (Entity) var8.get(var9); + + if (par1Class.isAssignableFrom(var10.getClass()) && var10.boundingBox.intersectsWith(par2AxisAlignedBB) + && (par4IEntitySelector == null || par4IEntitySelector.isEntityApplicable(var10))) { + par3List.add(var10); + } + } + } + } + + /** + * Returns true if this Chunk needs to be saved + */ + public boolean needsSaving(boolean par1) { + if (par1) { + if (this.hasEntities && this.worldObj.getTotalWorldTime() != this.lastSaveTime || this.isModified) { + return true; + } + } else if (this.hasEntities && this.worldObj.getTotalWorldTime() >= this.lastSaveTime + 600L) { + return true; + } + + return this.isModified; + } + + public Random getRandomWithSeed(long par1) { + return new Random(this.worldObj.getSeed() + (long) (this.xPosition * this.xPosition * 4987142) + + (long) (this.xPosition * 5947611) + (long) (this.zPosition * this.zPosition) * 4392871L + + (long) (this.zPosition * 389711) ^ par1); + } + + public boolean isEmpty() { + return false; + } + + public void populateChunk(IChunkProvider par1IChunkProvider, IChunkProvider par2IChunkProvider, int par3, + int par4) { + if (!this.isTerrainPopulated && par1IChunkProvider.chunkExists(par3 + 1, par4 + 1) + && par1IChunkProvider.chunkExists(par3, par4 + 1) && par1IChunkProvider.chunkExists(par3 + 1, par4)) { + par1IChunkProvider.populate(par2IChunkProvider, par3, par4); + } + + if (par1IChunkProvider.chunkExists(par3 - 1, par4) + && !par1IChunkProvider.provideChunk(par3 - 1, par4).isTerrainPopulated + && par1IChunkProvider.chunkExists(par3 - 1, par4 + 1) && par1IChunkProvider.chunkExists(par3, par4 + 1) + && par1IChunkProvider.chunkExists(par3 - 1, par4 + 1)) { + par1IChunkProvider.populate(par2IChunkProvider, par3 - 1, par4); + } + + if (par1IChunkProvider.chunkExists(par3, par4 - 1) + && !par1IChunkProvider.provideChunk(par3, par4 - 1).isTerrainPopulated + && par1IChunkProvider.chunkExists(par3 + 1, par4 - 1) + && par1IChunkProvider.chunkExists(par3 + 1, par4 - 1) + && par1IChunkProvider.chunkExists(par3 + 1, par4)) { + par1IChunkProvider.populate(par2IChunkProvider, par3, par4 - 1); + } + + if (par1IChunkProvider.chunkExists(par3 - 1, par4 - 1) + && !par1IChunkProvider.provideChunk(par3 - 1, par4 - 1).isTerrainPopulated + && par1IChunkProvider.chunkExists(par3, par4 - 1) && par1IChunkProvider.chunkExists(par3 - 1, par4)) { + par1IChunkProvider.populate(par2IChunkProvider, par3 - 1, par4 - 1); + } + } + + /** + * Gets the height to which rain/snow will fall. Calculates it if not already + * stored. + */ + public int getPrecipitationHeight(int par1, int par2) { + int var3 = par1 | par2 << 4; + int var4 = this.precipitationHeightMap[var3]; + + if (var4 == -999) { + int var5 = this.getTopFilledSegment() + 15; + var4 = -1; + + while (var5 > 0 && var4 == -1) { + int var6 = this.getBlockID(par1, var5, par2); + Material var7 = var6 == 0 ? Material.air : Block.blocksList[var6].blockMaterial; + + if (!var7.blocksMovement() && !var7.isLiquid()) { + --var5; + } else { + var4 = var5 + 1; + } + } + + this.precipitationHeightMap[var3] = var4; + } + + return var4; + } + + /** + * Checks whether skylight needs updated; if it does, calls updateSkylight_do + */ + public void updateSkylight() { + if (this.isGapLightingUpdated && !this.worldObj.provider.hasNoSky) { + this.updateSkylight_do(); + } + } + + /** + * Gets a ChunkCoordIntPair representing the Chunk's position. + */ + public ChunkCoordIntPair getChunkCoordIntPair() { + return new ChunkCoordIntPair(this.xPosition, this.zPosition); + } + + /** + * Returns whether the ExtendedBlockStorages containing levels (in blocks) from + * arg 1 to arg 2 are fully empty (true) or not (false). + */ + public boolean getAreLevelsEmpty(int par1, int par2) { + if (par1 < 0) { + par1 = 0; + } + + if (par2 >= 256) { + par2 = 255; + } + + for (int var3 = par1; var3 <= par2; var3 += 16) { + ExtendedBlockStorage var4 = this.storageArrays[var3 >> 4]; + + if (var4 != null && !var4.isEmpty()) { + return false; + } + } + + return true; + } + + public void setStorageArrays(ExtendedBlockStorage[] par1ArrayOfExtendedBlockStorage) { + this.storageArrays = par1ArrayOfExtendedBlockStorage; + } + + /** + * This method retrieves the biome at a set of coordinates + */ + public BiomeGenBase getBiomeGenForWorldCoords(int par1, int par2, WorldChunkManager par3WorldChunkManager) { + int var4 = this.blockBiomeArray[par2 << 4 | par1] & 255; + + if (var4 == 255) { + BiomeGenBase var5 = par3WorldChunkManager.getBiomeGenAt((this.xPosition << 4) + par1, + (this.zPosition << 4) + par2); + var4 = var5.biomeID; + this.blockBiomeArray[par2 << 4 | par1] = (byte) (var4 & 255); + } + + return BiomeGenBase.biomeList[var4] == null ? BiomeGenBase.plains : BiomeGenBase.biomeList[var4]; + } + + /** + * Returns an array containing a 16x16 mapping on the X/Z of block positions in + * this Chunk to biome IDs. + */ + public byte[] getBiomeArray() { + return this.blockBiomeArray; + } + + /** + * Accepts a 256-entry array that contains a 16x16 mapping on the X/Z plane of + * block positions in this Chunk to biome IDs. + */ + public void setBiomeArray(byte[] par1ArrayOfByte) { + this.blockBiomeArray = par1ArrayOfByte; + } + + /** + * Resets the relight check index to 0 for this Chunk. + */ + public void resetRelightChecks() { + this.queuedLightChecks = 0; + } + + /** + * Called once-per-chunk-per-tick, and advances the round-robin relight check + * index by up to 8 blocks at a time. In a worst-case scenario, can potentially + * take up to 25.6 seconds, calculated via (4096/8)/20, to re-check all blocks + * in a chunk, which may explain lagging light updates on initial world + * generation. + */ + public void enqueueRelightChecks() { + for (int var1 = 0; var1 < 8; ++var1) { + if (this.queuedLightChecks >= 4096) { + return; + } + + int var2 = this.queuedLightChecks % 16; + int var3 = this.queuedLightChecks / 16 % 16; + int var4 = this.queuedLightChecks / 256; + ++this.queuedLightChecks; + int var5 = (this.xPosition << 4) + var3; + int var6 = (this.zPosition << 4) + var4; + + for (int var7 = 0; var7 < 16; ++var7) { + int var8 = (var2 << 4) + var7; + + if (this.storageArrays[var2] == null + && (var7 == 0 || var7 == 15 || var3 == 0 || var3 == 15 || var4 == 0 || var4 == 15) + || this.storageArrays[var2] != null + && this.storageArrays[var2].getExtBlockID(var3, var7, var4) == 0) { + if (Block.lightValue[this.worldObj.getBlockId(var5, var8 - 1, var6)] > 0) { + this.worldObj.updateAllLightTypes(var5, var8 - 1, var6); + } + + if (Block.lightValue[this.worldObj.getBlockId(var5, var8 + 1, var6)] > 0) { + this.worldObj.updateAllLightTypes(var5, var8 + 1, var6); + } + + if (Block.lightValue[this.worldObj.getBlockId(var5 - 1, var8, var6)] > 0) { + this.worldObj.updateAllLightTypes(var5 - 1, var8, var6); + } + + if (Block.lightValue[this.worldObj.getBlockId(var5 + 1, var8, var6)] > 0) { + this.worldObj.updateAllLightTypes(var5 + 1, var8, var6); + } + + if (Block.lightValue[this.worldObj.getBlockId(var5, var8, var6 - 1)] > 0) { + this.worldObj.updateAllLightTypes(var5, var8, var6 - 1); + } + + if (Block.lightValue[this.worldObj.getBlockId(var5, var8, var6 + 1)] > 0) { + this.worldObj.updateAllLightTypes(var5, var8, var6 + 1); + } + + this.worldObj.updateAllLightTypes(var5, var8, var6); + } + } + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ChunkCache.java b/sp-server/src/main/java/net/minecraft/src/ChunkCache.java new file mode 100644 index 0000000..0cfe973 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ChunkCache.java @@ -0,0 +1,124 @@ +package net.minecraft.src; + +public class ChunkCache implements IBlockAccess { + private int chunkX; + private int chunkZ; + private Chunk[][] chunkArray; + + /** set by !chunk.getAreLevelsEmpty */ + private boolean hasExtendedLevels; + + /** Reference to the World object. */ + private World worldObj; + + public ChunkCache(World par1World, int par2, int par3, int par4, int par5, int par6, int par7, int par8) { + this.worldObj = par1World; + this.chunkX = par2 - par8 >> 4; + this.chunkZ = par4 - par8 >> 4; + int var9 = par5 + par8 >> 4; + int var10 = par7 + par8 >> 4; + this.chunkArray = new Chunk[var9 - this.chunkX + 1][var10 - this.chunkZ + 1]; + this.hasExtendedLevels = true; + int var11; + int var12; + Chunk var13; + + for (var11 = this.chunkX; var11 <= var9; ++var11) { + for (var12 = this.chunkZ; var12 <= var10; ++var12) { + var13 = par1World.getChunkFromChunkCoords(var11, var12); + + if (var13 != null) { + this.chunkArray[var11 - this.chunkX][var12 - this.chunkZ] = var13; + } + } + } + + for (var11 = par2 >> 4; var11 <= par5 >> 4; ++var11) { + for (var12 = par4 >> 4; var12 <= par7 >> 4; ++var12) { + var13 = this.chunkArray[var11 - this.chunkX][var12 - this.chunkZ]; + + if (var13 != null && !var13.getAreLevelsEmpty(par3, par6)) { + this.hasExtendedLevels = false; + } + } + } + } + + /** + * Returns the block ID at coords x,y,z + */ + public int getBlockId(int par1, int par2, int par3) { + if (par2 < 0) { + return 0; + } else if (par2 >= 256) { + return 0; + } else { + int var4 = (par1 >> 4) - this.chunkX; + int var5 = (par3 >> 4) - this.chunkZ; + + if (var4 >= 0 && var4 < this.chunkArray.length && var5 >= 0 && var5 < this.chunkArray[var4].length) { + Chunk var6 = this.chunkArray[var4][var5]; + return var6 == null ? 0 : var6.getBlockID(par1 & 15, par2, par3 & 15); + } else { + return 0; + } + } + } + + /** + * Returns the TileEntity associated with a given block in X,Y,Z coordinates, or + * null if no TileEntity exists + */ + public TileEntity getBlockTileEntity(int par1, int par2, int par3) { + int var4 = (par1 >> 4) - this.chunkX; + int var5 = (par3 >> 4) - this.chunkZ; + return this.chunkArray[var4][var5].getChunkBlockTileEntity(par1 & 15, par2, par3 & 15); + } + + /** + * Returns the block metadata at coords x,y,z + */ + public int getBlockMetadata(int par1, int par2, int par3) { + if (par2 < 0) { + return 0; + } else if (par2 >= 256) { + return 0; + } else { + int var4 = (par1 >> 4) - this.chunkX; + int var5 = (par3 >> 4) - this.chunkZ; + return this.chunkArray[var4][var5].getBlockMetadata(par1 & 15, par2, par3 & 15); + } + } + + /** + * Returns the block's material. + */ + public Material getBlockMaterial(int par1, int par2, int par3) { + int var4 = this.getBlockId(par1, par2, par3); + return var4 == 0 ? Material.air : Block.blocksList[var4].blockMaterial; + } + + /** + * Returns true if the block at the specified coordinates is an opaque cube. + * Args: x, y, z + */ + public boolean isBlockNormalCube(int par1, int par2, int par3) { + Block var4 = Block.blocksList[this.getBlockId(par1, par2, par3)]; + return var4 == null ? false : var4.blockMaterial.blocksMovement() && var4.renderAsNormalBlock(); + } + + /** + * Return the Vec3Pool object for this world. + */ + public Vec3Pool getWorldVec3Pool() { + return this.worldObj.getWorldVec3Pool(); + } + + /** + * Is this block powering in the specified direction Args: x, y, z, direction + */ + public int isBlockProvidingPowerTo(int par1, int par2, int par3, int par4) { + int var5 = this.getBlockId(par1, par2, par3); + return var5 == 0 ? 0 : Block.blocksList[var5].isProvidingStrongPower(this, par1, par2, par3, par4); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ChunkCoordIntPair.java b/sp-server/src/main/java/net/minecraft/src/ChunkCoordIntPair.java new file mode 100644 index 0000000..1efaa0e --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ChunkCoordIntPair.java @@ -0,0 +1,49 @@ +package net.minecraft.src; + +public class ChunkCoordIntPair { + /** The X position of this Chunk Coordinate Pair */ + public final int chunkXPos; + + /** The Z position of this Chunk Coordinate Pair */ + public final int chunkZPos; + + public ChunkCoordIntPair(int par1, int par2) { + this.chunkXPos = par1; + this.chunkZPos = par2; + } + + /** + * converts a chunk coordinate pair to an integer (suitable for hashing) + */ + public static long chunkXZ2Int(int par0, int par1) { + return (long) par0 & 4294967295L | ((long) par1 & 4294967295L) << 32; + } + + public int hashCode() { + long var1 = chunkXZ2Int(this.chunkXPos, this.chunkZPos); + int var3 = (int) var1; + int var4 = (int) (var1 >> 32); + return var3 ^ var4; + } + + public boolean equals(Object par1Obj) { + ChunkCoordIntPair var2 = (ChunkCoordIntPair) par1Obj; + return var2.chunkXPos == this.chunkXPos && var2.chunkZPos == this.chunkZPos; + } + + public int getCenterXPos() { + return (this.chunkXPos << 4) + 8; + } + + public int getCenterZPosition() { + return (this.chunkZPos << 4) + 8; + } + + public ChunkPosition getChunkPosition(int par1) { + return new ChunkPosition(this.getCenterXPos(), par1, this.getCenterZPosition()); + } + + public String toString() { + return "[" + this.chunkXPos + ", " + this.chunkZPos + "]"; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ChunkCoordinates.java b/sp-server/src/main/java/net/minecraft/src/ChunkCoordinates.java new file mode 100644 index 0000000..3eaf8e7 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ChunkCoordinates.java @@ -0,0 +1,78 @@ +package net.minecraft.src; + +public class ChunkCoordinates implements Comparable { + public int posX; + + /** the y coordinate */ + public int posY; + + /** the z coordinate */ + public int posZ; + + public ChunkCoordinates() { + } + + public ChunkCoordinates(int par1, int par2, int par3) { + this.posX = par1; + this.posY = par2; + this.posZ = par3; + } + + public ChunkCoordinates(ChunkCoordinates par1ChunkCoordinates) { + this.posX = par1ChunkCoordinates.posX; + this.posY = par1ChunkCoordinates.posY; + this.posZ = par1ChunkCoordinates.posZ; + } + + public boolean equals(Object par1Obj) { + if (!(par1Obj instanceof ChunkCoordinates)) { + return false; + } else { + ChunkCoordinates var2 = (ChunkCoordinates) par1Obj; + return this.posX == var2.posX && this.posY == var2.posY && this.posZ == var2.posZ; + } + } + + public int hashCode() { + return this.posX + this.posZ << 8 + this.posY << 16; + } + + /** + * Compare the coordinate with another coordinate + */ + public int compareChunkCoordinate(ChunkCoordinates par1ChunkCoordinates) { + return this.posY == par1ChunkCoordinates.posY + ? (this.posZ == par1ChunkCoordinates.posZ ? this.posX - par1ChunkCoordinates.posX + : this.posZ - par1ChunkCoordinates.posZ) + : this.posY - par1ChunkCoordinates.posY; + } + + public void set(int par1, int par2, int par3) { + this.posX = par1; + this.posY = par2; + this.posZ = par3; + } + + /** + * Returns the squared distance between this coordinates and the coordinates + * given as argument. + */ + public float getDistanceSquared(int par1, int par2, int par3) { + int var4 = this.posX - par1; + int var5 = this.posY - par2; + int var6 = this.posZ - par3; + return (float) (var4 * var4 + var5 * var5 + var6 * var6); + } + + /** + * Return the squared distance between this coordinates and the ChunkCoordinates + * given as argument. + */ + public float getDistanceSquaredToChunkCoordinates(ChunkCoordinates par1ChunkCoordinates) { + return this.getDistanceSquared(par1ChunkCoordinates.posX, par1ChunkCoordinates.posY, par1ChunkCoordinates.posZ); + } + + public int compareTo(Object par1Obj) { + return this.compareChunkCoordinate((ChunkCoordinates) par1Obj); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ChunkLoader.java b/sp-server/src/main/java/net/minecraft/src/ChunkLoader.java new file mode 100644 index 0000000..e9b2209 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ChunkLoader.java @@ -0,0 +1,122 @@ +package net.minecraft.src; + +public class ChunkLoader { + public static AnvilConverterData load(NBTTagCompound par0NBTTagCompound) { + int var1 = par0NBTTagCompound.getInteger("xPos"); + int var2 = par0NBTTagCompound.getInteger("zPos"); + AnvilConverterData var3 = new AnvilConverterData(var1, var2); + var3.blocks = par0NBTTagCompound.getByteArray("Blocks"); + var3.data = new NibbleArrayReader(par0NBTTagCompound.getByteArray("Data"), 7); + var3.skyLight = new NibbleArrayReader(par0NBTTagCompound.getByteArray("SkyLight"), 7); + var3.blockLight = new NibbleArrayReader(par0NBTTagCompound.getByteArray("BlockLight"), 7); + var3.heightmap = par0NBTTagCompound.getByteArray("HeightMap"); + var3.terrainPopulated = par0NBTTagCompound.getBoolean("TerrainPopulated"); + var3.entities = par0NBTTagCompound.getTagList("Entities"); + var3.tileEntities = par0NBTTagCompound.getTagList("TileEntities"); + var3.tileTicks = par0NBTTagCompound.getTagList("TileTicks"); + + try { + var3.lastUpdated = par0NBTTagCompound.getLong("LastUpdate"); + } catch (ClassCastException var5) { + var3.lastUpdated = (long) par0NBTTagCompound.getInteger("LastUpdate"); + } + + return var3; + } + + public static void convertToAnvilFormat(AnvilConverterData par0AnvilConverterData, + NBTTagCompound par1NBTTagCompound, WorldChunkManager par2WorldChunkManager) { + par1NBTTagCompound.setInteger("xPos", par0AnvilConverterData.x); + par1NBTTagCompound.setInteger("zPos", par0AnvilConverterData.z); + par1NBTTagCompound.setLong("LastUpdate", par0AnvilConverterData.lastUpdated); + int[] var3 = new int[par0AnvilConverterData.heightmap.length]; + + for (int var4 = 0; var4 < par0AnvilConverterData.heightmap.length; ++var4) { + var3[var4] = par0AnvilConverterData.heightmap[var4]; + } + + par1NBTTagCompound.setIntArray("HeightMap", var3); + par1NBTTagCompound.setBoolean("TerrainPopulated", par0AnvilConverterData.terrainPopulated); + NBTTagList var16 = new NBTTagList("Sections"); + int var7; + + for (int var5 = 0; var5 < 8; ++var5) { + boolean var6 = true; + + for (var7 = 0; var7 < 16 && var6; ++var7) { + int var8 = 0; + + while (var8 < 16 && var6) { + int var9 = 0; + + while (true) { + if (var9 < 16) { + int var10 = var7 << 11 | var9 << 7 | var8 + (var5 << 4); + byte var11 = par0AnvilConverterData.blocks[var10]; + + if (var11 == 0) { + ++var9; + continue; + } + + var6 = false; + } + + ++var8; + break; + } + } + } + + if (!var6) { + byte[] var19 = new byte[4096]; + NibbleArray var20 = new NibbleArray(var19.length, 4); + NibbleArray var21 = new NibbleArray(var19.length, 4); + NibbleArray var22 = new NibbleArray(var19.length, 4); + + for (int var23 = 0; var23 < 16; ++var23) { + for (int var12 = 0; var12 < 16; ++var12) { + for (int var13 = 0; var13 < 16; ++var13) { + int var14 = var23 << 11 | var13 << 7 | var12 + (var5 << 4); + byte var15 = par0AnvilConverterData.blocks[var14]; + var19[var12 << 8 | var13 << 4 | var23] = (byte) (var15 & 255); + var20.set(var23, var12, var13, + par0AnvilConverterData.data.get(var23, var12 + (var5 << 4), var13)); + var21.set(var23, var12, var13, + par0AnvilConverterData.skyLight.get(var23, var12 + (var5 << 4), var13)); + var22.set(var23, var12, var13, + par0AnvilConverterData.blockLight.get(var23, var12 + (var5 << 4), var13)); + } + } + } + + NBTTagCompound var24 = new NBTTagCompound(); + var24.setByte("Y", (byte) (var5 & 255)); + var24.setByteArray("Blocks", var19); + var24.setByteArray("Data", var20.data); + var24.setByteArray("SkyLight", var21.data); + var24.setByteArray("BlockLight", var22.data); + var16.appendTag(var24); + } + } + + par1NBTTagCompound.setTag("Sections", var16); + byte[] var17 = new byte[256]; + + for (int var18 = 0; var18 < 16; ++var18) { + for (var7 = 0; var7 < 16; ++var7) { + var17[var7 << 4 + | var18] = (byte) (par2WorldChunkManager.getBiomeGenAt(par0AnvilConverterData.x << 4 | var18, + par0AnvilConverterData.z << 4 | var7).biomeID & 255); + } + } + + par1NBTTagCompound.setByteArray("Biomes", var17); + par1NBTTagCompound.setTag("Entities", par0AnvilConverterData.entities); + par1NBTTagCompound.setTag("TileEntities", par0AnvilConverterData.tileEntities); + + if (par0AnvilConverterData.tileTicks != null) { + par1NBTTagCompound.setTag("TileTicks", par0AnvilConverterData.tileTicks); + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ChunkPosition.java b/sp-server/src/main/java/net/minecraft/src/ChunkPosition.java new file mode 100644 index 0000000..8ac7d4d --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ChunkPosition.java @@ -0,0 +1,36 @@ +package net.minecraft.src; + +public class ChunkPosition { + /** The x coordinate of this ChunkPosition */ + public final int x; + + /** The y coordinate of this ChunkPosition */ + public final int y; + + /** The z coordinate of this ChunkPosition */ + public final int z; + + public ChunkPosition(int par1, int par2, int par3) { + this.x = par1; + this.y = par2; + this.z = par3; + } + + public ChunkPosition(Vec3 par1Vec3) { + this(MathHelper.floor_double(par1Vec3.xCoord), MathHelper.floor_double(par1Vec3.yCoord), + MathHelper.floor_double(par1Vec3.zCoord)); + } + + public boolean equals(Object par1Obj) { + if (!(par1Obj instanceof ChunkPosition)) { + return false; + } else { + ChunkPosition var2 = (ChunkPosition) par1Obj; + return var2.x == this.x && var2.y == this.y && var2.z == this.z; + } + } + + public int hashCode() { + return this.x * 8976890 + this.y * 981131 + this.z; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ChunkProviderEnd.java b/sp-server/src/main/java/net/minecraft/src/ChunkProviderEnd.java new file mode 100644 index 0000000..a558712 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ChunkProviderEnd.java @@ -0,0 +1,363 @@ +package net.minecraft.src; + +import java.util.List; +import java.util.Random; + +public class ChunkProviderEnd implements IChunkProvider { + private Random endRNG; + private NoiseGeneratorOctaves noiseGen1; + private NoiseGeneratorOctaves noiseGen2; + private NoiseGeneratorOctaves noiseGen3; + public NoiseGeneratorOctaves noiseGen4; + public NoiseGeneratorOctaves noiseGen5; + private World endWorld; + private double[] densities; + + /** The biomes that are used to generate the chunk */ + private BiomeGenBase[] biomesForGeneration; + double[] noiseData1; + double[] noiseData2; + double[] noiseData3; + double[] noiseData4; + double[] noiseData5; + int[][] field_73203_h = new int[32][32]; + + public ChunkProviderEnd(World par1World, long par2) { + this.endWorld = par1World; + this.endRNG = new Random(par2); + this.noiseGen1 = new NoiseGeneratorOctaves(this.endRNG, 16); + this.noiseGen2 = new NoiseGeneratorOctaves(this.endRNG, 16); + this.noiseGen3 = new NoiseGeneratorOctaves(this.endRNG, 8); + this.noiseGen4 = new NoiseGeneratorOctaves(this.endRNG, 10); + this.noiseGen5 = new NoiseGeneratorOctaves(this.endRNG, 16); + } + + public void generateTerrain(int par1, int par2, byte[] par3ArrayOfByte, BiomeGenBase[] par4ArrayOfBiomeGenBase) { + byte var5 = 2; + int var6 = var5 + 1; + byte var7 = 33; + int var8 = var5 + 1; + this.densities = this.initializeNoiseField(this.densities, par1 * var5, 0, par2 * var5, var6, var7, var8); + + for (int var9 = 0; var9 < var5; ++var9) { + for (int var10 = 0; var10 < var5; ++var10) { + for (int var11 = 0; var11 < 32; ++var11) { + double var12 = 0.25D; + double var14 = this.densities[((var9 + 0) * var8 + var10 + 0) * var7 + var11 + 0]; + double var16 = this.densities[((var9 + 0) * var8 + var10 + 1) * var7 + var11 + 0]; + double var18 = this.densities[((var9 + 1) * var8 + var10 + 0) * var7 + var11 + 0]; + double var20 = this.densities[((var9 + 1) * var8 + var10 + 1) * var7 + var11 + 0]; + double var22 = (this.densities[((var9 + 0) * var8 + var10 + 0) * var7 + var11 + 1] - var14) * var12; + double var24 = (this.densities[((var9 + 0) * var8 + var10 + 1) * var7 + var11 + 1] - var16) * var12; + double var26 = (this.densities[((var9 + 1) * var8 + var10 + 0) * var7 + var11 + 1] - var18) * var12; + double var28 = (this.densities[((var9 + 1) * var8 + var10 + 1) * var7 + var11 + 1] - var20) * var12; + + for (int var30 = 0; var30 < 4; ++var30) { + double var31 = 0.125D; + double var33 = var14; + double var35 = var16; + double var37 = (var18 - var14) * var31; + double var39 = (var20 - var16) * var31; + + for (int var41 = 0; var41 < 8; ++var41) { + int var42 = var41 + var9 * 8 << 11 | 0 + var10 * 8 << 7 | var11 * 4 + var30; + short var43 = 128; + double var44 = 0.125D; + double var46 = var33; + double var48 = (var35 - var33) * var44; + + for (int var50 = 0; var50 < 8; ++var50) { + int var51 = 0; + + if (var46 > 0.0D) { + var51 = Block.whiteStone.blockID; + } + + par3ArrayOfByte[var42] = (byte) var51; + var42 += var43; + var46 += var48; + } + + var33 += var37; + var35 += var39; + } + + var14 += var22; + var16 += var24; + var18 += var26; + var20 += var28; + } + } + } + } + } + + public void replaceBlocksForBiome(int par1, int par2, byte[] par3ArrayOfByte, + BiomeGenBase[] par4ArrayOfBiomeGenBase) { + for (int var5 = 0; var5 < 16; ++var5) { + for (int var6 = 0; var6 < 16; ++var6) { + byte var7 = 1; + int var8 = -1; + byte var9 = (byte) Block.whiteStone.blockID; + byte var10 = (byte) Block.whiteStone.blockID; + + for (int var11 = 127; var11 >= 0; --var11) { + int var12 = (var6 * 16 + var5) * 128 + var11; + byte var13 = par3ArrayOfByte[var12]; + + if (var13 == 0) { + var8 = -1; + } else if (var13 == Block.stone.blockID) { + if (var8 == -1) { + if (var7 <= 0) { + var9 = 0; + var10 = (byte) Block.whiteStone.blockID; + } + + var8 = var7; + + if (var11 >= 0) { + par3ArrayOfByte[var12] = var9; + } else { + par3ArrayOfByte[var12] = var10; + } + } else if (var8 > 0) { + --var8; + par3ArrayOfByte[var12] = var10; + } + } + } + } + } + } + + /** + * loads or generates the chunk at the chunk location specified + */ + public Chunk loadChunk(int par1, int par2) { + return this.provideChunk(par1, par2); + } + + /** + * Will return back a chunk, if it doesn't exist and its not a MP client it will + * generates all the blocks for the specified chunk from the map seed and chunk + * seed + */ + public Chunk provideChunk(int par1, int par2) { + this.endRNG.setSeed((long) par1 * 341873128712L + (long) par2 * 132897987541L); + byte[] var3 = new byte[32768]; + this.biomesForGeneration = this.endWorld.getWorldChunkManager().loadBlockGeneratorData(this.biomesForGeneration, + par1 * 16, par2 * 16, 16, 16); + this.generateTerrain(par1, par2, var3, this.biomesForGeneration); + this.replaceBlocksForBiome(par1, par2, var3, this.biomesForGeneration); + Chunk var4 = new Chunk(this.endWorld, var3, par1, par2); + byte[] var5 = var4.getBiomeArray(); + + for (int var6 = 0; var6 < var5.length; ++var6) { + var5[var6] = (byte) this.biomesForGeneration[var6].biomeID; + } + + var4.generateSkylightMap(); + return var4; + } + + /** + * generates a subset of the level's terrain data. Takes 7 arguments: the + * [empty] noise array, the position, and the size. + */ + private double[] initializeNoiseField(double[] par1ArrayOfDouble, int par2, int par3, int par4, int par5, int par6, + int par7) { + if (par1ArrayOfDouble == null) { + par1ArrayOfDouble = new double[par5 * par6 * par7]; + } + + double var8 = 684.412D; + double var10 = 684.412D; + this.noiseData4 = this.noiseGen4.generateNoiseOctaves(this.noiseData4, par2, par4, par5, par7, 1.121D, 1.121D, + 0.5D); + this.noiseData5 = this.noiseGen5.generateNoiseOctaves(this.noiseData5, par2, par4, par5, par7, 200.0D, 200.0D, + 0.5D); + var8 *= 2.0D; + this.noiseData1 = this.noiseGen3.generateNoiseOctaves(this.noiseData1, par2, par3, par4, par5, par6, par7, + var8 / 80.0D, var10 / 160.0D, var8 / 80.0D); + this.noiseData2 = this.noiseGen1.generateNoiseOctaves(this.noiseData2, par2, par3, par4, par5, par6, par7, var8, + var10, var8); + this.noiseData3 = this.noiseGen2.generateNoiseOctaves(this.noiseData3, par2, par3, par4, par5, par6, par7, var8, + var10, var8); + int var12 = 0; + int var13 = 0; + + for (int var14 = 0; var14 < par5; ++var14) { + for (int var15 = 0; var15 < par7; ++var15) { + double var16 = (this.noiseData4[var13] + 256.0D) / 512.0D; + + if (var16 > 1.0D) { + var16 = 1.0D; + } + + double var18 = this.noiseData5[var13] / 8000.0D; + + if (var18 < 0.0D) { + var18 = -var18 * 0.3D; + } + + var18 = var18 * 3.0D - 2.0D; + float var20 = (float) (var14 + par2 - 0) / 1.0F; + float var21 = (float) (var15 + par4 - 0) / 1.0F; + float var22 = 100.0F - MathHelper.sqrt_float(var20 * var20 + var21 * var21) * 8.0F; + + if (var22 > 80.0F) { + var22 = 80.0F; + } + + if (var22 < -100.0F) { + var22 = -100.0F; + } + + if (var18 > 1.0D) { + var18 = 1.0D; + } + + var18 /= 8.0D; + var18 = 0.0D; + + if (var16 < 0.0D) { + var16 = 0.0D; + } + + var16 += 0.5D; + var18 = var18 * (double) par6 / 16.0D; + ++var13; + double var23 = (double) par6 / 2.0D; + + for (int var25 = 0; var25 < par6; ++var25) { + double var26 = 0.0D; + double var28 = ((double) var25 - var23) * 8.0D / var16; + + if (var28 < 0.0D) { + var28 *= -1.0D; + } + + double var30 = this.noiseData2[var12] / 512.0D; + double var32 = this.noiseData3[var12] / 512.0D; + double var34 = (this.noiseData1[var12] / 10.0D + 1.0D) / 2.0D; + + if (var34 < 0.0D) { + var26 = var30; + } else if (var34 > 1.0D) { + var26 = var32; + } else { + var26 = var30 + (var32 - var30) * var34; + } + + var26 -= 8.0D; + var26 += (double) var22; + byte var36 = 2; + double var37; + + if (var25 > par6 / 2 - var36) { + var37 = (double) ((float) (var25 - (par6 / 2 - var36)) / 64.0F); + + if (var37 < 0.0D) { + var37 = 0.0D; + } + + if (var37 > 1.0D) { + var37 = 1.0D; + } + + var26 = var26 * (1.0D - var37) + -3000.0D * var37; + } + + var36 = 8; + + if (var25 < var36) { + var37 = (double) ((float) (var36 - var25) / ((float) var36 - 1.0F)); + var26 = var26 * (1.0D - var37) + -30.0D * var37; + } + + par1ArrayOfDouble[var12] = var26; + ++var12; + } + } + } + + return par1ArrayOfDouble; + } + + /** + * Checks to see if a chunk exists at x, y + */ + public boolean chunkExists(int par1, int par2) { + return true; + } + + /** + * Populates chunk with ores etc etc + */ + public void populate(IChunkProvider par1IChunkProvider, int par2, int par3) { + BlockSand.fallInstantly = true; + int var4 = par2 * 16; + int var5 = par3 * 16; + BiomeGenBase var6 = this.endWorld.getBiomeGenForCoords(var4 + 16, var5 + 16); + var6.decorate(this.endWorld, this.endWorld.rand, var4, var5); + BlockSand.fallInstantly = false; + } + + /** + * Two modes of operation: if passed true, save all Chunks in one go. If passed + * false, save up to two chunks. Return true if all chunks have been saved. + */ + public boolean saveChunks(boolean par1, IProgressUpdate par2IProgressUpdate) { + return true; + } + + public void func_104112_b() { + } + + /** + * Unloads chunks that are marked to be unloaded. This is not guaranteed to + * unload every such chunk. + */ + public boolean unloadQueuedChunks() { + return false; + } + + /** + * Returns if the IChunkProvider supports saving. + */ + public boolean canSave() { + return true; + } + + /** + * Converts the instance data to a readable string. + */ + public String makeString() { + return "RandomLevelSource"; + } + + /** + * Returns a list of creatures of the specified type that can spawn at the given + * location. + */ + public List getPossibleCreatures(EnumCreatureType par1EnumCreatureType, int par2, int par3, int par4) { + BiomeGenBase var5 = this.endWorld.getBiomeGenForCoords(par2, par4); + return var5 == null ? null : var5.getSpawnableList(par1EnumCreatureType); + } + + /** + * Returns the location of the closest structure of the specified type. If not + * found returns null. + */ + public ChunkPosition findClosestStructure(World par1World, String par2Str, int par3, int par4, int par5) { + return null; + } + + public int getLoadedChunkCount() { + return 0; + } + + public void recreateStructures(int par1, int par2) { + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ChunkProviderFlat.java b/sp-server/src/main/java/net/minecraft/src/ChunkProviderFlat.java new file mode 100644 index 0000000..bb38772 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ChunkProviderFlat.java @@ -0,0 +1,266 @@ +package net.minecraft.src; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Random; + +public class ChunkProviderFlat implements IChunkProvider { + private World worldObj; + private Random random; + private final byte[] field_82700_c = new byte[256]; + private final byte[] field_82698_d = new byte[256]; + private final FlatGeneratorInfo field_82699_e; + private final List structureGenerators = new ArrayList(); + private final boolean field_82697_g; + private final boolean field_82702_h; + private WorldGenLakes waterLakeGenerator; + private WorldGenLakes lavaLakeGenerator; + + public ChunkProviderFlat(World par1World, long par2, boolean par4, String par5Str) { + this.worldObj = par1World; + this.random = new Random(par2); + this.field_82699_e = FlatGeneratorInfo.createFlatGeneratorFromString(par5Str); + + if (par4) { + Map var6 = this.field_82699_e.getWorldFeatures(); + + if (var6.containsKey("village")) { + Map var7 = (Map) var6.get("village"); + + if (!var7.containsKey("size")) { + var7.put("size", "1"); + } + + this.structureGenerators.add(new MapGenVillage(var7)); + } + + if (var6.containsKey("biome_1")) { + this.structureGenerators.add(new MapGenScatteredFeature((Map) var6.get("biome_1"))); + } + + if (var6.containsKey("mineshaft")) { + this.structureGenerators.add(new MapGenMineshaft((Map) var6.get("mineshaft"))); + } + + if (var6.containsKey("stronghold")) { + this.structureGenerators.add(new MapGenStronghold((Map) var6.get("stronghold"))); + } + } + + this.field_82697_g = this.field_82699_e.getWorldFeatures().containsKey("decoration"); + + if (this.field_82699_e.getWorldFeatures().containsKey("lake")) { + this.waterLakeGenerator = new WorldGenLakes(Block.waterStill.blockID); + } + + if (this.field_82699_e.getWorldFeatures().containsKey("lava_lake")) { + this.lavaLakeGenerator = new WorldGenLakes(Block.lavaStill.blockID); + } + + this.field_82702_h = this.field_82699_e.getWorldFeatures().containsKey("dungeon"); + Iterator var9 = this.field_82699_e.getFlatLayers().iterator(); + + while (var9.hasNext()) { + FlatLayerInfo var10 = (FlatLayerInfo) var9.next(); + + for (int var8 = var10.getMinY(); var8 < var10.getMinY() + var10.getLayerCount(); ++var8) { + this.field_82700_c[var8] = (byte) (var10.getFillBlock() & 255); + this.field_82698_d[var8] = (byte) var10.getFillBlockMeta(); + } + } + } + + /** + * loads or generates the chunk at the chunk location specified + */ + public Chunk loadChunk(int par1, int par2) { + return this.provideChunk(par1, par2); + } + + /** + * Will return back a chunk, if it doesn't exist and its not a MP client it will + * generates all the blocks for the specified chunk from the map seed and chunk + * seed + */ + public Chunk provideChunk(int par1, int par2) { + Chunk var3 = new Chunk(this.worldObj, par1, par2); + + for (int var4 = 0; var4 < this.field_82700_c.length; ++var4) { + int var5 = var4 >> 4; + ExtendedBlockStorage var6 = var3.getBlockStorageArray()[var5]; + + if (var6 == null) { + var6 = new ExtendedBlockStorage(var4, !this.worldObj.provider.hasNoSky); + var3.getBlockStorageArray()[var5] = var6; + } + + for (int var7 = 0; var7 < 16; ++var7) { + for (int var8 = 0; var8 < 16; ++var8) { + var6.setExtBlockID(var7, var4 & 15, var8, this.field_82700_c[var4] & 255); + var6.setExtBlockMetadata(var7, var4 & 15, var8, this.field_82698_d[var4]); + } + } + } + + var3.generateSkylightMap(); + BiomeGenBase[] var9 = this.worldObj.getWorldChunkManager().loadBlockGeneratorData((BiomeGenBase[]) null, + par1 * 16, par2 * 16, 16, 16); + byte[] var10 = var3.getBiomeArray(); + + for (int var11 = 0; var11 < var10.length; ++var11) { + var10[var11] = (byte) var9[var11].biomeID; + } + + Iterator var12 = this.structureGenerators.iterator(); + + while (var12.hasNext()) { + MapGenStructure var13 = (MapGenStructure) var12.next(); + var13.generate(this, this.worldObj, par1, par2, (byte[]) null); + } + + var3.generateSkylightMap(); + return var3; + } + + /** + * Checks to see if a chunk exists at x, y + */ + public boolean chunkExists(int par1, int par2) { + return true; + } + + /** + * Populates chunk with ores etc etc + */ + public void populate(IChunkProvider par1IChunkProvider, int par2, int par3) { + int var4 = par2 * 16; + int var5 = par3 * 16; + BiomeGenBase var6 = this.worldObj.getBiomeGenForCoords(var4 + 16, var5 + 16); + boolean var7 = false; + this.random.setSeed(this.worldObj.getSeed()); + long var8 = this.random.nextLong() / 2L * 2L + 1L; + long var10 = this.random.nextLong() / 2L * 2L + 1L; + this.random.setSeed((long) par2 * var8 + (long) par3 * var10 ^ this.worldObj.getSeed()); + Iterator var12 = this.structureGenerators.iterator(); + + while (var12.hasNext()) { + MapGenStructure var13 = (MapGenStructure) var12.next(); + boolean var14 = var13.generateStructuresInChunk(this.worldObj, this.random, par2, par3); + + if (var13 instanceof MapGenVillage) { + var7 |= var14; + } + } + + int var16; + int var17; + int var18; + + if (this.waterLakeGenerator != null && !var7 && this.random.nextInt(4) == 0) { + var16 = var4 + this.random.nextInt(16) + 8; + var17 = this.random.nextInt(128); + var18 = var5 + this.random.nextInt(16) + 8; + this.waterLakeGenerator.generate(this.worldObj, this.random, var16, var17, var18); + } + + if (this.lavaLakeGenerator != null && !var7 && this.random.nextInt(8) == 0) { + var16 = var4 + this.random.nextInt(16) + 8; + var17 = this.random.nextInt(this.random.nextInt(120) + 8); + var18 = var5 + this.random.nextInt(16) + 8; + + if (var17 < 63 || this.random.nextInt(10) == 0) { + this.lavaLakeGenerator.generate(this.worldObj, this.random, var16, var17, var18); + } + } + + if (this.field_82702_h) { + for (var16 = 0; var16 < 8; ++var16) { + var17 = var4 + this.random.nextInt(16) + 8; + var18 = this.random.nextInt(128); + int var15 = var5 + this.random.nextInt(16) + 8; + (new WorldGenDungeons()).generate(this.worldObj, this.random, var17, var18, var15); + } + } + + if (this.field_82697_g) { + var6.decorate(this.worldObj, this.random, var4, var5); + } + } + + /** + * Two modes of operation: if passed true, save all Chunks in one go. If passed + * false, save up to two chunks. Return true if all chunks have been saved. + */ + public boolean saveChunks(boolean par1, IProgressUpdate par2IProgressUpdate) { + return true; + } + + public void func_104112_b() { + } + + /** + * Unloads chunks that are marked to be unloaded. This is not guaranteed to + * unload every such chunk. + */ + public boolean unloadQueuedChunks() { + return false; + } + + /** + * Returns if the IChunkProvider supports saving. + */ + public boolean canSave() { + return true; + } + + /** + * Converts the instance data to a readable string. + */ + public String makeString() { + return "FlatLevelSource"; + } + + /** + * Returns a list of creatures of the specified type that can spawn at the given + * location. + */ + public List getPossibleCreatures(EnumCreatureType par1EnumCreatureType, int par2, int par3, int par4) { + BiomeGenBase var5 = this.worldObj.getBiomeGenForCoords(par2, par4); + return var5 == null ? null : var5.getSpawnableList(par1EnumCreatureType); + } + + /** + * Returns the location of the closest structure of the specified type. If not + * found returns null. + */ + public ChunkPosition findClosestStructure(World par1World, String par2Str, int par3, int par4, int par5) { + if ("Stronghold".equals(par2Str)) { + Iterator var6 = this.structureGenerators.iterator(); + + while (var6.hasNext()) { + MapGenStructure var7 = (MapGenStructure) var6.next(); + + if (var7 instanceof MapGenStronghold) { + return var7.getNearestInstance(par1World, par3, par4, par5); + } + } + } + + return null; + } + + public int getLoadedChunkCount() { + return 0; + } + + public void recreateStructures(int par1, int par2) { + Iterator var3 = this.structureGenerators.iterator(); + + while (var3.hasNext()) { + MapGenStructure var4 = (MapGenStructure) var3.next(); + var4.generate(this, this.worldObj, par1, par2, (byte[]) null); + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ChunkProviderGenerate.java b/sp-server/src/main/java/net/minecraft/src/ChunkProviderGenerate.java new file mode 100644 index 0000000..82a443f --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ChunkProviderGenerate.java @@ -0,0 +1,552 @@ +package net.minecraft.src; + +import java.util.List; +import java.util.Random; + +public class ChunkProviderGenerate implements IChunkProvider { + /** RNG. */ + private Random rand; + + /** A NoiseGeneratorOctaves used in generating terrain */ + private NoiseGeneratorOctaves noiseGen1; + + /** A NoiseGeneratorOctaves used in generating terrain */ + private NoiseGeneratorOctaves noiseGen2; + + /** A NoiseGeneratorOctaves used in generating terrain */ + private NoiseGeneratorOctaves noiseGen3; + + /** A NoiseGeneratorOctaves used in generating terrain */ + private NoiseGeneratorOctaves noiseGen4; + + /** A NoiseGeneratorOctaves used in generating terrain */ + public NoiseGeneratorOctaves noiseGen5; + + /** A NoiseGeneratorOctaves used in generating terrain */ + public NoiseGeneratorOctaves noiseGen6; + public NoiseGeneratorOctaves mobSpawnerNoise; + + /** Reference to the World object. */ + private World worldObj; + + /** are map structures going to be generated (e.g. strongholds) */ + private final boolean mapFeaturesEnabled; + + /** Holds the overall noise array used in chunk generation */ + private double[] noiseArray; + private double[] stoneNoise = new double[256]; + private MapGenBase caveGenerator = new MapGenCaves(); + + /** Holds Stronghold Generator */ + private MapGenStronghold strongholdGenerator = new MapGenStronghold(); + + /** Holds Village Generator */ + private MapGenVillage villageGenerator = new MapGenVillage(); + + /** Holds Mineshaft Generator */ + private MapGenMineshaft mineshaftGenerator = new MapGenMineshaft(); + private MapGenScatteredFeature scatteredFeatureGenerator = new MapGenScatteredFeature(); + + /** Holds ravine generator */ + private MapGenBase ravineGenerator = new MapGenRavine(); + + /** The biomes that are used to generate the chunk */ + private BiomeGenBase[] biomesForGeneration; + + /** A double array that hold terrain noise from noiseGen3 */ + double[] noise3; + + /** A double array that hold terrain noise */ + double[] noise1; + + /** A double array that hold terrain noise from noiseGen2 */ + double[] noise2; + + /** A double array that hold terrain noise from noiseGen5 */ + double[] noise5; + + /** A double array that holds terrain noise from noiseGen6 */ + double[] noise6; + + /** + * Used to store the 5x5 parabolic field that is used during terrain generation. + */ + float[] parabolicField; + int[][] field_73219_j = new int[32][32]; + + public ChunkProviderGenerate(World par1World, long par2, boolean par4) { + this.worldObj = par1World; + this.mapFeaturesEnabled = par4; + this.rand = new Random(par2); + this.noiseGen1 = new NoiseGeneratorOctaves(this.rand, 16); + this.noiseGen2 = new NoiseGeneratorOctaves(this.rand, 16); + this.noiseGen3 = new NoiseGeneratorOctaves(this.rand, 8); + this.noiseGen4 = new NoiseGeneratorOctaves(this.rand, 4); + this.noiseGen5 = new NoiseGeneratorOctaves(this.rand, 10); + this.noiseGen6 = new NoiseGeneratorOctaves(this.rand, 16); + this.mobSpawnerNoise = new NoiseGeneratorOctaves(this.rand, 8); + } + + /** + * Generates the shape of the terrain for the chunk though its all stone though + * the water is frozen if the temperature is low enough + */ + public void generateTerrain(int par1, int par2, byte[] par3ArrayOfByte) { + byte var4 = 4; + byte var5 = 16; + byte var6 = 63; + int var7 = var4 + 1; + byte var8 = 17; + int var9 = var4 + 1; + this.biomesForGeneration = this.worldObj.getWorldChunkManager().getBiomesForGeneration(this.biomesForGeneration, + par1 * 4 - 2, par2 * 4 - 2, var7 + 5, var9 + 5); + this.noiseArray = this.initializeNoiseField(this.noiseArray, par1 * var4, 0, par2 * var4, var7, var8, var9); + + for (int var10 = 0; var10 < var4; ++var10) { + for (int var11 = 0; var11 < var4; ++var11) { + for (int var12 = 0; var12 < var5; ++var12) { + double var13 = 0.125D; + double var15 = this.noiseArray[((var10 + 0) * var9 + var11 + 0) * var8 + var12 + 0]; + double var17 = this.noiseArray[((var10 + 0) * var9 + var11 + 1) * var8 + var12 + 0]; + double var19 = this.noiseArray[((var10 + 1) * var9 + var11 + 0) * var8 + var12 + 0]; + double var21 = this.noiseArray[((var10 + 1) * var9 + var11 + 1) * var8 + var12 + 0]; + double var23 = (this.noiseArray[((var10 + 0) * var9 + var11 + 0) * var8 + var12 + 1] - var15) + * var13; + double var25 = (this.noiseArray[((var10 + 0) * var9 + var11 + 1) * var8 + var12 + 1] - var17) + * var13; + double var27 = (this.noiseArray[((var10 + 1) * var9 + var11 + 0) * var8 + var12 + 1] - var19) + * var13; + double var29 = (this.noiseArray[((var10 + 1) * var9 + var11 + 1) * var8 + var12 + 1] - var21) + * var13; + + for (int var31 = 0; var31 < 8; ++var31) { + double var32 = 0.25D; + double var34 = var15; + double var36 = var17; + double var38 = (var19 - var15) * var32; + double var40 = (var21 - var17) * var32; + + for (int var42 = 0; var42 < 4; ++var42) { + int var43 = var42 + var10 * 4 << 11 | 0 + var11 * 4 << 7 | var12 * 8 + var31; + short var44 = 128; + var43 -= var44; + double var45 = 0.25D; + double var49 = (var36 - var34) * var45; + double var47 = var34 - var49; + + for (int var51 = 0; var51 < 4; ++var51) { + if ((var47 += var49) > 0.0D) { + par3ArrayOfByte[var43 += var44] = (byte) Block.stone.blockID; + } else if (var12 * 8 + var31 < var6) { + par3ArrayOfByte[var43 += var44] = (byte) Block.waterStill.blockID; + } else { + par3ArrayOfByte[var43 += var44] = 0; + } + } + + var34 += var38; + var36 += var40; + } + + var15 += var23; + var17 += var25; + var19 += var27; + var21 += var29; + } + } + } + } + } + + /** + * Replaces the stone that was placed in with blocks that match the biome + */ + public void replaceBlocksForBiome(int par1, int par2, byte[] par3ArrayOfByte, + BiomeGenBase[] par4ArrayOfBiomeGenBase) { + byte var5 = 63; + double var6 = 0.03125D; + this.stoneNoise = this.noiseGen4.generateNoiseOctaves(this.stoneNoise, par1 * 16, par2 * 16, 0, 16, 16, 1, + var6 * 2.0D, var6 * 2.0D, var6 * 2.0D); + + for (int var8 = 0; var8 < 16; ++var8) { + for (int var9 = 0; var9 < 16; ++var9) { + BiomeGenBase var10 = par4ArrayOfBiomeGenBase[var9 + var8 * 16]; + float var11 = var10.getFloatTemperature(); + int var12 = (int) (this.stoneNoise[var8 + var9 * 16] / 3.0D + 3.0D + this.rand.nextDouble() * 0.25D); + int var13 = -1; + byte var14 = var10.topBlock; + byte var15 = var10.fillerBlock; + + for (int var16 = 127; var16 >= 0; --var16) { + int var17 = (var9 * 16 + var8) * 128 + var16; + + if (var16 <= 0 + this.rand.nextInt(5)) { + par3ArrayOfByte[var17] = (byte) Block.bedrock.blockID; + } else { + byte var18 = par3ArrayOfByte[var17]; + + if (var18 == 0) { + var13 = -1; + } else if (var18 == Block.stone.blockID) { + if (var13 == -1) { + if (var12 <= 0) { + var14 = 0; + var15 = (byte) Block.stone.blockID; + } else if (var16 >= var5 - 4 && var16 <= var5 + 1) { + var14 = var10.topBlock; + var15 = var10.fillerBlock; + } + + if (var16 < var5 && var14 == 0) { + if (var11 < 0.15F) { + var14 = (byte) Block.ice.blockID; + } else { + var14 = (byte) Block.waterStill.blockID; + } + } + + var13 = var12; + + if (var16 >= var5 - 1) { + par3ArrayOfByte[var17] = var14; + } else { + par3ArrayOfByte[var17] = var15; + } + } else if (var13 > 0) { + --var13; + par3ArrayOfByte[var17] = var15; + + if (var13 == 0 && var15 == Block.sand.blockID) { + var13 = this.rand.nextInt(4); + var15 = (byte) Block.sandStone.blockID; + } + } + } + } + } + } + } + } + + /** + * loads or generates the chunk at the chunk location specified + */ + public Chunk loadChunk(int par1, int par2) { + return this.provideChunk(par1, par2); + } + + /** + * Will return back a chunk, if it doesn't exist and its not a MP client it will + * generates all the blocks for the specified chunk from the map seed and chunk + * seed + */ + public Chunk provideChunk(int par1, int par2) { + this.rand.setSeed((long) par1 * 341873128712L + (long) par2 * 132897987541L); + byte[] var3 = new byte[32768]; + this.generateTerrain(par1, par2, var3); + this.biomesForGeneration = this.worldObj.getWorldChunkManager().loadBlockGeneratorData(this.biomesForGeneration, + par1 * 16, par2 * 16, 16, 16); + this.replaceBlocksForBiome(par1, par2, var3, this.biomesForGeneration); + this.caveGenerator.generate(this, this.worldObj, par1, par2, var3); + this.ravineGenerator.generate(this, this.worldObj, par1, par2, var3); + + if (this.mapFeaturesEnabled) { + this.mineshaftGenerator.generate(this, this.worldObj, par1, par2, var3); + this.villageGenerator.generate(this, this.worldObj, par1, par2, var3); + this.strongholdGenerator.generate(this, this.worldObj, par1, par2, var3); + this.scatteredFeatureGenerator.generate(this, this.worldObj, par1, par2, var3); + } + + Chunk var4 = new Chunk(this.worldObj, var3, par1, par2); + byte[] var5 = var4.getBiomeArray(); + + for (int var6 = 0; var6 < var5.length; ++var6) { + var5[var6] = (byte) this.biomesForGeneration[var6].biomeID; + } + + var4.generateSkylightMap(); + return var4; + } + + /** + * generates a subset of the level's terrain data. Takes 7 arguments: the + * [empty] noise array, the position, and the size. + */ + private double[] initializeNoiseField(double[] par1ArrayOfDouble, int par2, int par3, int par4, int par5, int par6, + int par7) { + if (par1ArrayOfDouble == null) { + par1ArrayOfDouble = new double[par5 * par6 * par7]; + } + + if (this.parabolicField == null) { + this.parabolicField = new float[25]; + + for (int var8 = -2; var8 <= 2; ++var8) { + for (int var9 = -2; var9 <= 2; ++var9) { + float var10 = 10.0F / MathHelper.sqrt_float((float) (var8 * var8 + var9 * var9) + 0.2F); + this.parabolicField[var8 + 2 + (var9 + 2) * 5] = var10; + } + } + } + + double var44 = 684.412D; + double var45 = 684.412D; + this.noise5 = this.noiseGen5.generateNoiseOctaves(this.noise5, par2, par4, par5, par7, 1.121D, 1.121D, 0.5D); + this.noise6 = this.noiseGen6.generateNoiseOctaves(this.noise6, par2, par4, par5, par7, 200.0D, 200.0D, 0.5D); + this.noise3 = this.noiseGen3.generateNoiseOctaves(this.noise3, par2, par3, par4, par5, par6, par7, + var44 / 80.0D, var45 / 160.0D, var44 / 80.0D); + this.noise1 = this.noiseGen1.generateNoiseOctaves(this.noise1, par2, par3, par4, par5, par6, par7, var44, var45, + var44); + this.noise2 = this.noiseGen2.generateNoiseOctaves(this.noise2, par2, par3, par4, par5, par6, par7, var44, var45, + var44); + boolean var43 = false; + boolean var42 = false; + int var12 = 0; + int var13 = 0; + + for (int var14 = 0; var14 < par5; ++var14) { + for (int var15 = 0; var15 < par7; ++var15) { + float var16 = 0.0F; + float var17 = 0.0F; + float var18 = 0.0F; + byte var19 = 2; + BiomeGenBase var20 = this.biomesForGeneration[var14 + 2 + (var15 + 2) * (par5 + 5)]; + + for (int var21 = -var19; var21 <= var19; ++var21) { + for (int var22 = -var19; var22 <= var19; ++var22) { + BiomeGenBase var23 = this.biomesForGeneration[var14 + var21 + 2 + + (var15 + var22 + 2) * (par5 + 5)]; + float var24 = this.parabolicField[var21 + 2 + (var22 + 2) * 5] / (var23.minHeight + 2.0F); + + if (var23.minHeight > var20.minHeight) { + var24 /= 2.0F; + } + + var16 += var23.maxHeight * var24; + var17 += var23.minHeight * var24; + var18 += var24; + } + } + + var16 /= var18; + var17 /= var18; + var16 = var16 * 0.9F + 0.1F; + var17 = (var17 * 4.0F - 1.0F) / 8.0F; + double var46 = this.noise6[var13] / 8000.0D; + + if (var46 < 0.0D) { + var46 = -var46 * 0.3D; + } + + var46 = var46 * 3.0D - 2.0D; + + if (var46 < 0.0D) { + var46 /= 2.0D; + + if (var46 < -1.0D) { + var46 = -1.0D; + } + + var46 /= 1.4D; + var46 /= 2.0D; + } else { + if (var46 > 1.0D) { + var46 = 1.0D; + } + + var46 /= 8.0D; + } + + ++var13; + + for (int var47 = 0; var47 < par6; ++var47) { + double var48 = (double) var17; + double var26 = (double) var16; + var48 += var46 * 0.2D; + var48 = var48 * (double) par6 / 16.0D; + double var28 = (double) par6 / 2.0D + var48 * 4.0D; + double var30 = 0.0D; + double var32 = ((double) var47 - var28) * 12.0D * 128.0D / 128.0D / var26; + + if (var32 < 0.0D) { + var32 *= 4.0D; + } + + double var34 = this.noise1[var12] / 512.0D; + double var36 = this.noise2[var12] / 512.0D; + double var38 = (this.noise3[var12] / 10.0D + 1.0D) / 2.0D; + + if (var38 < 0.0D) { + var30 = var34; + } else if (var38 > 1.0D) { + var30 = var36; + } else { + var30 = var34 + (var36 - var34) * var38; + } + + var30 -= var32; + + if (var47 > par6 - 4) { + double var40 = (double) ((float) (var47 - (par6 - 4)) / 3.0F); + var30 = var30 * (1.0D - var40) + -10.0D * var40; + } + + par1ArrayOfDouble[var12] = var30; + ++var12; + } + } + } + + return par1ArrayOfDouble; + } + + /** + * Checks to see if a chunk exists at x, y + */ + public boolean chunkExists(int par1, int par2) { + return true; + } + + /** + * Populates chunk with ores etc etc + */ + public void populate(IChunkProvider par1IChunkProvider, int par2, int par3) { + BlockSand.fallInstantly = true; + int var4 = par2 * 16; + int var5 = par3 * 16; + BiomeGenBase var6 = this.worldObj.getBiomeGenForCoords(var4 + 16, var5 + 16); + this.rand.setSeed(this.worldObj.getSeed()); + long var7 = this.rand.nextLong() / 2L * 2L + 1L; + long var9 = this.rand.nextLong() / 2L * 2L + 1L; + this.rand.setSeed((long) par2 * var7 + (long) par3 * var9 ^ this.worldObj.getSeed()); + boolean var11 = false; + + if (this.mapFeaturesEnabled) { + this.mineshaftGenerator.generateStructuresInChunk(this.worldObj, this.rand, par2, par3); + var11 = this.villageGenerator.generateStructuresInChunk(this.worldObj, this.rand, par2, par3); + this.strongholdGenerator.generateStructuresInChunk(this.worldObj, this.rand, par2, par3); + this.scatteredFeatureGenerator.generateStructuresInChunk(this.worldObj, this.rand, par2, par3); + } + + int var12; + int var13; + int var14; + + if (!var11 && this.rand.nextInt(4) == 0) { + var12 = var4 + this.rand.nextInt(16) + 8; + var13 = this.rand.nextInt(128); + var14 = var5 + this.rand.nextInt(16) + 8; + (new WorldGenLakes(Block.waterStill.blockID)).generate(this.worldObj, this.rand, var12, var13, var14); + } + + if (!var11 && this.rand.nextInt(8) == 0) { + var12 = var4 + this.rand.nextInt(16) + 8; + var13 = this.rand.nextInt(this.rand.nextInt(120) + 8); + var14 = var5 + this.rand.nextInt(16) + 8; + + if (var13 < 63 || this.rand.nextInt(10) == 0) { + (new WorldGenLakes(Block.lavaStill.blockID)).generate(this.worldObj, this.rand, var12, var13, var14); + } + } + + for (var12 = 0; var12 < 8; ++var12) { + var13 = var4 + this.rand.nextInt(16) + 8; + var14 = this.rand.nextInt(128); + int var15 = var5 + this.rand.nextInt(16) + 8; + + if ((new WorldGenDungeons()).generate(this.worldObj, this.rand, var13, var14, var15)) { + ; + } + } + + var6.decorate(this.worldObj, this.rand, var4, var5); + SpawnerAnimals.performWorldGenSpawning(this.worldObj, var6, var4 + 8, var5 + 8, 16, 16, this.rand); + var4 += 8; + var5 += 8; + + for (var12 = 0; var12 < 16; ++var12) { + for (var13 = 0; var13 < 16; ++var13) { + var14 = this.worldObj.getPrecipitationHeight(var4 + var12, var5 + var13); + + if (this.worldObj.isBlockFreezable(var12 + var4, var14 - 1, var13 + var5)) { + this.worldObj.setBlock(var12 + var4, var14 - 1, var13 + var5, Block.ice.blockID, 0, 2); + } + + if (this.worldObj.canSnowAt(var12 + var4, var14, var13 + var5)) { + this.worldObj.setBlock(var12 + var4, var14, var13 + var5, Block.snow.blockID, 0, 2); + } + } + } + + BlockSand.fallInstantly = false; + } + + /** + * Two modes of operation: if passed true, save all Chunks in one go. If passed + * false, save up to two chunks. Return true if all chunks have been saved. + */ + public boolean saveChunks(boolean par1, IProgressUpdate par2IProgressUpdate) { + return true; + } + + public void func_104112_b() { + } + + /** + * Unloads chunks that are marked to be unloaded. This is not guaranteed to + * unload every such chunk. + */ + public boolean unloadQueuedChunks() { + return false; + } + + /** + * Returns if the IChunkProvider supports saving. + */ + public boolean canSave() { + return true; + } + + /** + * Converts the instance data to a readable string. + */ + public String makeString() { + return "RandomLevelSource"; + } + + /** + * Returns a list of creatures of the specified type that can spawn at the given + * location. + */ + public List getPossibleCreatures(EnumCreatureType par1EnumCreatureType, int par2, int par3, int par4) { + BiomeGenBase var5 = this.worldObj.getBiomeGenForCoords(par2, par4); + return var5 == null ? null + : (var5 == BiomeGenBase.swampland && par1EnumCreatureType == EnumCreatureType.monster + && this.scatteredFeatureGenerator.hasStructureAt(par2, par3, par4) + ? this.scatteredFeatureGenerator.getScatteredFeatureSpawnList() + : var5.getSpawnableList(par1EnumCreatureType)); + } + + /** + * Returns the location of the closest structure of the specified type. If not + * found returns null. + */ + public ChunkPosition findClosestStructure(World par1World, String par2Str, int par3, int par4, int par5) { + return "Stronghold".equals(par2Str) && this.strongholdGenerator != null + ? this.strongholdGenerator.getNearestInstance(par1World, par3, par4, par5) + : null; + } + + public int getLoadedChunkCount() { + return 0; + } + + public void recreateStructures(int par1, int par2) { + if (this.mapFeaturesEnabled) { + this.mineshaftGenerator.generate(this, this.worldObj, par1, par2, (byte[]) null); + this.villageGenerator.generate(this, this.worldObj, par1, par2, (byte[]) null); + this.strongholdGenerator.generate(this, this.worldObj, par1, par2, (byte[]) null); + this.scatteredFeatureGenerator.generate(this, this.worldObj, par1, par2, (byte[]) null); + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ChunkProviderHell.java b/sp-server/src/main/java/net/minecraft/src/ChunkProviderHell.java new file mode 100644 index 0000000..c746f7a --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ChunkProviderHell.java @@ -0,0 +1,523 @@ +package net.minecraft.src; + +import java.util.List; +import java.util.Random; + +public class ChunkProviderHell implements IChunkProvider { + private Random hellRNG; + + /** A NoiseGeneratorOctaves used in generating nether terrain */ + private NoiseGeneratorOctaves netherNoiseGen1; + private NoiseGeneratorOctaves netherNoiseGen2; + private NoiseGeneratorOctaves netherNoiseGen3; + + /** Determines whether slowsand or gravel can be generated at a location */ + private NoiseGeneratorOctaves slowsandGravelNoiseGen; + + /** + * Determines whether something other than nettherack can be generated at a + * location + */ + private NoiseGeneratorOctaves netherrackExculsivityNoiseGen; + public NoiseGeneratorOctaves netherNoiseGen6; + public NoiseGeneratorOctaves netherNoiseGen7; + + /** Is the world that the nether is getting generated. */ + private World worldObj; + private double[] noiseField; + public MapGenNetherBridge genNetherBridge = new MapGenNetherBridge(); + + /** + * Holds the noise used to determine whether slowsand can be generated at a + * location + */ + private double[] slowsandNoise = new double[256]; + private double[] gravelNoise = new double[256]; + + /** + * Holds the noise used to determine whether something other than netherrack can + * be generated at a location + */ + private double[] netherrackExclusivityNoise = new double[256]; + private MapGenBase netherCaveGenerator = new MapGenCavesHell(); + double[] noiseData1; + double[] noiseData2; + double[] noiseData3; + double[] noiseData4; + double[] noiseData5; + + public ChunkProviderHell(World par1World, long par2) { + this.worldObj = par1World; + this.hellRNG = new Random(par2); + this.netherNoiseGen1 = new NoiseGeneratorOctaves(this.hellRNG, 16); + this.netherNoiseGen2 = new NoiseGeneratorOctaves(this.hellRNG, 16); + this.netherNoiseGen3 = new NoiseGeneratorOctaves(this.hellRNG, 8); + this.slowsandGravelNoiseGen = new NoiseGeneratorOctaves(this.hellRNG, 4); + this.netherrackExculsivityNoiseGen = new NoiseGeneratorOctaves(this.hellRNG, 4); + this.netherNoiseGen6 = new NoiseGeneratorOctaves(this.hellRNG, 10); + this.netherNoiseGen7 = new NoiseGeneratorOctaves(this.hellRNG, 16); + } + + /** + * Generates the shape of the terrain in the nether. + */ + public void generateNetherTerrain(int par1, int par2, byte[] par3ArrayOfByte) { + byte var4 = 4; + byte var5 = 32; + int var6 = var4 + 1; + byte var7 = 17; + int var8 = var4 + 1; + this.noiseField = this.initializeNoiseField(this.noiseField, par1 * var4, 0, par2 * var4, var6, var7, var8); + + for (int var9 = 0; var9 < var4; ++var9) { + for (int var10 = 0; var10 < var4; ++var10) { + for (int var11 = 0; var11 < 16; ++var11) { + double var12 = 0.125D; + double var14 = this.noiseField[((var9 + 0) * var8 + var10 + 0) * var7 + var11 + 0]; + double var16 = this.noiseField[((var9 + 0) * var8 + var10 + 1) * var7 + var11 + 0]; + double var18 = this.noiseField[((var9 + 1) * var8 + var10 + 0) * var7 + var11 + 0]; + double var20 = this.noiseField[((var9 + 1) * var8 + var10 + 1) * var7 + var11 + 0]; + double var22 = (this.noiseField[((var9 + 0) * var8 + var10 + 0) * var7 + var11 + 1] - var14) + * var12; + double var24 = (this.noiseField[((var9 + 0) * var8 + var10 + 1) * var7 + var11 + 1] - var16) + * var12; + double var26 = (this.noiseField[((var9 + 1) * var8 + var10 + 0) * var7 + var11 + 1] - var18) + * var12; + double var28 = (this.noiseField[((var9 + 1) * var8 + var10 + 1) * var7 + var11 + 1] - var20) + * var12; + + for (int var30 = 0; var30 < 8; ++var30) { + double var31 = 0.25D; + double var33 = var14; + double var35 = var16; + double var37 = (var18 - var14) * var31; + double var39 = (var20 - var16) * var31; + + for (int var41 = 0; var41 < 4; ++var41) { + int var42 = var41 + var9 * 4 << 11 | 0 + var10 * 4 << 7 | var11 * 8 + var30; + short var43 = 128; + double var44 = 0.25D; + double var46 = var33; + double var48 = (var35 - var33) * var44; + + for (int var50 = 0; var50 < 4; ++var50) { + int var51 = 0; + + if (var11 * 8 + var30 < var5) { + var51 = Block.lavaStill.blockID; + } + + if (var46 > 0.0D) { + var51 = Block.netherrack.blockID; + } + + par3ArrayOfByte[var42] = (byte) var51; + var42 += var43; + var46 += var48; + } + + var33 += var37; + var35 += var39; + } + + var14 += var22; + var16 += var24; + var18 += var26; + var20 += var28; + } + } + } + } + } + + /** + * name based on ChunkProviderGenerate + */ + public void replaceBlocksForBiome(int par1, int par2, byte[] par3ArrayOfByte) { + byte var4 = 64; + double var5 = 0.03125D; + this.slowsandNoise = this.slowsandGravelNoiseGen.generateNoiseOctaves(this.slowsandNoise, par1 * 16, par2 * 16, + 0, 16, 16, 1, var5, var5, 1.0D); + this.gravelNoise = this.slowsandGravelNoiseGen.generateNoiseOctaves(this.gravelNoise, par1 * 16, 109, par2 * 16, + 16, 1, 16, var5, 1.0D, var5); + this.netherrackExclusivityNoise = this.netherrackExculsivityNoiseGen.generateNoiseOctaves( + this.netherrackExclusivityNoise, par1 * 16, par2 * 16, 0, 16, 16, 1, var5 * 2.0D, var5 * 2.0D, + var5 * 2.0D); + + for (int var7 = 0; var7 < 16; ++var7) { + for (int var8 = 0; var8 < 16; ++var8) { + boolean var9 = this.slowsandNoise[var7 + var8 * 16] + this.hellRNG.nextDouble() * 0.2D > 0.0D; + boolean var10 = this.gravelNoise[var7 + var8 * 16] + this.hellRNG.nextDouble() * 0.2D > 0.0D; + int var11 = (int) (this.netherrackExclusivityNoise[var7 + var8 * 16] / 3.0D + 3.0D + + this.hellRNG.nextDouble() * 0.25D); + int var12 = -1; + byte var13 = (byte) Block.netherrack.blockID; + byte var14 = (byte) Block.netherrack.blockID; + + for (int var15 = 127; var15 >= 0; --var15) { + int var16 = (var8 * 16 + var7) * 128 + var15; + + if (var15 < 127 - this.hellRNG.nextInt(5) && var15 > 0 + this.hellRNG.nextInt(5)) { + byte var17 = par3ArrayOfByte[var16]; + + if (var17 == 0) { + var12 = -1; + } else if (var17 == Block.netherrack.blockID) { + if (var12 == -1) { + if (var11 <= 0) { + var13 = 0; + var14 = (byte) Block.netherrack.blockID; + } else if (var15 >= var4 - 4 && var15 <= var4 + 1) { + var13 = (byte) Block.netherrack.blockID; + var14 = (byte) Block.netherrack.blockID; + + if (var10) { + var13 = (byte) Block.gravel.blockID; + } + + if (var10) { + var14 = (byte) Block.netherrack.blockID; + } + + if (var9) { + var13 = (byte) Block.slowSand.blockID; + } + + if (var9) { + var14 = (byte) Block.slowSand.blockID; + } + } + + if (var15 < var4 && var13 == 0) { + var13 = (byte) Block.lavaStill.blockID; + } + + var12 = var11; + + if (var15 >= var4 - 1) { + par3ArrayOfByte[var16] = var13; + } else { + par3ArrayOfByte[var16] = var14; + } + } else if (var12 > 0) { + --var12; + par3ArrayOfByte[var16] = var14; + } + } + } else { + par3ArrayOfByte[var16] = (byte) Block.bedrock.blockID; + } + } + } + } + } + + /** + * loads or generates the chunk at the chunk location specified + */ + public Chunk loadChunk(int par1, int par2) { + return this.provideChunk(par1, par2); + } + + /** + * Will return back a chunk, if it doesn't exist and its not a MP client it will + * generates all the blocks for the specified chunk from the map seed and chunk + * seed + */ + public Chunk provideChunk(int par1, int par2) { + this.hellRNG.setSeed((long) par1 * 341873128712L + (long) par2 * 132897987541L); + byte[] var3 = new byte[32768]; + this.generateNetherTerrain(par1, par2, var3); + this.replaceBlocksForBiome(par1, par2, var3); + this.netherCaveGenerator.generate(this, this.worldObj, par1, par2, var3); + this.genNetherBridge.generate(this, this.worldObj, par1, par2, var3); + Chunk var4 = new Chunk(this.worldObj, var3, par1, par2); + BiomeGenBase[] var5 = this.worldObj.getWorldChunkManager().loadBlockGeneratorData((BiomeGenBase[]) null, + par1 * 16, par2 * 16, 16, 16); + byte[] var6 = var4.getBiomeArray(); + + for (int var7 = 0; var7 < var6.length; ++var7) { + var6[var7] = (byte) var5[var7].biomeID; + } + + var4.resetRelightChecks(); + return var4; + } + + /** + * generates a subset of the level's terrain data. Takes 7 arguments: the + * [empty] noise array, the position, and the size. + */ + private double[] initializeNoiseField(double[] par1ArrayOfDouble, int par2, int par3, int par4, int par5, int par6, + int par7) { + if (par1ArrayOfDouble == null) { + par1ArrayOfDouble = new double[par5 * par6 * par7]; + } + + double var8 = 684.412D; + double var10 = 2053.236D; + this.noiseData4 = this.netherNoiseGen6.generateNoiseOctaves(this.noiseData4, par2, par3, par4, par5, 1, par7, + 1.0D, 0.0D, 1.0D); + this.noiseData5 = this.netherNoiseGen7.generateNoiseOctaves(this.noiseData5, par2, par3, par4, par5, 1, par7, + 100.0D, 0.0D, 100.0D); + this.noiseData1 = this.netherNoiseGen3.generateNoiseOctaves(this.noiseData1, par2, par3, par4, par5, par6, par7, + var8 / 80.0D, var10 / 60.0D, var8 / 80.0D); + this.noiseData2 = this.netherNoiseGen1.generateNoiseOctaves(this.noiseData2, par2, par3, par4, par5, par6, par7, + var8, var10, var8); + this.noiseData3 = this.netherNoiseGen2.generateNoiseOctaves(this.noiseData3, par2, par3, par4, par5, par6, par7, + var8, var10, var8); + int var12 = 0; + int var13 = 0; + double[] var14 = new double[par6]; + int var15; + + for (var15 = 0; var15 < par6; ++var15) { + var14[var15] = Math.cos((double) var15 * Math.PI * 6.0D / (double) par6) * 2.0D; + double var16 = (double) var15; + + if (var15 > par6 / 2) { + var16 = (double) (par6 - 1 - var15); + } + + if (var16 < 4.0D) { + var16 = 4.0D - var16; + var14[var15] -= var16 * var16 * var16 * 10.0D; + } + } + + for (var15 = 0; var15 < par5; ++var15) { + for (int var36 = 0; var36 < par7; ++var36) { + double var17 = (this.noiseData4[var13] + 256.0D) / 512.0D; + + if (var17 > 1.0D) { + var17 = 1.0D; + } + + double var19 = 0.0D; + double var21 = this.noiseData5[var13] / 8000.0D; + + if (var21 < 0.0D) { + var21 = -var21; + } + + var21 = var21 * 3.0D - 3.0D; + + if (var21 < 0.0D) { + var21 /= 2.0D; + + if (var21 < -1.0D) { + var21 = -1.0D; + } + + var21 /= 1.4D; + var21 /= 2.0D; + var17 = 0.0D; + } else { + if (var21 > 1.0D) { + var21 = 1.0D; + } + + var21 /= 6.0D; + } + + var17 += 0.5D; + var21 = var21 * (double) par6 / 16.0D; + ++var13; + + for (int var23 = 0; var23 < par6; ++var23) { + double var24 = 0.0D; + double var26 = var14[var23]; + double var28 = this.noiseData2[var12] / 512.0D; + double var30 = this.noiseData3[var12] / 512.0D; + double var32 = (this.noiseData1[var12] / 10.0D + 1.0D) / 2.0D; + + if (var32 < 0.0D) { + var24 = var28; + } else if (var32 > 1.0D) { + var24 = var30; + } else { + var24 = var28 + (var30 - var28) * var32; + } + + var24 -= var26; + double var34; + + if (var23 > par6 - 4) { + var34 = (double) ((float) (var23 - (par6 - 4)) / 3.0F); + var24 = var24 * (1.0D - var34) + -10.0D * var34; + } + + if ((double) var23 < var19) { + var34 = (var19 - (double) var23) / 4.0D; + + if (var34 < 0.0D) { + var34 = 0.0D; + } + + if (var34 > 1.0D) { + var34 = 1.0D; + } + + var24 = var24 * (1.0D - var34) + -10.0D * var34; + } + + par1ArrayOfDouble[var12] = var24; + ++var12; + } + } + } + + return par1ArrayOfDouble; + } + + /** + * Checks to see if a chunk exists at x, y + */ + public boolean chunkExists(int par1, int par2) { + return true; + } + + /** + * Populates chunk with ores etc etc + */ + public void populate(IChunkProvider par1IChunkProvider, int par2, int par3) { + BlockSand.fallInstantly = true; + int var4 = par2 * 16; + int var5 = par3 * 16; + this.genNetherBridge.generateStructuresInChunk(this.worldObj, this.hellRNG, par2, par3); + int var6; + int var7; + int var8; + int var9; + + for (var6 = 0; var6 < 8; ++var6) { + var7 = var4 + this.hellRNG.nextInt(16) + 8; + var8 = this.hellRNG.nextInt(120) + 4; + var9 = var5 + this.hellRNG.nextInt(16) + 8; + (new WorldGenHellLava(Block.lavaMoving.blockID, false)).generate(this.worldObj, this.hellRNG, var7, var8, + var9); + } + + var6 = this.hellRNG.nextInt(this.hellRNG.nextInt(10) + 1) + 1; + int var10; + + for (var7 = 0; var7 < var6; ++var7) { + var8 = var4 + this.hellRNG.nextInt(16) + 8; + var9 = this.hellRNG.nextInt(120) + 4; + var10 = var5 + this.hellRNG.nextInt(16) + 8; + (new WorldGenFire()).generate(this.worldObj, this.hellRNG, var8, var9, var10); + } + + var6 = this.hellRNG.nextInt(this.hellRNG.nextInt(10) + 1); + + for (var7 = 0; var7 < var6; ++var7) { + var8 = var4 + this.hellRNG.nextInt(16) + 8; + var9 = this.hellRNG.nextInt(120) + 4; + var10 = var5 + this.hellRNG.nextInt(16) + 8; + (new WorldGenGlowStone1()).generate(this.worldObj, this.hellRNG, var8, var9, var10); + } + + for (var7 = 0; var7 < 10; ++var7) { + var8 = var4 + this.hellRNG.nextInt(16) + 8; + var9 = this.hellRNG.nextInt(128); + var10 = var5 + this.hellRNG.nextInt(16) + 8; + (new WorldGenGlowStone2()).generate(this.worldObj, this.hellRNG, var8, var9, var10); + } + + if (this.hellRNG.nextInt(1) == 0) { + var7 = var4 + this.hellRNG.nextInt(16) + 8; + var8 = this.hellRNG.nextInt(128); + var9 = var5 + this.hellRNG.nextInt(16) + 8; + (new WorldGenFlowers(Block.mushroomBrown.blockID)).generate(this.worldObj, this.hellRNG, var7, var8, var9); + } + + if (this.hellRNG.nextInt(1) == 0) { + var7 = var4 + this.hellRNG.nextInt(16) + 8; + var8 = this.hellRNG.nextInt(128); + var9 = var5 + this.hellRNG.nextInt(16) + 8; + (new WorldGenFlowers(Block.mushroomRed.blockID)).generate(this.worldObj, this.hellRNG, var7, var8, var9); + } + + WorldGenMinable var12 = new WorldGenMinable(Block.oreNetherQuartz.blockID, 13, Block.netherrack.blockID); + int var11; + + for (var8 = 0; var8 < 16; ++var8) { + var9 = var4 + this.hellRNG.nextInt(16); + var10 = this.hellRNG.nextInt(108) + 10; + var11 = var5 + this.hellRNG.nextInt(16); + var12.generate(this.worldObj, this.hellRNG, var9, var10, var11); + } + + for (var8 = 0; var8 < 16; ++var8) { + var9 = var4 + this.hellRNG.nextInt(16); + var10 = this.hellRNG.nextInt(108) + 10; + var11 = var5 + this.hellRNG.nextInt(16); + (new WorldGenHellLava(Block.lavaMoving.blockID, true)).generate(this.worldObj, this.hellRNG, var9, var10, + var11); + } + + BlockSand.fallInstantly = false; + } + + /** + * Two modes of operation: if passed true, save all Chunks in one go. If passed + * false, save up to two chunks. Return true if all chunks have been saved. + */ + public boolean saveChunks(boolean par1, IProgressUpdate par2IProgressUpdate) { + return true; + } + + public void func_104112_b() { + } + + /** + * Unloads chunks that are marked to be unloaded. This is not guaranteed to + * unload every such chunk. + */ + public boolean unloadQueuedChunks() { + return false; + } + + /** + * Returns if the IChunkProvider supports saving. + */ + public boolean canSave() { + return true; + } + + /** + * Converts the instance data to a readable string. + */ + public String makeString() { + return "HellRandomLevelSource"; + } + + /** + * Returns a list of creatures of the specified type that can spawn at the given + * location. + */ + public List getPossibleCreatures(EnumCreatureType par1EnumCreatureType, int par2, int par3, int par4) { + if (par1EnumCreatureType == EnumCreatureType.monster && this.genNetherBridge.hasStructureAt(par2, par3, par4)) { + return this.genNetherBridge.getSpawnList(); + } else { + BiomeGenBase var5 = this.worldObj.getBiomeGenForCoords(par2, par4); + return var5 == null ? null : var5.getSpawnableList(par1EnumCreatureType); + } + } + + /** + * Returns the location of the closest structure of the specified type. If not + * found returns null. + */ + public ChunkPosition findClosestStructure(World par1World, String par2Str, int par3, int par4, int par5) { + return null; + } + + public int getLoadedChunkCount() { + return 0; + } + + public void recreateStructures(int par1, int par2) { + this.genNetherBridge.generate(this, this.worldObj, par1, par2, (byte[]) null); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ChunkProviderServer.java b/sp-server/src/main/java/net/minecraft/src/ChunkProviderServer.java new file mode 100644 index 0000000..daed095 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ChunkProviderServer.java @@ -0,0 +1,288 @@ +package net.minecraft.src; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +public class ChunkProviderServer implements IChunkProvider { + private Set droppedChunksSet = new HashSet(); + + /** a dummy chunk, returned in place of an actual chunk. */ + private Chunk dummyChunk; + + /** + * chunk generator object. Calls to load nonexistent chunks are forwarded to + * this object. + */ + private IChunkProvider serverChunkGenerator; + private IChunkLoader chunkLoader; + + /** + * if set, this flag forces a request to load a chunk to load the chunk rather + * than defaulting to the dummy if possible + */ + public boolean chunkLoadOverride = true; + + /** map of chunk Id's to Chunk instances */ + private LongHashMap id2ChunkMap = new LongHashMap(); + private List loadedChunks = new ArrayList(); + private WorldServer worldObj; + + public ChunkProviderServer(WorldServer par1WorldServer, IChunkLoader par2IChunkLoader, + IChunkProvider par3IChunkProvider) { + this.dummyChunk = new EmptyChunk(par1WorldServer, 0, 0); + this.worldObj = par1WorldServer; + this.chunkLoader = par2IChunkLoader; + this.serverChunkGenerator = par3IChunkProvider; + } + + /** + * Checks to see if a chunk exists at x, y + */ + public boolean chunkExists(int par1, int par2) { + return this.id2ChunkMap.containsItem(ChunkCoordIntPair.chunkXZ2Int(par1, par2)); + } + + public void dropChunk(int par1, int par2) { + if (this.worldObj.provider.canRespawnHere()) { + ChunkCoordinates var3 = this.worldObj.getSpawnPoint(); + int var4 = par1 * 16 + 8 - var3.posX; + int var5 = par2 * 16 + 8 - var3.posZ; + short var6 = 128; + + if (var4 < -var6 || var4 > var6 || var5 < -var6 || var5 > var6) { + this.droppedChunksSet.add(Long.valueOf(ChunkCoordIntPair.chunkXZ2Int(par1, par2))); + } + } else { + this.droppedChunksSet.add(Long.valueOf(ChunkCoordIntPair.chunkXZ2Int(par1, par2))); + } + } + + /** + * marks all chunks for unload, ignoring those near the spawn + */ + public void unloadAllChunks() { + Iterator var1 = this.loadedChunks.iterator(); + + while (var1.hasNext()) { + Chunk var2 = (Chunk) var1.next(); + this.dropChunk(var2.xPosition, var2.zPosition); + } + } + + /** + * loads or generates the chunk at the chunk location specified + */ + public Chunk loadChunk(int par1, int par2) { + long var3 = ChunkCoordIntPair.chunkXZ2Int(par1, par2); + this.droppedChunksSet.remove(Long.valueOf(var3)); + Chunk var5 = (Chunk) this.id2ChunkMap.getValueByKey(var3); + + if (var5 == null) { + var5 = this.loadChunkFromFile(par1, par2); + + if (var5 == null) { + if (this.serverChunkGenerator == null) { + var5 = this.dummyChunk; + } else { + try { + var5 = this.serverChunkGenerator.provideChunk(par1, par2); + } catch (Throwable var9) { + CrashReport var7 = CrashReport.makeCrashReport(var9, "Exception generating new chunk"); + CrashReportCategory var8 = var7.makeCategory("Chunk to be generated"); + var8.addCrashSection("Location", + String.format("%d,%d", new Object[] { Integer.valueOf(par1), Integer.valueOf(par2) })); + var8.addCrashSection("Position hash", Long.valueOf(var3)); + var8.addCrashSection("Generator", this.serverChunkGenerator.makeString()); + throw new ReportedException(var7); + } + } + } + + this.id2ChunkMap.add(var3, var5); + this.loadedChunks.add(var5); + + if (var5 != null) { + var5.onChunkLoad(); + } + + var5.populateChunk(this, this, par1, par2); + } + + return var5; + } + + /** + * Will return back a chunk, if it doesn't exist and its not a MP client it will + * generates all the blocks for the specified chunk from the map seed and chunk + * seed + */ + public Chunk provideChunk(int par1, int par2) { + Chunk var3 = (Chunk) this.id2ChunkMap.getValueByKey(ChunkCoordIntPair.chunkXZ2Int(par1, par2)); + return var3 == null ? (!this.worldObj.findingSpawnPoint && !this.chunkLoadOverride ? this.dummyChunk + : this.loadChunk(par1, par2)) : var3; + } + + private Chunk loadChunkFromFile(int par1, int par2) { + if (this.chunkLoader == null) { + return null; + } else { + try { + Chunk var3 = this.chunkLoader.loadChunk(this.worldObj, par1, par2); + + if (var3 != null) { + var3.lastSaveTime = this.worldObj.getTotalWorldTime(); + + if (this.serverChunkGenerator != null) { + this.serverChunkGenerator.recreateStructures(par1, par2); + } + } + + return var3; + } catch (Exception var4) { + var4.printStackTrace(); + return null; + } + } + } + + private void saveChunkExtraData(Chunk par1Chunk) { + if (this.chunkLoader != null) { + try { + this.chunkLoader.saveExtraChunkData(this.worldObj, par1Chunk); + } catch (Exception var3) { + var3.printStackTrace(); + } + } + } + + private void saveChunkData(Chunk par1Chunk) { + if (this.chunkLoader != null) { + try { + par1Chunk.lastSaveTime = this.worldObj.getTotalWorldTime(); + this.chunkLoader.saveChunk(this.worldObj, par1Chunk); + } catch (IOException var3) { + var3.printStackTrace(); + } catch (MinecraftException var4) { + var4.printStackTrace(); + } + } + } + + /** + * Populates chunk with ores etc etc + */ + public void populate(IChunkProvider par1IChunkProvider, int par2, int par3) { + Chunk var4 = this.provideChunk(par2, par3); + + if (!var4.isTerrainPopulated) { + var4.isTerrainPopulated = true; + + if (this.serverChunkGenerator != null) { + this.serverChunkGenerator.populate(par1IChunkProvider, par2, par3); + var4.setChunkModified(); + } + } + } + + /** + * Two modes of operation: if passed true, save all Chunks in one go. If passed + * false, save up to two chunks. Return true if all chunks have been saved. + */ + public boolean saveChunks(boolean par1, IProgressUpdate par2IProgressUpdate) { + int var3 = 0; + + for (int var4 = 0; var4 < this.loadedChunks.size(); ++var4) { + Chunk var5 = (Chunk) this.loadedChunks.get(var4); + + if (par1) { + this.saveChunkExtraData(var5); + } + + if (var5.needsSaving(par1)) { + this.saveChunkData(var5); + var5.isModified = false; + ++var3; + + if (var3 == 24 && !par1) { + return false; + } + } + } + + return true; + } + + public void func_104112_b() { + if (this.chunkLoader != null) { + this.chunkLoader.saveExtraData(); + } + } + + /** + * Unloads chunks that are marked to be unloaded. This is not guaranteed to + * unload every such chunk. + */ + public boolean unloadQueuedChunks() { + if (!this.worldObj.levelSaving) { + for (int var1 = 0; var1 < 100; ++var1) { + if (!this.droppedChunksSet.isEmpty()) { + Long var2 = (Long) this.droppedChunksSet.iterator().next(); + Chunk var3 = (Chunk) this.id2ChunkMap.getValueByKey(var2.longValue()); + var3.onChunkUnload(); + this.saveChunkData(var3); + this.saveChunkExtraData(var3); + this.droppedChunksSet.remove(var2); + this.id2ChunkMap.remove(var2.longValue()); + this.loadedChunks.remove(var3); + } + } + + if (this.chunkLoader != null) { + this.chunkLoader.chunkTick(); + } + } + + return this.serverChunkGenerator.unloadQueuedChunks(); + } + + /** + * Returns if the IChunkProvider supports saving. + */ + public boolean canSave() { + return !this.worldObj.levelSaving; + } + + /** + * Converts the instance data to a readable string. + */ + public String makeString() { + return "ServerChunkCache: " + this.id2ChunkMap.getNumHashElements() + " Drop: " + this.droppedChunksSet.size(); + } + + /** + * Returns a list of creatures of the specified type that can spawn at the given + * location. + */ + public List getPossibleCreatures(EnumCreatureType par1EnumCreatureType, int par2, int par3, int par4) { + return this.serverChunkGenerator.getPossibleCreatures(par1EnumCreatureType, par2, par3, par4); + } + + /** + * Returns the location of the closest structure of the specified type. If not + * found returns null. + */ + public ChunkPosition findClosestStructure(World par1World, String par2Str, int par3, int par4, int par5) { + return this.serverChunkGenerator.findClosestStructure(par1World, par2Str, par3, par4, par5); + } + + public int getLoadedChunkCount() { + return this.id2ChunkMap.getNumHashElements(); + } + + public void recreateStructures(int par1, int par2) { + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CombatEntry.java b/sp-server/src/main/java/net/minecraft/src/CombatEntry.java new file mode 100644 index 0000000..b0535f9 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CombatEntry.java @@ -0,0 +1,44 @@ +package net.minecraft.src; + +public class CombatEntry { + private final DamageSource field_94569_a; + private final int field_94567_b; + private final int field_94568_c; + private final int field_94565_d; + private final String field_94566_e; + private final float field_94564_f; + + public CombatEntry(DamageSource par1DamageSource, int par2, int par3, int par4, String par5Str, float par6) { + this.field_94569_a = par1DamageSource; + this.field_94567_b = par2; + this.field_94568_c = par4; + this.field_94565_d = par3; + this.field_94566_e = par5Str; + this.field_94564_f = par6; + } + + public DamageSource func_94560_a() { + return this.field_94569_a; + } + + public int func_94563_c() { + return this.field_94568_c; + } + + public boolean func_94559_f() { + return this.field_94569_a.getEntity() instanceof EntityLiving; + } + + public String func_94562_g() { + return this.field_94566_e; + } + + public String func_94558_h() { + return this.func_94560_a().getEntity() == null ? null + : this.func_94560_a().getEntity().getTranslatedEntityName(); + } + + public float func_94561_i() { + return this.field_94569_a == DamageSource.outOfWorld ? Float.MAX_VALUE : this.field_94564_f; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CombatTracker.java b/sp-server/src/main/java/net/minecraft/src/CombatTracker.java new file mode 100644 index 0000000..6ea9ac0 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CombatTracker.java @@ -0,0 +1,181 @@ +package net.minecraft.src; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +public class CombatTracker { + private final List field_94556_a = new ArrayList(); + private final EntityLiving field_94554_b; + private int field_94555_c = 0; + private boolean field_94552_d = false; + private boolean field_94553_e = false; + private String field_94551_f; + + public CombatTracker(EntityLiving par1EntityLiving) { + this.field_94554_b = par1EntityLiving; + } + + public void func_94545_a() { + this.func_94542_g(); + + if (this.field_94554_b.isOnLadder()) { + int var1 = this.field_94554_b.worldObj.getBlockId(MathHelper.floor_double(this.field_94554_b.posX), + MathHelper.floor_double(this.field_94554_b.boundingBox.minY), + MathHelper.floor_double(this.field_94554_b.posZ)); + + if (var1 == Block.ladder.blockID) { + this.field_94551_f = "ladder"; + } else if (var1 == Block.vine.blockID) { + this.field_94551_f = "vines"; + } + } else if (this.field_94554_b.isInWater()) { + this.field_94551_f = "water"; + } + } + + public void func_94547_a(DamageSource par1DamageSource, int par2, int par3) { + this.func_94549_h(); + this.func_94545_a(); + CombatEntry var4 = new CombatEntry(par1DamageSource, this.field_94554_b.ticksExisted, par2, par3, + this.field_94551_f, this.field_94554_b.fallDistance); + this.field_94556_a.add(var4); + this.field_94555_c = this.field_94554_b.ticksExisted; + this.field_94553_e = true; + this.field_94552_d |= var4.func_94559_f(); + } + + public String func_94546_b() { + if (this.field_94556_a.size() == 0) { + return this.field_94554_b.getTranslatedEntityName() + " died"; + } else { + CombatEntry var1 = this.func_94544_f(); + CombatEntry var2 = (CombatEntry) this.field_94556_a.get(this.field_94556_a.size() - 1); + String var3 = ""; + String var4 = var2.func_94558_h(); + Entity var5 = var2.func_94560_a().getEntity(); + + if (var1 != null && var2.func_94560_a() == DamageSource.fall) { + String var6 = var1.func_94558_h(); + + if (var1.func_94560_a() != DamageSource.fall && var1.func_94560_a() != DamageSource.outOfWorld) { + if (var6 != null && (var4 == null || !var6.equals(var4))) { + Entity var9 = var1.func_94560_a().getEntity(); + ItemStack var8 = var9 instanceof EntityLiving ? ((EntityLiving) var9).getHeldItem() : null; + + if (var8 != null && var8.hasDisplayName()) { + var3 = StatCollector.translateToLocalFormatted("death.fell.assist.item", new Object[] { + this.field_94554_b.getTranslatedEntityName(), var4, var8.getDisplayName() }); + } else { + var3 = StatCollector.translateToLocalFormatted("death.fell.assist", + new Object[] { this.field_94554_b.getTranslatedEntityName(), var6 }); + } + } else if (var4 != null) { + ItemStack var7 = var5 instanceof EntityLiving ? ((EntityLiving) var5).getHeldItem() : null; + + if (var7 != null && var7.hasDisplayName()) { + var3 = StatCollector.translateToLocalFormatted("death.fell.finish.item", new Object[] { + this.field_94554_b.getTranslatedEntityName(), var4, var7.getDisplayName() }); + } else { + var3 = StatCollector.translateToLocalFormatted("death.fell.finish", + new Object[] { this.field_94554_b.getTranslatedEntityName(), var4 }); + } + } else { + var3 = StatCollector.translateToLocalFormatted("death.fell.killer", + new Object[] { this.field_94554_b.getTranslatedEntityName() }); + } + } else { + var3 = StatCollector.translateToLocalFormatted("death.fell.accident." + this.func_94548_b(var1), + new Object[] { this.field_94554_b.getTranslatedEntityName() }); + } + } else { + var3 = var2.func_94560_a().getDeathMessage(this.field_94554_b); + } + + return var3; + } + } + + public EntityLiving func_94550_c() { + EntityLiving var1 = null; + EntityPlayer var2 = null; + int var3 = 0; + int var4 = 0; + Iterator var5 = this.field_94556_a.iterator(); + + while (var5.hasNext()) { + CombatEntry var6 = (CombatEntry) var5.next(); + + if (var6.func_94560_a().getEntity() instanceof EntityPlayer + && (var2 == null || var6.func_94563_c() > var4)) { + var4 = var6.func_94563_c(); + var2 = (EntityPlayer) var6.func_94560_a().getEntity(); + } + + if (var6.func_94560_a().getEntity() instanceof EntityLiving + && (var1 == null || var6.func_94563_c() > var3)) { + var3 = var6.func_94563_c(); + var1 = (EntityLiving) var6.func_94560_a().getEntity(); + } + } + + if (var2 != null && var4 >= var3 / 3) { + return var2; + } else { + return var1; + } + } + + private CombatEntry func_94544_f() { + CombatEntry var1 = null; + CombatEntry var2 = null; + byte var3 = 0; + float var4 = 0.0F; + + for (int var5 = 0; var5 < this.field_94556_a.size(); ++var5) { + CombatEntry var6 = (CombatEntry) this.field_94556_a.get(var5); + CombatEntry var7 = var5 > 0 ? (CombatEntry) this.field_94556_a.get(var5 - 1) : null; + + if ((var6.func_94560_a() == DamageSource.fall || var6.func_94560_a() == DamageSource.outOfWorld) + && var6.func_94561_i() > 0.0F && (var1 == null || var6.func_94561_i() > var4)) { + if (var5 > 0) { + var1 = var7; + } else { + var1 = var6; + } + + var4 = var6.func_94561_i(); + } + + if (var6.func_94562_g() != null && (var2 == null || var6.func_94563_c() > var3)) { + var2 = var6; + } + } + + if (var4 > 5.0F && var1 != null) { + return var1; + } else if (var3 > 5 && var2 != null) { + return var2; + } else { + return null; + } + } + + private String func_94548_b(CombatEntry par1CombatEntry) { + return par1CombatEntry.func_94562_g() == null ? "generic" : par1CombatEntry.func_94562_g(); + } + + private void func_94542_g() { + this.field_94551_f = null; + } + + private void func_94549_h() { + int var1 = this.field_94552_d ? 300 : 100; + + if (this.field_94553_e && this.field_94554_b.ticksExisted - this.field_94555_c > var1) { + this.field_94556_a.clear(); + this.field_94553_e = false; + this.field_94552_d = false; + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CommandBase.java b/sp-server/src/main/java/net/minecraft/src/CommandBase.java new file mode 100644 index 0000000..84a46e2 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CommandBase.java @@ -0,0 +1,272 @@ +package net.minecraft.src; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import net.minecraft.server.MinecraftServer; + +public abstract class CommandBase implements ICommand { + private static IAdminCommand theAdmin = null; + + /** + * Return the required permission level for this command. + */ + public int getRequiredPermissionLevel() { + return 4; + } + + public String getCommandUsage(ICommandSender par1ICommandSender) { + return "/" + this.getCommandName(); + } + + public List getCommandAliases() { + return null; + } + + /** + * Returns true if the given command sender is allowed to use this command. + */ + public boolean canCommandSenderUseCommand(ICommandSender par1ICommandSender) { + return par1ICommandSender.canCommandSenderUseCommand(this.getRequiredPermissionLevel(), this.getCommandName()); + } + + /** + * Adds the strings available in this command to the given list of tab + * completion options. + */ + public List addTabCompletionOptions(ICommandSender par1ICommandSender, String[] par2ArrayOfStr) { + return null; + } + + /** + * Parses an int from the given string. + */ + public static int parseInt(ICommandSender par0ICommandSender, String par1Str) { + try { + return Integer.parseInt(par1Str); + } catch (NumberFormatException var3) { + throw new NumberInvalidException("commands.generic.num.invalid", new Object[] { par1Str }); + } + } + + /** + * Parses an int from the given sring with a specified minimum. + */ + public static int parseIntWithMin(ICommandSender par0ICommandSender, String par1Str, int par2) { + return parseIntBounded(par0ICommandSender, par1Str, par2, Integer.MAX_VALUE); + } + + /** + * Parses an int from the given string within a specified bound. + */ + public static int parseIntBounded(ICommandSender par0ICommandSender, String par1Str, int par2, int par3) { + int var4 = parseInt(par0ICommandSender, par1Str); + + if (var4 < par2) { + throw new NumberInvalidException("commands.generic.num.tooSmall", + new Object[] { Integer.valueOf(var4), Integer.valueOf(par2) }); + } else if (var4 > par3) { + throw new NumberInvalidException("commands.generic.num.tooBig", + new Object[] { Integer.valueOf(var4), Integer.valueOf(par3) }); + } else { + return var4; + } + } + + /** + * Parses a double from the given string or throws an exception if it's not a + * double. + */ + public static double parseDouble(ICommandSender par0ICommandSender, String par1Str) { + try { + return Double.parseDouble(par1Str); + } catch (NumberFormatException var3) { + throw new NumberInvalidException("commands.generic.double.invalid", new Object[] { par1Str }); + } + } + + /** + * Returns the given ICommandSender as a EntityPlayer or throw an exception. + */ + public static EntityPlayerMP getCommandSenderAsPlayer(ICommandSender par0ICommandSender) { + if (par0ICommandSender instanceof EntityPlayerMP) { + return (EntityPlayerMP) par0ICommandSender; + } else { + throw new PlayerNotFoundException("You must specify which player you wish to perform this action on.", + new Object[0]); + } + } + + public static EntityPlayerMP func_82359_c(ICommandSender par0ICommandSender, String par1Str) { + EntityPlayerMP var2 = PlayerSelector.matchOnePlayer(par0ICommandSender, par1Str); + + if (var2 != null) { + return var2; + } else { + var2 = MinecraftServer.getServer().getConfigurationManager().getPlayerEntity(par1Str); + + if (var2 == null) { + throw new PlayerNotFoundException(); + } else { + return var2; + } + } + } + + public static String func_96332_d(ICommandSender par0ICommandSender, String par1Str) { + EntityPlayerMP var2 = PlayerSelector.matchOnePlayer(par0ICommandSender, par1Str); + + if (var2 != null) { + return var2.getEntityName(); + } else if (PlayerSelector.hasArguments(par1Str)) { + throw new PlayerNotFoundException(); + } else { + return par1Str; + } + } + + public static String func_82360_a(ICommandSender par0ICommandSender, String[] par1ArrayOfStr, int par2) { + return func_82361_a(par0ICommandSender, par1ArrayOfStr, par2, false); + } + + public static String func_82361_a(ICommandSender par0ICommandSender, String[] par1ArrayOfStr, int par2, + boolean par3) { + StringBuilder var4 = new StringBuilder(); + + for (int var5 = par2; var5 < par1ArrayOfStr.length; ++var5) { + if (var5 > par2) { + var4.append(" "); + } + + String var6 = par1ArrayOfStr[var5]; + + if (par3) { + String var7 = PlayerSelector.matchPlayersAsString(par0ICommandSender, var6); + + if (var7 != null) { + var6 = var7; + } else if (PlayerSelector.hasArguments(var6)) { + throw new PlayerNotFoundException(); + } + } + + var4.append(var6); + } + + return var4.toString(); + } + + /** + * Joins the given string array into a "x, y, and z" seperated string. + */ + public static String joinNiceString(Object[] par0ArrayOfObj) { + StringBuilder var1 = new StringBuilder(); + + for (int var2 = 0; var2 < par0ArrayOfObj.length; ++var2) { + String var3 = par0ArrayOfObj[var2].toString(); + + if (var2 > 0) { + if (var2 == par0ArrayOfObj.length - 1) { + var1.append(" and "); + } else { + var1.append(", "); + } + } + + var1.append(var3); + } + + return var1.toString(); + } + + public static String func_96333_a(Collection par0Collection) { + return joinNiceString(par0Collection.toArray(new String[0])); + } + + /** + * Returns true if the given substring is exactly equal to the start of the + * given string (case insensitive). + */ + public static boolean doesStringStartWith(String par0Str, String par1Str) { + return par1Str.regionMatches(true, 0, par0Str, 0, par0Str.length()); + } + + /** + * Returns a List of strings (chosen from the given strings) which the last word + * in the given string array is a beginning-match for. (Tab completion). + */ + public static List getListOfStringsMatchingLastWord(String[] par0ArrayOfStr, String... par1ArrayOfStr) { + String var2 = par0ArrayOfStr[par0ArrayOfStr.length - 1]; + ArrayList var3 = new ArrayList(); + String[] var4 = par1ArrayOfStr; + int var5 = par1ArrayOfStr.length; + + for (int var6 = 0; var6 < var5; ++var6) { + String var7 = var4[var6]; + + if (doesStringStartWith(var2, var7)) { + var3.add(var7); + } + } + + return var3; + } + + /** + * Returns a List of strings (chosen from the given string iterable) which the + * last word in the given string array is a beginning-match for. (Tab + * completion). + */ + public static List getListOfStringsFromIterableMatchingLastWord(String[] par0ArrayOfStr, Iterable par1Iterable) { + String var2 = par0ArrayOfStr[par0ArrayOfStr.length - 1]; + ArrayList var3 = new ArrayList(); + Iterator var4 = par1Iterable.iterator(); + + while (var4.hasNext()) { + String var5 = (String) var4.next(); + + if (doesStringStartWith(var2, var5)) { + var3.add(var5); + } + } + + return var3; + } + + /** + * Return whether the specified command parameter index is a username parameter. + */ + public boolean isUsernameIndex(String[] par1ArrayOfStr, int par2) { + return false; + } + + public static void notifyAdmins(ICommandSender par0ICommandSender, String par1Str, Object... par2ArrayOfObj) { + notifyAdmins(par0ICommandSender, 0, par1Str, par2ArrayOfObj); + } + + public static void notifyAdmins(ICommandSender par0ICommandSender, int par1, String par2Str, + Object... par3ArrayOfObj) { + if (theAdmin != null) { + theAdmin.notifyAdmins(par0ICommandSender, par1, par2Str, par3ArrayOfObj); + } + } + + /** + * Sets the static IAdminCommander. + */ + public static void setAdminCommander(IAdminCommand par0IAdminCommand) { + theAdmin = par0IAdminCommand; + } + + /** + * Compares the name of this command to the name of the given command. + */ + public int compareTo(ICommand par1ICommand) { + return this.getCommandName().compareTo(par1ICommand.getCommandName()); + } + + public int compareTo(Object par1Obj) { + return this.compareTo((ICommand) par1Obj); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CommandClearInventory.java b/sp-server/src/main/java/net/minecraft/src/CommandClearInventory.java new file mode 100644 index 0000000..a7aa13c --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CommandClearInventory.java @@ -0,0 +1,61 @@ +package net.minecraft.src; + +import java.util.List; +import net.minecraft.server.MinecraftServer; + +public class CommandClearInventory extends CommandBase { + public String getCommandName() { + return "clear"; + } + + public String getCommandUsage(ICommandSender par1ICommandSender) { + return par1ICommandSender.translateString("commands.clear.usage", new Object[0]); + } + + /** + * Return the required permission level for this command. + */ + public int getRequiredPermissionLevel() { + return 2; + } + + public void processCommand(ICommandSender par1ICommandSender, String[] par2ArrayOfStr) { + EntityPlayerMP var3 = par2ArrayOfStr.length == 0 ? getCommandSenderAsPlayer(par1ICommandSender) + : func_82359_c(par1ICommandSender, par2ArrayOfStr[0]); + int var4 = par2ArrayOfStr.length >= 2 ? parseIntWithMin(par1ICommandSender, par2ArrayOfStr[1], 1) : -1; + int var5 = par2ArrayOfStr.length >= 3 ? parseIntWithMin(par1ICommandSender, par2ArrayOfStr[2], 0) : -1; + int var6 = var3.inventory.clearInventory(var4, var5); + var3.inventoryContainer.detectAndSendChanges(); + + if (var6 == 0) { + throw new CommandException("commands.clear.failure", new Object[] { var3.getEntityName() }); + } else { + notifyAdmins(par1ICommandSender, "commands.clear.success", + new Object[] { var3.getEntityName(), Integer.valueOf(var6) }); + } + } + + /** + * Adds the strings available in this command to the given list of tab + * completion options. + */ + public List addTabCompletionOptions(ICommandSender par1ICommandSender, String[] par2ArrayOfStr) { + return par2ArrayOfStr.length == 1 + ? getListOfStringsMatchingLastWord(par2ArrayOfStr, this.getAllOnlineUsernames()) + : null; + } + + /** + * Return all usernames currently connected to the server. + */ + protected String[] getAllOnlineUsernames() { + return MinecraftServer.getServer().getAllUsernames(); + } + + /** + * Return whether the specified command parameter index is a username parameter. + */ + public boolean isUsernameIndex(String[] par1ArrayOfStr, int par2) { + return par2 == 0; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CommandDebug.java b/sp-server/src/main/java/net/minecraft/src/CommandDebug.java new file mode 100644 index 0000000..a1d6dbd --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CommandDebug.java @@ -0,0 +1,147 @@ +package net.minecraft.src; + +import java.io.File; +import java.io.FileWriter; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.List; +import net.minecraft.server.MinecraftServer; + +public class CommandDebug extends CommandBase { + /** Time the debugging started in milliseconds. */ + private long startTime = 0L; + + /** The number of ticks when debugging started. */ + private int startTicks = 0; + + public String getCommandName() { + return "debug"; + } + + /** + * Return the required permission level for this command. + */ + public int getRequiredPermissionLevel() { + return 3; + } + + public void processCommand(ICommandSender par1ICommandSender, String[] par2ArrayOfStr) { + if (par2ArrayOfStr.length == 1) { + if (par2ArrayOfStr[0].equals("start")) { + notifyAdmins(par1ICommandSender, "commands.debug.start", new Object[0]); + MinecraftServer.getServer().enableProfiling(); + this.startTime = System.currentTimeMillis(); + this.startTicks = MinecraftServer.getServer().getTickCounter(); + return; + } + + if (par2ArrayOfStr[0].equals("stop")) { + if (!MinecraftServer.getServer().theProfiler.profilingEnabled) { + throw new CommandException("commands.debug.notStarted", new Object[0]); + } + + long var3 = System.currentTimeMillis(); + int var5 = MinecraftServer.getServer().getTickCounter(); + long var6 = var3 - this.startTime; + int var8 = var5 - this.startTicks; + this.saveProfilerResults(var6, var8); + MinecraftServer.getServer().theProfiler.profilingEnabled = false; + notifyAdmins(par1ICommandSender, "commands.debug.stop", + new Object[] { Float.valueOf((float) var6 / 1000.0F), Integer.valueOf(var8) }); + return; + } + } + + throw new WrongUsageException("commands.debug.usage", new Object[0]); + } + + private void saveProfilerResults(long par1, int par3) { + File var4 = new File(MinecraftServer.getServer().getFile("debug"), + "profile-results-" + (new SimpleDateFormat("yyyy-MM-dd_HH.mm.ss")).format(new Date()) + ".txt"); + var4.getParentFile().mkdirs(); + + try { + FileWriter var5 = new FileWriter(var4); + var5.write(this.getProfilerResults(par1, par3)); + var5.close(); + } catch (Throwable var6) { + MinecraftServer.getServer().getLogAgent().logSevereException("Could not save profiler results to " + var4, + var6); + } + } + + private String getProfilerResults(long par1, int par3) { + StringBuilder var4 = new StringBuilder(); + var4.append("---- Minecraft Profiler Results ----\n"); + var4.append("// "); + var4.append(getWittyComment()); + var4.append("\n\n"); + var4.append("Time span: ").append(par1).append(" ms\n"); + var4.append("Tick span: ").append(par3).append(" ticks\n"); + var4.append("// This is approximately ") + .append(String.format("%.2f", new Object[] { Float.valueOf((float) par3 / ((float) par1 / 1000.0F)) })) + .append(" ticks per second. It should be ").append(20).append(" ticks per second\n\n"); + var4.append("--- BEGIN PROFILE DUMP ---\n\n"); + this.getProfileDump(0, "root", var4); + var4.append("--- END PROFILE DUMP ---\n\n"); + return var4.toString(); + } + + private void getProfileDump(int par1, String par2Str, StringBuilder par3StringBuilder) { + List var4 = MinecraftServer.getServer().theProfiler.getProfilingData(par2Str); + + if (var4 != null && var4.size() >= 3) { + for (int var5 = 1; var5 < var4.size(); ++var5) { + ProfilerResult var6 = (ProfilerResult) var4.get(var5); + par3StringBuilder.append(String.format("[%02d] ", new Object[] { Integer.valueOf(par1) })); + + for (int var7 = 0; var7 < par1; ++var7) { + par3StringBuilder.append(" "); + } + + par3StringBuilder.append(var6.field_76331_c); + par3StringBuilder.append(" - "); + par3StringBuilder.append(String.format("%.2f", new Object[] { Double.valueOf(var6.field_76332_a) })); + par3StringBuilder.append("%/"); + par3StringBuilder.append(String.format("%.2f", new Object[] { Double.valueOf(var6.field_76330_b) })); + par3StringBuilder.append("%\n"); + + if (!var6.field_76331_c.equals("unspecified")) { + try { + this.getProfileDump(par1 + 1, par2Str + "." + var6.field_76331_c, par3StringBuilder); + } catch (Exception var8) { + par3StringBuilder.append("[[ EXCEPTION " + var8 + " ]]"); + } + } + } + } + } + + /** + * Returns a random "witty" comment. + */ + private static String getWittyComment() { + String[] var0 = new String[] { "Shiny numbers!", "Am I not running fast enough? :(", + "I\'m working as hard as I can!", "Will I ever be good enough for you? :(", "Speedy. Zoooooom!", + "Hello world", "40% better than a crash report.", "Now with extra numbers", "Now with less numbers", + "Now with the same numbers", "You should add flames to things, it makes them go faster!", + "Do you feel the need for... optimization?", "*cracks redstone whip*", + "Maybe if you treated it better then it\'ll have more motivation to work faster! Poor server." }; + + try { + return var0[(int) (System.nanoTime() % (long) var0.length)]; + } catch (Throwable var2) { + return "Witty comment unavailable :("; + } + } + + /** + * Adds the strings available in this command to the given list of tab + * completion options. + */ + public List addTabCompletionOptions(ICommandSender par1ICommandSender, String[] par2ArrayOfStr) { + return par2ArrayOfStr.length == 1 + ? getListOfStringsMatchingLastWord(par2ArrayOfStr, new String[] { "start", "stop" }) + : null; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CommandDefaultGameMode.java b/sp-server/src/main/java/net/minecraft/src/CommandDefaultGameMode.java new file mode 100644 index 0000000..ae889a8 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CommandDefaultGameMode.java @@ -0,0 +1,28 @@ +package net.minecraft.src; + +import net.minecraft.server.MinecraftServer; + +public class CommandDefaultGameMode extends CommandGameMode { + public String getCommandName() { + return "defaultgamemode"; + } + + public String getCommandUsage(ICommandSender par1ICommandSender) { + return par1ICommandSender.translateString("commands.defaultgamemode.usage", new Object[0]); + } + + public void processCommand(ICommandSender par1ICommandSender, String[] par2ArrayOfStr) { + if (par2ArrayOfStr.length > 0) { + EnumGameType var3 = this.getGameModeFromCommand(par1ICommandSender, par2ArrayOfStr[0]); + this.setGameType(var3); + String var4 = StatCollector.translateToLocal("gameMode." + var3.getName()); + notifyAdmins(par1ICommandSender, "commands.defaultgamemode.success", new Object[] { var4 }); + } else { + throw new WrongUsageException("commands.defaultgamemode.usage", new Object[0]); + } + } + + protected void setGameType(EnumGameType par1EnumGameType) { + MinecraftServer.getServer().setGameType(par1EnumGameType); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CommandDifficulty.java b/sp-server/src/main/java/net/minecraft/src/CommandDifficulty.java new file mode 100644 index 0000000..7409b01 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CommandDifficulty.java @@ -0,0 +1,63 @@ +package net.minecraft.src; + +import java.util.List; +import net.minecraft.server.MinecraftServer; + +public class CommandDifficulty extends CommandBase { + private static final String[] difficulties = new String[] { "options.difficulty.peaceful", + "options.difficulty.easy", "options.difficulty.normal", "options.difficulty.hard" }; + + public String getCommandName() { + return "difficulty"; + } + + /** + * Return the required permission level for this command. + */ + public int getRequiredPermissionLevel() { + return 2; + } + + public String getCommandUsage(ICommandSender par1ICommandSender) { + return par1ICommandSender.translateString("commands.difficulty.usage", new Object[0]); + } + + public void processCommand(ICommandSender par1ICommandSender, String[] par2ArrayOfStr) { + if (par2ArrayOfStr.length > 0) { + int var3 = this.getDifficultyForName(par1ICommandSender, par2ArrayOfStr[0]); + MinecraftServer.getServer().setDifficultyForAllWorlds(var3); + String var4 = StatCollector.translateToLocal(difficulties[var3]); + notifyAdmins(par1ICommandSender, "commands.difficulty.success", new Object[] { var4 }); + } else { + throw new WrongUsageException("commands.difficulty.usage", new Object[0]); + } + } + + /** + * Return the difficulty value for the specified string. + */ + protected int getDifficultyForName(ICommandSender par1ICommandSender, String par2Str) { + return !par2Str.equalsIgnoreCase("peaceful") + && !par2Str.equalsIgnoreCase("p") + ? (!par2Str.equalsIgnoreCase("easy") + && !par2Str.equalsIgnoreCase("e") + ? (!par2Str.equalsIgnoreCase("normal") && !par2Str.equalsIgnoreCase("n") + ? (!par2Str.equalsIgnoreCase("hard") && !par2Str.equalsIgnoreCase("h") + ? parseIntBounded(par1ICommandSender, par2Str, 0, 3) + : 3) + : 2) + : 1) + : 0; + } + + /** + * Adds the strings available in this command to the given list of tab + * completion options. + */ + public List addTabCompletionOptions(ICommandSender par1ICommandSender, String[] par2ArrayOfStr) { + return par2ArrayOfStr.length == 1 + ? getListOfStringsMatchingLastWord(par2ArrayOfStr, + new String[] { "peaceful", "easy", "normal", "hard" }) + : null; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CommandEffect.java b/sp-server/src/main/java/net/minecraft/src/CommandEffect.java new file mode 100644 index 0000000..184dbc1 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CommandEffect.java @@ -0,0 +1,91 @@ +package net.minecraft.src; + +import java.util.List; +import net.minecraft.server.MinecraftServer; + +public class CommandEffect extends CommandBase { + public String getCommandName() { + return "effect"; + } + + /** + * Return the required permission level for this command. + */ + public int getRequiredPermissionLevel() { + return 2; + } + + public String getCommandUsage(ICommandSender par1ICommandSender) { + return par1ICommandSender.translateString("commands.effect.usage", new Object[0]); + } + + public void processCommand(ICommandSender par1ICommandSender, String[] par2ArrayOfStr) { + if (par2ArrayOfStr.length >= 2) { + EntityPlayerMP var3 = func_82359_c(par1ICommandSender, par2ArrayOfStr[0]); + int var4 = parseIntWithMin(par1ICommandSender, par2ArrayOfStr[1], 1); + int var5 = 600; + int var6 = 30; + int var7 = 0; + + if (var4 >= 0 && var4 < Potion.potionTypes.length && Potion.potionTypes[var4] != null) { + if (par2ArrayOfStr.length >= 3) { + var6 = parseIntBounded(par1ICommandSender, par2ArrayOfStr[2], 0, 1000000); + + if (Potion.potionTypes[var4].isInstant()) { + var5 = var6; + } else { + var5 = var6 * 20; + } + } else if (Potion.potionTypes[var4].isInstant()) { + var5 = 1; + } + + if (par2ArrayOfStr.length >= 4) { + var7 = parseIntBounded(par1ICommandSender, par2ArrayOfStr[3], 0, 255); + } + + if (var6 == 0) { + if (!var3.isPotionActive(var4)) { + throw new CommandException("commands.effect.failure.notActive", + new Object[] { StatCollector.translateToLocal(Potion.potionTypes[var4].getName()), + var3.getEntityName() }); + } + + var3.removePotionEffect(var4); + notifyAdmins(par1ICommandSender, "commands.effect.success.removed", new Object[] { + StatCollector.translateToLocal(Potion.potionTypes[var4].getName()), var3.getEntityName() }); + } else { + PotionEffect var8 = new PotionEffect(var4, var5, var7); + var3.addPotionEffect(var8); + notifyAdmins(par1ICommandSender, "commands.effect.success", + new Object[] { StatCollector.translateToLocal(var8.getEffectName()), Integer.valueOf(var4), + Integer.valueOf(var7), var3.getEntityName(), Integer.valueOf(var6) }); + } + } else { + throw new NumberInvalidException("commands.effect.notFound", new Object[] { Integer.valueOf(var4) }); + } + } else { + throw new WrongUsageException("commands.effect.usage", new Object[0]); + } + } + + /** + * Adds the strings available in this command to the given list of tab + * completion options. + */ + public List addTabCompletionOptions(ICommandSender par1ICommandSender, String[] par2ArrayOfStr) { + return par2ArrayOfStr.length == 1 ? getListOfStringsMatchingLastWord(par2ArrayOfStr, this.getAllUsernames()) + : null; + } + + protected String[] getAllUsernames() { + return MinecraftServer.getServer().getAllUsernames(); + } + + /** + * Return whether the specified command parameter index is a username parameter. + */ + public boolean isUsernameIndex(String[] par1ArrayOfStr, int par2) { + return par2 == 0; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CommandEnchant.java b/sp-server/src/main/java/net/minecraft/src/CommandEnchant.java new file mode 100644 index 0000000..2127a37 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CommandEnchant.java @@ -0,0 +1,95 @@ +package net.minecraft.src; + +import java.util.List; +import net.minecraft.server.MinecraftServer; + +public class CommandEnchant extends CommandBase { + public String getCommandName() { + return "enchant"; + } + + /** + * Return the required permission level for this command. + */ + public int getRequiredPermissionLevel() { + return 2; + } + + public String getCommandUsage(ICommandSender par1ICommandSender) { + return par1ICommandSender.translateString("commands.enchant.usage", new Object[0]); + } + + public void processCommand(ICommandSender par1ICommandSender, String[] par2ArrayOfStr) { + if (par2ArrayOfStr.length < 2) { + throw new WrongUsageException("commands.enchant.usage", new Object[0]); + } else { + EntityPlayerMP var3 = func_82359_c(par1ICommandSender, par2ArrayOfStr[0]); + int var4 = parseIntBounded(par1ICommandSender, par2ArrayOfStr[1], 0, + Enchantment.enchantmentsList.length - 1); + int var5 = 1; + ItemStack var6 = var3.getCurrentEquippedItem(); + + if (var6 == null) { + notifyAdmins(par1ICommandSender, "commands.enchant.noItem", new Object[0]); + } else { + Enchantment var7 = Enchantment.enchantmentsList[var4]; + + if (var7 == null) { + throw new NumberInvalidException("commands.enchant.notFound", + new Object[] { Integer.valueOf(var4) }); + } else if (!var7.func_92089_a(var6)) { + notifyAdmins(par1ICommandSender, "commands.enchant.cantEnchant", new Object[0]); + } else { + if (par2ArrayOfStr.length >= 3) { + var5 = parseIntBounded(par1ICommandSender, par2ArrayOfStr[2], var7.getMinLevel(), + var7.getMaxLevel()); + } + + if (var6.hasTagCompound()) { + NBTTagList var8 = var6.getEnchantmentTagList(); + + if (var8 != null) { + for (int var9 = 0; var9 < var8.tagCount(); ++var9) { + short var10 = ((NBTTagCompound) var8.tagAt(var9)).getShort("id"); + + if (Enchantment.enchantmentsList[var10] != null) { + Enchantment var11 = Enchantment.enchantmentsList[var10]; + + if (!var11.canApplyTogether(var7)) { + notifyAdmins(par1ICommandSender, "commands.enchant.cantCombine", + new Object[] { var7.getTranslatedName(var5), var11.getTranslatedName( + ((NBTTagCompound) var8.tagAt(var9)).getShort("lvl")) }); + return; + } + } + } + } + } + + var6.addEnchantment(var7, var5); + notifyAdmins(par1ICommandSender, "commands.enchant.success", new Object[0]); + } + } + } + } + + /** + * Adds the strings available in this command to the given list of tab + * completion options. + */ + public List addTabCompletionOptions(ICommandSender par1ICommandSender, String[] par2ArrayOfStr) { + return par2ArrayOfStr.length == 1 ? getListOfStringsMatchingLastWord(par2ArrayOfStr, this.getListOfPlayers()) + : null; + } + + protected String[] getListOfPlayers() { + return MinecraftServer.getServer().getAllUsernames(); + } + + /** + * Return whether the specified command parameter index is a username parameter. + */ + public boolean isUsernameIndex(String[] par1ArrayOfStr, int par2) { + return par2 == 0; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CommandException.java b/sp-server/src/main/java/net/minecraft/src/CommandException.java new file mode 100644 index 0000000..3e6b25a --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CommandException.java @@ -0,0 +1,14 @@ +package net.minecraft.src; + +public class CommandException extends RuntimeException { + private Object[] errorObjects; + + public CommandException(String par1Str, Object... par2ArrayOfObj) { + super(par1Str); + this.errorObjects = par2ArrayOfObj; + } + + public Object[] getErrorOjbects() { + return this.errorObjects; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CommandGameMode.java b/sp-server/src/main/java/net/minecraft/src/CommandGameMode.java new file mode 100644 index 0000000..31b8d7b --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CommandGameMode.java @@ -0,0 +1,81 @@ +package net.minecraft.src; + +import java.util.List; +import net.minecraft.server.MinecraftServer; + +public class CommandGameMode extends CommandBase { + public String getCommandName() { + return "gamemode"; + } + + /** + * Return the required permission level for this command. + */ + public int getRequiredPermissionLevel() { + return 2; + } + + public String getCommandUsage(ICommandSender par1ICommandSender) { + return par1ICommandSender.translateString("commands.gamemode.usage", new Object[0]); + } + + public void processCommand(ICommandSender par1ICommandSender, String[] par2ArrayOfStr) { + if (par2ArrayOfStr.length > 0) { + EnumGameType var3 = this.getGameModeFromCommand(par1ICommandSender, par2ArrayOfStr[0]); + EntityPlayerMP var4 = par2ArrayOfStr.length >= 2 ? func_82359_c(par1ICommandSender, par2ArrayOfStr[1]) + : getCommandSenderAsPlayer(par1ICommandSender); + var4.setGameType(var3); + var4.fallDistance = 0.0F; + String var5 = StatCollector.translateToLocal("gameMode." + var3.getName()); + + if (var4 != par1ICommandSender) { + notifyAdmins(par1ICommandSender, 1, "commands.gamemode.success.other", + new Object[] { var4.getEntityName(), var5 }); + } else { + notifyAdmins(par1ICommandSender, 1, "commands.gamemode.success.self", new Object[] { var5 }); + } + } else { + throw new WrongUsageException("commands.gamemode.usage", new Object[0]); + } + } + + /** + * Gets the Game Mode specified in the command. + */ + protected EnumGameType getGameModeFromCommand(ICommandSender par1ICommandSender, String par2Str) { + return !par2Str.equalsIgnoreCase(EnumGameType.SURVIVAL.getName()) && !par2Str.equalsIgnoreCase("s") + ? (!par2Str.equalsIgnoreCase(EnumGameType.CREATIVE.getName()) && !par2Str.equalsIgnoreCase("c") + ? (!par2Str.equalsIgnoreCase(EnumGameType.ADVENTURE.getName()) && !par2Str.equalsIgnoreCase("a") + ? WorldSettings.getGameTypeById(parseIntBounded(par1ICommandSender, par2Str, 0, + EnumGameType.values().length - 2)) + : EnumGameType.ADVENTURE) + : EnumGameType.CREATIVE) + : EnumGameType.SURVIVAL; + } + + /** + * Adds the strings available in this command to the given list of tab + * completion options. + */ + public List addTabCompletionOptions(ICommandSender par1ICommandSender, String[] par2ArrayOfStr) { + return par2ArrayOfStr.length == 1 + ? getListOfStringsMatchingLastWord(par2ArrayOfStr, new String[] { "survival", "creative", "adventure" }) + : (par2ArrayOfStr.length == 2 + ? getListOfStringsMatchingLastWord(par2ArrayOfStr, this.getListOfPlayerUsernames()) + : null); + } + + /** + * Returns String array containing all player usernames in the server. + */ + protected String[] getListOfPlayerUsernames() { + return MinecraftServer.getServer().getAllUsernames(); + } + + /** + * Return whether the specified command parameter index is a username parameter. + */ + public boolean isUsernameIndex(String[] par1ArrayOfStr, int par2) { + return par2 == 1; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CommandGameRule.java b/sp-server/src/main/java/net/minecraft/src/CommandGameRule.java new file mode 100644 index 0000000..9aa4511 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CommandGameRule.java @@ -0,0 +1,72 @@ +package net.minecraft.src; + +import java.util.List; +import net.minecraft.server.MinecraftServer; + +public class CommandGameRule extends CommandBase { + public String getCommandName() { + return "gamerule"; + } + + /** + * Return the required permission level for this command. + */ + public int getRequiredPermissionLevel() { + return 2; + } + + public String getCommandUsage(ICommandSender par1ICommandSender) { + return par1ICommandSender.translateString("commands.gamerule.usage", new Object[0]); + } + + public void processCommand(ICommandSender par1ICommandSender, String[] par2ArrayOfStr) { + String var6; + + if (par2ArrayOfStr.length == 2) { + var6 = par2ArrayOfStr[0]; + String var7 = par2ArrayOfStr[1]; + GameRules var8 = this.getGameRules(); + + if (var8.hasRule(var6)) { + var8.setOrCreateGameRule(var6, var7); + notifyAdmins(par1ICommandSender, "commands.gamerule.success", new Object[0]); + } else { + notifyAdmins(par1ICommandSender, "commands.gamerule.norule", new Object[] { var6 }); + } + } else if (par2ArrayOfStr.length == 1) { + var6 = par2ArrayOfStr[0]; + GameRules var4 = this.getGameRules(); + + if (var4.hasRule(var6)) { + String var5 = var4.getGameRuleStringValue(var6); + par1ICommandSender.sendChatToPlayer(var6 + " = " + var5); + } else { + notifyAdmins(par1ICommandSender, "commands.gamerule.norule", new Object[] { var6 }); + } + } else if (par2ArrayOfStr.length == 0) { + GameRules var3 = this.getGameRules(); + par1ICommandSender.sendChatToPlayer(joinNiceString(var3.getRules())); + } else { + throw new WrongUsageException("commands.gamerule.usage", new Object[0]); + } + } + + /** + * Adds the strings available in this command to the given list of tab + * completion options. + */ + public List addTabCompletionOptions(ICommandSender par1ICommandSender, String[] par2ArrayOfStr) { + return par2ArrayOfStr.length == 1 + ? getListOfStringsMatchingLastWord(par2ArrayOfStr, this.getGameRules().getRules()) + : (par2ArrayOfStr.length == 2 + ? getListOfStringsMatchingLastWord(par2ArrayOfStr, new String[] { "true", "false" }) + : null); + } + + /** + * Return the game rule set this command should be able to manipulate. + */ + private GameRules getGameRules() { + return MinecraftServer.getServer().worldServerForDimension(0).getGameRules(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CommandGive.java b/sp-server/src/main/java/net/minecraft/src/CommandGive.java new file mode 100644 index 0000000..48aa876 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CommandGive.java @@ -0,0 +1,70 @@ +package net.minecraft.src; + +import java.util.List; +import net.minecraft.server.MinecraftServer; + +public class CommandGive extends CommandBase { + public String getCommandName() { + return "give"; + } + + /** + * Return the required permission level for this command. + */ + public int getRequiredPermissionLevel() { + return 2; + } + + public String getCommandUsage(ICommandSender par1ICommandSender) { + return par1ICommandSender.translateString("commands.give.usage", new Object[0]); + } + + public void processCommand(ICommandSender par1ICommandSender, String[] par2ArrayOfStr) { + if (par2ArrayOfStr.length >= 2) { + EntityPlayerMP var3 = func_82359_c(par1ICommandSender, par2ArrayOfStr[0]); + int var4 = parseIntWithMin(par1ICommandSender, par2ArrayOfStr[1], 1); + int var5 = 1; + int var6 = 0; + + if (Item.itemsList[var4] == null) { + throw new NumberInvalidException("commands.give.notFound", new Object[] { Integer.valueOf(var4) }); + } else { + if (par2ArrayOfStr.length >= 3) { + var5 = parseIntBounded(par1ICommandSender, par2ArrayOfStr[2], 1, 64); + } + + if (par2ArrayOfStr.length >= 4) { + var6 = parseInt(par1ICommandSender, par2ArrayOfStr[3]); + } + + ItemStack var7 = new ItemStack(var4, var5, var6); + EntityItem var8 = var3.dropPlayerItem(var7); + var8.delayBeforeCanPickup = 0; + notifyAdmins(par1ICommandSender, "commands.give.success", + new Object[] { Item.itemsList[var4].func_77653_i(var7), Integer.valueOf(var4), + Integer.valueOf(var5), var3.getEntityName() }); + } + } else { + throw new WrongUsageException("commands.give.usage", new Object[0]); + } + } + + /** + * Adds the strings available in this command to the given list of tab + * completion options. + */ + public List addTabCompletionOptions(ICommandSender par1ICommandSender, String[] par2ArrayOfStr) { + return par2ArrayOfStr.length == 1 ? getListOfStringsMatchingLastWord(par2ArrayOfStr, this.getPlayers()) : null; + } + + protected String[] getPlayers() { + return MinecraftServer.getServer().getAllUsernames(); + } + + /** + * Return whether the specified command parameter index is a username parameter. + */ + public boolean isUsernameIndex(String[] par1ArrayOfStr, int par2) { + return par2 == 0; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CommandHandler.java b/sp-server/src/main/java/net/minecraft/src/CommandHandler.java new file mode 100644 index 0000000..df7ce0e --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CommandHandler.java @@ -0,0 +1,200 @@ +package net.minecraft.src; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.Map.Entry; + +public class CommandHandler implements ICommandManager { + /** Map of Strings to the ICommand objects they represent */ + private final Map commandMap = new HashMap(); + + /** The set of ICommand objects currently loaded. */ + private final Set commandSet = new HashSet(); + + public int executeCommand(ICommandSender par1ICommandSender, String par2Str) { + par2Str = par2Str.trim(); + + if (par2Str.startsWith("/")) { + par2Str = par2Str.substring(1); + } + + String[] var3 = par2Str.split(" "); + String var4 = var3[0]; + var3 = dropFirstString(var3); + ICommand var5 = (ICommand) this.commandMap.get(var4); + int var6 = this.getUsernameIndex(var5, var3); + int var7 = 0; + + try { + if (var5 == null) { + throw new CommandNotFoundException(); + } + + if (var5.canCommandSenderUseCommand(par1ICommandSender)) { + if (var6 > -1) { + EntityPlayerMP[] var8 = PlayerSelector.matchPlayers(par1ICommandSender, var3[var6]); + String var9 = var3[var6]; + EntityPlayerMP[] var10 = var8; + int var11 = var8.length; + + for (int var12 = 0; var12 < var11; ++var12) { + EntityPlayerMP var13 = var10[var12]; + var3[var6] = var13.getEntityName(); + + try { + var5.processCommand(par1ICommandSender, var3); + ++var7; + } catch (CommandException var15) { + par1ICommandSender.sendChatToPlayer(EnumChatFormatting.RED + + par1ICommandSender.translateString(var15.getMessage(), var15.getErrorOjbects())); + } + } + + var3[var6] = var9; + } else { + var5.processCommand(par1ICommandSender, var3); + ++var7; + } + } else { + par1ICommandSender.sendChatToPlayer( + "" + EnumChatFormatting.RED + "You do not have permission to use this command."); + } + } catch (WrongUsageException var16) { + par1ICommandSender.sendChatToPlayer(EnumChatFormatting.RED + par1ICommandSender.translateString( + "commands.generic.usage", + new Object[] { par1ICommandSender.translateString(var16.getMessage(), var16.getErrorOjbects()) })); + } catch (CommandException var17) { + par1ICommandSender.sendChatToPlayer(EnumChatFormatting.RED + + par1ICommandSender.translateString(var17.getMessage(), var17.getErrorOjbects())); + } catch (Throwable var18) { + par1ICommandSender.sendChatToPlayer(EnumChatFormatting.RED + + par1ICommandSender.translateString("commands.generic.exception", new Object[0])); + var18.printStackTrace(); + } + + return var7; + } + + /** + * adds the command and any aliases it has to the internal map of available + * commands + */ + public ICommand registerCommand(ICommand par1ICommand) { + List var2 = par1ICommand.getCommandAliases(); + this.commandMap.put(par1ICommand.getCommandName(), par1ICommand); + this.commandSet.add(par1ICommand); + + if (var2 != null) { + Iterator var3 = var2.iterator(); + + while (var3.hasNext()) { + String var4 = (String) var3.next(); + ICommand var5 = (ICommand) this.commandMap.get(var4); + + if (var5 == null || !var5.getCommandName().equals(var4)) { + this.commandMap.put(var4, par1ICommand); + } + } + } + + return par1ICommand; + } + + /** + * creates a new array and sets elements 0..n-2 to be 0..n-1 of the input (n + * elements) + */ + private static String[] dropFirstString(String[] par0ArrayOfStr) { + String[] var1 = new String[par0ArrayOfStr.length - 1]; + + for (int var2 = 1; var2 < par0ArrayOfStr.length; ++var2) { + var1[var2 - 1] = par0ArrayOfStr[var2]; + } + + return var1; + } + + /** + * Performs a "begins with" string match on each token in par2. Only returns + * commands that par1 can use. + */ + public List getPossibleCommands(ICommandSender par1ICommandSender, String par2Str) { + String[] var3 = par2Str.split(" ", -1); + String var4 = var3[0]; + + if (var3.length == 1) { + ArrayList var8 = new ArrayList(); + Iterator var6 = this.commandMap.entrySet().iterator(); + + while (var6.hasNext()) { + Entry var7 = (Entry) var6.next(); + + if (CommandBase.doesStringStartWith(var4, (String) var7.getKey()) + && ((ICommand) var7.getValue()).canCommandSenderUseCommand(par1ICommandSender)) { + var8.add(var7.getKey()); + } + } + + return var8; + } else { + if (var3.length > 1) { + ICommand var5 = (ICommand) this.commandMap.get(var4); + + if (var5 != null) { + return var5.addTabCompletionOptions(par1ICommandSender, dropFirstString(var3)); + } + } + + return null; + } + } + + /** + * returns all commands that the commandSender can use + */ + public List getPossibleCommands(ICommandSender par1ICommandSender) { + ArrayList var2 = new ArrayList(); + Iterator var3 = this.commandSet.iterator(); + + while (var3.hasNext()) { + ICommand var4 = (ICommand) var3.next(); + + if (var4.canCommandSenderUseCommand(par1ICommandSender)) { + var2.add(var4); + } + } + + return var2; + } + + /** + * returns a map of string to commads. All commands are returned, not just ones + * which someone has permission to use. + */ + public Map getCommands() { + return this.commandMap; + } + + /** + * Return a command's first parameter index containing a valid username. + */ + private int getUsernameIndex(ICommand par1ICommand, String[] par2ArrayOfStr) { + if (par1ICommand == null) { + return -1; + } else { + for (int var3 = 0; var3 < par2ArrayOfStr.length; ++var3) { + if (par1ICommand.isUsernameIndex(par2ArrayOfStr, var3) + && PlayerSelector.matchesMultiplePlayers(par2ArrayOfStr[var3])) { + return var3; + } + } + + return -1; + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CommandHelp.java b/sp-server/src/main/java/net/minecraft/src/CommandHelp.java new file mode 100644 index 0000000..fa2b5ce --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CommandHelp.java @@ -0,0 +1,78 @@ +package net.minecraft.src; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import net.minecraft.server.MinecraftServer; + +public class CommandHelp extends CommandBase { + public String getCommandName() { + return "help"; + } + + /** + * Return the required permission level for this command. + */ + public int getRequiredPermissionLevel() { + return 0; + } + + public String getCommandUsage(ICommandSender par1ICommandSender) { + return par1ICommandSender.translateString("commands.help.usage", new Object[0]); + } + + public List getCommandAliases() { + return Arrays.asList(new String[] { "?" }); + } + + public void processCommand(ICommandSender par1ICommandSender, String[] par2ArrayOfStr) { + List var3 = this.getSortedPossibleCommands(par1ICommandSender); + byte var4 = 7; + int var5 = (var3.size() - 1) / var4; + boolean var6 = false; + ICommand var9; + int var11; + + try { + var11 = par2ArrayOfStr.length == 0 ? 0 + : parseIntBounded(par1ICommandSender, par2ArrayOfStr[0], 1, var5 + 1) - 1; + } catch (NumberInvalidException var10) { + Map var8 = this.getCommands(); + var9 = (ICommand) var8.get(par2ArrayOfStr[0]); + + if (var9 != null) { + throw new WrongUsageException(var9.getCommandUsage(par1ICommandSender), new Object[0]); + } + + throw new CommandNotFoundException(); + } + + int var7 = Math.min((var11 + 1) * var4, var3.size()); + par1ICommandSender.sendChatToPlayer(EnumChatFormatting.DARK_GREEN + par1ICommandSender.translateString( + "commands.help.header", new Object[] { Integer.valueOf(var11 + 1), Integer.valueOf(var5 + 1) })); + + for (int var12 = var11 * var4; var12 < var7; ++var12) { + var9 = (ICommand) var3.get(var12); + par1ICommandSender.sendChatToPlayer(var9.getCommandUsage(par1ICommandSender)); + } + + if (var11 == 0 && par1ICommandSender instanceof EntityPlayer) { + par1ICommandSender.sendChatToPlayer(EnumChatFormatting.GREEN + + par1ICommandSender.translateString("commands.help.footer", new Object[0])); + } + } + + /** + * Returns a sorted list of all possible commands for the given ICommandSender. + */ + protected List getSortedPossibleCommands(ICommandSender par1ICommandSender) { + List var2 = MinecraftServer.getServer().getCommandManager().getPossibleCommands(par1ICommandSender); + Collections.sort(var2); + return var2; + } + + protected Map getCommands() { + return MinecraftServer.getServer().getCommandManager().getCommands(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CommandKill.java b/sp-server/src/main/java/net/minecraft/src/CommandKill.java new file mode 100644 index 0000000..e4c0b8f --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CommandKill.java @@ -0,0 +1,20 @@ +package net.minecraft.src; + +public class CommandKill extends CommandBase { + public String getCommandName() { + return "kill"; + } + + /** + * Return the required permission level for this command. + */ + public int getRequiredPermissionLevel() { + return 0; + } + + public void processCommand(ICommandSender par1ICommandSender, String[] par2ArrayOfStr) { + EntityPlayerMP var3 = getCommandSenderAsPlayer(par1ICommandSender); + var3.attackEntityFrom(DamageSource.outOfWorld, 1000); + par1ICommandSender.sendChatToPlayer("Ouch. That looks like it hurt."); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CommandNotFoundException.java b/sp-server/src/main/java/net/minecraft/src/CommandNotFoundException.java new file mode 100644 index 0000000..f2d4be0 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CommandNotFoundException.java @@ -0,0 +1,11 @@ +package net.minecraft.src; + +public class CommandNotFoundException extends CommandException { + public CommandNotFoundException() { + this("commands.generic.notFound", new Object[0]); + } + + public CommandNotFoundException(String par1Str, Object... par2ArrayOfObj) { + super(par1Str, par2ArrayOfObj); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CommandServerBan.java b/sp-server/src/main/java/net/minecraft/src/CommandServerBan.java new file mode 100644 index 0000000..68ebb50 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CommandServerBan.java @@ -0,0 +1,62 @@ +package net.minecraft.src; + +import java.util.List; +import net.minecraft.server.MinecraftServer; + +public class CommandServerBan extends CommandBase { + public String getCommandName() { + return "ban"; + } + + /** + * Return the required permission level for this command. + */ + public int getRequiredPermissionLevel() { + return 3; + } + + public String getCommandUsage(ICommandSender par1ICommandSender) { + return par1ICommandSender.translateString("commands.ban.usage", new Object[0]); + } + + /** + * Returns true if the given command sender is allowed to use this command. + */ + public boolean canCommandSenderUseCommand(ICommandSender par1ICommandSender) { + return MinecraftServer.getServer().getConfigurationManager().getBannedPlayers().isListActive() + && super.canCommandSenderUseCommand(par1ICommandSender); + } + + public void processCommand(ICommandSender par1ICommandSender, String[] par2ArrayOfStr) { + if (par2ArrayOfStr.length >= 1 && par2ArrayOfStr[0].length() > 0) { + EntityPlayerMP var3 = MinecraftServer.getServer().getConfigurationManager() + .getPlayerEntity(par2ArrayOfStr[0]); + BanEntry var4 = new BanEntry(par2ArrayOfStr[0]); + var4.setBannedBy(par1ICommandSender.getCommandSenderName()); + + if (par2ArrayOfStr.length >= 2) { + var4.setBanReason(func_82360_a(par1ICommandSender, par2ArrayOfStr, 1)); + } + + MinecraftServer.getServer().getConfigurationManager().getBannedPlayers().put(var4); + + if (var3 != null) { + var3.playerNetServerHandler.kickPlayer("You are banned from this server."); + } + + notifyAdmins(par1ICommandSender, "commands.ban.success", new Object[] { par2ArrayOfStr[0] }); + } else { + throw new WrongUsageException("commands.ban.usage", new Object[0]); + } + } + + /** + * Adds the strings available in this command to the given list of tab + * completion options. + */ + public List addTabCompletionOptions(ICommandSender par1ICommandSender, String[] par2ArrayOfStr) { + return par2ArrayOfStr.length >= 1 + ? getListOfStringsMatchingLastWord(par2ArrayOfStr, MinecraftServer.getServer().getAllUsernames()) + : null; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CommandServerBanIp.java b/sp-server/src/main/java/net/minecraft/src/CommandServerBanIp.java new file mode 100644 index 0000000..4bac7d4 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CommandServerBanIp.java @@ -0,0 +1,101 @@ +package net.minecraft.src; + +import java.util.Iterator; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import net.minecraft.server.MinecraftServer; + +public class CommandServerBanIp extends CommandBase { + public static final Pattern IPv4Pattern = Pattern.compile( + "^([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])$"); + + public String getCommandName() { + return "ban-ip"; + } + + /** + * Return the required permission level for this command. + */ + public int getRequiredPermissionLevel() { + return 3; + } + + /** + * Returns true if the given command sender is allowed to use this command. + */ + public boolean canCommandSenderUseCommand(ICommandSender par1ICommandSender) { + return MinecraftServer.getServer().getConfigurationManager().getBannedIPs().isListActive() + && super.canCommandSenderUseCommand(par1ICommandSender); + } + + public String getCommandUsage(ICommandSender par1ICommandSender) { + return par1ICommandSender.translateString("commands.banip.usage", new Object[0]); + } + + public void processCommand(ICommandSender par1ICommandSender, String[] par2ArrayOfStr) { + if (par2ArrayOfStr.length >= 1 && par2ArrayOfStr[0].length() > 1) { + Matcher var3 = IPv4Pattern.matcher(par2ArrayOfStr[0]); + String var4 = null; + + if (par2ArrayOfStr.length >= 2) { + var4 = func_82360_a(par1ICommandSender, par2ArrayOfStr, 1); + } + + if (var3.matches()) { + this.banIP(par1ICommandSender, par2ArrayOfStr[0], var4); + } else { + EntityPlayerMP var5 = MinecraftServer.getServer().getConfigurationManager() + .getPlayerEntity(par2ArrayOfStr[0]); + + if (var5 == null) { + throw new PlayerNotFoundException("commands.banip.invalid", new Object[0]); + } + + this.banIP(par1ICommandSender, var5.getPlayerIP(), var4); + } + } else { + throw new WrongUsageException("commands.banip.usage", new Object[0]); + } + } + + /** + * Adds the strings available in this command to the given list of tab + * completion options. + */ + public List addTabCompletionOptions(ICommandSender par1ICommandSender, String[] par2ArrayOfStr) { + return par2ArrayOfStr.length == 1 + ? getListOfStringsMatchingLastWord(par2ArrayOfStr, MinecraftServer.getServer().getAllUsernames()) + : null; + } + + /** + * Actually does the banning work. + */ + protected void banIP(ICommandSender par1ICommandSender, String par2Str, String par3Str) { + BanEntry var4 = new BanEntry(par2Str); + var4.setBannedBy(par1ICommandSender.getCommandSenderName()); + + if (par3Str != null) { + var4.setBanReason(par3Str); + } + + MinecraftServer.getServer().getConfigurationManager().getBannedIPs().put(var4); + List var5 = MinecraftServer.getServer().getConfigurationManager().getPlayerList(par2Str); + String[] var6 = new String[var5.size()]; + int var7 = 0; + EntityPlayerMP var9; + + for (Iterator var8 = var5.iterator(); var8.hasNext(); var6[var7++] = var9.getEntityName()) { + var9 = (EntityPlayerMP) var8.next(); + var9.playerNetServerHandler.kickPlayer("You have been IP banned."); + } + + if (var5.isEmpty()) { + notifyAdmins(par1ICommandSender, "commands.banip.success", new Object[] { par2Str }); + } else { + notifyAdmins(par1ICommandSender, "commands.banip.success.players", + new Object[] { par2Str, joinNiceString(var6) }); + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CommandServerBanlist.java b/sp-server/src/main/java/net/minecraft/src/CommandServerBanlist.java new file mode 100644 index 0000000..a7688ed --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CommandServerBanlist.java @@ -0,0 +1,56 @@ +package net.minecraft.src; + +import java.util.List; +import net.minecraft.server.MinecraftServer; + +public class CommandServerBanlist extends CommandBase { + public String getCommandName() { + return "banlist"; + } + + /** + * Return the required permission level for this command. + */ + public int getRequiredPermissionLevel() { + return 3; + } + + /** + * Returns true if the given command sender is allowed to use this command. + */ + public boolean canCommandSenderUseCommand(ICommandSender par1ICommandSender) { + return (MinecraftServer.getServer().getConfigurationManager().getBannedIPs().isListActive() + || MinecraftServer.getServer().getConfigurationManager().getBannedPlayers().isListActive()) + && super.canCommandSenderUseCommand(par1ICommandSender); + } + + public String getCommandUsage(ICommandSender par1ICommandSender) { + return par1ICommandSender.translateString("commands.banlist.usage", new Object[0]); + } + + public void processCommand(ICommandSender par1ICommandSender, String[] par2ArrayOfStr) { + if (par2ArrayOfStr.length >= 1 && par2ArrayOfStr[0].equalsIgnoreCase("ips")) { + par1ICommandSender.sendChatToPlayer(par1ICommandSender.translateString("commands.banlist.ips", + new Object[] { Integer.valueOf(MinecraftServer.getServer().getConfigurationManager().getBannedIPs() + .getBannedList().size()) })); + par1ICommandSender.sendChatToPlayer(joinNiceString(MinecraftServer.getServer().getConfigurationManager() + .getBannedIPs().getBannedList().keySet().toArray())); + } else { + par1ICommandSender.sendChatToPlayer(par1ICommandSender.translateString("commands.banlist.players", + new Object[] { Integer.valueOf(MinecraftServer.getServer().getConfigurationManager() + .getBannedPlayers().getBannedList().size()) })); + par1ICommandSender.sendChatToPlayer(joinNiceString(MinecraftServer.getServer().getConfigurationManager() + .getBannedPlayers().getBannedList().keySet().toArray())); + } + } + + /** + * Adds the strings available in this command to the given list of tab + * completion options. + */ + public List addTabCompletionOptions(ICommandSender par1ICommandSender, String[] par2ArrayOfStr) { + return par2ArrayOfStr.length == 1 + ? getListOfStringsMatchingLastWord(par2ArrayOfStr, new String[] { "players", "ips" }) + : null; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CommandServerDeop.java b/sp-server/src/main/java/net/minecraft/src/CommandServerDeop.java new file mode 100644 index 0000000..04a1dba --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CommandServerDeop.java @@ -0,0 +1,41 @@ +package net.minecraft.src; + +import java.util.List; +import net.minecraft.server.MinecraftServer; + +public class CommandServerDeop extends CommandBase { + public String getCommandName() { + return "deop"; + } + + /** + * Return the required permission level for this command. + */ + public int getRequiredPermissionLevel() { + return 3; + } + + public String getCommandUsage(ICommandSender par1ICommandSender) { + return par1ICommandSender.translateString("commands.deop.usage", new Object[0]); + } + + public void processCommand(ICommandSender par1ICommandSender, String[] par2ArrayOfStr) { + if (par2ArrayOfStr.length == 1 && par2ArrayOfStr[0].length() > 0) { + MinecraftServer.getServer().getConfigurationManager().removeOp(par2ArrayOfStr[0]); + notifyAdmins(par1ICommandSender, "commands.deop.success", new Object[] { par2ArrayOfStr[0] }); + } else { + throw new WrongUsageException("commands.deop.usage", new Object[0]); + } + } + + /** + * Adds the strings available in this command to the given list of tab + * completion options. + */ + public List addTabCompletionOptions(ICommandSender par1ICommandSender, String[] par2ArrayOfStr) { + return par2ArrayOfStr.length == 1 + ? getListOfStringsFromIterableMatchingLastWord(par2ArrayOfStr, + MinecraftServer.getServer().getConfigurationManager().getOps()) + : null; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CommandServerEmote.java b/sp-server/src/main/java/net/minecraft/src/CommandServerEmote.java new file mode 100644 index 0000000..87c278e --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CommandServerEmote.java @@ -0,0 +1,40 @@ +package net.minecraft.src; + +import java.util.List; +import net.minecraft.server.MinecraftServer; + +public class CommandServerEmote extends CommandBase { + public String getCommandName() { + return "me"; + } + + /** + * Return the required permission level for this command. + */ + public int getRequiredPermissionLevel() { + return 0; + } + + public String getCommandUsage(ICommandSender par1ICommandSender) { + return par1ICommandSender.translateString("commands.me.usage", new Object[0]); + } + + public void processCommand(ICommandSender par1ICommandSender, String[] par2ArrayOfStr) { + if (par2ArrayOfStr.length > 0) { + String var3 = func_82361_a(par1ICommandSender, par2ArrayOfStr, 0, + par1ICommandSender.canCommandSenderUseCommand(1, "me")); + MinecraftServer.getServer().getConfigurationManager().sendPacketToAllPlayers( + new Packet3Chat("* " + par1ICommandSender.getCommandSenderName() + " " + var3)); + } else { + throw new WrongUsageException("commands.me.usage", new Object[0]); + } + } + + /** + * Adds the strings available in this command to the given list of tab + * completion options. + */ + public List addTabCompletionOptions(ICommandSender par1ICommandSender, String[] par2ArrayOfStr) { + return getListOfStringsMatchingLastWord(par2ArrayOfStr, MinecraftServer.getServer().getAllUsernames()); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CommandServerKick.java b/sp-server/src/main/java/net/minecraft/src/CommandServerKick.java new file mode 100644 index 0000000..842f82f --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CommandServerKick.java @@ -0,0 +1,60 @@ +package net.minecraft.src; + +import java.util.List; +import net.minecraft.server.MinecraftServer; + +public class CommandServerKick extends CommandBase { + public String getCommandName() { + return "kick"; + } + + /** + * Return the required permission level for this command. + */ + public int getRequiredPermissionLevel() { + return 3; + } + + public String getCommandUsage(ICommandSender par1ICommandSender) { + return par1ICommandSender.translateString("commands.kick.usage", new Object[0]); + } + + public void processCommand(ICommandSender par1ICommandSender, String[] par2ArrayOfStr) { + if (par2ArrayOfStr.length > 0 && par2ArrayOfStr[0].length() > 1) { + EntityPlayerMP var3 = MinecraftServer.getServer().getConfigurationManager() + .getPlayerEntity(par2ArrayOfStr[0]); + String var4 = "Kicked by an operator."; + boolean var5 = false; + + if (var3 == null) { + throw new PlayerNotFoundException(); + } else { + if (par2ArrayOfStr.length >= 2) { + var4 = func_82360_a(par1ICommandSender, par2ArrayOfStr, 1); + var5 = true; + } + + var3.playerNetServerHandler.kickPlayer(var4); + + if (var5) { + notifyAdmins(par1ICommandSender, "commands.kick.success.reason", + new Object[] { var3.getEntityName(), var4 }); + } else { + notifyAdmins(par1ICommandSender, "commands.kick.success", new Object[] { var3.getEntityName() }); + } + } + } else { + throw new WrongUsageException("commands.kick.usage", new Object[0]); + } + } + + /** + * Adds the strings available in this command to the given list of tab + * completion options. + */ + public List addTabCompletionOptions(ICommandSender par1ICommandSender, String[] par2ArrayOfStr) { + return par2ArrayOfStr.length >= 1 + ? getListOfStringsMatchingLastWord(par2ArrayOfStr, MinecraftServer.getServer().getAllUsernames()) + : null; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CommandServerList.java b/sp-server/src/main/java/net/minecraft/src/CommandServerList.java new file mode 100644 index 0000000..729d652 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CommandServerList.java @@ -0,0 +1,24 @@ +package net.minecraft.src; + +import net.minecraft.server.MinecraftServer; + +public class CommandServerList extends CommandBase { + public String getCommandName() { + return "list"; + } + + /** + * Return the required permission level for this command. + */ + public int getRequiredPermissionLevel() { + return 0; + } + + public void processCommand(ICommandSender par1ICommandSender, String[] par2ArrayOfStr) { + par1ICommandSender.sendChatToPlayer(par1ICommandSender.translateString("commands.players.list", + new Object[] { Integer.valueOf(MinecraftServer.getServer().getCurrentPlayerCount()), + Integer.valueOf(MinecraftServer.getServer().getMaxPlayers()) })); + par1ICommandSender + .sendChatToPlayer(MinecraftServer.getServer().getConfigurationManager().getPlayerListAsString()); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CommandServerMessage.java b/sp-server/src/main/java/net/minecraft/src/CommandServerMessage.java new file mode 100644 index 0000000..9281430 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CommandServerMessage.java @@ -0,0 +1,60 @@ +package net.minecraft.src; + +import java.util.Arrays; +import java.util.List; +import net.minecraft.server.MinecraftServer; + +public class CommandServerMessage extends CommandBase { + public List getCommandAliases() { + return Arrays.asList(new String[] { "w", "msg" }); + } + + public String getCommandName() { + return "tell"; + } + + /** + * Return the required permission level for this command. + */ + public int getRequiredPermissionLevel() { + return 0; + } + + public void processCommand(ICommandSender par1ICommandSender, String[] par2ArrayOfStr) { + if (par2ArrayOfStr.length < 2) { + throw new WrongUsageException("commands.message.usage", new Object[0]); + } else { + EntityPlayerMP var3 = func_82359_c(par1ICommandSender, par2ArrayOfStr[0]); + + if (var3 == null) { + throw new PlayerNotFoundException(); + } else if (var3 == par1ICommandSender) { + throw new PlayerNotFoundException("commands.message.sameTarget", new Object[0]); + } else { + String var4 = func_82361_a(par1ICommandSender, par2ArrayOfStr, 1, + !(par1ICommandSender instanceof EntityPlayer)); + var3.sendChatToPlayer(EnumChatFormatting.GRAY + "" + EnumChatFormatting.ITALIC + + var3.translateString("commands.message.display.incoming", + new Object[] { par1ICommandSender.getCommandSenderName(), var4 })); + par1ICommandSender.sendChatToPlayer(EnumChatFormatting.GRAY + "" + EnumChatFormatting.ITALIC + + par1ICommandSender.translateString("commands.message.display.outgoing", + new Object[] { var3.getCommandSenderName(), var4 })); + } + } + } + + /** + * Adds the strings available in this command to the given list of tab + * completion options. + */ + public List addTabCompletionOptions(ICommandSender par1ICommandSender, String[] par2ArrayOfStr) { + return getListOfStringsMatchingLastWord(par2ArrayOfStr, MinecraftServer.getServer().getAllUsernames()); + } + + /** + * Return whether the specified command parameter index is a username parameter. + */ + public boolean isUsernameIndex(String[] par1ArrayOfStr, int par2) { + return par2 == 0; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CommandServerOp.java b/sp-server/src/main/java/net/minecraft/src/CommandServerOp.java new file mode 100644 index 0000000..4424c0b --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CommandServerOp.java @@ -0,0 +1,57 @@ +package net.minecraft.src; + +import java.util.ArrayList; +import java.util.List; +import net.minecraft.server.MinecraftServer; + +public class CommandServerOp extends CommandBase { + public String getCommandName() { + return "op"; + } + + /** + * Return the required permission level for this command. + */ + public int getRequiredPermissionLevel() { + return 3; + } + + public String getCommandUsage(ICommandSender par1ICommandSender) { + return par1ICommandSender.translateString("commands.op.usage", new Object[0]); + } + + public void processCommand(ICommandSender par1ICommandSender, String[] par2ArrayOfStr) { + if (par2ArrayOfStr.length == 1 && par2ArrayOfStr[0].length() > 0) { + MinecraftServer.getServer().getConfigurationManager().addOp(par2ArrayOfStr[0]); + notifyAdmins(par1ICommandSender, "commands.op.success", new Object[] { par2ArrayOfStr[0] }); + } else { + throw new WrongUsageException("commands.op.usage", new Object[0]); + } + } + + /** + * Adds the strings available in this command to the given list of tab + * completion options. + */ + public List addTabCompletionOptions(ICommandSender par1ICommandSender, String[] par2ArrayOfStr) { + if (par2ArrayOfStr.length == 1) { + String var3 = par2ArrayOfStr[par2ArrayOfStr.length - 1]; + ArrayList var4 = new ArrayList(); + String[] var5 = MinecraftServer.getServer().getAllUsernames(); + int var6 = var5.length; + + for (int var7 = 0; var7 < var6; ++var7) { + String var8 = var5[var7]; + + if (!MinecraftServer.getServer().getConfigurationManager().areCommandsAllowed(var8) + && doesStringStartWith(var3, var8)) { + var4.add(var8); + } + } + + return var4; + } else { + return null; + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CommandServerPardon.java b/sp-server/src/main/java/net/minecraft/src/CommandServerPardon.java new file mode 100644 index 0000000..2ee3d8f --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CommandServerPardon.java @@ -0,0 +1,50 @@ +package net.minecraft.src; + +import java.util.List; +import net.minecraft.server.MinecraftServer; + +public class CommandServerPardon extends CommandBase { + public String getCommandName() { + return "pardon"; + } + + /** + * Return the required permission level for this command. + */ + public int getRequiredPermissionLevel() { + return 3; + } + + public String getCommandUsage(ICommandSender par1ICommandSender) { + return par1ICommandSender.translateString("commands.unban.usage", new Object[0]); + } + + /** + * Returns true if the given command sender is allowed to use this command. + */ + public boolean canCommandSenderUseCommand(ICommandSender par1ICommandSender) { + return MinecraftServer.getServer().getConfigurationManager().getBannedPlayers().isListActive() + && super.canCommandSenderUseCommand(par1ICommandSender); + } + + public void processCommand(ICommandSender par1ICommandSender, String[] par2ArrayOfStr) { + if (par2ArrayOfStr.length == 1 && par2ArrayOfStr[0].length() > 0) { + MinecraftServer.getServer().getConfigurationManager().getBannedPlayers().remove(par2ArrayOfStr[0]); + notifyAdmins(par1ICommandSender, "commands.unban.success", new Object[] { par2ArrayOfStr[0] }); + } else { + throw new WrongUsageException("commands.unban.usage", new Object[0]); + } + } + + /** + * Adds the strings available in this command to the given list of tab + * completion options. + */ + public List addTabCompletionOptions(ICommandSender par1ICommandSender, String[] par2ArrayOfStr) { + return par2ArrayOfStr.length == 1 + ? getListOfStringsFromIterableMatchingLastWord(par2ArrayOfStr, + MinecraftServer.getServer().getConfigurationManager().getBannedPlayers().getBannedList() + .keySet()) + : null; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CommandServerPardonIp.java b/sp-server/src/main/java/net/minecraft/src/CommandServerPardonIp.java new file mode 100644 index 0000000..67fcd7a --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CommandServerPardonIp.java @@ -0,0 +1,56 @@ +package net.minecraft.src; + +import java.util.List; +import java.util.regex.Matcher; +import net.minecraft.server.MinecraftServer; + +public class CommandServerPardonIp extends CommandBase { + public String getCommandName() { + return "pardon-ip"; + } + + /** + * Return the required permission level for this command. + */ + public int getRequiredPermissionLevel() { + return 3; + } + + /** + * Returns true if the given command sender is allowed to use this command. + */ + public boolean canCommandSenderUseCommand(ICommandSender par1ICommandSender) { + return MinecraftServer.getServer().getConfigurationManager().getBannedIPs().isListActive() + && super.canCommandSenderUseCommand(par1ICommandSender); + } + + public String getCommandUsage(ICommandSender par1ICommandSender) { + return par1ICommandSender.translateString("commands.unbanip.usage", new Object[0]); + } + + public void processCommand(ICommandSender par1ICommandSender, String[] par2ArrayOfStr) { + if (par2ArrayOfStr.length == 1 && par2ArrayOfStr[0].length() > 1) { + Matcher var3 = CommandServerBanIp.IPv4Pattern.matcher(par2ArrayOfStr[0]); + + if (var3.matches()) { + MinecraftServer.getServer().getConfigurationManager().getBannedIPs().remove(par2ArrayOfStr[0]); + notifyAdmins(par1ICommandSender, "commands.unbanip.success", new Object[] { par2ArrayOfStr[0] }); + } else { + throw new SyntaxErrorException("commands.unbanip.invalid", new Object[0]); + } + } else { + throw new WrongUsageException("commands.unbanip.usage", new Object[0]); + } + } + + /** + * Adds the strings available in this command to the given list of tab + * completion options. + */ + public List addTabCompletionOptions(ICommandSender par1ICommandSender, String[] par2ArrayOfStr) { + return par2ArrayOfStr.length == 1 + ? getListOfStringsFromIterableMatchingLastWord(par2ArrayOfStr, + MinecraftServer.getServer().getConfigurationManager().getBannedIPs().getBannedList().keySet()) + : null; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CommandServerPublishLocal.java b/sp-server/src/main/java/net/minecraft/src/CommandServerPublishLocal.java new file mode 100644 index 0000000..f6befb4 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CommandServerPublishLocal.java @@ -0,0 +1,26 @@ +package net.minecraft.src; + +import net.minecraft.server.MinecraftServer; + +public class CommandServerPublishLocal extends CommandBase { + public String getCommandName() { + return "publish"; + } + + /** + * Return the required permission level for this command. + */ + public int getRequiredPermissionLevel() { + return 4; + } + + public void processCommand(ICommandSender par1ICommandSender, String[] par2ArrayOfStr) { + String var3 = MinecraftServer.getServer().shareToLAN(EnumGameType.SURVIVAL, false); + + if (var3 != null) { + notifyAdmins(par1ICommandSender, "commands.publish.started", new Object[] { var3 }); + } else { + notifyAdmins(par1ICommandSender, "commands.publish.failed", new Object[0]); + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CommandServerSaveAll.java b/sp-server/src/main/java/net/minecraft/src/CommandServerSaveAll.java new file mode 100644 index 0000000..d5493b2 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CommandServerSaveAll.java @@ -0,0 +1,64 @@ +package net.minecraft.src; + +import net.minecraft.server.MinecraftServer; + +public class CommandServerSaveAll extends CommandBase { + public String getCommandName() { + return "save-all"; + } + + /** + * Return the required permission level for this command. + */ + public int getRequiredPermissionLevel() { + return 4; + } + + public void processCommand(ICommandSender par1ICommandSender, String[] par2ArrayOfStr) { + MinecraftServer var3 = MinecraftServer.getServer(); + par1ICommandSender.sendChatToPlayer(par1ICommandSender.translateString("commands.save.start", new Object[0])); + + if (var3.getConfigurationManager() != null) { + var3.getConfigurationManager().saveAllPlayerData(); + } + + try { + int var4; + WorldServer var5; + boolean var6; + + for (var4 = 0; var4 < var3.worldServers.length; ++var4) { + if (var3.worldServers[var4] != null) { + var5 = var3.worldServers[var4]; + var6 = var5.levelSaving; + var5.levelSaving = false; + var5.saveAllChunks(true, (IProgressUpdate) null); + var5.levelSaving = var6; + } + } + + if (par2ArrayOfStr.length > 0 && "flush".equals(par2ArrayOfStr[0])) { + par1ICommandSender.sendChatToPlayer( + par1ICommandSender.translateString("commands.save.flushStart", new Object[0])); + + for (var4 = 0; var4 < var3.worldServers.length; ++var4) { + if (var3.worldServers[var4] != null) { + var5 = var3.worldServers[var4]; + var6 = var5.levelSaving; + var5.levelSaving = false; + var5.func_104140_m(); + var5.levelSaving = var6; + } + } + + par1ICommandSender + .sendChatToPlayer(par1ICommandSender.translateString("commands.save.flushEnd", new Object[0])); + } + } catch (MinecraftException var7) { + notifyAdmins(par1ICommandSender, "commands.save.failed", new Object[] { var7.getMessage() }); + return; + } + + notifyAdmins(par1ICommandSender, "commands.save.success", new Object[0]); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CommandServerSaveOff.java b/sp-server/src/main/java/net/minecraft/src/CommandServerSaveOff.java new file mode 100644 index 0000000..5ca0a17 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CommandServerSaveOff.java @@ -0,0 +1,29 @@ +package net.minecraft.src; + +import net.minecraft.server.MinecraftServer; + +public class CommandServerSaveOff extends CommandBase { + public String getCommandName() { + return "save-off"; + } + + /** + * Return the required permission level for this command. + */ + public int getRequiredPermissionLevel() { + return 4; + } + + public void processCommand(ICommandSender par1ICommandSender, String[] par2ArrayOfStr) { + MinecraftServer var3 = MinecraftServer.getServer(); + + for (int var4 = 0; var4 < var3.worldServers.length; ++var4) { + if (var3.worldServers[var4] != null) { + WorldServer var5 = var3.worldServers[var4]; + var5.levelSaving = true; + } + } + + notifyAdmins(par1ICommandSender, "commands.save.disabled", new Object[0]); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CommandServerSaveOn.java b/sp-server/src/main/java/net/minecraft/src/CommandServerSaveOn.java new file mode 100644 index 0000000..b05d839 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CommandServerSaveOn.java @@ -0,0 +1,29 @@ +package net.minecraft.src; + +import net.minecraft.server.MinecraftServer; + +public class CommandServerSaveOn extends CommandBase { + public String getCommandName() { + return "save-on"; + } + + /** + * Return the required permission level for this command. + */ + public int getRequiredPermissionLevel() { + return 4; + } + + public void processCommand(ICommandSender par1ICommandSender, String[] par2ArrayOfStr) { + MinecraftServer var3 = MinecraftServer.getServer(); + + for (int var4 = 0; var4 < var3.worldServers.length; ++var4) { + if (var3.worldServers[var4] != null) { + WorldServer var5 = var3.worldServers[var4]; + var5.levelSaving = false; + } + } + + notifyAdmins(par1ICommandSender, "commands.save.enabled", new Object[0]); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CommandServerSay.java b/sp-server/src/main/java/net/minecraft/src/CommandServerSay.java new file mode 100644 index 0000000..eadd154 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CommandServerSay.java @@ -0,0 +1,41 @@ +package net.minecraft.src; + +import java.util.List; +import net.minecraft.server.MinecraftServer; + +public class CommandServerSay extends CommandBase { + public String getCommandName() { + return "say"; + } + + /** + * Return the required permission level for this command. + */ + public int getRequiredPermissionLevel() { + return 1; + } + + public String getCommandUsage(ICommandSender par1ICommandSender) { + return par1ICommandSender.translateString("commands.say.usage", new Object[0]); + } + + public void processCommand(ICommandSender par1ICommandSender, String[] par2ArrayOfStr) { + if (par2ArrayOfStr.length > 0 && par2ArrayOfStr[0].length() > 0) { + String var3 = func_82361_a(par1ICommandSender, par2ArrayOfStr, 0, true); + MinecraftServer.getServer().getConfigurationManager().sendChatMsg( + String.format("[%s] %s", new Object[] { par1ICommandSender.getCommandSenderName(), var3 })); + } else { + throw new WrongUsageException("commands.say.usage", new Object[0]); + } + } + + /** + * Adds the strings available in this command to the given list of tab + * completion options. + */ + public List addTabCompletionOptions(ICommandSender par1ICommandSender, String[] par2ArrayOfStr) { + return par2ArrayOfStr.length >= 1 + ? getListOfStringsMatchingLastWord(par2ArrayOfStr, MinecraftServer.getServer().getAllUsernames()) + : null; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CommandServerStop.java b/sp-server/src/main/java/net/minecraft/src/CommandServerStop.java new file mode 100644 index 0000000..8733bfe --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CommandServerStop.java @@ -0,0 +1,21 @@ +package net.minecraft.src; + +import net.minecraft.server.MinecraftServer; + +public class CommandServerStop extends CommandBase { + public String getCommandName() { + return "stop"; + } + + /** + * Return the required permission level for this command. + */ + public int getRequiredPermissionLevel() { + return 4; + } + + public void processCommand(ICommandSender par1ICommandSender, String[] par2ArrayOfStr) { + notifyAdmins(par1ICommandSender, "commands.stop.start", new Object[0]); + MinecraftServer.getServer().initiateShutdown(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CommandServerTp.java b/sp-server/src/main/java/net/minecraft/src/CommandServerTp.java new file mode 100644 index 0000000..757f22f --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CommandServerTp.java @@ -0,0 +1,122 @@ +package net.minecraft.src; + +import java.util.List; +import net.minecraft.server.MinecraftServer; + +public class CommandServerTp extends CommandBase { + public String getCommandName() { + return "tp"; + } + + /** + * Return the required permission level for this command. + */ + public int getRequiredPermissionLevel() { + return 2; + } + + public String getCommandUsage(ICommandSender par1ICommandSender) { + return par1ICommandSender.translateString("commands.tp.usage", new Object[0]); + } + + public void processCommand(ICommandSender par1ICommandSender, String[] par2ArrayOfStr) { + if (par2ArrayOfStr.length < 1) { + throw new WrongUsageException("commands.tp.usage", new Object[0]); + } else { + EntityPlayerMP var3; + + if (par2ArrayOfStr.length != 2 && par2ArrayOfStr.length != 4) { + var3 = getCommandSenderAsPlayer(par1ICommandSender); + } else { + var3 = func_82359_c(par1ICommandSender, par2ArrayOfStr[0]); + + if (var3 == null) { + throw new PlayerNotFoundException(); + } + } + + if (par2ArrayOfStr.length != 3 && par2ArrayOfStr.length != 4) { + if (par2ArrayOfStr.length == 1 || par2ArrayOfStr.length == 2) { + EntityPlayerMP var11 = func_82359_c(par1ICommandSender, par2ArrayOfStr[par2ArrayOfStr.length - 1]); + + if (var11 == null) { + throw new PlayerNotFoundException(); + } + + if (var11.worldObj != var3.worldObj) { + notifyAdmins(par1ICommandSender, "commands.tp.notSameDimension", new Object[0]); + return; + } + + var3.mountEntity((Entity) null); + var3.playerNetServerHandler.setPlayerLocation(var11.posX, var11.posY, var11.posZ, var11.rotationYaw, + var11.rotationPitch); + notifyAdmins(par1ICommandSender, "commands.tp.success", + new Object[] { var3.getEntityName(), var11.getEntityName() }); + } + } else if (var3.worldObj != null) { + int var4 = par2ArrayOfStr.length - 3; + double var5 = this.func_82368_a(par1ICommandSender, var3.posX, par2ArrayOfStr[var4++]); + double var7 = this.func_82367_a(par1ICommandSender, var3.posY, par2ArrayOfStr[var4++], 0, 0); + double var9 = this.func_82368_a(par1ICommandSender, var3.posZ, par2ArrayOfStr[var4++]); + var3.mountEntity((Entity) null); + var3.setPositionAndUpdate(var5, var7, var9); + notifyAdmins(par1ICommandSender, "commands.tp.success.coordinates", new Object[] { var3.getEntityName(), + Double.valueOf(var5), Double.valueOf(var7), Double.valueOf(var9) }); + } + } + } + + private double func_82368_a(ICommandSender par1ICommandSender, double par2, String par4Str) { + return this.func_82367_a(par1ICommandSender, par2, par4Str, -30000000, 30000000); + } + + private double func_82367_a(ICommandSender par1ICommandSender, double par2, String par4Str, int par5, int par6) { + boolean var7 = par4Str.startsWith("~"); + double var8 = var7 ? par2 : 0.0D; + + if (!var7 || par4Str.length() > 1) { + boolean var10 = par4Str.contains("."); + + if (var7) { + par4Str = par4Str.substring(1); + } + + var8 += parseDouble(par1ICommandSender, par4Str); + + if (!var10 && !var7) { + var8 += 0.5D; + } + } + + if (par5 != 0 || par6 != 0) { + if (var8 < (double) par5) { + throw new NumberInvalidException("commands.generic.double.tooSmall", + new Object[] { Double.valueOf(var8), Integer.valueOf(par5) }); + } + + if (var8 > (double) par6) { + throw new NumberInvalidException("commands.generic.double.tooBig", + new Object[] { Double.valueOf(var8), Integer.valueOf(par6) }); + } + } + + return var8; + } + + /** + * Adds the strings available in this command to the given list of tab + * completion options. + */ + public List addTabCompletionOptions(ICommandSender par1ICommandSender, String[] par2ArrayOfStr) { + return par2ArrayOfStr.length != 1 && par2ArrayOfStr.length != 2 ? null + : getListOfStringsMatchingLastWord(par2ArrayOfStr, MinecraftServer.getServer().getAllUsernames()); + } + + /** + * Return whether the specified command parameter index is a username parameter. + */ + public boolean isUsernameIndex(String[] par1ArrayOfStr, int par2) { + return par2 == 0; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CommandServerWhitelist.java b/sp-server/src/main/java/net/minecraft/src/CommandServerWhitelist.java new file mode 100644 index 0000000..e6301f8 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CommandServerWhitelist.java @@ -0,0 +1,118 @@ +package net.minecraft.src; + +import java.util.ArrayList; +import java.util.List; +import net.minecraft.server.MinecraftServer; + +public class CommandServerWhitelist extends CommandBase { + public String getCommandName() { + return "whitelist"; + } + + /** + * Return the required permission level for this command. + */ + public int getRequiredPermissionLevel() { + return 3; + } + + public String getCommandUsage(ICommandSender par1ICommandSender) { + return par1ICommandSender.translateString("commands.whitelist.usage", new Object[0]); + } + + public void processCommand(ICommandSender par1ICommandSender, String[] par2ArrayOfStr) { + if (par2ArrayOfStr.length >= 1) { + if (par2ArrayOfStr[0].equals("on")) { + MinecraftServer.getServer().getConfigurationManager().setWhiteListEnabled(true); + notifyAdmins(par1ICommandSender, "commands.whitelist.enabled", new Object[0]); + return; + } + + if (par2ArrayOfStr[0].equals("off")) { + MinecraftServer.getServer().getConfigurationManager().setWhiteListEnabled(false); + notifyAdmins(par1ICommandSender, "commands.whitelist.disabled", new Object[0]); + return; + } + + if (par2ArrayOfStr[0].equals("list")) { + par1ICommandSender.sendChatToPlayer(par1ICommandSender.translateString("commands.whitelist.list", + new Object[] { + Integer.valueOf(MinecraftServer.getServer().getConfigurationManager() + .getWhiteListedPlayers().size()), + Integer.valueOf(MinecraftServer.getServer().getConfigurationManager() + .getAvailablePlayerDat().length) })); + par1ICommandSender.sendChatToPlayer(joinNiceString(MinecraftServer.getServer().getConfigurationManager() + .getWhiteListedPlayers().toArray(new String[0]))); + return; + } + + if (par2ArrayOfStr[0].equals("add")) { + if (par2ArrayOfStr.length < 2) { + throw new WrongUsageException("commands.whitelist.add.usage", new Object[0]); + } + + MinecraftServer.getServer().getConfigurationManager().addToWhiteList(par2ArrayOfStr[1]); + notifyAdmins(par1ICommandSender, "commands.whitelist.add.success", new Object[] { par2ArrayOfStr[1] }); + return; + } + + if (par2ArrayOfStr[0].equals("remove")) { + if (par2ArrayOfStr.length < 2) { + throw new WrongUsageException("commands.whitelist.remove.usage", new Object[0]); + } + + MinecraftServer.getServer().getConfigurationManager().removeFromWhitelist(par2ArrayOfStr[1]); + notifyAdmins(par1ICommandSender, "commands.whitelist.remove.success", + new Object[] { par2ArrayOfStr[1] }); + return; + } + + if (par2ArrayOfStr[0].equals("reload")) { + MinecraftServer.getServer().getConfigurationManager().loadWhiteList(); + notifyAdmins(par1ICommandSender, "commands.whitelist.reloaded", new Object[0]); + return; + } + } + + throw new WrongUsageException("commands.whitelist.usage", new Object[0]); + } + + /** + * Adds the strings available in this command to the given list of tab + * completion options. + */ + public List addTabCompletionOptions(ICommandSender par1ICommandSender, String[] par2ArrayOfStr) { + if (par2ArrayOfStr.length == 1) { + return getListOfStringsMatchingLastWord(par2ArrayOfStr, + new String[] { "on", "off", "list", "add", "remove", "reload" }); + } else { + if (par2ArrayOfStr.length == 2) { + if (par2ArrayOfStr[0].equals("add")) { + String[] var3 = MinecraftServer.getServer().getConfigurationManager().getAvailablePlayerDat(); + ArrayList var4 = new ArrayList(); + String var5 = par2ArrayOfStr[par2ArrayOfStr.length - 1]; + String[] var6 = var3; + int var7 = var3.length; + + for (int var8 = 0; var8 < var7; ++var8) { + String var9 = var6[var8]; + + if (doesStringStartWith(var5, var9) && !MinecraftServer.getServer().getConfigurationManager() + .getWhiteListedPlayers().contains(var9)) { + var4.add(var9); + } + } + + return var4; + } + + if (par2ArrayOfStr[0].equals("remove")) { + return getListOfStringsFromIterableMatchingLastWord(par2ArrayOfStr, + MinecraftServer.getServer().getConfigurationManager().getWhiteListedPlayers()); + } + } + + return null; + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CommandSetSpawnpoint.java b/sp-server/src/main/java/net/minecraft/src/CommandSetSpawnpoint.java new file mode 100644 index 0000000..6f762df --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CommandSetSpawnpoint.java @@ -0,0 +1,65 @@ +package net.minecraft.src; + +import java.util.List; +import net.minecraft.server.MinecraftServer; + +public class CommandSetSpawnpoint extends CommandBase { + public String getCommandName() { + return "spawnpoint"; + } + + /** + * Return the required permission level for this command. + */ + public int getRequiredPermissionLevel() { + return 2; + } + + public String getCommandUsage(ICommandSender par1ICommandSender) { + return par1ICommandSender.translateString("commands.spawnpoint.usage", new Object[0]); + } + + public void processCommand(ICommandSender par1ICommandSender, String[] par2ArrayOfStr) { + EntityPlayerMP var3 = par2ArrayOfStr.length == 0 ? getCommandSenderAsPlayer(par1ICommandSender) + : func_82359_c(par1ICommandSender, par2ArrayOfStr[0]); + + if (par2ArrayOfStr.length == 4) { + if (var3.worldObj != null) { + byte var4 = 1; + int var5 = 30000000; + int var9 = var4 + 1; + int var6 = parseIntBounded(par1ICommandSender, par2ArrayOfStr[var4], -var5, var5); + int var7 = parseIntBounded(par1ICommandSender, par2ArrayOfStr[var9++], 0, 256); + int var8 = parseIntBounded(par1ICommandSender, par2ArrayOfStr[var9++], -var5, var5); + var3.setSpawnChunk(new ChunkCoordinates(var6, var7, var8), true); + notifyAdmins(par1ICommandSender, "commands.spawnpoint.success", new Object[] { var3.getEntityName(), + Integer.valueOf(var6), Integer.valueOf(var7), Integer.valueOf(var8) }); + } + } else { + if (par2ArrayOfStr.length > 1) { + throw new WrongUsageException("commands.spawnpoint.usage", new Object[0]); + } + + ChunkCoordinates var10 = var3.getCommandSenderPosition(); + var3.setSpawnChunk(var10, true); + notifyAdmins(par1ICommandSender, "commands.spawnpoint.success", new Object[] { var3.getEntityName(), + Integer.valueOf(var10.posX), Integer.valueOf(var10.posY), Integer.valueOf(var10.posZ) }); + } + } + + /** + * Adds the strings available in this command to the given list of tab + * completion options. + */ + public List addTabCompletionOptions(ICommandSender par1ICommandSender, String[] par2ArrayOfStr) { + return par2ArrayOfStr.length != 1 && par2ArrayOfStr.length != 2 ? null + : getListOfStringsMatchingLastWord(par2ArrayOfStr, MinecraftServer.getServer().getAllUsernames()); + } + + /** + * Return whether the specified command parameter index is a username parameter. + */ + public boolean isUsernameIndex(String[] par1ArrayOfStr, int par2) { + return par2 == 0; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CommandShowSeed.java b/sp-server/src/main/java/net/minecraft/src/CommandShowSeed.java new file mode 100644 index 0000000..6b3af28 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CommandShowSeed.java @@ -0,0 +1,29 @@ +package net.minecraft.src; + +import net.minecraft.server.MinecraftServer; + +public class CommandShowSeed extends CommandBase { + /** + * Returns true if the given command sender is allowed to use this command. + */ + public boolean canCommandSenderUseCommand(ICommandSender par1ICommandSender) { + return MinecraftServer.getServer().isSinglePlayer() || super.canCommandSenderUseCommand(par1ICommandSender); + } + + public String getCommandName() { + return "seed"; + } + + /** + * Return the required permission level for this command. + */ + public int getRequiredPermissionLevel() { + return 2; + } + + public void processCommand(ICommandSender par1ICommandSender, String[] par2ArrayOfStr) { + Object var3 = par1ICommandSender instanceof EntityPlayer ? ((EntityPlayer) par1ICommandSender).worldObj + : MinecraftServer.getServer().worldServerForDimension(0); + par1ICommandSender.sendChatToPlayer("Seed: " + ((World) var3).getSeed()); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CommandTime.java b/sp-server/src/main/java/net/minecraft/src/CommandTime.java new file mode 100644 index 0000000..c90cd2d --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CommandTime.java @@ -0,0 +1,81 @@ +package net.minecraft.src; + +import java.util.List; +import net.minecraft.server.MinecraftServer; + +public class CommandTime extends CommandBase { + public String getCommandName() { + return "time"; + } + + /** + * Return the required permission level for this command. + */ + public int getRequiredPermissionLevel() { + return 2; + } + + public String getCommandUsage(ICommandSender par1ICommandSender) { + return par1ICommandSender.translateString("commands.time.usage", new Object[0]); + } + + public void processCommand(ICommandSender par1ICommandSender, String[] par2ArrayOfStr) { + if (par2ArrayOfStr.length > 1) { + int var3; + + if (par2ArrayOfStr[0].equals("set")) { + if (par2ArrayOfStr[1].equals("day")) { + var3 = 0; + } else if (par2ArrayOfStr[1].equals("night")) { + var3 = 12500; + } else { + var3 = parseIntWithMin(par1ICommandSender, par2ArrayOfStr[1], 0); + } + + this.setTime(par1ICommandSender, var3); + notifyAdmins(par1ICommandSender, "commands.time.set", new Object[] { Integer.valueOf(var3) }); + return; + } + + if (par2ArrayOfStr[0].equals("add")) { + var3 = parseIntWithMin(par1ICommandSender, par2ArrayOfStr[1], 0); + this.addTime(par1ICommandSender, var3); + notifyAdmins(par1ICommandSender, "commands.time.added", new Object[] { Integer.valueOf(var3) }); + return; + } + } + + throw new WrongUsageException("commands.time.usage", new Object[0]); + } + + /** + * Adds the strings available in this command to the given list of tab + * completion options. + */ + public List addTabCompletionOptions(ICommandSender par1ICommandSender, String[] par2ArrayOfStr) { + return par2ArrayOfStr.length == 1 + ? getListOfStringsMatchingLastWord(par2ArrayOfStr, new String[] { "set", "add" }) + : (par2ArrayOfStr.length == 2 && par2ArrayOfStr[0].equals("set") + ? getListOfStringsMatchingLastWord(par2ArrayOfStr, new String[] { "day", "night" }) + : null); + } + + /** + * Set the time in the server object. + */ + protected void setTime(ICommandSender par1ICommandSender, int par2) { + for (int var3 = 0; var3 < MinecraftServer.getServer().worldServers.length; ++var3) { + MinecraftServer.getServer().worldServers[var3].setWorldTime((long) par2); + } + } + + /** + * Adds (or removes) time in the server object. + */ + protected void addTime(ICommandSender par1ICommandSender, int par2) { + for (int var3 = 0; var3 < MinecraftServer.getServer().worldServers.length; ++var3) { + WorldServer var4 = MinecraftServer.getServer().worldServers[var3]; + var4.setWorldTime(var4.getWorldTime() + (long) par2); + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CommandToggleDownfall.java b/sp-server/src/main/java/net/minecraft/src/CommandToggleDownfall.java new file mode 100644 index 0000000..ed17834 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CommandToggleDownfall.java @@ -0,0 +1,29 @@ +package net.minecraft.src; + +import net.minecraft.server.MinecraftServer; + +public class CommandToggleDownfall extends CommandBase { + public String getCommandName() { + return "toggledownfall"; + } + + /** + * Return the required permission level for this command. + */ + public int getRequiredPermissionLevel() { + return 2; + } + + public void processCommand(ICommandSender par1ICommandSender, String[] par2ArrayOfStr) { + this.toggleDownfall(); + notifyAdmins(par1ICommandSender, "commands.downfall.success", new Object[0]); + } + + /** + * Toggle rain and enable thundering. + */ + protected void toggleDownfall() { + MinecraftServer.getServer().worldServers[0].commandToggleDownfall(); + MinecraftServer.getServer().worldServers[0].getWorldInfo().setThundering(true); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CommandWeather.java b/sp-server/src/main/java/net/minecraft/src/CommandWeather.java new file mode 100644 index 0000000..2947e1c --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CommandWeather.java @@ -0,0 +1,59 @@ +package net.minecraft.src; + +import java.util.List; +import java.util.Random; +import net.minecraft.server.MinecraftServer; + +public class CommandWeather extends CommandBase { + public String getCommandName() { + return "weather"; + } + + /** + * Return the required permission level for this command. + */ + public int getRequiredPermissionLevel() { + return 2; + } + + public void processCommand(ICommandSender par1ICommandSender, String[] par2ArrayOfStr) { + if (par2ArrayOfStr.length < 1) { + throw new WrongUsageException("commands.weather.usage", new Object[0]); + } else { + int var3 = (300 + (new Random()).nextInt(600)) * 20; + + if (par2ArrayOfStr.length >= 2) { + var3 = parseIntBounded(par1ICommandSender, par2ArrayOfStr[1], 1, 1000000) * 20; + } + + WorldServer var4 = MinecraftServer.getServer().worldServers[0]; + WorldInfo var5 = var4.getWorldInfo(); + var5.setRainTime(var3); + var5.setThunderTime(var3); + + if ("clear".equalsIgnoreCase(par2ArrayOfStr[0])) { + var5.setRaining(false); + var5.setThundering(false); + notifyAdmins(par1ICommandSender, "commands.weather.clear", new Object[0]); + } else if ("rain".equalsIgnoreCase(par2ArrayOfStr[0])) { + var5.setRaining(true); + var5.setThundering(false); + notifyAdmins(par1ICommandSender, "commands.weather.rain", new Object[0]); + } else if ("thunder".equalsIgnoreCase(par2ArrayOfStr[0])) { + var5.setRaining(true); + var5.setThundering(true); + notifyAdmins(par1ICommandSender, "commands.weather.thunder", new Object[0]); + } + } + } + + /** + * Adds the strings available in this command to the given list of tab + * completion options. + */ + public List addTabCompletionOptions(ICommandSender par1ICommandSender, String[] par2ArrayOfStr) { + return par2ArrayOfStr.length == 1 + ? getListOfStringsMatchingLastWord(par2ArrayOfStr, new String[] { "clear", "rain", "thunder" }) + : null; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CommandXP.java b/sp-server/src/main/java/net/minecraft/src/CommandXP.java new file mode 100644 index 0000000..01979db --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CommandXP.java @@ -0,0 +1,89 @@ +package net.minecraft.src; + +import java.util.List; +import net.minecraft.server.MinecraftServer; + +public class CommandXP extends CommandBase { + public String getCommandName() { + return "xp"; + } + + /** + * Return the required permission level for this command. + */ + public int getRequiredPermissionLevel() { + return 2; + } + + public String getCommandUsage(ICommandSender par1ICommandSender) { + return par1ICommandSender.translateString("commands.xp.usage", new Object[0]); + } + + public void processCommand(ICommandSender par1ICommandSender, String[] par2ArrayOfStr) { + if (par2ArrayOfStr.length <= 0) { + throw new WrongUsageException("commands.xp.usage", new Object[0]); + } else { + String var4 = par2ArrayOfStr[0]; + boolean var5 = var4.endsWith("l") || var4.endsWith("L"); + + if (var5 && var4.length() > 1) { + var4 = var4.substring(0, var4.length() - 1); + } + + int var6 = parseInt(par1ICommandSender, var4); + boolean var7 = var6 < 0; + + if (var7) { + var6 *= -1; + } + + EntityPlayerMP var3; + + if (par2ArrayOfStr.length > 1) { + var3 = func_82359_c(par1ICommandSender, par2ArrayOfStr[1]); + } else { + var3 = getCommandSenderAsPlayer(par1ICommandSender); + } + + if (var5) { + if (var7) { + var3.addExperienceLevel(-var6); + notifyAdmins(par1ICommandSender, "commands.xp.success.negative.levels", + new Object[] { Integer.valueOf(var6), var3.getEntityName() }); + } else { + var3.addExperienceLevel(var6); + notifyAdmins(par1ICommandSender, "commands.xp.success.levels", + new Object[] { Integer.valueOf(var6), var3.getEntityName() }); + } + } else { + if (var7) { + throw new WrongUsageException("commands.xp.failure.widthdrawXp", new Object[0]); + } + + var3.addExperience(var6); + notifyAdmins(par1ICommandSender, "commands.xp.success", + new Object[] { Integer.valueOf(var6), var3.getEntityName() }); + } + } + } + + /** + * Adds the strings available in this command to the given list of tab + * completion options. + */ + public List addTabCompletionOptions(ICommandSender par1ICommandSender, String[] par2ArrayOfStr) { + return par2ArrayOfStr.length == 2 ? getListOfStringsMatchingLastWord(par2ArrayOfStr, this.getAllUsernames()) + : null; + } + + protected String[] getAllUsernames() { + return MinecraftServer.getServer().getAllUsernames(); + } + + /** + * Return whether the specified command parameter index is a username parameter. + */ + public boolean isUsernameIndex(String[] par1ArrayOfStr, int par2) { + return par2 == 1; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ComparatorClassSorter.java b/sp-server/src/main/java/net/minecraft/src/ComparatorClassSorter.java new file mode 100644 index 0000000..affaf64 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ComparatorClassSorter.java @@ -0,0 +1,21 @@ +package net.minecraft.src; + +import java.util.Comparator; + +class ComparatorClassSorter implements Comparator { + final CallableSuspiciousClasses theSuspiciousClasses; + + ComparatorClassSorter(CallableSuspiciousClasses par1CallableSuspiciousClasses) { + this.theSuspiciousClasses = par1CallableSuspiciousClasses; + } + + public int func_85081_a(Class par1Class, Class par2Class) { + String var3 = par1Class.getPackage() == null ? "" : par1Class.getPackage().getName(); + String var4 = par2Class.getPackage() == null ? "" : par2Class.getPackage().getName(); + return var3.compareTo(var4); + } + + public int compare(Object par1Obj, Object par2Obj) { + return this.func_85081_a((Class) par1Obj, (Class) par2Obj); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ComponentMineshaftCorridor.java b/sp-server/src/main/java/net/minecraft/src/ComponentMineshaftCorridor.java new file mode 100644 index 0000000..df7aeb0 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ComponentMineshaftCorridor.java @@ -0,0 +1,323 @@ +package net.minecraft.src; + +import java.util.List; +import java.util.Random; + +public class ComponentMineshaftCorridor extends StructureComponent { + private final boolean hasRails; + private final boolean hasSpiders; + private boolean spawnerPlaced; + + /** + * A count of the different sections of this mine. The space between ceiling + * supports. + */ + private int sectionCount; + + public ComponentMineshaftCorridor(int par1, Random par2Random, StructureBoundingBox par3StructureBoundingBox, + int par4) { + super(par1); + this.coordBaseMode = par4; + this.boundingBox = par3StructureBoundingBox; + this.hasRails = par2Random.nextInt(3) == 0; + this.hasSpiders = !this.hasRails && par2Random.nextInt(23) == 0; + + if (this.coordBaseMode != 2 && this.coordBaseMode != 0) { + this.sectionCount = par3StructureBoundingBox.getXSize() / 5; + } else { + this.sectionCount = par3StructureBoundingBox.getZSize() / 5; + } + } + + public static StructureBoundingBox findValidPlacement(List par0List, Random par1Random, int par2, int par3, + int par4, int par5) { + StructureBoundingBox var6 = new StructureBoundingBox(par2, par3, par4, par2, par3 + 2, par4); + int var7; + + for (var7 = par1Random.nextInt(3) + 2; var7 > 0; --var7) { + int var8 = var7 * 5; + + switch (par5) { + case 0: + var6.maxX = par2 + 2; + var6.maxZ = par4 + (var8 - 1); + break; + + case 1: + var6.minX = par2 - (var8 - 1); + var6.maxZ = par4 + 2; + break; + + case 2: + var6.maxX = par2 + 2; + var6.minZ = par4 - (var8 - 1); + break; + + case 3: + var6.maxX = par2 + (var8 - 1); + var6.maxZ = par4 + 2; + } + + if (StructureComponent.findIntersecting(par0List, var6) == null) { + break; + } + } + + return var7 > 0 ? var6 : null; + } + + /** + * Initiates construction of the Structure Component picked, at the current + * Location of StructGen + */ + public void buildComponent(StructureComponent par1StructureComponent, List par2List, Random par3Random) { + int var4 = this.getComponentType(); + int var5 = par3Random.nextInt(4); + + switch (this.coordBaseMode) { + case 0: + if (var5 <= 1) { + StructureMineshaftPieces.getNextComponent(par1StructureComponent, par2List, par3Random, + this.boundingBox.minX, this.boundingBox.minY - 1 + par3Random.nextInt(3), + this.boundingBox.maxZ + 1, this.coordBaseMode, var4); + } else if (var5 == 2) { + StructureMineshaftPieces.getNextComponent(par1StructureComponent, par2List, par3Random, + this.boundingBox.minX - 1, this.boundingBox.minY - 1 + par3Random.nextInt(3), + this.boundingBox.maxZ - 3, 1, var4); + } else { + StructureMineshaftPieces.getNextComponent(par1StructureComponent, par2List, par3Random, + this.boundingBox.maxX + 1, this.boundingBox.minY - 1 + par3Random.nextInt(3), + this.boundingBox.maxZ - 3, 3, var4); + } + + break; + + case 1: + if (var5 <= 1) { + StructureMineshaftPieces.getNextComponent(par1StructureComponent, par2List, par3Random, + this.boundingBox.minX - 1, this.boundingBox.minY - 1 + par3Random.nextInt(3), + this.boundingBox.minZ, this.coordBaseMode, var4); + } else if (var5 == 2) { + StructureMineshaftPieces.getNextComponent(par1StructureComponent, par2List, par3Random, + this.boundingBox.minX, this.boundingBox.minY - 1 + par3Random.nextInt(3), + this.boundingBox.minZ - 1, 2, var4); + } else { + StructureMineshaftPieces.getNextComponent(par1StructureComponent, par2List, par3Random, + this.boundingBox.minX, this.boundingBox.minY - 1 + par3Random.nextInt(3), + this.boundingBox.maxZ + 1, 0, var4); + } + + break; + + case 2: + if (var5 <= 1) { + StructureMineshaftPieces.getNextComponent(par1StructureComponent, par2List, par3Random, + this.boundingBox.minX, this.boundingBox.minY - 1 + par3Random.nextInt(3), + this.boundingBox.minZ - 1, this.coordBaseMode, var4); + } else if (var5 == 2) { + StructureMineshaftPieces.getNextComponent(par1StructureComponent, par2List, par3Random, + this.boundingBox.minX - 1, this.boundingBox.minY - 1 + par3Random.nextInt(3), + this.boundingBox.minZ, 1, var4); + } else { + StructureMineshaftPieces.getNextComponent(par1StructureComponent, par2List, par3Random, + this.boundingBox.maxX + 1, this.boundingBox.minY - 1 + par3Random.nextInt(3), + this.boundingBox.minZ, 3, var4); + } + + break; + + case 3: + if (var5 <= 1) { + StructureMineshaftPieces.getNextComponent(par1StructureComponent, par2List, par3Random, + this.boundingBox.maxX + 1, this.boundingBox.minY - 1 + par3Random.nextInt(3), + this.boundingBox.minZ, this.coordBaseMode, var4); + } else if (var5 == 2) { + StructureMineshaftPieces.getNextComponent(par1StructureComponent, par2List, par3Random, + this.boundingBox.maxX - 3, this.boundingBox.minY - 1 + par3Random.nextInt(3), + this.boundingBox.minZ - 1, 2, var4); + } else { + StructureMineshaftPieces.getNextComponent(par1StructureComponent, par2List, par3Random, + this.boundingBox.maxX - 3, this.boundingBox.minY - 1 + par3Random.nextInt(3), + this.boundingBox.maxZ + 1, 0, var4); + } + } + + if (var4 < 8) { + int var6; + int var7; + + if (this.coordBaseMode != 2 && this.coordBaseMode != 0) { + for (var6 = this.boundingBox.minX + 3; var6 + 3 <= this.boundingBox.maxX; var6 += 5) { + var7 = par3Random.nextInt(5); + + if (var7 == 0) { + StructureMineshaftPieces.getNextComponent(par1StructureComponent, par2List, par3Random, var6, + this.boundingBox.minY, this.boundingBox.minZ - 1, 2, var4 + 1); + } else if (var7 == 1) { + StructureMineshaftPieces.getNextComponent(par1StructureComponent, par2List, par3Random, var6, + this.boundingBox.minY, this.boundingBox.maxZ + 1, 0, var4 + 1); + } + } + } else { + for (var6 = this.boundingBox.minZ + 3; var6 + 3 <= this.boundingBox.maxZ; var6 += 5) { + var7 = par3Random.nextInt(5); + + if (var7 == 0) { + StructureMineshaftPieces.getNextComponent(par1StructureComponent, par2List, par3Random, + this.boundingBox.minX - 1, this.boundingBox.minY, var6, 1, var4 + 1); + } else if (var7 == 1) { + StructureMineshaftPieces.getNextComponent(par1StructureComponent, par2List, par3Random, + this.boundingBox.maxX + 1, this.boundingBox.minY, var6, 3, var4 + 1); + } + } + } + } + } + + /** + * Used to generate chests with items in it. ex: Temple Chests, Village + * Blacksmith Chests, Mineshaft Chests. + */ + protected boolean generateStructureChestContents(World par1World, StructureBoundingBox par2StructureBoundingBox, + Random par3Random, int par4, int par5, int par6, + WeightedRandomChestContent[] par7ArrayOfWeightedRandomChestContent, int par8) { + int var9 = this.getXWithOffset(par4, par6); + int var10 = this.getYWithOffset(par5); + int var11 = this.getZWithOffset(par4, par6); + + if (par2StructureBoundingBox.isVecInside(var9, var10, var11) && par1World.getBlockId(var9, var10, var11) == 0) { + par1World.setBlock(var9, var10, var11, Block.rail.blockID, + this.getMetadataWithOffset(Block.rail.blockID, par3Random.nextBoolean() ? 1 : 0), 2); + EntityMinecartChest var12 = new EntityMinecartChest(par1World, (double) ((float) var9 + 0.5F), + (double) ((float) var10 + 0.5F), (double) ((float) var11 + 0.5F)); + WeightedRandomChestContent.generateChestContents(par3Random, par7ArrayOfWeightedRandomChestContent, var12, + par8); + par1World.spawnEntityInWorld(var12); + return true; + } else { + return false; + } + } + + /** + * second Part of Structure generating, this for example places Spiderwebs, Mob + * Spawners, it closes Mineshafts at the end, it adds Fences... + */ + public boolean addComponentParts(World par1World, Random par2Random, + StructureBoundingBox par3StructureBoundingBox) { + if (this.isLiquidInStructureBoundingBox(par1World, par3StructureBoundingBox)) { + return false; + } else { + int var8 = this.sectionCount * 5 - 1; + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 0, 0, 2, 1, var8, 0, 0, false); + this.randomlyFillWithBlocks(par1World, par3StructureBoundingBox, par2Random, 0.8F, 0, 2, 0, 2, 2, var8, 0, + 0, false); + + if (this.hasSpiders) { + this.randomlyFillWithBlocks(par1World, par3StructureBoundingBox, par2Random, 0.6F, 0, 0, 0, 2, 1, var8, + Block.web.blockID, 0, false); + } + + int var9; + int var10; + int var11; + + for (var9 = 0; var9 < this.sectionCount; ++var9) { + var10 = 2 + var9 * 5; + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 0, var10, 0, 1, var10, Block.fence.blockID, + 0, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 2, 0, var10, 2, 1, var10, Block.fence.blockID, + 0, false); + + if (par2Random.nextInt(4) == 0) { + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 2, var10, 0, 2, var10, + Block.planks.blockID, 0, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 2, 2, var10, 2, 2, var10, + Block.planks.blockID, 0, false); + } else { + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 2, var10, 2, 2, var10, + Block.planks.blockID, 0, false); + } + + this.randomlyPlaceBlock(par1World, par3StructureBoundingBox, par2Random, 0.1F, 0, 2, var10 - 1, + Block.web.blockID, 0); + this.randomlyPlaceBlock(par1World, par3StructureBoundingBox, par2Random, 0.1F, 2, 2, var10 - 1, + Block.web.blockID, 0); + this.randomlyPlaceBlock(par1World, par3StructureBoundingBox, par2Random, 0.1F, 0, 2, var10 + 1, + Block.web.blockID, 0); + this.randomlyPlaceBlock(par1World, par3StructureBoundingBox, par2Random, 0.1F, 2, 2, var10 + 1, + Block.web.blockID, 0); + this.randomlyPlaceBlock(par1World, par3StructureBoundingBox, par2Random, 0.05F, 0, 2, var10 - 2, + Block.web.blockID, 0); + this.randomlyPlaceBlock(par1World, par3StructureBoundingBox, par2Random, 0.05F, 2, 2, var10 - 2, + Block.web.blockID, 0); + this.randomlyPlaceBlock(par1World, par3StructureBoundingBox, par2Random, 0.05F, 0, 2, var10 + 2, + Block.web.blockID, 0); + this.randomlyPlaceBlock(par1World, par3StructureBoundingBox, par2Random, 0.05F, 2, 2, var10 + 2, + Block.web.blockID, 0); + this.randomlyPlaceBlock(par1World, par3StructureBoundingBox, par2Random, 0.05F, 1, 2, var10 - 1, + Block.torchWood.blockID, 0); + this.randomlyPlaceBlock(par1World, par3StructureBoundingBox, par2Random, 0.05F, 1, 2, var10 + 1, + Block.torchWood.blockID, 0); + + if (par2Random.nextInt(100) == 0) { + this.generateStructureChestContents(par1World, par3StructureBoundingBox, par2Random, 2, 0, + var10 - 1, + WeightedRandomChestContent.func_92080_a(StructureMineshaftPieces.func_78816_a(), + new WeightedRandomChestContent[] { Item.enchantedBook.func_92114_b(par2Random) }), + 3 + par2Random.nextInt(4)); + } + + if (par2Random.nextInt(100) == 0) { + this.generateStructureChestContents(par1World, par3StructureBoundingBox, par2Random, 0, 0, + var10 + 1, + WeightedRandomChestContent.func_92080_a(StructureMineshaftPieces.func_78816_a(), + new WeightedRandomChestContent[] { Item.enchantedBook.func_92114_b(par2Random) }), + 3 + par2Random.nextInt(4)); + } + + if (this.hasSpiders && !this.spawnerPlaced) { + var11 = this.getYWithOffset(0); + int var12 = var10 - 1 + par2Random.nextInt(3); + int var13 = this.getXWithOffset(1, var12); + var12 = this.getZWithOffset(1, var12); + + if (par3StructureBoundingBox.isVecInside(var13, var11, var12)) { + this.spawnerPlaced = true; + par1World.setBlock(var13, var11, var12, Block.mobSpawner.blockID, 0, 2); + TileEntityMobSpawner var14 = (TileEntityMobSpawner) par1World.getBlockTileEntity(var13, var11, + var12); + + if (var14 != null) { + var14.func_98049_a().setMobID("CaveSpider"); + } + } + } + } + + for (var9 = 0; var9 <= 2; ++var9) { + for (var10 = 0; var10 <= var8; ++var10) { + var11 = this.getBlockIdAtCurrentPosition(par1World, var9, -1, var10, par3StructureBoundingBox); + + if (var11 == 0) { + this.placeBlockAtCurrentPosition(par1World, Block.planks.blockID, 0, var9, -1, var10, + par3StructureBoundingBox); + } + } + } + + if (this.hasRails) { + for (var9 = 0; var9 <= var8; ++var9) { + var10 = this.getBlockIdAtCurrentPosition(par1World, 1, -1, var9, par3StructureBoundingBox); + + if (var10 > 0 && Block.opaqueCubeLookup[var10]) { + this.randomlyPlaceBlock(par1World, par3StructureBoundingBox, par2Random, 0.7F, 1, 0, var9, + Block.rail.blockID, this.getMetadataWithOffset(Block.rail.blockID, 0)); + } + } + } + + return true; + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ComponentMineshaftCross.java b/sp-server/src/main/java/net/minecraft/src/ComponentMineshaftCross.java new file mode 100644 index 0000000..ee1663c --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ComponentMineshaftCross.java @@ -0,0 +1,183 @@ +package net.minecraft.src; + +import java.util.List; +import java.util.Random; + +public class ComponentMineshaftCross extends StructureComponent { + private final int corridorDirection; + private final boolean isMultipleFloors; + + public ComponentMineshaftCross(int par1, Random par2Random, StructureBoundingBox par3StructureBoundingBox, + int par4) { + super(par1); + this.corridorDirection = par4; + this.boundingBox = par3StructureBoundingBox; + this.isMultipleFloors = par3StructureBoundingBox.getYSize() > 3; + } + + public static StructureBoundingBox findValidPlacement(List par0List, Random par1Random, int par2, int par3, + int par4, int par5) { + StructureBoundingBox var6 = new StructureBoundingBox(par2, par3, par4, par2, par3 + 2, par4); + + if (par1Random.nextInt(4) == 0) { + var6.maxY += 4; + } + + switch (par5) { + case 0: + var6.minX = par2 - 1; + var6.maxX = par2 + 3; + var6.maxZ = par4 + 4; + break; + + case 1: + var6.minX = par2 - 4; + var6.minZ = par4 - 1; + var6.maxZ = par4 + 3; + break; + + case 2: + var6.minX = par2 - 1; + var6.maxX = par2 + 3; + var6.minZ = par4 - 4; + break; + + case 3: + var6.maxX = par2 + 4; + var6.minZ = par4 - 1; + var6.maxZ = par4 + 3; + } + + return StructureComponent.findIntersecting(par0List, var6) != null ? null : var6; + } + + /** + * Initiates construction of the Structure Component picked, at the current + * Location of StructGen + */ + public void buildComponent(StructureComponent par1StructureComponent, List par2List, Random par3Random) { + int var4 = this.getComponentType(); + + switch (this.corridorDirection) { + case 0: + StructureMineshaftPieces.getNextComponent(par1StructureComponent, par2List, par3Random, + this.boundingBox.minX + 1, this.boundingBox.minY, this.boundingBox.maxZ + 1, 0, var4); + StructureMineshaftPieces.getNextComponent(par1StructureComponent, par2List, par3Random, + this.boundingBox.minX - 1, this.boundingBox.minY, this.boundingBox.minZ + 1, 1, var4); + StructureMineshaftPieces.getNextComponent(par1StructureComponent, par2List, par3Random, + this.boundingBox.maxX + 1, this.boundingBox.minY, this.boundingBox.minZ + 1, 3, var4); + break; + + case 1: + StructureMineshaftPieces.getNextComponent(par1StructureComponent, par2List, par3Random, + this.boundingBox.minX + 1, this.boundingBox.minY, this.boundingBox.minZ - 1, 2, var4); + StructureMineshaftPieces.getNextComponent(par1StructureComponent, par2List, par3Random, + this.boundingBox.minX + 1, this.boundingBox.minY, this.boundingBox.maxZ + 1, 0, var4); + StructureMineshaftPieces.getNextComponent(par1StructureComponent, par2List, par3Random, + this.boundingBox.minX - 1, this.boundingBox.minY, this.boundingBox.minZ + 1, 1, var4); + break; + + case 2: + StructureMineshaftPieces.getNextComponent(par1StructureComponent, par2List, par3Random, + this.boundingBox.minX + 1, this.boundingBox.minY, this.boundingBox.minZ - 1, 2, var4); + StructureMineshaftPieces.getNextComponent(par1StructureComponent, par2List, par3Random, + this.boundingBox.minX - 1, this.boundingBox.minY, this.boundingBox.minZ + 1, 1, var4); + StructureMineshaftPieces.getNextComponent(par1StructureComponent, par2List, par3Random, + this.boundingBox.maxX + 1, this.boundingBox.minY, this.boundingBox.minZ + 1, 3, var4); + break; + + case 3: + StructureMineshaftPieces.getNextComponent(par1StructureComponent, par2List, par3Random, + this.boundingBox.minX + 1, this.boundingBox.minY, this.boundingBox.minZ - 1, 2, var4); + StructureMineshaftPieces.getNextComponent(par1StructureComponent, par2List, par3Random, + this.boundingBox.minX + 1, this.boundingBox.minY, this.boundingBox.maxZ + 1, 0, var4); + StructureMineshaftPieces.getNextComponent(par1StructureComponent, par2List, par3Random, + this.boundingBox.maxX + 1, this.boundingBox.minY, this.boundingBox.minZ + 1, 3, var4); + } + + if (this.isMultipleFloors) { + if (par3Random.nextBoolean()) { + StructureMineshaftPieces.getNextComponent(par1StructureComponent, par2List, par3Random, + this.boundingBox.minX + 1, this.boundingBox.minY + 3 + 1, this.boundingBox.minZ - 1, 2, var4); + } + + if (par3Random.nextBoolean()) { + StructureMineshaftPieces.getNextComponent(par1StructureComponent, par2List, par3Random, + this.boundingBox.minX - 1, this.boundingBox.minY + 3 + 1, this.boundingBox.minZ + 1, 1, var4); + } + + if (par3Random.nextBoolean()) { + StructureMineshaftPieces.getNextComponent(par1StructureComponent, par2List, par3Random, + this.boundingBox.maxX + 1, this.boundingBox.minY + 3 + 1, this.boundingBox.minZ + 1, 3, var4); + } + + if (par3Random.nextBoolean()) { + StructureMineshaftPieces.getNextComponent(par1StructureComponent, par2List, par3Random, + this.boundingBox.minX + 1, this.boundingBox.minY + 3 + 1, this.boundingBox.maxZ + 1, 0, var4); + } + } + } + + /** + * second Part of Structure generating, this for example places Spiderwebs, Mob + * Spawners, it closes Mineshafts at the end, it adds Fences... + */ + public boolean addComponentParts(World par1World, Random par2Random, + StructureBoundingBox par3StructureBoundingBox) { + if (this.isLiquidInStructureBoundingBox(par1World, par3StructureBoundingBox)) { + return false; + } else { + if (this.isMultipleFloors) { + this.fillWithBlocks(par1World, par3StructureBoundingBox, this.boundingBox.minX + 1, + this.boundingBox.minY, this.boundingBox.minZ, this.boundingBox.maxX - 1, + this.boundingBox.minY + 3 - 1, this.boundingBox.maxZ, 0, 0, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, this.boundingBox.minX, this.boundingBox.minY, + this.boundingBox.minZ + 1, this.boundingBox.maxX, this.boundingBox.minY + 3 - 1, + this.boundingBox.maxZ - 1, 0, 0, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, this.boundingBox.minX + 1, + this.boundingBox.maxY - 2, this.boundingBox.minZ, this.boundingBox.maxX - 1, + this.boundingBox.maxY, this.boundingBox.maxZ, 0, 0, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, this.boundingBox.minX, + this.boundingBox.maxY - 2, this.boundingBox.minZ + 1, this.boundingBox.maxX, + this.boundingBox.maxY, this.boundingBox.maxZ - 1, 0, 0, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, this.boundingBox.minX + 1, + this.boundingBox.minY + 3, this.boundingBox.minZ + 1, this.boundingBox.maxX - 1, + this.boundingBox.minY + 3, this.boundingBox.maxZ - 1, 0, 0, false); + } else { + this.fillWithBlocks(par1World, par3StructureBoundingBox, this.boundingBox.minX + 1, + this.boundingBox.minY, this.boundingBox.minZ, this.boundingBox.maxX - 1, this.boundingBox.maxY, + this.boundingBox.maxZ, 0, 0, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, this.boundingBox.minX, this.boundingBox.minY, + this.boundingBox.minZ + 1, this.boundingBox.maxX, this.boundingBox.maxY, + this.boundingBox.maxZ - 1, 0, 0, false); + } + + this.fillWithBlocks(par1World, par3StructureBoundingBox, this.boundingBox.minX + 1, this.boundingBox.minY, + this.boundingBox.minZ + 1, this.boundingBox.minX + 1, this.boundingBox.maxY, + this.boundingBox.minZ + 1, Block.planks.blockID, 0, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, this.boundingBox.minX + 1, this.boundingBox.minY, + this.boundingBox.maxZ - 1, this.boundingBox.minX + 1, this.boundingBox.maxY, + this.boundingBox.maxZ - 1, Block.planks.blockID, 0, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, this.boundingBox.maxX - 1, this.boundingBox.minY, + this.boundingBox.minZ + 1, this.boundingBox.maxX - 1, this.boundingBox.maxY, + this.boundingBox.minZ + 1, Block.planks.blockID, 0, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, this.boundingBox.maxX - 1, this.boundingBox.minY, + this.boundingBox.maxZ - 1, this.boundingBox.maxX - 1, this.boundingBox.maxY, + this.boundingBox.maxZ - 1, Block.planks.blockID, 0, false); + + for (int var4 = this.boundingBox.minX; var4 <= this.boundingBox.maxX; ++var4) { + for (int var5 = this.boundingBox.minZ; var5 <= this.boundingBox.maxZ; ++var5) { + int var6 = this.getBlockIdAtCurrentPosition(par1World, var4, this.boundingBox.minY - 1, var5, + par3StructureBoundingBox); + + if (var6 == 0) { + this.placeBlockAtCurrentPosition(par1World, Block.planks.blockID, 0, var4, + this.boundingBox.minY - 1, var5, par3StructureBoundingBox); + } + } + } + + return true; + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ComponentMineshaftRoom.java b/sp-server/src/main/java/net/minecraft/src/ComponentMineshaftRoom.java new file mode 100644 index 0000000..fbd5b95 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ComponentMineshaftRoom.java @@ -0,0 +1,136 @@ +package net.minecraft.src; + +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Random; + +public class ComponentMineshaftRoom extends StructureComponent { + /** List of other Mineshaft components linked to this room. */ + private List roomsLinkedToTheRoom = new LinkedList(); + + public ComponentMineshaftRoom(int par1, Random par2Random, int par3, int par4) { + super(par1); + this.boundingBox = new StructureBoundingBox(par3, 50, par4, par3 + 7 + par2Random.nextInt(6), + 54 + par2Random.nextInt(6), par4 + 7 + par2Random.nextInt(6)); + } + + /** + * Initiates construction of the Structure Component picked, at the current + * Location of StructGen + */ + public void buildComponent(StructureComponent par1StructureComponent, List par2List, Random par3Random) { + int var4 = this.getComponentType(); + int var6 = this.boundingBox.getYSize() - 3 - 1; + + if (var6 <= 0) { + var6 = 1; + } + + int var5; + StructureComponent var7; + StructureBoundingBox var8; + + for (var5 = 0; var5 < this.boundingBox.getXSize(); var5 += 4) { + var5 += par3Random.nextInt(this.boundingBox.getXSize()); + + if (var5 + 3 > this.boundingBox.getXSize()) { + break; + } + + var7 = StructureMineshaftPieces.getNextComponent(par1StructureComponent, par2List, par3Random, + this.boundingBox.minX + var5, this.boundingBox.minY + par3Random.nextInt(var6) + 1, + this.boundingBox.minZ - 1, 2, var4); + + if (var7 != null) { + var8 = var7.getBoundingBox(); + this.roomsLinkedToTheRoom.add(new StructureBoundingBox(var8.minX, var8.minY, this.boundingBox.minZ, + var8.maxX, var8.maxY, this.boundingBox.minZ + 1)); + } + } + + for (var5 = 0; var5 < this.boundingBox.getXSize(); var5 += 4) { + var5 += par3Random.nextInt(this.boundingBox.getXSize()); + + if (var5 + 3 > this.boundingBox.getXSize()) { + break; + } + + var7 = StructureMineshaftPieces.getNextComponent(par1StructureComponent, par2List, par3Random, + this.boundingBox.minX + var5, this.boundingBox.minY + par3Random.nextInt(var6) + 1, + this.boundingBox.maxZ + 1, 0, var4); + + if (var7 != null) { + var8 = var7.getBoundingBox(); + this.roomsLinkedToTheRoom.add(new StructureBoundingBox(var8.minX, var8.minY, this.boundingBox.maxZ - 1, + var8.maxX, var8.maxY, this.boundingBox.maxZ)); + } + } + + for (var5 = 0; var5 < this.boundingBox.getZSize(); var5 += 4) { + var5 += par3Random.nextInt(this.boundingBox.getZSize()); + + if (var5 + 3 > this.boundingBox.getZSize()) { + break; + } + + var7 = StructureMineshaftPieces.getNextComponent(par1StructureComponent, par2List, par3Random, + this.boundingBox.minX - 1, this.boundingBox.minY + par3Random.nextInt(var6) + 1, + this.boundingBox.minZ + var5, 1, var4); + + if (var7 != null) { + var8 = var7.getBoundingBox(); + this.roomsLinkedToTheRoom.add(new StructureBoundingBox(this.boundingBox.minX, var8.minY, var8.minZ, + this.boundingBox.minX + 1, var8.maxY, var8.maxZ)); + } + } + + for (var5 = 0; var5 < this.boundingBox.getZSize(); var5 += 4) { + var5 += par3Random.nextInt(this.boundingBox.getZSize()); + + if (var5 + 3 > this.boundingBox.getZSize()) { + break; + } + + var7 = StructureMineshaftPieces.getNextComponent(par1StructureComponent, par2List, par3Random, + this.boundingBox.maxX + 1, this.boundingBox.minY + par3Random.nextInt(var6) + 1, + this.boundingBox.minZ + var5, 3, var4); + + if (var7 != null) { + var8 = var7.getBoundingBox(); + this.roomsLinkedToTheRoom.add(new StructureBoundingBox(this.boundingBox.maxX - 1, var8.minY, var8.minZ, + this.boundingBox.maxX, var8.maxY, var8.maxZ)); + } + } + } + + /** + * second Part of Structure generating, this for example places Spiderwebs, Mob + * Spawners, it closes Mineshafts at the end, it adds Fences... + */ + public boolean addComponentParts(World par1World, Random par2Random, + StructureBoundingBox par3StructureBoundingBox) { + if (this.isLiquidInStructureBoundingBox(par1World, par3StructureBoundingBox)) { + return false; + } else { + this.fillWithBlocks(par1World, par3StructureBoundingBox, this.boundingBox.minX, this.boundingBox.minY, + this.boundingBox.minZ, this.boundingBox.maxX, this.boundingBox.minY, this.boundingBox.maxZ, + Block.dirt.blockID, 0, true); + this.fillWithBlocks(par1World, par3StructureBoundingBox, this.boundingBox.minX, this.boundingBox.minY + 1, + this.boundingBox.minZ, this.boundingBox.maxX, + Math.min(this.boundingBox.minY + 3, this.boundingBox.maxY), this.boundingBox.maxZ, 0, 0, false); + Iterator var4 = this.roomsLinkedToTheRoom.iterator(); + + while (var4.hasNext()) { + StructureBoundingBox var5 = (StructureBoundingBox) var4.next(); + this.fillWithBlocks(par1World, par3StructureBoundingBox, var5.minX, var5.maxY - 2, var5.minZ, var5.maxX, + var5.maxY, var5.maxZ, 0, 0, false); + } + + this.randomlyRareFillWithBlocks(par1World, par3StructureBoundingBox, this.boundingBox.minX, + this.boundingBox.minY + 4, this.boundingBox.minZ, this.boundingBox.maxX, this.boundingBox.maxY, + this.boundingBox.maxZ, 0, false); + return true; + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ComponentMineshaftStairs.java b/sp-server/src/main/java/net/minecraft/src/ComponentMineshaftStairs.java new file mode 100644 index 0000000..da030b5 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ComponentMineshaftStairs.java @@ -0,0 +1,94 @@ +package net.minecraft.src; + +import java.util.List; +import java.util.Random; + +public class ComponentMineshaftStairs extends StructureComponent { + public ComponentMineshaftStairs(int par1, Random par2Random, StructureBoundingBox par3StructureBoundingBox, + int par4) { + super(par1); + this.coordBaseMode = par4; + this.boundingBox = par3StructureBoundingBox; + } + + /** + * Trys to find a valid place to put this component. + */ + public static StructureBoundingBox findValidPlacement(List par0List, Random par1Random, int par2, int par3, + int par4, int par5) { + StructureBoundingBox var6 = new StructureBoundingBox(par2, par3 - 5, par4, par2, par3 + 2, par4); + + switch (par5) { + case 0: + var6.maxX = par2 + 2; + var6.maxZ = par4 + 8; + break; + + case 1: + var6.minX = par2 - 8; + var6.maxZ = par4 + 2; + break; + + case 2: + var6.maxX = par2 + 2; + var6.minZ = par4 - 8; + break; + + case 3: + var6.maxX = par2 + 8; + var6.maxZ = par4 + 2; + } + + return StructureComponent.findIntersecting(par0List, var6) != null ? null : var6; + } + + /** + * Initiates construction of the Structure Component picked, at the current + * Location of StructGen + */ + public void buildComponent(StructureComponent par1StructureComponent, List par2List, Random par3Random) { + int var4 = this.getComponentType(); + + switch (this.coordBaseMode) { + case 0: + StructureMineshaftPieces.getNextComponent(par1StructureComponent, par2List, par3Random, + this.boundingBox.minX, this.boundingBox.minY, this.boundingBox.maxZ + 1, 0, var4); + break; + + case 1: + StructureMineshaftPieces.getNextComponent(par1StructureComponent, par2List, par3Random, + this.boundingBox.minX - 1, this.boundingBox.minY, this.boundingBox.minZ, 1, var4); + break; + + case 2: + StructureMineshaftPieces.getNextComponent(par1StructureComponent, par2List, par3Random, + this.boundingBox.minX, this.boundingBox.minY, this.boundingBox.minZ - 1, 2, var4); + break; + + case 3: + StructureMineshaftPieces.getNextComponent(par1StructureComponent, par2List, par3Random, + this.boundingBox.maxX + 1, this.boundingBox.minY, this.boundingBox.minZ, 3, var4); + } + } + + /** + * second Part of Structure generating, this for example places Spiderwebs, Mob + * Spawners, it closes Mineshafts at the end, it adds Fences... + */ + public boolean addComponentParts(World par1World, Random par2Random, + StructureBoundingBox par3StructureBoundingBox) { + if (this.isLiquidInStructureBoundingBox(par1World, par3StructureBoundingBox)) { + return false; + } else { + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 5, 0, 2, 7, 1, 0, 0, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 0, 7, 2, 2, 8, 0, 0, false); + + for (int var4 = 0; var4 < 5; ++var4) { + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 5 - var4 - (var4 < 4 ? 1 : 0), 2 + var4, 2, + 7 - var4, 2 + var4, 0, 0, false); + } + + return true; + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ComponentNetherBridgeCorridor.java b/sp-server/src/main/java/net/minecraft/src/ComponentNetherBridgeCorridor.java new file mode 100644 index 0000000..33db437 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ComponentNetherBridgeCorridor.java @@ -0,0 +1,71 @@ +package net.minecraft.src; + +import java.util.List; +import java.util.Random; + +public class ComponentNetherBridgeCorridor extends ComponentNetherBridgePiece { + public ComponentNetherBridgeCorridor(int par1, Random par2Random, StructureBoundingBox par3StructureBoundingBox, + int par4) { + super(par1); + this.coordBaseMode = par4; + this.boundingBox = par3StructureBoundingBox; + } + + /** + * Initiates construction of the Structure Component picked, at the current + * Location of StructGen + */ + public void buildComponent(StructureComponent par1StructureComponent, List par2List, Random par3Random) { + this.getNextComponentX((ComponentNetherBridgeStartPiece) par1StructureComponent, par2List, par3Random, 0, 1, + true); + } + + /** + * Creates and returns a new component piece. Or null if it could not find + * enough room to place it. + */ + public static ComponentNetherBridgeCorridor createValidComponent(List par0List, Random par1Random, int par2, + int par3, int par4, int par5, int par6) { + StructureBoundingBox var7 = StructureBoundingBox.getComponentToAddBoundingBox(par2, par3, par4, -1, 0, 0, 5, 7, + 5, par5); + return isAboveGround(var7) && StructureComponent.findIntersecting(par0List, var7) == null + ? new ComponentNetherBridgeCorridor(par6, par1Random, var7, par5) + : null; + } + + /** + * second Part of Structure generating, this for example places Spiderwebs, Mob + * Spawners, it closes Mineshafts at the end, it adds Fences... + */ + public boolean addComponentParts(World par1World, Random par2Random, + StructureBoundingBox par3StructureBoundingBox) { + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 0, 0, 4, 1, 4, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 2, 0, 4, 5, 4, 0, 0, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 4, 2, 0, 4, 5, 4, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 4, 3, 1, 4, 4, 1, Block.netherFence.blockID, + Block.netherFence.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 4, 3, 3, 4, 4, 3, Block.netherFence.blockID, + Block.netherFence.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 2, 0, 0, 5, 0, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 2, 4, 3, 5, 4, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 1, 3, 4, 1, 4, 4, Block.netherFence.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 3, 3, 4, 3, 4, 4, Block.netherFence.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 6, 0, 4, 6, 4, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + + for (int var4 = 0; var4 <= 4; ++var4) { + for (int var5 = 0; var5 <= 4; ++var5) { + this.fillCurrentPositionBlocksDownwards(par1World, Block.netherBrick.blockID, 0, var4, -1, var5, + par3StructureBoundingBox); + } + } + + return true; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ComponentNetherBridgeCorridor2.java b/sp-server/src/main/java/net/minecraft/src/ComponentNetherBridgeCorridor2.java new file mode 100644 index 0000000..6598459 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ComponentNetherBridgeCorridor2.java @@ -0,0 +1,71 @@ +package net.minecraft.src; + +import java.util.List; +import java.util.Random; + +public class ComponentNetherBridgeCorridor2 extends ComponentNetherBridgePiece { + public ComponentNetherBridgeCorridor2(int par1, Random par2Random, StructureBoundingBox par3StructureBoundingBox, + int par4) { + super(par1); + this.coordBaseMode = par4; + this.boundingBox = par3StructureBoundingBox; + } + + /** + * Initiates construction of the Structure Component picked, at the current + * Location of StructGen + */ + public void buildComponent(StructureComponent par1StructureComponent, List par2List, Random par3Random) { + this.getNextComponentZ((ComponentNetherBridgeStartPiece) par1StructureComponent, par2List, par3Random, 0, 1, + true); + } + + /** + * Creates and returns a new component piece. Or null if it could not find + * enough room to place it. + */ + public static ComponentNetherBridgeCorridor2 createValidComponent(List par0List, Random par1Random, int par2, + int par3, int par4, int par5, int par6) { + StructureBoundingBox var7 = StructureBoundingBox.getComponentToAddBoundingBox(par2, par3, par4, -1, 0, 0, 5, 7, + 5, par5); + return isAboveGround(var7) && StructureComponent.findIntersecting(par0List, var7) == null + ? new ComponentNetherBridgeCorridor2(par6, par1Random, var7, par5) + : null; + } + + /** + * second Part of Structure generating, this for example places Spiderwebs, Mob + * Spawners, it closes Mineshafts at the end, it adds Fences... + */ + public boolean addComponentParts(World par1World, Random par2Random, + StructureBoundingBox par3StructureBoundingBox) { + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 0, 0, 4, 1, 4, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 2, 0, 4, 5, 4, 0, 0, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 2, 0, 0, 5, 4, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 3, 1, 0, 4, 1, Block.netherFence.blockID, + Block.netherFence.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 3, 3, 0, 4, 3, Block.netherFence.blockID, + Block.netherFence.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 4, 2, 0, 4, 5, 0, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 1, 2, 4, 4, 5, 4, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 1, 3, 4, 1, 4, 4, Block.netherFence.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 3, 3, 4, 3, 4, 4, Block.netherFence.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 6, 0, 4, 6, 4, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + + for (int var4 = 0; var4 <= 4; ++var4) { + for (int var5 = 0; var5 <= 4; ++var5) { + this.fillCurrentPositionBlocksDownwards(par1World, Block.netherBrick.blockID, 0, var4, -1, var5, + par3StructureBoundingBox); + } + } + + return true; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ComponentNetherBridgeCorridor3.java b/sp-server/src/main/java/net/minecraft/src/ComponentNetherBridgeCorridor3.java new file mode 100644 index 0000000..809bb9c --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ComponentNetherBridgeCorridor3.java @@ -0,0 +1,83 @@ +package net.minecraft.src; + +import java.util.List; +import java.util.Random; + +public class ComponentNetherBridgeCorridor3 extends ComponentNetherBridgePiece { + public ComponentNetherBridgeCorridor3(int par1, Random par2Random, StructureBoundingBox par3StructureBoundingBox, + int par4) { + super(par1); + this.coordBaseMode = par4; + this.boundingBox = par3StructureBoundingBox; + } + + /** + * Initiates construction of the Structure Component picked, at the current + * Location of StructGen + */ + public void buildComponent(StructureComponent par1StructureComponent, List par2List, Random par3Random) { + this.getNextComponentNormal((ComponentNetherBridgeStartPiece) par1StructureComponent, par2List, par3Random, 1, + 0, true); + } + + /** + * Creates and returns a new component piece. Or null if it could not find + * enough room to place it. + */ + public static ComponentNetherBridgeCorridor3 createValidComponent(List par0List, Random par1Random, int par2, + int par3, int par4, int par5, int par6) { + StructureBoundingBox var7 = StructureBoundingBox.getComponentToAddBoundingBox(par2, par3, par4, -1, -7, 0, 5, + 14, 10, par5); + return isAboveGround(var7) && StructureComponent.findIntersecting(par0List, var7) == null + ? new ComponentNetherBridgeCorridor3(par6, par1Random, var7, par5) + : null; + } + + /** + * second Part of Structure generating, this for example places Spiderwebs, Mob + * Spawners, it closes Mineshafts at the end, it adds Fences... + */ + public boolean addComponentParts(World par1World, Random par2Random, + StructureBoundingBox par3StructureBoundingBox) { + int var4 = this.getMetadataWithOffset(Block.stairsNetherBrick.blockID, 2); + + for (int var5 = 0; var5 <= 9; ++var5) { + int var6 = Math.max(1, 7 - var5); + int var7 = Math.min(Math.max(var6 + 5, 14 - var5), 13); + int var8 = var5; + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 0, var5, 4, var6, var5, + Block.netherBrick.blockID, Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 1, var6 + 1, var5, 3, var7 - 1, var5, 0, 0, false); + + if (var5 <= 6) { + this.placeBlockAtCurrentPosition(par1World, Block.stairsNetherBrick.blockID, var4, 1, var6 + 1, var5, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stairsNetherBrick.blockID, var4, 2, var6 + 1, var5, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stairsNetherBrick.blockID, var4, 3, var6 + 1, var5, + par3StructureBoundingBox); + } + + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, var7, var5, 4, var7, var5, + Block.netherBrick.blockID, Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, var6 + 1, var5, 0, var7 - 1, var5, + Block.netherBrick.blockID, Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 4, var6 + 1, var5, 4, var7 - 1, var5, + Block.netherBrick.blockID, Block.netherBrick.blockID, false); + + if ((var5 & 1) == 0) { + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, var6 + 2, var5, 0, var6 + 3, var5, + Block.netherFence.blockID, Block.netherFence.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 4, var6 + 2, var5, 4, var6 + 3, var5, + Block.netherFence.blockID, Block.netherFence.blockID, false); + } + + for (int var9 = 0; var9 <= 4; ++var9) { + this.fillCurrentPositionBlocksDownwards(par1World, Block.netherBrick.blockID, 0, var9, -1, var8, + par3StructureBoundingBox); + } + } + + return true; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ComponentNetherBridgeCorridor4.java b/sp-server/src/main/java/net/minecraft/src/ComponentNetherBridgeCorridor4.java new file mode 100644 index 0000000..e2cd597 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ComponentNetherBridgeCorridor4.java @@ -0,0 +1,95 @@ +package net.minecraft.src; + +import java.util.List; +import java.util.Random; + +public class ComponentNetherBridgeCorridor4 extends ComponentNetherBridgePiece { + public ComponentNetherBridgeCorridor4(int par1, Random par2Random, StructureBoundingBox par3StructureBoundingBox, + int par4) { + super(par1); + this.coordBaseMode = par4; + this.boundingBox = par3StructureBoundingBox; + } + + /** + * Initiates construction of the Structure Component picked, at the current + * Location of StructGen + */ + public void buildComponent(StructureComponent par1StructureComponent, List par2List, Random par3Random) { + byte var4 = 1; + + if (this.coordBaseMode == 1 || this.coordBaseMode == 2) { + var4 = 5; + } + + this.getNextComponentX((ComponentNetherBridgeStartPiece) par1StructureComponent, par2List, par3Random, 0, var4, + par3Random.nextInt(8) > 0); + this.getNextComponentZ((ComponentNetherBridgeStartPiece) par1StructureComponent, par2List, par3Random, 0, var4, + par3Random.nextInt(8) > 0); + } + + /** + * Creates and returns a new component piece. Or null if it could not find + * enough room to place it. + */ + public static ComponentNetherBridgeCorridor4 createValidComponent(List par0List, Random par1Random, int par2, + int par3, int par4, int par5, int par6) { + StructureBoundingBox var7 = StructureBoundingBox.getComponentToAddBoundingBox(par2, par3, par4, -3, 0, 0, 9, 7, + 9, par5); + return isAboveGround(var7) && StructureComponent.findIntersecting(par0List, var7) == null + ? new ComponentNetherBridgeCorridor4(par6, par1Random, var7, par5) + : null; + } + + /** + * second Part of Structure generating, this for example places Spiderwebs, Mob + * Spawners, it closes Mineshafts at the end, it adds Fences... + */ + public boolean addComponentParts(World par1World, Random par2Random, + StructureBoundingBox par3StructureBoundingBox) { + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 0, 0, 8, 1, 8, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 2, 0, 8, 5, 8, 0, 0, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 6, 0, 8, 6, 5, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 2, 0, 2, 5, 0, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 6, 2, 0, 8, 5, 0, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 1, 3, 0, 1, 4, 0, Block.netherFence.blockID, + Block.netherFence.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 7, 3, 0, 7, 4, 0, Block.netherFence.blockID, + Block.netherFence.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 2, 4, 8, 2, 8, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 1, 1, 4, 2, 2, 4, 0, 0, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 6, 1, 4, 7, 2, 4, 0, 0, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 3, 8, 8, 3, 8, Block.netherFence.blockID, + Block.netherFence.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 3, 6, 0, 3, 7, Block.netherFence.blockID, + Block.netherFence.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 8, 3, 6, 8, 3, 7, Block.netherFence.blockID, + Block.netherFence.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 3, 4, 0, 5, 5, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 8, 3, 4, 8, 5, 5, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 1, 3, 5, 2, 5, 5, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 6, 3, 5, 7, 5, 5, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 1, 4, 5, 1, 5, 5, Block.netherFence.blockID, + Block.netherFence.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 7, 4, 5, 7, 5, 5, Block.netherFence.blockID, + Block.netherFence.blockID, false); + + for (int var4 = 0; var4 <= 5; ++var4) { + for (int var5 = 0; var5 <= 8; ++var5) { + this.fillCurrentPositionBlocksDownwards(par1World, Block.netherBrick.blockID, 0, var5, -1, var4, + par3StructureBoundingBox); + } + } + + return true; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ComponentNetherBridgeCorridor5.java b/sp-server/src/main/java/net/minecraft/src/ComponentNetherBridgeCorridor5.java new file mode 100644 index 0000000..0c0384c --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ComponentNetherBridgeCorridor5.java @@ -0,0 +1,69 @@ +package net.minecraft.src; + +import java.util.List; +import java.util.Random; + +public class ComponentNetherBridgeCorridor5 extends ComponentNetherBridgePiece { + public ComponentNetherBridgeCorridor5(int par1, Random par2Random, StructureBoundingBox par3StructureBoundingBox, + int par4) { + super(par1); + this.coordBaseMode = par4; + this.boundingBox = par3StructureBoundingBox; + } + + /** + * Initiates construction of the Structure Component picked, at the current + * Location of StructGen + */ + public void buildComponent(StructureComponent par1StructureComponent, List par2List, Random par3Random) { + this.getNextComponentNormal((ComponentNetherBridgeStartPiece) par1StructureComponent, par2List, par3Random, 1, + 0, true); + } + + /** + * Creates and returns a new component piece. Or null if it could not find + * enough room to place it. + */ + public static ComponentNetherBridgeCorridor5 createValidComponent(List par0List, Random par1Random, int par2, + int par3, int par4, int par5, int par6) { + StructureBoundingBox var7 = StructureBoundingBox.getComponentToAddBoundingBox(par2, par3, par4, -1, 0, 0, 5, 7, + 5, par5); + return isAboveGround(var7) && StructureComponent.findIntersecting(par0List, var7) == null + ? new ComponentNetherBridgeCorridor5(par6, par1Random, var7, par5) + : null; + } + + /** + * second Part of Structure generating, this for example places Spiderwebs, Mob + * Spawners, it closes Mineshafts at the end, it adds Fences... + */ + public boolean addComponentParts(World par1World, Random par2Random, + StructureBoundingBox par3StructureBoundingBox) { + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 0, 0, 4, 1, 4, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 2, 0, 4, 5, 4, 0, 0, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 2, 0, 0, 5, 4, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 4, 2, 0, 4, 5, 4, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 3, 1, 0, 4, 1, Block.netherFence.blockID, + Block.netherFence.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 3, 3, 0, 4, 3, Block.netherFence.blockID, + Block.netherFence.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 4, 3, 1, 4, 4, 1, Block.netherFence.blockID, + Block.netherFence.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 4, 3, 3, 4, 4, 3, Block.netherFence.blockID, + Block.netherFence.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 6, 0, 4, 6, 4, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + + for (int var4 = 0; var4 <= 4; ++var4) { + for (int var5 = 0; var5 <= 4; ++var5) { + this.fillCurrentPositionBlocksDownwards(par1World, Block.netherBrick.blockID, 0, var4, -1, var5, + par3StructureBoundingBox); + } + } + + return true; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ComponentNetherBridgeCrossing.java b/sp-server/src/main/java/net/minecraft/src/ComponentNetherBridgeCrossing.java new file mode 100644 index 0000000..2c04269 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ComponentNetherBridgeCrossing.java @@ -0,0 +1,91 @@ +package net.minecraft.src; + +import java.util.List; +import java.util.Random; + +public class ComponentNetherBridgeCrossing extends ComponentNetherBridgePiece { + public ComponentNetherBridgeCrossing(int par1, Random par2Random, StructureBoundingBox par3StructureBoundingBox, + int par4) { + super(par1); + this.coordBaseMode = par4; + this.boundingBox = par3StructureBoundingBox; + } + + /** + * Initiates construction of the Structure Component picked, at the current + * Location of StructGen + */ + public void buildComponent(StructureComponent par1StructureComponent, List par2List, Random par3Random) { + this.getNextComponentNormal((ComponentNetherBridgeStartPiece) par1StructureComponent, par2List, par3Random, 2, + 0, false); + this.getNextComponentX((ComponentNetherBridgeStartPiece) par1StructureComponent, par2List, par3Random, 0, 2, + false); + this.getNextComponentZ((ComponentNetherBridgeStartPiece) par1StructureComponent, par2List, par3Random, 0, 2, + false); + } + + /** + * Creates and returns a new component piece. Or null if it could not find + * enough room to place it. + */ + public static ComponentNetherBridgeCrossing createValidComponent(List par0List, Random par1Random, int par2, + int par3, int par4, int par5, int par6) { + StructureBoundingBox var7 = StructureBoundingBox.getComponentToAddBoundingBox(par2, par3, par4, -2, 0, 0, 7, 9, + 7, par5); + return isAboveGround(var7) && StructureComponent.findIntersecting(par0List, var7) == null + ? new ComponentNetherBridgeCrossing(par6, par1Random, var7, par5) + : null; + } + + /** + * second Part of Structure generating, this for example places Spiderwebs, Mob + * Spawners, it closes Mineshafts at the end, it adds Fences... + */ + public boolean addComponentParts(World par1World, Random par2Random, + StructureBoundingBox par3StructureBoundingBox) { + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 0, 0, 6, 1, 6, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 2, 0, 6, 7, 6, 0, 0, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 2, 0, 1, 6, 0, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 2, 6, 1, 6, 6, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 5, 2, 0, 6, 6, 0, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 5, 2, 6, 6, 6, 6, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 2, 0, 0, 6, 1, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 2, 5, 0, 6, 6, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 6, 2, 0, 6, 6, 1, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 6, 2, 5, 6, 6, 6, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 2, 6, 0, 4, 6, 0, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 2, 5, 0, 4, 5, 0, Block.netherFence.blockID, + Block.netherFence.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 2, 6, 6, 4, 6, 6, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 2, 5, 6, 4, 5, 6, Block.netherFence.blockID, + Block.netherFence.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 6, 2, 0, 6, 4, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 5, 2, 0, 5, 4, Block.netherFence.blockID, + Block.netherFence.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 6, 6, 2, 6, 6, 4, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 6, 5, 2, 6, 5, 4, Block.netherFence.blockID, + Block.netherFence.blockID, false); + + for (int var4 = 0; var4 <= 6; ++var4) { + for (int var5 = 0; var5 <= 6; ++var5) { + this.fillCurrentPositionBlocksDownwards(par1World, Block.netherBrick.blockID, 0, var4, -1, var5, + par3StructureBoundingBox); + } + } + + return true; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ComponentNetherBridgeCrossing2.java b/sp-server/src/main/java/net/minecraft/src/ComponentNetherBridgeCrossing2.java new file mode 100644 index 0000000..8ef5243 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ComponentNetherBridgeCrossing2.java @@ -0,0 +1,69 @@ +package net.minecraft.src; + +import java.util.List; +import java.util.Random; + +public class ComponentNetherBridgeCrossing2 extends ComponentNetherBridgePiece { + public ComponentNetherBridgeCrossing2(int par1, Random par2Random, StructureBoundingBox par3StructureBoundingBox, + int par4) { + super(par1); + this.coordBaseMode = par4; + this.boundingBox = par3StructureBoundingBox; + } + + /** + * Initiates construction of the Structure Component picked, at the current + * Location of StructGen + */ + public void buildComponent(StructureComponent par1StructureComponent, List par2List, Random par3Random) { + this.getNextComponentNormal((ComponentNetherBridgeStartPiece) par1StructureComponent, par2List, par3Random, 1, + 0, true); + this.getNextComponentX((ComponentNetherBridgeStartPiece) par1StructureComponent, par2List, par3Random, 0, 1, + true); + this.getNextComponentZ((ComponentNetherBridgeStartPiece) par1StructureComponent, par2List, par3Random, 0, 1, + true); + } + + /** + * Creates and returns a new component piece. Or null if it could not find + * enough room to place it. + */ + public static ComponentNetherBridgeCrossing2 createValidComponent(List par0List, Random par1Random, int par2, + int par3, int par4, int par5, int par6) { + StructureBoundingBox var7 = StructureBoundingBox.getComponentToAddBoundingBox(par2, par3, par4, -1, 0, 0, 5, 7, + 5, par5); + return isAboveGround(var7) && StructureComponent.findIntersecting(par0List, var7) == null + ? new ComponentNetherBridgeCrossing2(par6, par1Random, var7, par5) + : null; + } + + /** + * second Part of Structure generating, this for example places Spiderwebs, Mob + * Spawners, it closes Mineshafts at the end, it adds Fences... + */ + public boolean addComponentParts(World par1World, Random par2Random, + StructureBoundingBox par3StructureBoundingBox) { + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 0, 0, 4, 1, 4, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 2, 0, 4, 5, 4, 0, 0, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 2, 0, 0, 5, 0, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 4, 2, 0, 4, 5, 0, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 2, 4, 0, 5, 4, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 4, 2, 4, 4, 5, 4, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 6, 0, 4, 6, 4, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + + for (int var4 = 0; var4 <= 4; ++var4) { + for (int var5 = 0; var5 <= 4; ++var5) { + this.fillCurrentPositionBlocksDownwards(par1World, Block.netherBrick.blockID, 0, var4, -1, var5, + par3StructureBoundingBox); + } + } + + return true; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ComponentNetherBridgeCrossing3.java b/sp-server/src/main/java/net/minecraft/src/ComponentNetherBridgeCrossing3.java new file mode 100644 index 0000000..fbf42f5 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ComponentNetherBridgeCrossing3.java @@ -0,0 +1,123 @@ +package net.minecraft.src; + +import java.util.List; +import java.util.Random; + +public class ComponentNetherBridgeCrossing3 extends ComponentNetherBridgePiece { + public ComponentNetherBridgeCrossing3(int par1, Random par2Random, StructureBoundingBox par3StructureBoundingBox, + int par4) { + super(par1); + this.coordBaseMode = par4; + this.boundingBox = par3StructureBoundingBox; + } + + protected ComponentNetherBridgeCrossing3(Random par1Random, int par2, int par3) { + super(0); + this.coordBaseMode = par1Random.nextInt(4); + + switch (this.coordBaseMode) { + case 0: + case 2: + this.boundingBox = new StructureBoundingBox(par2, 64, par3, par2 + 19 - 1, 73, par3 + 19 - 1); + break; + + default: + this.boundingBox = new StructureBoundingBox(par2, 64, par3, par2 + 19 - 1, 73, par3 + 19 - 1); + } + } + + /** + * Initiates construction of the Structure Component picked, at the current + * Location of StructGen + */ + public void buildComponent(StructureComponent par1StructureComponent, List par2List, Random par3Random) { + this.getNextComponentNormal((ComponentNetherBridgeStartPiece) par1StructureComponent, par2List, par3Random, 8, + 3, false); + this.getNextComponentX((ComponentNetherBridgeStartPiece) par1StructureComponent, par2List, par3Random, 3, 8, + false); + this.getNextComponentZ((ComponentNetherBridgeStartPiece) par1StructureComponent, par2List, par3Random, 3, 8, + false); + } + + /** + * Creates and returns a new component piece. Or null if it could not find + * enough room to place it. + */ + public static ComponentNetherBridgeCrossing3 createValidComponent(List par0List, Random par1Random, int par2, + int par3, int par4, int par5, int par6) { + StructureBoundingBox var7 = StructureBoundingBox.getComponentToAddBoundingBox(par2, par3, par4, -8, -3, 0, 19, + 10, 19, par5); + return isAboveGround(var7) && StructureComponent.findIntersecting(par0List, var7) == null + ? new ComponentNetherBridgeCrossing3(par6, par1Random, var7, par5) + : null; + } + + /** + * second Part of Structure generating, this for example places Spiderwebs, Mob + * Spawners, it closes Mineshafts at the end, it adds Fences... + */ + public boolean addComponentParts(World par1World, Random par2Random, + StructureBoundingBox par3StructureBoundingBox) { + this.fillWithBlocks(par1World, par3StructureBoundingBox, 7, 3, 0, 11, 4, 18, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 3, 7, 18, 4, 11, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 8, 5, 0, 10, 7, 18, 0, 0, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 5, 8, 18, 7, 10, 0, 0, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 7, 5, 0, 7, 5, 7, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 7, 5, 11, 7, 5, 18, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 11, 5, 0, 11, 5, 7, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 11, 5, 11, 11, 5, 18, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 5, 7, 7, 5, 7, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 11, 5, 7, 18, 5, 7, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 5, 11, 7, 5, 11, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 11, 5, 11, 18, 5, 11, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 7, 2, 0, 11, 2, 5, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 7, 2, 13, 11, 2, 18, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 7, 0, 0, 11, 1, 3, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 7, 0, 15, 11, 1, 18, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + int var4; + int var5; + + for (var4 = 7; var4 <= 11; ++var4) { + for (var5 = 0; var5 <= 2; ++var5) { + this.fillCurrentPositionBlocksDownwards(par1World, Block.netherBrick.blockID, 0, var4, -1, var5, + par3StructureBoundingBox); + this.fillCurrentPositionBlocksDownwards(par1World, Block.netherBrick.blockID, 0, var4, -1, 18 - var5, + par3StructureBoundingBox); + } + } + + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 2, 7, 5, 2, 11, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 13, 2, 7, 18, 2, 11, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 0, 7, 3, 1, 11, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 15, 0, 7, 18, 1, 11, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + + for (var4 = 0; var4 <= 2; ++var4) { + for (var5 = 7; var5 <= 11; ++var5) { + this.fillCurrentPositionBlocksDownwards(par1World, Block.netherBrick.blockID, 0, var4, -1, var5, + par3StructureBoundingBox); + this.fillCurrentPositionBlocksDownwards(par1World, Block.netherBrick.blockID, 0, 18 - var4, -1, var5, + par3StructureBoundingBox); + } + } + + return true; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ComponentNetherBridgeEnd.java b/sp-server/src/main/java/net/minecraft/src/ComponentNetherBridgeEnd.java new file mode 100644 index 0000000..ee09273 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ComponentNetherBridgeEnd.java @@ -0,0 +1,68 @@ +package net.minecraft.src; + +import java.util.List; +import java.util.Random; + +public class ComponentNetherBridgeEnd extends ComponentNetherBridgePiece { + private int fillSeed; + + public ComponentNetherBridgeEnd(int par1, Random par2Random, StructureBoundingBox par3StructureBoundingBox, + int par4) { + super(par1); + this.coordBaseMode = par4; + this.boundingBox = par3StructureBoundingBox; + this.fillSeed = par2Random.nextInt(); + } + + public static ComponentNetherBridgeEnd func_74971_a(List par0List, Random par1Random, int par2, int par3, int par4, + int par5, int par6) { + StructureBoundingBox var7 = StructureBoundingBox.getComponentToAddBoundingBox(par2, par3, par4, -1, -3, 0, 5, + 10, 8, par5); + return isAboveGround(var7) && StructureComponent.findIntersecting(par0List, var7) == null + ? new ComponentNetherBridgeEnd(par6, par1Random, var7, par5) + : null; + } + + /** + * second Part of Structure generating, this for example places Spiderwebs, Mob + * Spawners, it closes Mineshafts at the end, it adds Fences... + */ + public boolean addComponentParts(World par1World, Random par2Random, + StructureBoundingBox par3StructureBoundingBox) { + Random var4 = new Random((long) this.fillSeed); + int var5; + int var6; + int var7; + + for (var5 = 0; var5 <= 4; ++var5) { + for (var6 = 3; var6 <= 4; ++var6) { + var7 = var4.nextInt(8); + this.fillWithBlocks(par1World, par3StructureBoundingBox, var5, var6, 0, var5, var6, var7, + Block.netherBrick.blockID, Block.netherBrick.blockID, false); + } + } + + var5 = var4.nextInt(8); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 5, 0, 0, 5, var5, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + var5 = var4.nextInt(8); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 4, 5, 0, 4, 5, var5, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + + for (var5 = 0; var5 <= 4; ++var5) { + var6 = var4.nextInt(5); + this.fillWithBlocks(par1World, par3StructureBoundingBox, var5, 2, 0, var5, 2, var6, + Block.netherBrick.blockID, Block.netherBrick.blockID, false); + } + + for (var5 = 0; var5 <= 4; ++var5) { + for (var6 = 0; var6 <= 1; ++var6) { + var7 = var4.nextInt(3); + this.fillWithBlocks(par1World, par3StructureBoundingBox, var5, var6, 0, var5, var6, var7, + Block.netherBrick.blockID, Block.netherBrick.blockID, false); + } + } + + return true; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ComponentNetherBridgeEntrance.java b/sp-server/src/main/java/net/minecraft/src/ComponentNetherBridgeEntrance.java new file mode 100644 index 0000000..019d840 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ComponentNetherBridgeEntrance.java @@ -0,0 +1,155 @@ +package net.minecraft.src; + +import java.util.List; +import java.util.Random; + +public class ComponentNetherBridgeEntrance extends ComponentNetherBridgePiece { + public ComponentNetherBridgeEntrance(int par1, Random par2Random, StructureBoundingBox par3StructureBoundingBox, + int par4) { + super(par1); + this.coordBaseMode = par4; + this.boundingBox = par3StructureBoundingBox; + } + + /** + * Initiates construction of the Structure Component picked, at the current + * Location of StructGen + */ + public void buildComponent(StructureComponent par1StructureComponent, List par2List, Random par3Random) { + this.getNextComponentNormal((ComponentNetherBridgeStartPiece) par1StructureComponent, par2List, par3Random, 5, + 3, true); + } + + /** + * Creates and returns a new component piece. Or null if it could not find + * enough room to place it. + */ + public static ComponentNetherBridgeEntrance createValidComponent(List par0List, Random par1Random, int par2, + int par3, int par4, int par5, int par6) { + StructureBoundingBox var7 = StructureBoundingBox.getComponentToAddBoundingBox(par2, par3, par4, -5, -3, 0, 13, + 14, 13, par5); + return isAboveGround(var7) && StructureComponent.findIntersecting(par0List, var7) == null + ? new ComponentNetherBridgeEntrance(par6, par1Random, var7, par5) + : null; + } + + /** + * second Part of Structure generating, this for example places Spiderwebs, Mob + * Spawners, it closes Mineshafts at the end, it adds Fences... + */ + public boolean addComponentParts(World par1World, Random par2Random, + StructureBoundingBox par3StructureBoundingBox) { + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 3, 0, 12, 4, 12, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 5, 0, 12, 13, 12, 0, 0, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 5, 0, 1, 12, 12, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 11, 5, 0, 12, 12, 12, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 2, 5, 11, 4, 12, 12, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 8, 5, 11, 10, 12, 12, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 5, 9, 11, 7, 12, 12, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 2, 5, 0, 4, 12, 1, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 8, 5, 0, 10, 12, 1, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 5, 9, 0, 7, 12, 1, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 2, 11, 2, 10, 12, 10, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 5, 8, 0, 7, 8, 0, Block.netherFence.blockID, + Block.netherFence.blockID, false); + int var4; + + for (var4 = 1; var4 <= 11; var4 += 2) { + this.fillWithBlocks(par1World, par3StructureBoundingBox, var4, 10, 0, var4, 11, 0, + Block.netherFence.blockID, Block.netherFence.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, var4, 10, 12, var4, 11, 12, + Block.netherFence.blockID, Block.netherFence.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 10, var4, 0, 11, var4, + Block.netherFence.blockID, Block.netherFence.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 12, 10, var4, 12, 11, var4, + Block.netherFence.blockID, Block.netherFence.blockID, false); + this.placeBlockAtCurrentPosition(par1World, Block.netherBrick.blockID, 0, var4, 13, 0, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.netherBrick.blockID, 0, var4, 13, 12, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.netherBrick.blockID, 0, 0, 13, var4, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.netherBrick.blockID, 0, 12, 13, var4, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.netherFence.blockID, 0, var4 + 1, 13, 0, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.netherFence.blockID, 0, var4 + 1, 13, 12, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.netherFence.blockID, 0, 0, 13, var4 + 1, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.netherFence.blockID, 0, 12, 13, var4 + 1, + par3StructureBoundingBox); + } + + this.placeBlockAtCurrentPosition(par1World, Block.netherFence.blockID, 0, 0, 13, 0, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.netherFence.blockID, 0, 0, 13, 12, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.netherFence.blockID, 0, 0, 13, 0, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.netherFence.blockID, 0, 12, 13, 0, par3StructureBoundingBox); + + for (var4 = 3; var4 <= 9; var4 += 2) { + this.fillWithBlocks(par1World, par3StructureBoundingBox, 1, 7, var4, 1, 8, var4, Block.netherFence.blockID, + Block.netherFence.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 11, 7, var4, 11, 8, var4, + Block.netherFence.blockID, Block.netherFence.blockID, false); + } + + this.fillWithBlocks(par1World, par3StructureBoundingBox, 4, 2, 0, 8, 2, 12, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 2, 4, 12, 2, 8, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 4, 0, 0, 8, 1, 3, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 4, 0, 9, 8, 1, 12, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 0, 4, 3, 1, 8, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 9, 0, 4, 12, 1, 8, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + int var5; + + for (var4 = 4; var4 <= 8; ++var4) { + for (var5 = 0; var5 <= 2; ++var5) { + this.fillCurrentPositionBlocksDownwards(par1World, Block.netherBrick.blockID, 0, var4, -1, var5, + par3StructureBoundingBox); + this.fillCurrentPositionBlocksDownwards(par1World, Block.netherBrick.blockID, 0, var4, -1, 12 - var5, + par3StructureBoundingBox); + } + } + + for (var4 = 0; var4 <= 2; ++var4) { + for (var5 = 4; var5 <= 8; ++var5) { + this.fillCurrentPositionBlocksDownwards(par1World, Block.netherBrick.blockID, 0, var4, -1, var5, + par3StructureBoundingBox); + this.fillCurrentPositionBlocksDownwards(par1World, Block.netherBrick.blockID, 0, 12 - var4, -1, var5, + par3StructureBoundingBox); + } + } + + this.fillWithBlocks(par1World, par3StructureBoundingBox, 5, 5, 5, 7, 5, 7, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 6, 1, 6, 6, 4, 6, 0, 0, false); + this.placeBlockAtCurrentPosition(par1World, Block.netherBrick.blockID, 0, 6, 0, 6, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.lavaMoving.blockID, 0, 6, 5, 6, par3StructureBoundingBox); + var4 = this.getXWithOffset(6, 6); + var5 = this.getYWithOffset(5); + int var6 = this.getZWithOffset(6, 6); + + if (par3StructureBoundingBox.isVecInside(var4, var5, var6)) { + par1World.scheduledUpdatesAreImmediate = true; + Block.blocksList[Block.lavaMoving.blockID].updateTick(par1World, var4, var5, var6, par2Random); + par1World.scheduledUpdatesAreImmediate = false; + } + + return true; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ComponentNetherBridgeNetherStalkRoom.java b/sp-server/src/main/java/net/minecraft/src/ComponentNetherBridgeNetherStalkRoom.java new file mode 100644 index 0000000..f0e59cf --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ComponentNetherBridgeNetherStalkRoom.java @@ -0,0 +1,215 @@ +package net.minecraft.src; + +import java.util.List; +import java.util.Random; + +public class ComponentNetherBridgeNetherStalkRoom extends ComponentNetherBridgePiece { + public ComponentNetherBridgeNetherStalkRoom(int par1, Random par2Random, + StructureBoundingBox par3StructureBoundingBox, int par4) { + super(par1); + this.coordBaseMode = par4; + this.boundingBox = par3StructureBoundingBox; + } + + /** + * Initiates construction of the Structure Component picked, at the current + * Location of StructGen + */ + public void buildComponent(StructureComponent par1StructureComponent, List par2List, Random par3Random) { + this.getNextComponentNormal((ComponentNetherBridgeStartPiece) par1StructureComponent, par2List, par3Random, 5, + 3, true); + this.getNextComponentNormal((ComponentNetherBridgeStartPiece) par1StructureComponent, par2List, par3Random, 5, + 11, true); + } + + /** + * Creates and returns a new component piece. Or null if it could not find + * enough room to place it. + */ + public static ComponentNetherBridgeNetherStalkRoom createValidComponent(List par0List, Random par1Random, int par2, + int par3, int par4, int par5, int par6) { + StructureBoundingBox var7 = StructureBoundingBox.getComponentToAddBoundingBox(par2, par3, par4, -5, -3, 0, 13, + 14, 13, par5); + return isAboveGround(var7) && StructureComponent.findIntersecting(par0List, var7) == null + ? new ComponentNetherBridgeNetherStalkRoom(par6, par1Random, var7, par5) + : null; + } + + /** + * second Part of Structure generating, this for example places Spiderwebs, Mob + * Spawners, it closes Mineshafts at the end, it adds Fences... + */ + public boolean addComponentParts(World par1World, Random par2Random, + StructureBoundingBox par3StructureBoundingBox) { + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 3, 0, 12, 4, 12, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 5, 0, 12, 13, 12, 0, 0, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 5, 0, 1, 12, 12, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 11, 5, 0, 12, 12, 12, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 2, 5, 11, 4, 12, 12, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 8, 5, 11, 10, 12, 12, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 5, 9, 11, 7, 12, 12, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 2, 5, 0, 4, 12, 1, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 8, 5, 0, 10, 12, 1, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 5, 9, 0, 7, 12, 1, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 2, 11, 2, 10, 12, 10, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + int var4; + + for (var4 = 1; var4 <= 11; var4 += 2) { + this.fillWithBlocks(par1World, par3StructureBoundingBox, var4, 10, 0, var4, 11, 0, + Block.netherFence.blockID, Block.netherFence.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, var4, 10, 12, var4, 11, 12, + Block.netherFence.blockID, Block.netherFence.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 10, var4, 0, 11, var4, + Block.netherFence.blockID, Block.netherFence.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 12, 10, var4, 12, 11, var4, + Block.netherFence.blockID, Block.netherFence.blockID, false); + this.placeBlockAtCurrentPosition(par1World, Block.netherBrick.blockID, 0, var4, 13, 0, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.netherBrick.blockID, 0, var4, 13, 12, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.netherBrick.blockID, 0, 0, 13, var4, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.netherBrick.blockID, 0, 12, 13, var4, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.netherFence.blockID, 0, var4 + 1, 13, 0, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.netherFence.blockID, 0, var4 + 1, 13, 12, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.netherFence.blockID, 0, 0, 13, var4 + 1, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.netherFence.blockID, 0, 12, 13, var4 + 1, + par3StructureBoundingBox); + } + + this.placeBlockAtCurrentPosition(par1World, Block.netherFence.blockID, 0, 0, 13, 0, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.netherFence.blockID, 0, 0, 13, 12, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.netherFence.blockID, 0, 0, 13, 0, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.netherFence.blockID, 0, 12, 13, 0, par3StructureBoundingBox); + + for (var4 = 3; var4 <= 9; var4 += 2) { + this.fillWithBlocks(par1World, par3StructureBoundingBox, 1, 7, var4, 1, 8, var4, Block.netherFence.blockID, + Block.netherFence.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 11, 7, var4, 11, 8, var4, + Block.netherFence.blockID, Block.netherFence.blockID, false); + } + + var4 = this.getMetadataWithOffset(Block.stairsNetherBrick.blockID, 3); + int var5; + int var6; + int var7; + + for (var5 = 0; var5 <= 6; ++var5) { + var6 = var5 + 4; + + for (var7 = 5; var7 <= 7; ++var7) { + this.placeBlockAtCurrentPosition(par1World, Block.stairsNetherBrick.blockID, var4, var7, 5 + var5, var6, + par3StructureBoundingBox); + } + + if (var6 >= 5 && var6 <= 8) { + this.fillWithBlocks(par1World, par3StructureBoundingBox, 5, 5, var6, 7, var5 + 4, var6, + Block.netherBrick.blockID, Block.netherBrick.blockID, false); + } else if (var6 >= 9 && var6 <= 10) { + this.fillWithBlocks(par1World, par3StructureBoundingBox, 5, 8, var6, 7, var5 + 4, var6, + Block.netherBrick.blockID, Block.netherBrick.blockID, false); + } + + if (var5 >= 1) { + this.fillWithBlocks(par1World, par3StructureBoundingBox, 5, 6 + var5, var6, 7, 9 + var5, var6, 0, 0, + false); + } + } + + for (var5 = 5; var5 <= 7; ++var5) { + this.placeBlockAtCurrentPosition(par1World, Block.stairsNetherBrick.blockID, var4, var5, 12, 11, + par3StructureBoundingBox); + } + + this.fillWithBlocks(par1World, par3StructureBoundingBox, 5, 6, 7, 5, 7, 7, Block.netherFence.blockID, + Block.netherFence.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 7, 6, 7, 7, 7, 7, Block.netherFence.blockID, + Block.netherFence.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 5, 13, 12, 7, 13, 12, 0, 0, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 2, 5, 2, 3, 5, 3, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 2, 5, 9, 3, 5, 10, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 2, 5, 4, 2, 5, 8, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 9, 5, 2, 10, 5, 3, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 9, 5, 9, 10, 5, 10, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 10, 5, 4, 10, 5, 8, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + var5 = this.getMetadataWithOffset(Block.stairsNetherBrick.blockID, 0); + var6 = this.getMetadataWithOffset(Block.stairsNetherBrick.blockID, 1); + this.placeBlockAtCurrentPosition(par1World, Block.stairsNetherBrick.blockID, var6, 4, 5, 2, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stairsNetherBrick.blockID, var6, 4, 5, 3, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stairsNetherBrick.blockID, var6, 4, 5, 9, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stairsNetherBrick.blockID, var6, 4, 5, 10, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stairsNetherBrick.blockID, var5, 8, 5, 2, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stairsNetherBrick.blockID, var5, 8, 5, 3, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stairsNetherBrick.blockID, var5, 8, 5, 9, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stairsNetherBrick.blockID, var5, 8, 5, 10, + par3StructureBoundingBox); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 3, 4, 4, 4, 4, 8, Block.slowSand.blockID, + Block.slowSand.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 8, 4, 4, 9, 4, 8, Block.slowSand.blockID, + Block.slowSand.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 3, 5, 4, 4, 5, 8, Block.netherStalk.blockID, + Block.netherStalk.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 8, 5, 4, 9, 5, 8, Block.netherStalk.blockID, + Block.netherStalk.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 4, 2, 0, 8, 2, 12, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 2, 4, 12, 2, 8, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 4, 0, 0, 8, 1, 3, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 4, 0, 9, 8, 1, 12, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 0, 4, 3, 1, 8, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 9, 0, 4, 12, 1, 8, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + int var8; + + for (var7 = 4; var7 <= 8; ++var7) { + for (var8 = 0; var8 <= 2; ++var8) { + this.fillCurrentPositionBlocksDownwards(par1World, Block.netherBrick.blockID, 0, var7, -1, var8, + par3StructureBoundingBox); + this.fillCurrentPositionBlocksDownwards(par1World, Block.netherBrick.blockID, 0, var7, -1, 12 - var8, + par3StructureBoundingBox); + } + } + + for (var7 = 0; var7 <= 2; ++var7) { + for (var8 = 4; var8 <= 8; ++var8) { + this.fillCurrentPositionBlocksDownwards(par1World, Block.netherBrick.blockID, 0, var7, -1, var8, + par3StructureBoundingBox); + this.fillCurrentPositionBlocksDownwards(par1World, Block.netherBrick.blockID, 0, 12 - var7, -1, var8, + par3StructureBoundingBox); + } + } + + return true; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ComponentNetherBridgePiece.java b/sp-server/src/main/java/net/minecraft/src/ComponentNetherBridgePiece.java new file mode 100644 index 0000000..ca55d39 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ComponentNetherBridgePiece.java @@ -0,0 +1,198 @@ +package net.minecraft.src; + +import java.util.Iterator; +import java.util.List; +import java.util.Random; + +abstract class ComponentNetherBridgePiece extends StructureComponent { + protected ComponentNetherBridgePiece(int par1) { + super(par1); + } + + private int getTotalWeight(List par1List) { + boolean var2 = false; + int var3 = 0; + StructureNetherBridgePieceWeight var5; + + for (Iterator var4 = par1List.iterator(); var4.hasNext(); var3 += var5.field_78826_b) { + var5 = (StructureNetherBridgePieceWeight) var4.next(); + + if (var5.field_78824_d > 0 && var5.field_78827_c < var5.field_78824_d) { + var2 = true; + } + } + + return var2 ? var3 : -1; + } + + private ComponentNetherBridgePiece getNextComponent( + ComponentNetherBridgeStartPiece par1ComponentNetherBridgeStartPiece, List par2List, List par3List, + Random par4Random, int par5, int par6, int par7, int par8, int par9) { + int var10 = this.getTotalWeight(par2List); + boolean var11 = var10 > 0 && par9 <= 30; + int var12 = 0; + + while (var12 < 5 && var11) { + ++var12; + int var13 = par4Random.nextInt(var10); + Iterator var14 = par2List.iterator(); + + while (var14.hasNext()) { + StructureNetherBridgePieceWeight var15 = (StructureNetherBridgePieceWeight) var14.next(); + var13 -= var15.field_78826_b; + + if (var13 < 0) { + if (!var15.func_78822_a(par9) + || var15 == par1ComponentNetherBridgeStartPiece.theNetherBridgePieceWeight + && !var15.field_78825_e) { + break; + } + + ComponentNetherBridgePiece var16 = StructureNetherBridgePieces.createNextComponent(var15, par3List, + par4Random, par5, par6, par7, par8, par9); + + if (var16 != null) { + ++var15.field_78827_c; + par1ComponentNetherBridgeStartPiece.theNetherBridgePieceWeight = var15; + + if (!var15.func_78823_a()) { + par2List.remove(var15); + } + + return var16; + } + } + } + } + + return ComponentNetherBridgeEnd.func_74971_a(par3List, par4Random, par5, par6, par7, par8, par9); + } + + /** + * Finds a random component to tack on to the bridge. Or builds the end. + */ + private StructureComponent getNextComponent(ComponentNetherBridgeStartPiece par1ComponentNetherBridgeStartPiece, + List par2List, Random par3Random, int par4, int par5, int par6, int par7, int par8, boolean par9) { + if (Math.abs(par4 - par1ComponentNetherBridgeStartPiece.getBoundingBox().minX) <= 112 + && Math.abs(par6 - par1ComponentNetherBridgeStartPiece.getBoundingBox().minZ) <= 112) { + List var10 = par1ComponentNetherBridgeStartPiece.primaryWeights; + + if (par9) { + var10 = par1ComponentNetherBridgeStartPiece.secondaryWeights; + } + + ComponentNetherBridgePiece var11 = this.getNextComponent(par1ComponentNetherBridgeStartPiece, var10, + par2List, par3Random, par4, par5, par6, par7, par8 + 1); + + if (var11 != null) { + par2List.add(var11); + par1ComponentNetherBridgeStartPiece.field_74967_d.add(var11); + } + + return var11; + } else { + return ComponentNetherBridgeEnd.func_74971_a(par2List, par3Random, par4, par5, par6, par7, par8); + } + } + + /** + * Gets the next component in any cardinal direction + */ + protected StructureComponent getNextComponentNormal( + ComponentNetherBridgeStartPiece par1ComponentNetherBridgeStartPiece, List par2List, Random par3Random, + int par4, int par5, boolean par6) { + switch (this.coordBaseMode) { + case 0: + return this.getNextComponent(par1ComponentNetherBridgeStartPiece, par2List, par3Random, + this.boundingBox.minX + par4, this.boundingBox.minY + par5, this.boundingBox.maxZ + 1, + this.coordBaseMode, this.getComponentType(), par6); + + case 1: + return this.getNextComponent(par1ComponentNetherBridgeStartPiece, par2List, par3Random, + this.boundingBox.minX - 1, this.boundingBox.minY + par5, this.boundingBox.minZ + par4, + this.coordBaseMode, this.getComponentType(), par6); + + case 2: + return this.getNextComponent(par1ComponentNetherBridgeStartPiece, par2List, par3Random, + this.boundingBox.minX + par4, this.boundingBox.minY + par5, this.boundingBox.minZ - 1, + this.coordBaseMode, this.getComponentType(), par6); + + case 3: + return this.getNextComponent(par1ComponentNetherBridgeStartPiece, par2List, par3Random, + this.boundingBox.maxX + 1, this.boundingBox.minY + par5, this.boundingBox.minZ + par4, + this.coordBaseMode, this.getComponentType(), par6); + + default: + return null; + } + } + + /** + * Gets the next component in the +/- X direction + */ + protected StructureComponent getNextComponentX(ComponentNetherBridgeStartPiece par1ComponentNetherBridgeStartPiece, + List par2List, Random par3Random, int par4, int par5, boolean par6) { + switch (this.coordBaseMode) { + case 0: + return this.getNextComponent(par1ComponentNetherBridgeStartPiece, par2List, par3Random, + this.boundingBox.minX - 1, this.boundingBox.minY + par4, this.boundingBox.minZ + par5, 1, + this.getComponentType(), par6); + + case 1: + return this.getNextComponent(par1ComponentNetherBridgeStartPiece, par2List, par3Random, + this.boundingBox.minX + par5, this.boundingBox.minY + par4, this.boundingBox.minZ - 1, 2, + this.getComponentType(), par6); + + case 2: + return this.getNextComponent(par1ComponentNetherBridgeStartPiece, par2List, par3Random, + this.boundingBox.minX - 1, this.boundingBox.minY + par4, this.boundingBox.minZ + par5, 1, + this.getComponentType(), par6); + + case 3: + return this.getNextComponent(par1ComponentNetherBridgeStartPiece, par2List, par3Random, + this.boundingBox.minX + par5, this.boundingBox.minY + par4, this.boundingBox.minZ - 1, 2, + this.getComponentType(), par6); + + default: + return null; + } + } + + /** + * Gets the next component in the +/- Z direction + */ + protected StructureComponent getNextComponentZ(ComponentNetherBridgeStartPiece par1ComponentNetherBridgeStartPiece, + List par2List, Random par3Random, int par4, int par5, boolean par6) { + switch (this.coordBaseMode) { + case 0: + return this.getNextComponent(par1ComponentNetherBridgeStartPiece, par2List, par3Random, + this.boundingBox.maxX + 1, this.boundingBox.minY + par4, this.boundingBox.minZ + par5, 3, + this.getComponentType(), par6); + + case 1: + return this.getNextComponent(par1ComponentNetherBridgeStartPiece, par2List, par3Random, + this.boundingBox.minX + par5, this.boundingBox.minY + par4, this.boundingBox.maxZ + 1, 0, + this.getComponentType(), par6); + + case 2: + return this.getNextComponent(par1ComponentNetherBridgeStartPiece, par2List, par3Random, + this.boundingBox.maxX + 1, this.boundingBox.minY + par4, this.boundingBox.minZ + par5, 3, + this.getComponentType(), par6); + + case 3: + return this.getNextComponent(par1ComponentNetherBridgeStartPiece, par2List, par3Random, + this.boundingBox.minX + par5, this.boundingBox.minY + par4, this.boundingBox.maxZ + 1, 0, + this.getComponentType(), par6); + + default: + return null; + } + } + + /** + * Checks if the bounding box's minY is > 10 + */ + protected static boolean isAboveGround(StructureBoundingBox par0StructureBoundingBox) { + return par0StructureBoundingBox != null && par0StructureBoundingBox.minY > 10; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ComponentNetherBridgeStairs.java b/sp-server/src/main/java/net/minecraft/src/ComponentNetherBridgeStairs.java new file mode 100644 index 0000000..c667cde --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ComponentNetherBridgeStairs.java @@ -0,0 +1,87 @@ +package net.minecraft.src; + +import java.util.List; +import java.util.Random; + +public class ComponentNetherBridgeStairs extends ComponentNetherBridgePiece { + public ComponentNetherBridgeStairs(int par1, Random par2Random, StructureBoundingBox par3StructureBoundingBox, + int par4) { + super(par1); + this.coordBaseMode = par4; + this.boundingBox = par3StructureBoundingBox; + } + + /** + * Initiates construction of the Structure Component picked, at the current + * Location of StructGen + */ + public void buildComponent(StructureComponent par1StructureComponent, List par2List, Random par3Random) { + this.getNextComponentZ((ComponentNetherBridgeStartPiece) par1StructureComponent, par2List, par3Random, 6, 2, + false); + } + + /** + * Creates and returns a new component piece. Or null if it could not find + * enough room to place it. + */ + public static ComponentNetherBridgeStairs createValidComponent(List par0List, Random par1Random, int par2, int par3, + int par4, int par5, int par6) { + StructureBoundingBox var7 = StructureBoundingBox.getComponentToAddBoundingBox(par2, par3, par4, -2, 0, 0, 7, 11, + 7, par5); + return isAboveGround(var7) && StructureComponent.findIntersecting(par0List, var7) == null + ? new ComponentNetherBridgeStairs(par6, par1Random, var7, par5) + : null; + } + + /** + * second Part of Structure generating, this for example places Spiderwebs, Mob + * Spawners, it closes Mineshafts at the end, it adds Fences... + */ + public boolean addComponentParts(World par1World, Random par2Random, + StructureBoundingBox par3StructureBoundingBox) { + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 0, 0, 6, 1, 6, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 2, 0, 6, 10, 6, 0, 0, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 2, 0, 1, 8, 0, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 5, 2, 0, 6, 8, 0, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 2, 1, 0, 8, 6, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 6, 2, 1, 6, 8, 6, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 1, 2, 6, 5, 8, 6, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 3, 2, 0, 5, 4, Block.netherFence.blockID, + Block.netherFence.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 6, 3, 2, 6, 5, 2, Block.netherFence.blockID, + Block.netherFence.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 6, 3, 4, 6, 5, 4, Block.netherFence.blockID, + Block.netherFence.blockID, false); + this.placeBlockAtCurrentPosition(par1World, Block.netherBrick.blockID, 0, 5, 2, 5, par3StructureBoundingBox); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 4, 2, 5, 4, 3, 5, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 3, 2, 5, 3, 4, 5, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 2, 2, 5, 2, 5, 5, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 1, 2, 5, 1, 6, 5, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 1, 7, 1, 5, 7, 4, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 6, 8, 2, 6, 8, 4, 0, 0, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 2, 6, 0, 4, 8, 0, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 2, 5, 0, 4, 5, 0, Block.netherFence.blockID, + Block.netherFence.blockID, false); + + for (int var4 = 0; var4 <= 6; ++var4) { + for (int var5 = 0; var5 <= 6; ++var5) { + this.fillCurrentPositionBlocksDownwards(par1World, Block.netherBrick.blockID, 0, var4, -1, var5, + par3StructureBoundingBox); + } + } + + return true; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ComponentNetherBridgeStartPiece.java b/sp-server/src/main/java/net/minecraft/src/ComponentNetherBridgeStartPiece.java new file mode 100644 index 0000000..86c178e --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ComponentNetherBridgeStartPiece.java @@ -0,0 +1,47 @@ +package net.minecraft.src; + +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +public class ComponentNetherBridgeStartPiece extends ComponentNetherBridgeCrossing3 { + /** Instance of StructureNetherBridgePieceWeight. */ + public StructureNetherBridgePieceWeight theNetherBridgePieceWeight; + + /** + * Contains the list of valid piece weights for the set of nether bridge + * structure pieces. + */ + public List primaryWeights = new ArrayList(); + + /** + * Contains the list of valid piece weights for the secondary set of nether + * bridge structure pieces. + */ + public List secondaryWeights; + public ArrayList field_74967_d = new ArrayList(); + + public ComponentNetherBridgeStartPiece(Random par1Random, int par2, int par3) { + super(par1Random, par2, par3); + StructureNetherBridgePieceWeight[] var4 = StructureNetherBridgePieces.getPrimaryComponents(); + int var5 = var4.length; + int var6; + StructureNetherBridgePieceWeight var7; + + for (var6 = 0; var6 < var5; ++var6) { + var7 = var4[var6]; + var7.field_78827_c = 0; + this.primaryWeights.add(var7); + } + + this.secondaryWeights = new ArrayList(); + var4 = StructureNetherBridgePieces.getSecondaryComponents(); + var5 = var4.length; + + for (var6 = 0; var6 < var5; ++var6) { + var7 = var4[var6]; + var7.field_78827_c = 0; + this.secondaryWeights.add(var7); + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ComponentNetherBridgeStraight.java b/sp-server/src/main/java/net/minecraft/src/ComponentNetherBridgeStraight.java new file mode 100644 index 0000000..c32326c --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ComponentNetherBridgeStraight.java @@ -0,0 +1,85 @@ +package net.minecraft.src; + +import java.util.List; +import java.util.Random; + +public class ComponentNetherBridgeStraight extends ComponentNetherBridgePiece { + public ComponentNetherBridgeStraight(int par1, Random par2Random, StructureBoundingBox par3StructureBoundingBox, + int par4) { + super(par1); + this.coordBaseMode = par4; + this.boundingBox = par3StructureBoundingBox; + } + + /** + * Initiates construction of the Structure Component picked, at the current + * Location of StructGen + */ + public void buildComponent(StructureComponent par1StructureComponent, List par2List, Random par3Random) { + this.getNextComponentNormal((ComponentNetherBridgeStartPiece) par1StructureComponent, par2List, par3Random, 1, + 3, false); + } + + /** + * Creates and returns a new component piece. Or null if it could not find + * enough room to place it. + */ + public static ComponentNetherBridgeStraight createValidComponent(List par0List, Random par1Random, int par2, + int par3, int par4, int par5, int par6) { + StructureBoundingBox var7 = StructureBoundingBox.getComponentToAddBoundingBox(par2, par3, par4, -1, -3, 0, 5, + 10, 19, par5); + return isAboveGround(var7) && StructureComponent.findIntersecting(par0List, var7) == null + ? new ComponentNetherBridgeStraight(par6, par1Random, var7, par5) + : null; + } + + /** + * second Part of Structure generating, this for example places Spiderwebs, Mob + * Spawners, it closes Mineshafts at the end, it adds Fences... + */ + public boolean addComponentParts(World par1World, Random par2Random, + StructureBoundingBox par3StructureBoundingBox) { + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 3, 0, 4, 4, 18, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 1, 5, 0, 3, 7, 18, 0, 0, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 5, 0, 0, 5, 18, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 4, 5, 0, 4, 5, 18, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 2, 0, 4, 2, 5, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 2, 13, 4, 2, 18, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 0, 0, 4, 1, 3, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 0, 15, 4, 1, 18, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + + for (int var4 = 0; var4 <= 4; ++var4) { + for (int var5 = 0; var5 <= 2; ++var5) { + this.fillCurrentPositionBlocksDownwards(par1World, Block.netherBrick.blockID, 0, var4, -1, var5, + par3StructureBoundingBox); + this.fillCurrentPositionBlocksDownwards(par1World, Block.netherBrick.blockID, 0, var4, -1, 18 - var5, + par3StructureBoundingBox); + } + } + + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 1, 1, 0, 4, 1, Block.netherFence.blockID, + Block.netherFence.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 3, 4, 0, 4, 4, Block.netherFence.blockID, + Block.netherFence.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 3, 14, 0, 4, 14, Block.netherFence.blockID, + Block.netherFence.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 1, 17, 0, 4, 17, Block.netherFence.blockID, + Block.netherFence.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 4, 1, 1, 4, 4, 1, Block.netherFence.blockID, + Block.netherFence.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 4, 3, 4, 4, 4, 4, Block.netherFence.blockID, + Block.netherFence.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 4, 3, 14, 4, 4, 14, Block.netherFence.blockID, + Block.netherFence.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 4, 1, 17, 4, 4, 17, Block.netherFence.blockID, + Block.netherFence.blockID, false); + return true; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ComponentNetherBridgeThrone.java b/sp-server/src/main/java/net/minecraft/src/ComponentNetherBridgeThrone.java new file mode 100644 index 0000000..4b1e2f2 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ComponentNetherBridgeThrone.java @@ -0,0 +1,96 @@ +package net.minecraft.src; + +import java.util.List; +import java.util.Random; + +public class ComponentNetherBridgeThrone extends ComponentNetherBridgePiece { + private boolean hasSpawner; + + public ComponentNetherBridgeThrone(int par1, Random par2Random, StructureBoundingBox par3StructureBoundingBox, + int par4) { + super(par1); + this.coordBaseMode = par4; + this.boundingBox = par3StructureBoundingBox; + } + + /** + * Creates and returns a new component piece. Or null if it could not find + * enough room to place it. + */ + public static ComponentNetherBridgeThrone createValidComponent(List par0List, Random par1Random, int par2, int par3, + int par4, int par5, int par6) { + StructureBoundingBox var7 = StructureBoundingBox.getComponentToAddBoundingBox(par2, par3, par4, -2, 0, 0, 7, 8, + 9, par5); + return isAboveGround(var7) && StructureComponent.findIntersecting(par0List, var7) == null + ? new ComponentNetherBridgeThrone(par6, par1Random, var7, par5) + : null; + } + + /** + * second Part of Structure generating, this for example places Spiderwebs, Mob + * Spawners, it closes Mineshafts at the end, it adds Fences... + */ + public boolean addComponentParts(World par1World, Random par2Random, + StructureBoundingBox par3StructureBoundingBox) { + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 2, 0, 6, 7, 7, 0, 0, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 1, 0, 0, 5, 1, 7, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 1, 2, 1, 5, 2, 7, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 1, 3, 2, 5, 3, 7, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 1, 4, 3, 5, 4, 7, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 1, 2, 0, 1, 4, 2, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 5, 2, 0, 5, 4, 2, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 1, 5, 2, 1, 5, 3, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 5, 5, 2, 5, 5, 3, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 5, 3, 0, 5, 8, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 6, 5, 3, 6, 5, 8, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 1, 5, 8, 5, 5, 8, Block.netherBrick.blockID, + Block.netherBrick.blockID, false); + this.placeBlockAtCurrentPosition(par1World, Block.netherFence.blockID, 0, 1, 6, 3, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.netherFence.blockID, 0, 5, 6, 3, par3StructureBoundingBox); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 6, 3, 0, 6, 8, Block.netherFence.blockID, + Block.netherFence.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 6, 6, 3, 6, 6, 8, Block.netherFence.blockID, + Block.netherFence.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 1, 6, 8, 5, 7, 8, Block.netherFence.blockID, + Block.netherFence.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 2, 8, 8, 4, 8, 8, Block.netherFence.blockID, + Block.netherFence.blockID, false); + int var4; + int var5; + + if (!this.hasSpawner) { + var4 = this.getYWithOffset(5); + var5 = this.getXWithOffset(3, 5); + int var6 = this.getZWithOffset(3, 5); + + if (par3StructureBoundingBox.isVecInside(var5, var4, var6)) { + this.hasSpawner = true; + par1World.setBlock(var5, var4, var6, Block.mobSpawner.blockID, 0, 2); + TileEntityMobSpawner var7 = (TileEntityMobSpawner) par1World.getBlockTileEntity(var5, var4, var6); + + if (var7 != null) { + var7.func_98049_a().setMobID("Blaze"); + } + } + } + + for (var4 = 0; var4 <= 6; ++var4) { + for (var5 = 0; var5 <= 6; ++var5) { + this.fillCurrentPositionBlocksDownwards(par1World, Block.netherBrick.blockID, 0, var4, -1, var5, + par3StructureBoundingBox); + } + } + + return true; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ComponentScatteredFeature.java b/sp-server/src/main/java/net/minecraft/src/ComponentScatteredFeature.java new file mode 100644 index 0000000..0311340 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ComponentScatteredFeature.java @@ -0,0 +1,62 @@ +package net.minecraft.src; + +import java.util.Random; + +abstract class ComponentScatteredFeature extends StructureComponent { + /** The size of the bounding box for this feature in the X axis */ + protected final int scatteredFeatureSizeX; + + /** The size of the bounding box for this feature in the Y axis */ + protected final int scatteredFeatureSizeY; + + /** The size of the bounding box for this feature in the Z axis */ + protected final int scatteredFeatureSizeZ; + protected int field_74936_d = -1; + + protected ComponentScatteredFeature(Random par1Random, int par2, int par3, int par4, int par5, int par6, int par7) { + super(0); + this.scatteredFeatureSizeX = par5; + this.scatteredFeatureSizeY = par6; + this.scatteredFeatureSizeZ = par7; + this.coordBaseMode = par1Random.nextInt(4); + + switch (this.coordBaseMode) { + case 0: + case 2: + this.boundingBox = new StructureBoundingBox(par2, par3, par4, par2 + par5 - 1, par3 + par6 - 1, + par4 + par7 - 1); + break; + + default: + this.boundingBox = new StructureBoundingBox(par2, par3, par4, par2 + par7 - 1, par3 + par6 - 1, + par4 + par5 - 1); + } + } + + protected boolean func_74935_a(World par1World, StructureBoundingBox par2StructureBoundingBox, int par3) { + if (this.field_74936_d >= 0) { + return true; + } else { + int var4 = 0; + int var5 = 0; + + for (int var6 = this.boundingBox.minZ; var6 <= this.boundingBox.maxZ; ++var6) { + for (int var7 = this.boundingBox.minX; var7 <= this.boundingBox.maxX; ++var7) { + if (par2StructureBoundingBox.isVecInside(var7, 64, var6)) { + var4 += Math.max(par1World.getTopSolidOrLiquidBlock(var7, var6), + par1World.provider.getAverageGroundLevel()); + ++var5; + } + } + } + + if (var5 == 0) { + return false; + } else { + this.field_74936_d = var4 / var5; + this.boundingBox.offset(0, this.field_74936_d - this.boundingBox.minY + par3, 0); + return true; + } + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ComponentScatteredFeatureDesertPyramid.java b/sp-server/src/main/java/net/minecraft/src/ComponentScatteredFeatureDesertPyramid.java new file mode 100644 index 0000000..7fc8a77 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ComponentScatteredFeatureDesertPyramid.java @@ -0,0 +1,323 @@ +package net.minecraft.src; + +import java.util.Random; + +public class ComponentScatteredFeatureDesertPyramid extends ComponentScatteredFeature { + private boolean[] field_74940_h = new boolean[4]; + + /** List of items to generate in chests of Temples. */ + private static final WeightedRandomChestContent[] itemsToGenerateInTemple = new WeightedRandomChestContent[] { + new WeightedRandomChestContent(Item.diamond.itemID, 0, 1, 3, 3), + new WeightedRandomChestContent(Item.ingotIron.itemID, 0, 1, 5, 10), + new WeightedRandomChestContent(Item.ingotGold.itemID, 0, 2, 7, 15), + new WeightedRandomChestContent(Item.emerald.itemID, 0, 1, 3, 2), + new WeightedRandomChestContent(Item.bone.itemID, 0, 4, 6, 20), + new WeightedRandomChestContent(Item.rottenFlesh.itemID, 0, 3, 7, 16) }; + + public ComponentScatteredFeatureDesertPyramid(Random par1Random, int par2, int par3) { + super(par1Random, par2, 64, par3, 21, 15, 21); + } + + /** + * second Part of Structure generating, this for example places Spiderwebs, Mob + * Spawners, it closes Mineshafts at the end, it adds Fences... + */ + public boolean addComponentParts(World par1World, Random par2Random, + StructureBoundingBox par3StructureBoundingBox) { + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, -4, 0, this.scatteredFeatureSizeX - 1, 0, + this.scatteredFeatureSizeZ - 1, Block.sandStone.blockID, Block.sandStone.blockID, false); + int var4; + + for (var4 = 1; var4 <= 9; ++var4) { + this.fillWithBlocks(par1World, par3StructureBoundingBox, var4, var4, var4, + this.scatteredFeatureSizeX - 1 - var4, var4, this.scatteredFeatureSizeZ - 1 - var4, + Block.sandStone.blockID, Block.sandStone.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, var4 + 1, var4, var4 + 1, + this.scatteredFeatureSizeX - 2 - var4, var4, this.scatteredFeatureSizeZ - 2 - var4, 0, 0, false); + } + + int var5; + + for (var4 = 0; var4 < this.scatteredFeatureSizeX; ++var4) { + for (var5 = 0; var5 < this.scatteredFeatureSizeZ; ++var5) { + this.fillCurrentPositionBlocksDownwards(par1World, Block.sandStone.blockID, 0, var4, -5, var5, + par3StructureBoundingBox); + } + } + + var4 = this.getMetadataWithOffset(Block.stairsSandStone.blockID, 3); + var5 = this.getMetadataWithOffset(Block.stairsSandStone.blockID, 2); + int var6 = this.getMetadataWithOffset(Block.stairsSandStone.blockID, 0); + int var7 = this.getMetadataWithOffset(Block.stairsSandStone.blockID, 1); + byte var8 = 1; + byte var9 = 11; + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 0, 0, 4, 9, 4, Block.sandStone.blockID, 0, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 1, 10, 1, 3, 10, 3, Block.sandStone.blockID, + Block.sandStone.blockID, false); + this.placeBlockAtCurrentPosition(par1World, Block.stairsSandStone.blockID, var4, 2, 10, 0, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stairsSandStone.blockID, var5, 2, 10, 4, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stairsSandStone.blockID, var6, 0, 10, 2, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stairsSandStone.blockID, var7, 4, 10, 2, + par3StructureBoundingBox); + this.fillWithBlocks(par1World, par3StructureBoundingBox, this.scatteredFeatureSizeX - 5, 0, 0, + this.scatteredFeatureSizeX - 1, 9, 4, Block.sandStone.blockID, 0, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, this.scatteredFeatureSizeX - 4, 10, 1, + this.scatteredFeatureSizeX - 2, 10, 3, Block.sandStone.blockID, Block.sandStone.blockID, false); + this.placeBlockAtCurrentPosition(par1World, Block.stairsSandStone.blockID, var4, this.scatteredFeatureSizeX - 3, + 10, 0, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stairsSandStone.blockID, var5, this.scatteredFeatureSizeX - 3, + 10, 4, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stairsSandStone.blockID, var6, this.scatteredFeatureSizeX - 5, + 10, 2, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stairsSandStone.blockID, var7, this.scatteredFeatureSizeX - 1, + 10, 2, par3StructureBoundingBox); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 8, 0, 0, 12, 4, 4, Block.sandStone.blockID, 0, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 9, 1, 0, 11, 3, 4, 0, 0, false); + this.placeBlockAtCurrentPosition(par1World, Block.sandStone.blockID, 2, 9, 1, 1, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.sandStone.blockID, 2, 9, 2, 1, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.sandStone.blockID, 2, 9, 3, 1, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.sandStone.blockID, 2, 10, 3, 1, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.sandStone.blockID, 2, 11, 3, 1, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.sandStone.blockID, 2, 11, 2, 1, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.sandStone.blockID, 2, 11, 1, 1, par3StructureBoundingBox); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 4, 1, 1, 8, 3, 3, Block.sandStone.blockID, 0, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 4, 1, 2, 8, 2, 2, 0, 0, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 12, 1, 1, 16, 3, 3, Block.sandStone.blockID, 0, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 12, 1, 2, 16, 2, 2, 0, 0, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 5, 4, 5, this.scatteredFeatureSizeX - 6, 4, + this.scatteredFeatureSizeZ - 6, Block.sandStone.blockID, Block.sandStone.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 9, 4, 9, 11, 4, 11, 0, 0, false); + this.fillWithMetadataBlocks(par1World, par3StructureBoundingBox, 8, 1, 8, 8, 3, 8, Block.sandStone.blockID, 2, + Block.sandStone.blockID, 2, false); + this.fillWithMetadataBlocks(par1World, par3StructureBoundingBox, 12, 1, 8, 12, 3, 8, Block.sandStone.blockID, 2, + Block.sandStone.blockID, 2, false); + this.fillWithMetadataBlocks(par1World, par3StructureBoundingBox, 8, 1, 12, 8, 3, 12, Block.sandStone.blockID, 2, + Block.sandStone.blockID, 2, false); + this.fillWithMetadataBlocks(par1World, par3StructureBoundingBox, 12, 1, 12, 12, 3, 12, Block.sandStone.blockID, + 2, Block.sandStone.blockID, 2, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 1, 1, 5, 4, 4, 11, Block.sandStone.blockID, + Block.sandStone.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, this.scatteredFeatureSizeX - 5, 1, 5, + this.scatteredFeatureSizeX - 2, 4, 11, Block.sandStone.blockID, Block.sandStone.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 6, 7, 9, 6, 7, 11, Block.sandStone.blockID, + Block.sandStone.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, this.scatteredFeatureSizeX - 7, 7, 9, + this.scatteredFeatureSizeX - 7, 7, 11, Block.sandStone.blockID, Block.sandStone.blockID, false); + this.fillWithMetadataBlocks(par1World, par3StructureBoundingBox, 5, 5, 9, 5, 7, 11, Block.sandStone.blockID, 2, + Block.sandStone.blockID, 2, false); + this.fillWithMetadataBlocks(par1World, par3StructureBoundingBox, this.scatteredFeatureSizeX - 6, 5, 9, + this.scatteredFeatureSizeX - 6, 7, 11, Block.sandStone.blockID, 2, Block.sandStone.blockID, 2, false); + this.placeBlockAtCurrentPosition(par1World, 0, 0, 5, 5, 10, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, 0, 0, 5, 6, 10, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, 0, 0, 6, 6, 10, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, 0, 0, this.scatteredFeatureSizeX - 6, 5, 10, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, 0, 0, this.scatteredFeatureSizeX - 6, 6, 10, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, 0, 0, this.scatteredFeatureSizeX - 7, 6, 10, + par3StructureBoundingBox); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 2, 4, 4, 2, 6, 4, 0, 0, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, this.scatteredFeatureSizeX - 3, 4, 4, + this.scatteredFeatureSizeX - 3, 6, 4, 0, 0, false); + this.placeBlockAtCurrentPosition(par1World, Block.stairsSandStone.blockID, var4, 2, 4, 5, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stairsSandStone.blockID, var4, 2, 3, 4, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stairsSandStone.blockID, var4, this.scatteredFeatureSizeX - 3, + 4, 5, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stairsSandStone.blockID, var4, this.scatteredFeatureSizeX - 3, + 3, 4, par3StructureBoundingBox); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 1, 1, 3, 2, 2, 3, Block.sandStone.blockID, + Block.sandStone.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, this.scatteredFeatureSizeX - 3, 1, 3, + this.scatteredFeatureSizeX - 2, 2, 3, Block.sandStone.blockID, Block.sandStone.blockID, false); + this.placeBlockAtCurrentPosition(par1World, Block.stairsSandStone.blockID, 0, 1, 1, 2, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stairsSandStone.blockID, 0, this.scatteredFeatureSizeX - 2, 1, + 2, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stoneSingleSlab.blockID, 1, 1, 2, 2, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stoneSingleSlab.blockID, 1, this.scatteredFeatureSizeX - 2, 2, + 2, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stairsSandStone.blockID, var7, 2, 1, 2, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stairsSandStone.blockID, var6, this.scatteredFeatureSizeX - 3, + 1, 2, par3StructureBoundingBox); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 4, 3, 5, 4, 3, 18, Block.sandStone.blockID, + Block.sandStone.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, this.scatteredFeatureSizeX - 5, 3, 5, + this.scatteredFeatureSizeX - 5, 3, 17, Block.sandStone.blockID, Block.sandStone.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 3, 1, 5, 4, 2, 16, 0, 0, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, this.scatteredFeatureSizeX - 6, 1, 5, + this.scatteredFeatureSizeX - 5, 2, 16, 0, 0, false); + int var10; + + for (var10 = 5; var10 <= 17; var10 += 2) { + this.placeBlockAtCurrentPosition(par1World, Block.sandStone.blockID, 2, 4, 1, var10, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.sandStone.blockID, 1, 4, 2, var10, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.sandStone.blockID, 2, this.scatteredFeatureSizeX - 5, 1, + var10, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.sandStone.blockID, 1, this.scatteredFeatureSizeX - 5, 2, + var10, par3StructureBoundingBox); + } + + this.placeBlockAtCurrentPosition(par1World, Block.cloth.blockID, var8, 10, 0, 7, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.cloth.blockID, var8, 10, 0, 8, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.cloth.blockID, var8, 9, 0, 9, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.cloth.blockID, var8, 11, 0, 9, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.cloth.blockID, var8, 8, 0, 10, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.cloth.blockID, var8, 12, 0, 10, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.cloth.blockID, var8, 7, 0, 10, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.cloth.blockID, var8, 13, 0, 10, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.cloth.blockID, var8, 9, 0, 11, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.cloth.blockID, var8, 11, 0, 11, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.cloth.blockID, var8, 10, 0, 12, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.cloth.blockID, var8, 10, 0, 13, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.cloth.blockID, var9, 10, 0, 10, par3StructureBoundingBox); + + for (var10 = 0; var10 <= this.scatteredFeatureSizeX - 1; var10 += this.scatteredFeatureSizeX - 1) { + this.placeBlockAtCurrentPosition(par1World, Block.sandStone.blockID, 2, var10, 2, 1, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.cloth.blockID, var8, var10, 2, 2, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.sandStone.blockID, 2, var10, 2, 3, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.sandStone.blockID, 2, var10, 3, 1, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.cloth.blockID, var8, var10, 3, 2, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.sandStone.blockID, 2, var10, 3, 3, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.cloth.blockID, var8, var10, 4, 1, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.sandStone.blockID, 1, var10, 4, 2, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.cloth.blockID, var8, var10, 4, 3, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.sandStone.blockID, 2, var10, 5, 1, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.cloth.blockID, var8, var10, 5, 2, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.sandStone.blockID, 2, var10, 5, 3, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.cloth.blockID, var8, var10, 6, 1, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.sandStone.blockID, 1, var10, 6, 2, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.cloth.blockID, var8, var10, 6, 3, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.cloth.blockID, var8, var10, 7, 1, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.cloth.blockID, var8, var10, 7, 2, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.cloth.blockID, var8, var10, 7, 3, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.sandStone.blockID, 2, var10, 8, 1, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.sandStone.blockID, 2, var10, 8, 2, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.sandStone.blockID, 2, var10, 8, 3, + par3StructureBoundingBox); + } + + for (var10 = 2; var10 <= this.scatteredFeatureSizeX - 3; var10 += this.scatteredFeatureSizeX - 3 - 2) { + this.placeBlockAtCurrentPosition(par1World, Block.sandStone.blockID, 2, var10 - 1, 2, 0, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.cloth.blockID, var8, var10, 2, 0, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.sandStone.blockID, 2, var10 + 1, 2, 0, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.sandStone.blockID, 2, var10 - 1, 3, 0, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.cloth.blockID, var8, var10, 3, 0, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.sandStone.blockID, 2, var10 + 1, 3, 0, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.cloth.blockID, var8, var10 - 1, 4, 0, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.sandStone.blockID, 1, var10, 4, 0, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.cloth.blockID, var8, var10 + 1, 4, 0, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.sandStone.blockID, 2, var10 - 1, 5, 0, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.cloth.blockID, var8, var10, 5, 0, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.sandStone.blockID, 2, var10 + 1, 5, 0, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.cloth.blockID, var8, var10 - 1, 6, 0, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.sandStone.blockID, 1, var10, 6, 0, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.cloth.blockID, var8, var10 + 1, 6, 0, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.cloth.blockID, var8, var10 - 1, 7, 0, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.cloth.blockID, var8, var10, 7, 0, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.cloth.blockID, var8, var10 + 1, 7, 0, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.sandStone.blockID, 2, var10 - 1, 8, 0, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.sandStone.blockID, 2, var10, 8, 0, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.sandStone.blockID, 2, var10 + 1, 8, 0, + par3StructureBoundingBox); + } + + this.fillWithMetadataBlocks(par1World, par3StructureBoundingBox, 8, 4, 0, 12, 6, 0, Block.sandStone.blockID, 2, + Block.sandStone.blockID, 2, false); + this.placeBlockAtCurrentPosition(par1World, 0, 0, 8, 6, 0, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, 0, 0, 12, 6, 0, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.cloth.blockID, var8, 9, 5, 0, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.sandStone.blockID, 1, 10, 5, 0, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.cloth.blockID, var8, 11, 5, 0, par3StructureBoundingBox); + this.fillWithMetadataBlocks(par1World, par3StructureBoundingBox, 8, -14, 8, 12, -11, 12, + Block.sandStone.blockID, 2, Block.sandStone.blockID, 2, false); + this.fillWithMetadataBlocks(par1World, par3StructureBoundingBox, 8, -10, 8, 12, -10, 12, + Block.sandStone.blockID, 1, Block.sandStone.blockID, 1, false); + this.fillWithMetadataBlocks(par1World, par3StructureBoundingBox, 8, -9, 8, 12, -9, 12, Block.sandStone.blockID, + 2, Block.sandStone.blockID, 2, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 8, -8, 8, 12, -1, 12, Block.sandStone.blockID, + Block.sandStone.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 9, -11, 9, 11, -1, 11, 0, 0, false); + this.placeBlockAtCurrentPosition(par1World, Block.pressurePlateStone.blockID, 0, 10, -11, 10, + par3StructureBoundingBox); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 9, -13, 9, 11, -13, 11, Block.tnt.blockID, 0, false); + this.placeBlockAtCurrentPosition(par1World, 0, 0, 8, -11, 10, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, 0, 0, 8, -10, 10, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.sandStone.blockID, 1, 7, -10, 10, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.sandStone.blockID, 2, 7, -11, 10, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, 0, 0, 12, -11, 10, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, 0, 0, 12, -10, 10, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.sandStone.blockID, 1, 13, -10, 10, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.sandStone.blockID, 2, 13, -11, 10, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, 0, 0, 10, -11, 8, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, 0, 0, 10, -10, 8, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.sandStone.blockID, 1, 10, -10, 7, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.sandStone.blockID, 2, 10, -11, 7, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, 0, 0, 10, -11, 12, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, 0, 0, 10, -10, 12, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.sandStone.blockID, 1, 10, -10, 13, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.sandStone.blockID, 2, 10, -11, 13, par3StructureBoundingBox); + + for (var10 = 0; var10 < 4; ++var10) { + if (!this.field_74940_h[var10]) { + int var11 = Direction.offsetX[var10] * 2; + int var12 = Direction.offsetZ[var10] * 2; + this.field_74940_h[var10] = this.generateStructureChestContents(par1World, par3StructureBoundingBox, + par2Random, 10 + var11, -11, 10 + var12, + WeightedRandomChestContent.func_92080_a(itemsToGenerateInTemple, + new WeightedRandomChestContent[] { Item.enchantedBook.func_92114_b(par2Random) }), + 2 + par2Random.nextInt(5)); + } + } + + return true; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ComponentScatteredFeatureJunglePyramid.java b/sp-server/src/main/java/net/minecraft/src/ComponentScatteredFeatureJunglePyramid.java new file mode 100644 index 0000000..953d460 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ComponentScatteredFeatureJunglePyramid.java @@ -0,0 +1,341 @@ +package net.minecraft.src; + +import java.util.Random; + +public class ComponentScatteredFeatureJunglePyramid extends ComponentScatteredFeature { + private boolean field_74947_h; + private boolean field_74948_i; + private boolean field_74945_j; + private boolean field_74946_k; + + /** List of Chest contents to be generated in the Jungle Pyramid chests. */ + private static final WeightedRandomChestContent[] junglePyramidsChestContents = new WeightedRandomChestContent[] { + new WeightedRandomChestContent(Item.diamond.itemID, 0, 1, 3, 3), + new WeightedRandomChestContent(Item.ingotIron.itemID, 0, 1, 5, 10), + new WeightedRandomChestContent(Item.ingotGold.itemID, 0, 2, 7, 15), + new WeightedRandomChestContent(Item.emerald.itemID, 0, 1, 3, 2), + new WeightedRandomChestContent(Item.bone.itemID, 0, 4, 6, 20), + new WeightedRandomChestContent(Item.rottenFlesh.itemID, 0, 3, 7, 16) }; + + /** + * List of Dispenser contents to be generated in the Jungle Pyramid dispensers. + */ + private static final WeightedRandomChestContent[] junglePyramidsDispenserContents = new WeightedRandomChestContent[] { + new WeightedRandomChestContent(Item.arrow.itemID, 0, 2, 7, 30) }; + + /** List of random stones to be generated in the Jungle Pyramid. */ + private static StructureScatteredFeatureStones junglePyramidsRandomScatteredStones = new StructureScatteredFeatureStones( + (ComponentScatteredFeaturePieces2) null); + + public ComponentScatteredFeatureJunglePyramid(Random par1Random, int par2, int par3) { + super(par1Random, par2, 64, par3, 12, 10, 15); + } + + /** + * second Part of Structure generating, this for example places Spiderwebs, Mob + * Spawners, it closes Mineshafts at the end, it adds Fences... + */ + public boolean addComponentParts(World par1World, Random par2Random, + StructureBoundingBox par3StructureBoundingBox) { + if (!this.func_74935_a(par1World, par3StructureBoundingBox, 0)) { + return false; + } else { + int var4 = this.getMetadataWithOffset(Block.stairsCobblestone.blockID, 3); + int var5 = this.getMetadataWithOffset(Block.stairsCobblestone.blockID, 2); + int var6 = this.getMetadataWithOffset(Block.stairsCobblestone.blockID, 0); + int var7 = this.getMetadataWithOffset(Block.stairsCobblestone.blockID, 1); + this.fillWithRandomizedBlocks(par1World, par3StructureBoundingBox, 0, -4, 0, this.scatteredFeatureSizeX - 1, + 0, this.scatteredFeatureSizeZ - 1, false, par2Random, junglePyramidsRandomScatteredStones); + this.fillWithRandomizedBlocks(par1World, par3StructureBoundingBox, 2, 1, 2, 9, 2, 2, false, par2Random, + junglePyramidsRandomScatteredStones); + this.fillWithRandomizedBlocks(par1World, par3StructureBoundingBox, 2, 1, 12, 9, 2, 12, false, par2Random, + junglePyramidsRandomScatteredStones); + this.fillWithRandomizedBlocks(par1World, par3StructureBoundingBox, 2, 1, 3, 2, 2, 11, false, par2Random, + junglePyramidsRandomScatteredStones); + this.fillWithRandomizedBlocks(par1World, par3StructureBoundingBox, 9, 1, 3, 9, 2, 11, false, par2Random, + junglePyramidsRandomScatteredStones); + this.fillWithRandomizedBlocks(par1World, par3StructureBoundingBox, 1, 3, 1, 10, 6, 1, false, par2Random, + junglePyramidsRandomScatteredStones); + this.fillWithRandomizedBlocks(par1World, par3StructureBoundingBox, 1, 3, 13, 10, 6, 13, false, par2Random, + junglePyramidsRandomScatteredStones); + this.fillWithRandomizedBlocks(par1World, par3StructureBoundingBox, 1, 3, 2, 1, 6, 12, false, par2Random, + junglePyramidsRandomScatteredStones); + this.fillWithRandomizedBlocks(par1World, par3StructureBoundingBox, 10, 3, 2, 10, 6, 12, false, par2Random, + junglePyramidsRandomScatteredStones); + this.fillWithRandomizedBlocks(par1World, par3StructureBoundingBox, 2, 3, 2, 9, 3, 12, false, par2Random, + junglePyramidsRandomScatteredStones); + this.fillWithRandomizedBlocks(par1World, par3StructureBoundingBox, 2, 6, 2, 9, 6, 12, false, par2Random, + junglePyramidsRandomScatteredStones); + this.fillWithRandomizedBlocks(par1World, par3StructureBoundingBox, 3, 7, 3, 8, 7, 11, false, par2Random, + junglePyramidsRandomScatteredStones); + this.fillWithRandomizedBlocks(par1World, par3StructureBoundingBox, 4, 8, 4, 7, 8, 10, false, par2Random, + junglePyramidsRandomScatteredStones); + this.fillWithAir(par1World, par3StructureBoundingBox, 3, 1, 3, 8, 2, 11); + this.fillWithAir(par1World, par3StructureBoundingBox, 4, 3, 6, 7, 3, 9); + this.fillWithAir(par1World, par3StructureBoundingBox, 2, 4, 2, 9, 5, 12); + this.fillWithAir(par1World, par3StructureBoundingBox, 4, 6, 5, 7, 6, 9); + this.fillWithAir(par1World, par3StructureBoundingBox, 5, 7, 6, 6, 7, 8); + this.fillWithAir(par1World, par3StructureBoundingBox, 5, 1, 2, 6, 2, 2); + this.fillWithAir(par1World, par3StructureBoundingBox, 5, 2, 12, 6, 2, 12); + this.fillWithAir(par1World, par3StructureBoundingBox, 5, 5, 1, 6, 5, 1); + this.fillWithAir(par1World, par3StructureBoundingBox, 5, 5, 13, 6, 5, 13); + this.placeBlockAtCurrentPosition(par1World, 0, 0, 1, 5, 5, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, 0, 0, 10, 5, 5, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, 0, 0, 1, 5, 9, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, 0, 0, 10, 5, 9, par3StructureBoundingBox); + int var8; + + for (var8 = 0; var8 <= 14; var8 += 14) { + this.fillWithRandomizedBlocks(par1World, par3StructureBoundingBox, 2, 4, var8, 2, 5, var8, false, + par2Random, junglePyramidsRandomScatteredStones); + this.fillWithRandomizedBlocks(par1World, par3StructureBoundingBox, 4, 4, var8, 4, 5, var8, false, + par2Random, junglePyramidsRandomScatteredStones); + this.fillWithRandomizedBlocks(par1World, par3StructureBoundingBox, 7, 4, var8, 7, 5, var8, false, + par2Random, junglePyramidsRandomScatteredStones); + this.fillWithRandomizedBlocks(par1World, par3StructureBoundingBox, 9, 4, var8, 9, 5, var8, false, + par2Random, junglePyramidsRandomScatteredStones); + } + + this.fillWithRandomizedBlocks(par1World, par3StructureBoundingBox, 5, 6, 0, 6, 6, 0, false, par2Random, + junglePyramidsRandomScatteredStones); + + for (var8 = 0; var8 <= 11; var8 += 11) { + for (int var9 = 2; var9 <= 12; var9 += 2) { + this.fillWithRandomizedBlocks(par1World, par3StructureBoundingBox, var8, 4, var9, var8, 5, var9, + false, par2Random, junglePyramidsRandomScatteredStones); + } + + this.fillWithRandomizedBlocks(par1World, par3StructureBoundingBox, var8, 6, 5, var8, 6, 5, false, + par2Random, junglePyramidsRandomScatteredStones); + this.fillWithRandomizedBlocks(par1World, par3StructureBoundingBox, var8, 6, 9, var8, 6, 9, false, + par2Random, junglePyramidsRandomScatteredStones); + } + + this.fillWithRandomizedBlocks(par1World, par3StructureBoundingBox, 2, 7, 2, 2, 9, 2, false, par2Random, + junglePyramidsRandomScatteredStones); + this.fillWithRandomizedBlocks(par1World, par3StructureBoundingBox, 9, 7, 2, 9, 9, 2, false, par2Random, + junglePyramidsRandomScatteredStones); + this.fillWithRandomizedBlocks(par1World, par3StructureBoundingBox, 2, 7, 12, 2, 9, 12, false, par2Random, + junglePyramidsRandomScatteredStones); + this.fillWithRandomizedBlocks(par1World, par3StructureBoundingBox, 9, 7, 12, 9, 9, 12, false, par2Random, + junglePyramidsRandomScatteredStones); + this.fillWithRandomizedBlocks(par1World, par3StructureBoundingBox, 4, 9, 4, 4, 9, 4, false, par2Random, + junglePyramidsRandomScatteredStones); + this.fillWithRandomizedBlocks(par1World, par3StructureBoundingBox, 7, 9, 4, 7, 9, 4, false, par2Random, + junglePyramidsRandomScatteredStones); + this.fillWithRandomizedBlocks(par1World, par3StructureBoundingBox, 4, 9, 10, 4, 9, 10, false, par2Random, + junglePyramidsRandomScatteredStones); + this.fillWithRandomizedBlocks(par1World, par3StructureBoundingBox, 7, 9, 10, 7, 9, 10, false, par2Random, + junglePyramidsRandomScatteredStones); + this.fillWithRandomizedBlocks(par1World, par3StructureBoundingBox, 5, 9, 7, 6, 9, 7, false, par2Random, + junglePyramidsRandomScatteredStones); + this.placeBlockAtCurrentPosition(par1World, Block.stairsCobblestone.blockID, var4, 5, 9, 6, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stairsCobblestone.blockID, var4, 6, 9, 6, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stairsCobblestone.blockID, var5, 5, 9, 8, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stairsCobblestone.blockID, var5, 6, 9, 8, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stairsCobblestone.blockID, var4, 4, 0, 0, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stairsCobblestone.blockID, var4, 5, 0, 0, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stairsCobblestone.blockID, var4, 6, 0, 0, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stairsCobblestone.blockID, var4, 7, 0, 0, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stairsCobblestone.blockID, var4, 4, 1, 8, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stairsCobblestone.blockID, var4, 4, 2, 9, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stairsCobblestone.blockID, var4, 4, 3, 10, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stairsCobblestone.blockID, var4, 7, 1, 8, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stairsCobblestone.blockID, var4, 7, 2, 9, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stairsCobblestone.blockID, var4, 7, 3, 10, + par3StructureBoundingBox); + this.fillWithRandomizedBlocks(par1World, par3StructureBoundingBox, 4, 1, 9, 4, 1, 9, false, par2Random, + junglePyramidsRandomScatteredStones); + this.fillWithRandomizedBlocks(par1World, par3StructureBoundingBox, 7, 1, 9, 7, 1, 9, false, par2Random, + junglePyramidsRandomScatteredStones); + this.fillWithRandomizedBlocks(par1World, par3StructureBoundingBox, 4, 1, 10, 7, 2, 10, false, par2Random, + junglePyramidsRandomScatteredStones); + this.fillWithRandomizedBlocks(par1World, par3StructureBoundingBox, 5, 4, 5, 6, 4, 5, false, par2Random, + junglePyramidsRandomScatteredStones); + this.placeBlockAtCurrentPosition(par1World, Block.stairsCobblestone.blockID, var6, 4, 4, 5, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stairsCobblestone.blockID, var7, 7, 4, 5, + par3StructureBoundingBox); + + for (var8 = 0; var8 < 4; ++var8) { + this.placeBlockAtCurrentPosition(par1World, Block.stairsCobblestone.blockID, var5, 5, 0 - var8, + 6 + var8, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stairsCobblestone.blockID, var5, 6, 0 - var8, + 6 + var8, par3StructureBoundingBox); + this.fillWithAir(par1World, par3StructureBoundingBox, 5, 0 - var8, 7 + var8, 6, 0 - var8, 9 + var8); + } + + this.fillWithAir(par1World, par3StructureBoundingBox, 1, -3, 12, 10, -1, 13); + this.fillWithAir(par1World, par3StructureBoundingBox, 1, -3, 1, 3, -1, 13); + this.fillWithAir(par1World, par3StructureBoundingBox, 1, -3, 1, 9, -1, 5); + + for (var8 = 1; var8 <= 13; var8 += 2) { + this.fillWithRandomizedBlocks(par1World, par3StructureBoundingBox, 1, -3, var8, 1, -2, var8, false, + par2Random, junglePyramidsRandomScatteredStones); + } + + for (var8 = 2; var8 <= 12; var8 += 2) { + this.fillWithRandomizedBlocks(par1World, par3StructureBoundingBox, 1, -1, var8, 3, -1, var8, false, + par2Random, junglePyramidsRandomScatteredStones); + } + + this.fillWithRandomizedBlocks(par1World, par3StructureBoundingBox, 2, -2, 1, 5, -2, 1, false, par2Random, + junglePyramidsRandomScatteredStones); + this.fillWithRandomizedBlocks(par1World, par3StructureBoundingBox, 7, -2, 1, 9, -2, 1, false, par2Random, + junglePyramidsRandomScatteredStones); + this.fillWithRandomizedBlocks(par1World, par3StructureBoundingBox, 6, -3, 1, 6, -3, 1, false, par2Random, + junglePyramidsRandomScatteredStones); + this.fillWithRandomizedBlocks(par1World, par3StructureBoundingBox, 6, -1, 1, 6, -1, 1, false, par2Random, + junglePyramidsRandomScatteredStones); + this.placeBlockAtCurrentPosition(par1World, Block.tripWireSource.blockID, + this.getMetadataWithOffset(Block.tripWireSource.blockID, 3) | 4, 1, -3, 8, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.tripWireSource.blockID, + this.getMetadataWithOffset(Block.tripWireSource.blockID, 1) | 4, 4, -3, 8, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.tripWire.blockID, 4, 2, -3, 8, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.tripWire.blockID, 4, 3, -3, 8, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.redstoneWire.blockID, 0, 5, -3, 7, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.redstoneWire.blockID, 0, 5, -3, 6, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.redstoneWire.blockID, 0, 5, -3, 5, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.redstoneWire.blockID, 0, 5, -3, 4, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.redstoneWire.blockID, 0, 5, -3, 3, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.redstoneWire.blockID, 0, 5, -3, 2, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.redstoneWire.blockID, 0, 5, -3, 1, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.redstoneWire.blockID, 0, 4, -3, 1, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.cobblestoneMossy.blockID, 0, 3, -3, 1, + par3StructureBoundingBox); + + if (!this.field_74945_j) { + this.field_74945_j = this.generateStructureDispenserContents(par1World, par3StructureBoundingBox, + par2Random, 3, -2, 1, 2, junglePyramidsDispenserContents, 2); + } + + this.placeBlockAtCurrentPosition(par1World, Block.vine.blockID, 15, 3, -2, 2, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.tripWireSource.blockID, + this.getMetadataWithOffset(Block.tripWireSource.blockID, 2) | 4, 7, -3, 1, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.tripWireSource.blockID, + this.getMetadataWithOffset(Block.tripWireSource.blockID, 0) | 4, 7, -3, 5, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.tripWire.blockID, 4, 7, -3, 2, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.tripWire.blockID, 4, 7, -3, 3, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.tripWire.blockID, 4, 7, -3, 4, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.redstoneWire.blockID, 0, 8, -3, 6, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.redstoneWire.blockID, 0, 9, -3, 6, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.redstoneWire.blockID, 0, 9, -3, 5, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.cobblestoneMossy.blockID, 0, 9, -3, 4, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.redstoneWire.blockID, 0, 9, -2, 4, + par3StructureBoundingBox); + + if (!this.field_74946_k) { + this.field_74946_k = this.generateStructureDispenserContents(par1World, par3StructureBoundingBox, + par2Random, 9, -2, 3, 4, junglePyramidsDispenserContents, 2); + } + + this.placeBlockAtCurrentPosition(par1World, Block.vine.blockID, 15, 8, -1, 3, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.vine.blockID, 15, 8, -2, 3, par3StructureBoundingBox); + + if (!this.field_74947_h) { + this.field_74947_h = this.generateStructureChestContents(par1World, par3StructureBoundingBox, + par2Random, 8, -3, 3, + WeightedRandomChestContent.func_92080_a(junglePyramidsChestContents, + new WeightedRandomChestContent[] { Item.enchantedBook.func_92114_b(par2Random) }), + 2 + par2Random.nextInt(5)); + } + + this.placeBlockAtCurrentPosition(par1World, Block.cobblestoneMossy.blockID, 0, 9, -3, 2, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.cobblestoneMossy.blockID, 0, 8, -3, 1, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.cobblestoneMossy.blockID, 0, 4, -3, 5, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.cobblestoneMossy.blockID, 0, 5, -2, 5, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.cobblestoneMossy.blockID, 0, 5, -1, 5, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.cobblestoneMossy.blockID, 0, 6, -3, 5, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.cobblestoneMossy.blockID, 0, 7, -2, 5, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.cobblestoneMossy.blockID, 0, 7, -1, 5, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.cobblestoneMossy.blockID, 0, 8, -3, 5, + par3StructureBoundingBox); + this.fillWithRandomizedBlocks(par1World, par3StructureBoundingBox, 9, -1, 1, 9, -1, 5, false, par2Random, + junglePyramidsRandomScatteredStones); + this.fillWithAir(par1World, par3StructureBoundingBox, 8, -3, 8, 10, -1, 10); + this.placeBlockAtCurrentPosition(par1World, Block.stoneBrick.blockID, 3, 8, -2, 11, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stoneBrick.blockID, 3, 9, -2, 11, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stoneBrick.blockID, 3, 10, -2, 11, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.lever.blockID, + BlockLever.invertMetadata(this.getMetadataWithOffset(Block.lever.blockID, 2)), 8, -2, 12, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.lever.blockID, + BlockLever.invertMetadata(this.getMetadataWithOffset(Block.lever.blockID, 2)), 9, -2, 12, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.lever.blockID, + BlockLever.invertMetadata(this.getMetadataWithOffset(Block.lever.blockID, 2)), 10, -2, 12, + par3StructureBoundingBox); + this.fillWithRandomizedBlocks(par1World, par3StructureBoundingBox, 8, -3, 8, 8, -3, 10, false, par2Random, + junglePyramidsRandomScatteredStones); + this.fillWithRandomizedBlocks(par1World, par3StructureBoundingBox, 10, -3, 8, 10, -3, 10, false, par2Random, + junglePyramidsRandomScatteredStones); + this.placeBlockAtCurrentPosition(par1World, Block.cobblestoneMossy.blockID, 0, 10, -2, 9, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.redstoneWire.blockID, 0, 8, -2, 9, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.redstoneWire.blockID, 0, 8, -2, 10, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.redstoneWire.blockID, 0, 10, -1, 9, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.pistonStickyBase.blockID, 1, 9, -2, 8, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.pistonStickyBase.blockID, + this.getMetadataWithOffset(Block.pistonStickyBase.blockID, 4), 10, -2, 8, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.pistonStickyBase.blockID, + this.getMetadataWithOffset(Block.pistonStickyBase.blockID, 4), 10, -1, 8, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.redstoneRepeaterIdle.blockID, + this.getMetadataWithOffset(Block.redstoneRepeaterIdle.blockID, 2), 10, -2, 10, + par3StructureBoundingBox); + + if (!this.field_74948_i) { + this.field_74948_i = this.generateStructureChestContents(par1World, par3StructureBoundingBox, + par2Random, 9, -3, 10, + WeightedRandomChestContent.func_92080_a(junglePyramidsChestContents, + new WeightedRandomChestContent[] { Item.enchantedBook.func_92114_b(par2Random) }), + 2 + par2Random.nextInt(5)); + } + + return true; + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ComponentScatteredFeaturePieces2.java b/sp-server/src/main/java/net/minecraft/src/ComponentScatteredFeaturePieces2.java new file mode 100644 index 0000000..1db727b --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ComponentScatteredFeaturePieces2.java @@ -0,0 +1,4 @@ +package net.minecraft.src; + +class ComponentScatteredFeaturePieces2 { +} diff --git a/sp-server/src/main/java/net/minecraft/src/ComponentScatteredFeatureSwampHut.java b/sp-server/src/main/java/net/minecraft/src/ComponentScatteredFeatureSwampHut.java new file mode 100644 index 0000000..99c55a8 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ComponentScatteredFeatureSwampHut.java @@ -0,0 +1,93 @@ +package net.minecraft.src; + +import java.util.Random; + +public class ComponentScatteredFeatureSwampHut extends ComponentScatteredFeature { + /** Whether this swamp hut has a witch. */ + private boolean hasWitch; + + public ComponentScatteredFeatureSwampHut(Random par1Random, int par2, int par3) { + super(par1Random, par2, 64, par3, 7, 5, 9); + } + + /** + * second Part of Structure generating, this for example places Spiderwebs, Mob + * Spawners, it closes Mineshafts at the end, it adds Fences... + */ + public boolean addComponentParts(World par1World, Random par2Random, + StructureBoundingBox par3StructureBoundingBox) { + if (!this.func_74935_a(par1World, par3StructureBoundingBox, 0)) { + return false; + } else { + this.fillWithMetadataBlocks(par1World, par3StructureBoundingBox, 1, 1, 1, 5, 1, 7, Block.planks.blockID, 1, + Block.planks.blockID, 1, false); + this.fillWithMetadataBlocks(par1World, par3StructureBoundingBox, 1, 4, 2, 5, 4, 7, Block.planks.blockID, 1, + Block.planks.blockID, 1, false); + this.fillWithMetadataBlocks(par1World, par3StructureBoundingBox, 2, 1, 0, 4, 1, 0, Block.planks.blockID, 1, + Block.planks.blockID, 1, false); + this.fillWithMetadataBlocks(par1World, par3StructureBoundingBox, 2, 2, 2, 3, 3, 2, Block.planks.blockID, 1, + Block.planks.blockID, 1, false); + this.fillWithMetadataBlocks(par1World, par3StructureBoundingBox, 1, 2, 3, 1, 3, 6, Block.planks.blockID, 1, + Block.planks.blockID, 1, false); + this.fillWithMetadataBlocks(par1World, par3StructureBoundingBox, 5, 2, 3, 5, 3, 6, Block.planks.blockID, 1, + Block.planks.blockID, 1, false); + this.fillWithMetadataBlocks(par1World, par3StructureBoundingBox, 2, 2, 7, 4, 3, 7, Block.planks.blockID, 1, + Block.planks.blockID, 1, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 1, 0, 2, 1, 3, 2, Block.wood.blockID, + Block.wood.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 5, 0, 2, 5, 3, 2, Block.wood.blockID, + Block.wood.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 1, 0, 7, 1, 3, 7, Block.wood.blockID, + Block.wood.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 5, 0, 7, 5, 3, 7, Block.wood.blockID, + Block.wood.blockID, false); + this.placeBlockAtCurrentPosition(par1World, Block.fence.blockID, 0, 2, 3, 2, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.fence.blockID, 0, 3, 3, 7, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, 0, 0, 1, 3, 4, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, 0, 0, 5, 3, 4, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, 0, 0, 5, 3, 5, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.flowerPot.blockID, 7, 1, 3, 5, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.workbench.blockID, 0, 3, 2, 6, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.cauldron.blockID, 0, 4, 2, 6, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.fence.blockID, 0, 1, 2, 1, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.fence.blockID, 0, 5, 2, 1, par3StructureBoundingBox); + int var4 = this.getMetadataWithOffset(Block.stairsWoodOak.blockID, 3); + int var5 = this.getMetadataWithOffset(Block.stairsWoodOak.blockID, 1); + int var6 = this.getMetadataWithOffset(Block.stairsWoodOak.blockID, 0); + int var7 = this.getMetadataWithOffset(Block.stairsWoodOak.blockID, 2); + this.fillWithMetadataBlocks(par1World, par3StructureBoundingBox, 0, 4, 1, 6, 4, 1, + Block.stairsWoodSpruce.blockID, var4, Block.stairsWoodSpruce.blockID, var4, false); + this.fillWithMetadataBlocks(par1World, par3StructureBoundingBox, 0, 4, 2, 0, 4, 7, + Block.stairsWoodSpruce.blockID, var6, Block.stairsWoodSpruce.blockID, var6, false); + this.fillWithMetadataBlocks(par1World, par3StructureBoundingBox, 6, 4, 2, 6, 4, 7, + Block.stairsWoodSpruce.blockID, var5, Block.stairsWoodSpruce.blockID, var5, false); + this.fillWithMetadataBlocks(par1World, par3StructureBoundingBox, 0, 4, 8, 6, 4, 8, + Block.stairsWoodSpruce.blockID, var7, Block.stairsWoodSpruce.blockID, var7, false); + int var8; + int var9; + + for (var8 = 2; var8 <= 7; var8 += 5) { + for (var9 = 1; var9 <= 5; var9 += 4) { + this.fillCurrentPositionBlocksDownwards(par1World, Block.wood.blockID, 0, var9, -1, var8, + par3StructureBoundingBox); + } + } + + if (!this.hasWitch) { + var8 = this.getXWithOffset(2, 5); + var9 = this.getYWithOffset(2); + int var10 = this.getZWithOffset(2, 5); + + if (par3StructureBoundingBox.isVecInside(var8, var9, var10)) { + this.hasWitch = true; + EntityWitch var11 = new EntityWitch(par1World); + var11.setLocationAndAngles((double) var8 + 0.5D, (double) var9, (double) var10 + 0.5D, 0.0F, 0.0F); + var11.initCreature(); + par1World.spawnEntityInWorld(var11); + } + } + + return true; + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ComponentStronghold.java b/sp-server/src/main/java/net/minecraft/src/ComponentStronghold.java new file mode 100644 index 0000000..7a2c21f --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ComponentStronghold.java @@ -0,0 +1,210 @@ +package net.minecraft.src; + +import java.util.List; +import java.util.Random; + +abstract class ComponentStronghold extends StructureComponent { + protected ComponentStronghold(int par1) { + super(par1); + } + + /** + * builds a door of the enumerated types (empty opening is a door) + */ + protected void placeDoor(World par1World, Random par2Random, StructureBoundingBox par3StructureBoundingBox, + EnumDoor par4EnumDoor, int par5, int par6, int par7) { + switch (EnumDoorHelper.doorEnum[par4EnumDoor.ordinal()]) { + case 1: + default: + this.fillWithBlocks(par1World, par3StructureBoundingBox, par5, par6, par7, par5 + 3 - 1, par6 + 3 - 1, par7, + 0, 0, false); + break; + + case 2: + this.placeBlockAtCurrentPosition(par1World, Block.stoneBrick.blockID, 0, par5, par6, par7, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stoneBrick.blockID, 0, par5, par6 + 1, par7, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stoneBrick.blockID, 0, par5, par6 + 2, par7, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stoneBrick.blockID, 0, par5 + 1, par6 + 2, par7, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stoneBrick.blockID, 0, par5 + 2, par6 + 2, par7, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stoneBrick.blockID, 0, par5 + 2, par6 + 1, par7, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stoneBrick.blockID, 0, par5 + 2, par6, par7, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.doorWood.blockID, 0, par5 + 1, par6, par7, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.doorWood.blockID, 8, par5 + 1, par6 + 1, par7, + par3StructureBoundingBox); + break; + + case 3: + this.placeBlockAtCurrentPosition(par1World, 0, 0, par5 + 1, par6, par7, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, 0, 0, par5 + 1, par6 + 1, par7, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.fenceIron.blockID, 0, par5, par6, par7, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.fenceIron.blockID, 0, par5, par6 + 1, par7, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.fenceIron.blockID, 0, par5, par6 + 2, par7, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.fenceIron.blockID, 0, par5 + 1, par6 + 2, par7, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.fenceIron.blockID, 0, par5 + 2, par6 + 2, par7, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.fenceIron.blockID, 0, par5 + 2, par6 + 1, par7, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.fenceIron.blockID, 0, par5 + 2, par6, par7, + par3StructureBoundingBox); + break; + + case 4: + this.placeBlockAtCurrentPosition(par1World, Block.stoneBrick.blockID, 0, par5, par6, par7, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stoneBrick.blockID, 0, par5, par6 + 1, par7, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stoneBrick.blockID, 0, par5, par6 + 2, par7, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stoneBrick.blockID, 0, par5 + 1, par6 + 2, par7, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stoneBrick.blockID, 0, par5 + 2, par6 + 2, par7, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stoneBrick.blockID, 0, par5 + 2, par6 + 1, par7, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stoneBrick.blockID, 0, par5 + 2, par6, par7, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.doorIron.blockID, 0, par5 + 1, par6, par7, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.doorIron.blockID, 8, par5 + 1, par6 + 1, par7, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stoneButton.blockID, + this.getMetadataWithOffset(Block.stoneButton.blockID, 4), par5 + 2, par6 + 1, par7 + 1, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stoneButton.blockID, + this.getMetadataWithOffset(Block.stoneButton.blockID, 3), par5 + 2, par6 + 1, par7 - 1, + par3StructureBoundingBox); + } + } + + protected EnumDoor getRandomDoor(Random par1Random) { + int var2 = par1Random.nextInt(5); + + switch (var2) { + case 0: + case 1: + default: + return EnumDoor.OPENING; + + case 2: + return EnumDoor.WOOD_DOOR; + + case 3: + return EnumDoor.GRATES; + + case 4: + return EnumDoor.IRON_DOOR; + } + } + + /** + * Gets the next component in any cardinal direction + */ + protected StructureComponent getNextComponentNormal(ComponentStrongholdStairs2 par1ComponentStrongholdStairs2, + List par2List, Random par3Random, int par4, int par5) { + switch (this.coordBaseMode) { + case 0: + return StructureStrongholdPieces.getNextValidComponentAccess(par1ComponentStrongholdStairs2, par2List, + par3Random, this.boundingBox.minX + par4, this.boundingBox.minY + par5, this.boundingBox.maxZ + 1, + this.coordBaseMode, this.getComponentType()); + + case 1: + return StructureStrongholdPieces.getNextValidComponentAccess(par1ComponentStrongholdStairs2, par2List, + par3Random, this.boundingBox.minX - 1, this.boundingBox.minY + par5, this.boundingBox.minZ + par4, + this.coordBaseMode, this.getComponentType()); + + case 2: + return StructureStrongholdPieces.getNextValidComponentAccess(par1ComponentStrongholdStairs2, par2List, + par3Random, this.boundingBox.minX + par4, this.boundingBox.minY + par5, this.boundingBox.minZ - 1, + this.coordBaseMode, this.getComponentType()); + + case 3: + return StructureStrongholdPieces.getNextValidComponentAccess(par1ComponentStrongholdStairs2, par2List, + par3Random, this.boundingBox.maxX + 1, this.boundingBox.minY + par5, this.boundingBox.minZ + par4, + this.coordBaseMode, this.getComponentType()); + + default: + return null; + } + } + + /** + * Gets the next component in the +/- X direction + */ + protected StructureComponent getNextComponentX(ComponentStrongholdStairs2 par1ComponentStrongholdStairs2, + List par2List, Random par3Random, int par4, int par5) { + switch (this.coordBaseMode) { + case 0: + return StructureStrongholdPieces.getNextValidComponentAccess(par1ComponentStrongholdStairs2, par2List, + par3Random, this.boundingBox.minX - 1, this.boundingBox.minY + par4, this.boundingBox.minZ + par5, + 1, this.getComponentType()); + + case 1: + return StructureStrongholdPieces.getNextValidComponentAccess(par1ComponentStrongholdStairs2, par2List, + par3Random, this.boundingBox.minX + par5, this.boundingBox.minY + par4, this.boundingBox.minZ - 1, + 2, this.getComponentType()); + + case 2: + return StructureStrongholdPieces.getNextValidComponentAccess(par1ComponentStrongholdStairs2, par2List, + par3Random, this.boundingBox.minX - 1, this.boundingBox.minY + par4, this.boundingBox.minZ + par5, + 1, this.getComponentType()); + + case 3: + return StructureStrongholdPieces.getNextValidComponentAccess(par1ComponentStrongholdStairs2, par2List, + par3Random, this.boundingBox.minX + par5, this.boundingBox.minY + par4, this.boundingBox.minZ - 1, + 2, this.getComponentType()); + + default: + return null; + } + } + + /** + * Gets the next component in the +/- Z direction + */ + protected StructureComponent getNextComponentZ(ComponentStrongholdStairs2 par1ComponentStrongholdStairs2, + List par2List, Random par3Random, int par4, int par5) { + switch (this.coordBaseMode) { + case 0: + return StructureStrongholdPieces.getNextValidComponentAccess(par1ComponentStrongholdStairs2, par2List, + par3Random, this.boundingBox.maxX + 1, this.boundingBox.minY + par4, this.boundingBox.minZ + par5, + 3, this.getComponentType()); + + case 1: + return StructureStrongholdPieces.getNextValidComponentAccess(par1ComponentStrongholdStairs2, par2List, + par3Random, this.boundingBox.minX + par5, this.boundingBox.minY + par4, this.boundingBox.maxZ + 1, + 0, this.getComponentType()); + + case 2: + return StructureStrongholdPieces.getNextValidComponentAccess(par1ComponentStrongholdStairs2, par2List, + par3Random, this.boundingBox.maxX + 1, this.boundingBox.minY + par4, this.boundingBox.minZ + par5, + 3, this.getComponentType()); + + case 3: + return StructureStrongholdPieces.getNextValidComponentAccess(par1ComponentStrongholdStairs2, par2List, + par3Random, this.boundingBox.minX + par5, this.boundingBox.minY + par4, this.boundingBox.maxZ + 1, + 0, this.getComponentType()); + + default: + return null; + } + } + + /** + * returns false if the Structure Bounding Box goes below 10 + */ + protected static boolean canStrongholdGoDeeper(StructureBoundingBox par0StructureBoundingBox) { + return par0StructureBoundingBox != null && par0StructureBoundingBox.minY > 10; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ComponentStrongholdChestCorridor.java b/sp-server/src/main/java/net/minecraft/src/ComponentStrongholdChestCorridor.java new file mode 100644 index 0000000..5596927 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ComponentStrongholdChestCorridor.java @@ -0,0 +1,98 @@ +package net.minecraft.src; + +import java.util.List; +import java.util.Random; + +public class ComponentStrongholdChestCorridor extends ComponentStronghold { + /** List of items that Stronghold chests can contain. */ + private static final WeightedRandomChestContent[] strongholdChestContents = new WeightedRandomChestContent[] { + new WeightedRandomChestContent(Item.enderPearl.itemID, 0, 1, 1, 10), + new WeightedRandomChestContent(Item.diamond.itemID, 0, 1, 3, 3), + new WeightedRandomChestContent(Item.ingotIron.itemID, 0, 1, 5, 10), + new WeightedRandomChestContent(Item.ingotGold.itemID, 0, 1, 3, 5), + new WeightedRandomChestContent(Item.redstone.itemID, 0, 4, 9, 5), + new WeightedRandomChestContent(Item.bread.itemID, 0, 1, 3, 15), + new WeightedRandomChestContent(Item.appleRed.itemID, 0, 1, 3, 15), + new WeightedRandomChestContent(Item.pickaxeIron.itemID, 0, 1, 1, 5), + new WeightedRandomChestContent(Item.swordIron.itemID, 0, 1, 1, 5), + new WeightedRandomChestContent(Item.plateIron.itemID, 0, 1, 1, 5), + new WeightedRandomChestContent(Item.helmetIron.itemID, 0, 1, 1, 5), + new WeightedRandomChestContent(Item.legsIron.itemID, 0, 1, 1, 5), + new WeightedRandomChestContent(Item.bootsIron.itemID, 0, 1, 1, 5), + new WeightedRandomChestContent(Item.appleGold.itemID, 0, 1, 1, 1) }; + private final EnumDoor doorType; + private boolean hasMadeChest; + + public ComponentStrongholdChestCorridor(int par1, Random par2Random, StructureBoundingBox par3StructureBoundingBox, + int par4) { + super(par1); + this.coordBaseMode = par4; + this.doorType = this.getRandomDoor(par2Random); + this.boundingBox = par3StructureBoundingBox; + } + + /** + * Initiates construction of the Structure Component picked, at the current + * Location of StructGen + */ + public void buildComponent(StructureComponent par1StructureComponent, List par2List, Random par3Random) { + this.getNextComponentNormal((ComponentStrongholdStairs2) par1StructureComponent, par2List, par3Random, 1, 1); + } + + public static ComponentStrongholdChestCorridor findValidPlacement(List par0List, Random par1Random, int par2, + int par3, int par4, int par5, int par6) { + StructureBoundingBox var7 = StructureBoundingBox.getComponentToAddBoundingBox(par2, par3, par4, -1, -1, 0, 5, 5, + 7, par5); + return canStrongholdGoDeeper(var7) && StructureComponent.findIntersecting(par0List, var7) == null + ? new ComponentStrongholdChestCorridor(par6, par1Random, var7, par5) + : null; + } + + /** + * second Part of Structure generating, this for example places Spiderwebs, Mob + * Spawners, it closes Mineshafts at the end, it adds Fences... + */ + public boolean addComponentParts(World par1World, Random par2Random, + StructureBoundingBox par3StructureBoundingBox) { + if (this.isLiquidInStructureBoundingBox(par1World, par3StructureBoundingBox)) { + return false; + } else { + this.fillWithRandomizedBlocks(par1World, par3StructureBoundingBox, 0, 0, 0, 4, 4, 6, true, par2Random, + StructureStrongholdPieces.getStrongholdStones()); + this.placeDoor(par1World, par2Random, par3StructureBoundingBox, this.doorType, 1, 1, 0); + this.placeDoor(par1World, par2Random, par3StructureBoundingBox, EnumDoor.OPENING, 1, 1, 6); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 3, 1, 2, 3, 1, 4, Block.stoneBrick.blockID, + Block.stoneBrick.blockID, false); + this.placeBlockAtCurrentPosition(par1World, Block.stoneSingleSlab.blockID, 5, 3, 1, 1, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stoneSingleSlab.blockID, 5, 3, 1, 5, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stoneSingleSlab.blockID, 5, 3, 2, 2, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stoneSingleSlab.blockID, 5, 3, 2, 4, + par3StructureBoundingBox); + int var4; + + for (var4 = 2; var4 <= 4; ++var4) { + this.placeBlockAtCurrentPosition(par1World, Block.stoneSingleSlab.blockID, 5, 2, 1, var4, + par3StructureBoundingBox); + } + + if (!this.hasMadeChest) { + var4 = this.getYWithOffset(2); + int var5 = this.getXWithOffset(3, 3); + int var6 = this.getZWithOffset(3, 3); + + if (par3StructureBoundingBox.isVecInside(var5, var4, var6)) { + this.hasMadeChest = true; + this.generateStructureChestContents(par1World, par3StructureBoundingBox, par2Random, 3, 2, 3, + WeightedRandomChestContent.func_92080_a(strongholdChestContents, + new WeightedRandomChestContent[] { Item.enchantedBook.func_92114_b(par2Random) }), + 2 + par2Random.nextInt(2)); + } + } + + return true; + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ComponentStrongholdCorridor.java b/sp-server/src/main/java/net/minecraft/src/ComponentStrongholdCorridor.java new file mode 100644 index 0000000..32339e6 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ComponentStrongholdCorridor.java @@ -0,0 +1,89 @@ +package net.minecraft.src; + +import java.util.List; +import java.util.Random; + +public class ComponentStrongholdCorridor extends ComponentStronghold { + private final int field_74993_a; + + public ComponentStrongholdCorridor(int par1, Random par2Random, StructureBoundingBox par3StructureBoundingBox, + int par4) { + super(par1); + this.coordBaseMode = par4; + this.boundingBox = par3StructureBoundingBox; + this.field_74993_a = par4 != 2 && par4 != 0 ? par3StructureBoundingBox.getXSize() + : par3StructureBoundingBox.getZSize(); + } + + public static StructureBoundingBox func_74992_a(List par0List, Random par1Random, int par2, int par3, int par4, + int par5) { + StructureBoundingBox var7 = StructureBoundingBox.getComponentToAddBoundingBox(par2, par3, par4, -1, -1, 0, 5, 5, + 4, par5); + StructureComponent var8 = StructureComponent.findIntersecting(par0List, var7); + + if (var8 == null) { + return null; + } else { + if (var8.getBoundingBox().minY == var7.minY) { + for (int var9 = 3; var9 >= 1; --var9) { + var7 = StructureBoundingBox.getComponentToAddBoundingBox(par2, par3, par4, -1, -1, 0, 5, 5, + var9 - 1, par5); + + if (!var8.getBoundingBox().intersectsWith(var7)) { + return StructureBoundingBox.getComponentToAddBoundingBox(par2, par3, par4, -1, -1, 0, 5, 5, + var9, par5); + } + } + } + + return null; + } + } + + /** + * second Part of Structure generating, this for example places Spiderwebs, Mob + * Spawners, it closes Mineshafts at the end, it adds Fences... + */ + public boolean addComponentParts(World par1World, Random par2Random, + StructureBoundingBox par3StructureBoundingBox) { + if (this.isLiquidInStructureBoundingBox(par1World, par3StructureBoundingBox)) { + return false; + } else { + for (int var4 = 0; var4 < this.field_74993_a; ++var4) { + this.placeBlockAtCurrentPosition(par1World, Block.stoneBrick.blockID, 0, 0, 0, var4, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stoneBrick.blockID, 0, 1, 0, var4, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stoneBrick.blockID, 0, 2, 0, var4, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stoneBrick.blockID, 0, 3, 0, var4, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stoneBrick.blockID, 0, 4, 0, var4, + par3StructureBoundingBox); + + for (int var5 = 1; var5 <= 3; ++var5) { + this.placeBlockAtCurrentPosition(par1World, Block.stoneBrick.blockID, 0, 0, var5, var4, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, 0, 0, 1, var5, var4, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, 0, 0, 2, var5, var4, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, 0, 0, 3, var5, var4, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stoneBrick.blockID, 0, 4, var5, var4, + par3StructureBoundingBox); + } + + this.placeBlockAtCurrentPosition(par1World, Block.stoneBrick.blockID, 0, 0, 4, var4, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stoneBrick.blockID, 0, 1, 4, var4, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stoneBrick.blockID, 0, 2, 4, var4, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stoneBrick.blockID, 0, 3, 4, var4, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stoneBrick.blockID, 0, 4, 4, var4, + par3StructureBoundingBox); + } + + return true; + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ComponentStrongholdCrossing.java b/sp-server/src/main/java/net/minecraft/src/ComponentStrongholdCrossing.java new file mode 100644 index 0000000..4d87446 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ComponentStrongholdCrossing.java @@ -0,0 +1,126 @@ +package net.minecraft.src; + +import java.util.List; +import java.util.Random; + +public class ComponentStrongholdCrossing extends ComponentStronghold { + protected final EnumDoor doorType; + private boolean field_74996_b; + private boolean field_74997_c; + private boolean field_74995_d; + private boolean field_74999_h; + + public ComponentStrongholdCrossing(int par1, Random par2Random, StructureBoundingBox par3StructureBoundingBox, + int par4) { + super(par1); + this.coordBaseMode = par4; + this.doorType = this.getRandomDoor(par2Random); + this.boundingBox = par3StructureBoundingBox; + this.field_74996_b = par2Random.nextBoolean(); + this.field_74997_c = par2Random.nextBoolean(); + this.field_74995_d = par2Random.nextBoolean(); + this.field_74999_h = par2Random.nextInt(3) > 0; + } + + /** + * Initiates construction of the Structure Component picked, at the current + * Location of StructGen + */ + public void buildComponent(StructureComponent par1StructureComponent, List par2List, Random par3Random) { + int var4 = 3; + int var5 = 5; + + if (this.coordBaseMode == 1 || this.coordBaseMode == 2) { + var4 = 8 - var4; + var5 = 8 - var5; + } + + this.getNextComponentNormal((ComponentStrongholdStairs2) par1StructureComponent, par2List, par3Random, 5, 1); + + if (this.field_74996_b) { + this.getNextComponentX((ComponentStrongholdStairs2) par1StructureComponent, par2List, par3Random, var4, 1); + } + + if (this.field_74997_c) { + this.getNextComponentX((ComponentStrongholdStairs2) par1StructureComponent, par2List, par3Random, var5, 7); + } + + if (this.field_74995_d) { + this.getNextComponentZ((ComponentStrongholdStairs2) par1StructureComponent, par2List, par3Random, var4, 1); + } + + if (this.field_74999_h) { + this.getNextComponentZ((ComponentStrongholdStairs2) par1StructureComponent, par2List, par3Random, var5, 7); + } + } + + public static ComponentStrongholdCrossing findValidPlacement(List par0List, Random par1Random, int par2, int par3, + int par4, int par5, int par6) { + StructureBoundingBox var7 = StructureBoundingBox.getComponentToAddBoundingBox(par2, par3, par4, -4, -3, 0, 10, + 9, 11, par5); + return canStrongholdGoDeeper(var7) && StructureComponent.findIntersecting(par0List, var7) == null + ? new ComponentStrongholdCrossing(par6, par1Random, var7, par5) + : null; + } + + /** + * second Part of Structure generating, this for example places Spiderwebs, Mob + * Spawners, it closes Mineshafts at the end, it adds Fences... + */ + public boolean addComponentParts(World par1World, Random par2Random, + StructureBoundingBox par3StructureBoundingBox) { + if (this.isLiquidInStructureBoundingBox(par1World, par3StructureBoundingBox)) { + return false; + } else { + this.fillWithRandomizedBlocks(par1World, par3StructureBoundingBox, 0, 0, 0, 9, 8, 10, true, par2Random, + StructureStrongholdPieces.getStrongholdStones()); + this.placeDoor(par1World, par2Random, par3StructureBoundingBox, this.doorType, 4, 3, 0); + + if (this.field_74996_b) { + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 3, 1, 0, 5, 3, 0, 0, false); + } + + if (this.field_74995_d) { + this.fillWithBlocks(par1World, par3StructureBoundingBox, 9, 3, 1, 9, 5, 3, 0, 0, false); + } + + if (this.field_74997_c) { + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 5, 7, 0, 7, 9, 0, 0, false); + } + + if (this.field_74999_h) { + this.fillWithBlocks(par1World, par3StructureBoundingBox, 9, 5, 7, 9, 7, 9, 0, 0, false); + } + + this.fillWithBlocks(par1World, par3StructureBoundingBox, 5, 1, 10, 7, 3, 10, 0, 0, false); + this.fillWithRandomizedBlocks(par1World, par3StructureBoundingBox, 1, 2, 1, 8, 2, 6, false, par2Random, + StructureStrongholdPieces.getStrongholdStones()); + this.fillWithRandomizedBlocks(par1World, par3StructureBoundingBox, 4, 1, 5, 4, 4, 9, false, par2Random, + StructureStrongholdPieces.getStrongholdStones()); + this.fillWithRandomizedBlocks(par1World, par3StructureBoundingBox, 8, 1, 5, 8, 4, 9, false, par2Random, + StructureStrongholdPieces.getStrongholdStones()); + this.fillWithRandomizedBlocks(par1World, par3StructureBoundingBox, 1, 4, 7, 3, 4, 9, false, par2Random, + StructureStrongholdPieces.getStrongholdStones()); + this.fillWithRandomizedBlocks(par1World, par3StructureBoundingBox, 1, 3, 5, 3, 3, 6, false, par2Random, + StructureStrongholdPieces.getStrongholdStones()); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 1, 3, 4, 3, 3, 4, Block.stoneSingleSlab.blockID, + Block.stoneSingleSlab.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 1, 4, 6, 3, 4, 6, Block.stoneSingleSlab.blockID, + Block.stoneSingleSlab.blockID, false); + this.fillWithRandomizedBlocks(par1World, par3StructureBoundingBox, 5, 1, 7, 7, 1, 8, false, par2Random, + StructureStrongholdPieces.getStrongholdStones()); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 5, 1, 9, 7, 1, 9, Block.stoneSingleSlab.blockID, + Block.stoneSingleSlab.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 5, 2, 7, 7, 2, 7, Block.stoneSingleSlab.blockID, + Block.stoneSingleSlab.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 4, 5, 7, 4, 5, 9, Block.stoneSingleSlab.blockID, + Block.stoneSingleSlab.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 8, 5, 7, 8, 5, 9, Block.stoneSingleSlab.blockID, + Block.stoneSingleSlab.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 5, 5, 7, 7, 5, 9, Block.stoneDoubleSlab.blockID, + Block.stoneDoubleSlab.blockID, false); + this.placeBlockAtCurrentPosition(par1World, Block.torchWood.blockID, 0, 6, 5, 6, par3StructureBoundingBox); + return true; + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ComponentStrongholdLeftTurn.java b/sp-server/src/main/java/net/minecraft/src/ComponentStrongholdLeftTurn.java new file mode 100644 index 0000000..8a7a01a --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ComponentStrongholdLeftTurn.java @@ -0,0 +1,60 @@ +package net.minecraft.src; + +import java.util.List; +import java.util.Random; + +public class ComponentStrongholdLeftTurn extends ComponentStronghold { + protected final EnumDoor doorType; + + public ComponentStrongholdLeftTurn(int par1, Random par2Random, StructureBoundingBox par3StructureBoundingBox, + int par4) { + super(par1); + this.coordBaseMode = par4; + this.doorType = this.getRandomDoor(par2Random); + this.boundingBox = par3StructureBoundingBox; + } + + /** + * Initiates construction of the Structure Component picked, at the current + * Location of StructGen + */ + public void buildComponent(StructureComponent par1StructureComponent, List par2List, Random par3Random) { + if (this.coordBaseMode != 2 && this.coordBaseMode != 3) { + this.getNextComponentZ((ComponentStrongholdStairs2) par1StructureComponent, par2List, par3Random, 1, 1); + } else { + this.getNextComponentX((ComponentStrongholdStairs2) par1StructureComponent, par2List, par3Random, 1, 1); + } + } + + public static ComponentStrongholdLeftTurn findValidPlacement(List par0List, Random par1Random, int par2, int par3, + int par4, int par5, int par6) { + StructureBoundingBox var7 = StructureBoundingBox.getComponentToAddBoundingBox(par2, par3, par4, -1, -1, 0, 5, 5, + 5, par5); + return canStrongholdGoDeeper(var7) && StructureComponent.findIntersecting(par0List, var7) == null + ? new ComponentStrongholdLeftTurn(par6, par1Random, var7, par5) + : null; + } + + /** + * second Part of Structure generating, this for example places Spiderwebs, Mob + * Spawners, it closes Mineshafts at the end, it adds Fences... + */ + public boolean addComponentParts(World par1World, Random par2Random, + StructureBoundingBox par3StructureBoundingBox) { + if (this.isLiquidInStructureBoundingBox(par1World, par3StructureBoundingBox)) { + return false; + } else { + this.fillWithRandomizedBlocks(par1World, par3StructureBoundingBox, 0, 0, 0, 4, 4, 4, true, par2Random, + StructureStrongholdPieces.getStrongholdStones()); + this.placeDoor(par1World, par2Random, par3StructureBoundingBox, this.doorType, 1, 1, 0); + + if (this.coordBaseMode != 2 && this.coordBaseMode != 3) { + this.fillWithBlocks(par1World, par3StructureBoundingBox, 4, 1, 1, 4, 3, 3, 0, 0, false); + } else { + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 1, 1, 0, 3, 3, 0, 0, false); + } + + return true; + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ComponentStrongholdLibrary.java b/sp-server/src/main/java/net/minecraft/src/ComponentStrongholdLibrary.java new file mode 100644 index 0000000..6f467bd --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ComponentStrongholdLibrary.java @@ -0,0 +1,202 @@ +package net.minecraft.src; + +import java.util.List; +import java.util.Random; + +public class ComponentStrongholdLibrary extends ComponentStronghold { + /** List of items that Stronghold Library chests can contain. */ + private static final WeightedRandomChestContent[] strongholdLibraryChestContents = new WeightedRandomChestContent[] { + new WeightedRandomChestContent(Item.book.itemID, 0, 1, 3, 20), + new WeightedRandomChestContent(Item.paper.itemID, 0, 2, 7, 20), + new WeightedRandomChestContent(Item.emptyMap.itemID, 0, 1, 1, 1), + new WeightedRandomChestContent(Item.compass.itemID, 0, 1, 1, 1) }; + protected final EnumDoor doorType; + private final boolean isLargeRoom; + + public ComponentStrongholdLibrary(int par1, Random par2Random, StructureBoundingBox par3StructureBoundingBox, + int par4) { + super(par1); + this.coordBaseMode = par4; + this.doorType = this.getRandomDoor(par2Random); + this.boundingBox = par3StructureBoundingBox; + this.isLargeRoom = par3StructureBoundingBox.getYSize() > 6; + } + + public static ComponentStrongholdLibrary findValidPlacement(List par0List, Random par1Random, int par2, int par3, + int par4, int par5, int par6) { + StructureBoundingBox var7 = StructureBoundingBox.getComponentToAddBoundingBox(par2, par3, par4, -4, -1, 0, 14, + 11, 15, par5); + + if (!canStrongholdGoDeeper(var7) || StructureComponent.findIntersecting(par0List, var7) != null) { + var7 = StructureBoundingBox.getComponentToAddBoundingBox(par2, par3, par4, -4, -1, 0, 14, 6, 15, par5); + + if (!canStrongholdGoDeeper(var7) || StructureComponent.findIntersecting(par0List, var7) != null) { + return null; + } + } + + return new ComponentStrongholdLibrary(par6, par1Random, var7, par5); + } + + /** + * second Part of Structure generating, this for example places Spiderwebs, Mob + * Spawners, it closes Mineshafts at the end, it adds Fences... + */ + public boolean addComponentParts(World par1World, Random par2Random, + StructureBoundingBox par3StructureBoundingBox) { + if (this.isLiquidInStructureBoundingBox(par1World, par3StructureBoundingBox)) { + return false; + } else { + byte var4 = 11; + + if (!this.isLargeRoom) { + var4 = 6; + } + + this.fillWithRandomizedBlocks(par1World, par3StructureBoundingBox, 0, 0, 0, 13, var4 - 1, 14, true, + par2Random, StructureStrongholdPieces.getStrongholdStones()); + this.placeDoor(par1World, par2Random, par3StructureBoundingBox, this.doorType, 4, 1, 0); + this.randomlyFillWithBlocks(par1World, par3StructureBoundingBox, par2Random, 0.07F, 2, 1, 1, 11, 4, 13, + Block.web.blockID, Block.web.blockID, false); + int var7; + + for (var7 = 1; var7 <= 13; ++var7) { + if ((var7 - 1) % 4 == 0) { + this.fillWithBlocks(par1World, par3StructureBoundingBox, 1, 1, var7, 1, 4, var7, + Block.planks.blockID, Block.planks.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 12, 1, var7, 12, 4, var7, + Block.planks.blockID, Block.planks.blockID, false); + this.placeBlockAtCurrentPosition(par1World, Block.torchWood.blockID, 0, 2, 3, var7, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.torchWood.blockID, 0, 11, 3, var7, + par3StructureBoundingBox); + + if (this.isLargeRoom) { + this.fillWithBlocks(par1World, par3StructureBoundingBox, 1, 6, var7, 1, 9, var7, + Block.planks.blockID, Block.planks.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 12, 6, var7, 12, 9, var7, + Block.planks.blockID, Block.planks.blockID, false); + } + } else { + this.fillWithBlocks(par1World, par3StructureBoundingBox, 1, 1, var7, 1, 4, var7, + Block.bookShelf.blockID, Block.bookShelf.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 12, 1, var7, 12, 4, var7, + Block.bookShelf.blockID, Block.bookShelf.blockID, false); + + if (this.isLargeRoom) { + this.fillWithBlocks(par1World, par3StructureBoundingBox, 1, 6, var7, 1, 9, var7, + Block.bookShelf.blockID, Block.bookShelf.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 12, 6, var7, 12, 9, var7, + Block.bookShelf.blockID, Block.bookShelf.blockID, false); + } + } + } + + for (var7 = 3; var7 < 12; var7 += 2) { + this.fillWithBlocks(par1World, par3StructureBoundingBox, 3, 1, var7, 4, 3, var7, + Block.bookShelf.blockID, Block.bookShelf.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 6, 1, var7, 7, 3, var7, + Block.bookShelf.blockID, Block.bookShelf.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 9, 1, var7, 10, 3, var7, + Block.bookShelf.blockID, Block.bookShelf.blockID, false); + } + + if (this.isLargeRoom) { + this.fillWithBlocks(par1World, par3StructureBoundingBox, 1, 5, 1, 3, 5, 13, Block.planks.blockID, + Block.planks.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 10, 5, 1, 12, 5, 13, Block.planks.blockID, + Block.planks.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 4, 5, 1, 9, 5, 2, Block.planks.blockID, + Block.planks.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 4, 5, 12, 9, 5, 13, Block.planks.blockID, + Block.planks.blockID, false); + this.placeBlockAtCurrentPosition(par1World, Block.planks.blockID, 0, 9, 5, 11, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.planks.blockID, 0, 8, 5, 11, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.planks.blockID, 0, 9, 5, 10, + par3StructureBoundingBox); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 3, 6, 2, 3, 6, 12, Block.fence.blockID, + Block.fence.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 10, 6, 2, 10, 6, 10, Block.fence.blockID, + Block.fence.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 4, 6, 2, 9, 6, 2, Block.fence.blockID, + Block.fence.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 4, 6, 12, 8, 6, 12, Block.fence.blockID, + Block.fence.blockID, false); + this.placeBlockAtCurrentPosition(par1World, Block.fence.blockID, 0, 9, 6, 11, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.fence.blockID, 0, 8, 6, 11, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.fence.blockID, 0, 9, 6, 10, par3StructureBoundingBox); + var7 = this.getMetadataWithOffset(Block.ladder.blockID, 3); + this.placeBlockAtCurrentPosition(par1World, Block.ladder.blockID, var7, 10, 1, 13, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.ladder.blockID, var7, 10, 2, 13, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.ladder.blockID, var7, 10, 3, 13, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.ladder.blockID, var7, 10, 4, 13, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.ladder.blockID, var7, 10, 5, 13, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.ladder.blockID, var7, 10, 6, 13, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.ladder.blockID, var7, 10, 7, 13, + par3StructureBoundingBox); + byte var8 = 7; + byte var9 = 7; + this.placeBlockAtCurrentPosition(par1World, Block.fence.blockID, 0, var8 - 1, 9, var9, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.fence.blockID, 0, var8, 9, var9, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.fence.blockID, 0, var8 - 1, 8, var9, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.fence.blockID, 0, var8, 8, var9, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.fence.blockID, 0, var8 - 1, 7, var9, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.fence.blockID, 0, var8, 7, var9, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.fence.blockID, 0, var8 - 2, 7, var9, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.fence.blockID, 0, var8 + 1, 7, var9, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.fence.blockID, 0, var8 - 1, 7, var9 - 1, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.fence.blockID, 0, var8 - 1, 7, var9 + 1, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.fence.blockID, 0, var8, 7, var9 - 1, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.fence.blockID, 0, var8, 7, var9 + 1, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.torchWood.blockID, 0, var8 - 2, 8, var9, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.torchWood.blockID, 0, var8 + 1, 8, var9, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.torchWood.blockID, 0, var8 - 1, 8, var9 - 1, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.torchWood.blockID, 0, var8 - 1, 8, var9 + 1, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.torchWood.blockID, 0, var8, 8, var9 - 1, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.torchWood.blockID, 0, var8, 8, var9 + 1, + par3StructureBoundingBox); + } + + this.generateStructureChestContents(par1World, par3StructureBoundingBox, par2Random, 3, 3, 5, + WeightedRandomChestContent.func_92080_a(strongholdLibraryChestContents, + new WeightedRandomChestContent[] { Item.enchantedBook.func_92112_a(par2Random, 1, 5, 2) }), + 1 + par2Random.nextInt(4)); + + if (this.isLargeRoom) { + this.placeBlockAtCurrentPosition(par1World, 0, 0, 12, 9, 1, par3StructureBoundingBox); + this.generateStructureChestContents(par1World, par3StructureBoundingBox, par2Random, 12, 8, 1, + WeightedRandomChestContent.func_92080_a(strongholdLibraryChestContents, + new WeightedRandomChestContent[] { + Item.enchantedBook.func_92112_a(par2Random, 1, 5, 2) }), + 1 + par2Random.nextInt(4)); + } + + return true; + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ComponentStrongholdPortalRoom.java b/sp-server/src/main/java/net/minecraft/src/ComponentStrongholdPortalRoom.java new file mode 100644 index 0000000..3542658 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ComponentStrongholdPortalRoom.java @@ -0,0 +1,167 @@ +package net.minecraft.src; + +import java.util.List; +import java.util.Random; + +public class ComponentStrongholdPortalRoom extends ComponentStronghold { + private boolean hasSpawner; + + public ComponentStrongholdPortalRoom(int par1, Random par2Random, StructureBoundingBox par3StructureBoundingBox, + int par4) { + super(par1); + this.coordBaseMode = par4; + this.boundingBox = par3StructureBoundingBox; + } + + /** + * Initiates construction of the Structure Component picked, at the current + * Location of StructGen + */ + public void buildComponent(StructureComponent par1StructureComponent, List par2List, Random par3Random) { + if (par1StructureComponent != null) { + ((ComponentStrongholdStairs2) par1StructureComponent).strongholdPortalRoom = this; + } + } + + public static ComponentStrongholdPortalRoom findValidPlacement(List par0List, Random par1Random, int par2, int par3, + int par4, int par5, int par6) { + StructureBoundingBox var7 = StructureBoundingBox.getComponentToAddBoundingBox(par2, par3, par4, -4, -1, 0, 11, + 8, 16, par5); + return canStrongholdGoDeeper(var7) && StructureComponent.findIntersecting(par0List, var7) == null + ? new ComponentStrongholdPortalRoom(par6, par1Random, var7, par5) + : null; + } + + /** + * second Part of Structure generating, this for example places Spiderwebs, Mob + * Spawners, it closes Mineshafts at the end, it adds Fences... + */ + public boolean addComponentParts(World par1World, Random par2Random, + StructureBoundingBox par3StructureBoundingBox) { + this.fillWithRandomizedBlocks(par1World, par3StructureBoundingBox, 0, 0, 0, 10, 7, 15, false, par2Random, + StructureStrongholdPieces.getStrongholdStones()); + this.placeDoor(par1World, par2Random, par3StructureBoundingBox, EnumDoor.GRATES, 4, 1, 0); + byte var4 = 6; + this.fillWithRandomizedBlocks(par1World, par3StructureBoundingBox, 1, var4, 1, 1, var4, 14, false, par2Random, + StructureStrongholdPieces.getStrongholdStones()); + this.fillWithRandomizedBlocks(par1World, par3StructureBoundingBox, 9, var4, 1, 9, var4, 14, false, par2Random, + StructureStrongholdPieces.getStrongholdStones()); + this.fillWithRandomizedBlocks(par1World, par3StructureBoundingBox, 2, var4, 1, 8, var4, 2, false, par2Random, + StructureStrongholdPieces.getStrongholdStones()); + this.fillWithRandomizedBlocks(par1World, par3StructureBoundingBox, 2, var4, 14, 8, var4, 14, false, par2Random, + StructureStrongholdPieces.getStrongholdStones()); + this.fillWithRandomizedBlocks(par1World, par3StructureBoundingBox, 1, 1, 1, 2, 1, 4, false, par2Random, + StructureStrongholdPieces.getStrongholdStones()); + this.fillWithRandomizedBlocks(par1World, par3StructureBoundingBox, 8, 1, 1, 9, 1, 4, false, par2Random, + StructureStrongholdPieces.getStrongholdStones()); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 1, 1, 1, 1, 1, 3, Block.lavaMoving.blockID, + Block.lavaMoving.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 9, 1, 1, 9, 1, 3, Block.lavaMoving.blockID, + Block.lavaMoving.blockID, false); + this.fillWithRandomizedBlocks(par1World, par3StructureBoundingBox, 3, 1, 8, 7, 1, 12, false, par2Random, + StructureStrongholdPieces.getStrongholdStones()); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 4, 1, 9, 6, 1, 11, Block.lavaMoving.blockID, + Block.lavaMoving.blockID, false); + int var5; + + for (var5 = 3; var5 < 14; var5 += 2) { + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 3, var5, 0, 4, var5, Block.fenceIron.blockID, + Block.fenceIron.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 10, 3, var5, 10, 4, var5, Block.fenceIron.blockID, + Block.fenceIron.blockID, false); + } + + for (var5 = 2; var5 < 9; var5 += 2) { + this.fillWithBlocks(par1World, par3StructureBoundingBox, var5, 3, 15, var5, 4, 15, Block.fenceIron.blockID, + Block.fenceIron.blockID, false); + } + + var5 = this.getMetadataWithOffset(Block.stairsStoneBrick.blockID, 3); + this.fillWithRandomizedBlocks(par1World, par3StructureBoundingBox, 4, 1, 5, 6, 1, 7, false, par2Random, + StructureStrongholdPieces.getStrongholdStones()); + this.fillWithRandomizedBlocks(par1World, par3StructureBoundingBox, 4, 2, 6, 6, 2, 7, false, par2Random, + StructureStrongholdPieces.getStrongholdStones()); + this.fillWithRandomizedBlocks(par1World, par3StructureBoundingBox, 4, 3, 7, 6, 3, 7, false, par2Random, + StructureStrongholdPieces.getStrongholdStones()); + + for (int var6 = 4; var6 <= 6; ++var6) { + this.placeBlockAtCurrentPosition(par1World, Block.stairsStoneBrick.blockID, var5, var6, 1, 4, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stairsStoneBrick.blockID, var5, var6, 2, 5, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stairsStoneBrick.blockID, var5, var6, 3, 6, + par3StructureBoundingBox); + } + + byte var14 = 2; + byte var7 = 0; + byte var8 = 3; + byte var9 = 1; + + switch (this.coordBaseMode) { + case 0: + var14 = 0; + var7 = 2; + break; + + case 1: + var14 = 1; + var7 = 3; + var8 = 0; + var9 = 2; + + case 2: + default: + break; + + case 3: + var14 = 3; + var7 = 1; + var8 = 0; + var9 = 2; + } + + this.placeBlockAtCurrentPosition(par1World, Block.endPortalFrame.blockID, + var14 + (par2Random.nextFloat() > 0.9F ? 4 : 0), 4, 3, 8, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.endPortalFrame.blockID, + var14 + (par2Random.nextFloat() > 0.9F ? 4 : 0), 5, 3, 8, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.endPortalFrame.blockID, + var14 + (par2Random.nextFloat() > 0.9F ? 4 : 0), 6, 3, 8, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.endPortalFrame.blockID, + var7 + (par2Random.nextFloat() > 0.9F ? 4 : 0), 4, 3, 12, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.endPortalFrame.blockID, + var7 + (par2Random.nextFloat() > 0.9F ? 4 : 0), 5, 3, 12, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.endPortalFrame.blockID, + var7 + (par2Random.nextFloat() > 0.9F ? 4 : 0), 6, 3, 12, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.endPortalFrame.blockID, + var8 + (par2Random.nextFloat() > 0.9F ? 4 : 0), 3, 3, 9, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.endPortalFrame.blockID, + var8 + (par2Random.nextFloat() > 0.9F ? 4 : 0), 3, 3, 10, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.endPortalFrame.blockID, + var8 + (par2Random.nextFloat() > 0.9F ? 4 : 0), 3, 3, 11, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.endPortalFrame.blockID, + var9 + (par2Random.nextFloat() > 0.9F ? 4 : 0), 7, 3, 9, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.endPortalFrame.blockID, + var9 + (par2Random.nextFloat() > 0.9F ? 4 : 0), 7, 3, 10, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.endPortalFrame.blockID, + var9 + (par2Random.nextFloat() > 0.9F ? 4 : 0), 7, 3, 11, par3StructureBoundingBox); + + if (!this.hasSpawner) { + int var13 = this.getYWithOffset(3); + int var10 = this.getXWithOffset(5, 6); + int var11 = this.getZWithOffset(5, 6); + + if (par3StructureBoundingBox.isVecInside(var10, var13, var11)) { + this.hasSpawner = true; + par1World.setBlock(var10, var13, var11, Block.mobSpawner.blockID, 0, 2); + TileEntityMobSpawner var12 = (TileEntityMobSpawner) par1World.getBlockTileEntity(var10, var13, var11); + + if (var12 != null) { + var12.func_98049_a().setMobID("Silverfish"); + } + } + } + + return true; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ComponentStrongholdPrison.java b/sp-server/src/main/java/net/minecraft/src/ComponentStrongholdPrison.java new file mode 100644 index 0000000..32284dc --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ComponentStrongholdPrison.java @@ -0,0 +1,72 @@ +package net.minecraft.src; + +import java.util.List; +import java.util.Random; + +public class ComponentStrongholdPrison extends ComponentStronghold { + protected final EnumDoor doorType; + + public ComponentStrongholdPrison(int par1, Random par2Random, StructureBoundingBox par3StructureBoundingBox, + int par4) { + super(par1); + this.coordBaseMode = par4; + this.doorType = this.getRandomDoor(par2Random); + this.boundingBox = par3StructureBoundingBox; + } + + /** + * Initiates construction of the Structure Component picked, at the current + * Location of StructGen + */ + public void buildComponent(StructureComponent par1StructureComponent, List par2List, Random par3Random) { + this.getNextComponentNormal((ComponentStrongholdStairs2) par1StructureComponent, par2List, par3Random, 1, 1); + } + + public static ComponentStrongholdPrison findValidPlacement(List par0List, Random par1Random, int par2, int par3, + int par4, int par5, int par6) { + StructureBoundingBox var7 = StructureBoundingBox.getComponentToAddBoundingBox(par2, par3, par4, -1, -1, 0, 9, 5, + 11, par5); + return canStrongholdGoDeeper(var7) && StructureComponent.findIntersecting(par0List, var7) == null + ? new ComponentStrongholdPrison(par6, par1Random, var7, par5) + : null; + } + + /** + * second Part of Structure generating, this for example places Spiderwebs, Mob + * Spawners, it closes Mineshafts at the end, it adds Fences... + */ + public boolean addComponentParts(World par1World, Random par2Random, + StructureBoundingBox par3StructureBoundingBox) { + if (this.isLiquidInStructureBoundingBox(par1World, par3StructureBoundingBox)) { + return false; + } else { + this.fillWithRandomizedBlocks(par1World, par3StructureBoundingBox, 0, 0, 0, 8, 4, 10, true, par2Random, + StructureStrongholdPieces.getStrongholdStones()); + this.placeDoor(par1World, par2Random, par3StructureBoundingBox, this.doorType, 1, 1, 0); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 1, 1, 10, 3, 3, 10, 0, 0, false); + this.fillWithRandomizedBlocks(par1World, par3StructureBoundingBox, 4, 1, 1, 4, 3, 1, false, par2Random, + StructureStrongholdPieces.getStrongholdStones()); + this.fillWithRandomizedBlocks(par1World, par3StructureBoundingBox, 4, 1, 3, 4, 3, 3, false, par2Random, + StructureStrongholdPieces.getStrongholdStones()); + this.fillWithRandomizedBlocks(par1World, par3StructureBoundingBox, 4, 1, 7, 4, 3, 7, false, par2Random, + StructureStrongholdPieces.getStrongholdStones()); + this.fillWithRandomizedBlocks(par1World, par3StructureBoundingBox, 4, 1, 9, 4, 3, 9, false, par2Random, + StructureStrongholdPieces.getStrongholdStones()); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 4, 1, 4, 4, 3, 6, Block.fenceIron.blockID, + Block.fenceIron.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 5, 1, 5, 7, 3, 5, Block.fenceIron.blockID, + Block.fenceIron.blockID, false); + this.placeBlockAtCurrentPosition(par1World, Block.fenceIron.blockID, 0, 4, 3, 2, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.fenceIron.blockID, 0, 4, 3, 8, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.doorIron.blockID, + this.getMetadataWithOffset(Block.doorIron.blockID, 3), 4, 1, 2, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.doorIron.blockID, + this.getMetadataWithOffset(Block.doorIron.blockID, 3) + 8, 4, 2, 2, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.doorIron.blockID, + this.getMetadataWithOffset(Block.doorIron.blockID, 3), 4, 1, 8, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.doorIron.blockID, + this.getMetadataWithOffset(Block.doorIron.blockID, 3) + 8, 4, 2, 8, par3StructureBoundingBox); + return true; + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ComponentStrongholdRightTurn.java b/sp-server/src/main/java/net/minecraft/src/ComponentStrongholdRightTurn.java new file mode 100644 index 0000000..959dcd8 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ComponentStrongholdRightTurn.java @@ -0,0 +1,46 @@ +package net.minecraft.src; + +import java.util.List; +import java.util.Random; + +public class ComponentStrongholdRightTurn extends ComponentStrongholdLeftTurn { + public ComponentStrongholdRightTurn(int par1, Random par2Random, StructureBoundingBox par3StructureBoundingBox, + int par4) { + super(par1, par2Random, par3StructureBoundingBox, par4); + } + + /** + * Initiates construction of the Structure Component picked, at the current + * Location of StructGen + */ + public void buildComponent(StructureComponent par1StructureComponent, List par2List, Random par3Random) { + if (this.coordBaseMode != 2 && this.coordBaseMode != 3) { + this.getNextComponentX((ComponentStrongholdStairs2) par1StructureComponent, par2List, par3Random, 1, 1); + } else { + this.getNextComponentZ((ComponentStrongholdStairs2) par1StructureComponent, par2List, par3Random, 1, 1); + } + } + + /** + * second Part of Structure generating, this for example places Spiderwebs, Mob + * Spawners, it closes Mineshafts at the end, it adds Fences... + */ + public boolean addComponentParts(World par1World, Random par2Random, + StructureBoundingBox par3StructureBoundingBox) { + if (this.isLiquidInStructureBoundingBox(par1World, par3StructureBoundingBox)) { + return false; + } else { + this.fillWithRandomizedBlocks(par1World, par3StructureBoundingBox, 0, 0, 0, 4, 4, 4, true, par2Random, + StructureStrongholdPieces.getStrongholdStones()); + this.placeDoor(par1World, par2Random, par3StructureBoundingBox, this.doorType, 1, 1, 0); + + if (this.coordBaseMode != 2 && this.coordBaseMode != 3) { + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 1, 1, 0, 3, 3, 0, 0, false); + } else { + this.fillWithBlocks(par1World, par3StructureBoundingBox, 4, 1, 1, 4, 3, 3, 0, 0, false); + } + + return true; + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ComponentStrongholdRoomCrossing.java b/sp-server/src/main/java/net/minecraft/src/ComponentStrongholdRoomCrossing.java new file mode 100644 index 0000000..72ce5ab --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ComponentStrongholdRoomCrossing.java @@ -0,0 +1,205 @@ +package net.minecraft.src; + +import java.util.List; +import java.util.Random; + +public class ComponentStrongholdRoomCrossing extends ComponentStronghold { + /** + * Items that could generate in the chest that is located in Stronghold Room + * Crossing. + */ + private static final WeightedRandomChestContent[] strongholdRoomCrossingChestContents = new WeightedRandomChestContent[] { + new WeightedRandomChestContent(Item.ingotIron.itemID, 0, 1, 5, 10), + new WeightedRandomChestContent(Item.ingotGold.itemID, 0, 1, 3, 5), + new WeightedRandomChestContent(Item.redstone.itemID, 0, 4, 9, 5), + new WeightedRandomChestContent(Item.coal.itemID, 0, 3, 8, 10), + new WeightedRandomChestContent(Item.bread.itemID, 0, 1, 3, 15), + new WeightedRandomChestContent(Item.appleRed.itemID, 0, 1, 3, 15), + new WeightedRandomChestContent(Item.pickaxeIron.itemID, 0, 1, 1, 1) }; + protected final EnumDoor doorType; + protected final int roomType; + + public ComponentStrongholdRoomCrossing(int par1, Random par2Random, StructureBoundingBox par3StructureBoundingBox, + int par4) { + super(par1); + this.coordBaseMode = par4; + this.doorType = this.getRandomDoor(par2Random); + this.boundingBox = par3StructureBoundingBox; + this.roomType = par2Random.nextInt(5); + } + + /** + * Initiates construction of the Structure Component picked, at the current + * Location of StructGen + */ + public void buildComponent(StructureComponent par1StructureComponent, List par2List, Random par3Random) { + this.getNextComponentNormal((ComponentStrongholdStairs2) par1StructureComponent, par2List, par3Random, 4, 1); + this.getNextComponentX((ComponentStrongholdStairs2) par1StructureComponent, par2List, par3Random, 1, 4); + this.getNextComponentZ((ComponentStrongholdStairs2) par1StructureComponent, par2List, par3Random, 1, 4); + } + + public static ComponentStrongholdRoomCrossing findValidPlacement(List par0List, Random par1Random, int par2, + int par3, int par4, int par5, int par6) { + StructureBoundingBox var7 = StructureBoundingBox.getComponentToAddBoundingBox(par2, par3, par4, -4, -1, 0, 11, + 7, 11, par5); + return canStrongholdGoDeeper(var7) && StructureComponent.findIntersecting(par0List, var7) == null + ? new ComponentStrongholdRoomCrossing(par6, par1Random, var7, par5) + : null; + } + + /** + * second Part of Structure generating, this for example places Spiderwebs, Mob + * Spawners, it closes Mineshafts at the end, it adds Fences... + */ + public boolean addComponentParts(World par1World, Random par2Random, + StructureBoundingBox par3StructureBoundingBox) { + if (this.isLiquidInStructureBoundingBox(par1World, par3StructureBoundingBox)) { + return false; + } else { + this.fillWithRandomizedBlocks(par1World, par3StructureBoundingBox, 0, 0, 0, 10, 6, 10, true, par2Random, + StructureStrongholdPieces.getStrongholdStones()); + this.placeDoor(par1World, par2Random, par3StructureBoundingBox, this.doorType, 4, 1, 0); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 4, 1, 10, 6, 3, 10, 0, 0, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 1, 4, 0, 3, 6, 0, 0, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 10, 1, 4, 10, 3, 6, 0, 0, false); + int var4; + + switch (this.roomType) { + case 0: + this.placeBlockAtCurrentPosition(par1World, Block.stoneBrick.blockID, 0, 5, 1, 5, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stoneBrick.blockID, 0, 5, 2, 5, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stoneBrick.blockID, 0, 5, 3, 5, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.torchWood.blockID, 0, 4, 3, 5, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.torchWood.blockID, 0, 6, 3, 5, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.torchWood.blockID, 0, 5, 3, 4, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.torchWood.blockID, 0, 5, 3, 6, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stoneSingleSlab.blockID, 0, 4, 1, 4, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stoneSingleSlab.blockID, 0, 4, 1, 5, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stoneSingleSlab.blockID, 0, 4, 1, 6, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stoneSingleSlab.blockID, 0, 6, 1, 4, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stoneSingleSlab.blockID, 0, 6, 1, 5, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stoneSingleSlab.blockID, 0, 6, 1, 6, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stoneSingleSlab.blockID, 0, 5, 1, 4, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stoneSingleSlab.blockID, 0, 5, 1, 6, + par3StructureBoundingBox); + break; + + case 1: + for (var4 = 0; var4 < 5; ++var4) { + this.placeBlockAtCurrentPosition(par1World, Block.stoneBrick.blockID, 0, 3, 1, 3 + var4, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stoneBrick.blockID, 0, 7, 1, 3 + var4, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stoneBrick.blockID, 0, 3 + var4, 1, 3, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stoneBrick.blockID, 0, 3 + var4, 1, 7, + par3StructureBoundingBox); + } + + this.placeBlockAtCurrentPosition(par1World, Block.stoneBrick.blockID, 0, 5, 1, 5, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stoneBrick.blockID, 0, 5, 2, 5, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stoneBrick.blockID, 0, 5, 3, 5, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.waterMoving.blockID, 0, 5, 4, 5, + par3StructureBoundingBox); + break; + + case 2: + for (var4 = 1; var4 <= 9; ++var4) { + this.placeBlockAtCurrentPosition(par1World, Block.cobblestone.blockID, 0, 1, 3, var4, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.cobblestone.blockID, 0, 9, 3, var4, + par3StructureBoundingBox); + } + + for (var4 = 1; var4 <= 9; ++var4) { + this.placeBlockAtCurrentPosition(par1World, Block.cobblestone.blockID, 0, var4, 3, 1, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.cobblestone.blockID, 0, var4, 3, 9, + par3StructureBoundingBox); + } + + this.placeBlockAtCurrentPosition(par1World, Block.cobblestone.blockID, 0, 5, 1, 4, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.cobblestone.blockID, 0, 5, 1, 6, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.cobblestone.blockID, 0, 5, 3, 4, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.cobblestone.blockID, 0, 5, 3, 6, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.cobblestone.blockID, 0, 4, 1, 5, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.cobblestone.blockID, 0, 6, 1, 5, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.cobblestone.blockID, 0, 4, 3, 5, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.cobblestone.blockID, 0, 6, 3, 5, + par3StructureBoundingBox); + + for (var4 = 1; var4 <= 3; ++var4) { + this.placeBlockAtCurrentPosition(par1World, Block.cobblestone.blockID, 0, 4, var4, 4, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.cobblestone.blockID, 0, 6, var4, 4, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.cobblestone.blockID, 0, 4, var4, 6, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.cobblestone.blockID, 0, 6, var4, 6, + par3StructureBoundingBox); + } + + this.placeBlockAtCurrentPosition(par1World, Block.torchWood.blockID, 0, 5, 3, 5, + par3StructureBoundingBox); + + for (var4 = 2; var4 <= 8; ++var4) { + this.placeBlockAtCurrentPosition(par1World, Block.planks.blockID, 0, 2, 3, var4, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.planks.blockID, 0, 3, 3, var4, + par3StructureBoundingBox); + + if (var4 <= 3 || var4 >= 7) { + this.placeBlockAtCurrentPosition(par1World, Block.planks.blockID, 0, 4, 3, var4, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.planks.blockID, 0, 5, 3, var4, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.planks.blockID, 0, 6, 3, var4, + par3StructureBoundingBox); + } + + this.placeBlockAtCurrentPosition(par1World, Block.planks.blockID, 0, 7, 3, var4, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.planks.blockID, 0, 8, 3, var4, + par3StructureBoundingBox); + } + + this.placeBlockAtCurrentPosition(par1World, Block.ladder.blockID, + this.getMetadataWithOffset(Block.ladder.blockID, 4), 9, 1, 3, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.ladder.blockID, + this.getMetadataWithOffset(Block.ladder.blockID, 4), 9, 2, 3, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.ladder.blockID, + this.getMetadataWithOffset(Block.ladder.blockID, 4), 9, 3, 3, par3StructureBoundingBox); + this.generateStructureChestContents(par1World, par3StructureBoundingBox, par2Random, 3, 4, 8, + WeightedRandomChestContent.func_92080_a(strongholdRoomCrossingChestContents, + new WeightedRandomChestContent[] { Item.enchantedBook.func_92114_b(par2Random) }), + 1 + par2Random.nextInt(4)); + } + + return true; + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ComponentStrongholdStairs.java b/sp-server/src/main/java/net/minecraft/src/ComponentStrongholdStairs.java new file mode 100644 index 0000000..d5e4b3d --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ComponentStrongholdStairs.java @@ -0,0 +1,99 @@ +package net.minecraft.src; + +import java.util.List; +import java.util.Random; + +public class ComponentStrongholdStairs extends ComponentStronghold { + private final boolean field_75024_a; + private final EnumDoor doorType; + + public ComponentStrongholdStairs(int par1, Random par2Random, int par3, int par4) { + super(par1); + this.field_75024_a = true; + this.coordBaseMode = par2Random.nextInt(4); + this.doorType = EnumDoor.OPENING; + + switch (this.coordBaseMode) { + case 0: + case 2: + this.boundingBox = new StructureBoundingBox(par3, 64, par4, par3 + 5 - 1, 74, par4 + 5 - 1); + break; + + default: + this.boundingBox = new StructureBoundingBox(par3, 64, par4, par3 + 5 - 1, 74, par4 + 5 - 1); + } + } + + public ComponentStrongholdStairs(int par1, Random par2Random, StructureBoundingBox par3StructureBoundingBox, + int par4) { + super(par1); + this.field_75024_a = false; + this.coordBaseMode = par4; + this.doorType = this.getRandomDoor(par2Random); + this.boundingBox = par3StructureBoundingBox; + } + + /** + * Initiates construction of the Structure Component picked, at the current + * Location of StructGen + */ + public void buildComponent(StructureComponent par1StructureComponent, List par2List, Random par3Random) { + if (this.field_75024_a) { + StructureStrongholdPieces.setComponentType(ComponentStrongholdCrossing.class); + } + + this.getNextComponentNormal((ComponentStrongholdStairs2) par1StructureComponent, par2List, par3Random, 1, 1); + } + + /** + * performs some checks, then gives out a fresh Stairs component + */ + public static ComponentStrongholdStairs getStrongholdStairsComponent(List par0List, Random par1Random, int par2, + int par3, int par4, int par5, int par6) { + StructureBoundingBox var7 = StructureBoundingBox.getComponentToAddBoundingBox(par2, par3, par4, -1, -7, 0, 5, + 11, 5, par5); + return canStrongholdGoDeeper(var7) && StructureComponent.findIntersecting(par0List, var7) == null + ? new ComponentStrongholdStairs(par6, par1Random, var7, par5) + : null; + } + + /** + * second Part of Structure generating, this for example places Spiderwebs, Mob + * Spawners, it closes Mineshafts at the end, it adds Fences... + */ + public boolean addComponentParts(World par1World, Random par2Random, + StructureBoundingBox par3StructureBoundingBox) { + if (this.isLiquidInStructureBoundingBox(par1World, par3StructureBoundingBox)) { + return false; + } else { + this.fillWithRandomizedBlocks(par1World, par3StructureBoundingBox, 0, 0, 0, 4, 10, 4, true, par2Random, + StructureStrongholdPieces.getStrongholdStones()); + this.placeDoor(par1World, par2Random, par3StructureBoundingBox, this.doorType, 1, 7, 0); + this.placeDoor(par1World, par2Random, par3StructureBoundingBox, EnumDoor.OPENING, 1, 1, 4); + this.placeBlockAtCurrentPosition(par1World, Block.stoneBrick.blockID, 0, 2, 6, 1, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stoneBrick.blockID, 0, 1, 5, 1, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stoneSingleSlab.blockID, 0, 1, 6, 1, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stoneBrick.blockID, 0, 1, 5, 2, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stoneBrick.blockID, 0, 1, 4, 3, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stoneSingleSlab.blockID, 0, 1, 5, 3, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stoneBrick.blockID, 0, 2, 4, 3, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stoneBrick.blockID, 0, 3, 3, 3, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stoneSingleSlab.blockID, 0, 3, 4, 3, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stoneBrick.blockID, 0, 3, 3, 2, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stoneBrick.blockID, 0, 3, 2, 1, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stoneSingleSlab.blockID, 0, 3, 3, 1, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stoneBrick.blockID, 0, 2, 2, 1, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stoneBrick.blockID, 0, 1, 1, 1, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stoneSingleSlab.blockID, 0, 1, 2, 1, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stoneBrick.blockID, 0, 1, 1, 2, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stoneSingleSlab.blockID, 0, 1, 1, 3, + par3StructureBoundingBox); + return true; + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ComponentStrongholdStairs2.java b/sp-server/src/main/java/net/minecraft/src/ComponentStrongholdStairs2.java new file mode 100644 index 0000000..aa53e34 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ComponentStrongholdStairs2.java @@ -0,0 +1,18 @@ +package net.minecraft.src; + +import java.util.ArrayList; +import java.util.Random; + +public class ComponentStrongholdStairs2 extends ComponentStrongholdStairs { + public StructureStrongholdPieceWeight strongholdPieceWeight; + public ComponentStrongholdPortalRoom strongholdPortalRoom; + public ArrayList field_75026_c = new ArrayList(); + + public ComponentStrongholdStairs2(int par1, Random par2Random, int par3, int par4) { + super(0, par2Random, par3, par4); + } + + public ChunkPosition getCenter() { + return this.strongholdPortalRoom != null ? this.strongholdPortalRoom.getCenter() : super.getCenter(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ComponentStrongholdStairsStraight.java b/sp-server/src/main/java/net/minecraft/src/ComponentStrongholdStairsStraight.java new file mode 100644 index 0000000..bc63d0b --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ComponentStrongholdStairsStraight.java @@ -0,0 +1,70 @@ +package net.minecraft.src; + +import java.util.List; +import java.util.Random; + +public class ComponentStrongholdStairsStraight extends ComponentStronghold { + private final EnumDoor doorType; + + public ComponentStrongholdStairsStraight(int par1, Random par2Random, StructureBoundingBox par3StructureBoundingBox, + int par4) { + super(par1); + this.coordBaseMode = par4; + this.doorType = this.getRandomDoor(par2Random); + this.boundingBox = par3StructureBoundingBox; + } + + /** + * Initiates construction of the Structure Component picked, at the current + * Location of StructGen + */ + public void buildComponent(StructureComponent par1StructureComponent, List par2List, Random par3Random) { + this.getNextComponentNormal((ComponentStrongholdStairs2) par1StructureComponent, par2List, par3Random, 1, 1); + } + + public static ComponentStrongholdStairsStraight findValidPlacement(List par0List, Random par1Random, int par2, + int par3, int par4, int par5, int par6) { + StructureBoundingBox var7 = StructureBoundingBox.getComponentToAddBoundingBox(par2, par3, par4, -1, -7, 0, 5, + 11, 8, par5); + return canStrongholdGoDeeper(var7) && StructureComponent.findIntersecting(par0List, var7) == null + ? new ComponentStrongholdStairsStraight(par6, par1Random, var7, par5) + : null; + } + + /** + * second Part of Structure generating, this for example places Spiderwebs, Mob + * Spawners, it closes Mineshafts at the end, it adds Fences... + */ + public boolean addComponentParts(World par1World, Random par2Random, + StructureBoundingBox par3StructureBoundingBox) { + if (this.isLiquidInStructureBoundingBox(par1World, par3StructureBoundingBox)) { + return false; + } else { + this.fillWithRandomizedBlocks(par1World, par3StructureBoundingBox, 0, 0, 0, 4, 10, 7, true, par2Random, + StructureStrongholdPieces.getStrongholdStones()); + this.placeDoor(par1World, par2Random, par3StructureBoundingBox, this.doorType, 1, 7, 0); + this.placeDoor(par1World, par2Random, par3StructureBoundingBox, EnumDoor.OPENING, 1, 1, 7); + int var4 = this.getMetadataWithOffset(Block.stairsCobblestone.blockID, 2); + + for (int var5 = 0; var5 < 6; ++var5) { + this.placeBlockAtCurrentPosition(par1World, Block.stairsCobblestone.blockID, var4, 1, 6 - var5, + 1 + var5, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stairsCobblestone.blockID, var4, 2, 6 - var5, + 1 + var5, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stairsCobblestone.blockID, var4, 3, 6 - var5, + 1 + var5, par3StructureBoundingBox); + + if (var5 < 5) { + this.placeBlockAtCurrentPosition(par1World, Block.stoneBrick.blockID, 0, 1, 5 - var5, 1 + var5, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stoneBrick.blockID, 0, 2, 5 - var5, 1 + var5, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stoneBrick.blockID, 0, 3, 5 - var5, 1 + var5, + par3StructureBoundingBox); + } + } + + return true; + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ComponentStrongholdStraight.java b/sp-server/src/main/java/net/minecraft/src/ComponentStrongholdStraight.java new file mode 100644 index 0000000..65aa8e6 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ComponentStrongholdStraight.java @@ -0,0 +1,79 @@ +package net.minecraft.src; + +import java.util.List; +import java.util.Random; + +public class ComponentStrongholdStraight extends ComponentStronghold { + private final EnumDoor doorType; + private final boolean expandsX; + private final boolean expandsZ; + + public ComponentStrongholdStraight(int par1, Random par2Random, StructureBoundingBox par3StructureBoundingBox, + int par4) { + super(par1); + this.coordBaseMode = par4; + this.doorType = this.getRandomDoor(par2Random); + this.boundingBox = par3StructureBoundingBox; + this.expandsX = par2Random.nextInt(2) == 0; + this.expandsZ = par2Random.nextInt(2) == 0; + } + + /** + * Initiates construction of the Structure Component picked, at the current + * Location of StructGen + */ + public void buildComponent(StructureComponent par1StructureComponent, List par2List, Random par3Random) { + this.getNextComponentNormal((ComponentStrongholdStairs2) par1StructureComponent, par2List, par3Random, 1, 1); + + if (this.expandsX) { + this.getNextComponentX((ComponentStrongholdStairs2) par1StructureComponent, par2List, par3Random, 1, 2); + } + + if (this.expandsZ) { + this.getNextComponentZ((ComponentStrongholdStairs2) par1StructureComponent, par2List, par3Random, 1, 2); + } + } + + public static ComponentStrongholdStraight findValidPlacement(List par0List, Random par1Random, int par2, int par3, + int par4, int par5, int par6) { + StructureBoundingBox var7 = StructureBoundingBox.getComponentToAddBoundingBox(par2, par3, par4, -1, -1, 0, 5, 5, + 7, par5); + return canStrongholdGoDeeper(var7) && StructureComponent.findIntersecting(par0List, var7) == null + ? new ComponentStrongholdStraight(par6, par1Random, var7, par5) + : null; + } + + /** + * second Part of Structure generating, this for example places Spiderwebs, Mob + * Spawners, it closes Mineshafts at the end, it adds Fences... + */ + public boolean addComponentParts(World par1World, Random par2Random, + StructureBoundingBox par3StructureBoundingBox) { + if (this.isLiquidInStructureBoundingBox(par1World, par3StructureBoundingBox)) { + return false; + } else { + this.fillWithRandomizedBlocks(par1World, par3StructureBoundingBox, 0, 0, 0, 4, 4, 6, true, par2Random, + StructureStrongholdPieces.getStrongholdStones()); + this.placeDoor(par1World, par2Random, par3StructureBoundingBox, this.doorType, 1, 1, 0); + this.placeDoor(par1World, par2Random, par3StructureBoundingBox, EnumDoor.OPENING, 1, 1, 6); + this.randomlyPlaceBlock(par1World, par3StructureBoundingBox, par2Random, 0.1F, 1, 2, 1, + Block.torchWood.blockID, 0); + this.randomlyPlaceBlock(par1World, par3StructureBoundingBox, par2Random, 0.1F, 3, 2, 1, + Block.torchWood.blockID, 0); + this.randomlyPlaceBlock(par1World, par3StructureBoundingBox, par2Random, 0.1F, 1, 2, 5, + Block.torchWood.blockID, 0); + this.randomlyPlaceBlock(par1World, par3StructureBoundingBox, par2Random, 0.1F, 3, 2, 5, + Block.torchWood.blockID, 0); + + if (this.expandsX) { + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 1, 2, 0, 3, 4, 0, 0, false); + } + + if (this.expandsZ) { + this.fillWithBlocks(par1World, par3StructureBoundingBox, 4, 1, 2, 4, 3, 4, 0, 0, false); + } + + return true; + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ComponentVillage.java b/sp-server/src/main/java/net/minecraft/src/ComponentVillage.java new file mode 100644 index 0000000..5b308b1 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ComponentVillage.java @@ -0,0 +1,232 @@ +package net.minecraft.src; + +import java.util.List; +import java.util.Random; + +abstract class ComponentVillage extends StructureComponent { + /** The number of villagers that have been spawned in this component. */ + private int villagersSpawned; + + /** The starting piece of the village. */ + protected ComponentVillageStartPiece startPiece; + + protected ComponentVillage(ComponentVillageStartPiece par1ComponentVillageStartPiece, int par2) { + super(par2); + this.startPiece = par1ComponentVillageStartPiece; + } + + /** + * Gets the next village component, with the bounding box shifted -1 in the X + * and Z direction. + */ + protected StructureComponent getNextComponentNN(ComponentVillageStartPiece par1ComponentVillageStartPiece, + List par2List, Random par3Random, int par4, int par5) { + switch (this.coordBaseMode) { + case 0: + return StructureVillagePieces.getNextStructureComponent(par1ComponentVillageStartPiece, par2List, + par3Random, this.boundingBox.minX - 1, this.boundingBox.minY + par4, this.boundingBox.minZ + par5, + 1, this.getComponentType()); + + case 1: + return StructureVillagePieces.getNextStructureComponent(par1ComponentVillageStartPiece, par2List, + par3Random, this.boundingBox.minX + par5, this.boundingBox.minY + par4, this.boundingBox.minZ - 1, + 2, this.getComponentType()); + + case 2: + return StructureVillagePieces.getNextStructureComponent(par1ComponentVillageStartPiece, par2List, + par3Random, this.boundingBox.minX - 1, this.boundingBox.minY + par4, this.boundingBox.minZ + par5, + 1, this.getComponentType()); + + case 3: + return StructureVillagePieces.getNextStructureComponent(par1ComponentVillageStartPiece, par2List, + par3Random, this.boundingBox.minX + par5, this.boundingBox.minY + par4, this.boundingBox.minZ - 1, + 2, this.getComponentType()); + + default: + return null; + } + } + + /** + * Gets the next village component, with the bounding box shifted +1 in the X + * and Z direction. + */ + protected StructureComponent getNextComponentPP(ComponentVillageStartPiece par1ComponentVillageStartPiece, + List par2List, Random par3Random, int par4, int par5) { + switch (this.coordBaseMode) { + case 0: + return StructureVillagePieces.getNextStructureComponent(par1ComponentVillageStartPiece, par2List, + par3Random, this.boundingBox.maxX + 1, this.boundingBox.minY + par4, this.boundingBox.minZ + par5, + 3, this.getComponentType()); + + case 1: + return StructureVillagePieces.getNextStructureComponent(par1ComponentVillageStartPiece, par2List, + par3Random, this.boundingBox.minX + par5, this.boundingBox.minY + par4, this.boundingBox.maxZ + 1, + 0, this.getComponentType()); + + case 2: + return StructureVillagePieces.getNextStructureComponent(par1ComponentVillageStartPiece, par2List, + par3Random, this.boundingBox.maxX + 1, this.boundingBox.minY + par4, this.boundingBox.minZ + par5, + 3, this.getComponentType()); + + case 3: + return StructureVillagePieces.getNextStructureComponent(par1ComponentVillageStartPiece, par2List, + par3Random, this.boundingBox.minX + par5, this.boundingBox.minY + par4, this.boundingBox.maxZ + 1, + 0, this.getComponentType()); + + default: + return null; + } + } + + /** + * Discover the y coordinate that will serve as the ground level of the supplied + * BoundingBox. (A median of all the levels in the BB's horizontal rectangle). + */ + protected int getAverageGroundLevel(World par1World, StructureBoundingBox par2StructureBoundingBox) { + int var3 = 0; + int var4 = 0; + + for (int var5 = this.boundingBox.minZ; var5 <= this.boundingBox.maxZ; ++var5) { + for (int var6 = this.boundingBox.minX; var6 <= this.boundingBox.maxX; ++var6) { + if (par2StructureBoundingBox.isVecInside(var6, 64, var5)) { + var3 += Math.max(par1World.getTopSolidOrLiquidBlock(var6, var5), + par1World.provider.getAverageGroundLevel()); + ++var4; + } + } + } + + if (var4 == 0) { + return -1; + } else { + return var3 / var4; + } + } + + protected static boolean canVillageGoDeeper(StructureBoundingBox par0StructureBoundingBox) { + return par0StructureBoundingBox != null && par0StructureBoundingBox.minY > 10; + } + + /** + * Spawns a number of villagers in this component. Parameters: world, component + * bounding box, x offset, y offset, z offset, number of villagers + */ + protected void spawnVillagers(World par1World, StructureBoundingBox par2StructureBoundingBox, int par3, int par4, + int par5, int par6) { + if (this.villagersSpawned < par6) { + for (int var7 = this.villagersSpawned; var7 < par6; ++var7) { + int var8 = this.getXWithOffset(par3 + var7, par5); + int var9 = this.getYWithOffset(par4); + int var10 = this.getZWithOffset(par3 + var7, par5); + + if (!par2StructureBoundingBox.isVecInside(var8, var9, var10)) { + break; + } + + ++this.villagersSpawned; + EntityVillager var11 = new EntityVillager(par1World, this.getVillagerType(var7)); + var11.setLocationAndAngles((double) var8 + 0.5D, (double) var9, (double) var10 + 0.5D, 0.0F, 0.0F); + par1World.spawnEntityInWorld(var11); + } + } + } + + /** + * Returns the villager type to spawn in this component, based on the number of + * villagers already spawned. + */ + protected int getVillagerType(int par1) { + return 0; + } + + /** + * Gets the replacement block for the current biome + */ + protected int getBiomeSpecificBlock(int par1, int par2) { + if (this.startPiece.inDesert) { + if (par1 == Block.wood.blockID) { + return Block.sandStone.blockID; + } + + if (par1 == Block.cobblestone.blockID) { + return Block.sandStone.blockID; + } + + if (par1 == Block.planks.blockID) { + return Block.sandStone.blockID; + } + + if (par1 == Block.stairsWoodOak.blockID) { + return Block.stairsSandStone.blockID; + } + + if (par1 == Block.stairsCobblestone.blockID) { + return Block.stairsSandStone.blockID; + } + + if (par1 == Block.gravel.blockID) { + return Block.sandStone.blockID; + } + } + + return par1; + } + + /** + * Gets the replacement block metadata for the current biome + */ + protected int getBiomeSpecificBlockMetadata(int par1, int par2) { + if (this.startPiece.inDesert) { + if (par1 == Block.wood.blockID) { + return 0; + } + + if (par1 == Block.cobblestone.blockID) { + return 0; + } + + if (par1 == Block.planks.blockID) { + return 2; + } + } + + return par2; + } + + /** + * current Position depends on currently set Coordinates mode, is computed here + */ + protected void placeBlockAtCurrentPosition(World par1World, int par2, int par3, int par4, int par5, int par6, + StructureBoundingBox par7StructureBoundingBox) { + int var8 = this.getBiomeSpecificBlock(par2, par3); + int var9 = this.getBiomeSpecificBlockMetadata(par2, par3); + super.placeBlockAtCurrentPosition(par1World, var8, var9, par4, par5, par6, par7StructureBoundingBox); + } + + /** + * arguments: (World worldObj, StructureBoundingBox structBB, int minX, int + * minY, int minZ, int maxX, int maxY, int maxZ, int placeBlockId, int + * replaceBlockId, boolean alwaysreplace) + */ + protected void fillWithBlocks(World par1World, StructureBoundingBox par2StructureBoundingBox, int par3, int par4, + int par5, int par6, int par7, int par8, int par9, int par10, boolean par11) { + int var12 = this.getBiomeSpecificBlock(par9, 0); + int var13 = this.getBiomeSpecificBlockMetadata(par9, 0); + int var14 = this.getBiomeSpecificBlock(par10, 0); + int var15 = this.getBiomeSpecificBlockMetadata(par10, 0); + super.fillWithMetadataBlocks(par1World, par2StructureBoundingBox, par3, par4, par5, par6, par7, par8, var12, + var13, var14, var15, par11); + } + + /** + * Overwrites air and liquids from selected position downwards, stops at hitting + * anything else. + */ + protected void fillCurrentPositionBlocksDownwards(World par1World, int par2, int par3, int par4, int par5, int par6, + StructureBoundingBox par7StructureBoundingBox) { + int var8 = this.getBiomeSpecificBlock(par2, par3); + int var9 = this.getBiomeSpecificBlockMetadata(par2, par3); + super.fillCurrentPositionBlocksDownwards(par1World, var8, var9, par4, par5, par6, par7StructureBoundingBox); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ComponentVillageChurch.java b/sp-server/src/main/java/net/minecraft/src/ComponentVillageChurch.java new file mode 100644 index 0000000..c7411e8 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ComponentVillageChurch.java @@ -0,0 +1,141 @@ +package net.minecraft.src; + +import java.util.List; +import java.util.Random; + +public class ComponentVillageChurch extends ComponentVillage { + private int averageGroundLevel = -1; + + public ComponentVillageChurch(ComponentVillageStartPiece par1ComponentVillageStartPiece, int par2, + Random par3Random, StructureBoundingBox par4StructureBoundingBox, int par5) { + super(par1ComponentVillageStartPiece, par2); + this.coordBaseMode = par5; + this.boundingBox = par4StructureBoundingBox; + } + + public static ComponentVillageChurch func_74919_a(ComponentVillageStartPiece par0ComponentVillageStartPiece, + List par1List, Random par2Random, int par3, int par4, int par5, int par6, int par7) { + StructureBoundingBox var8 = StructureBoundingBox.getComponentToAddBoundingBox(par3, par4, par5, 0, 0, 0, 5, 12, + 9, par6); + return canVillageGoDeeper(var8) && StructureComponent.findIntersecting(par1List, var8) == null + ? new ComponentVillageChurch(par0ComponentVillageStartPiece, par7, par2Random, var8, par6) + : null; + } + + /** + * second Part of Structure generating, this for example places Spiderwebs, Mob + * Spawners, it closes Mineshafts at the end, it adds Fences... + */ + public boolean addComponentParts(World par1World, Random par2Random, + StructureBoundingBox par3StructureBoundingBox) { + if (this.averageGroundLevel < 0) { + this.averageGroundLevel = this.getAverageGroundLevel(par1World, par3StructureBoundingBox); + + if (this.averageGroundLevel < 0) { + return true; + } + + this.boundingBox.offset(0, this.averageGroundLevel - this.boundingBox.maxY + 12 - 1, 0); + } + + this.fillWithBlocks(par1World, par3StructureBoundingBox, 1, 1, 1, 3, 3, 7, 0, 0, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 1, 5, 1, 3, 9, 3, 0, 0, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 1, 0, 0, 3, 0, 8, Block.cobblestone.blockID, + Block.cobblestone.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 1, 1, 0, 3, 10, 0, Block.cobblestone.blockID, + Block.cobblestone.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 1, 1, 0, 10, 3, Block.cobblestone.blockID, + Block.cobblestone.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 4, 1, 1, 4, 10, 3, Block.cobblestone.blockID, + Block.cobblestone.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 0, 4, 0, 4, 7, Block.cobblestone.blockID, + Block.cobblestone.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 4, 0, 4, 4, 4, 7, Block.cobblestone.blockID, + Block.cobblestone.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 1, 1, 8, 3, 4, 8, Block.cobblestone.blockID, + Block.cobblestone.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 1, 5, 4, 3, 10, 4, Block.cobblestone.blockID, + Block.cobblestone.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 1, 5, 5, 3, 5, 7, Block.cobblestone.blockID, + Block.cobblestone.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 9, 0, 4, 9, 4, Block.cobblestone.blockID, + Block.cobblestone.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 4, 0, 4, 4, 4, Block.cobblestone.blockID, + Block.cobblestone.blockID, false); + this.placeBlockAtCurrentPosition(par1World, Block.cobblestone.blockID, 0, 0, 11, 2, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.cobblestone.blockID, 0, 4, 11, 2, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.cobblestone.blockID, 0, 2, 11, 0, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.cobblestone.blockID, 0, 2, 11, 4, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.cobblestone.blockID, 0, 1, 1, 6, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.cobblestone.blockID, 0, 1, 1, 7, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.cobblestone.blockID, 0, 2, 1, 7, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.cobblestone.blockID, 0, 3, 1, 6, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.cobblestone.blockID, 0, 3, 1, 7, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stairsCobblestone.blockID, + this.getMetadataWithOffset(Block.stairsCobblestone.blockID, 3), 1, 1, 5, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stairsCobblestone.blockID, + this.getMetadataWithOffset(Block.stairsCobblestone.blockID, 3), 2, 1, 6, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stairsCobblestone.blockID, + this.getMetadataWithOffset(Block.stairsCobblestone.blockID, 3), 3, 1, 5, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stairsCobblestone.blockID, + this.getMetadataWithOffset(Block.stairsCobblestone.blockID, 1), 1, 2, 7, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stairsCobblestone.blockID, + this.getMetadataWithOffset(Block.stairsCobblestone.blockID, 0), 3, 2, 7, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.thinGlass.blockID, 0, 0, 2, 2, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.thinGlass.blockID, 0, 0, 3, 2, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.thinGlass.blockID, 0, 4, 2, 2, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.thinGlass.blockID, 0, 4, 3, 2, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.thinGlass.blockID, 0, 0, 6, 2, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.thinGlass.blockID, 0, 0, 7, 2, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.thinGlass.blockID, 0, 4, 6, 2, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.thinGlass.blockID, 0, 4, 7, 2, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.thinGlass.blockID, 0, 2, 6, 0, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.thinGlass.blockID, 0, 2, 7, 0, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.thinGlass.blockID, 0, 2, 6, 4, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.thinGlass.blockID, 0, 2, 7, 4, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.thinGlass.blockID, 0, 0, 3, 6, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.thinGlass.blockID, 0, 4, 3, 6, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.thinGlass.blockID, 0, 2, 3, 8, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.torchWood.blockID, 0, 2, 4, 7, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.torchWood.blockID, 0, 1, 4, 6, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.torchWood.blockID, 0, 3, 4, 6, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.torchWood.blockID, 0, 2, 4, 5, par3StructureBoundingBox); + int var4 = this.getMetadataWithOffset(Block.ladder.blockID, 4); + int var5; + + for (var5 = 1; var5 <= 9; ++var5) { + this.placeBlockAtCurrentPosition(par1World, Block.ladder.blockID, var4, 3, var5, 3, + par3StructureBoundingBox); + } + + this.placeBlockAtCurrentPosition(par1World, 0, 0, 2, 1, 0, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, 0, 0, 2, 2, 0, par3StructureBoundingBox); + this.placeDoorAtCurrentPosition(par1World, par3StructureBoundingBox, par2Random, 2, 1, 0, + this.getMetadataWithOffset(Block.doorWood.blockID, 1)); + + if (this.getBlockIdAtCurrentPosition(par1World, 2, 0, -1, par3StructureBoundingBox) == 0 + && this.getBlockIdAtCurrentPosition(par1World, 2, -1, -1, par3StructureBoundingBox) != 0) { + this.placeBlockAtCurrentPosition(par1World, Block.stairsCobblestone.blockID, + this.getMetadataWithOffset(Block.stairsCobblestone.blockID, 3), 2, 0, -1, par3StructureBoundingBox); + } + + for (var5 = 0; var5 < 9; ++var5) { + for (int var6 = 0; var6 < 5; ++var6) { + this.clearCurrentPositionBlocksUpwards(par1World, var6, 12, var5, par3StructureBoundingBox); + this.fillCurrentPositionBlocksDownwards(par1World, Block.cobblestone.blockID, 0, var6, -1, var5, + par3StructureBoundingBox); + } + } + + this.spawnVillagers(par1World, par3StructureBoundingBox, 2, 1, 2, 1); + return true; + } + + /** + * Returns the villager type to spawn in this component, based on the number of + * villagers already spawned. + */ + protected int getVillagerType(int par1) { + return 2; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ComponentVillageField.java b/sp-server/src/main/java/net/minecraft/src/ComponentVillageField.java new file mode 100644 index 0000000..a06c3b6 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ComponentVillageField.java @@ -0,0 +1,127 @@ +package net.minecraft.src; + +import java.util.List; +import java.util.Random; + +public class ComponentVillageField extends ComponentVillage { + private int averageGroundLevel = -1; + + /** First crop type for this field. */ + private int cropTypeA; + + /** Second crop type for this field. */ + private int cropTypeB; + + /** Third crop type for this field. */ + private int cropTypeC; + + /** Fourth crop type for this field. */ + private int cropTypeD; + + public ComponentVillageField(ComponentVillageStartPiece par1ComponentVillageStartPiece, int par2, Random par3Random, + StructureBoundingBox par4StructureBoundingBox, int par5) { + super(par1ComponentVillageStartPiece, par2); + this.coordBaseMode = par5; + this.boundingBox = par4StructureBoundingBox; + this.cropTypeA = this.getRandomCrop(par3Random); + this.cropTypeB = this.getRandomCrop(par3Random); + this.cropTypeC = this.getRandomCrop(par3Random); + this.cropTypeD = this.getRandomCrop(par3Random); + } + + /** + * Returns a crop type to be planted on this field. + */ + private int getRandomCrop(Random par1Random) { + switch (par1Random.nextInt(5)) { + case 0: + return Block.carrot.blockID; + + case 1: + return Block.potato.blockID; + + default: + return Block.crops.blockID; + } + } + + public static ComponentVillageField func_74900_a(ComponentVillageStartPiece par0ComponentVillageStartPiece, + List par1List, Random par2Random, int par3, int par4, int par5, int par6, int par7) { + StructureBoundingBox var8 = StructureBoundingBox.getComponentToAddBoundingBox(par3, par4, par5, 0, 0, 0, 13, 4, + 9, par6); + return canVillageGoDeeper(var8) && StructureComponent.findIntersecting(par1List, var8) == null + ? new ComponentVillageField(par0ComponentVillageStartPiece, par7, par2Random, var8, par6) + : null; + } + + /** + * second Part of Structure generating, this for example places Spiderwebs, Mob + * Spawners, it closes Mineshafts at the end, it adds Fences... + */ + public boolean addComponentParts(World par1World, Random par2Random, + StructureBoundingBox par3StructureBoundingBox) { + if (this.averageGroundLevel < 0) { + this.averageGroundLevel = this.getAverageGroundLevel(par1World, par3StructureBoundingBox); + + if (this.averageGroundLevel < 0) { + return true; + } + + this.boundingBox.offset(0, this.averageGroundLevel - this.boundingBox.maxY + 4 - 1, 0); + } + + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 1, 0, 12, 4, 8, 0, 0, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 1, 0, 1, 2, 0, 7, Block.tilledField.blockID, + Block.tilledField.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 4, 0, 1, 5, 0, 7, Block.tilledField.blockID, + Block.tilledField.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 7, 0, 1, 8, 0, 7, Block.tilledField.blockID, + Block.tilledField.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 10, 0, 1, 11, 0, 7, Block.tilledField.blockID, + Block.tilledField.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 0, 0, 0, 0, 8, Block.wood.blockID, + Block.wood.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 6, 0, 0, 6, 0, 8, Block.wood.blockID, + Block.wood.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 12, 0, 0, 12, 0, 8, Block.wood.blockID, + Block.wood.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 1, 0, 0, 11, 0, 0, Block.wood.blockID, + Block.wood.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 1, 0, 8, 11, 0, 8, Block.wood.blockID, + Block.wood.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 3, 0, 1, 3, 0, 7, Block.waterMoving.blockID, + Block.waterMoving.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 9, 0, 1, 9, 0, 7, Block.waterMoving.blockID, + Block.waterMoving.blockID, false); + int var4; + + for (var4 = 1; var4 <= 7; ++var4) { + this.placeBlockAtCurrentPosition(par1World, this.cropTypeA, + MathHelper.getRandomIntegerInRange(par2Random, 2, 7), 1, 1, var4, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, this.cropTypeA, + MathHelper.getRandomIntegerInRange(par2Random, 2, 7), 2, 1, var4, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, this.cropTypeB, + MathHelper.getRandomIntegerInRange(par2Random, 2, 7), 4, 1, var4, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, this.cropTypeB, + MathHelper.getRandomIntegerInRange(par2Random, 2, 7), 5, 1, var4, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, this.cropTypeC, + MathHelper.getRandomIntegerInRange(par2Random, 2, 7), 7, 1, var4, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, this.cropTypeC, + MathHelper.getRandomIntegerInRange(par2Random, 2, 7), 8, 1, var4, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, this.cropTypeD, + MathHelper.getRandomIntegerInRange(par2Random, 2, 7), 10, 1, var4, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, this.cropTypeD, + MathHelper.getRandomIntegerInRange(par2Random, 2, 7), 11, 1, var4, par3StructureBoundingBox); + } + + for (var4 = 0; var4 < 9; ++var4) { + for (int var5 = 0; var5 < 13; ++var5) { + this.clearCurrentPositionBlocksUpwards(par1World, var5, 4, var4, par3StructureBoundingBox); + this.fillCurrentPositionBlocksDownwards(par1World, Block.dirt.blockID, 0, var5, -1, var4, + par3StructureBoundingBox); + } + } + + return true; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ComponentVillageField2.java b/sp-server/src/main/java/net/minecraft/src/ComponentVillageField2.java new file mode 100644 index 0000000..7abb5db --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ComponentVillageField2.java @@ -0,0 +1,103 @@ +package net.minecraft.src; + +import java.util.List; +import java.util.Random; + +public class ComponentVillageField2 extends ComponentVillage { + private int averageGroundLevel = -1; + + /** First crop type for this field. */ + private int cropTypeA; + + /** Second crop type for this field. */ + private int cropTypeB; + + public ComponentVillageField2(ComponentVillageStartPiece par1ComponentVillageStartPiece, int par2, + Random par3Random, StructureBoundingBox par4StructureBoundingBox, int par5) { + super(par1ComponentVillageStartPiece, par2); + this.coordBaseMode = par5; + this.boundingBox = par4StructureBoundingBox; + this.cropTypeA = this.pickRandomCrop(par3Random); + this.cropTypeB = this.pickRandomCrop(par3Random); + } + + /** + * Returns a crop type to be planted on this field. + */ + private int pickRandomCrop(Random par1Random) { + switch (par1Random.nextInt(5)) { + case 0: + return Block.carrot.blockID; + + case 1: + return Block.potato.blockID; + + default: + return Block.crops.blockID; + } + } + + public static ComponentVillageField2 func_74902_a(ComponentVillageStartPiece par0ComponentVillageStartPiece, + List par1List, Random par2Random, int par3, int par4, int par5, int par6, int par7) { + StructureBoundingBox var8 = StructureBoundingBox.getComponentToAddBoundingBox(par3, par4, par5, 0, 0, 0, 7, 4, + 9, par6); + return canVillageGoDeeper(var8) && StructureComponent.findIntersecting(par1List, var8) == null + ? new ComponentVillageField2(par0ComponentVillageStartPiece, par7, par2Random, var8, par6) + : null; + } + + /** + * second Part of Structure generating, this for example places Spiderwebs, Mob + * Spawners, it closes Mineshafts at the end, it adds Fences... + */ + public boolean addComponentParts(World par1World, Random par2Random, + StructureBoundingBox par3StructureBoundingBox) { + if (this.averageGroundLevel < 0) { + this.averageGroundLevel = this.getAverageGroundLevel(par1World, par3StructureBoundingBox); + + if (this.averageGroundLevel < 0) { + return true; + } + + this.boundingBox.offset(0, this.averageGroundLevel - this.boundingBox.maxY + 4 - 1, 0); + } + + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 1, 0, 6, 4, 8, 0, 0, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 1, 0, 1, 2, 0, 7, Block.tilledField.blockID, + Block.tilledField.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 4, 0, 1, 5, 0, 7, Block.tilledField.blockID, + Block.tilledField.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 0, 0, 0, 0, 8, Block.wood.blockID, + Block.wood.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 6, 0, 0, 6, 0, 8, Block.wood.blockID, + Block.wood.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 1, 0, 0, 5, 0, 0, Block.wood.blockID, + Block.wood.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 1, 0, 8, 5, 0, 8, Block.wood.blockID, + Block.wood.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 3, 0, 1, 3, 0, 7, Block.waterMoving.blockID, + Block.waterMoving.blockID, false); + int var4; + + for (var4 = 1; var4 <= 7; ++var4) { + this.placeBlockAtCurrentPosition(par1World, this.cropTypeA, + MathHelper.getRandomIntegerInRange(par2Random, 2, 7), 1, 1, var4, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, this.cropTypeA, + MathHelper.getRandomIntegerInRange(par2Random, 2, 7), 2, 1, var4, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, this.cropTypeB, + MathHelper.getRandomIntegerInRange(par2Random, 2, 7), 4, 1, var4, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, this.cropTypeB, + MathHelper.getRandomIntegerInRange(par2Random, 2, 7), 5, 1, var4, par3StructureBoundingBox); + } + + for (var4 = 0; var4 < 9; ++var4) { + for (int var5 = 0; var5 < 7; ++var5) { + this.clearCurrentPositionBlocksUpwards(par1World, var5, 4, var4, par3StructureBoundingBox); + this.fillCurrentPositionBlocksDownwards(par1World, Block.dirt.blockID, 0, var5, -1, var4, + par3StructureBoundingBox); + } + } + + return true; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ComponentVillageHall.java b/sp-server/src/main/java/net/minecraft/src/ComponentVillageHall.java new file mode 100644 index 0000000..b64d410 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ComponentVillageHall.java @@ -0,0 +1,153 @@ +package net.minecraft.src; + +import java.util.List; +import java.util.Random; + +public class ComponentVillageHall extends ComponentVillage { + private int averageGroundLevel = -1; + + public ComponentVillageHall(ComponentVillageStartPiece par1ComponentVillageStartPiece, int par2, Random par3Random, + StructureBoundingBox par4StructureBoundingBox, int par5) { + super(par1ComponentVillageStartPiece, par2); + this.coordBaseMode = par5; + this.boundingBox = par4StructureBoundingBox; + } + + public static ComponentVillageHall func_74906_a(ComponentVillageStartPiece par0ComponentVillageStartPiece, + List par1List, Random par2Random, int par3, int par4, int par5, int par6, int par7) { + StructureBoundingBox var8 = StructureBoundingBox.getComponentToAddBoundingBox(par3, par4, par5, 0, 0, 0, 9, 7, + 11, par6); + return canVillageGoDeeper(var8) && StructureComponent.findIntersecting(par1List, var8) == null + ? new ComponentVillageHall(par0ComponentVillageStartPiece, par7, par2Random, var8, par6) + : null; + } + + /** + * second Part of Structure generating, this for example places Spiderwebs, Mob + * Spawners, it closes Mineshafts at the end, it adds Fences... + */ + public boolean addComponentParts(World par1World, Random par2Random, + StructureBoundingBox par3StructureBoundingBox) { + if (this.averageGroundLevel < 0) { + this.averageGroundLevel = this.getAverageGroundLevel(par1World, par3StructureBoundingBox); + + if (this.averageGroundLevel < 0) { + return true; + } + + this.boundingBox.offset(0, this.averageGroundLevel - this.boundingBox.maxY + 7 - 1, 0); + } + + this.fillWithBlocks(par1World, par3StructureBoundingBox, 1, 1, 1, 7, 4, 4, 0, 0, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 2, 1, 6, 8, 4, 10, 0, 0, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 2, 0, 6, 8, 0, 10, Block.dirt.blockID, + Block.dirt.blockID, false); + this.placeBlockAtCurrentPosition(par1World, Block.cobblestone.blockID, 0, 6, 0, 6, par3StructureBoundingBox); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 2, 1, 6, 2, 1, 10, Block.fence.blockID, + Block.fence.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 8, 1, 6, 8, 1, 10, Block.fence.blockID, + Block.fence.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 3, 1, 10, 7, 1, 10, Block.fence.blockID, + Block.fence.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 1, 0, 1, 7, 0, 4, Block.planks.blockID, + Block.planks.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 0, 0, 0, 3, 5, Block.cobblestone.blockID, + Block.cobblestone.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 8, 0, 0, 8, 3, 5, Block.cobblestone.blockID, + Block.cobblestone.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 1, 0, 0, 7, 1, 0, Block.cobblestone.blockID, + Block.cobblestone.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 1, 0, 5, 7, 1, 5, Block.cobblestone.blockID, + Block.cobblestone.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 1, 2, 0, 7, 3, 0, Block.planks.blockID, + Block.planks.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 1, 2, 5, 7, 3, 5, Block.planks.blockID, + Block.planks.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 4, 1, 8, 4, 1, Block.planks.blockID, + Block.planks.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 4, 4, 8, 4, 4, Block.planks.blockID, + Block.planks.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 5, 2, 8, 5, 3, Block.planks.blockID, + Block.planks.blockID, false); + this.placeBlockAtCurrentPosition(par1World, Block.planks.blockID, 0, 0, 4, 2, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.planks.blockID, 0, 0, 4, 3, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.planks.blockID, 0, 8, 4, 2, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.planks.blockID, 0, 8, 4, 3, par3StructureBoundingBox); + int var4 = this.getMetadataWithOffset(Block.stairsWoodOak.blockID, 3); + int var5 = this.getMetadataWithOffset(Block.stairsWoodOak.blockID, 2); + int var6; + int var7; + + for (var6 = -1; var6 <= 2; ++var6) { + for (var7 = 0; var7 <= 8; ++var7) { + this.placeBlockAtCurrentPosition(par1World, Block.stairsWoodOak.blockID, var4, var7, 4 + var6, var6, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stairsWoodOak.blockID, var5, var7, 4 + var6, 5 - var6, + par3StructureBoundingBox); + } + } + + this.placeBlockAtCurrentPosition(par1World, Block.wood.blockID, 0, 0, 2, 1, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.wood.blockID, 0, 0, 2, 4, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.wood.blockID, 0, 8, 2, 1, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.wood.blockID, 0, 8, 2, 4, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.thinGlass.blockID, 0, 0, 2, 2, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.thinGlass.blockID, 0, 0, 2, 3, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.thinGlass.blockID, 0, 8, 2, 2, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.thinGlass.blockID, 0, 8, 2, 3, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.thinGlass.blockID, 0, 2, 2, 5, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.thinGlass.blockID, 0, 3, 2, 5, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.thinGlass.blockID, 0, 5, 2, 0, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.thinGlass.blockID, 0, 6, 2, 5, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.fence.blockID, 0, 2, 1, 3, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.pressurePlatePlanks.blockID, 0, 2, 2, 3, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.planks.blockID, 0, 1, 1, 4, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stairsWoodOak.blockID, + this.getMetadataWithOffset(Block.stairsWoodOak.blockID, 3), 2, 1, 4, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stairsWoodOak.blockID, + this.getMetadataWithOffset(Block.stairsWoodOak.blockID, 1), 1, 1, 3, par3StructureBoundingBox); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 5, 0, 1, 7, 0, 3, Block.stoneDoubleSlab.blockID, + Block.stoneDoubleSlab.blockID, false); + this.placeBlockAtCurrentPosition(par1World, Block.stoneDoubleSlab.blockID, 0, 6, 1, 1, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stoneDoubleSlab.blockID, 0, 6, 1, 2, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, 0, 0, 2, 1, 0, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, 0, 0, 2, 2, 0, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.torchWood.blockID, 0, 2, 3, 1, par3StructureBoundingBox); + this.placeDoorAtCurrentPosition(par1World, par3StructureBoundingBox, par2Random, 2, 1, 0, + this.getMetadataWithOffset(Block.doorWood.blockID, 1)); + + if (this.getBlockIdAtCurrentPosition(par1World, 2, 0, -1, par3StructureBoundingBox) == 0 + && this.getBlockIdAtCurrentPosition(par1World, 2, -1, -1, par3StructureBoundingBox) != 0) { + this.placeBlockAtCurrentPosition(par1World, Block.stairsCobblestone.blockID, + this.getMetadataWithOffset(Block.stairsCobblestone.blockID, 3), 2, 0, -1, par3StructureBoundingBox); + } + + this.placeBlockAtCurrentPosition(par1World, 0, 0, 6, 1, 5, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, 0, 0, 6, 2, 5, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.torchWood.blockID, 0, 6, 3, 4, par3StructureBoundingBox); + this.placeDoorAtCurrentPosition(par1World, par3StructureBoundingBox, par2Random, 6, 1, 5, + this.getMetadataWithOffset(Block.doorWood.blockID, 1)); + + for (var6 = 0; var6 < 5; ++var6) { + for (var7 = 0; var7 < 9; ++var7) { + this.clearCurrentPositionBlocksUpwards(par1World, var7, 7, var6, par3StructureBoundingBox); + this.fillCurrentPositionBlocksDownwards(par1World, Block.cobblestone.blockID, 0, var7, -1, var6, + par3StructureBoundingBox); + } + } + + this.spawnVillagers(par1World, par3StructureBoundingBox, 4, 1, 2, 2); + return true; + } + + /** + * Returns the villager type to spawn in this component, based on the number of + * villagers already spawned. + */ + protected int getVillagerType(int par1) { + return par1 == 0 ? 4 : 0; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ComponentVillageHouse1.java b/sp-server/src/main/java/net/minecraft/src/ComponentVillageHouse1.java new file mode 100644 index 0000000..c683bcd --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ComponentVillageHouse1.java @@ -0,0 +1,161 @@ +package net.minecraft.src; + +import java.util.List; +import java.util.Random; + +public class ComponentVillageHouse1 extends ComponentVillage { + private int averageGroundLevel = -1; + + public ComponentVillageHouse1(ComponentVillageStartPiece par1ComponentVillageStartPiece, int par2, + Random par3Random, StructureBoundingBox par4StructureBoundingBox, int par5) { + super(par1ComponentVillageStartPiece, par2); + this.coordBaseMode = par5; + this.boundingBox = par4StructureBoundingBox; + } + + public static ComponentVillageHouse1 func_74898_a(ComponentVillageStartPiece par0ComponentVillageStartPiece, + List par1List, Random par2Random, int par3, int par4, int par5, int par6, int par7) { + StructureBoundingBox var8 = StructureBoundingBox.getComponentToAddBoundingBox(par3, par4, par5, 0, 0, 0, 9, 9, + 6, par6); + return canVillageGoDeeper(var8) && StructureComponent.findIntersecting(par1List, var8) == null + ? new ComponentVillageHouse1(par0ComponentVillageStartPiece, par7, par2Random, var8, par6) + : null; + } + + /** + * second Part of Structure generating, this for example places Spiderwebs, Mob + * Spawners, it closes Mineshafts at the end, it adds Fences... + */ + public boolean addComponentParts(World par1World, Random par2Random, + StructureBoundingBox par3StructureBoundingBox) { + if (this.averageGroundLevel < 0) { + this.averageGroundLevel = this.getAverageGroundLevel(par1World, par3StructureBoundingBox); + + if (this.averageGroundLevel < 0) { + return true; + } + + this.boundingBox.offset(0, this.averageGroundLevel - this.boundingBox.maxY + 9 - 1, 0); + } + + this.fillWithBlocks(par1World, par3StructureBoundingBox, 1, 1, 1, 7, 5, 4, 0, 0, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 0, 0, 8, 0, 5, Block.cobblestone.blockID, + Block.cobblestone.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 5, 0, 8, 5, 5, Block.cobblestone.blockID, + Block.cobblestone.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 6, 1, 8, 6, 4, Block.cobblestone.blockID, + Block.cobblestone.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 7, 2, 8, 7, 3, Block.cobblestone.blockID, + Block.cobblestone.blockID, false); + int var4 = this.getMetadataWithOffset(Block.stairsWoodOak.blockID, 3); + int var5 = this.getMetadataWithOffset(Block.stairsWoodOak.blockID, 2); + int var6; + int var7; + + for (var6 = -1; var6 <= 2; ++var6) { + for (var7 = 0; var7 <= 8; ++var7) { + this.placeBlockAtCurrentPosition(par1World, Block.stairsWoodOak.blockID, var4, var7, 6 + var6, var6, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stairsWoodOak.blockID, var5, var7, 6 + var6, 5 - var6, + par3StructureBoundingBox); + } + } + + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 1, 0, 0, 1, 5, Block.cobblestone.blockID, + Block.cobblestone.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 1, 1, 5, 8, 1, 5, Block.cobblestone.blockID, + Block.cobblestone.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 8, 1, 0, 8, 1, 4, Block.cobblestone.blockID, + Block.cobblestone.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 2, 1, 0, 7, 1, 0, Block.cobblestone.blockID, + Block.cobblestone.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 2, 0, 0, 4, 0, Block.cobblestone.blockID, + Block.cobblestone.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 2, 5, 0, 4, 5, Block.cobblestone.blockID, + Block.cobblestone.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 8, 2, 5, 8, 4, 5, Block.cobblestone.blockID, + Block.cobblestone.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 8, 2, 0, 8, 4, 0, Block.cobblestone.blockID, + Block.cobblestone.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 2, 1, 0, 4, 4, Block.planks.blockID, + Block.planks.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 1, 2, 5, 7, 4, 5, Block.planks.blockID, + Block.planks.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 8, 2, 1, 8, 4, 4, Block.planks.blockID, + Block.planks.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 1, 2, 0, 7, 4, 0, Block.planks.blockID, + Block.planks.blockID, false); + this.placeBlockAtCurrentPosition(par1World, Block.thinGlass.blockID, 0, 4, 2, 0, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.thinGlass.blockID, 0, 5, 2, 0, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.thinGlass.blockID, 0, 6, 2, 0, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.thinGlass.blockID, 0, 4, 3, 0, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.thinGlass.blockID, 0, 5, 3, 0, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.thinGlass.blockID, 0, 6, 3, 0, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.thinGlass.blockID, 0, 0, 2, 2, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.thinGlass.blockID, 0, 0, 2, 3, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.thinGlass.blockID, 0, 0, 3, 2, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.thinGlass.blockID, 0, 0, 3, 3, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.thinGlass.blockID, 0, 8, 2, 2, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.thinGlass.blockID, 0, 8, 2, 3, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.thinGlass.blockID, 0, 8, 3, 2, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.thinGlass.blockID, 0, 8, 3, 3, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.thinGlass.blockID, 0, 2, 2, 5, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.thinGlass.blockID, 0, 3, 2, 5, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.thinGlass.blockID, 0, 5, 2, 5, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.thinGlass.blockID, 0, 6, 2, 5, par3StructureBoundingBox); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 1, 4, 1, 7, 4, 1, Block.planks.blockID, + Block.planks.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 1, 4, 4, 7, 4, 4, Block.planks.blockID, + Block.planks.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 1, 3, 4, 7, 3, 4, Block.bookShelf.blockID, + Block.bookShelf.blockID, false); + this.placeBlockAtCurrentPosition(par1World, Block.planks.blockID, 0, 7, 1, 4, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stairsWoodOak.blockID, + this.getMetadataWithOffset(Block.stairsWoodOak.blockID, 0), 7, 1, 3, par3StructureBoundingBox); + var6 = this.getMetadataWithOffset(Block.stairsWoodOak.blockID, 3); + this.placeBlockAtCurrentPosition(par1World, Block.stairsWoodOak.blockID, var6, 6, 1, 4, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stairsWoodOak.blockID, var6, 5, 1, 4, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stairsWoodOak.blockID, var6, 4, 1, 4, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stairsWoodOak.blockID, var6, 3, 1, 4, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.fence.blockID, 0, 6, 1, 3, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.pressurePlatePlanks.blockID, 0, 6, 2, 3, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.fence.blockID, 0, 4, 1, 3, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.pressurePlatePlanks.blockID, 0, 4, 2, 3, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.workbench.blockID, 0, 7, 1, 1, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, 0, 0, 1, 1, 0, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, 0, 0, 1, 2, 0, par3StructureBoundingBox); + this.placeDoorAtCurrentPosition(par1World, par3StructureBoundingBox, par2Random, 1, 1, 0, + this.getMetadataWithOffset(Block.doorWood.blockID, 1)); + + if (this.getBlockIdAtCurrentPosition(par1World, 1, 0, -1, par3StructureBoundingBox) == 0 + && this.getBlockIdAtCurrentPosition(par1World, 1, -1, -1, par3StructureBoundingBox) != 0) { + this.placeBlockAtCurrentPosition(par1World, Block.stairsCobblestone.blockID, + this.getMetadataWithOffset(Block.stairsCobblestone.blockID, 3), 1, 0, -1, par3StructureBoundingBox); + } + + for (var7 = 0; var7 < 6; ++var7) { + for (int var8 = 0; var8 < 9; ++var8) { + this.clearCurrentPositionBlocksUpwards(par1World, var8, 9, var7, par3StructureBoundingBox); + this.fillCurrentPositionBlocksDownwards(par1World, Block.cobblestone.blockID, 0, var8, -1, var7, + par3StructureBoundingBox); + } + } + + this.spawnVillagers(par1World, par3StructureBoundingBox, 2, 1, 2, 1); + return true; + } + + /** + * Returns the villager type to spawn in this component, based on the number of + * villagers already spawned. + */ + protected int getVillagerType(int par1) { + return 1; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ComponentVillageHouse2.java b/sp-server/src/main/java/net/minecraft/src/ComponentVillageHouse2.java new file mode 100644 index 0000000..39397c3 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ComponentVillageHouse2.java @@ -0,0 +1,153 @@ +package net.minecraft.src; + +import java.util.List; +import java.util.Random; + +public class ComponentVillageHouse2 extends ComponentVillage { + /** List of items that Village's Blacksmith chest can contain. */ + private static final WeightedRandomChestContent[] villageBlacksmithChestContents = new WeightedRandomChestContent[] { + new WeightedRandomChestContent(Item.diamond.itemID, 0, 1, 3, 3), + new WeightedRandomChestContent(Item.ingotIron.itemID, 0, 1, 5, 10), + new WeightedRandomChestContent(Item.ingotGold.itemID, 0, 1, 3, 5), + new WeightedRandomChestContent(Item.bread.itemID, 0, 1, 3, 15), + new WeightedRandomChestContent(Item.appleRed.itemID, 0, 1, 3, 15), + new WeightedRandomChestContent(Item.pickaxeIron.itemID, 0, 1, 1, 5), + new WeightedRandomChestContent(Item.swordIron.itemID, 0, 1, 1, 5), + new WeightedRandomChestContent(Item.plateIron.itemID, 0, 1, 1, 5), + new WeightedRandomChestContent(Item.helmetIron.itemID, 0, 1, 1, 5), + new WeightedRandomChestContent(Item.legsIron.itemID, 0, 1, 1, 5), + new WeightedRandomChestContent(Item.bootsIron.itemID, 0, 1, 1, 5), + new WeightedRandomChestContent(Block.obsidian.blockID, 0, 3, 7, 5), + new WeightedRandomChestContent(Block.sapling.blockID, 0, 3, 7, 5) }; + private int averageGroundLevel = -1; + private boolean hasMadeChest; + + public ComponentVillageHouse2(ComponentVillageStartPiece par1ComponentVillageStartPiece, int par2, + Random par3Random, StructureBoundingBox par4StructureBoundingBox, int par5) { + super(par1ComponentVillageStartPiece, par2); + this.coordBaseMode = par5; + this.boundingBox = par4StructureBoundingBox; + } + + public static ComponentVillageHouse2 func_74915_a(ComponentVillageStartPiece par0ComponentVillageStartPiece, + List par1List, Random par2Random, int par3, int par4, int par5, int par6, int par7) { + StructureBoundingBox var8 = StructureBoundingBox.getComponentToAddBoundingBox(par3, par4, par5, 0, 0, 0, 10, 6, + 7, par6); + return canVillageGoDeeper(var8) && StructureComponent.findIntersecting(par1List, var8) == null + ? new ComponentVillageHouse2(par0ComponentVillageStartPiece, par7, par2Random, var8, par6) + : null; + } + + /** + * second Part of Structure generating, this for example places Spiderwebs, Mob + * Spawners, it closes Mineshafts at the end, it adds Fences... + */ + public boolean addComponentParts(World par1World, Random par2Random, + StructureBoundingBox par3StructureBoundingBox) { + if (this.averageGroundLevel < 0) { + this.averageGroundLevel = this.getAverageGroundLevel(par1World, par3StructureBoundingBox); + + if (this.averageGroundLevel < 0) { + return true; + } + + this.boundingBox.offset(0, this.averageGroundLevel - this.boundingBox.maxY + 6 - 1, 0); + } + + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 1, 0, 9, 4, 6, 0, 0, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 0, 0, 9, 0, 6, Block.cobblestone.blockID, + Block.cobblestone.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 4, 0, 9, 4, 6, Block.cobblestone.blockID, + Block.cobblestone.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 5, 0, 9, 5, 6, Block.stoneSingleSlab.blockID, + Block.stoneSingleSlab.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 1, 5, 1, 8, 5, 5, 0, 0, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 1, 1, 0, 2, 3, 0, Block.planks.blockID, + Block.planks.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 1, 0, 0, 4, 0, Block.wood.blockID, + Block.wood.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 3, 1, 0, 3, 4, 0, Block.wood.blockID, + Block.wood.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 1, 6, 0, 4, 6, Block.wood.blockID, + Block.wood.blockID, false); + this.placeBlockAtCurrentPosition(par1World, Block.planks.blockID, 0, 3, 3, 1, par3StructureBoundingBox); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 3, 1, 2, 3, 3, 2, Block.planks.blockID, + Block.planks.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 4, 1, 3, 5, 3, 3, Block.planks.blockID, + Block.planks.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 1, 1, 0, 3, 5, Block.planks.blockID, + Block.planks.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 1, 1, 6, 5, 3, 6, Block.planks.blockID, + Block.planks.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 5, 1, 0, 5, 3, 0, Block.fence.blockID, + Block.fence.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 9, 1, 0, 9, 3, 0, Block.fence.blockID, + Block.fence.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 6, 1, 4, 9, 4, 6, Block.cobblestone.blockID, + Block.cobblestone.blockID, false); + this.placeBlockAtCurrentPosition(par1World, Block.lavaMoving.blockID, 0, 7, 1, 5, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.lavaMoving.blockID, 0, 8, 1, 5, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.fenceIron.blockID, 0, 9, 2, 5, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.fenceIron.blockID, 0, 9, 2, 4, par3StructureBoundingBox); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 7, 2, 4, 8, 2, 5, 0, 0, false); + this.placeBlockAtCurrentPosition(par1World, Block.cobblestone.blockID, 0, 6, 1, 3, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.furnaceIdle.blockID, 0, 6, 2, 3, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.furnaceIdle.blockID, 0, 6, 3, 3, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stoneDoubleSlab.blockID, 0, 8, 1, 1, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.thinGlass.blockID, 0, 0, 2, 2, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.thinGlass.blockID, 0, 0, 2, 4, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.thinGlass.blockID, 0, 2, 2, 6, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.thinGlass.blockID, 0, 4, 2, 6, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.fence.blockID, 0, 2, 1, 4, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.pressurePlatePlanks.blockID, 0, 2, 2, 4, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.planks.blockID, 0, 1, 1, 5, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stairsWoodOak.blockID, + this.getMetadataWithOffset(Block.stairsWoodOak.blockID, 3), 2, 1, 5, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stairsWoodOak.blockID, + this.getMetadataWithOffset(Block.stairsWoodOak.blockID, 1), 1, 1, 4, par3StructureBoundingBox); + int var4; + int var5; + + if (!this.hasMadeChest) { + var4 = this.getYWithOffset(1); + var5 = this.getXWithOffset(5, 5); + int var6 = this.getZWithOffset(5, 5); + + if (par3StructureBoundingBox.isVecInside(var5, var4, var6)) { + this.hasMadeChest = true; + this.generateStructureChestContents(par1World, par3StructureBoundingBox, par2Random, 5, 1, 5, + villageBlacksmithChestContents, 3 + par2Random.nextInt(6)); + } + } + + for (var4 = 6; var4 <= 8; ++var4) { + if (this.getBlockIdAtCurrentPosition(par1World, var4, 0, -1, par3StructureBoundingBox) == 0 + && this.getBlockIdAtCurrentPosition(par1World, var4, -1, -1, par3StructureBoundingBox) != 0) { + this.placeBlockAtCurrentPosition(par1World, Block.stairsCobblestone.blockID, + this.getMetadataWithOffset(Block.stairsCobblestone.blockID, 3), var4, 0, -1, + par3StructureBoundingBox); + } + } + + for (var4 = 0; var4 < 7; ++var4) { + for (var5 = 0; var5 < 10; ++var5) { + this.clearCurrentPositionBlocksUpwards(par1World, var5, 6, var4, par3StructureBoundingBox); + this.fillCurrentPositionBlocksDownwards(par1World, Block.cobblestone.blockID, 0, var5, -1, var4, + par3StructureBoundingBox); + } + } + + this.spawnVillagers(par1World, par3StructureBoundingBox, 7, 1, 1, 1); + return true; + } + + /** + * Returns the villager type to spawn in this component, based on the number of + * villagers already spawned. + */ + protected int getVillagerType(int par1) { + return 3; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ComponentVillageHouse3.java b/sp-server/src/main/java/net/minecraft/src/ComponentVillageHouse3.java new file mode 100644 index 0000000..07043a9 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ComponentVillageHouse3.java @@ -0,0 +1,184 @@ +package net.minecraft.src; + +import java.util.List; +import java.util.Random; + +public class ComponentVillageHouse3 extends ComponentVillage { + private int averageGroundLevel = -1; + + public ComponentVillageHouse3(ComponentVillageStartPiece par1ComponentVillageStartPiece, int par2, + Random par3Random, StructureBoundingBox par4StructureBoundingBox, int par5) { + super(par1ComponentVillageStartPiece, par2); + this.coordBaseMode = par5; + this.boundingBox = par4StructureBoundingBox; + } + + public static ComponentVillageHouse3 func_74921_a(ComponentVillageStartPiece par0ComponentVillageStartPiece, + List par1List, Random par2Random, int par3, int par4, int par5, int par6, int par7) { + StructureBoundingBox var8 = StructureBoundingBox.getComponentToAddBoundingBox(par3, par4, par5, 0, 0, 0, 9, 7, + 12, par6); + return canVillageGoDeeper(var8) && StructureComponent.findIntersecting(par1List, var8) == null + ? new ComponentVillageHouse3(par0ComponentVillageStartPiece, par7, par2Random, var8, par6) + : null; + } + + /** + * second Part of Structure generating, this for example places Spiderwebs, Mob + * Spawners, it closes Mineshafts at the end, it adds Fences... + */ + public boolean addComponentParts(World par1World, Random par2Random, + StructureBoundingBox par3StructureBoundingBox) { + if (this.averageGroundLevel < 0) { + this.averageGroundLevel = this.getAverageGroundLevel(par1World, par3StructureBoundingBox); + + if (this.averageGroundLevel < 0) { + return true; + } + + this.boundingBox.offset(0, this.averageGroundLevel - this.boundingBox.maxY + 7 - 1, 0); + } + + this.fillWithBlocks(par1World, par3StructureBoundingBox, 1, 1, 1, 7, 4, 4, 0, 0, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 2, 1, 6, 8, 4, 10, 0, 0, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 2, 0, 5, 8, 0, 10, Block.planks.blockID, + Block.planks.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 1, 0, 1, 7, 0, 4, Block.planks.blockID, + Block.planks.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 0, 0, 0, 3, 5, Block.cobblestone.blockID, + Block.cobblestone.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 8, 0, 0, 8, 3, 10, Block.cobblestone.blockID, + Block.cobblestone.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 1, 0, 0, 7, 2, 0, Block.cobblestone.blockID, + Block.cobblestone.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 1, 0, 5, 2, 1, 5, Block.cobblestone.blockID, + Block.cobblestone.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 2, 0, 6, 2, 3, 10, Block.cobblestone.blockID, + Block.cobblestone.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 3, 0, 10, 7, 3, 10, Block.cobblestone.blockID, + Block.cobblestone.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 1, 2, 0, 7, 3, 0, Block.planks.blockID, + Block.planks.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 1, 2, 5, 2, 3, 5, Block.planks.blockID, + Block.planks.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 4, 1, 8, 4, 1, Block.planks.blockID, + Block.planks.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 4, 4, 3, 4, 4, Block.planks.blockID, + Block.planks.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 5, 2, 8, 5, 3, Block.planks.blockID, + Block.planks.blockID, false); + this.placeBlockAtCurrentPosition(par1World, Block.planks.blockID, 0, 0, 4, 2, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.planks.blockID, 0, 0, 4, 3, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.planks.blockID, 0, 8, 4, 2, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.planks.blockID, 0, 8, 4, 3, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.planks.blockID, 0, 8, 4, 4, par3StructureBoundingBox); + int var4 = this.getMetadataWithOffset(Block.stairsWoodOak.blockID, 3); + int var5 = this.getMetadataWithOffset(Block.stairsWoodOak.blockID, 2); + int var6; + int var7; + + for (var6 = -1; var6 <= 2; ++var6) { + for (var7 = 0; var7 <= 8; ++var7) { + this.placeBlockAtCurrentPosition(par1World, Block.stairsWoodOak.blockID, var4, var7, 4 + var6, var6, + par3StructureBoundingBox); + + if ((var6 > -1 || var7 <= 1) && (var6 > 0 || var7 <= 3) && (var6 > 1 || var7 <= 4 || var7 >= 6)) { + this.placeBlockAtCurrentPosition(par1World, Block.stairsWoodOak.blockID, var5, var7, 4 + var6, + 5 - var6, par3StructureBoundingBox); + } + } + } + + this.fillWithBlocks(par1World, par3StructureBoundingBox, 3, 4, 5, 3, 4, 10, Block.planks.blockID, + Block.planks.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 7, 4, 2, 7, 4, 10, Block.planks.blockID, + Block.planks.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 4, 5, 4, 4, 5, 10, Block.planks.blockID, + Block.planks.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 6, 5, 4, 6, 5, 10, Block.planks.blockID, + Block.planks.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 5, 6, 3, 5, 6, 10, Block.planks.blockID, + Block.planks.blockID, false); + var6 = this.getMetadataWithOffset(Block.stairsWoodOak.blockID, 0); + int var8; + + for (var7 = 4; var7 >= 1; --var7) { + this.placeBlockAtCurrentPosition(par1World, Block.planks.blockID, 0, var7, 2 + var7, 7 - var7, + par3StructureBoundingBox); + + for (var8 = 8 - var7; var8 <= 10; ++var8) { + this.placeBlockAtCurrentPosition(par1World, Block.stairsWoodOak.blockID, var6, var7, 2 + var7, var8, + par3StructureBoundingBox); + } + } + + var7 = this.getMetadataWithOffset(Block.stairsWoodOak.blockID, 1); + this.placeBlockAtCurrentPosition(par1World, Block.planks.blockID, 0, 6, 6, 3, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.planks.blockID, 0, 7, 5, 4, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.stairsWoodOak.blockID, var7, 6, 6, 4, + par3StructureBoundingBox); + int var9; + + for (var8 = 6; var8 <= 8; ++var8) { + for (var9 = 5; var9 <= 10; ++var9) { + this.placeBlockAtCurrentPosition(par1World, Block.stairsWoodOak.blockID, var7, var8, 12 - var8, var9, + par3StructureBoundingBox); + } + } + + this.placeBlockAtCurrentPosition(par1World, Block.wood.blockID, 0, 0, 2, 1, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.wood.blockID, 0, 0, 2, 4, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.thinGlass.blockID, 0, 0, 2, 2, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.thinGlass.blockID, 0, 0, 2, 3, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.wood.blockID, 0, 4, 2, 0, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.thinGlass.blockID, 0, 5, 2, 0, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.wood.blockID, 0, 6, 2, 0, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.wood.blockID, 0, 8, 2, 1, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.thinGlass.blockID, 0, 8, 2, 2, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.thinGlass.blockID, 0, 8, 2, 3, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.wood.blockID, 0, 8, 2, 4, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.planks.blockID, 0, 8, 2, 5, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.wood.blockID, 0, 8, 2, 6, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.thinGlass.blockID, 0, 8, 2, 7, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.thinGlass.blockID, 0, 8, 2, 8, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.wood.blockID, 0, 8, 2, 9, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.wood.blockID, 0, 2, 2, 6, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.thinGlass.blockID, 0, 2, 2, 7, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.thinGlass.blockID, 0, 2, 2, 8, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.wood.blockID, 0, 2, 2, 9, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.wood.blockID, 0, 4, 4, 10, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.thinGlass.blockID, 0, 5, 4, 10, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.wood.blockID, 0, 6, 4, 10, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.planks.blockID, 0, 5, 5, 10, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, 0, 0, 2, 1, 0, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, 0, 0, 2, 2, 0, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.torchWood.blockID, 0, 2, 3, 1, par3StructureBoundingBox); + this.placeDoorAtCurrentPosition(par1World, par3StructureBoundingBox, par2Random, 2, 1, 0, + this.getMetadataWithOffset(Block.doorWood.blockID, 1)); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 1, 0, -1, 3, 2, -1, 0, 0, false); + + if (this.getBlockIdAtCurrentPosition(par1World, 2, 0, -1, par3StructureBoundingBox) == 0 + && this.getBlockIdAtCurrentPosition(par1World, 2, -1, -1, par3StructureBoundingBox) != 0) { + this.placeBlockAtCurrentPosition(par1World, Block.stairsCobblestone.blockID, + this.getMetadataWithOffset(Block.stairsCobblestone.blockID, 3), 2, 0, -1, par3StructureBoundingBox); + } + + for (var8 = 0; var8 < 5; ++var8) { + for (var9 = 0; var9 < 9; ++var9) { + this.clearCurrentPositionBlocksUpwards(par1World, var9, 7, var8, par3StructureBoundingBox); + this.fillCurrentPositionBlocksDownwards(par1World, Block.cobblestone.blockID, 0, var9, -1, var8, + par3StructureBoundingBox); + } + } + + for (var8 = 5; var8 < 11; ++var8) { + for (var9 = 2; var9 < 9; ++var9) { + this.clearCurrentPositionBlocksUpwards(par1World, var9, 7, var8, par3StructureBoundingBox); + this.fillCurrentPositionBlocksDownwards(par1World, Block.cobblestone.blockID, 0, var9, -1, var8, + par3StructureBoundingBox); + } + } + + this.spawnVillagers(par1World, par3StructureBoundingBox, 4, 1, 2, 2); + return true; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ComponentVillageHouse4_Garden.java b/sp-server/src/main/java/net/minecraft/src/ComponentVillageHouse4_Garden.java new file mode 100644 index 0000000..8353004 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ComponentVillageHouse4_Garden.java @@ -0,0 +1,127 @@ +package net.minecraft.src; + +import java.util.List; +import java.util.Random; + +public class ComponentVillageHouse4_Garden extends ComponentVillage { + private int averageGroundLevel = -1; + private final boolean isRoofAccessible; + + public ComponentVillageHouse4_Garden(ComponentVillageStartPiece par1ComponentVillageStartPiece, int par2, + Random par3Random, StructureBoundingBox par4StructureBoundingBox, int par5) { + super(par1ComponentVillageStartPiece, par2); + this.coordBaseMode = par5; + this.boundingBox = par4StructureBoundingBox; + this.isRoofAccessible = par3Random.nextBoolean(); + } + + public static ComponentVillageHouse4_Garden func_74912_a(ComponentVillageStartPiece par0ComponentVillageStartPiece, + List par1List, Random par2Random, int par3, int par4, int par5, int par6, int par7) { + StructureBoundingBox var8 = StructureBoundingBox.getComponentToAddBoundingBox(par3, par4, par5, 0, 0, 0, 5, 6, + 5, par6); + return StructureComponent.findIntersecting(par1List, var8) != null ? null + : new ComponentVillageHouse4_Garden(par0ComponentVillageStartPiece, par7, par2Random, var8, par6); + } + + /** + * second Part of Structure generating, this for example places Spiderwebs, Mob + * Spawners, it closes Mineshafts at the end, it adds Fences... + */ + public boolean addComponentParts(World par1World, Random par2Random, + StructureBoundingBox par3StructureBoundingBox) { + if (this.averageGroundLevel < 0) { + this.averageGroundLevel = this.getAverageGroundLevel(par1World, par3StructureBoundingBox); + + if (this.averageGroundLevel < 0) { + return true; + } + + this.boundingBox.offset(0, this.averageGroundLevel - this.boundingBox.maxY + 6 - 1, 0); + } + + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 0, 0, 4, 0, 4, Block.cobblestone.blockID, + Block.cobblestone.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 4, 0, 4, 4, 4, Block.wood.blockID, + Block.wood.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 1, 4, 1, 3, 4, 3, Block.planks.blockID, + Block.planks.blockID, false); + this.placeBlockAtCurrentPosition(par1World, Block.cobblestone.blockID, 0, 0, 1, 0, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.cobblestone.blockID, 0, 0, 2, 0, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.cobblestone.blockID, 0, 0, 3, 0, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.cobblestone.blockID, 0, 4, 1, 0, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.cobblestone.blockID, 0, 4, 2, 0, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.cobblestone.blockID, 0, 4, 3, 0, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.cobblestone.blockID, 0, 0, 1, 4, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.cobblestone.blockID, 0, 0, 2, 4, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.cobblestone.blockID, 0, 0, 3, 4, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.cobblestone.blockID, 0, 4, 1, 4, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.cobblestone.blockID, 0, 4, 2, 4, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.cobblestone.blockID, 0, 4, 3, 4, par3StructureBoundingBox); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 1, 1, 0, 3, 3, Block.planks.blockID, + Block.planks.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 4, 1, 1, 4, 3, 3, Block.planks.blockID, + Block.planks.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 1, 1, 4, 3, 3, 4, Block.planks.blockID, + Block.planks.blockID, false); + this.placeBlockAtCurrentPosition(par1World, Block.thinGlass.blockID, 0, 0, 2, 2, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.thinGlass.blockID, 0, 2, 2, 4, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.thinGlass.blockID, 0, 4, 2, 2, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.planks.blockID, 0, 1, 1, 0, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.planks.blockID, 0, 1, 2, 0, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.planks.blockID, 0, 1, 3, 0, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.planks.blockID, 0, 2, 3, 0, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.planks.blockID, 0, 3, 3, 0, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.planks.blockID, 0, 3, 2, 0, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.planks.blockID, 0, 3, 1, 0, par3StructureBoundingBox); + + if (this.getBlockIdAtCurrentPosition(par1World, 2, 0, -1, par3StructureBoundingBox) == 0 + && this.getBlockIdAtCurrentPosition(par1World, 2, -1, -1, par3StructureBoundingBox) != 0) { + this.placeBlockAtCurrentPosition(par1World, Block.stairsCobblestone.blockID, + this.getMetadataWithOffset(Block.stairsCobblestone.blockID, 3), 2, 0, -1, par3StructureBoundingBox); + } + + this.fillWithBlocks(par1World, par3StructureBoundingBox, 1, 1, 1, 3, 3, 3, 0, 0, false); + + if (this.isRoofAccessible) { + this.placeBlockAtCurrentPosition(par1World, Block.fence.blockID, 0, 0, 5, 0, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.fence.blockID, 0, 1, 5, 0, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.fence.blockID, 0, 2, 5, 0, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.fence.blockID, 0, 3, 5, 0, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.fence.blockID, 0, 4, 5, 0, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.fence.blockID, 0, 0, 5, 4, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.fence.blockID, 0, 1, 5, 4, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.fence.blockID, 0, 2, 5, 4, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.fence.blockID, 0, 3, 5, 4, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.fence.blockID, 0, 4, 5, 4, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.fence.blockID, 0, 4, 5, 1, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.fence.blockID, 0, 4, 5, 2, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.fence.blockID, 0, 4, 5, 3, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.fence.blockID, 0, 0, 5, 1, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.fence.blockID, 0, 0, 5, 2, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.fence.blockID, 0, 0, 5, 3, par3StructureBoundingBox); + } + + int var4; + + if (this.isRoofAccessible) { + var4 = this.getMetadataWithOffset(Block.ladder.blockID, 3); + this.placeBlockAtCurrentPosition(par1World, Block.ladder.blockID, var4, 3, 1, 3, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.ladder.blockID, var4, 3, 2, 3, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.ladder.blockID, var4, 3, 3, 3, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.ladder.blockID, var4, 3, 4, 3, par3StructureBoundingBox); + } + + this.placeBlockAtCurrentPosition(par1World, Block.torchWood.blockID, 0, 2, 3, 1, par3StructureBoundingBox); + + for (var4 = 0; var4 < 5; ++var4) { + for (int var5 = 0; var5 < 5; ++var5) { + this.clearCurrentPositionBlocksUpwards(par1World, var5, 6, var4, par3StructureBoundingBox); + this.fillCurrentPositionBlocksDownwards(par1World, Block.cobblestone.blockID, 0, var5, -1, var4, + par3StructureBoundingBox); + } + } + + this.spawnVillagers(par1World, par3StructureBoundingBox, 1, 1, 2, 1); + return true; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ComponentVillagePathGen.java b/sp-server/src/main/java/net/minecraft/src/ComponentVillagePathGen.java new file mode 100644 index 0000000..0556bd2 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ComponentVillagePathGen.java @@ -0,0 +1,142 @@ +package net.minecraft.src; + +import java.util.List; +import java.util.Random; + +public class ComponentVillagePathGen extends ComponentVillageRoadPiece { + private int averageGroundLevel; + + public ComponentVillagePathGen(ComponentVillageStartPiece par1ComponentVillageStartPiece, int par2, + Random par3Random, StructureBoundingBox par4StructureBoundingBox, int par5) { + super(par1ComponentVillageStartPiece, par2); + this.coordBaseMode = par5; + this.boundingBox = par4StructureBoundingBox; + this.averageGroundLevel = Math.max(par4StructureBoundingBox.getXSize(), par4StructureBoundingBox.getZSize()); + } + + /** + * Initiates construction of the Structure Component picked, at the current + * Location of StructGen + */ + public void buildComponent(StructureComponent par1StructureComponent, List par2List, Random par3Random) { + boolean var4 = false; + int var5; + StructureComponent var6; + + for (var5 = par3Random.nextInt(5); var5 < this.averageGroundLevel - 8; var5 += 2 + par3Random.nextInt(5)) { + var6 = this.getNextComponentNN((ComponentVillageStartPiece) par1StructureComponent, par2List, par3Random, 0, + var5); + + if (var6 != null) { + var5 += Math.max(var6.boundingBox.getXSize(), var6.boundingBox.getZSize()); + var4 = true; + } + } + + for (var5 = par3Random.nextInt(5); var5 < this.averageGroundLevel - 8; var5 += 2 + par3Random.nextInt(5)) { + var6 = this.getNextComponentPP((ComponentVillageStartPiece) par1StructureComponent, par2List, par3Random, 0, + var5); + + if (var6 != null) { + var5 += Math.max(var6.boundingBox.getXSize(), var6.boundingBox.getZSize()); + var4 = true; + } + } + + if (var4 && par3Random.nextInt(3) > 0) { + switch (this.coordBaseMode) { + case 0: + StructureVillagePieces.getNextStructureComponentVillagePath( + (ComponentVillageStartPiece) par1StructureComponent, par2List, par3Random, + this.boundingBox.minX - 1, this.boundingBox.minY, this.boundingBox.maxZ - 2, 1, + this.getComponentType()); + break; + + case 1: + StructureVillagePieces.getNextStructureComponentVillagePath( + (ComponentVillageStartPiece) par1StructureComponent, par2List, par3Random, + this.boundingBox.minX, this.boundingBox.minY, this.boundingBox.minZ - 1, 2, + this.getComponentType()); + break; + + case 2: + StructureVillagePieces.getNextStructureComponentVillagePath( + (ComponentVillageStartPiece) par1StructureComponent, par2List, par3Random, + this.boundingBox.minX - 1, this.boundingBox.minY, this.boundingBox.minZ, 1, + this.getComponentType()); + break; + + case 3: + StructureVillagePieces.getNextStructureComponentVillagePath( + (ComponentVillageStartPiece) par1StructureComponent, par2List, par3Random, + this.boundingBox.maxX - 2, this.boundingBox.minY, this.boundingBox.minZ - 1, 2, + this.getComponentType()); + } + } + + if (var4 && par3Random.nextInt(3) > 0) { + switch (this.coordBaseMode) { + case 0: + StructureVillagePieces.getNextStructureComponentVillagePath( + (ComponentVillageStartPiece) par1StructureComponent, par2List, par3Random, + this.boundingBox.maxX + 1, this.boundingBox.minY, this.boundingBox.maxZ - 2, 3, + this.getComponentType()); + break; + + case 1: + StructureVillagePieces.getNextStructureComponentVillagePath( + (ComponentVillageStartPiece) par1StructureComponent, par2List, par3Random, + this.boundingBox.minX, this.boundingBox.minY, this.boundingBox.maxZ + 1, 0, + this.getComponentType()); + break; + + case 2: + StructureVillagePieces.getNextStructureComponentVillagePath( + (ComponentVillageStartPiece) par1StructureComponent, par2List, par3Random, + this.boundingBox.maxX + 1, this.boundingBox.minY, this.boundingBox.minZ, 3, + this.getComponentType()); + break; + + case 3: + StructureVillagePieces.getNextStructureComponentVillagePath( + (ComponentVillageStartPiece) par1StructureComponent, par2List, par3Random, + this.boundingBox.maxX - 2, this.boundingBox.minY, this.boundingBox.maxZ + 1, 0, + this.getComponentType()); + } + } + } + + public static StructureBoundingBox func_74933_a(ComponentVillageStartPiece par0ComponentVillageStartPiece, + List par1List, Random par2Random, int par3, int par4, int par5, int par6) { + for (int var7 = 7 * MathHelper.getRandomIntegerInRange(par2Random, 3, 5); var7 >= 7; var7 -= 7) { + StructureBoundingBox var8 = StructureBoundingBox.getComponentToAddBoundingBox(par3, par4, par5, 0, 0, 0, 3, + 3, var7, par6); + + if (StructureComponent.findIntersecting(par1List, var8) == null) { + return var8; + } + } + + return null; + } + + /** + * second Part of Structure generating, this for example places Spiderwebs, Mob + * Spawners, it closes Mineshafts at the end, it adds Fences... + */ + public boolean addComponentParts(World par1World, Random par2Random, + StructureBoundingBox par3StructureBoundingBox) { + int var4 = this.getBiomeSpecificBlock(Block.gravel.blockID, 0); + + for (int var5 = this.boundingBox.minX; var5 <= this.boundingBox.maxX; ++var5) { + for (int var6 = this.boundingBox.minZ; var6 <= this.boundingBox.maxZ; ++var6) { + if (par3StructureBoundingBox.isVecInside(var5, 64, var6)) { + int var7 = par1World.getTopSolidOrLiquidBlock(var5, var6) - 1; + par1World.setBlock(var5, var7, var6, var4, 0, 2); + } + } + } + + return true; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ComponentVillageRoadPiece.java b/sp-server/src/main/java/net/minecraft/src/ComponentVillageRoadPiece.java new file mode 100644 index 0000000..636250e --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ComponentVillageRoadPiece.java @@ -0,0 +1,7 @@ +package net.minecraft.src; + +public abstract class ComponentVillageRoadPiece extends ComponentVillage { + protected ComponentVillageRoadPiece(ComponentVillageStartPiece par1ComponentVillageStartPiece, int par2) { + super(par1ComponentVillageStartPiece, par2); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ComponentVillageStartPiece.java b/sp-server/src/main/java/net/minecraft/src/ComponentVillageStartPiece.java new file mode 100644 index 0000000..4acfa2f --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ComponentVillageStartPiece.java @@ -0,0 +1,38 @@ +package net.minecraft.src; + +import java.util.ArrayList; +import java.util.Random; + +public class ComponentVillageStartPiece extends ComponentVillageWell { + public final WorldChunkManager worldChunkMngr; + + /** Boolean that determines if the village is in a desert or not. */ + public final boolean inDesert; + + /** World terrain type, 0 for normal, 1 for flap map */ + public final int terrainType; + public StructureVillagePieceWeight structVillagePieceWeight; + + /** + * Contains List of all spawnable Structure Piece Weights. If no more Pieces of + * a type can be spawned, they are removed from this list + */ + public ArrayList structureVillageWeightedPieceList; + public ArrayList field_74932_i = new ArrayList(); + public ArrayList field_74930_j = new ArrayList(); + + public ComponentVillageStartPiece(WorldChunkManager par1WorldChunkManager, int par2, Random par3Random, int par4, + int par5, ArrayList par6ArrayList, int par7) { + super((ComponentVillageStartPiece) null, 0, par3Random, par4, par5); + this.worldChunkMngr = par1WorldChunkManager; + this.structureVillageWeightedPieceList = par6ArrayList; + this.terrainType = par7; + BiomeGenBase var8 = par1WorldChunkManager.getBiomeGenAt(par4, par5); + this.inDesert = var8 == BiomeGenBase.desert || var8 == BiomeGenBase.desertHills; + this.startPiece = this; + } + + public WorldChunkManager getWorldChunkManager() { + return this.worldChunkMngr; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ComponentVillageTorch.java b/sp-server/src/main/java/net/minecraft/src/ComponentVillageTorch.java new file mode 100644 index 0000000..be48d9c --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ComponentVillageTorch.java @@ -0,0 +1,50 @@ +package net.minecraft.src; + +import java.util.List; +import java.util.Random; + +public class ComponentVillageTorch extends ComponentVillage { + private int averageGroundLevel = -1; + + public ComponentVillageTorch(ComponentVillageStartPiece par1ComponentVillageStartPiece, int par2, Random par3Random, + StructureBoundingBox par4StructureBoundingBox, int par5) { + super(par1ComponentVillageStartPiece, par2); + this.coordBaseMode = par5; + this.boundingBox = par4StructureBoundingBox; + } + + public static StructureBoundingBox func_74904_a(ComponentVillageStartPiece par0ComponentVillageStartPiece, + List par1List, Random par2Random, int par3, int par4, int par5, int par6) { + StructureBoundingBox var7 = StructureBoundingBox.getComponentToAddBoundingBox(par3, par4, par5, 0, 0, 0, 3, 4, + 2, par6); + return StructureComponent.findIntersecting(par1List, var7) != null ? null : var7; + } + + /** + * second Part of Structure generating, this for example places Spiderwebs, Mob + * Spawners, it closes Mineshafts at the end, it adds Fences... + */ + public boolean addComponentParts(World par1World, Random par2Random, + StructureBoundingBox par3StructureBoundingBox) { + if (this.averageGroundLevel < 0) { + this.averageGroundLevel = this.getAverageGroundLevel(par1World, par3StructureBoundingBox); + + if (this.averageGroundLevel < 0) { + return true; + } + + this.boundingBox.offset(0, this.averageGroundLevel - this.boundingBox.maxY + 4 - 1, 0); + } + + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 0, 0, 2, 3, 1, 0, 0, false); + this.placeBlockAtCurrentPosition(par1World, Block.fence.blockID, 0, 1, 0, 0, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.fence.blockID, 0, 1, 1, 0, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.fence.blockID, 0, 1, 2, 0, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.cloth.blockID, 15, 1, 3, 0, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.torchWood.blockID, 0, 0, 3, 0, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.torchWood.blockID, 0, 1, 3, 1, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.torchWood.blockID, 0, 2, 3, 0, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.torchWood.blockID, 0, 1, 3, -1, par3StructureBoundingBox); + return true; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ComponentVillageWell.java b/sp-server/src/main/java/net/minecraft/src/ComponentVillageWell.java new file mode 100644 index 0000000..203f5c3 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ComponentVillageWell.java @@ -0,0 +1,90 @@ +package net.minecraft.src; + +import java.util.List; +import java.util.Random; + +public class ComponentVillageWell extends ComponentVillage { + private final boolean field_74924_a = true; + private int averageGroundLevel = -1; + + public ComponentVillageWell(ComponentVillageStartPiece par1ComponentVillageStartPiece, int par2, Random par3Random, + int par4, int par5) { + super(par1ComponentVillageStartPiece, par2); + this.coordBaseMode = par3Random.nextInt(4); + + switch (this.coordBaseMode) { + case 0: + case 2: + this.boundingBox = new StructureBoundingBox(par4, 64, par5, par4 + 6 - 1, 78, par5 + 6 - 1); + break; + + default: + this.boundingBox = new StructureBoundingBox(par4, 64, par5, par4 + 6 - 1, 78, par5 + 6 - 1); + } + } + + /** + * Initiates construction of the Structure Component picked, at the current + * Location of StructGen + */ + public void buildComponent(StructureComponent par1StructureComponent, List par2List, Random par3Random) { + StructureVillagePieces.getNextStructureComponentVillagePath((ComponentVillageStartPiece) par1StructureComponent, + par2List, par3Random, this.boundingBox.minX - 1, this.boundingBox.maxY - 4, this.boundingBox.minZ + 1, + 1, this.getComponentType()); + StructureVillagePieces.getNextStructureComponentVillagePath((ComponentVillageStartPiece) par1StructureComponent, + par2List, par3Random, this.boundingBox.maxX + 1, this.boundingBox.maxY - 4, this.boundingBox.minZ + 1, + 3, this.getComponentType()); + StructureVillagePieces.getNextStructureComponentVillagePath((ComponentVillageStartPiece) par1StructureComponent, + par2List, par3Random, this.boundingBox.minX + 1, this.boundingBox.maxY - 4, this.boundingBox.minZ - 1, + 2, this.getComponentType()); + StructureVillagePieces.getNextStructureComponentVillagePath((ComponentVillageStartPiece) par1StructureComponent, + par2List, par3Random, this.boundingBox.minX + 1, this.boundingBox.maxY - 4, this.boundingBox.maxZ + 1, + 0, this.getComponentType()); + } + + /** + * second Part of Structure generating, this for example places Spiderwebs, Mob + * Spawners, it closes Mineshafts at the end, it adds Fences... + */ + public boolean addComponentParts(World par1World, Random par2Random, + StructureBoundingBox par3StructureBoundingBox) { + if (this.averageGroundLevel < 0) { + this.averageGroundLevel = this.getAverageGroundLevel(par1World, par3StructureBoundingBox); + + if (this.averageGroundLevel < 0) { + return true; + } + + this.boundingBox.offset(0, this.averageGroundLevel - this.boundingBox.maxY + 3, 0); + } + + this.fillWithBlocks(par1World, par3StructureBoundingBox, 1, 0, 1, 4, 12, 4, Block.cobblestone.blockID, + Block.waterMoving.blockID, false); + this.placeBlockAtCurrentPosition(par1World, 0, 0, 2, 12, 2, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, 0, 0, 3, 12, 2, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, 0, 0, 2, 12, 3, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, 0, 0, 3, 12, 3, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.fence.blockID, 0, 1, 13, 1, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.fence.blockID, 0, 1, 14, 1, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.fence.blockID, 0, 4, 13, 1, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.fence.blockID, 0, 4, 14, 1, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.fence.blockID, 0, 1, 13, 4, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.fence.blockID, 0, 1, 14, 4, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.fence.blockID, 0, 4, 13, 4, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.fence.blockID, 0, 4, 14, 4, par3StructureBoundingBox); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 1, 15, 1, 4, 15, 4, Block.cobblestone.blockID, + Block.cobblestone.blockID, false); + + for (int var4 = 0; var4 <= 5; ++var4) { + for (int var5 = 0; var5 <= 5; ++var5) { + if (var5 == 0 || var5 == 5 || var4 == 0 || var4 == 5) { + this.placeBlockAtCurrentPosition(par1World, Block.gravel.blockID, 0, var5, 11, var4, + par3StructureBoundingBox); + this.clearCurrentPositionBlocksUpwards(par1World, var5, 12, var4, par3StructureBoundingBox); + } + } + } + + return true; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ComponentVillageWoodHut.java b/sp-server/src/main/java/net/minecraft/src/ComponentVillageWoodHut.java new file mode 100644 index 0000000..04a69a7 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ComponentVillageWoodHut.java @@ -0,0 +1,117 @@ +package net.minecraft.src; + +import java.util.List; +import java.util.Random; + +public class ComponentVillageWoodHut extends ComponentVillage { + private int averageGroundLevel = -1; + private final boolean isTallHouse; + private final int tablePosition; + + public ComponentVillageWoodHut(ComponentVillageStartPiece par1ComponentVillageStartPiece, int par2, + Random par3Random, StructureBoundingBox par4StructureBoundingBox, int par5) { + super(par1ComponentVillageStartPiece, par2); + this.coordBaseMode = par5; + this.boundingBox = par4StructureBoundingBox; + this.isTallHouse = par3Random.nextBoolean(); + this.tablePosition = par3Random.nextInt(3); + } + + public static ComponentVillageWoodHut func_74908_a(ComponentVillageStartPiece par0ComponentVillageStartPiece, + List par1List, Random par2Random, int par3, int par4, int par5, int par6, int par7) { + StructureBoundingBox var8 = StructureBoundingBox.getComponentToAddBoundingBox(par3, par4, par5, 0, 0, 0, 4, 6, + 5, par6); + return canVillageGoDeeper(var8) && StructureComponent.findIntersecting(par1List, var8) == null + ? new ComponentVillageWoodHut(par0ComponentVillageStartPiece, par7, par2Random, var8, par6) + : null; + } + + /** + * second Part of Structure generating, this for example places Spiderwebs, Mob + * Spawners, it closes Mineshafts at the end, it adds Fences... + */ + public boolean addComponentParts(World par1World, Random par2Random, + StructureBoundingBox par3StructureBoundingBox) { + if (this.averageGroundLevel < 0) { + this.averageGroundLevel = this.getAverageGroundLevel(par1World, par3StructureBoundingBox); + + if (this.averageGroundLevel < 0) { + return true; + } + + this.boundingBox.offset(0, this.averageGroundLevel - this.boundingBox.maxY + 6 - 1, 0); + } + + this.fillWithBlocks(par1World, par3StructureBoundingBox, 1, 1, 1, 3, 5, 4, 0, 0, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 0, 0, 3, 0, 4, Block.cobblestone.blockID, + Block.cobblestone.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 1, 0, 1, 2, 0, 3, Block.dirt.blockID, + Block.dirt.blockID, false); + + if (this.isTallHouse) { + this.fillWithBlocks(par1World, par3StructureBoundingBox, 1, 4, 1, 2, 4, 3, Block.wood.blockID, + Block.wood.blockID, false); + } else { + this.fillWithBlocks(par1World, par3StructureBoundingBox, 1, 5, 1, 2, 5, 3, Block.wood.blockID, + Block.wood.blockID, false); + } + + this.placeBlockAtCurrentPosition(par1World, Block.wood.blockID, 0, 1, 4, 0, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.wood.blockID, 0, 2, 4, 0, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.wood.blockID, 0, 1, 4, 4, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.wood.blockID, 0, 2, 4, 4, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.wood.blockID, 0, 0, 4, 1, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.wood.blockID, 0, 0, 4, 2, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.wood.blockID, 0, 0, 4, 3, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.wood.blockID, 0, 3, 4, 1, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.wood.blockID, 0, 3, 4, 2, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.wood.blockID, 0, 3, 4, 3, par3StructureBoundingBox); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 1, 0, 0, 3, 0, Block.wood.blockID, + Block.wood.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 3, 1, 0, 3, 3, 0, Block.wood.blockID, + Block.wood.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 1, 4, 0, 3, 4, Block.wood.blockID, + Block.wood.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 3, 1, 4, 3, 3, 4, Block.wood.blockID, + Block.wood.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 0, 1, 1, 0, 3, 3, Block.planks.blockID, + Block.planks.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 3, 1, 1, 3, 3, 3, Block.planks.blockID, + Block.planks.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 1, 1, 0, 2, 3, 0, Block.planks.blockID, + Block.planks.blockID, false); + this.fillWithBlocks(par1World, par3StructureBoundingBox, 1, 1, 4, 2, 3, 4, Block.planks.blockID, + Block.planks.blockID, false); + this.placeBlockAtCurrentPosition(par1World, Block.thinGlass.blockID, 0, 0, 2, 2, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.thinGlass.blockID, 0, 3, 2, 2, par3StructureBoundingBox); + + if (this.tablePosition > 0) { + this.placeBlockAtCurrentPosition(par1World, Block.fence.blockID, 0, this.tablePosition, 1, 3, + par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, Block.pressurePlatePlanks.blockID, 0, this.tablePosition, 2, 3, + par3StructureBoundingBox); + } + + this.placeBlockAtCurrentPosition(par1World, 0, 0, 1, 1, 0, par3StructureBoundingBox); + this.placeBlockAtCurrentPosition(par1World, 0, 0, 1, 2, 0, par3StructureBoundingBox); + this.placeDoorAtCurrentPosition(par1World, par3StructureBoundingBox, par2Random, 1, 1, 0, + this.getMetadataWithOffset(Block.doorWood.blockID, 1)); + + if (this.getBlockIdAtCurrentPosition(par1World, 1, 0, -1, par3StructureBoundingBox) == 0 + && this.getBlockIdAtCurrentPosition(par1World, 1, -1, -1, par3StructureBoundingBox) != 0) { + this.placeBlockAtCurrentPosition(par1World, Block.stairsCobblestone.blockID, + this.getMetadataWithOffset(Block.stairsCobblestone.blockID, 3), 1, 0, -1, par3StructureBoundingBox); + } + + for (int var4 = 0; var4 < 5; ++var4) { + for (int var5 = 0; var5 < 4; ++var5) { + this.clearCurrentPositionBlocksUpwards(par1World, var5, 6, var4, par3StructureBoundingBox); + this.fillCurrentPositionBlocksDownwards(par1World, Block.cobblestone.blockID, 0, var5, -1, var4, + par3StructureBoundingBox); + } + } + + this.spawnVillagers(par1World, par3StructureBoundingBox, 1, 1, 2, 1); + return true; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CompressedStreamTools.java b/sp-server/src/main/java/net/minecraft/src/CompressedStreamTools.java new file mode 100644 index 0000000..d9fa175 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CompressedStreamTools.java @@ -0,0 +1,90 @@ +package net.minecraft.src; + +import java.io.BufferedInputStream; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.DataInput; +import java.io.DataInputStream; +import java.io.DataOutput; +import java.io.DataOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.zip.GZIPInputStream; +import java.util.zip.GZIPOutputStream; + +public class CompressedStreamTools { + /** + * Load the gzipped compound from the inputstream. + */ + public static NBTTagCompound readCompressed(InputStream par0InputStream) throws IOException { + DataInputStream var1 = new DataInputStream(new BufferedInputStream(new GZIPInputStream(par0InputStream))); + NBTTagCompound var2; + + try { + var2 = read(var1); + } finally { + var1.close(); + } + + return var2; + } + + /** + * Write the compound, gzipped, to the outputstream. + */ + public static void writeCompressed(NBTTagCompound par0NBTTagCompound, OutputStream par1OutputStream) + throws IOException { + DataOutputStream var2 = new DataOutputStream(new GZIPOutputStream(par1OutputStream)); + + try { + write(par0NBTTagCompound, var2); + } finally { + var2.close(); + } + } + + public static NBTTagCompound decompress(byte[] par0ArrayOfByte) throws IOException { + DataInputStream var1 = new DataInputStream( + new BufferedInputStream(new GZIPInputStream(new ByteArrayInputStream(par0ArrayOfByte)))); + NBTTagCompound var2; + + try { + var2 = read(var1); + } finally { + var1.close(); + } + + return var2; + } + + public static byte[] compress(NBTTagCompound par0NBTTagCompound) throws IOException { + ByteArrayOutputStream var1 = new ByteArrayOutputStream(); + DataOutputStream var2 = new DataOutputStream(new GZIPOutputStream(var1)); + + try { + write(par0NBTTagCompound, var2); + } finally { + var2.close(); + } + + return var1.toByteArray(); + } + + /** + * Reads from a CompressedStream. + */ + public static NBTTagCompound read(DataInput par0DataInput) throws IOException { + NBTBase var1 = NBTBase.readNamedTag(par0DataInput); + + if (var1 instanceof NBTTagCompound) { + return (NBTTagCompound) var1; + } else { + throw new IOException("Root tag must be a named compound tag"); + } + } + + public static void write(NBTTagCompound par0NBTTagCompound, DataOutput par1DataOutput) throws IOException { + NBTBase.writeNamedTag(par0NBTTagCompound, par1DataOutput); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/Container.java b/sp-server/src/main/java/net/minecraft/src/Container.java new file mode 100644 index 0000000..ffb2048 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/Container.java @@ -0,0 +1,600 @@ +package net.minecraft.src; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +public abstract class Container { + /** the list of all items(stacks) for the corresponding slot */ + public List inventoryItemStacks = new ArrayList(); + + /** the list of all slots in the inventory */ + public List inventorySlots = new ArrayList(); + public int windowId = 0; + private short transactionID = 0; + private int field_94535_f = -1; + private int field_94536_g = 0; + private final Set field_94537_h = new HashSet(); + + /** + * list of all people that need to be notified when this craftinventory changes + */ + protected List crafters = new ArrayList(); + private Set playerList = new HashSet(); + + /** + * Adds an item slot to this container + */ + protected Slot addSlotToContainer(Slot par1Slot) { + par1Slot.slotNumber = this.inventorySlots.size(); + this.inventorySlots.add(par1Slot); + this.inventoryItemStacks.add((Object) null); + return par1Slot; + } + + public void onCraftGuiOpened(ICrafting par1ICrafting) { + if (this.crafters.contains(par1ICrafting)) { + throw new IllegalArgumentException("Listener already listening"); + } else { + this.crafters.add(par1ICrafting); + par1ICrafting.updateCraftingInventory(this, this.getInventory()); + this.detectAndSendChanges(); + } + } + + /** + * returns a list if itemStacks, for each slot. + */ + public List getInventory() { + ArrayList var1 = new ArrayList(); + + for (int var2 = 0; var2 < this.inventorySlots.size(); ++var2) { + var1.add(((Slot) this.inventorySlots.get(var2)).getStack()); + } + + return var1; + } + + /** + * Looks for changes made in the container, sends them to every listener. + */ + public void detectAndSendChanges() { + for (int var1 = 0; var1 < this.inventorySlots.size(); ++var1) { + ItemStack var2 = ((Slot) this.inventorySlots.get(var1)).getStack(); + ItemStack var3 = (ItemStack) this.inventoryItemStacks.get(var1); + + if (!ItemStack.areItemStacksEqual(var3, var2)) { + var3 = var2 == null ? null : var2.copy(); + this.inventoryItemStacks.set(var1, var3); + + for (int var4 = 0; var4 < this.crafters.size(); ++var4) { + ((ICrafting) this.crafters.get(var4)).sendSlotContents(this, var1, var3); + } + } + } + } + + /** + * enchants the item on the table using the specified slot; also deducts XP from + * player + */ + public boolean enchantItem(EntityPlayer par1EntityPlayer, int par2) { + return false; + } + + public Slot getSlotFromInventory(IInventory par1IInventory, int par2) { + for (int var3 = 0; var3 < this.inventorySlots.size(); ++var3) { + Slot var4 = (Slot) this.inventorySlots.get(var3); + + if (var4.isHere(par1IInventory, par2)) { + return var4; + } + } + + return null; + } + + public Slot getSlot(int par1) { + return (Slot) this.inventorySlots.get(par1); + } + + /** + * Take a stack from the specified inventory slot. + */ + public ItemStack transferStackInSlot(EntityPlayer par1EntityPlayer, int par2) { + Slot var3 = (Slot) this.inventorySlots.get(par2); + return var3 != null ? var3.getStack() : null; + } + + public ItemStack slotClick(int par1, int par2, int par3, EntityPlayer par4EntityPlayer) { + ItemStack var5 = null; + InventoryPlayer var6 = par4EntityPlayer.inventory; + int var9; + ItemStack var17; + + if (par3 == 5) { + int var7 = this.field_94536_g; + this.field_94536_g = func_94532_c(par2); + + if ((var7 != 1 || this.field_94536_g != 2) && var7 != this.field_94536_g) { + this.func_94533_d(); + } else if (var6.getItemStack() == null) { + this.func_94533_d(); + } else if (this.field_94536_g == 0) { + this.field_94535_f = func_94529_b(par2); + + if (func_94528_d(this.field_94535_f)) { + this.field_94536_g = 1; + this.field_94537_h.clear(); + } else { + this.func_94533_d(); + } + } else if (this.field_94536_g == 1) { + Slot var8 = (Slot) this.inventorySlots.get(par1); + + if (var8 != null && func_94527_a(var8, var6.getItemStack(), true) + && var8.isItemValid(var6.getItemStack()) + && var6.getItemStack().stackSize > this.field_94537_h.size() && this.func_94531_b(var8)) { + this.field_94537_h.add(var8); + } + } else if (this.field_94536_g == 2) { + if (!this.field_94537_h.isEmpty()) { + var17 = var6.getItemStack().copy(); + var9 = var6.getItemStack().stackSize; + Iterator var10 = this.field_94537_h.iterator(); + + while (var10.hasNext()) { + Slot var11 = (Slot) var10.next(); + + if (var11 != null && func_94527_a(var11, var6.getItemStack(), true) + && var11.isItemValid(var6.getItemStack()) + && var6.getItemStack().stackSize >= this.field_94537_h.size() + && this.func_94531_b(var11)) { + ItemStack var12 = var17.copy(); + int var13 = var11.getHasStack() ? var11.getStack().stackSize : 0; + func_94525_a(this.field_94537_h, this.field_94535_f, var12, var13); + + if (var12.stackSize > var12.getMaxStackSize()) { + var12.stackSize = var12.getMaxStackSize(); + } + + if (var12.stackSize > var11.getSlotStackLimit()) { + var12.stackSize = var11.getSlotStackLimit(); + } + + var9 -= var12.stackSize - var13; + var11.putStack(var12); + } + } + + var17.stackSize = var9; + + if (var17.stackSize <= 0) { + var17 = null; + } + + var6.setItemStack(var17); + } + + this.func_94533_d(); + } else { + this.func_94533_d(); + } + } else if (this.field_94536_g != 0) { + this.func_94533_d(); + } else { + Slot var16; + int var19; + ItemStack var22; + + if ((par3 == 0 || par3 == 1) && (par2 == 0 || par2 == 1)) { + if (par1 == -999) { + if (var6.getItemStack() != null && par1 == -999) { + if (par2 == 0) { + par4EntityPlayer.dropPlayerItem(var6.getItemStack()); + var6.setItemStack((ItemStack) null); + } + + if (par2 == 1) { + par4EntityPlayer.dropPlayerItem(var6.getItemStack().splitStack(1)); + + if (var6.getItemStack().stackSize == 0) { + var6.setItemStack((ItemStack) null); + } + } + } + } else if (par3 == 1) { + if (par1 < 0) { + return null; + } + + var16 = (Slot) this.inventorySlots.get(par1); + + if (var16 != null && var16.canTakeStack(par4EntityPlayer)) { + var17 = this.transferStackInSlot(par4EntityPlayer, par1); + + if (var17 != null) { + var9 = var17.itemID; + var5 = var17.copy(); + + if (var16 != null && var16.getStack() != null && var16.getStack().itemID == var9) { + this.retrySlotClick(par1, par2, true, par4EntityPlayer); + } + } + } + } else { + if (par1 < 0) { + return null; + } + + var16 = (Slot) this.inventorySlots.get(par1); + + if (var16 != null) { + var17 = var16.getStack(); + ItemStack var20 = var6.getItemStack(); + + if (var17 != null) { + var5 = var17.copy(); + } + + if (var17 == null) { + if (var20 != null && var16.isItemValid(var20)) { + var19 = par2 == 0 ? var20.stackSize : 1; + + if (var19 > var16.getSlotStackLimit()) { + var19 = var16.getSlotStackLimit(); + } + + var16.putStack(var20.splitStack(var19)); + + if (var20.stackSize == 0) { + var6.setItemStack((ItemStack) null); + } + } + } else if (var16.canTakeStack(par4EntityPlayer)) { + if (var20 == null) { + var19 = par2 == 0 ? var17.stackSize : (var17.stackSize + 1) / 2; + var22 = var16.decrStackSize(var19); + var6.setItemStack(var22); + + if (var17.stackSize == 0) { + var16.putStack((ItemStack) null); + } + + var16.onPickupFromSlot(par4EntityPlayer, var6.getItemStack()); + } else if (var16.isItemValid(var20)) { + if (var17.itemID == var20.itemID && var17.getItemDamage() == var20.getItemDamage() + && ItemStack.areItemStackTagsEqual(var17, var20)) { + var19 = par2 == 0 ? var20.stackSize : 1; + + if (var19 > var16.getSlotStackLimit() - var17.stackSize) { + var19 = var16.getSlotStackLimit() - var17.stackSize; + } + + if (var19 > var20.getMaxStackSize() - var17.stackSize) { + var19 = var20.getMaxStackSize() - var17.stackSize; + } + + var20.splitStack(var19); + + if (var20.stackSize == 0) { + var6.setItemStack((ItemStack) null); + } + + var17.stackSize += var19; + } else if (var20.stackSize <= var16.getSlotStackLimit()) { + var16.putStack(var20); + var6.setItemStack(var17); + } + } else if (var17.itemID == var20.itemID && var20.getMaxStackSize() > 1 + && (!var17.getHasSubtypes() || var17.getItemDamage() == var20.getItemDamage()) + && ItemStack.areItemStackTagsEqual(var17, var20)) { + var19 = var17.stackSize; + + if (var19 > 0 && var19 + var20.stackSize <= var20.getMaxStackSize()) { + var20.stackSize += var19; + var17 = var16.decrStackSize(var19); + + if (var17.stackSize == 0) { + var16.putStack((ItemStack) null); + } + + var16.onPickupFromSlot(par4EntityPlayer, var6.getItemStack()); + } + } + } + + var16.onSlotChanged(); + } + } + } else if (par3 == 2 && par2 >= 0 && par2 < 9) { + var16 = (Slot) this.inventorySlots.get(par1); + + if (var16.canTakeStack(par4EntityPlayer)) { + var17 = var6.getStackInSlot(par2); + boolean var18 = var17 == null || var16.inventory == var6 && var16.isItemValid(var17); + var19 = -1; + + if (!var18) { + var19 = var6.getFirstEmptyStack(); + var18 |= var19 > -1; + } + + if (var16.getHasStack() && var18) { + var22 = var16.getStack(); + var6.setInventorySlotContents(par2, var22.copy()); + + if ((var16.inventory != var6 || !var16.isItemValid(var17)) && var17 != null) { + if (var19 > -1) { + var6.addItemStackToInventory(var17); + var16.decrStackSize(var22.stackSize); + var16.putStack((ItemStack) null); + var16.onPickupFromSlot(par4EntityPlayer, var22); + } + } else { + var16.decrStackSize(var22.stackSize); + var16.putStack(var17); + var16.onPickupFromSlot(par4EntityPlayer, var22); + } + } else if (!var16.getHasStack() && var17 != null && var16.isItemValid(var17)) { + var6.setInventorySlotContents(par2, (ItemStack) null); + var16.putStack(var17); + } + } + } else if (par3 == 3 && par4EntityPlayer.capabilities.isCreativeMode && var6.getItemStack() == null + && par1 >= 0) { + var16 = (Slot) this.inventorySlots.get(par1); + + if (var16 != null && var16.getHasStack()) { + var17 = var16.getStack().copy(); + var17.stackSize = var17.getMaxStackSize(); + var6.setItemStack(var17); + } + } else if (par3 == 4 && var6.getItemStack() == null && par1 >= 0) { + var16 = (Slot) this.inventorySlots.get(par1); + + if (var16 != null && var16.getHasStack() && var16.canTakeStack(par4EntityPlayer)) { + var17 = var16.decrStackSize(par2 == 0 ? 1 : var16.getStack().stackSize); + var16.onPickupFromSlot(par4EntityPlayer, var17); + par4EntityPlayer.dropPlayerItem(var17); + } + } else if (par3 == 6 && par1 >= 0) { + var16 = (Slot) this.inventorySlots.get(par1); + var17 = var6.getItemStack(); + + if (var17 != null && (var16 == null || !var16.getHasStack() || !var16.canTakeStack(par4EntityPlayer))) { + var9 = par2 == 0 ? 0 : this.inventorySlots.size() - 1; + var19 = par2 == 0 ? 1 : -1; + + for (int var21 = 0; var21 < 2; ++var21) { + for (int var23 = var9; var23 >= 0 && var23 < this.inventorySlots.size() + && var17.stackSize < var17.getMaxStackSize(); var23 += var19) { + Slot var24 = (Slot) this.inventorySlots.get(var23); + + if (var24.getHasStack() && func_94527_a(var24, var17, true) + && var24.canTakeStack(par4EntityPlayer) && this.func_94530_a(var17, var24) + && (var21 != 0 + || var24.getStack().stackSize != var24.getStack().getMaxStackSize())) { + int var14 = Math.min(var17.getMaxStackSize() - var17.stackSize, + var24.getStack().stackSize); + ItemStack var15 = var24.decrStackSize(var14); + var17.stackSize += var14; + + if (var15.stackSize <= 0) { + var24.putStack((ItemStack) null); + } + + var24.onPickupFromSlot(par4EntityPlayer, var15); + } + } + } + } + + this.detectAndSendChanges(); + } + } + + return var5; + } + + public boolean func_94530_a(ItemStack par1ItemStack, Slot par2Slot) { + return true; + } + + protected void retrySlotClick(int par1, int par2, boolean par3, EntityPlayer par4EntityPlayer) { + this.slotClick(par1, par2, 1, par4EntityPlayer); + } + + /** + * Callback for when the crafting gui is closed. + */ + public void onCraftGuiClosed(EntityPlayer par1EntityPlayer) { + InventoryPlayer var2 = par1EntityPlayer.inventory; + + if (var2.getItemStack() != null) { + par1EntityPlayer.dropPlayerItem(var2.getItemStack()); + var2.setItemStack((ItemStack) null); + } + } + + /** + * Callback for when the crafting matrix is changed. + */ + public void onCraftMatrixChanged(IInventory par1IInventory) { + this.detectAndSendChanges(); + } + + /** + * args: slotID, itemStack to put in slot + */ + public void putStackInSlot(int par1, ItemStack par2ItemStack) { + this.getSlot(par1).putStack(par2ItemStack); + } + + /** + * gets whether or not the player can craft in this inventory or not + */ + public boolean getCanCraft(EntityPlayer par1EntityPlayer) { + return !this.playerList.contains(par1EntityPlayer); + } + + /** + * sets whether the player can craft in this inventory or not + */ + public void setCanCraft(EntityPlayer par1EntityPlayer, boolean par2) { + if (par2) { + this.playerList.remove(par1EntityPlayer); + } else { + this.playerList.add(par1EntityPlayer); + } + } + + public abstract boolean canInteractWith(EntityPlayer var1); + + /** + * merges provided ItemStack with the first avaliable one in the + * container/player inventory + */ + protected boolean mergeItemStack(ItemStack par1ItemStack, int par2, int par3, boolean par4) { + boolean var5 = false; + int var6 = par2; + + if (par4) { + var6 = par3 - 1; + } + + Slot var7; + ItemStack var8; + + if (par1ItemStack.isStackable()) { + while (par1ItemStack.stackSize > 0 && (!par4 && var6 < par3 || par4 && var6 >= par2)) { + var7 = (Slot) this.inventorySlots.get(var6); + var8 = var7.getStack(); + + if (var8 != null && var8.itemID == par1ItemStack.itemID + && (!par1ItemStack.getHasSubtypes() || par1ItemStack.getItemDamage() == var8.getItemDamage()) + && ItemStack.areItemStackTagsEqual(par1ItemStack, var8)) { + int var9 = var8.stackSize + par1ItemStack.stackSize; + + if (var9 <= par1ItemStack.getMaxStackSize()) { + par1ItemStack.stackSize = 0; + var8.stackSize = var9; + var7.onSlotChanged(); + var5 = true; + } else if (var8.stackSize < par1ItemStack.getMaxStackSize()) { + par1ItemStack.stackSize -= par1ItemStack.getMaxStackSize() - var8.stackSize; + var8.stackSize = par1ItemStack.getMaxStackSize(); + var7.onSlotChanged(); + var5 = true; + } + } + + if (par4) { + --var6; + } else { + ++var6; + } + } + } + + if (par1ItemStack.stackSize > 0) { + if (par4) { + var6 = par3 - 1; + } else { + var6 = par2; + } + + while (!par4 && var6 < par3 || par4 && var6 >= par2) { + var7 = (Slot) this.inventorySlots.get(var6); + var8 = var7.getStack(); + + if (var8 == null) { + var7.putStack(par1ItemStack.copy()); + var7.onSlotChanged(); + par1ItemStack.stackSize = 0; + var5 = true; + break; + } + + if (par4) { + --var6; + } else { + ++var6; + } + } + } + + return var5; + } + + public static int func_94529_b(int par0) { + return par0 >> 2 & 3; + } + + public static int func_94532_c(int par0) { + return par0 & 3; + } + + public static boolean func_94528_d(int par0) { + return par0 == 0 || par0 == 1; + } + + protected void func_94533_d() { + this.field_94536_g = 0; + this.field_94537_h.clear(); + } + + public static boolean func_94527_a(Slot par0Slot, ItemStack par1ItemStack, boolean par2) { + boolean var3 = par0Slot == null || !par0Slot.getHasStack(); + + if (par0Slot != null && par0Slot.getHasStack() && par1ItemStack != null + && par1ItemStack.isItemEqual(par0Slot.getStack()) + && ItemStack.areItemStackTagsEqual(par0Slot.getStack(), par1ItemStack)) { + int var10002 = par2 ? 0 : par1ItemStack.stackSize; + var3 |= par0Slot.getStack().stackSize + var10002 <= par1ItemStack.getMaxStackSize(); + } + + return var3; + } + + public static void func_94525_a(Set par0Set, int par1, ItemStack par2ItemStack, int par3) { + switch (par1) { + case 0: + par2ItemStack.stackSize = MathHelper.floor_float((float) par2ItemStack.stackSize / (float) par0Set.size()); + break; + + case 1: + par2ItemStack.stackSize = 1; + } + + par2ItemStack.stackSize += par3; + } + + public boolean func_94531_b(Slot par1Slot) { + return true; + } + + public static int calcRedstoneFromInventory(IInventory par0IInventory) { + if (par0IInventory == null) { + return 0; + } else { + int var1 = 0; + float var2 = 0.0F; + + for (int var3 = 0; var3 < par0IInventory.getSizeInventory(); ++var3) { + ItemStack var4 = par0IInventory.getStackInSlot(var3); + + if (var4 != null) { + var2 += (float) var4.stackSize + / (float) Math.min(par0IInventory.getInventoryStackLimit(), var4.getMaxStackSize()); + ++var1; + } + } + + var2 /= (float) par0IInventory.getSizeInventory(); + return MathHelper.floor_float(var2 * 14.0F) + (var1 > 0 ? 1 : 0); + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ContainerBeacon.java b/sp-server/src/main/java/net/minecraft/src/ContainerBeacon.java new file mode 100644 index 0000000..c3f698e --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ContainerBeacon.java @@ -0,0 +1,110 @@ +package net.minecraft.src; + +public class ContainerBeacon extends Container { + private TileEntityBeacon theBeacon; + + /** + * This beacon's slot where you put in Emerald, Diamond, Gold or Iron Ingot. + */ + private final SlotBeacon beaconSlot; + private int field_82865_g; + private int field_82867_h; + private int field_82868_i; + + public ContainerBeacon(InventoryPlayer par1InventoryPlayer, TileEntityBeacon par2TileEntityBeacon) { + this.theBeacon = par2TileEntityBeacon; + this.addSlotToContainer(this.beaconSlot = new SlotBeacon(this, par2TileEntityBeacon, 0, 136, 110)); + byte var3 = 36; + short var4 = 137; + int var5; + + for (var5 = 0; var5 < 3; ++var5) { + for (int var6 = 0; var6 < 9; ++var6) { + this.addSlotToContainer( + new Slot(par1InventoryPlayer, var6 + var5 * 9 + 9, var3 + var6 * 18, var4 + var5 * 18)); + } + } + + for (var5 = 0; var5 < 9; ++var5) { + this.addSlotToContainer(new Slot(par1InventoryPlayer, var5, var3 + var5 * 18, 58 + var4)); + } + + this.field_82865_g = par2TileEntityBeacon.getLevels(); + this.field_82867_h = par2TileEntityBeacon.getPrimaryEffect(); + this.field_82868_i = par2TileEntityBeacon.getSecondaryEffect(); + } + + public void onCraftGuiOpened(ICrafting par1ICrafting) { + super.onCraftGuiOpened(par1ICrafting); + par1ICrafting.sendProgressBarUpdate(this, 0, this.field_82865_g); + par1ICrafting.sendProgressBarUpdate(this, 1, this.field_82867_h); + par1ICrafting.sendProgressBarUpdate(this, 2, this.field_82868_i); + } + + /** + * Looks for changes made in the container, sends them to every listener. + */ + public void detectAndSendChanges() { + super.detectAndSendChanges(); + } + + /** + * Returns the Tile Entity behind this beacon inventory / container + */ + public TileEntityBeacon getBeacon() { + return this.theBeacon; + } + + public boolean canInteractWith(EntityPlayer par1EntityPlayer) { + return this.theBeacon.isUseableByPlayer(par1EntityPlayer); + } + + /** + * Take a stack from the specified inventory slot. + */ + public ItemStack transferStackInSlot(EntityPlayer par1EntityPlayer, int par2) { + ItemStack var3 = null; + Slot var4 = (Slot) this.inventorySlots.get(par2); + + if (var4 != null && var4.getHasStack()) { + ItemStack var5 = var4.getStack(); + var3 = var5.copy(); + + if (par2 == 0) { + if (!this.mergeItemStack(var5, 1, 37, true)) { + return null; + } + + var4.onSlotChange(var5, var3); + } else if (!this.beaconSlot.getHasStack() && this.beaconSlot.isItemValid(var5) && var5.stackSize == 1) { + if (!this.mergeItemStack(var5, 0, 1, false)) { + return null; + } + } else if (par2 >= 1 && par2 < 28) { + if (!this.mergeItemStack(var5, 28, 37, false)) { + return null; + } + } else if (par2 >= 28 && par2 < 37) { + if (!this.mergeItemStack(var5, 1, 28, false)) { + return null; + } + } else if (!this.mergeItemStack(var5, 1, 37, false)) { + return null; + } + + if (var5.stackSize == 0) { + var4.putStack((ItemStack) null); + } else { + var4.onSlotChanged(); + } + + if (var5.stackSize == var3.stackSize) { + return null; + } + + var4.onPickupFromSlot(par1EntityPlayer, var5); + } + + return var3; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ContainerBrewingStand.java b/sp-server/src/main/java/net/minecraft/src/ContainerBrewingStand.java new file mode 100644 index 0000000..6f9c16d --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ContainerBrewingStand.java @@ -0,0 +1,115 @@ +package net.minecraft.src; + +public class ContainerBrewingStand extends Container { + private TileEntityBrewingStand tileBrewingStand; + + /** Instance of Slot. */ + private final Slot theSlot; + private int brewTime = 0; + + public ContainerBrewingStand(InventoryPlayer par1InventoryPlayer, + TileEntityBrewingStand par2TileEntityBrewingStand) { + this.tileBrewingStand = par2TileEntityBrewingStand; + this.addSlotToContainer( + new SlotBrewingStandPotion(par1InventoryPlayer.player, par2TileEntityBrewingStand, 0, 56, 46)); + this.addSlotToContainer( + new SlotBrewingStandPotion(par1InventoryPlayer.player, par2TileEntityBrewingStand, 1, 79, 53)); + this.addSlotToContainer( + new SlotBrewingStandPotion(par1InventoryPlayer.player, par2TileEntityBrewingStand, 2, 102, 46)); + this.theSlot = this + .addSlotToContainer(new SlotBrewingStandIngredient(this, par2TileEntityBrewingStand, 3, 79, 17)); + int var3; + + for (var3 = 0; var3 < 3; ++var3) { + for (int var4 = 0; var4 < 9; ++var4) { + this.addSlotToContainer( + new Slot(par1InventoryPlayer, var4 + var3 * 9 + 9, 8 + var4 * 18, 84 + var3 * 18)); + } + } + + for (var3 = 0; var3 < 9; ++var3) { + this.addSlotToContainer(new Slot(par1InventoryPlayer, var3, 8 + var3 * 18, 142)); + } + } + + public void onCraftGuiOpened(ICrafting par1ICrafting) { + super.onCraftGuiOpened(par1ICrafting); + par1ICrafting.sendProgressBarUpdate(this, 0, this.tileBrewingStand.getBrewTime()); + } + + /** + * Looks for changes made in the container, sends them to every listener. + */ + public void detectAndSendChanges() { + super.detectAndSendChanges(); + + for (int var1 = 0; var1 < this.crafters.size(); ++var1) { + ICrafting var2 = (ICrafting) this.crafters.get(var1); + + if (this.brewTime != this.tileBrewingStand.getBrewTime()) { + var2.sendProgressBarUpdate(this, 0, this.tileBrewingStand.getBrewTime()); + } + } + + this.brewTime = this.tileBrewingStand.getBrewTime(); + } + + public boolean canInteractWith(EntityPlayer par1EntityPlayer) { + return this.tileBrewingStand.isUseableByPlayer(par1EntityPlayer); + } + + /** + * Take a stack from the specified inventory slot. + */ + public ItemStack transferStackInSlot(EntityPlayer par1EntityPlayer, int par2) { + ItemStack var3 = null; + Slot var4 = (Slot) this.inventorySlots.get(par2); + + if (var4 != null && var4.getHasStack()) { + ItemStack var5 = var4.getStack(); + var3 = var5.copy(); + + if ((par2 < 0 || par2 > 2) && par2 != 3) { + if (!this.theSlot.getHasStack() && this.theSlot.isItemValid(var5)) { + if (!this.mergeItemStack(var5, 3, 4, false)) { + return null; + } + } else if (SlotBrewingStandPotion.canHoldPotion(var3)) { + if (!this.mergeItemStack(var5, 0, 3, false)) { + return null; + } + } else if (par2 >= 4 && par2 < 31) { + if (!this.mergeItemStack(var5, 31, 40, false)) { + return null; + } + } else if (par2 >= 31 && par2 < 40) { + if (!this.mergeItemStack(var5, 4, 31, false)) { + return null; + } + } else if (!this.mergeItemStack(var5, 4, 40, false)) { + return null; + } + } else { + if (!this.mergeItemStack(var5, 4, 40, true)) { + return null; + } + + var4.onSlotChange(var5, var3); + } + + if (var5.stackSize == 0) { + var4.putStack((ItemStack) null); + } else { + var4.onSlotChanged(); + } + + if (var5.stackSize == var3.stackSize) { + return null; + } + + var4.onPickupFromSlot(par1EntityPlayer, var5); + } + + return var3; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ContainerChest.java b/sp-server/src/main/java/net/minecraft/src/ContainerChest.java new file mode 100644 index 0000000..be9d112 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ContainerChest.java @@ -0,0 +1,80 @@ +package net.minecraft.src; + +public class ContainerChest extends Container { + private IInventory lowerChestInventory; + private int numRows; + + public ContainerChest(IInventory par1IInventory, IInventory par2IInventory) { + this.lowerChestInventory = par2IInventory; + this.numRows = par2IInventory.getSizeInventory() / 9; + par2IInventory.openChest(); + int var3 = (this.numRows - 4) * 18; + int var4; + int var5; + + for (var4 = 0; var4 < this.numRows; ++var4) { + for (var5 = 0; var5 < 9; ++var5) { + this.addSlotToContainer(new Slot(par2IInventory, var5 + var4 * 9, 8 + var5 * 18, 18 + var4 * 18)); + } + } + + for (var4 = 0; var4 < 3; ++var4) { + for (var5 = 0; var5 < 9; ++var5) { + this.addSlotToContainer( + new Slot(par1IInventory, var5 + var4 * 9 + 9, 8 + var5 * 18, 103 + var4 * 18 + var3)); + } + } + + for (var4 = 0; var4 < 9; ++var4) { + this.addSlotToContainer(new Slot(par1IInventory, var4, 8 + var4 * 18, 161 + var3)); + } + } + + public boolean canInteractWith(EntityPlayer par1EntityPlayer) { + return this.lowerChestInventory.isUseableByPlayer(par1EntityPlayer); + } + + /** + * Take a stack from the specified inventory slot. + */ + public ItemStack transferStackInSlot(EntityPlayer par1EntityPlayer, int par2) { + ItemStack var3 = null; + Slot var4 = (Slot) this.inventorySlots.get(par2); + + if (var4 != null && var4.getHasStack()) { + ItemStack var5 = var4.getStack(); + var3 = var5.copy(); + + if (par2 < this.numRows * 9) { + if (!this.mergeItemStack(var5, this.numRows * 9, this.inventorySlots.size(), true)) { + return null; + } + } else if (!this.mergeItemStack(var5, 0, this.numRows * 9, false)) { + return null; + } + + if (var5.stackSize == 0) { + var4.putStack((ItemStack) null); + } else { + var4.onSlotChanged(); + } + } + + return var3; + } + + /** + * Callback for when the crafting gui is closed. + */ + public void onCraftGuiClosed(EntityPlayer par1EntityPlayer) { + super.onCraftGuiClosed(par1EntityPlayer); + this.lowerChestInventory.closeChest(); + } + + /** + * Return this chest container's lower chest inventory. + */ + public IInventory getLowerChestInventory() { + return this.lowerChestInventory; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ContainerDispenser.java b/sp-server/src/main/java/net/minecraft/src/ContainerDispenser.java new file mode 100644 index 0000000..c7405ed --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ContainerDispenser.java @@ -0,0 +1,67 @@ +package net.minecraft.src; + +public class ContainerDispenser extends Container { + private TileEntityDispenser tileEntityDispenser; + + public ContainerDispenser(IInventory par1IInventory, TileEntityDispenser par2TileEntityDispenser) { + this.tileEntityDispenser = par2TileEntityDispenser; + int var3; + int var4; + + for (var3 = 0; var3 < 3; ++var3) { + for (var4 = 0; var4 < 3; ++var4) { + this.addSlotToContainer( + new Slot(par2TileEntityDispenser, var4 + var3 * 3, 62 + var4 * 18, 17 + var3 * 18)); + } + } + + for (var3 = 0; var3 < 3; ++var3) { + for (var4 = 0; var4 < 9; ++var4) { + this.addSlotToContainer(new Slot(par1IInventory, var4 + var3 * 9 + 9, 8 + var4 * 18, 84 + var3 * 18)); + } + } + + for (var3 = 0; var3 < 9; ++var3) { + this.addSlotToContainer(new Slot(par1IInventory, var3, 8 + var3 * 18, 142)); + } + } + + public boolean canInteractWith(EntityPlayer par1EntityPlayer) { + return this.tileEntityDispenser.isUseableByPlayer(par1EntityPlayer); + } + + /** + * Take a stack from the specified inventory slot. + */ + public ItemStack transferStackInSlot(EntityPlayer par1EntityPlayer, int par2) { + ItemStack var3 = null; + Slot var4 = (Slot) this.inventorySlots.get(par2); + + if (var4 != null && var4.getHasStack()) { + ItemStack var5 = var4.getStack(); + var3 = var5.copy(); + + if (par2 < 9) { + if (!this.mergeItemStack(var5, 9, 45, true)) { + return null; + } + } else if (!this.mergeItemStack(var5, 0, 9, false)) { + return null; + } + + if (var5.stackSize == 0) { + var4.putStack((ItemStack) null); + } else { + var4.onSlotChanged(); + } + + if (var5.stackSize == var3.stackSize) { + return null; + } + + var4.onPickupFromSlot(par1EntityPlayer, var5); + } + + return var3; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ContainerEnchantment.java b/sp-server/src/main/java/net/minecraft/src/ContainerEnchantment.java new file mode 100644 index 0000000..5e036f9 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ContainerEnchantment.java @@ -0,0 +1,246 @@ +package net.minecraft.src; + +import java.util.List; +import java.util.Random; + +public class ContainerEnchantment extends Container { + /** SlotEnchantmentTable object with ItemStack to be enchanted */ + public IInventory tableInventory = new SlotEnchantmentTable(this, "Enchant", true, 1); + + /** current world (for bookshelf counting) */ + private World worldPointer; + private int posX; + private int posY; + private int posZ; + private Random rand = new Random(); + + /** used as seed for EnchantmentNameParts (see GuiEnchantment) */ + public long nameSeed; + + /** 3-member array storing the enchantment levels of each slot */ + public int[] enchantLevels = new int[3]; + + public ContainerEnchantment(InventoryPlayer par1InventoryPlayer, World par2World, int par3, int par4, int par5) { + this.worldPointer = par2World; + this.posX = par3; + this.posY = par4; + this.posZ = par5; + this.addSlotToContainer(new SlotEnchantment(this, this.tableInventory, 0, 25, 47)); + int var6; + + for (var6 = 0; var6 < 3; ++var6) { + for (int var7 = 0; var7 < 9; ++var7) { + this.addSlotToContainer( + new Slot(par1InventoryPlayer, var7 + var6 * 9 + 9, 8 + var7 * 18, 84 + var6 * 18)); + } + } + + for (var6 = 0; var6 < 9; ++var6) { + this.addSlotToContainer(new Slot(par1InventoryPlayer, var6, 8 + var6 * 18, 142)); + } + } + + public void onCraftGuiOpened(ICrafting par1ICrafting) { + super.onCraftGuiOpened(par1ICrafting); + par1ICrafting.sendProgressBarUpdate(this, 0, this.enchantLevels[0]); + par1ICrafting.sendProgressBarUpdate(this, 1, this.enchantLevels[1]); + par1ICrafting.sendProgressBarUpdate(this, 2, this.enchantLevels[2]); + } + + /** + * Looks for changes made in the container, sends them to every listener. + */ + public void detectAndSendChanges() { + super.detectAndSendChanges(); + + for (int var1 = 0; var1 < this.crafters.size(); ++var1) { + ICrafting var2 = (ICrafting) this.crafters.get(var1); + var2.sendProgressBarUpdate(this, 0, this.enchantLevels[0]); + var2.sendProgressBarUpdate(this, 1, this.enchantLevels[1]); + var2.sendProgressBarUpdate(this, 2, this.enchantLevels[2]); + } + } + + /** + * Callback for when the crafting matrix is changed. + */ + public void onCraftMatrixChanged(IInventory par1IInventory) { + if (par1IInventory == this.tableInventory) { + ItemStack var2 = par1IInventory.getStackInSlot(0); + int var3; + + if (var2 != null && var2.isItemEnchantable()) { + this.nameSeed = this.rand.nextLong(); + + if (!this.worldPointer.isRemote) { + var3 = 0; + int var4; + + for (var4 = -1; var4 <= 1; ++var4) { + for (int var5 = -1; var5 <= 1; ++var5) { + if ((var4 != 0 || var5 != 0) + && this.worldPointer.isAirBlock(this.posX + var5, this.posY, this.posZ + var4) + && this.worldPointer.isAirBlock(this.posX + var5, this.posY + 1, + this.posZ + var4)) { + if (this.worldPointer.getBlockId(this.posX + var5 * 2, this.posY, + this.posZ + var4 * 2) == Block.bookShelf.blockID) { + ++var3; + } + + if (this.worldPointer.getBlockId(this.posX + var5 * 2, this.posY + 1, + this.posZ + var4 * 2) == Block.bookShelf.blockID) { + ++var3; + } + + if (var5 != 0 && var4 != 0) { + if (this.worldPointer.getBlockId(this.posX + var5 * 2, this.posY, + this.posZ + var4) == Block.bookShelf.blockID) { + ++var3; + } + + if (this.worldPointer.getBlockId(this.posX + var5 * 2, this.posY + 1, + this.posZ + var4) == Block.bookShelf.blockID) { + ++var3; + } + + if (this.worldPointer.getBlockId(this.posX + var5, this.posY, + this.posZ + var4 * 2) == Block.bookShelf.blockID) { + ++var3; + } + + if (this.worldPointer.getBlockId(this.posX + var5, this.posY + 1, + this.posZ + var4 * 2) == Block.bookShelf.blockID) { + ++var3; + } + } + } + } + } + + for (var4 = 0; var4 < 3; ++var4) { + this.enchantLevels[var4] = EnchantmentHelper.calcItemStackEnchantability(this.rand, var4, var3, + var2); + } + + this.detectAndSendChanges(); + } + } else { + for (var3 = 0; var3 < 3; ++var3) { + this.enchantLevels[var3] = 0; + } + } + } + } + + /** + * enchants the item on the table using the specified slot; also deducts XP from + * player + */ + public boolean enchantItem(EntityPlayer par1EntityPlayer, int par2) { + ItemStack var3 = this.tableInventory.getStackInSlot(0); + + if (this.enchantLevels[par2] > 0 && var3 != null + && (par1EntityPlayer.experienceLevel >= this.enchantLevels[par2] + || par1EntityPlayer.capabilities.isCreativeMode)) { + if (!this.worldPointer.isRemote) { + List var4 = EnchantmentHelper.buildEnchantmentList(this.rand, var3, this.enchantLevels[par2]); + boolean var5 = var3.itemID == Item.book.itemID; + + if (var4 != null) { + par1EntityPlayer.addExperienceLevel(-this.enchantLevels[par2]); + + if (var5) { + var3.itemID = Item.enchantedBook.itemID; + } + + int var6 = var5 ? this.rand.nextInt(var4.size()) : -1; + + for (int var7 = 0; var7 < var4.size(); ++var7) { + EnchantmentData var8 = (EnchantmentData) var4.get(var7); + + if (!var5 || var7 == var6) { + if (var5) { + Item.enchantedBook.func_92115_a(var3, var8); + } else { + var3.addEnchantment(var8.enchantmentobj, var8.enchantmentLevel); + } + } + } + + this.onCraftMatrixChanged(this.tableInventory); + } + } + + return true; + } else { + return false; + } + } + + /** + * Callback for when the crafting gui is closed. + */ + public void onCraftGuiClosed(EntityPlayer par1EntityPlayer) { + super.onCraftGuiClosed(par1EntityPlayer); + + if (!this.worldPointer.isRemote) { + ItemStack var2 = this.tableInventory.getStackInSlotOnClosing(0); + + if (var2 != null) { + par1EntityPlayer.dropPlayerItem(var2); + } + } + } + + public boolean canInteractWith(EntityPlayer par1EntityPlayer) { + return this.worldPointer.getBlockId(this.posX, this.posY, this.posZ) != Block.enchantmentTable.blockID ? false + : par1EntityPlayer.getDistanceSq((double) this.posX + 0.5D, (double) this.posY + 0.5D, + (double) this.posZ + 0.5D) <= 64.0D; + } + + /** + * Take a stack from the specified inventory slot. + */ + public ItemStack transferStackInSlot(EntityPlayer par1EntityPlayer, int par2) { + ItemStack var3 = null; + Slot var4 = (Slot) this.inventorySlots.get(par2); + + if (var4 != null && var4.getHasStack()) { + ItemStack var5 = var4.getStack(); + var3 = var5.copy(); + + if (par2 == 0) { + if (!this.mergeItemStack(var5, 1, 37, true)) { + return null; + } + } else { + if (((Slot) this.inventorySlots.get(0)).getHasStack() + || !((Slot) this.inventorySlots.get(0)).isItemValid(var5)) { + return null; + } + + if (var5.hasTagCompound() && var5.stackSize == 1) { + ((Slot) this.inventorySlots.get(0)).putStack(var5.copy()); + var5.stackSize = 0; + } else if (var5.stackSize >= 1) { + ((Slot) this.inventorySlots.get(0)).putStack(new ItemStack(var5.itemID, 1, var5.getItemDamage())); + --var5.stackSize; + } + } + + if (var5.stackSize == 0) { + var4.putStack((ItemStack) null); + } else { + var4.onSlotChanged(); + } + + if (var5.stackSize == var3.stackSize) { + return null; + } + + var4.onPickupFromSlot(par1EntityPlayer, var5); + } + + return var3; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ContainerFurnace.java b/sp-server/src/main/java/net/minecraft/src/ContainerFurnace.java new file mode 100644 index 0000000..408b11c --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ContainerFurnace.java @@ -0,0 +1,118 @@ +package net.minecraft.src; + +public class ContainerFurnace extends Container { + private TileEntityFurnace furnace; + private int lastCookTime = 0; + private int lastBurnTime = 0; + private int lastItemBurnTime = 0; + + public ContainerFurnace(InventoryPlayer par1InventoryPlayer, TileEntityFurnace par2TileEntityFurnace) { + this.furnace = par2TileEntityFurnace; + this.addSlotToContainer(new Slot(par2TileEntityFurnace, 0, 56, 17)); + this.addSlotToContainer(new Slot(par2TileEntityFurnace, 1, 56, 53)); + this.addSlotToContainer(new SlotFurnace(par1InventoryPlayer.player, par2TileEntityFurnace, 2, 116, 35)); + int var3; + + for (var3 = 0; var3 < 3; ++var3) { + for (int var4 = 0; var4 < 9; ++var4) { + this.addSlotToContainer( + new Slot(par1InventoryPlayer, var4 + var3 * 9 + 9, 8 + var4 * 18, 84 + var3 * 18)); + } + } + + for (var3 = 0; var3 < 9; ++var3) { + this.addSlotToContainer(new Slot(par1InventoryPlayer, var3, 8 + var3 * 18, 142)); + } + } + + public void onCraftGuiOpened(ICrafting par1ICrafting) { + super.onCraftGuiOpened(par1ICrafting); + par1ICrafting.sendProgressBarUpdate(this, 0, this.furnace.furnaceCookTime); + par1ICrafting.sendProgressBarUpdate(this, 1, this.furnace.furnaceBurnTime); + par1ICrafting.sendProgressBarUpdate(this, 2, this.furnace.currentItemBurnTime); + } + + /** + * Looks for changes made in the container, sends them to every listener. + */ + public void detectAndSendChanges() { + super.detectAndSendChanges(); + + for (int var1 = 0; var1 < this.crafters.size(); ++var1) { + ICrafting var2 = (ICrafting) this.crafters.get(var1); + + if (this.lastCookTime != this.furnace.furnaceCookTime) { + var2.sendProgressBarUpdate(this, 0, this.furnace.furnaceCookTime); + } + + if (this.lastBurnTime != this.furnace.furnaceBurnTime) { + var2.sendProgressBarUpdate(this, 1, this.furnace.furnaceBurnTime); + } + + if (this.lastItemBurnTime != this.furnace.currentItemBurnTime) { + var2.sendProgressBarUpdate(this, 2, this.furnace.currentItemBurnTime); + } + } + + this.lastCookTime = this.furnace.furnaceCookTime; + this.lastBurnTime = this.furnace.furnaceBurnTime; + this.lastItemBurnTime = this.furnace.currentItemBurnTime; + } + + public boolean canInteractWith(EntityPlayer par1EntityPlayer) { + return this.furnace.isUseableByPlayer(par1EntityPlayer); + } + + /** + * Take a stack from the specified inventory slot. + */ + public ItemStack transferStackInSlot(EntityPlayer par1EntityPlayer, int par2) { + ItemStack var3 = null; + Slot var4 = (Slot) this.inventorySlots.get(par2); + + if (var4 != null && var4.getHasStack()) { + ItemStack var5 = var4.getStack(); + var3 = var5.copy(); + + if (par2 == 2) { + if (!this.mergeItemStack(var5, 3, 39, true)) { + return null; + } + + var4.onSlotChange(var5, var3); + } else if (par2 != 1 && par2 != 0) { + if (FurnaceRecipes.smelting().getSmeltingResult(var5.getItem().itemID) != null) { + if (!this.mergeItemStack(var5, 0, 1, false)) { + return null; + } + } else if (TileEntityFurnace.isItemFuel(var5)) { + if (!this.mergeItemStack(var5, 1, 2, false)) { + return null; + } + } else if (par2 >= 3 && par2 < 30) { + if (!this.mergeItemStack(var5, 30, 39, false)) { + return null; + } + } else if (par2 >= 30 && par2 < 39 && !this.mergeItemStack(var5, 3, 30, false)) { + return null; + } + } else if (!this.mergeItemStack(var5, 3, 39, false)) { + return null; + } + + if (var5.stackSize == 0) { + var4.putStack((ItemStack) null); + } else { + var4.onSlotChanged(); + } + + if (var5.stackSize == var3.stackSize) { + return null; + } + + var4.onPickupFromSlot(par1EntityPlayer, var5); + } + + return var3; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ContainerHopper.java b/sp-server/src/main/java/net/minecraft/src/ContainerHopper.java new file mode 100644 index 0000000..dc2c73c --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ContainerHopper.java @@ -0,0 +1,69 @@ +package net.minecraft.src; + +public class ContainerHopper extends Container { + private final IInventory field_94538_a; + + public ContainerHopper(InventoryPlayer par1InventoryPlayer, IInventory par2IInventory) { + this.field_94538_a = par2IInventory; + par2IInventory.openChest(); + byte var3 = 51; + int var4; + + for (var4 = 0; var4 < par2IInventory.getSizeInventory(); ++var4) { + this.addSlotToContainer(new Slot(par2IInventory, var4, 44 + var4 * 18, 20)); + } + + for (var4 = 0; var4 < 3; ++var4) { + for (int var5 = 0; var5 < 9; ++var5) { + this.addSlotToContainer( + new Slot(par1InventoryPlayer, var5 + var4 * 9 + 9, 8 + var5 * 18, var4 * 18 + var3)); + } + } + + for (var4 = 0; var4 < 9; ++var4) { + this.addSlotToContainer(new Slot(par1InventoryPlayer, var4, 8 + var4 * 18, 58 + var3)); + } + } + + public boolean canInteractWith(EntityPlayer par1EntityPlayer) { + return this.field_94538_a.isUseableByPlayer(par1EntityPlayer); + } + + /** + * Take a stack from the specified inventory slot. + */ + public ItemStack transferStackInSlot(EntityPlayer par1EntityPlayer, int par2) { + ItemStack var3 = null; + Slot var4 = (Slot) this.inventorySlots.get(par2); + + if (var4 != null && var4.getHasStack()) { + ItemStack var5 = var4.getStack(); + var3 = var5.copy(); + + if (par2 < this.field_94538_a.getSizeInventory()) { + if (!this.mergeItemStack(var5, this.field_94538_a.getSizeInventory(), this.inventorySlots.size(), + true)) { + return null; + } + } else if (!this.mergeItemStack(var5, 0, this.field_94538_a.getSizeInventory(), false)) { + return null; + } + + if (var5.stackSize == 0) { + var4.putStack((ItemStack) null); + } else { + var4.onSlotChanged(); + } + } + + return var3; + } + + /** + * Callback for when the crafting gui is closed. + */ + public void onCraftGuiClosed(EntityPlayer par1EntityPlayer) { + super.onCraftGuiClosed(par1EntityPlayer); + this.field_94538_a.closeChest(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ContainerMerchant.java b/sp-server/src/main/java/net/minecraft/src/ContainerMerchant.java new file mode 100644 index 0000000..705a421 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ContainerMerchant.java @@ -0,0 +1,131 @@ +package net.minecraft.src; + +public class ContainerMerchant extends Container { + /** Instance of Merchant. */ + private IMerchant theMerchant; + private InventoryMerchant merchantInventory; + + /** Instance of World. */ + private final World theWorld; + + public ContainerMerchant(InventoryPlayer par1InventoryPlayer, IMerchant par2IMerchant, World par3World) { + this.theMerchant = par2IMerchant; + this.theWorld = par3World; + this.merchantInventory = new InventoryMerchant(par1InventoryPlayer.player, par2IMerchant); + this.addSlotToContainer(new Slot(this.merchantInventory, 0, 36, 53)); + this.addSlotToContainer(new Slot(this.merchantInventory, 1, 62, 53)); + this.addSlotToContainer( + new SlotMerchantResult(par1InventoryPlayer.player, par2IMerchant, this.merchantInventory, 2, 120, 53)); + int var4; + + for (var4 = 0; var4 < 3; ++var4) { + for (int var5 = 0; var5 < 9; ++var5) { + this.addSlotToContainer( + new Slot(par1InventoryPlayer, var5 + var4 * 9 + 9, 8 + var5 * 18, 84 + var4 * 18)); + } + } + + for (var4 = 0; var4 < 9; ++var4) { + this.addSlotToContainer(new Slot(par1InventoryPlayer, var4, 8 + var4 * 18, 142)); + } + } + + public InventoryMerchant getMerchantInventory() { + return this.merchantInventory; + } + + public void onCraftGuiOpened(ICrafting par1ICrafting) { + super.onCraftGuiOpened(par1ICrafting); + } + + /** + * Looks for changes made in the container, sends them to every listener. + */ + public void detectAndSendChanges() { + super.detectAndSendChanges(); + } + + /** + * Callback for when the crafting matrix is changed. + */ + public void onCraftMatrixChanged(IInventory par1IInventory) { + this.merchantInventory.resetRecipeAndSlots(); + super.onCraftMatrixChanged(par1IInventory); + } + + public void setCurrentRecipeIndex(int par1) { + this.merchantInventory.setCurrentRecipeIndex(par1); + } + + public boolean canInteractWith(EntityPlayer par1EntityPlayer) { + return this.theMerchant.getCustomer() == par1EntityPlayer; + } + + /** + * Take a stack from the specified inventory slot. + */ + public ItemStack transferStackInSlot(EntityPlayer par1EntityPlayer, int par2) { + ItemStack var3 = null; + Slot var4 = (Slot) this.inventorySlots.get(par2); + + if (var4 != null && var4.getHasStack()) { + ItemStack var5 = var4.getStack(); + var3 = var5.copy(); + + if (par2 == 2) { + if (!this.mergeItemStack(var5, 3, 39, true)) { + return null; + } + + var4.onSlotChange(var5, var3); + } else if (par2 != 0 && par2 != 1) { + if (par2 >= 3 && par2 < 30) { + if (!this.mergeItemStack(var5, 30, 39, false)) { + return null; + } + } else if (par2 >= 30 && par2 < 39 && !this.mergeItemStack(var5, 3, 30, false)) { + return null; + } + } else if (!this.mergeItemStack(var5, 3, 39, false)) { + return null; + } + + if (var5.stackSize == 0) { + var4.putStack((ItemStack) null); + } else { + var4.onSlotChanged(); + } + + if (var5.stackSize == var3.stackSize) { + return null; + } + + var4.onPickupFromSlot(par1EntityPlayer, var5); + } + + return var3; + } + + /** + * Callback for when the crafting gui is closed. + */ + public void onCraftGuiClosed(EntityPlayer par1EntityPlayer) { + super.onCraftGuiClosed(par1EntityPlayer); + this.theMerchant.setCustomer((EntityPlayer) null); + super.onCraftGuiClosed(par1EntityPlayer); + + if (!this.theWorld.isRemote) { + ItemStack var2 = this.merchantInventory.getStackInSlotOnClosing(0); + + if (var2 != null) { + par1EntityPlayer.dropPlayerItem(var2); + } + + var2 = this.merchantInventory.getStackInSlotOnClosing(1); + + if (var2 != null) { + par1EntityPlayer.dropPlayerItem(var2); + } + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ContainerPlayer.java b/sp-server/src/main/java/net/minecraft/src/ContainerPlayer.java new file mode 100644 index 0000000..a283323 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ContainerPlayer.java @@ -0,0 +1,137 @@ +package net.minecraft.src; + +public class ContainerPlayer extends Container { + /** The crafting matrix inventory. */ + public InventoryCrafting craftMatrix = new InventoryCrafting(this, 2, 2); + public IInventory craftResult = new InventoryCraftResult(); + + /** Determines if inventory manipulation should be handled. */ + public boolean isLocalWorld = false; + private final EntityPlayer thePlayer; + + public ContainerPlayer(InventoryPlayer par1InventoryPlayer, boolean par2, EntityPlayer par3EntityPlayer) { + this.isLocalWorld = par2; + this.thePlayer = par3EntityPlayer; + this.addSlotToContainer( + new SlotCrafting(par1InventoryPlayer.player, this.craftMatrix, this.craftResult, 0, 144, 36)); + int var4; + int var5; + + for (var4 = 0; var4 < 2; ++var4) { + for (var5 = 0; var5 < 2; ++var5) { + this.addSlotToContainer(new Slot(this.craftMatrix, var5 + var4 * 2, 88 + var5 * 18, 26 + var4 * 18)); + } + } + + for (var4 = 0; var4 < 4; ++var4) { + this.addSlotToContainer(new SlotArmor(this, par1InventoryPlayer, + par1InventoryPlayer.getSizeInventory() - 1 - var4, 8, 8 + var4 * 18, var4)); + } + + for (var4 = 0; var4 < 3; ++var4) { + for (var5 = 0; var5 < 9; ++var5) { + this.addSlotToContainer( + new Slot(par1InventoryPlayer, var5 + (var4 + 1) * 9, 8 + var5 * 18, 84 + var4 * 18)); + } + } + + for (var4 = 0; var4 < 9; ++var4) { + this.addSlotToContainer(new Slot(par1InventoryPlayer, var4, 8 + var4 * 18, 142)); + } + + this.onCraftMatrixChanged(this.craftMatrix); + } + + /** + * Callback for when the crafting matrix is changed. + */ + public void onCraftMatrixChanged(IInventory par1IInventory) { + this.craftResult.setInventorySlotContents(0, + CraftingManager.getInstance().findMatchingRecipe(this.craftMatrix, this.thePlayer.worldObj)); + } + + /** + * Callback for when the crafting gui is closed. + */ + public void onCraftGuiClosed(EntityPlayer par1EntityPlayer) { + super.onCraftGuiClosed(par1EntityPlayer); + + for (int var2 = 0; var2 < 4; ++var2) { + ItemStack var3 = this.craftMatrix.getStackInSlotOnClosing(var2); + + if (var3 != null) { + par1EntityPlayer.dropPlayerItem(var3); + } + } + + this.craftResult.setInventorySlotContents(0, (ItemStack) null); + } + + public boolean canInteractWith(EntityPlayer par1EntityPlayer) { + return true; + } + + /** + * Take a stack from the specified inventory slot. + */ + public ItemStack transferStackInSlot(EntityPlayer par1EntityPlayer, int par2) { + ItemStack var3 = null; + Slot var4 = (Slot) this.inventorySlots.get(par2); + + if (var4 != null && var4.getHasStack()) { + ItemStack var5 = var4.getStack(); + var3 = var5.copy(); + + if (par2 == 0) { + if (!this.mergeItemStack(var5, 9, 45, true)) { + return null; + } + + var4.onSlotChange(var5, var3); + } else if (par2 >= 1 && par2 < 5) { + if (!this.mergeItemStack(var5, 9, 45, false)) { + return null; + } + } else if (par2 >= 5 && par2 < 9) { + if (!this.mergeItemStack(var5, 9, 45, false)) { + return null; + } + } else if (var3.getItem() instanceof ItemArmor + && !((Slot) this.inventorySlots.get(5 + ((ItemArmor) var3.getItem()).armorType)).getHasStack()) { + int var6 = 5 + ((ItemArmor) var3.getItem()).armorType; + + if (!this.mergeItemStack(var5, var6, var6 + 1, false)) { + return null; + } + } else if (par2 >= 9 && par2 < 36) { + if (!this.mergeItemStack(var5, 36, 45, false)) { + return null; + } + } else if (par2 >= 36 && par2 < 45) { + if (!this.mergeItemStack(var5, 9, 36, false)) { + return null; + } + } else if (!this.mergeItemStack(var5, 9, 45, false)) { + return null; + } + + if (var5.stackSize == 0) { + var4.putStack((ItemStack) null); + } else { + var4.onSlotChanged(); + } + + if (var5.stackSize == var3.stackSize) { + return null; + } + + var4.onPickupFromSlot(par1EntityPlayer, var5); + } + + return var3; + } + + public boolean func_94530_a(ItemStack par1ItemStack, Slot par2Slot) { + return par2Slot.inventory != this.craftResult && super.func_94530_a(par1ItemStack, par2Slot); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ContainerRepair.java b/sp-server/src/main/java/net/minecraft/src/ContainerRepair.java new file mode 100644 index 0000000..0256e1b --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ContainerRepair.java @@ -0,0 +1,407 @@ +package net.minecraft.src; + +import java.util.Iterator; +import java.util.Map; + +public class ContainerRepair extends Container { + /** Here comes out item you merged and/or renamed. */ + private IInventory outputSlot = new InventoryCraftResult(); + + /** + * The 2slots where you put your items in that you want to merge and/or rename. + */ + private IInventory inputSlots = new InventoryRepair(this, "Repair", true, 2); + private World theWorld; + private int field_82861_i; + private int field_82858_j; + private int field_82859_k; + + /** The maximum cost of repairing/renaming in the anvil. */ + public int maximumCost = 0; + + /** determined by damage of input item and stackSize of repair materials */ + private int stackSizeToBeUsedInRepair = 0; + private String repairedItemName; + + /** The player that has this container open. */ + private final EntityPlayer thePlayer; + + public ContainerRepair(InventoryPlayer par1InventoryPlayer, World par2World, int par3, int par4, int par5, + EntityPlayer par6EntityPlayer) { + this.theWorld = par2World; + this.field_82861_i = par3; + this.field_82858_j = par4; + this.field_82859_k = par5; + this.thePlayer = par6EntityPlayer; + this.addSlotToContainer(new Slot(this.inputSlots, 0, 27, 47)); + this.addSlotToContainer(new Slot(this.inputSlots, 1, 76, 47)); + this.addSlotToContainer(new SlotRepair(this, this.outputSlot, 2, 134, 47, par2World, par3, par4, par5)); + int var7; + + for (var7 = 0; var7 < 3; ++var7) { + for (int var8 = 0; var8 < 9; ++var8) { + this.addSlotToContainer( + new Slot(par1InventoryPlayer, var8 + var7 * 9 + 9, 8 + var8 * 18, 84 + var7 * 18)); + } + } + + for (var7 = 0; var7 < 9; ++var7) { + this.addSlotToContainer(new Slot(par1InventoryPlayer, var7, 8 + var7 * 18, 142)); + } + } + + /** + * Callback for when the crafting matrix is changed. + */ + public void onCraftMatrixChanged(IInventory par1IInventory) { + super.onCraftMatrixChanged(par1IInventory); + + if (par1IInventory == this.inputSlots) { + this.updateRepairOutput(); + } + } + + /** + * called when the Anvil Input Slot changes, calculates the new result and puts + * it in the output slot + */ + public void updateRepairOutput() { + ItemStack var1 = this.inputSlots.getStackInSlot(0); + this.maximumCost = 0; + int var2 = 0; + byte var3 = 0; + int var4 = 0; + + if (var1 == null) { + this.outputSlot.setInventorySlotContents(0, (ItemStack) null); + this.maximumCost = 0; + } else { + ItemStack var5 = var1.copy(); + ItemStack var6 = this.inputSlots.getStackInSlot(1); + Map var7 = EnchantmentHelper.getEnchantments(var5); + boolean var8 = false; + int var19 = var3 + var1.getRepairCost() + (var6 == null ? 0 : var6.getRepairCost()); + this.stackSizeToBeUsedInRepair = 0; + int var9; + int var10; + int var11; + int var13; + int var14; + Iterator var21; + Enchantment var22; + + if (var6 != null) { + var8 = var6.itemID == Item.enchantedBook.itemID && Item.enchantedBook.func_92110_g(var6).tagCount() > 0; + + if (var5.isItemStackDamageable() && Item.itemsList[var5.itemID].getIsRepairable(var1, var6)) { + var9 = Math.min(var5.getItemDamageForDisplay(), var5.getMaxDamage() / 4); + + if (var9 <= 0) { + this.outputSlot.setInventorySlotContents(0, (ItemStack) null); + this.maximumCost = 0; + return; + } + + for (var10 = 0; var9 > 0 && var10 < var6.stackSize; ++var10) { + var11 = var5.getItemDamageForDisplay() - var9; + var5.setItemDamage(var11); + var2 += Math.max(1, var9 / 100) + var7.size(); + var9 = Math.min(var5.getItemDamageForDisplay(), var5.getMaxDamage() / 4); + } + + this.stackSizeToBeUsedInRepair = var10; + } else { + if (!var8 && (var5.itemID != var6.itemID || !var5.isItemStackDamageable())) { + this.outputSlot.setInventorySlotContents(0, (ItemStack) null); + this.maximumCost = 0; + return; + } + + if (var5.isItemStackDamageable() && !var8) { + var9 = var1.getMaxDamage() - var1.getItemDamageForDisplay(); + var10 = var6.getMaxDamage() - var6.getItemDamageForDisplay(); + var11 = var10 + var5.getMaxDamage() * 12 / 100; + int var12 = var9 + var11; + var13 = var5.getMaxDamage() - var12; + + if (var13 < 0) { + var13 = 0; + } + + if (var13 < var5.getItemDamage()) { + var5.setItemDamage(var13); + var2 += Math.max(1, var11 / 100); + } + } + + Map var20 = EnchantmentHelper.getEnchantments(var6); + var21 = var20.keySet().iterator(); + + while (var21.hasNext()) { + var11 = ((Integer) var21.next()).intValue(); + var22 = Enchantment.enchantmentsList[var11]; + var13 = var7.containsKey(Integer.valueOf(var11)) + ? ((Integer) var7.get(Integer.valueOf(var11))).intValue() + : 0; + var14 = ((Integer) var20.get(Integer.valueOf(var11))).intValue(); + int var10000; + + if (var13 == var14) { + ++var14; + var10000 = var14; + } else { + var10000 = Math.max(var14, var13); + } + + var14 = var10000; + int var15 = var14 - var13; + boolean var16 = var22.func_92089_a(var1); + + if (this.thePlayer.capabilities.isCreativeMode + || var1.itemID == ItemEnchantedBook.enchantedBook.itemID) { + var16 = true; + } + + Iterator var17 = var7.keySet().iterator(); + + while (var17.hasNext()) { + int var18 = ((Integer) var17.next()).intValue(); + + if (var18 != var11 && !var22.canApplyTogether(Enchantment.enchantmentsList[var18])) { + var16 = false; + var2 += var15; + } + } + + if (var16) { + if (var14 > var22.getMaxLevel()) { + var14 = var22.getMaxLevel(); + } + + var7.put(Integer.valueOf(var11), Integer.valueOf(var14)); + int var23 = 0; + + switch (var22.getWeight()) { + case 1: + var23 = 8; + break; + + case 2: + var23 = 4; + + case 3: + case 4: + case 6: + case 7: + case 8: + case 9: + default: + break; + + case 5: + var23 = 2; + break; + + case 10: + var23 = 1; + } + + if (var8) { + var23 = Math.max(1, var23 / 2); + } + + var2 += var23 * var15; + } + } + } + } + + if (this.repairedItemName != null && this.repairedItemName.length() > 0 + && !this.repairedItemName + .equalsIgnoreCase(this.thePlayer.getTranslator().translateNamedKey(var1.getItemName())) + && !this.repairedItemName.equals(var1.getDisplayName())) { + var4 = var1.isItemStackDamageable() ? 7 : var1.stackSize * 5; + var2 += var4; + + if (var1.hasDisplayName()) { + var19 += var4 / 2; + } + + var5.setItemName(this.repairedItemName); + } + + var9 = 0; + + for (var21 = var7.keySet().iterator(); var21.hasNext(); var19 += var9 + var13 * var14) { + var11 = ((Integer) var21.next()).intValue(); + var22 = Enchantment.enchantmentsList[var11]; + var13 = ((Integer) var7.get(Integer.valueOf(var11))).intValue(); + var14 = 0; + ++var9; + + switch (var22.getWeight()) { + case 1: + var14 = 8; + break; + + case 2: + var14 = 4; + + case 3: + case 4: + case 6: + case 7: + case 8: + case 9: + default: + break; + + case 5: + var14 = 2; + break; + + case 10: + var14 = 1; + } + + if (var8) { + var14 = Math.max(1, var14 / 2); + } + } + + if (var8) { + var19 = Math.max(1, var19 / 2); + } + + this.maximumCost = var19 + var2; + + if (var2 <= 0) { + var5 = null; + } + + if (var4 == var2 && var4 > 0 && this.maximumCost >= 40) { + this.theWorld.getWorldLogAgent() + .func_98233_a("Naming an item only, cost too high; giving discount to cap cost to 39 levels"); + this.maximumCost = 39; + } + + if (this.maximumCost >= 40 && !this.thePlayer.capabilities.isCreativeMode) { + var5 = null; + } + + if (var5 != null) { + var10 = var5.getRepairCost(); + + if (var6 != null && var10 < var6.getRepairCost()) { + var10 = var6.getRepairCost(); + } + + if (var5.hasDisplayName()) { + var10 -= 9; + } + + if (var10 < 0) { + var10 = 0; + } + + var10 += 2; + var5.setRepairCost(var10); + EnchantmentHelper.setEnchantments(var7, var5); + } + + this.outputSlot.setInventorySlotContents(0, var5); + this.detectAndSendChanges(); + } + } + + public void onCraftGuiOpened(ICrafting par1ICrafting) { + super.onCraftGuiOpened(par1ICrafting); + par1ICrafting.sendProgressBarUpdate(this, 0, this.maximumCost); + } + + /** + * Callback for when the crafting gui is closed. + */ + public void onCraftGuiClosed(EntityPlayer par1EntityPlayer) { + super.onCraftGuiClosed(par1EntityPlayer); + + if (!this.theWorld.isRemote) { + for (int var2 = 0; var2 < this.inputSlots.getSizeInventory(); ++var2) { + ItemStack var3 = this.inputSlots.getStackInSlotOnClosing(var2); + + if (var3 != null) { + par1EntityPlayer.dropPlayerItem(var3); + } + } + } + } + + public boolean canInteractWith(EntityPlayer par1EntityPlayer) { + return this.theWorld.getBlockId(this.field_82861_i, this.field_82858_j, + this.field_82859_k) != Block.anvil.blockID ? false + : par1EntityPlayer.getDistanceSq((double) this.field_82861_i + 0.5D, + (double) this.field_82858_j + 0.5D, (double) this.field_82859_k + 0.5D) <= 64.0D; + } + + /** + * Take a stack from the specified inventory slot. + */ + public ItemStack transferStackInSlot(EntityPlayer par1EntityPlayer, int par2) { + ItemStack var3 = null; + Slot var4 = (Slot) this.inventorySlots.get(par2); + + if (var4 != null && var4.getHasStack()) { + ItemStack var5 = var4.getStack(); + var3 = var5.copy(); + + if (par2 == 2) { + if (!this.mergeItemStack(var5, 3, 39, true)) { + return null; + } + + var4.onSlotChange(var5, var3); + } else if (par2 != 0 && par2 != 1) { + if (par2 >= 3 && par2 < 39 && !this.mergeItemStack(var5, 0, 2, false)) { + return null; + } + } else if (!this.mergeItemStack(var5, 3, 39, false)) { + return null; + } + + if (var5.stackSize == 0) { + var4.putStack((ItemStack) null); + } else { + var4.onSlotChanged(); + } + + if (var5.stackSize == var3.stackSize) { + return null; + } + + var4.onPickupFromSlot(par1EntityPlayer, var5); + } + + return var3; + } + + /** + * used by the Anvil GUI to update the Item Name being typed by the player + */ + public void updateItemName(String par1Str) { + this.repairedItemName = par1Str; + + if (this.getSlot(2).getHasStack()) { + this.getSlot(2).getStack().setItemName(this.repairedItemName); + } + + this.updateRepairOutput(); + } + + static IInventory getRepairInputInventory(ContainerRepair par0ContainerRepair) { + return par0ContainerRepair.inputSlots; + } + + static int getStackSizeUsedInRepair(ContainerRepair par0ContainerRepair) { + return par0ContainerRepair.stackSizeToBeUsedInRepair; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ContainerSheep.java b/sp-server/src/main/java/net/minecraft/src/ContainerSheep.java new file mode 100644 index 0000000..51f8979 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ContainerSheep.java @@ -0,0 +1,13 @@ +package net.minecraft.src; + +class ContainerSheep extends Container { + final EntitySheep field_90034_a; + + ContainerSheep(EntitySheep par1EntitySheep) { + this.field_90034_a = par1EntitySheep; + } + + public boolean canInteractWith(EntityPlayer par1EntityPlayer) { + return false; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ContainerWorkbench.java b/sp-server/src/main/java/net/minecraft/src/ContainerWorkbench.java new file mode 100644 index 0000000..3842597 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ContainerWorkbench.java @@ -0,0 +1,121 @@ +package net.minecraft.src; + +public class ContainerWorkbench extends Container { + /** The crafting matrix inventory (3x3). */ + public InventoryCrafting craftMatrix = new InventoryCrafting(this, 3, 3); + public IInventory craftResult = new InventoryCraftResult(); + private World worldObj; + private int posX; + private int posY; + private int posZ; + + public ContainerWorkbench(InventoryPlayer par1InventoryPlayer, World par2World, int par3, int par4, int par5) { + this.worldObj = par2World; + this.posX = par3; + this.posY = par4; + this.posZ = par5; + this.addSlotToContainer( + new SlotCrafting(par1InventoryPlayer.player, this.craftMatrix, this.craftResult, 0, 124, 35)); + int var6; + int var7; + + for (var6 = 0; var6 < 3; ++var6) { + for (var7 = 0; var7 < 3; ++var7) { + this.addSlotToContainer(new Slot(this.craftMatrix, var7 + var6 * 3, 30 + var7 * 18, 17 + var6 * 18)); + } + } + + for (var6 = 0; var6 < 3; ++var6) { + for (var7 = 0; var7 < 9; ++var7) { + this.addSlotToContainer( + new Slot(par1InventoryPlayer, var7 + var6 * 9 + 9, 8 + var7 * 18, 84 + var6 * 18)); + } + } + + for (var6 = 0; var6 < 9; ++var6) { + this.addSlotToContainer(new Slot(par1InventoryPlayer, var6, 8 + var6 * 18, 142)); + } + + this.onCraftMatrixChanged(this.craftMatrix); + } + + /** + * Callback for when the crafting matrix is changed. + */ + public void onCraftMatrixChanged(IInventory par1IInventory) { + this.craftResult.setInventorySlotContents(0, + CraftingManager.getInstance().findMatchingRecipe(this.craftMatrix, this.worldObj)); + } + + /** + * Callback for when the crafting gui is closed. + */ + public void onCraftGuiClosed(EntityPlayer par1EntityPlayer) { + super.onCraftGuiClosed(par1EntityPlayer); + + if (!this.worldObj.isRemote) { + for (int var2 = 0; var2 < 9; ++var2) { + ItemStack var3 = this.craftMatrix.getStackInSlotOnClosing(var2); + + if (var3 != null) { + par1EntityPlayer.dropPlayerItem(var3); + } + } + } + } + + public boolean canInteractWith(EntityPlayer par1EntityPlayer) { + return this.worldObj.getBlockId(this.posX, this.posY, this.posZ) != Block.workbench.blockID ? false + : par1EntityPlayer.getDistanceSq((double) this.posX + 0.5D, (double) this.posY + 0.5D, + (double) this.posZ + 0.5D) <= 64.0D; + } + + /** + * Take a stack from the specified inventory slot. + */ + public ItemStack transferStackInSlot(EntityPlayer par1EntityPlayer, int par2) { + ItemStack var3 = null; + Slot var4 = (Slot) this.inventorySlots.get(par2); + + if (var4 != null && var4.getHasStack()) { + ItemStack var5 = var4.getStack(); + var3 = var5.copy(); + + if (par2 == 0) { + if (!this.mergeItemStack(var5, 10, 46, true)) { + return null; + } + + var4.onSlotChange(var5, var3); + } else if (par2 >= 10 && par2 < 37) { + if (!this.mergeItemStack(var5, 37, 46, false)) { + return null; + } + } else if (par2 >= 37 && par2 < 46) { + if (!this.mergeItemStack(var5, 10, 37, false)) { + return null; + } + } else if (!this.mergeItemStack(var5, 10, 46, false)) { + return null; + } + + if (var5.stackSize == 0) { + var4.putStack((ItemStack) null); + } else { + var4.onSlotChanged(); + } + + if (var5.stackSize == var3.stackSize) { + return null; + } + + var4.onPickupFromSlot(par1EntityPlayer, var5); + } + + return var3; + } + + public boolean func_94530_a(ItemStack par1ItemStack, Slot par2Slot) { + return par2Slot.inventory != this.craftResult && super.func_94530_a(par1ItemStack, par2Slot); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ConvertingProgressUpdate.java b/sp-server/src/main/java/net/minecraft/src/ConvertingProgressUpdate.java new file mode 100644 index 0000000..4ffd3f8 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ConvertingProgressUpdate.java @@ -0,0 +1,39 @@ +package net.minecraft.src; + +import net.minecraft.server.MinecraftServer; + +public class ConvertingProgressUpdate implements IProgressUpdate { + private long field_96245_b; + + /** Reference to the MinecraftServer object. */ + final MinecraftServer mcServer; + + public ConvertingProgressUpdate(MinecraftServer par1) { + this.mcServer = par1; + this.field_96245_b = System.currentTimeMillis(); + } + + /** + * Shows the 'Saving level' string. + */ + public void displaySavingString(String par1Str) { + } + + /** + * Updates the progress bar on the loading screen to the specified amount. Args: + * loadProgress + */ + public void setLoadingProgress(int par1) { + if (System.currentTimeMillis() - this.field_96245_b >= 1000L) { + this.field_96245_b = System.currentTimeMillis(); + this.mcServer.getLogAgent().func_98233_a("Converting... " + par1 + "%"); + } + } + + /** + * Displays a string on the loading screen supposed to indicate what is being + * done currently. + */ + public void displayLoadingString(String par1Str) { + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CraftingManager.java b/sp-server/src/main/java/net/minecraft/src/CraftingManager.java new file mode 100644 index 0000000..6126440 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CraftingManager.java @@ -0,0 +1,342 @@ +package net.minecraft.src; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; + +public class CraftingManager { + /** The static instance of this class */ + private static final CraftingManager instance = new CraftingManager(); + + /** A list of all the recipes added */ + private List recipes = new ArrayList(); + + /** + * Returns the static instance of this class + */ + public static final CraftingManager getInstance() { + return instance; + } + + private CraftingManager() { + (new RecipesTools()).addRecipes(this); + (new RecipesWeapons()).addRecipes(this); + (new RecipesIngots()).addRecipes(this); + (new RecipesFood()).addRecipes(this); + (new RecipesCrafting()).addRecipes(this); + (new RecipesArmor()).addRecipes(this); + (new RecipesDyes()).addRecipes(this); + this.recipes.add(new RecipesArmorDyes()); + this.recipes.add(new RecipesMapCloning()); + this.recipes.add(new RecipesMapExtending()); + this.recipes.add(new RecipeFireworks()); + this.addRecipe(new ItemStack(Item.paper, 3), new Object[] { "###", '#', Item.reed }); + this.addShapelessRecipe(new ItemStack(Item.book, 1), + new Object[] { Item.paper, Item.paper, Item.paper, Item.leather }); + this.addShapelessRecipe(new ItemStack(Item.writableBook, 1), + new Object[] { Item.book, new ItemStack(Item.dyePowder, 1, 0), Item.feather }); + this.addRecipe(new ItemStack(Block.fence, 2), new Object[] { "###", "###", '#', Item.stick }); + this.addRecipe(new ItemStack(Block.cobblestoneWall, 6, 0), + new Object[] { "###", "###", '#', Block.cobblestone }); + this.addRecipe(new ItemStack(Block.cobblestoneWall, 6, 1), + new Object[] { "###", "###", '#', Block.cobblestoneMossy }); + this.addRecipe(new ItemStack(Block.netherFence, 6), new Object[] { "###", "###", '#', Block.netherBrick }); + this.addRecipe(new ItemStack(Block.fenceGate, 1), + new Object[] { "#W#", "#W#", '#', Item.stick, 'W', Block.planks }); + this.addRecipe(new ItemStack(Block.jukebox, 1), + new Object[] { "###", "#X#", "###", '#', Block.planks, 'X', Item.diamond }); + this.addRecipe(new ItemStack(Block.music, 1), + new Object[] { "###", "#X#", "###", '#', Block.planks, 'X', Item.redstone }); + this.addRecipe(new ItemStack(Block.bookShelf, 1), + new Object[] { "###", "XXX", "###", '#', Block.planks, 'X', Item.book }); + this.addRecipe(new ItemStack(Block.blockSnow, 1), new Object[] { "##", "##", '#', Item.snowball }); + this.addRecipe(new ItemStack(Block.snow, 6), new Object[] { "###", '#', Block.blockSnow }); + this.addRecipe(new ItemStack(Block.blockClay, 1), new Object[] { "##", "##", '#', Item.clay }); + this.addRecipe(new ItemStack(Block.brick, 1), new Object[] { "##", "##", '#', Item.brick }); + this.addRecipe(new ItemStack(Block.glowStone, 1), new Object[] { "##", "##", '#', Item.lightStoneDust }); + this.addRecipe(new ItemStack(Block.blockNetherQuartz, 1), new Object[] { "##", "##", '#', Item.netherQuartz }); + this.addRecipe(new ItemStack(Block.cloth, 1), new Object[] { "##", "##", '#', Item.silk }); + this.addRecipe(new ItemStack(Block.tnt, 1), + new Object[] { "X#X", "#X#", "X#X", 'X', Item.gunpowder, '#', Block.sand }); + this.addRecipe(new ItemStack(Block.stoneSingleSlab, 6, 3), new Object[] { "###", '#', Block.cobblestone }); + this.addRecipe(new ItemStack(Block.stoneSingleSlab, 6, 0), new Object[] { "###", '#', Block.stone }); + this.addRecipe(new ItemStack(Block.stoneSingleSlab, 6, 1), new Object[] { "###", '#', Block.sandStone }); + this.addRecipe(new ItemStack(Block.stoneSingleSlab, 6, 4), new Object[] { "###", '#', Block.brick }); + this.addRecipe(new ItemStack(Block.stoneSingleSlab, 6, 5), new Object[] { "###", '#', Block.stoneBrick }); + this.addRecipe(new ItemStack(Block.stoneSingleSlab, 6, 6), new Object[] { "###", '#', Block.netherBrick }); + this.addRecipe(new ItemStack(Block.stoneSingleSlab, 6, 7), + new Object[] { "###", '#', Block.blockNetherQuartz }); + this.addRecipe(new ItemStack(Block.woodSingleSlab, 6, 0), + new Object[] { "###", '#', new ItemStack(Block.planks, 1, 0) }); + this.addRecipe(new ItemStack(Block.woodSingleSlab, 6, 2), + new Object[] { "###", '#', new ItemStack(Block.planks, 1, 2) }); + this.addRecipe(new ItemStack(Block.woodSingleSlab, 6, 1), + new Object[] { "###", '#', new ItemStack(Block.planks, 1, 1) }); + this.addRecipe(new ItemStack(Block.woodSingleSlab, 6, 3), + new Object[] { "###", '#', new ItemStack(Block.planks, 1, 3) }); + this.addRecipe(new ItemStack(Block.ladder, 3), new Object[] { "# #", "###", "# #", '#', Item.stick }); + this.addRecipe(new ItemStack(Item.doorWood, 1), new Object[] { "##", "##", "##", '#', Block.planks }); + this.addRecipe(new ItemStack(Block.trapdoor, 2), new Object[] { "###", "###", '#', Block.planks }); + this.addRecipe(new ItemStack(Item.doorIron, 1), new Object[] { "##", "##", "##", '#', Item.ingotIron }); + this.addRecipe(new ItemStack(Item.sign, 3), + new Object[] { "###", "###", " X ", '#', Block.planks, 'X', Item.stick }); + this.addRecipe(new ItemStack(Item.cake, 1), new Object[] { "AAA", "BEB", "CCC", 'A', Item.bucketMilk, 'B', + Item.sugar, 'C', Item.wheat, 'E', Item.egg }); + this.addRecipe(new ItemStack(Item.sugar, 1), new Object[] { "#", '#', Item.reed }); + this.addRecipe(new ItemStack(Block.planks, 4, 0), new Object[] { "#", '#', new ItemStack(Block.wood, 1, 0) }); + this.addRecipe(new ItemStack(Block.planks, 4, 1), new Object[] { "#", '#', new ItemStack(Block.wood, 1, 1) }); + this.addRecipe(new ItemStack(Block.planks, 4, 2), new Object[] { "#", '#', new ItemStack(Block.wood, 1, 2) }); + this.addRecipe(new ItemStack(Block.planks, 4, 3), new Object[] { "#", '#', new ItemStack(Block.wood, 1, 3) }); + this.addRecipe(new ItemStack(Item.stick, 4), new Object[] { "#", "#", '#', Block.planks }); + this.addRecipe(new ItemStack(Block.torchWood, 4), new Object[] { "X", "#", 'X', Item.coal, '#', Item.stick }); + this.addRecipe(new ItemStack(Block.torchWood, 4), + new Object[] { "X", "#", 'X', new ItemStack(Item.coal, 1, 1), '#', Item.stick }); + this.addRecipe(new ItemStack(Item.bowlEmpty, 4), new Object[] { "# #", " # ", '#', Block.planks }); + this.addRecipe(new ItemStack(Item.glassBottle, 3), new Object[] { "# #", " # ", '#', Block.glass }); + this.addRecipe(new ItemStack(Block.rail, 16), + new Object[] { "X X", "X#X", "X X", 'X', Item.ingotIron, '#', Item.stick }); + this.addRecipe(new ItemStack(Block.railPowered, 6), + new Object[] { "X X", "X#X", "XRX", 'X', Item.ingotGold, 'R', Item.redstone, '#', Item.stick }); + this.addRecipe(new ItemStack(Block.railActivator, 6), new Object[] { "XSX", "X#X", "XSX", 'X', Item.ingotIron, + '#', Block.torchRedstoneActive, 'S', Item.stick }); + this.addRecipe(new ItemStack(Block.railDetector, 6), new Object[] { "X X", "X#X", "XRX", 'X', Item.ingotIron, + 'R', Item.redstone, '#', Block.pressurePlateStone }); + this.addRecipe(new ItemStack(Item.minecartEmpty, 1), new Object[] { "# #", "###", '#', Item.ingotIron }); + this.addRecipe(new ItemStack(Item.cauldron, 1), new Object[] { "# #", "# #", "###", '#', Item.ingotIron }); + this.addRecipe(new ItemStack(Item.brewingStand, 1), + new Object[] { " B ", "###", '#', Block.cobblestone, 'B', Item.blazeRod }); + this.addRecipe(new ItemStack(Block.pumpkinLantern, 1), + new Object[] { "A", "B", 'A', Block.pumpkin, 'B', Block.torchWood }); + this.addRecipe(new ItemStack(Item.minecartCrate, 1), + new Object[] { "A", "B", 'A', Block.chest, 'B', Item.minecartEmpty }); + this.addRecipe(new ItemStack(Item.minecartPowered, 1), + new Object[] { "A", "B", 'A', Block.furnaceIdle, 'B', Item.minecartEmpty }); + this.addRecipe(new ItemStack(Item.tntMinecart, 1), + new Object[] { "A", "B", 'A', Block.tnt, 'B', Item.minecartEmpty }); + this.addRecipe(new ItemStack(Item.hopperMinecart, 1), + new Object[] { "A", "B", 'A', Block.hopperBlock, 'B', Item.minecartEmpty }); + this.addRecipe(new ItemStack(Item.boat, 1), new Object[] { "# #", "###", '#', Block.planks }); + this.addRecipe(new ItemStack(Item.bucketEmpty, 1), new Object[] { "# #", " # ", '#', Item.ingotIron }); + this.addRecipe(new ItemStack(Item.flowerPot, 1), new Object[] { "# #", " # ", '#', Item.brick }); + this.addRecipe(new ItemStack(Item.flintAndSteel, 1), + new Object[] { "A ", " B", 'A', Item.ingotIron, 'B', Item.flint }); + this.addRecipe(new ItemStack(Item.bread, 1), new Object[] { "###", '#', Item.wheat }); + this.addRecipe(new ItemStack(Block.stairsWoodOak, 4), + new Object[] { "# ", "## ", "###", '#', new ItemStack(Block.planks, 1, 0) }); + this.addRecipe(new ItemStack(Block.stairsWoodBirch, 4), + new Object[] { "# ", "## ", "###", '#', new ItemStack(Block.planks, 1, 2) }); + this.addRecipe(new ItemStack(Block.stairsWoodSpruce, 4), + new Object[] { "# ", "## ", "###", '#', new ItemStack(Block.planks, 1, 1) }); + this.addRecipe(new ItemStack(Block.stairsWoodJungle, 4), + new Object[] { "# ", "## ", "###", '#', new ItemStack(Block.planks, 1, 3) }); + this.addRecipe(new ItemStack(Item.fishingRod, 1), + new Object[] { " #", " #X", "# X", '#', Item.stick, 'X', Item.silk }); + this.addRecipe(new ItemStack(Item.carrotOnAStick, 1), + new Object[] { "# ", " X", '#', Item.fishingRod, 'X', Item.carrot }).func_92100_c(); + this.addRecipe(new ItemStack(Block.stairsCobblestone, 4), + new Object[] { "# ", "## ", "###", '#', Block.cobblestone }); + this.addRecipe(new ItemStack(Block.stairsBrick, 4), new Object[] { "# ", "## ", "###", '#', Block.brick }); + this.addRecipe(new ItemStack(Block.stairsStoneBrick, 4), + new Object[] { "# ", "## ", "###", '#', Block.stoneBrick }); + this.addRecipe(new ItemStack(Block.stairsNetherBrick, 4), + new Object[] { "# ", "## ", "###", '#', Block.netherBrick }); + this.addRecipe(new ItemStack(Block.stairsSandStone, 4), + new Object[] { "# ", "## ", "###", '#', Block.sandStone }); + this.addRecipe(new ItemStack(Block.stairsNetherQuartz, 4), + new Object[] { "# ", "## ", "###", '#', Block.blockNetherQuartz }); + this.addRecipe(new ItemStack(Item.painting, 1), + new Object[] { "###", "#X#", "###", '#', Item.stick, 'X', Block.cloth }); + this.addRecipe(new ItemStack(Item.itemFrame, 1), + new Object[] { "###", "#X#", "###", '#', Item.stick, 'X', Item.leather }); + this.addRecipe(new ItemStack(Item.appleGold, 1, 0), + new Object[] { "###", "#X#", "###", '#', Item.goldNugget, 'X', Item.appleRed }); + this.addRecipe(new ItemStack(Item.appleGold, 1, 1), + new Object[] { "###", "#X#", "###", '#', Block.blockGold, 'X', Item.appleRed }); + this.addRecipe(new ItemStack(Item.goldenCarrot, 1, 0), + new Object[] { "###", "#X#", "###", '#', Item.goldNugget, 'X', Item.carrot }); + this.addRecipe(new ItemStack(Block.lever, 1), + new Object[] { "X", "#", '#', Block.cobblestone, 'X', Item.stick }); + this.addRecipe(new ItemStack(Block.tripWireSource, 2), + new Object[] { "I", "S", "#", '#', Block.planks, 'S', Item.stick, 'I', Item.ingotIron }); + this.addRecipe(new ItemStack(Block.torchRedstoneActive, 1), + new Object[] { "X", "#", '#', Item.stick, 'X', Item.redstone }); + this.addRecipe(new ItemStack(Item.redstoneRepeater, 1), + new Object[] { "#X#", "III", '#', Block.torchRedstoneActive, 'X', Item.redstone, 'I', Block.stone }); + this.addRecipe(new ItemStack(Item.comparator, 1), new Object[] { " # ", "#X#", "III", '#', + Block.torchRedstoneActive, 'X', Item.netherQuartz, 'I', Block.stone }); + this.addRecipe(new ItemStack(Item.pocketSundial, 1), + new Object[] { " # ", "#X#", " # ", '#', Item.ingotGold, 'X', Item.redstone }); + this.addRecipe(new ItemStack(Item.compass, 1), + new Object[] { " # ", "#X#", " # ", '#', Item.ingotIron, 'X', Item.redstone }); + this.addRecipe(new ItemStack(Item.emptyMap, 1), + new Object[] { "###", "#X#", "###", '#', Item.paper, 'X', Item.compass }); + this.addRecipe(new ItemStack(Block.stoneButton, 1), new Object[] { "#", '#', Block.stone }); + this.addRecipe(new ItemStack(Block.woodenButton, 1), new Object[] { "#", '#', Block.planks }); + this.addRecipe(new ItemStack(Block.pressurePlateStone, 1), new Object[] { "##", '#', Block.stone }); + this.addRecipe(new ItemStack(Block.pressurePlatePlanks, 1), new Object[] { "##", '#', Block.planks }); + this.addRecipe(new ItemStack(Block.pressurePlateIron, 1), new Object[] { "##", '#', Item.ingotIron }); + this.addRecipe(new ItemStack(Block.pressurePlateGold, 1), new Object[] { "##", '#', Item.ingotGold }); + this.addRecipe(new ItemStack(Block.dispenser, 1), + new Object[] { "###", "#X#", "#R#", '#', Block.cobblestone, 'X', Item.bow, 'R', Item.redstone }); + this.addRecipe(new ItemStack(Block.dropper, 1), + new Object[] { "###", "# #", "#R#", '#', Block.cobblestone, 'R', Item.redstone }); + this.addRecipe(new ItemStack(Block.pistonBase, 1), new Object[] { "TTT", "#X#", "#R#", '#', Block.cobblestone, + 'X', Item.ingotIron, 'R', Item.redstone, 'T', Block.planks }); + this.addRecipe(new ItemStack(Block.pistonStickyBase, 1), + new Object[] { "S", "P", 'S', Item.slimeBall, 'P', Block.pistonBase }); + this.addRecipe(new ItemStack(Item.bed, 1), new Object[] { "###", "XXX", '#', Block.cloth, 'X', Block.planks }); + this.addRecipe(new ItemStack(Block.enchantmentTable, 1), + new Object[] { " B ", "D#D", "###", '#', Block.obsidian, 'B', Item.book, 'D', Item.diamond }); + this.addRecipe(new ItemStack(Block.anvil, 1), + new Object[] { "III", " i ", "iii", 'I', Block.blockIron, 'i', Item.ingotIron }); + this.addShapelessRecipe(new ItemStack(Item.eyeOfEnder, 1), new Object[] { Item.enderPearl, Item.blazePowder }); + this.addShapelessRecipe(new ItemStack(Item.fireballCharge, 3), + new Object[] { Item.gunpowder, Item.blazePowder, Item.coal }); + this.addShapelessRecipe(new ItemStack(Item.fireballCharge, 3), + new Object[] { Item.gunpowder, Item.blazePowder, new ItemStack(Item.coal, 1, 1) }); + this.addRecipe(new ItemStack(Block.daylightSensor), new Object[] { "GGG", "QQQ", "WWW", 'G', Block.glass, 'Q', + Item.netherQuartz, 'W', Block.woodSingleSlab }); + this.addRecipe(new ItemStack(Block.hopperBlock), + new Object[] { "I I", "ICI", " I ", 'I', Item.ingotIron, 'C', Block.chest }); + Collections.sort(this.recipes, new RecipeSorter(this)); + System.out.println(this.recipes.size() + " recipes"); + } + + ShapedRecipes addRecipe(ItemStack par1ItemStack, Object... par2ArrayOfObj) { + String var3 = ""; + int var4 = 0; + int var5 = 0; + int var6 = 0; + + if (par2ArrayOfObj[var4] instanceof String[]) { + String[] var7 = (String[]) ((String[]) par2ArrayOfObj[var4++]); + + for (int var8 = 0; var8 < var7.length; ++var8) { + String var9 = var7[var8]; + ++var6; + var5 = var9.length(); + var3 = var3 + var9; + } + } else { + while (par2ArrayOfObj[var4] instanceof String) { + String var11 = (String) par2ArrayOfObj[var4++]; + ++var6; + var5 = var11.length(); + var3 = var3 + var11; + } + } + + HashMap var12; + + for (var12 = new HashMap(); var4 < par2ArrayOfObj.length; var4 += 2) { + Character var13 = (Character) par2ArrayOfObj[var4]; + ItemStack var15 = null; + + if (par2ArrayOfObj[var4 + 1] instanceof Item) { + var15 = new ItemStack((Item) par2ArrayOfObj[var4 + 1]); + } else if (par2ArrayOfObj[var4 + 1] instanceof Block) { + var15 = new ItemStack((Block) par2ArrayOfObj[var4 + 1], 1, 32767); + } else if (par2ArrayOfObj[var4 + 1] instanceof ItemStack) { + var15 = (ItemStack) par2ArrayOfObj[var4 + 1]; + } + + var12.put(var13, var15); + } + + ItemStack[] var14 = new ItemStack[var5 * var6]; + + for (int var16 = 0; var16 < var5 * var6; ++var16) { + char var10 = var3.charAt(var16); + + if (var12.containsKey(Character.valueOf(var10))) { + var14[var16] = ((ItemStack) var12.get(Character.valueOf(var10))).copy(); + } else { + var14[var16] = null; + } + } + + ShapedRecipes var17 = new ShapedRecipes(var5, var6, var14, par1ItemStack); + this.recipes.add(var17); + return var17; + } + + void addShapelessRecipe(ItemStack par1ItemStack, Object... par2ArrayOfObj) { + ArrayList var3 = new ArrayList(); + Object[] var4 = par2ArrayOfObj; + int var5 = par2ArrayOfObj.length; + + for (int var6 = 0; var6 < var5; ++var6) { + Object var7 = var4[var6]; + + if (var7 instanceof ItemStack) { + var3.add(((ItemStack) var7).copy()); + } else if (var7 instanceof Item) { + var3.add(new ItemStack((Item) var7)); + } else { + if (!(var7 instanceof Block)) { + throw new RuntimeException("Invalid shapeless recipy!"); + } + + var3.add(new ItemStack((Block) var7)); + } + } + + this.recipes.add(new ShapelessRecipes(par1ItemStack, var3)); + } + + public ItemStack findMatchingRecipe(InventoryCrafting par1InventoryCrafting, World par2World) { + int var3 = 0; + ItemStack var4 = null; + ItemStack var5 = null; + int var6; + + for (var6 = 0; var6 < par1InventoryCrafting.getSizeInventory(); ++var6) { + ItemStack var7 = par1InventoryCrafting.getStackInSlot(var6); + + if (var7 != null) { + if (var3 == 0) { + var4 = var7; + } + + if (var3 == 1) { + var5 = var7; + } + + ++var3; + } + } + + if (var3 == 2 && var4.itemID == var5.itemID && var4.stackSize == 1 && var5.stackSize == 1 + && Item.itemsList[var4.itemID].isDamageable()) { + Item var11 = Item.itemsList[var4.itemID]; + int var13 = var11.getMaxDamage() - var4.getItemDamageForDisplay(); + int var8 = var11.getMaxDamage() - var5.getItemDamageForDisplay(); + int var9 = var13 + var8 + var11.getMaxDamage() * 5 / 100; + int var10 = var11.getMaxDamage() - var9; + + if (var10 < 0) { + var10 = 0; + } + + return new ItemStack(var4.itemID, 1, var10); + } else { + for (var6 = 0; var6 < this.recipes.size(); ++var6) { + IRecipe var12 = (IRecipe) this.recipes.get(var6); + + if (var12.matches(par1InventoryCrafting, par2World)) { + return var12.getCraftingResult(par1InventoryCrafting); + } + } + + return null; + } + } + + /** + * returns the List<> of all recipes + */ + public List getRecipeList() { + return this.recipes; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CrashReport.java b/sp-server/src/main/java/net/minecraft/src/CrashReport.java new file mode 100644 index 0000000..85f2cfb --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CrashReport.java @@ -0,0 +1,268 @@ +package net.minecraft.src; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.Iterator; +import java.util.List; + +public class CrashReport { + /** Description of the crash report. */ + private final String description; + + /** The Throwable that is the "cause" for this crash and Crash Report. */ + private final Throwable cause; + private final CrashReportCategory field_85061_c = new CrashReportCategory(this, "System Details"); + + /** Holds the keys and values of all crash report sections. */ + private final List crashReportSections = new ArrayList(); + + /** File of crash report. */ + private File crashReportFile = null; + private boolean field_85059_f = true; + private StackTraceElement[] field_85060_g = new StackTraceElement[0]; + + public CrashReport(String par1Str, Throwable par2Throwable) { + this.description = par1Str; + this.cause = par2Throwable; + this.populateEnvironment(); + } + + /** + * Populates this crash report with initial information about the running server + * and operating system / java environment + */ + private void populateEnvironment() { + this.field_85061_c.addCrashSectionCallable("Minecraft Version", new CallableMinecraftVersion(this)); + this.field_85061_c.addCrashSectionCallable("Operating System", new CallableOSInfo(this)); + this.field_85061_c.addCrashSectionCallable("Java Version", new CallableJavaInfo(this)); + this.field_85061_c.addCrashSectionCallable("Java VM Version", new CallableJavaInfo2(this)); + this.field_85061_c.addCrashSectionCallable("Memory", new CallableMemoryInfo(this)); + this.field_85061_c.addCrashSectionCallable("JVM Flags", new CallableJVMFlags(this)); + this.field_85061_c.addCrashSectionCallable("AABB Pool Size", new CallableCrashMemoryReport(this)); + this.field_85061_c.addCrashSectionCallable("Suspicious classes", new CallableSuspiciousClasses(this)); + this.field_85061_c.addCrashSectionCallable("IntCache", new CallableIntCache(this)); + } + + /** + * Returns the description of the Crash Report. + */ + public String getDescription() { + return this.description; + } + + /** + * Returns the Throwable object that is the cause for the crash and Crash + * Report. + */ + public Throwable getCrashCause() { + return this.cause; + } + + /** + * Gets the various sections of the crash report into the given StringBuilder + */ + public void getSectionsInStringBuilder(StringBuilder par1StringBuilder) { + if (this.field_85060_g != null && this.field_85060_g.length > 0) { + par1StringBuilder.append("-- Head --\n"); + par1StringBuilder.append("Stacktrace:\n"); + StackTraceElement[] var2 = this.field_85060_g; + int var3 = var2.length; + + for (int var4 = 0; var4 < var3; ++var4) { + StackTraceElement var5 = var2[var4]; + par1StringBuilder.append("\t").append("at ").append(var5.toString()); + par1StringBuilder.append("\n"); + } + + par1StringBuilder.append("\n"); + } + + Iterator var6 = this.crashReportSections.iterator(); + + while (var6.hasNext()) { + CrashReportCategory var7 = (CrashReportCategory) var6.next(); + var7.func_85072_a(par1StringBuilder); + par1StringBuilder.append("\n\n"); + } + + this.field_85061_c.func_85072_a(par1StringBuilder); + } + + /** + * Gets the stack trace of the Throwable that caused this crash report, or if + * that fails, the cause .toString(). + */ + public String getCauseStackTraceOrString() { + StringWriter var1 = null; + PrintWriter var2 = null; + String var3 = this.cause.toString(); + + try { + var1 = new StringWriter(); + var2 = new PrintWriter(var1); + this.cause.printStackTrace(var2); + var3 = var1.toString(); + } finally { + try { + if (var1 != null) { + var1.close(); + } + + if (var2 != null) { + var2.close(); + } + } catch (IOException var10) { + ; + } + } + + return var3; + } + + /** + * Gets the complete report with headers, stack trace, and different sections as + * a string. + */ + public String getCompleteReport() { + StringBuilder var1 = new StringBuilder(); + var1.append("---- Minecraft Crash Report ----\n"); + var1.append("// "); + var1.append(getWittyComment()); + var1.append("\n\n"); + var1.append("Time: "); + var1.append((new SimpleDateFormat()).format(new Date())); + var1.append("\n"); + var1.append("Description: "); + var1.append(this.description); + var1.append("\n\n"); + var1.append(this.getCauseStackTraceOrString()); + var1.append("\n\nA detailed walkthrough of the error, its code path and all known details is as follows:\n"); + + for (int var2 = 0; var2 < 87; ++var2) { + var1.append("-"); + } + + var1.append("\n\n"); + this.getSectionsInStringBuilder(var1); + return var1.toString(); + } + + /** + * Saves the complete crash report to the given File. + */ + public boolean saveToFile(File par1File, ILogAgent par2ILogAgent) { + if (this.crashReportFile != null) { + return false; + } else { + if (par1File.getParentFile() != null) { + par1File.getParentFile().mkdirs(); + } + + try { + FileWriter var3 = new FileWriter(par1File); + var3.write(this.getCompleteReport()); + var3.close(); + this.crashReportFile = par1File; + return true; + } catch (Throwable var4) { + par2ILogAgent.logSevereException("Could not save crash report to " + par1File, var4); + return false; + } + } + } + + public CrashReportCategory func_85056_g() { + return this.field_85061_c; + } + + /** + * Creates a CrashReportCategory + */ + public CrashReportCategory makeCategory(String par1Str) { + return this.makeCategoryDepth(par1Str, 1); + } + + /** + * Creates a CrashReportCategory for the given stack trace depth + */ + public CrashReportCategory makeCategoryDepth(String par1Str, int par2) { + CrashReportCategory var3 = new CrashReportCategory(this, par1Str); + + if (this.field_85059_f) { + int var4 = var3.func_85073_a(par2); + StackTraceElement[] var5 = this.cause.getStackTrace(); + StackTraceElement var6 = null; + StackTraceElement var7 = null; + + if (var5 != null && var5.length - var4 < var5.length) { + var6 = var5[var5.length - var4]; + + if (var5.length + 1 - var4 < var5.length) { + var7 = var5[var5.length + 1 - var4]; + } + } + + this.field_85059_f = var3.func_85069_a(var6, var7); + + if (var4 > 0 && !this.crashReportSections.isEmpty()) { + CrashReportCategory var8 = (CrashReportCategory) this.crashReportSections + .get(this.crashReportSections.size() - 1); + var8.func_85070_b(var4); + } else if (var5 != null && var5.length >= var4) { + this.field_85060_g = new StackTraceElement[var5.length - var4]; + System.arraycopy(var5, 0, this.field_85060_g, 0, this.field_85060_g.length); + } else { + this.field_85059_f = false; + } + } + + this.crashReportSections.add(var3); + return var3; + } + + /** + * Gets a random witty comment for inclusion in this CrashReport + */ + private static String getWittyComment() { + String[] var0 = new String[] { "Who set us up the TNT?", + "Everything\'s going to plan. No, really, that was supposed to happen.", "Uh... Did I do that?", + "Oops.", "Why did you do that?", "I feel sad now :(", "My bad.", "I\'m sorry, Dave.", + "I let you down. Sorry :(", "On the bright side, I bought you a teddy bear!", "Daisy, daisy...", + "Oh - I know what I did wrong!", "Hey, that tickles! Hehehe!", "I blame Dinnerbone.", + "You should try our sister game, Minceraft!", "Don\'t be sad. I\'ll do better next time, I promise!", + "Don\'t be sad, have a hug! <3", "I just don\'t know what went wrong :(", "Shall we play a game?", + "Quite honestly, I wouldn\'t worry myself about that.", "I bet Cylons wouldn\'t have this problem.", + "Sorry :(", "Surprise! Haha. Well, this is awkward.", "Would you like a cupcake?", + "Hi. I\'m Minecraft, and I\'m a crashaholic.", "Ooh. Shiny.", "This doesn\'t make any sense!", + "Why is it breaking :(", "Don\'t do that.", "Ouch. That hurt :(", "You\'re mean.", + "This is a token for 1 free hug. Redeem at your nearest Mojangsta: [~~HUG~~]", + "There are four lights!" }; + + try { + return var0[(int) (System.nanoTime() % (long) var0.length)]; + } catch (Throwable var2) { + return "Witty comment unavailable :("; + } + } + + /** + * Creates a crash report for the exception + */ + public static CrashReport makeCrashReport(Throwable par0Throwable, String par1Str) { + CrashReport var2; + + if (par0Throwable instanceof ReportedException) { + var2 = ((ReportedException) par0Throwable).getCrashReport(); + } else { + var2 = new CrashReport(par1Str, par0Throwable); + } + + return var2; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CrashReportCategory.java b/sp-server/src/main/java/net/minecraft/src/CrashReportCategory.java new file mode 100644 index 0000000..9e0d871 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CrashReportCategory.java @@ -0,0 +1,181 @@ +package net.minecraft.src; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.concurrent.Callable; + +public class CrashReportCategory { + private final CrashReport theCrashReport; + private final String field_85076_b; + private final List field_85077_c = new ArrayList(); + private StackTraceElement[] stackTrace = new StackTraceElement[0]; + + public CrashReportCategory(CrashReport par1CrashReport, String par2Str) { + this.theCrashReport = par1CrashReport; + this.field_85076_b = par2Str; + } + + /** + * Returns a string with world information on location.Args:x,y,z + */ + public static String getLocationInfo(int par0, int par1, int par2) { + StringBuilder var3 = new StringBuilder(); + + try { + var3.append(String.format("World: (%d,%d,%d)", + new Object[] { Integer.valueOf(par0), Integer.valueOf(par1), Integer.valueOf(par2) })); + } catch (Throwable var16) { + var3.append("(Error finding world loc)"); + } + + var3.append(", "); + int var4; + int var5; + int var6; + int var7; + int var8; + int var9; + int var10; + int var11; + int var12; + + try { + var4 = par0 >> 4; + var5 = par2 >> 4; + var6 = par0 & 15; + var7 = par1 >> 4; + var8 = par2 & 15; + var9 = var4 << 4; + var10 = var5 << 4; + var11 = (var4 + 1 << 4) - 1; + var12 = (var5 + 1 << 4) - 1; + var3.append(String.format("Chunk: (at %d,%d,%d in %d,%d; contains blocks %d,0,%d to %d,255,%d)", + new Object[] { Integer.valueOf(var6), Integer.valueOf(var7), Integer.valueOf(var8), + Integer.valueOf(var4), Integer.valueOf(var5), Integer.valueOf(var9), Integer.valueOf(var10), + Integer.valueOf(var11), Integer.valueOf(var12) })); + } catch (Throwable var15) { + var3.append("(Error finding chunk loc)"); + } + + var3.append(", "); + + try { + var4 = par0 >> 9; + var5 = par2 >> 9; + var6 = var4 << 5; + var7 = var5 << 5; + var8 = (var4 + 1 << 5) - 1; + var9 = (var5 + 1 << 5) - 1; + var10 = var4 << 9; + var11 = var5 << 9; + var12 = (var4 + 1 << 9) - 1; + int var13 = (var5 + 1 << 9) - 1; + var3.append(String.format("Region: (%d,%d; contains chunks %d,%d to %d,%d, blocks %d,0,%d to %d,255,%d)", + new Object[] { Integer.valueOf(var4), Integer.valueOf(var5), Integer.valueOf(var6), + Integer.valueOf(var7), Integer.valueOf(var8), Integer.valueOf(var9), Integer.valueOf(var10), + Integer.valueOf(var11), Integer.valueOf(var12), Integer.valueOf(var13) })); + } catch (Throwable var14) { + var3.append("(Error finding world loc)"); + } + + return var3.toString(); + } + + /** + * Adds a Crashreport section with the given name with the value set to the + * result of the given Callable; + */ + public void addCrashSectionCallable(String par1Str, Callable par2Callable) { + try { + this.addCrashSection(par1Str, par2Callable.call()); + } catch (Throwable var4) { + this.addCrashSectionThrowable(par1Str, var4); + } + } + + /** + * Adds a Crashreport section with the given name with the given value (convered + * .toString()) + */ + public void addCrashSection(String par1Str, Object par2Obj) { + this.field_85077_c.add(new CrashReportCategoryEntry(par1Str, par2Obj)); + } + + /** + * Adds a Crashreport section with the given name with the given Throwable + */ + public void addCrashSectionThrowable(String par1Str, Throwable par2Throwable) { + this.addCrashSection(par1Str, par2Throwable); + } + + public int func_85073_a(int par1) { + StackTraceElement[] var2 = Thread.currentThread().getStackTrace(); + this.stackTrace = new StackTraceElement[var2.length - 3 - par1]; + System.arraycopy(var2, 3 + par1, this.stackTrace, 0, this.stackTrace.length); + return this.stackTrace.length; + } + + public boolean func_85069_a(StackTraceElement par1StackTraceElement, StackTraceElement par2StackTraceElement) { + if (this.stackTrace.length != 0 && par1StackTraceElement != null) { + StackTraceElement var3 = this.stackTrace[0]; + + if (var3.isNativeMethod() == par1StackTraceElement.isNativeMethod() + && var3.getClassName().equals(par1StackTraceElement.getClassName()) + && var3.getFileName().equals(par1StackTraceElement.getFileName()) + && var3.getMethodName().equals(par1StackTraceElement.getMethodName())) { + if (par2StackTraceElement != null != this.stackTrace.length > 1) { + return false; + } else if (par2StackTraceElement != null && !this.stackTrace[1].equals(par2StackTraceElement)) { + return false; + } else { + this.stackTrace[0] = par1StackTraceElement; + return true; + } + } else { + return false; + } + } else { + return false; + } + } + + public void func_85070_b(int par1) { + StackTraceElement[] var2 = new StackTraceElement[this.stackTrace.length - par1]; + System.arraycopy(this.stackTrace, 0, var2, 0, var2.length); + this.stackTrace = var2; + } + + public void func_85072_a(StringBuilder par1StringBuilder) { + par1StringBuilder.append("-- ").append(this.field_85076_b).append(" --\n"); + par1StringBuilder.append("Details:"); + Iterator var2 = this.field_85077_c.iterator(); + + while (var2.hasNext()) { + CrashReportCategoryEntry var3 = (CrashReportCategoryEntry) var2.next(); + par1StringBuilder.append("\n\t"); + par1StringBuilder.append(var3.func_85089_a()); + par1StringBuilder.append(": "); + par1StringBuilder.append(var3.func_85090_b()); + } + + if (this.stackTrace != null && this.stackTrace.length > 0) { + par1StringBuilder.append("\nStacktrace:"); + StackTraceElement[] var6 = this.stackTrace; + int var7 = var6.length; + + for (int var4 = 0; var4 < var7; ++var4) { + StackTraceElement var5 = var6[var4]; + par1StringBuilder.append("\n\tat "); + par1StringBuilder.append(var5.toString()); + } + } + } + + public static void func_85068_a(CrashReportCategory par0CrashReportCategory, int par1, int par2, int par3, int par4, + int par5) { + par0CrashReportCategory.addCrashSectionCallable("Block type", new CallableBlockType(par4)); + par0CrashReportCategory.addCrashSectionCallable("Block data value", new CallableBlockDataValue(par5)); + par0CrashReportCategory.addCrashSectionCallable("Block location", new CallableBlockLocation(par1, par2, par3)); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CrashReportCategoryEntry.java b/sp-server/src/main/java/net/minecraft/src/CrashReportCategoryEntry.java new file mode 100644 index 0000000..fcff667 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CrashReportCategoryEntry.java @@ -0,0 +1,27 @@ +package net.minecraft.src; + +class CrashReportCategoryEntry { + private final String field_85092_a; + private final String field_85091_b; + + public CrashReportCategoryEntry(String par1Str, Object par2Obj) { + this.field_85092_a = par1Str; + + if (par2Obj == null) { + this.field_85091_b = "~~NULL~~"; + } else if (par2Obj instanceof Throwable) { + Throwable var3 = (Throwable) par2Obj; + this.field_85091_b = "~~ERROR~~ " + var3.getClass().getSimpleName() + ": " + var3.getMessage(); + } else { + this.field_85091_b = par2Obj.toString(); + } + } + + public String func_85089_a() { + return this.field_85092_a; + } + + public String func_85090_b() { + return this.field_85091_b; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CreativeTabBlock.java b/sp-server/src/main/java/net/minecraft/src/CreativeTabBlock.java new file mode 100644 index 0000000..5051561 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CreativeTabBlock.java @@ -0,0 +1,7 @@ +package net.minecraft.src; + +final class CreativeTabBlock extends CreativeTabs { + CreativeTabBlock(int par1, String par2Str) { + super(par1, par2Str); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CreativeTabBrewing.java b/sp-server/src/main/java/net/minecraft/src/CreativeTabBrewing.java new file mode 100644 index 0000000..7ca7105 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CreativeTabBrewing.java @@ -0,0 +1,7 @@ +package net.minecraft.src; + +final class CreativeTabBrewing extends CreativeTabs { + CreativeTabBrewing(int par1, String par2Str) { + super(par1, par2Str); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CreativeTabCombat.java b/sp-server/src/main/java/net/minecraft/src/CreativeTabCombat.java new file mode 100644 index 0000000..e4a9fb8 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CreativeTabCombat.java @@ -0,0 +1,7 @@ +package net.minecraft.src; + +final class CreativeTabCombat extends CreativeTabs { + CreativeTabCombat(int par1, String par2Str) { + super(par1, par2Str); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CreativeTabDeco.java b/sp-server/src/main/java/net/minecraft/src/CreativeTabDeco.java new file mode 100644 index 0000000..2ccb8de --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CreativeTabDeco.java @@ -0,0 +1,7 @@ +package net.minecraft.src; + +final class CreativeTabDeco extends CreativeTabs { + CreativeTabDeco(int par1, String par2Str) { + super(par1, par2Str); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CreativeTabFood.java b/sp-server/src/main/java/net/minecraft/src/CreativeTabFood.java new file mode 100644 index 0000000..50cd34a --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CreativeTabFood.java @@ -0,0 +1,7 @@ +package net.minecraft.src; + +final class CreativeTabFood extends CreativeTabs { + CreativeTabFood(int par1, String par2Str) { + super(par1, par2Str); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CreativeTabInventory.java b/sp-server/src/main/java/net/minecraft/src/CreativeTabInventory.java new file mode 100644 index 0000000..51cadaf --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CreativeTabInventory.java @@ -0,0 +1,7 @@ +package net.minecraft.src; + +final class CreativeTabInventory extends CreativeTabs { + CreativeTabInventory(int par1, String par2Str) { + super(par1, par2Str); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CreativeTabMaterial.java b/sp-server/src/main/java/net/minecraft/src/CreativeTabMaterial.java new file mode 100644 index 0000000..c672aba --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CreativeTabMaterial.java @@ -0,0 +1,7 @@ +package net.minecraft.src; + +final class CreativeTabMaterial extends CreativeTabs { + CreativeTabMaterial(int par1, String par2Str) { + super(par1, par2Str); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CreativeTabMisc.java b/sp-server/src/main/java/net/minecraft/src/CreativeTabMisc.java new file mode 100644 index 0000000..acaf7ad --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CreativeTabMisc.java @@ -0,0 +1,7 @@ +package net.minecraft.src; + +final class CreativeTabMisc extends CreativeTabs { + CreativeTabMisc(int par1, String par2Str) { + super(par1, par2Str); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CreativeTabRedstone.java b/sp-server/src/main/java/net/minecraft/src/CreativeTabRedstone.java new file mode 100644 index 0000000..41cb38c --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CreativeTabRedstone.java @@ -0,0 +1,7 @@ +package net.minecraft.src; + +final class CreativeTabRedstone extends CreativeTabs { + CreativeTabRedstone(int par1, String par2Str) { + super(par1, par2Str); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CreativeTabSearch.java b/sp-server/src/main/java/net/minecraft/src/CreativeTabSearch.java new file mode 100644 index 0000000..163b86d --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CreativeTabSearch.java @@ -0,0 +1,7 @@ +package net.minecraft.src; + +final class CreativeTabSearch extends CreativeTabs { + CreativeTabSearch(int par1, String par2Str) { + super(par1, par2Str); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CreativeTabTools.java b/sp-server/src/main/java/net/minecraft/src/CreativeTabTools.java new file mode 100644 index 0000000..3724b08 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CreativeTabTools.java @@ -0,0 +1,7 @@ +package net.minecraft.src; + +final class CreativeTabTools extends CreativeTabs { + CreativeTabTools(int par1, String par2Str) { + super(par1, par2Str); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CreativeTabTransport.java b/sp-server/src/main/java/net/minecraft/src/CreativeTabTransport.java new file mode 100644 index 0000000..0c12643 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CreativeTabTransport.java @@ -0,0 +1,7 @@ +package net.minecraft.src; + +final class CreativeTabTransport extends CreativeTabs { + CreativeTabTransport(int par1, String par2Str) { + super(par1, par2Str); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CreativeTabs.java b/sp-server/src/main/java/net/minecraft/src/CreativeTabs.java new file mode 100644 index 0000000..a75ab56 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CreativeTabs.java @@ -0,0 +1,49 @@ +package net.minecraft.src; + +public class CreativeTabs { + public static final CreativeTabs[] creativeTabArray = new CreativeTabs[12]; + public static final CreativeTabs tabBlock = new CreativeTabBlock(0, "buildingBlocks"); + public static final CreativeTabs tabDecorations = new CreativeTabDeco(1, "decorations"); + public static final CreativeTabs tabRedstone = new CreativeTabRedstone(2, "redstone"); + public static final CreativeTabs tabTransport = new CreativeTabTransport(3, "transportation"); + public static final CreativeTabs tabMisc = new CreativeTabMisc(4, "misc"); + public static final CreativeTabs tabAllSearch = (new CreativeTabSearch(5, "search")) + .setBackgroundImageName("search.png"); + public static final CreativeTabs tabFood = new CreativeTabFood(6, "food"); + public static final CreativeTabs tabTools = new CreativeTabTools(7, "tools"); + public static final CreativeTabs tabCombat = new CreativeTabCombat(8, "combat"); + public static final CreativeTabs tabBrewing = new CreativeTabBrewing(9, "brewing"); + public static final CreativeTabs tabMaterials = new CreativeTabMaterial(10, "materials"); + public static final CreativeTabs tabInventory = (new CreativeTabInventory(11, "inventory")) + .setBackgroundImageName("survival_inv.png").setNoScrollbar().setNoTitle(); + private final int tabIndex; + private final String tabLabel; + + /** Texture to use. */ + private String theTexture = "list_items.png"; + private boolean hasScrollbar = true; + + /** Whether to draw the title in the foreground of the creative GUI */ + private boolean drawTitle = true; + + public CreativeTabs(int par1, String par2Str) { + this.tabIndex = par1; + this.tabLabel = par2Str; + creativeTabArray[par1] = this; + } + + public CreativeTabs setBackgroundImageName(String par1Str) { + this.theTexture = par1Str; + return this; + } + + public CreativeTabs setNoTitle() { + this.drawTitle = false; + return this; + } + + public CreativeTabs setNoScrollbar() { + this.hasScrollbar = false; + return this; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/CryptManager.java b/sp-server/src/main/java/net/minecraft/src/CryptManager.java new file mode 100644 index 0000000..16df563 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/CryptManager.java @@ -0,0 +1,175 @@ +package net.minecraft.src; + +import java.io.InputStream; +import java.io.OutputStream; +import java.io.UnsupportedEncodingException; +import java.nio.charset.Charset; +import java.security.InvalidKeyException; +import java.security.Key; +import java.security.KeyFactory; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.Security; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.X509EncodedKeySpec; +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; +import javax.crypto.SecretKey; +import javax.crypto.spec.SecretKeySpec; +import org.bouncycastle.crypto.BufferedBlockCipher; +import org.bouncycastle.crypto.engines.AESFastEngine; +import org.bouncycastle.crypto.io.CipherInputStream; +import org.bouncycastle.crypto.io.CipherOutputStream; +import org.bouncycastle.crypto.modes.CFBBlockCipher; +import org.bouncycastle.crypto.params.KeyParameter; +import org.bouncycastle.crypto.params.ParametersWithIV; +import org.bouncycastle.jce.provider.BouncyCastleProvider; + +public class CryptManager { + /** ISO_8859_1 */ + public static final Charset charSet = Charset.forName("ISO_8859_1"); + + /** + * Generates RSA KeyPair + */ + public static KeyPair generateKeyPair() { + try { + KeyPairGenerator var0 = KeyPairGenerator.getInstance("RSA"); + var0.initialize(1024); + return var0.generateKeyPair(); + } catch (NoSuchAlgorithmException var1) { + var1.printStackTrace(); + System.err.println("Key pair generation failed!"); + return null; + } + } + + /** + * Compute a serverId hash for use by sendSessionRequest() + */ + public static byte[] getServerIdHash(String par0Str, PublicKey par1PublicKey, SecretKey par2SecretKey) { + try { + return digestOperation("SHA-1", new byte[][] { par0Str.getBytes("ISO_8859_1"), par2SecretKey.getEncoded(), + par1PublicKey.getEncoded() }); + } catch (UnsupportedEncodingException var4) { + var4.printStackTrace(); + return null; + } + } + + /** + * Compute a message digest on arbitrary byte[] data + */ + private static byte[] digestOperation(String par0Str, byte[]... par1ArrayOfByte) { + try { + MessageDigest var2 = MessageDigest.getInstance(par0Str); + byte[][] var3 = par1ArrayOfByte; + int var4 = par1ArrayOfByte.length; + + for (int var5 = 0; var5 < var4; ++var5) { + byte[] var6 = var3[var5]; + var2.update(var6); + } + + return var2.digest(); + } catch (NoSuchAlgorithmException var7) { + var7.printStackTrace(); + return null; + } + } + + /** + * Create a new PublicKey from encoded X.509 data + */ + public static PublicKey decodePublicKey(byte[] par0ArrayOfByte) { + try { + X509EncodedKeySpec var1 = new X509EncodedKeySpec(par0ArrayOfByte); + KeyFactory var2 = KeyFactory.getInstance("RSA"); + return var2.generatePublic(var1); + } catch (NoSuchAlgorithmException var3) { + var3.printStackTrace(); + } catch (InvalidKeySpecException var4) { + var4.printStackTrace(); + } + + System.err.println("Public key reconstitute failed!"); + return null; + } + + /** + * Decrypt shared secret AES key using RSA private key + */ + public static SecretKey decryptSharedKey(PrivateKey par0PrivateKey, byte[] par1ArrayOfByte) { + return new SecretKeySpec(decryptData(par0PrivateKey, par1ArrayOfByte), "AES"); + } + + /** + * Decrypt byte[] data with RSA private key + */ + public static byte[] decryptData(Key par0Key, byte[] par1ArrayOfByte) { + return cipherOperation(2, par0Key, par1ArrayOfByte); + } + + /** + * Encrypt or decrypt byte[] data using the specified key + */ + private static byte[] cipherOperation(int par0, Key par1Key, byte[] par2ArrayOfByte) { + try { + return createTheCipherInstance(par0, par1Key.getAlgorithm(), par1Key).doFinal(par2ArrayOfByte); + } catch (IllegalBlockSizeException var4) { + var4.printStackTrace(); + } catch (BadPaddingException var5) { + var5.printStackTrace(); + } + + System.err.println("Cipher data failed!"); + return null; + } + + /** + * Creates the Cipher Instance. + */ + private static Cipher createTheCipherInstance(int par0, String par1Str, Key par2Key) { + try { + Cipher var3 = Cipher.getInstance(par1Str); + var3.init(par0, par2Key); + return var3; + } catch (InvalidKeyException var4) { + var4.printStackTrace(); + } catch (NoSuchAlgorithmException var5) { + var5.printStackTrace(); + } catch (NoSuchPaddingException var6) { + var6.printStackTrace(); + } + + System.err.println("Cipher creation failed!"); + return null; + } + + /** + * Create a new BufferedBlockCipher instance + */ + private static BufferedBlockCipher createBufferedBlockCipher(boolean par0, Key par1Key) { + BufferedBlockCipher var2 = new BufferedBlockCipher(new CFBBlockCipher(new AESFastEngine(), 8)); + var2.init(par0, new ParametersWithIV(new KeyParameter(par1Key.getEncoded()), par1Key.getEncoded(), 0, 16)); + return var2; + } + + public static OutputStream encryptOuputStream(SecretKey par0SecretKey, OutputStream par1OutputStream) { + return new CipherOutputStream(par1OutputStream, createBufferedBlockCipher(true, par0SecretKey)); + } + + public static InputStream decryptInputStream(SecretKey par0SecretKey, InputStream par1InputStream) { + return new CipherInputStream(par1InputStream, createBufferedBlockCipher(false, par0SecretKey)); + } + + static { + Security.addProvider(new BouncyCastleProvider()); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/DamageSource.java b/sp-server/src/main/java/net/minecraft/src/DamageSource.java new file mode 100644 index 0000000..4b93429 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/DamageSource.java @@ -0,0 +1,223 @@ +package net.minecraft.src; + +public class DamageSource { + public static DamageSource inFire = (new DamageSource("inFire")).setFireDamage(); + public static DamageSource onFire = (new DamageSource("onFire")).setDamageBypassesArmor().setFireDamage(); + public static DamageSource lava = (new DamageSource("lava")).setFireDamage(); + public static DamageSource inWall = (new DamageSource("inWall")).setDamageBypassesArmor(); + public static DamageSource drown = (new DamageSource("drown")).setDamageBypassesArmor(); + public static DamageSource starve = (new DamageSource("starve")).setDamageBypassesArmor(); + public static DamageSource cactus = new DamageSource("cactus"); + public static DamageSource fall = (new DamageSource("fall")).setDamageBypassesArmor(); + public static DamageSource outOfWorld = (new DamageSource("outOfWorld")).setDamageBypassesArmor() + .setDamageAllowedInCreativeMode(); + public static DamageSource generic = (new DamageSource("generic")).setDamageBypassesArmor(); + public static DamageSource magic = (new DamageSource("magic")).setDamageBypassesArmor().setMagicDamage(); + public static DamageSource wither = (new DamageSource("wither")).setDamageBypassesArmor(); + public static DamageSource anvil = new DamageSource("anvil"); + public static DamageSource fallingBlock = new DamageSource("fallingBlock"); + + /** This kind of damage can be blocked or not. */ + private boolean isUnblockable = false; + private boolean isDamageAllowedInCreativeMode = false; + private float hungerDamage = 0.3F; + + /** This kind of damage is based on fire or not. */ + private boolean fireDamage; + + /** This kind of damage is based on a projectile or not. */ + private boolean projectile; + + /** + * Whether this damage source will have its damage amount scaled based on the + * current difficulty. + */ + private boolean difficultyScaled; + + /** Whether the damage is magic based. */ + private boolean magicDamage = false; + private boolean explosion = false; + public String damageType; + + public static DamageSource causeMobDamage(EntityLiving par0EntityLiving) { + return new EntityDamageSource("mob", par0EntityLiving); + } + + /** + * returns an EntityDamageSource of type player + */ + public static DamageSource causePlayerDamage(EntityPlayer par0EntityPlayer) { + return new EntityDamageSource("player", par0EntityPlayer); + } + + /** + * returns EntityDamageSourceIndirect of an arrow + */ + public static DamageSource causeArrowDamage(EntityArrow par0EntityArrow, Entity par1Entity) { + return (new EntityDamageSourceIndirect("arrow", par0EntityArrow, par1Entity)).setProjectile(); + } + + /** + * returns EntityDamageSourceIndirect of a fireball + */ + public static DamageSource causeFireballDamage(EntityFireball par0EntityFireball, Entity par1Entity) { + return par1Entity == null + ? (new EntityDamageSourceIndirect("onFire", par0EntityFireball, par0EntityFireball)).setFireDamage() + .setProjectile() + : (new EntityDamageSourceIndirect("fireball", par0EntityFireball, par1Entity)).setFireDamage() + .setProjectile(); + } + + public static DamageSource causeThrownDamage(Entity par0Entity, Entity par1Entity) { + return (new EntityDamageSourceIndirect("thrown", par0Entity, par1Entity)).setProjectile(); + } + + public static DamageSource causeIndirectMagicDamage(Entity par0Entity, Entity par1Entity) { + return (new EntityDamageSourceIndirect("indirectMagic", par0Entity, par1Entity)).setDamageBypassesArmor() + .setMagicDamage(); + } + + /** + * Returns the EntityDamageSource of the Thorns enchantment + */ + public static DamageSource causeThornsDamage(Entity par0Entity) { + return (new EntityDamageSource("thorns", par0Entity)).setMagicDamage(); + } + + public static DamageSource setExplosionSource(Explosion par0Explosion) { + return par0Explosion != null && par0Explosion.func_94613_c() != null + ? (new EntityDamageSource("explosion.player", par0Explosion.func_94613_c())).setDifficultyScaled() + .setExplosion() + : (new DamageSource("explosion")).setDifficultyScaled().setExplosion(); + } + + /** + * Returns true if the damage is projectile based. + */ + public boolean isProjectile() { + return this.projectile; + } + + /** + * Define the damage type as projectile based. + */ + public DamageSource setProjectile() { + this.projectile = true; + return this; + } + + public boolean isExplosion() { + return this.explosion; + } + + public DamageSource setExplosion() { + this.explosion = true; + return this; + } + + public boolean isUnblockable() { + return this.isUnblockable; + } + + /** + * How much satiate(food) is consumed by this DamageSource + */ + public float getHungerDamage() { + return this.hungerDamage; + } + + public boolean canHarmInCreative() { + return this.isDamageAllowedInCreativeMode; + } + + protected DamageSource(String par1Str) { + this.damageType = par1Str; + } + + public Entity getSourceOfDamage() { + return this.getEntity(); + } + + public Entity getEntity() { + return null; + } + + protected DamageSource setDamageBypassesArmor() { + this.isUnblockable = true; + this.hungerDamage = 0.0F; + return this; + } + + protected DamageSource setDamageAllowedInCreativeMode() { + this.isDamageAllowedInCreativeMode = true; + return this; + } + + /** + * Define the damage type as fire based. + */ + protected DamageSource setFireDamage() { + this.fireDamage = true; + return this; + } + + /** + * Returns the message to be displayed on player death. + */ + public String getDeathMessage(EntityLiving par1EntityLiving) { + EntityLiving var2 = par1EntityLiving.func_94060_bK(); + String var3 = "death.attack." + this.damageType; + String var4 = var3 + ".player"; + return var2 != null && StatCollector.func_94522_b(var4) + ? StatCollector.translateToLocalFormatted(var4, + new Object[] { par1EntityLiving.getTranslatedEntityName(), var2.getTranslatedEntityName() }) + : StatCollector.translateToLocalFormatted(var3, + new Object[] { par1EntityLiving.getTranslatedEntityName() }); + } + + /** + * Returns true if the damage is fire based. + */ + public boolean isFireDamage() { + return this.fireDamage; + } + + /** + * Return the name of damage type. + */ + public String getDamageType() { + return this.damageType; + } + + /** + * Set whether this damage source will have its damage amount scaled based on + * the current difficulty. + */ + public DamageSource setDifficultyScaled() { + this.difficultyScaled = true; + return this; + } + + /** + * Return whether this damage source will have its damage amount scaled based on + * the current difficulty. + */ + public boolean isDifficultyScaled() { + return this.difficultyScaled; + } + + /** + * Returns true if the damage is magic based. + */ + public boolean isMagicDamage() { + return this.magicDamage; + } + + /** + * Define the damage type as magic based. + */ + public DamageSource setMagicDamage() { + this.magicDamage = true; + return this; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/DataWatcher.java b/sp-server/src/main/java/net/minecraft/src/DataWatcher.java new file mode 100644 index 0000000..cfcf88e --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/DataWatcher.java @@ -0,0 +1,311 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.concurrent.locks.ReadWriteLock; +import java.util.concurrent.locks.ReentrantReadWriteLock; + +public class DataWatcher { + /** When isBlank is true the DataWatcher is not watching any objects */ + private boolean isBlank = true; + private static final HashMap dataTypes = new HashMap(); + private final Map watchedObjects = new HashMap(); + + /** true if one or more object was changed */ + private boolean objectChanged; + private ReadWriteLock lock = new ReentrantReadWriteLock(); + + /** + * adds a new object to dataWatcher to watch, to update an already existing + * object see updateObject. Arguments: data Value Id, Object to add + */ + public void addObject(int par1, Object par2Obj) { + Integer var3 = (Integer) dataTypes.get(par2Obj.getClass()); + + if (var3 == null) { + throw new IllegalArgumentException("Unknown data type: " + par2Obj.getClass()); + } else if (par1 > 31) { + throw new IllegalArgumentException("Data value id is too big with " + par1 + "! (Max is " + 31 + ")"); + } else if (this.watchedObjects.containsKey(Integer.valueOf(par1))) { + throw new IllegalArgumentException("Duplicate id value for " + par1 + "!"); + } else { + WatchableObject var4 = new WatchableObject(var3.intValue(), par1, par2Obj); + this.lock.writeLock().lock(); + this.watchedObjects.put(Integer.valueOf(par1), var4); + this.lock.writeLock().unlock(); + this.isBlank = false; + } + } + + /** + * Add a new object for the DataWatcher to watch, using the specified data type. + */ + public void addObjectByDataType(int par1, int par2) { + WatchableObject var3 = new WatchableObject(par2, par1, (Object) null); + this.lock.writeLock().lock(); + this.watchedObjects.put(Integer.valueOf(par1), var3); + this.lock.writeLock().unlock(); + this.isBlank = false; + } + + /** + * gets the bytevalue of a watchable object + */ + public byte getWatchableObjectByte(int par1) { + return ((Byte) this.getWatchedObject(par1).getObject()).byteValue(); + } + + public short getWatchableObjectShort(int par1) { + return ((Short) this.getWatchedObject(par1).getObject()).shortValue(); + } + + /** + * gets a watchable object and returns it as a Integer + */ + public int getWatchableObjectInt(int par1) { + return ((Integer) this.getWatchedObject(par1).getObject()).intValue(); + } + + /** + * gets a watchable object and returns it as a String + */ + public String getWatchableObjectString(int par1) { + return (String) this.getWatchedObject(par1).getObject(); + } + + /** + * Get a watchable object as an ItemStack. + */ + public ItemStack getWatchableObjectItemStack(int par1) { + return (ItemStack) this.getWatchedObject(par1).getObject(); + } + + /** + * is threadsafe, unless it throws an exception, then + */ + private WatchableObject getWatchedObject(int par1) { + this.lock.readLock().lock(); + WatchableObject var2; + + try { + var2 = (WatchableObject) this.watchedObjects.get(Integer.valueOf(par1)); + } catch (Throwable var6) { + CrashReport var4 = CrashReport.makeCrashReport(var6, "Getting synched entity data"); + CrashReportCategory var5 = var4.makeCategory("Synched entity data"); + var5.addCrashSection("Data ID", Integer.valueOf(par1)); + throw new ReportedException(var4); + } + + this.lock.readLock().unlock(); + return var2; + } + + /** + * updates an already existing object + */ + public void updateObject(int par1, Object par2Obj) { + WatchableObject var3 = this.getWatchedObject(par1); + + if (!par2Obj.equals(var3.getObject())) { + var3.setObject(par2Obj); + var3.setWatched(true); + this.objectChanged = true; + } + } + + public void setObjectWatched(int par1) { + WatchableObject.setWatchableObjectWatched(this.getWatchedObject(par1), true); + this.objectChanged = true; + } + + /** + * true if one or more object was changed + */ + public boolean hasObjectChanged() { + return this.objectChanged; + } + + /** + * writes every object in passed list to dataoutputstream, terminated by 0x7F + */ + public static void writeObjectsInListToStream(List par0List, DataOutputStream par1DataOutputStream) + throws IOException { + if (par0List != null) { + Iterator var2 = par0List.iterator(); + + while (var2.hasNext()) { + WatchableObject var3 = (WatchableObject) var2.next(); + writeWatchableObject(par1DataOutputStream, var3); + } + } + + par1DataOutputStream.writeByte(127); + } + + public List unwatchAndReturnAllWatched() { + ArrayList var1 = null; + + if (this.objectChanged) { + this.lock.readLock().lock(); + Iterator var2 = this.watchedObjects.values().iterator(); + + while (var2.hasNext()) { + WatchableObject var3 = (WatchableObject) var2.next(); + + if (var3.isWatched()) { + var3.setWatched(false); + + if (var1 == null) { + var1 = new ArrayList(); + } + + var1.add(var3); + } + } + + this.lock.readLock().unlock(); + } + + this.objectChanged = false; + return var1; + } + + public void writeWatchableObjects(DataOutputStream par1DataOutputStream) throws IOException { + this.lock.readLock().lock(); + Iterator var2 = this.watchedObjects.values().iterator(); + + while (var2.hasNext()) { + WatchableObject var3 = (WatchableObject) var2.next(); + writeWatchableObject(par1DataOutputStream, var3); + } + + this.lock.readLock().unlock(); + par1DataOutputStream.writeByte(127); + } + + public List getAllWatched() { + ArrayList var1 = null; + this.lock.readLock().lock(); + WatchableObject var3; + + for (Iterator var2 = this.watchedObjects.values().iterator(); var2.hasNext(); var1.add(var3)) { + var3 = (WatchableObject) var2.next(); + + if (var1 == null) { + var1 = new ArrayList(); + } + } + + this.lock.readLock().unlock(); + return var1; + } + + private static void writeWatchableObject(DataOutputStream par0DataOutputStream, WatchableObject par1WatchableObject) + throws IOException { + int var2 = (par1WatchableObject.getObjectType() << 5 | par1WatchableObject.getDataValueId() & 31) & 255; + par0DataOutputStream.writeByte(var2); + + switch (par1WatchableObject.getObjectType()) { + case 0: + par0DataOutputStream.writeByte(((Byte) par1WatchableObject.getObject()).byteValue()); + break; + + case 1: + par0DataOutputStream.writeShort(((Short) par1WatchableObject.getObject()).shortValue()); + break; + + case 2: + par0DataOutputStream.writeInt(((Integer) par1WatchableObject.getObject()).intValue()); + break; + + case 3: + par0DataOutputStream.writeFloat(((Float) par1WatchableObject.getObject()).floatValue()); + break; + + case 4: + Packet.writeString((String) par1WatchableObject.getObject(), par0DataOutputStream); + break; + + case 5: + ItemStack var4 = (ItemStack) par1WatchableObject.getObject(); + Packet.writeItemStack(var4, par0DataOutputStream); + break; + + case 6: + ChunkCoordinates var3 = (ChunkCoordinates) par1WatchableObject.getObject(); + par0DataOutputStream.writeInt(var3.posX); + par0DataOutputStream.writeInt(var3.posY); + par0DataOutputStream.writeInt(var3.posZ); + } + } + + public static List readWatchableObjects(DataInputStream par0DataInputStream) throws IOException { + ArrayList var1 = null; + + for (byte var2 = par0DataInputStream.readByte(); var2 != 127; var2 = par0DataInputStream.readByte()) { + if (var1 == null) { + var1 = new ArrayList(); + } + + int var3 = (var2 & 224) >> 5; + int var4 = var2 & 31; + WatchableObject var5 = null; + + switch (var3) { + case 0: + var5 = new WatchableObject(var3, var4, Byte.valueOf(par0DataInputStream.readByte())); + break; + + case 1: + var5 = new WatchableObject(var3, var4, Short.valueOf(par0DataInputStream.readShort())); + break; + + case 2: + var5 = new WatchableObject(var3, var4, Integer.valueOf(par0DataInputStream.readInt())); + break; + + case 3: + var5 = new WatchableObject(var3, var4, Float.valueOf(par0DataInputStream.readFloat())); + break; + + case 4: + var5 = new WatchableObject(var3, var4, Packet.readString(par0DataInputStream, 64)); + break; + + case 5: + var5 = new WatchableObject(var3, var4, Packet.readItemStack(par0DataInputStream)); + break; + + case 6: + int var6 = par0DataInputStream.readInt(); + int var7 = par0DataInputStream.readInt(); + int var8 = par0DataInputStream.readInt(); + var5 = new WatchableObject(var3, var4, new ChunkCoordinates(var6, var7, var8)); + } + + var1.add(var5); + } + + return var1; + } + + public boolean getIsBlank() { + return this.isBlank; + } + + static { + dataTypes.put(Byte.class, Integer.valueOf(0)); + dataTypes.put(Short.class, Integer.valueOf(1)); + dataTypes.put(Integer.class, Integer.valueOf(2)); + dataTypes.put(Float.class, Integer.valueOf(3)); + dataTypes.put(String.class, Integer.valueOf(4)); + dataTypes.put(ItemStack.class, Integer.valueOf(5)); + dataTypes.put(ChunkCoordinates.class, Integer.valueOf(6)); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/DedicatedPlayerList.java b/sp-server/src/main/java/net/minecraft/src/DedicatedPlayerList.java new file mode 100644 index 0000000..69049e6 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/DedicatedPlayerList.java @@ -0,0 +1,167 @@ +package net.minecraft.src; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.PrintWriter; +import java.util.Iterator; +import net.minecraft.server.MinecraftServer; + +public class DedicatedPlayerList extends ServerConfigurationManager { + private File opsList; + private File whiteList; + + public DedicatedPlayerList(DedicatedServer par1DedicatedServer) { + super(par1DedicatedServer); + this.opsList = par1DedicatedServer.getFile("ops.txt"); + this.whiteList = par1DedicatedServer.getFile("white-list.txt"); + this.viewDistance = par1DedicatedServer.getIntProperty("view-distance", 10); + this.maxPlayers = par1DedicatedServer.getIntProperty("max-players", 20); + this.setWhiteListEnabled(par1DedicatedServer.getBooleanProperty("white-list", false)); + + if (!par1DedicatedServer.isSinglePlayer()) { + this.getBannedPlayers().setListActive(true); + this.getBannedIPs().setListActive(true); + } + + this.getBannedPlayers().loadBanList(); + this.getBannedPlayers().saveToFileWithHeader(); + this.getBannedIPs().loadBanList(); + this.getBannedIPs().saveToFileWithHeader(); + this.loadOpsList(); + this.readWhiteList(); + this.saveOpsList(); + + if (!this.whiteList.exists()) { + this.saveWhiteList(); + } + } + + public void setWhiteListEnabled(boolean par1) { + super.setWhiteListEnabled(par1); + this.getDedicatedServerInstance().setProperty("white-list", Boolean.valueOf(par1)); + this.getDedicatedServerInstance().saveProperties(); + } + + /** + * This adds a username to the ops list, then saves the op list + */ + public void addOp(String par1Str) { + super.addOp(par1Str); + this.saveOpsList(); + } + + /** + * This removes a username from the ops list, then saves the op list + */ + public void removeOp(String par1Str) { + super.removeOp(par1Str); + this.saveOpsList(); + } + + /** + * Remove the specified player from the whitelist. + */ + public void removeFromWhitelist(String par1Str) { + super.removeFromWhitelist(par1Str); + this.saveWhiteList(); + } + + /** + * Add the specified player to the white list. + */ + public void addToWhiteList(String par1Str) { + super.addToWhiteList(par1Str); + this.saveWhiteList(); + } + + /** + * Either does nothing, or calls readWhiteList. + */ + public void loadWhiteList() { + this.readWhiteList(); + } + + private void loadOpsList() { + try { + this.getOps().clear(); + BufferedReader var1 = new BufferedReader(new FileReader(this.opsList)); + String var2 = ""; + + while ((var2 = var1.readLine()) != null) { + this.getOps().add(var2.trim().toLowerCase()); + } + + var1.close(); + } catch (Exception var3) { + this.getDedicatedServerInstance().getLogAgent().func_98236_b("Failed to load operators list: " + var3); + } + } + + private void saveOpsList() { + try { + PrintWriter var1 = new PrintWriter(new FileWriter(this.opsList, false)); + Iterator var2 = this.getOps().iterator(); + + while (var2.hasNext()) { + String var3 = (String) var2.next(); + var1.println(var3); + } + + var1.close(); + } catch (Exception var4) { + this.getDedicatedServerInstance().getLogAgent().func_98236_b("Failed to save operators list: " + var4); + } + } + + private void readWhiteList() { + try { + this.getWhiteListedPlayers().clear(); + BufferedReader var1 = new BufferedReader(new FileReader(this.whiteList)); + String var2 = ""; + + while ((var2 = var1.readLine()) != null) { + this.getWhiteListedPlayers().add(var2.trim().toLowerCase()); + } + + var1.close(); + } catch (Exception var3) { + this.getDedicatedServerInstance().getLogAgent().func_98236_b("Failed to load white-list: " + var3); + } + } + + private void saveWhiteList() { + try { + PrintWriter var1 = new PrintWriter(new FileWriter(this.whiteList, false)); + Iterator var2 = this.getWhiteListedPlayers().iterator(); + + while (var2.hasNext()) { + String var3 = (String) var2.next(); + var1.println(var3); + } + + var1.close(); + } catch (Exception var4) { + this.getDedicatedServerInstance().getLogAgent().func_98236_b("Failed to save white-list: " + var4); + } + } + + /** + * Determine if the player is allowed to connect based on current server + * settings. + */ + public boolean isAllowedToLogin(String par1Str) { + par1Str = par1Str.trim().toLowerCase(); + return !this.isWhiteListEnabled() || this.areCommandsAllowed(par1Str) + || this.getWhiteListedPlayers().contains(par1Str); + } + + public DedicatedServer getDedicatedServerInstance() { + return (DedicatedServer) super.getServerInstance(); + } + + public MinecraftServer getServerInstance() { + return this.getDedicatedServerInstance(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/DedicatedServer.java b/sp-server/src/main/java/net/minecraft/src/DedicatedServer.java new file mode 100644 index 0000000..7b46f5e --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/DedicatedServer.java @@ -0,0 +1,368 @@ +package net.minecraft.src; + +import java.io.File; +import java.io.IOException; +import java.net.InetAddress; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Random; +import net.minecraft.server.MinecraftServer; + +public class DedicatedServer extends MinecraftServer implements IServer { + private final List pendingCommandList = Collections.synchronizedList(new ArrayList()); + private final ILogAgent field_98131_l; + private RConThreadQuery theRConThreadQuery; + private RConThreadMain theRConThreadMain; + private PropertyManager settings; + private boolean canSpawnStructures; + private EnumGameType gameType; + private NetworkListenThread networkThread; + private boolean guiIsEnabled = false; + + public DedicatedServer(File par1File) { + super(par1File); + this.field_98131_l = new LogAgent("Minecraft-Server", (String) null, + (new File(par1File, "server.log")).getAbsolutePath()); + new DedicatedServerSleepThread(this); + } + + /** + * Initialises the server and starts it. + */ + protected boolean startServer() throws IOException { + DedicatedServerCommandThread var1 = new DedicatedServerCommandThread(this); + var1.setDaemon(true); + var1.start(); + this.getLogAgent().func_98233_a("Starting minecraft server version 1.5.2"); + + if (Runtime.getRuntime().maxMemory() / 1024L / 1024L < 512L) { + this.getLogAgent().func_98236_b( + "To start the server with more ram, launch it as \"java -Xmx1024M -Xms1024M -jar minecraft_server.jar\""); + } + + this.getLogAgent().func_98233_a("Loading properties"); + this.settings = new PropertyManager(new File("server.properties"), this.getLogAgent()); + + if (this.isSinglePlayer()) { + this.setHostname("127.0.0.1"); + } else { + this.setOnlineMode(this.settings.getBooleanProperty("online-mode", true)); + this.setHostname(this.settings.getStringProperty("server-ip", "")); + } + + this.setCanSpawnAnimals(this.settings.getBooleanProperty("spawn-animals", true)); + this.setCanSpawnNPCs(this.settings.getBooleanProperty("spawn-npcs", true)); + this.setAllowPvp(this.settings.getBooleanProperty("pvp", true)); + this.setAllowFlight(this.settings.getBooleanProperty("allow-flight", false)); + this.setTexturePack(this.settings.getStringProperty("texture-pack", "")); + this.setMOTD(this.settings.getStringProperty("motd", "A Minecraft Server")); + this.func_104055_i(this.settings.getBooleanProperty("force-gamemode", false)); + + if (this.settings.getIntProperty("difficulty", 1) < 0) { + this.settings.setProperty("difficulty", Integer.valueOf(0)); + } else if (this.settings.getIntProperty("difficulty", 1) > 3) { + this.settings.setProperty("difficulty", Integer.valueOf(3)); + } + + this.canSpawnStructures = this.settings.getBooleanProperty("generate-structures", true); + int var2 = this.settings.getIntProperty("gamemode", EnumGameType.SURVIVAL.getID()); + this.gameType = WorldSettings.getGameTypeById(var2); + this.getLogAgent().func_98233_a("Default game type: " + this.gameType); + InetAddress var3 = null; + + if (this.getServerHostname().length() > 0) { + var3 = InetAddress.getByName(this.getServerHostname()); + } + + if (this.getServerPort() < 0) { + this.setServerPort(this.settings.getIntProperty("server-port", 25565)); + } + + this.getLogAgent().func_98233_a("Generating keypair"); + this.setKeyPair(CryptManager.generateKeyPair()); + this.getLogAgent() + .func_98233_a("Starting Minecraft server on " + + (this.getServerHostname().length() == 0 ? "*" : this.getServerHostname()) + ":" + + this.getServerPort()); + + try { + this.networkThread = new DedicatedServerListenThread(this, var3, this.getServerPort()); + } catch (IOException var16) { + this.getLogAgent().func_98236_b("**** FAILED TO BIND TO PORT!"); + this.getLogAgent().logWarningFormatted("The exception was: {0}", new Object[] { var16.toString() }); + this.getLogAgent().func_98236_b("Perhaps a server is already running on that port?"); + return false; + } + + if (!this.isServerInOnlineMode()) { + this.getLogAgent().func_98236_b("**** SERVER IS RUNNING IN OFFLINE/INSECURE MODE!"); + this.getLogAgent().func_98236_b("The server will make no attempt to authenticate usernames. Beware."); + this.getLogAgent().func_98236_b( + "While this makes the game possible to play without internet access, it also opens up the ability for hackers to connect with any username they choose."); + this.getLogAgent() + .func_98236_b("To change this, set \"online-mode\" to \"true\" in the server.properties file."); + } + + this.setConfigurationManager(new DedicatedPlayerList(this)); + long var4 = System.nanoTime(); + + if (this.getFolderName() == null) { + this.setFolderName(this.settings.getStringProperty("level-name", "world")); + } + + String var6 = this.settings.getStringProperty("level-seed", ""); + String var7 = this.settings.getStringProperty("level-type", "DEFAULT"); + String var8 = this.settings.getStringProperty("generator-settings", ""); + long var9 = (new Random()).nextLong(); + + if (var6.length() > 0) { + try { + long var11 = Long.parseLong(var6); + + if (var11 != 0L) { + var9 = var11; + } + } catch (NumberFormatException var15) { + var9 = (long) var6.hashCode(); + } + } + + WorldType var17 = WorldType.parseWorldType(var7); + + if (var17 == null) { + var17 = WorldType.DEFAULT; + } + + this.setBuildLimit(this.settings.getIntProperty("max-build-height", 256)); + this.setBuildLimit((this.getBuildLimit() + 8) / 16 * 16); + this.setBuildLimit(MathHelper.clamp_int(this.getBuildLimit(), 64, 256)); + this.settings.setProperty("max-build-height", Integer.valueOf(this.getBuildLimit())); + this.getLogAgent().func_98233_a("Preparing level \"" + this.getFolderName() + "\""); + this.loadAllWorlds(this.getFolderName(), this.getFolderName(), var9, var17, var8); + long var12 = System.nanoTime() - var4; + String var14 = String.format("%.3fs", new Object[] { Double.valueOf((double) var12 / 1.0E9D) }); + this.getLogAgent().func_98233_a("Done (" + var14 + ")! For help, type \"help\" or \"?\""); + + if (this.settings.getBooleanProperty("enable-query", false)) { + this.getLogAgent().func_98233_a("Starting GS4 status listener"); + this.theRConThreadQuery = new RConThreadQuery(this); + this.theRConThreadQuery.startThread(); + } + + if (this.settings.getBooleanProperty("enable-rcon", false)) { + this.getLogAgent().func_98233_a("Starting remote control listener"); + this.theRConThreadMain = new RConThreadMain(this); + this.theRConThreadMain.startThread(); + } + + return true; + } + + public boolean canStructuresSpawn() { + return this.canSpawnStructures; + } + + public EnumGameType getGameType() { + return this.gameType; + } + + /** + * Defaults to "1" (Easy) for the dedicated server, defaults to "2" (Normal) on + * the client. + */ + public int getDifficulty() { + return this.settings.getIntProperty("difficulty", 1); + } + + /** + * Defaults to false. + */ + public boolean isHardcore() { + return this.settings.getBooleanProperty("hardcore", false); + } + + /** + * Called on exit from the main run() loop. + */ + protected void finalTick(CrashReport par1CrashReport) { + while (this.isServerRunning()) { + this.executePendingCommands(); + + try { + Thread.sleep(10L); + } catch (InterruptedException var3) { + var3.printStackTrace(); + } + } + } + + /** + * Adds the server info, including from theWorldServer, to the crash report. + */ + public CrashReport addServerInfoToCrashReport(CrashReport par1CrashReport) { + par1CrashReport = super.addServerInfoToCrashReport(par1CrashReport); + par1CrashReport.func_85056_g().addCrashSectionCallable("Is Modded", new CallableType(this)); + par1CrashReport.func_85056_g().addCrashSectionCallable("Type", new CallableServerType(this)); + return par1CrashReport; + } + + /** + * Directly calls System.exit(0), instantly killing the program. + */ + protected void systemExitNow() { + System.exit(0); + } + + public void updateTimeLightAndEntities() { + super.updateTimeLightAndEntities(); + this.executePendingCommands(); + } + + public boolean getAllowNether() { + return this.settings.getBooleanProperty("allow-nether", true); + } + + public boolean allowSpawnMonsters() { + return this.settings.getBooleanProperty("spawn-monsters", true); + } + + public void addServerStatsToSnooper(PlayerUsageSnooper par1PlayerUsageSnooper) { + par1PlayerUsageSnooper.addData("whitelist_enabled", + Boolean.valueOf(this.getDedicatedPlayerList().isWhiteListEnabled())); + par1PlayerUsageSnooper.addData("whitelist_count", + Integer.valueOf(this.getDedicatedPlayerList().getWhiteListedPlayers().size())); + super.addServerStatsToSnooper(par1PlayerUsageSnooper); + } + + /** + * Returns whether snooping is enabled or not. + */ + public boolean isSnooperEnabled() { + return this.settings.getBooleanProperty("snooper-enabled", true); + } + + public void addPendingCommand(String par1Str, ICommandSender par2ICommandSender) { + this.pendingCommandList.add(new ServerCommand(par1Str, par2ICommandSender)); + } + + public void executePendingCommands() { + while (!this.pendingCommandList.isEmpty()) { + ServerCommand var1 = (ServerCommand) this.pendingCommandList.remove(0); + this.getCommandManager().executeCommand(var1.sender, var1.command); + } + } + + public boolean isDedicatedServer() { + return true; + } + + public DedicatedPlayerList getDedicatedPlayerList() { + return (DedicatedPlayerList) super.getConfigurationManager(); + } + + public NetworkListenThread getNetworkThread() { + return this.networkThread; + } + + /** + * Gets an integer property. If it does not exist, set it to the specified + * value. + */ + public int getIntProperty(String par1Str, int par2) { + return this.settings.getIntProperty(par1Str, par2); + } + + /** + * Gets a string property. If it does not exist, set it to the specified value. + */ + public String getStringProperty(String par1Str, String par2Str) { + return this.settings.getStringProperty(par1Str, par2Str); + } + + /** + * Gets a boolean property. If it does not exist, set it to the specified value. + */ + public boolean getBooleanProperty(String par1Str, boolean par2) { + return this.settings.getBooleanProperty(par1Str, par2); + } + + /** + * Saves an Object with the given property name. + */ + public void setProperty(String par1Str, Object par2Obj) { + this.settings.setProperty(par1Str, par2Obj); + } + + /** + * Saves all of the server properties to the properties file. + */ + public void saveProperties() { + this.settings.saveProperties(); + } + + /** + * Returns the filename where server properties are stored + */ + public String getSettingsFilename() { + File var1 = this.settings.getPropertiesFile(); + return var1 != null ? var1.getAbsolutePath() : "No settings file"; + } + + public void enableGui() { + ServerGUI.initGUI(this); + this.guiIsEnabled = true; + } + + public boolean getGuiEnabled() { + return this.guiIsEnabled; + } + + /** + * On dedicated does nothing. On integrated, sets commandsAllowedForAll, + * gameType and allows external connections. + */ + public String shareToLAN(EnumGameType par1EnumGameType, boolean par2) { + return ""; + } + + /** + * Return whether command blocks are enabled. + */ + public boolean isCommandBlockEnabled() { + return this.settings.getBooleanProperty("enable-command-block", false); + } + + /** + * Return the spawn protection area's size. + */ + public int getSpawnProtectionSize() { + return this.settings.getIntProperty("spawn-protection", super.getSpawnProtectionSize()); + } + + public boolean func_96290_a(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer) { + if (par1World.provider.dimensionId != 0) { + return false; + } else if (this.getDedicatedPlayerList().getOps().isEmpty()) { + return false; + } else if (this.getDedicatedPlayerList().areCommandsAllowed(par5EntityPlayer.username)) { + return false; + } else if (this.getSpawnProtectionSize() <= 0) { + return false; + } else { + ChunkCoordinates var6 = par1World.getSpawnPoint(); + int var7 = MathHelper.abs_int(par2 - var6.posX); + int var8 = MathHelper.abs_int(par4 - var6.posZ); + int var9 = Math.max(var7, var8); + return var9 <= this.getSpawnProtectionSize(); + } + } + + public ILogAgent getLogAgent() { + return this.field_98131_l; + } + + public ServerConfigurationManager getConfigurationManager() { + return this.getDedicatedPlayerList(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/DedicatedServerCommandThread.java b/sp-server/src/main/java/net/minecraft/src/DedicatedServerCommandThread.java new file mode 100644 index 0000000..4156aa1 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/DedicatedServerCommandThread.java @@ -0,0 +1,27 @@ +package net.minecraft.src; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; + +class DedicatedServerCommandThread extends Thread { + final DedicatedServer server; + + DedicatedServerCommandThread(DedicatedServer par1DedicatedServer) { + this.server = par1DedicatedServer; + } + + public void run() { + BufferedReader var1 = new BufferedReader(new InputStreamReader(System.in)); + String var2; + + try { + while (!this.server.isServerStopped() && this.server.isServerRunning() + && (var2 = var1.readLine()) != null) { + this.server.addPendingCommand(var2, this.server); + } + } catch (IOException var4) { + var4.printStackTrace(); + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/DedicatedServerListenThread.java b/sp-server/src/main/java/net/minecraft/src/DedicatedServerListenThread.java new file mode 100644 index 0000000..30ec22d --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/DedicatedServerListenThread.java @@ -0,0 +1,43 @@ +package net.minecraft.src; + +import java.io.IOException; +import java.net.InetAddress; +import net.minecraft.server.MinecraftServer; + +public class DedicatedServerListenThread extends NetworkListenThread { + /** Instance of ServerListenThread. */ + private final ServerListenThread theServerListenThread; + + public DedicatedServerListenThread(MinecraftServer par1MinecraftServer, InetAddress par2InetAddress, int par3) + throws IOException { + super(par1MinecraftServer); + this.theServerListenThread = new ServerListenThread(this, par2InetAddress, par3); + this.theServerListenThread.start(); + } + + public void stopListening() { + super.stopListening(); + this.theServerListenThread.func_71768_b(); + this.theServerListenThread.interrupt(); + } + + /** + * Handles all incoming connections and packets + */ + public void handleNetworkListenThread() { + this.theServerListenThread.processPendingConnections(); + super.handleNetworkListenThread(); + } + + public DedicatedServer getDedicatedServer() { + return (DedicatedServer) super.getServer(); + } + + public void func_71761_a(InetAddress par1InetAddress) { + this.theServerListenThread.func_71769_a(par1InetAddress); + } + + public MinecraftServer getServer() { + return this.getDedicatedServer(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/DedicatedServerSleepThread.java b/sp-server/src/main/java/net/minecraft/src/DedicatedServerSleepThread.java new file mode 100644 index 0000000..e320f10 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/DedicatedServerSleepThread.java @@ -0,0 +1,24 @@ +package net.minecraft.src; + +class DedicatedServerSleepThread extends Thread { + /** Instance of the DecitatedServer. */ + final DedicatedServer theDecitatedServer; + + DedicatedServerSleepThread(DedicatedServer par1DedicatedServer) { + this.theDecitatedServer = par1DedicatedServer; + this.setDaemon(true); + this.start(); + } + + public void run() { + while (true) { + try { + while (true) { + Thread.sleep(2147483647L); + } + } catch (InterruptedException var2) { + ; + } + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/DemoWorldManager.java b/sp-server/src/main/java/net/minecraft/src/DemoWorldManager.java new file mode 100644 index 0000000..d91af38 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/DemoWorldManager.java @@ -0,0 +1,111 @@ +package net.minecraft.src; + +public class DemoWorldManager extends ItemInWorldManager { + private boolean field_73105_c = false; + private boolean demoTimeExpired = false; + private int field_73104_e = 0; + private int field_73102_f = 0; + + public DemoWorldManager(World par1World) { + super(par1World); + } + + public void updateBlockRemoving() { + super.updateBlockRemoving(); + ++this.field_73102_f; + long var1 = this.theWorld.getTotalWorldTime(); + long var3 = var1 / 24000L + 1L; + + if (!this.field_73105_c && this.field_73102_f > 20) { + this.field_73105_c = true; + this.thisPlayerMP.playerNetServerHandler.sendPacket(new Packet70GameEvent(5, 0)); + } + + this.demoTimeExpired = var1 > 120500L; + + if (this.demoTimeExpired) { + ++this.field_73104_e; + } + + if (var1 % 24000L == 500L) { + if (var3 <= 6L) { + this.thisPlayerMP + .sendChatToPlayer(this.thisPlayerMP.translateString("demo.day." + var3, new Object[0])); + } + } else if (var3 == 1L) { + if (var1 == 100L) { + this.thisPlayerMP.playerNetServerHandler.sendPacket(new Packet70GameEvent(5, 101)); + } else if (var1 == 175L) { + this.thisPlayerMP.playerNetServerHandler.sendPacket(new Packet70GameEvent(5, 102)); + } else if (var1 == 250L) { + this.thisPlayerMP.playerNetServerHandler.sendPacket(new Packet70GameEvent(5, 103)); + } + } else if (var3 == 5L && var1 % 24000L == 22000L) { + this.thisPlayerMP.sendChatToPlayer(this.thisPlayerMP.translateString("demo.day.warning", new Object[0])); + } + } + + /** + * Sends a message to the player reminding them that this is the demo version + */ + private void sendDemoReminder() { + if (this.field_73104_e > 100) { + this.thisPlayerMP.sendChatToPlayer(this.thisPlayerMP.translateString("demo.reminder", new Object[0])); + this.field_73104_e = 0; + } + } + + /** + * if not creative, it calls destroyBlockInWorldPartially untill the block is + * broken first. par4 is the specific side. tryHarvestBlock can also be the + * result of this call + */ + public void onBlockClicked(int par1, int par2, int par3, int par4) { + if (this.demoTimeExpired) { + this.sendDemoReminder(); + } else { + super.onBlockClicked(par1, par2, par3, par4); + } + } + + public void blockRemoving(int par1, int par2, int par3) { + if (!this.demoTimeExpired) { + super.blockRemoving(par1, par2, par3); + } + } + + /** + * Attempts to harvest a block at the given coordinate + */ + public boolean tryHarvestBlock(int par1, int par2, int par3) { + return this.demoTimeExpired ? false : super.tryHarvestBlock(par1, par2, par3); + } + + /** + * Attempts to right-click use an item by the given EntityPlayer in the given + * World + */ + public boolean tryUseItem(EntityPlayer par1EntityPlayer, World par2World, ItemStack par3ItemStack) { + if (this.demoTimeExpired) { + this.sendDemoReminder(); + return false; + } else { + return super.tryUseItem(par1EntityPlayer, par2World, par3ItemStack); + } + } + + /** + * Activate the clicked on block, otherwise use the held item. Args: player, + * world, itemStack, x, y, z, side, xOffset, yOffset, zOffset + */ + public boolean activateBlockOrUseItem(EntityPlayer par1EntityPlayer, World par2World, ItemStack par3ItemStack, + int par4, int par5, int par6, int par7, float par8, float par9, float par10) { + if (this.demoTimeExpired) { + this.sendDemoReminder(); + return false; + } else { + return super.activateBlockOrUseItem(par1EntityPlayer, par2World, par3ItemStack, par4, par5, par6, par7, + par8, par9, par10); + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/DemoWorldServer.java b/sp-server/src/main/java/net/minecraft/src/DemoWorldServer.java new file mode 100644 index 0000000..865f2e4 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/DemoWorldServer.java @@ -0,0 +1,14 @@ +package net.minecraft.src; + +import net.minecraft.server.MinecraftServer; + +public class DemoWorldServer extends WorldServer { + private static final long demoWorldSeed = (long) "North Carolina".hashCode(); + public static final WorldSettings demoWorldSettings = (new WorldSettings(demoWorldSeed, EnumGameType.SURVIVAL, true, + false, WorldType.DEFAULT)).enableBonusChest(); + + public DemoWorldServer(MinecraftServer par1MinecraftServer, ISaveHandler par2ISaveHandler, String par3Str, int par4, + Profiler par5Profiler, ILogAgent par6ILogAgent) { + super(par1MinecraftServer, par2ISaveHandler, par3Str, par4, demoWorldSettings, par5Profiler, par6ILogAgent); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/DerivedWorldInfo.java b/sp-server/src/main/java/net/minecraft/src/DerivedWorldInfo.java new file mode 100644 index 0000000..3c14f63 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/DerivedWorldInfo.java @@ -0,0 +1,221 @@ +package net.minecraft.src; + +public class DerivedWorldInfo extends WorldInfo { + /** Instance of WorldInfo. */ + private final WorldInfo theWorldInfo; + + public DerivedWorldInfo(WorldInfo par1WorldInfo) { + this.theWorldInfo = par1WorldInfo; + } + + /** + * Gets the NBTTagCompound for the worldInfo + */ + public NBTTagCompound getNBTTagCompound() { + return this.theWorldInfo.getNBTTagCompound(); + } + + /** + * Creates a new NBTTagCompound for the world, with the given NBTTag as the + * "Player" + */ + public NBTTagCompound cloneNBTCompound(NBTTagCompound par1NBTTagCompound) { + return this.theWorldInfo.cloneNBTCompound(par1NBTTagCompound); + } + + /** + * Returns the seed of current world. + */ + public long getSeed() { + return this.theWorldInfo.getSeed(); + } + + /** + * Returns the x spawn position + */ + public int getSpawnX() { + return this.theWorldInfo.getSpawnX(); + } + + /** + * Return the Y axis spawning point of the player. + */ + public int getSpawnY() { + return this.theWorldInfo.getSpawnY(); + } + + /** + * Returns the z spawn position + */ + public int getSpawnZ() { + return this.theWorldInfo.getSpawnZ(); + } + + public long getWorldTotalTime() { + return this.theWorldInfo.getWorldTotalTime(); + } + + /** + * Get current world time + */ + public long getWorldTime() { + return this.theWorldInfo.getWorldTime(); + } + + /** + * Returns the player's NBTTagCompound to be loaded + */ + public NBTTagCompound getPlayerNBTTagCompound() { + return this.theWorldInfo.getPlayerNBTTagCompound(); + } + + public int getDimension() { + return this.theWorldInfo.getDimension(); + } + + /** + * Get current world name + */ + public String getWorldName() { + return this.theWorldInfo.getWorldName(); + } + + /** + * Returns the save version of this world + */ + public int getSaveVersion() { + return this.theWorldInfo.getSaveVersion(); + } + + /** + * Returns true if it is thundering, false otherwise. + */ + public boolean isThundering() { + return this.theWorldInfo.isThundering(); + } + + /** + * Returns the number of ticks until next thunderbolt. + */ + public int getThunderTime() { + return this.theWorldInfo.getThunderTime(); + } + + /** + * Returns true if it is raining, false otherwise. + */ + public boolean isRaining() { + return this.theWorldInfo.isRaining(); + } + + /** + * Return the number of ticks until rain. + */ + public int getRainTime() { + return this.theWorldInfo.getRainTime(); + } + + /** + * Gets the GameType. + */ + public EnumGameType getGameType() { + return this.theWorldInfo.getGameType(); + } + + public void incrementTotalWorldTime(long par1) { + } + + /** + * Set current world time + */ + public void setWorldTime(long par1) { + } + + /** + * Sets the spawn zone position. Args: x, y, z + */ + public void setSpawnPosition(int par1, int par2, int par3) { + } + + public void setWorldName(String par1Str) { + } + + /** + * Sets the save version of the world + */ + public void setSaveVersion(int par1) { + } + + /** + * Sets whether it is thundering or not. + */ + public void setThundering(boolean par1) { + } + + /** + * Defines the number of ticks until next thunderbolt. + */ + public void setThunderTime(int par1) { + } + + /** + * Sets whether it is raining or not. + */ + public void setRaining(boolean par1) { + } + + /** + * Sets the number of ticks until rain. + */ + public void setRainTime(int par1) { + } + + /** + * Get whether the map features (e.g. strongholds) generation is enabled or + * disabled. + */ + public boolean isMapFeaturesEnabled() { + return this.theWorldInfo.isMapFeaturesEnabled(); + } + + /** + * Returns true if hardcore mode is enabled, otherwise false + */ + public boolean isHardcoreModeEnabled() { + return this.theWorldInfo.isHardcoreModeEnabled(); + } + + public WorldType getTerrainType() { + return this.theWorldInfo.getTerrainType(); + } + + public void setTerrainType(WorldType par1WorldType) { + } + + /** + * Returns true if commands are allowed on this World. + */ + public boolean areCommandsAllowed() { + return this.theWorldInfo.areCommandsAllowed(); + } + + /** + * Returns true if the World is initialized. + */ + public boolean isInitialized() { + return this.theWorldInfo.isInitialized(); + } + + /** + * Sets the initialization status of the World. + */ + public void setServerInitialized(boolean par1) { + } + + /** + * Gets the GameRules class Instance. + */ + public GameRules getGameRulesInstance() { + return this.theWorldInfo.getGameRulesInstance(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/Direction.java b/sp-server/src/main/java/net/minecraft/src/Direction.java new file mode 100644 index 0000000..3433150 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/Direction.java @@ -0,0 +1,28 @@ +package net.minecraft.src; + +public class Direction { + public static final int[] offsetX = new int[] { 0, -1, 0, 1 }; + public static final int[] offsetZ = new int[] { 1, 0, -1, 0 }; + public static final String[] directions = new String[] { "SOUTH", "WEST", "NORTH", "EAST" }; + + /** Maps a Direction value (2D) to a Facing value (3D). */ + public static final int[] directionToFacing = new int[] { 3, 4, 2, 5 }; + + /** Maps a Facing value (3D) to a Direction value (2D). */ + public static final int[] facingToDirection = new int[] { -1, -1, 2, 0, 1, 3 }; + public static final int[] footInvisibleFaceRemap = new int[] { 2, 3, 0, 1 }; + public static final int[] enderEyeMetaToDirection = new int[] { 1, 2, 3, 0 }; + + /** Maps a direction to that to the left of it. */ + public static final int[] rotateLeft = new int[] { 3, 0, 1, 2 }; + public static final int[][] bedDirection = new int[][] { { 1, 0, 3, 2, 5, 4 }, { 1, 0, 5, 4, 2, 3 }, + { 1, 0, 2, 3, 4, 5 }, { 1, 0, 4, 5, 3, 2 } }; + + /** + * Returns the movement direction from a velocity vector. + */ + public static int getMovementDirection(double par0, double par2) { + return MathHelper.abs((float) par0) > MathHelper.abs((float) par2) ? (par0 > 0.0D ? 1 : 3) + : (par2 > 0.0D ? 2 : 0); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/DispenserBehaviorArrow.java b/sp-server/src/main/java/net/minecraft/src/DispenserBehaviorArrow.java new file mode 100644 index 0000000..fe8339d --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/DispenserBehaviorArrow.java @@ -0,0 +1,12 @@ +package net.minecraft.src; + +final class DispenserBehaviorArrow extends BehaviorProjectileDispense { + /** + * Return the projectile entity spawned by this dispense behavior. + */ + protected IProjectile getProjectileEntity(World par1World, IPosition par2IPosition) { + EntityArrow var3 = new EntityArrow(par1World, par2IPosition.getX(), par2IPosition.getY(), par2IPosition.getZ()); + var3.canBePickedUp = 1; + return var3; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/DispenserBehaviorBoat.java b/sp-server/src/main/java/net/minecraft/src/DispenserBehaviorBoat.java new file mode 100644 index 0000000..b56ec06 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/DispenserBehaviorBoat.java @@ -0,0 +1,44 @@ +package net.minecraft.src; + +final class DispenserBehaviorBoat extends BehaviorDefaultDispenseItem { + private final BehaviorDefaultDispenseItem defaultDispenserItemBehavior = new BehaviorDefaultDispenseItem(); + + /** + * Dispense the specified stack, play the dispense sound and spawn particles. + */ + public ItemStack dispenseStack(IBlockSource par1IBlockSource, ItemStack par2ItemStack) { + EnumFacing var3 = BlockDispenser.getFacing(par1IBlockSource.getBlockMetadata()); + World var4 = par1IBlockSource.getWorld(); + double var5 = par1IBlockSource.getX() + (double) ((float) var3.getFrontOffsetX() * 1.125F); + double var7 = par1IBlockSource.getY() + (double) ((float) var3.getFrontOffsetY() * 1.125F); + double var9 = par1IBlockSource.getZ() + (double) ((float) var3.getFrontOffsetZ() * 1.125F); + int var11 = par1IBlockSource.getXInt() + var3.getFrontOffsetX(); + int var12 = par1IBlockSource.getYInt() + var3.getFrontOffsetY(); + int var13 = par1IBlockSource.getZInt() + var3.getFrontOffsetZ(); + Material var14 = var4.getBlockMaterial(var11, var12, var13); + double var15; + + if (Material.water.equals(var14)) { + var15 = 1.0D; + } else { + if (!Material.air.equals(var14) || !Material.water.equals(var4.getBlockMaterial(var11, var12 - 1, var13))) { + return this.defaultDispenserItemBehavior.dispense(par1IBlockSource, par2ItemStack); + } + + var15 = 0.0D; + } + + EntityBoat var17 = new EntityBoat(var4, var5, var7 + var15, var9); + var4.spawnEntityInWorld(var17); + par2ItemStack.splitStack(1); + return par2ItemStack; + } + + /** + * Play the dispense sound from the specified block. + */ + protected void playDispenseSound(IBlockSource par1IBlockSource) { + par1IBlockSource.getWorld().playAuxSFX(1000, par1IBlockSource.getXInt(), par1IBlockSource.getYInt(), + par1IBlockSource.getZInt(), 0); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/DispenserBehaviorDye.java b/sp-server/src/main/java/net/minecraft/src/DispenserBehaviorDye.java new file mode 100644 index 0000000..6588d9d --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/DispenserBehaviorDye.java @@ -0,0 +1,43 @@ +package net.minecraft.src; + +final class DispenserBehaviorDye extends BehaviorDefaultDispenseItem { + private boolean field_96461_b = true; + + /** + * Dispense the specified stack, play the dispense sound and spawn particles. + */ + protected ItemStack dispenseStack(IBlockSource par1IBlockSource, ItemStack par2ItemStack) { + if (par2ItemStack.getItemDamage() == 15) { + EnumFacing var3 = BlockDispenser.getFacing(par1IBlockSource.getBlockMetadata()); + World var4 = par1IBlockSource.getWorld(); + int var5 = par1IBlockSource.getXInt() + var3.getFrontOffsetX(); + int var6 = par1IBlockSource.getYInt() + var3.getFrontOffsetY(); + int var7 = par1IBlockSource.getZInt() + var3.getFrontOffsetZ(); + + if (ItemDye.func_96604_a(par2ItemStack, var4, var5, var6, var7)) { + if (!var4.isRemote) { + var4.playAuxSFX(2005, var5, var6, var7, 0); + } + } else { + this.field_96461_b = false; + } + + return par2ItemStack; + } else { + return super.dispenseStack(par1IBlockSource, par2ItemStack); + } + } + + /** + * Play the dispense sound from the specified block. + */ + protected void playDispenseSound(IBlockSource par1IBlockSource) { + if (this.field_96461_b) { + par1IBlockSource.getWorld().playAuxSFX(1000, par1IBlockSource.getXInt(), par1IBlockSource.getYInt(), + par1IBlockSource.getZInt(), 0); + } else { + par1IBlockSource.getWorld().playAuxSFX(1001, par1IBlockSource.getXInt(), par1IBlockSource.getYInt(), + par1IBlockSource.getZInt(), 0); + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/DispenserBehaviorEgg.java b/sp-server/src/main/java/net/minecraft/src/DispenserBehaviorEgg.java new file mode 100644 index 0000000..81bdb97 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/DispenserBehaviorEgg.java @@ -0,0 +1,10 @@ +package net.minecraft.src; + +final class DispenserBehaviorEgg extends BehaviorProjectileDispense { + /** + * Return the projectile entity spawned by this dispense behavior. + */ + protected IProjectile getProjectileEntity(World par1World, IPosition par2IPosition) { + return new EntityEgg(par1World, par2IPosition.getX(), par2IPosition.getY(), par2IPosition.getZ()); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/DispenserBehaviorEmptyBucket.java b/sp-server/src/main/java/net/minecraft/src/DispenserBehaviorEmptyBucket.java new file mode 100644 index 0000000..d71413d --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/DispenserBehaviorEmptyBucket.java @@ -0,0 +1,40 @@ +package net.minecraft.src; + +final class DispenserBehaviorEmptyBucket extends BehaviorDefaultDispenseItem { + private final BehaviorDefaultDispenseItem defaultDispenserItemBehavior = new BehaviorDefaultDispenseItem(); + + /** + * Dispense the specified stack, play the dispense sound and spawn particles. + */ + public ItemStack dispenseStack(IBlockSource par1IBlockSource, ItemStack par2ItemStack) { + EnumFacing var3 = BlockDispenser.getFacing(par1IBlockSource.getBlockMetadata()); + World var4 = par1IBlockSource.getWorld(); + int var5 = par1IBlockSource.getXInt() + var3.getFrontOffsetX(); + int var6 = par1IBlockSource.getYInt() + var3.getFrontOffsetY(); + int var7 = par1IBlockSource.getZInt() + var3.getFrontOffsetZ(); + Material var8 = var4.getBlockMaterial(var5, var6, var7); + int var9 = var4.getBlockMetadata(var5, var6, var7); + Item var10; + + if (Material.water.equals(var8) && var9 == 0) { + var10 = Item.bucketWater; + } else { + if (!Material.lava.equals(var8) || var9 != 0) { + return super.dispenseStack(par1IBlockSource, par2ItemStack); + } + + var10 = Item.bucketLava; + } + + var4.setBlockToAir(var5, var6, var7); + + if (--par2ItemStack.stackSize == 0) { + par2ItemStack.itemID = var10.itemID; + par2ItemStack.stackSize = 1; + } else if (((TileEntityDispenser) par1IBlockSource.getBlockTileEntity()).addItem(new ItemStack(var10)) < 0) { + this.defaultDispenserItemBehavior.dispense(par1IBlockSource, new ItemStack(var10)); + } + + return par2ItemStack; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/DispenserBehaviorExperience.java b/sp-server/src/main/java/net/minecraft/src/DispenserBehaviorExperience.java new file mode 100644 index 0000000..3852da9 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/DispenserBehaviorExperience.java @@ -0,0 +1,18 @@ +package net.minecraft.src; + +final class DispenserBehaviorExperience extends BehaviorProjectileDispense { + /** + * Return the projectile entity spawned by this dispense behavior. + */ + protected IProjectile getProjectileEntity(World par1World, IPosition par2IPosition) { + return new EntityExpBottle(par1World, par2IPosition.getX(), par2IPosition.getY(), par2IPosition.getZ()); + } + + protected float func_82498_a() { + return super.func_82498_a() * 0.5F; + } + + protected float func_82500_b() { + return super.func_82500_b() * 1.25F; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/DispenserBehaviorFilledBucket.java b/sp-server/src/main/java/net/minecraft/src/DispenserBehaviorFilledBucket.java new file mode 100644 index 0000000..b949311 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/DispenserBehaviorFilledBucket.java @@ -0,0 +1,25 @@ +package net.minecraft.src; + +final class DispenserBehaviorFilledBucket extends BehaviorDefaultDispenseItem { + private final BehaviorDefaultDispenseItem defaultDispenserItemBehavior = new BehaviorDefaultDispenseItem(); + + /** + * Dispense the specified stack, play the dispense sound and spawn particles. + */ + public ItemStack dispenseStack(IBlockSource par1IBlockSource, ItemStack par2ItemStack) { + ItemBucket var3 = (ItemBucket) par2ItemStack.getItem(); + int var4 = par1IBlockSource.getXInt(); + int var5 = par1IBlockSource.getYInt(); + int var6 = par1IBlockSource.getZInt(); + EnumFacing var7 = BlockDispenser.getFacing(par1IBlockSource.getBlockMetadata()); + + if (var3.tryPlaceContainedLiquid(par1IBlockSource.getWorld(), (double) var4, (double) var5, (double) var6, + var4 + var7.getFrontOffsetX(), var5 + var7.getFrontOffsetY(), var6 + var7.getFrontOffsetZ())) { + par2ItemStack.itemID = Item.bucketEmpty.itemID; + par2ItemStack.stackSize = 1; + return par2ItemStack; + } else { + return this.defaultDispenserItemBehavior.dispense(par1IBlockSource, par2ItemStack); + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/DispenserBehaviorFire.java b/sp-server/src/main/java/net/minecraft/src/DispenserBehaviorFire.java new file mode 100644 index 0000000..8d90d8d --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/DispenserBehaviorFire.java @@ -0,0 +1,44 @@ +package net.minecraft.src; + +final class DispenserBehaviorFire extends BehaviorDefaultDispenseItem { + private boolean field_96466_b = true; + + /** + * Dispense the specified stack, play the dispense sound and spawn particles. + */ + protected ItemStack dispenseStack(IBlockSource par1IBlockSource, ItemStack par2ItemStack) { + EnumFacing var3 = BlockDispenser.getFacing(par1IBlockSource.getBlockMetadata()); + World var4 = par1IBlockSource.getWorld(); + int var5 = par1IBlockSource.getXInt() + var3.getFrontOffsetX(); + int var6 = par1IBlockSource.getYInt() + var3.getFrontOffsetY(); + int var7 = par1IBlockSource.getZInt() + var3.getFrontOffsetZ(); + + if (var4.isAirBlock(var5, var6, var7)) { + var4.setBlock(var5, var6, var7, Block.fire.blockID); + + if (par2ItemStack.func_96631_a(1, var4.rand)) { + par2ItemStack.stackSize = 0; + } + } else if (var4.getBlockId(var5, var6, var7) == Block.tnt.blockID) { + Block.tnt.onBlockDestroyedByPlayer(var4, var5, var6, var7, 1); + var4.setBlockToAir(var5, var6, var7); + } else { + this.field_96466_b = false; + } + + return par2ItemStack; + } + + /** + * Play the dispense sound from the specified block. + */ + protected void playDispenseSound(IBlockSource par1IBlockSource) { + if (this.field_96466_b) { + par1IBlockSource.getWorld().playAuxSFX(1000, par1IBlockSource.getXInt(), par1IBlockSource.getYInt(), + par1IBlockSource.getZInt(), 0); + } else { + par1IBlockSource.getWorld().playAuxSFX(1001, par1IBlockSource.getXInt(), par1IBlockSource.getYInt(), + par1IBlockSource.getZInt(), 0); + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/DispenserBehaviorFireball.java b/sp-server/src/main/java/net/minecraft/src/DispenserBehaviorFireball.java new file mode 100644 index 0000000..079e69f --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/DispenserBehaviorFireball.java @@ -0,0 +1,32 @@ +package net.minecraft.src; + +import java.util.Random; + +final class DispenserBehaviorFireball extends BehaviorDefaultDispenseItem { + /** + * Dispense the specified stack, play the dispense sound and spawn particles. + */ + public ItemStack dispenseStack(IBlockSource par1IBlockSource, ItemStack par2ItemStack) { + EnumFacing var3 = BlockDispenser.getFacing(par1IBlockSource.getBlockMetadata()); + IPosition var4 = BlockDispenser.getIPositionFromBlockSource(par1IBlockSource); + double var5 = var4.getX() + (double) ((float) var3.getFrontOffsetX() * 0.3F); + double var7 = var4.getY() + (double) ((float) var3.getFrontOffsetX() * 0.3F); + double var9 = var4.getZ() + (double) ((float) var3.getFrontOffsetZ() * 0.3F); + World var11 = par1IBlockSource.getWorld(); + Random var12 = var11.rand; + double var13 = var12.nextGaussian() * 0.05D + (double) var3.getFrontOffsetX(); + double var15 = var12.nextGaussian() * 0.05D + (double) var3.getFrontOffsetY(); + double var17 = var12.nextGaussian() * 0.05D + (double) var3.getFrontOffsetZ(); + var11.spawnEntityInWorld(new EntitySmallFireball(var11, var5, var7, var9, var13, var15, var17)); + par2ItemStack.splitStack(1); + return par2ItemStack; + } + + /** + * Play the dispense sound from the specified block. + */ + protected void playDispenseSound(IBlockSource par1IBlockSource) { + par1IBlockSource.getWorld().playAuxSFX(1009, par1IBlockSource.getXInt(), par1IBlockSource.getYInt(), + par1IBlockSource.getZInt(), 0); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/DispenserBehaviorFireworks.java b/sp-server/src/main/java/net/minecraft/src/DispenserBehaviorFireworks.java new file mode 100644 index 0000000..a056b49 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/DispenserBehaviorFireworks.java @@ -0,0 +1,26 @@ +package net.minecraft.src; + +final class DispenserBehaviorFireworks extends BehaviorDefaultDispenseItem { + /** + * Dispense the specified stack, play the dispense sound and spawn particles. + */ + public ItemStack dispenseStack(IBlockSource par1IBlockSource, ItemStack par2ItemStack) { + EnumFacing var3 = BlockDispenser.getFacing(par1IBlockSource.getBlockMetadata()); + double var4 = par1IBlockSource.getX() + (double) var3.getFrontOffsetX(); + double var6 = (double) ((float) par1IBlockSource.getYInt() + 0.2F); + double var8 = par1IBlockSource.getZ() + (double) var3.getFrontOffsetZ(); + EntityFireworkRocket var10 = new EntityFireworkRocket(par1IBlockSource.getWorld(), var4, var6, var8, + par2ItemStack); + par1IBlockSource.getWorld().spawnEntityInWorld(var10); + par2ItemStack.splitStack(1); + return par2ItemStack; + } + + /** + * Play the dispense sound from the specified block. + */ + protected void playDispenseSound(IBlockSource par1IBlockSource) { + par1IBlockSource.getWorld().playAuxSFX(1002, par1IBlockSource.getXInt(), par1IBlockSource.getYInt(), + par1IBlockSource.getZInt(), 0); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/DispenserBehaviorMobEgg.java b/sp-server/src/main/java/net/minecraft/src/DispenserBehaviorMobEgg.java new file mode 100644 index 0000000..26298d6 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/DispenserBehaviorMobEgg.java @@ -0,0 +1,22 @@ +package net.minecraft.src; + +final class DispenserBehaviorMobEgg extends BehaviorDefaultDispenseItem { + /** + * Dispense the specified stack, play the dispense sound and spawn particles. + */ + public ItemStack dispenseStack(IBlockSource par1IBlockSource, ItemStack par2ItemStack) { + EnumFacing var3 = BlockDispenser.getFacing(par1IBlockSource.getBlockMetadata()); + double var4 = par1IBlockSource.getX() + (double) var3.getFrontOffsetX(); + double var6 = (double) ((float) par1IBlockSource.getYInt() + 0.2F); + double var8 = par1IBlockSource.getZ() + (double) var3.getFrontOffsetZ(); + Entity var10 = ItemMonsterPlacer.spawnCreature(par1IBlockSource.getWorld(), par2ItemStack.getItemDamage(), var4, + var6, var8); + + if (var10 instanceof EntityLiving && par2ItemStack.hasDisplayName()) { + ((EntityLiving) var10).func_94058_c(par2ItemStack.getDisplayName()); + } + + par2ItemStack.splitStack(1); + return par2ItemStack; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/DispenserBehaviorPotion.java b/sp-server/src/main/java/net/minecraft/src/DispenserBehaviorPotion.java new file mode 100644 index 0000000..8538963 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/DispenserBehaviorPotion.java @@ -0,0 +1,14 @@ +package net.minecraft.src; + +final class DispenserBehaviorPotion implements IBehaviorDispenseItem { + private final BehaviorDefaultDispenseItem defaultDispenserItemBehavior = new BehaviorDefaultDispenseItem(); + + /** + * Dispenses the specified ItemStack from a dispenser. + */ + public ItemStack dispense(IBlockSource par1IBlockSource, ItemStack par2ItemStack) { + return ItemPotion.isSplash(par2ItemStack.getItemDamage()) + ? (new DispenserBehaviorPotionProjectile(this, par2ItemStack)).dispense(par1IBlockSource, par2ItemStack) + : this.defaultDispenserItemBehavior.dispense(par1IBlockSource, par2ItemStack); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/DispenserBehaviorPotionProjectile.java b/sp-server/src/main/java/net/minecraft/src/DispenserBehaviorPotionProjectile.java new file mode 100644 index 0000000..95b44ac --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/DispenserBehaviorPotionProjectile.java @@ -0,0 +1,28 @@ +package net.minecraft.src; + +class DispenserBehaviorPotionProjectile extends BehaviorProjectileDispense { + final ItemStack potionItemStack; + + final DispenserBehaviorPotion dispenserPotionBehavior; + + DispenserBehaviorPotionProjectile(DispenserBehaviorPotion par1DispenserBehaviorPotion, ItemStack par2ItemStack) { + this.dispenserPotionBehavior = par1DispenserBehaviorPotion; + this.potionItemStack = par2ItemStack; + } + + /** + * Return the projectile entity spawned by this dispense behavior. + */ + protected IProjectile getProjectileEntity(World par1World, IPosition par2IPosition) { + return new EntityPotion(par1World, par2IPosition.getX(), par2IPosition.getY(), par2IPosition.getZ(), + this.potionItemStack.copy()); + } + + protected float func_82498_a() { + return super.func_82498_a() * 0.5F; + } + + protected float func_82500_b() { + return super.func_82500_b() * 1.25F; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/DispenserBehaviorSnowball.java b/sp-server/src/main/java/net/minecraft/src/DispenserBehaviorSnowball.java new file mode 100644 index 0000000..f9ffb8b --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/DispenserBehaviorSnowball.java @@ -0,0 +1,10 @@ +package net.minecraft.src; + +final class DispenserBehaviorSnowball extends BehaviorProjectileDispense { + /** + * Return the projectile entity spawned by this dispense behavior. + */ + protected IProjectile getProjectileEntity(World par1World, IPosition par2IPosition) { + return new EntitySnowball(par1World, par2IPosition.getX(), par2IPosition.getY(), par2IPosition.getZ()); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/DispenserBehaviorTNT.java b/sp-server/src/main/java/net/minecraft/src/DispenserBehaviorTNT.java new file mode 100644 index 0000000..8a35241 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/DispenserBehaviorTNT.java @@ -0,0 +1,19 @@ +package net.minecraft.src; + +final class DispenserBehaviorTNT extends BehaviorDefaultDispenseItem { + /** + * Dispense the specified stack, play the dispense sound and spawn particles. + */ + protected ItemStack dispenseStack(IBlockSource par1IBlockSource, ItemStack par2ItemStack) { + EnumFacing var3 = BlockDispenser.getFacing(par1IBlockSource.getBlockMetadata()); + World var4 = par1IBlockSource.getWorld(); + int var5 = par1IBlockSource.getXInt() + var3.getFrontOffsetX(); + int var6 = par1IBlockSource.getYInt() + var3.getFrontOffsetY(); + int var7 = par1IBlockSource.getZInt() + var3.getFrontOffsetZ(); + EntityTNTPrimed var8 = new EntityTNTPrimed(var4, (double) ((float) var5 + 0.5F), (double) ((float) var6 + 0.5F), + (double) ((float) var7 + 0.5F), (EntityLiving) null); + var4.spawnEntityInWorld(var8); + --par2ItemStack.stackSize; + return par2ItemStack; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/DispenserBehaviors.java b/sp-server/src/main/java/net/minecraft/src/DispenserBehaviors.java new file mode 100644 index 0000000..23e881c --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/DispenserBehaviors.java @@ -0,0 +1,23 @@ +package net.minecraft.src; + +public class DispenserBehaviors { + public static void func_96467_a() { + BlockDispenser.dispenseBehaviorRegistry.putObject(Item.arrow, new DispenserBehaviorArrow()); + BlockDispenser.dispenseBehaviorRegistry.putObject(Item.egg, new DispenserBehaviorEgg()); + BlockDispenser.dispenseBehaviorRegistry.putObject(Item.snowball, new DispenserBehaviorSnowball()); + BlockDispenser.dispenseBehaviorRegistry.putObject(Item.expBottle, new DispenserBehaviorExperience()); + BlockDispenser.dispenseBehaviorRegistry.putObject(Item.potion, new DispenserBehaviorPotion()); + BlockDispenser.dispenseBehaviorRegistry.putObject(Item.monsterPlacer, new DispenserBehaviorMobEgg()); + BlockDispenser.dispenseBehaviorRegistry.putObject(Item.firework, new DispenserBehaviorFireworks()); + BlockDispenser.dispenseBehaviorRegistry.putObject(Item.fireballCharge, new DispenserBehaviorFireball()); + BlockDispenser.dispenseBehaviorRegistry.putObject(Item.boat, new DispenserBehaviorBoat()); + DispenserBehaviorFilledBucket var0 = new DispenserBehaviorFilledBucket(); + BlockDispenser.dispenseBehaviorRegistry.putObject(Item.bucketLava, var0); + BlockDispenser.dispenseBehaviorRegistry.putObject(Item.bucketWater, var0); + BlockDispenser.dispenseBehaviorRegistry.putObject(Item.bucketEmpty, new DispenserBehaviorEmptyBucket()); + BlockDispenser.dispenseBehaviorRegistry.putObject(Item.flintAndSteel, new DispenserBehaviorFire()); + BlockDispenser.dispenseBehaviorRegistry.putObject(Item.dyePowder, new DispenserBehaviorDye()); + BlockDispenser.dispenseBehaviorRegistry.putObject(Item.itemsList[Block.tnt.blockID], + new DispenserBehaviorTNT()); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/Empty3.java b/sp-server/src/main/java/net/minecraft/src/Empty3.java new file mode 100644 index 0000000..8c4433e --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/Empty3.java @@ -0,0 +1,4 @@ +package net.minecraft.src; + +class Empty3 { +} diff --git a/sp-server/src/main/java/net/minecraft/src/EmptyChunk.java b/sp-server/src/main/java/net/minecraft/src/EmptyChunk.java new file mode 100644 index 0000000..b833c7c --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EmptyChunk.java @@ -0,0 +1,195 @@ +package net.minecraft.src; + +import java.util.List; +import java.util.Random; + +public class EmptyChunk extends Chunk { + public EmptyChunk(World par1World, int par2, int par3) { + super(par1World, par2, par3); + } + + /** + * Checks whether the chunk is at the X/Z location specified + */ + public boolean isAtLocation(int par1, int par2) { + return par1 == this.xPosition && par2 == this.zPosition; + } + + /** + * Returns the value in the height map at this x, z coordinate in the chunk + */ + public int getHeightValue(int par1, int par2) { + return 0; + } + + /** + * Generates the initial skylight map for the chunk upon generation or load. + */ + public void generateSkylightMap() { + } + + /** + * Return the ID of a block in the chunk. + */ + public int getBlockID(int par1, int par2, int par3) { + return 0; + } + + public int getBlockLightOpacity(int par1, int par2, int par3) { + return 255; + } + + /** + * Sets a blockID of a position within a chunk with metadata. Args: x, y, z, + * blockID, metadata + */ + public boolean setBlockIDWithMetadata(int par1, int par2, int par3, int par4, int par5) { + return true; + } + + /** + * Return the metadata corresponding to the given coordinates inside a chunk. + */ + public int getBlockMetadata(int par1, int par2, int par3) { + return 0; + } + + /** + * Set the metadata of a block in the chunk + */ + public boolean setBlockMetadata(int par1, int par2, int par3, int par4) { + return false; + } + + /** + * Gets the amount of light saved in this block (doesn't adjust for daylight) + */ + public int getSavedLightValue(EnumSkyBlock par1EnumSkyBlock, int par2, int par3, int par4) { + return 0; + } + + /** + * Sets the light value at the coordinate. If enumskyblock is set to sky it sets + * it in the skylightmap and if its a block then into the blocklightmap. Args + * enumSkyBlock, x, y, z, lightValue + */ + public void setLightValue(EnumSkyBlock par1EnumSkyBlock, int par2, int par3, int par4, int par5) { + } + + /** + * Gets the amount of light on a block taking into account sunlight + */ + public int getBlockLightValue(int par1, int par2, int par3, int par4) { + return 0; + } + + /** + * Adds an entity to the chunk. Args: entity + */ + public void addEntity(Entity par1Entity) { + } + + /** + * removes entity using its y chunk coordinate as its index + */ + public void removeEntity(Entity par1Entity) { + } + + /** + * Removes entity at the specified index from the entity array. + */ + public void removeEntityAtIndex(Entity par1Entity, int par2) { + } + + /** + * Returns whether is not a block above this one blocking sight to the sky (done + * via checking against the heightmap) + */ + public boolean canBlockSeeTheSky(int par1, int par2, int par3) { + return false; + } + + /** + * Gets the TileEntity for a given block in this chunk + */ + public TileEntity getChunkBlockTileEntity(int par1, int par2, int par3) { + return null; + } + + /** + * Adds a TileEntity to a chunk + */ + public void addTileEntity(TileEntity par1TileEntity) { + } + + /** + * Sets the TileEntity for a given block in this chunk + */ + public void setChunkBlockTileEntity(int par1, int par2, int par3, TileEntity par4TileEntity) { + } + + /** + * Removes the TileEntity for a given block in this chunk + */ + public void removeChunkBlockTileEntity(int par1, int par2, int par3) { + } + + /** + * Called when this Chunk is loaded by the ChunkProvider + */ + public void onChunkLoad() { + } + + /** + * Called when this Chunk is unloaded by the ChunkProvider + */ + public void onChunkUnload() { + } + + /** + * Sets the isModified flag for this Chunk + */ + public void setChunkModified() { + } + + /** + * Fills the given list of all entities that intersect within the given bounding + * box that aren't the passed entity Args: entity, aabb, listToFill + */ + public void getEntitiesWithinAABBForEntity(Entity par1Entity, AxisAlignedBB par2AxisAlignedBB, List par3List, + IEntitySelector par4IEntitySelector) { + } + + /** + * Gets all entities that can be assigned to the specified class. Args: + * entityClass, aabb, listToFill + */ + public void getEntitiesOfTypeWithinAAAB(Class par1Class, AxisAlignedBB par2AxisAlignedBB, List par3List, + IEntitySelector par4IEntitySelector) { + } + + /** + * Returns true if this Chunk needs to be saved + */ + public boolean needsSaving(boolean par1) { + return false; + } + + public Random getRandomWithSeed(long par1) { + return new Random(this.worldObj.getSeed() + (long) (this.xPosition * this.xPosition * 4987142) + + (long) (this.xPosition * 5947611) + (long) (this.zPosition * this.zPosition) * 4392871L + + (long) (this.zPosition * 389711) ^ par1); + } + + public boolean isEmpty() { + return true; + } + + /** + * Returns whether the ExtendedBlockStorages containing levels (in blocks) from + * arg 1 to arg 2 are fully empty (true) or not (false). + */ + public boolean getAreLevelsEmpty(int par1, int par2) { + return true; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/Enchantment.java b/sp-server/src/main/java/net/minecraft/src/Enchantment.java new file mode 100644 index 0000000..0d042bb --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/Enchantment.java @@ -0,0 +1,211 @@ +package net.minecraft.src; + +import java.util.ArrayList; + +public abstract class Enchantment { + public static final Enchantment[] enchantmentsList = new Enchantment[256]; + public static final Enchantment[] field_92090_c; + + /** Converts environmental damage to armour damage */ + public static final Enchantment protection = new EnchantmentProtection(0, 10, 0); + + /** Protection against fire */ + public static final Enchantment fireProtection = new EnchantmentProtection(1, 5, 1); + + /** Less fall damage */ + public static final Enchantment featherFalling = new EnchantmentProtection(2, 5, 2); + + /** Protection against explosions */ + public static final Enchantment blastProtection = new EnchantmentProtection(3, 2, 3); + + /** Protection against projectile entities (e.g. arrows) */ + public static final Enchantment projectileProtection = new EnchantmentProtection(4, 5, 4); + + /** + * Decreases the rate of air loss underwater; increases time between damage + * while suffocating + */ + public static final Enchantment respiration = new EnchantmentOxygen(5, 2); + + /** Increases underwater mining rate */ + public static final Enchantment aquaAffinity = new EnchantmentWaterWorker(6, 2); + public static final Enchantment thorns = new EnchantmentThorns(7, 1); + + /** Extra damage to mobs */ + public static final Enchantment sharpness = new EnchantmentDamage(16, 10, 0); + + /** Extra damage to zombies, zombie pigmen and skeletons */ + public static final Enchantment smite = new EnchantmentDamage(17, 5, 1); + + /** Extra damage to spiders, cave spiders and silverfish */ + public static final Enchantment baneOfArthropods = new EnchantmentDamage(18, 5, 2); + + /** Knocks mob and players backwards upon hit */ + public static final Enchantment knockback = new EnchantmentKnockback(19, 5); + + /** Lights mobs on fire */ + public static final Enchantment fireAspect = new EnchantmentFireAspect(20, 2); + + /** Mobs have a chance to drop more loot */ + public static final Enchantment looting = new EnchantmentLootBonus(21, 2, EnumEnchantmentType.weapon); + + /** Faster resource gathering while in use */ + public static final Enchantment efficiency = new EnchantmentDigging(32, 10); + + /** + * Blocks mined will drop themselves, even if it should drop something else + * (e.g. stone will drop stone, not cobblestone) + */ + public static final Enchantment silkTouch = new EnchantmentUntouching(33, 1); + + /** + * Sometimes, the tool's durability will not be spent when the tool is used + */ + public static final Enchantment unbreaking = new EnchantmentDurability(34, 5); + + /** Can multiply the drop rate of items from blocks */ + public static final Enchantment fortune = new EnchantmentLootBonus(35, 2, EnumEnchantmentType.digger); + + /** Power enchantment for bows, add's extra damage to arrows. */ + public static final Enchantment power = new EnchantmentArrowDamage(48, 10); + + /** + * Knockback enchantments for bows, the arrows will knockback the target when + * hit. + */ + public static final Enchantment punch = new EnchantmentArrowKnockback(49, 2); + + /** + * Flame enchantment for bows. Arrows fired by the bow will be on fire. Any + * target hit will also set on fire. + */ + public static final Enchantment flame = new EnchantmentArrowFire(50, 2); + + /** + * Infinity enchantment for bows. The bow will not consume arrows anymore, but + * will still required at least one arrow on inventory use the bow. + */ + public static final Enchantment infinity = new EnchantmentArrowInfinite(51, 1); + public final int effectId; + private final int weight; + + /** The EnumEnchantmentType given to this Enchantment. */ + public EnumEnchantmentType type; + + /** Used in localisation and stats. */ + protected String name; + + protected Enchantment(int par1, int par2, EnumEnchantmentType par3EnumEnchantmentType) { + this.effectId = par1; + this.weight = par2; + this.type = par3EnumEnchantmentType; + + if (enchantmentsList[par1] != null) { + throw new IllegalArgumentException("Duplicate enchantment id!"); + } else { + enchantmentsList[par1] = this; + } + } + + public int getWeight() { + return this.weight; + } + + /** + * Returns the minimum level that the enchantment can have. + */ + public int getMinLevel() { + return 1; + } + + /** + * Returns the maximum level that the enchantment can have. + */ + public int getMaxLevel() { + return 1; + } + + /** + * Returns the minimal value of enchantability needed on the enchantment level + * passed. + */ + public int getMinEnchantability(int par1) { + return 1 + par1 * 10; + } + + /** + * Returns the maximum value of enchantability nedded on the enchantment level + * passed. + */ + public int getMaxEnchantability(int par1) { + return this.getMinEnchantability(par1) + 5; + } + + /** + * Calculates de damage protection of the enchantment based on level and damage + * source passed. + */ + public int calcModifierDamage(int par1, DamageSource par2DamageSource) { + return 0; + } + + /** + * Calculates de (magic) damage done by the enchantment on a living entity based + * on level and entity passed. + */ + public int calcModifierLiving(int par1, EntityLiving par2EntityLiving) { + return 0; + } + + /** + * Determines if the enchantment passed can be applyied together with this + * enchantment. + */ + public boolean canApplyTogether(Enchantment par1Enchantment) { + return this != par1Enchantment; + } + + /** + * Sets the enchantment name + */ + public Enchantment setName(String par1Str) { + this.name = par1Str; + return this; + } + + /** + * Return the name of key in translation table of this enchantment. + */ + public String getName() { + return "enchantment." + this.name; + } + + /** + * Returns the correct traslated name of the enchantment and the level in roman + * numbers. + */ + public String getTranslatedName(int par1) { + String var2 = StatCollector.translateToLocal(this.getName()); + return var2 + " " + StatCollector.translateToLocal("enchantment.level." + par1); + } + + public boolean func_92089_a(ItemStack par1ItemStack) { + return this.type.canEnchantItem(par1ItemStack.getItem()); + } + + static { + ArrayList var0 = new ArrayList(); + Enchantment[] var1 = enchantmentsList; + int var2 = var1.length; + + for (int var3 = 0; var3 < var2; ++var3) { + Enchantment var4 = var1[var3]; + + if (var4 != null) { + var0.add(var4); + } + } + + field_92090_c = (Enchantment[]) var0.toArray(new Enchantment[0]); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EnchantmentArrowDamage.java b/sp-server/src/main/java/net/minecraft/src/EnchantmentArrowDamage.java new file mode 100644 index 0000000..7d1b531 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EnchantmentArrowDamage.java @@ -0,0 +1,31 @@ +package net.minecraft.src; + +public class EnchantmentArrowDamage extends Enchantment { + public EnchantmentArrowDamage(int par1, int par2) { + super(par1, par2, EnumEnchantmentType.bow); + this.setName("arrowDamage"); + } + + /** + * Returns the minimal value of enchantability needed on the enchantment level + * passed. + */ + public int getMinEnchantability(int par1) { + return 1 + (par1 - 1) * 10; + } + + /** + * Returns the maximum value of enchantability nedded on the enchantment level + * passed. + */ + public int getMaxEnchantability(int par1) { + return this.getMinEnchantability(par1) + 15; + } + + /** + * Returns the maximum level that the enchantment can have. + */ + public int getMaxLevel() { + return 5; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EnchantmentArrowFire.java b/sp-server/src/main/java/net/minecraft/src/EnchantmentArrowFire.java new file mode 100644 index 0000000..71c42be --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EnchantmentArrowFire.java @@ -0,0 +1,31 @@ +package net.minecraft.src; + +public class EnchantmentArrowFire extends Enchantment { + public EnchantmentArrowFire(int par1, int par2) { + super(par1, par2, EnumEnchantmentType.bow); + this.setName("arrowFire"); + } + + /** + * Returns the minimal value of enchantability needed on the enchantment level + * passed. + */ + public int getMinEnchantability(int par1) { + return 20; + } + + /** + * Returns the maximum value of enchantability nedded on the enchantment level + * passed. + */ + public int getMaxEnchantability(int par1) { + return 50; + } + + /** + * Returns the maximum level that the enchantment can have. + */ + public int getMaxLevel() { + return 1; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EnchantmentArrowInfinite.java b/sp-server/src/main/java/net/minecraft/src/EnchantmentArrowInfinite.java new file mode 100644 index 0000000..fe94cde --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EnchantmentArrowInfinite.java @@ -0,0 +1,31 @@ +package net.minecraft.src; + +public class EnchantmentArrowInfinite extends Enchantment { + public EnchantmentArrowInfinite(int par1, int par2) { + super(par1, par2, EnumEnchantmentType.bow); + this.setName("arrowInfinite"); + } + + /** + * Returns the minimal value of enchantability needed on the enchantment level + * passed. + */ + public int getMinEnchantability(int par1) { + return 20; + } + + /** + * Returns the maximum value of enchantability nedded on the enchantment level + * passed. + */ + public int getMaxEnchantability(int par1) { + return 50; + } + + /** + * Returns the maximum level that the enchantment can have. + */ + public int getMaxLevel() { + return 1; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EnchantmentArrowKnockback.java b/sp-server/src/main/java/net/minecraft/src/EnchantmentArrowKnockback.java new file mode 100644 index 0000000..bf8d973 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EnchantmentArrowKnockback.java @@ -0,0 +1,31 @@ +package net.minecraft.src; + +public class EnchantmentArrowKnockback extends Enchantment { + public EnchantmentArrowKnockback(int par1, int par2) { + super(par1, par2, EnumEnchantmentType.bow); + this.setName("arrowKnockback"); + } + + /** + * Returns the minimal value of enchantability needed on the enchantment level + * passed. + */ + public int getMinEnchantability(int par1) { + return 12 + (par1 - 1) * 20; + } + + /** + * Returns the maximum value of enchantability nedded on the enchantment level + * passed. + */ + public int getMaxEnchantability(int par1) { + return this.getMinEnchantability(par1) + 25; + } + + /** + * Returns the maximum level that the enchantment can have. + */ + public int getMaxLevel() { + return 2; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EnchantmentDamage.java b/sp-server/src/main/java/net/minecraft/src/EnchantmentDamage.java new file mode 100644 index 0000000..4b83f6b --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EnchantmentDamage.java @@ -0,0 +1,90 @@ +package net.minecraft.src; + +public class EnchantmentDamage extends Enchantment { + /** Holds the name to be translated of each protection type. */ + private static final String[] protectionName = new String[] { "all", "undead", "arthropods" }; + + /** + * Holds the base factor of enchantability needed to be able to use the enchant. + */ + private static final int[] baseEnchantability = new int[] { 1, 5, 5 }; + + /** + * Holds how much each level increased the enchantability factor to be able to + * use this enchant. + */ + private static final int[] levelEnchantability = new int[] { 11, 8, 8 }; + + /** + * Used on the formula of base enchantability, this is the 'window' factor of + * values to be able to use thing enchant. + */ + private static final int[] thresholdEnchantability = new int[] { 20, 20, 20 }; + + /** + * Defines the type of damage of the enchantment, 0 = all, 1 = undead, 3 = + * arthropods + */ + public final int damageType; + + public EnchantmentDamage(int par1, int par2, int par3) { + super(par1, par2, EnumEnchantmentType.weapon); + this.damageType = par3; + } + + /** + * Returns the minimal value of enchantability needed on the enchantment level + * passed. + */ + public int getMinEnchantability(int par1) { + return baseEnchantability[this.damageType] + (par1 - 1) * levelEnchantability[this.damageType]; + } + + /** + * Returns the maximum value of enchantability nedded on the enchantment level + * passed. + */ + public int getMaxEnchantability(int par1) { + return this.getMinEnchantability(par1) + thresholdEnchantability[this.damageType]; + } + + /** + * Returns the maximum level that the enchantment can have. + */ + public int getMaxLevel() { + return 5; + } + + /** + * Calculates de (magic) damage done by the enchantment on a living entity based + * on level and entity passed. + */ + public int calcModifierLiving(int par1, EntityLiving par2EntityLiving) { + return this.damageType == 0 ? MathHelper.floor_float((float) par1 * 2.75F) + : (this.damageType == 1 && par2EntityLiving.getCreatureAttribute() == EnumCreatureAttribute.UNDEAD + ? MathHelper.floor_float((float) par1 * 4.5F) + : (this.damageType == 2 + && par2EntityLiving.getCreatureAttribute() == EnumCreatureAttribute.ARTHROPOD + ? MathHelper.floor_float((float) par1 * 4.5F) + : 0)); + } + + /** + * Return the name of key in translation table of this enchantment. + */ + public String getName() { + return "enchantment.damage." + protectionName[this.damageType]; + } + + /** + * Determines if the enchantment passed can be applyied together with this + * enchantment. + */ + public boolean canApplyTogether(Enchantment par1Enchantment) { + return !(par1Enchantment instanceof EnchantmentDamage); + } + + public boolean func_92089_a(ItemStack par1ItemStack) { + return par1ItemStack.getItem() instanceof ItemAxe ? true : super.func_92089_a(par1ItemStack); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EnchantmentData.java b/sp-server/src/main/java/net/minecraft/src/EnchantmentData.java new file mode 100644 index 0000000..04b96cd --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EnchantmentData.java @@ -0,0 +1,19 @@ +package net.minecraft.src; + +public class EnchantmentData extends WeightedRandomItem { + /** Enchantment object associated with this EnchantmentData */ + public final Enchantment enchantmentobj; + + /** Enchantment level associated with this EnchantmentData */ + public final int enchantmentLevel; + + public EnchantmentData(Enchantment par1Enchantment, int par2) { + super(par1Enchantment.getWeight()); + this.enchantmentobj = par1Enchantment; + this.enchantmentLevel = par2; + } + + public EnchantmentData(int par1, int par2) { + this(Enchantment.enchantmentsList[par1], par2); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EnchantmentDigging.java b/sp-server/src/main/java/net/minecraft/src/EnchantmentDigging.java new file mode 100644 index 0000000..307987b --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EnchantmentDigging.java @@ -0,0 +1,35 @@ +package net.minecraft.src; + +public class EnchantmentDigging extends Enchantment { + protected EnchantmentDigging(int par1, int par2) { + super(par1, par2, EnumEnchantmentType.digger); + this.setName("digging"); + } + + /** + * Returns the minimal value of enchantability needed on the enchantment level + * passed. + */ + public int getMinEnchantability(int par1) { + return 1 + 10 * (par1 - 1); + } + + /** + * Returns the maximum value of enchantability nedded on the enchantment level + * passed. + */ + public int getMaxEnchantability(int par1) { + return super.getMinEnchantability(par1) + 50; + } + + /** + * Returns the maximum level that the enchantment can have. + */ + public int getMaxLevel() { + return 5; + } + + public boolean func_92089_a(ItemStack par1ItemStack) { + return par1ItemStack.getItem().itemID == Item.shears.itemID ? true : super.func_92089_a(par1ItemStack); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EnchantmentDurability.java b/sp-server/src/main/java/net/minecraft/src/EnchantmentDurability.java new file mode 100644 index 0000000..2b6fdc6 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EnchantmentDurability.java @@ -0,0 +1,42 @@ +package net.minecraft.src; + +import java.util.Random; + +public class EnchantmentDurability extends Enchantment { + protected EnchantmentDurability(int par1, int par2) { + super(par1, par2, EnumEnchantmentType.digger); + this.setName("durability"); + } + + /** + * Returns the minimal value of enchantability needed on the enchantment level + * passed. + */ + public int getMinEnchantability(int par1) { + return 5 + (par1 - 1) * 8; + } + + /** + * Returns the maximum value of enchantability nedded on the enchantment level + * passed. + */ + public int getMaxEnchantability(int par1) { + return super.getMinEnchantability(par1) + 50; + } + + /** + * Returns the maximum level that the enchantment can have. + */ + public int getMaxLevel() { + return 3; + } + + public boolean func_92089_a(ItemStack par1ItemStack) { + return par1ItemStack.isItemStackDamageable() ? true : super.func_92089_a(par1ItemStack); + } + + public static boolean func_92097_a(ItemStack par0ItemStack, int par1, Random par2Random) { + return par0ItemStack.getItem() instanceof ItemArmor && par2Random.nextFloat() < 0.6F ? false + : par2Random.nextInt(par1 + 1) > 0; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EnchantmentFireAspect.java b/sp-server/src/main/java/net/minecraft/src/EnchantmentFireAspect.java new file mode 100644 index 0000000..51e4809 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EnchantmentFireAspect.java @@ -0,0 +1,31 @@ +package net.minecraft.src; + +public class EnchantmentFireAspect extends Enchantment { + protected EnchantmentFireAspect(int par1, int par2) { + super(par1, par2, EnumEnchantmentType.weapon); + this.setName("fire"); + } + + /** + * Returns the minimal value of enchantability needed on the enchantment level + * passed. + */ + public int getMinEnchantability(int par1) { + return 10 + 20 * (par1 - 1); + } + + /** + * Returns the maximum value of enchantability nedded on the enchantment level + * passed. + */ + public int getMaxEnchantability(int par1) { + return super.getMinEnchantability(par1) + 50; + } + + /** + * Returns the maximum level that the enchantment can have. + */ + public int getMaxLevel() { + return 2; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EnchantmentHelper.java b/sp-server/src/main/java/net/minecraft/src/EnchantmentHelper.java new file mode 100644 index 0000000..6948ca6 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EnchantmentHelper.java @@ -0,0 +1,422 @@ +package net.minecraft.src; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Random; + +public class EnchantmentHelper { + /** Is the random seed of enchantment effects. */ + private static final Random enchantmentRand = new Random(); + + /** + * Used to calculate the extra armor of enchantments on armors equipped on + * player. + */ + private static final EnchantmentModifierDamage enchantmentModifierDamage = new EnchantmentModifierDamage( + (Empty3) null); + + /** + * Used to calculate the (magic) extra damage done by enchantments on current + * equipped item of player. + */ + private static final EnchantmentModifierLiving enchantmentModifierLiving = new EnchantmentModifierLiving( + (Empty3) null); + + /** + * Returns the level of enchantment on the ItemStack passed. + */ + public static int getEnchantmentLevel(int par0, ItemStack par1ItemStack) { + if (par1ItemStack == null) { + return 0; + } else { + NBTTagList var2 = par1ItemStack.getEnchantmentTagList(); + + if (var2 == null) { + return 0; + } else { + for (int var3 = 0; var3 < var2.tagCount(); ++var3) { + short var4 = ((NBTTagCompound) var2.tagAt(var3)).getShort("id"); + short var5 = ((NBTTagCompound) var2.tagAt(var3)).getShort("lvl"); + + if (var4 == par0) { + return var5; + } + } + + return 0; + } + } + } + + /** + * Return the enchantments for the specified stack. + */ + public static Map getEnchantments(ItemStack par0ItemStack) { + LinkedHashMap var1 = new LinkedHashMap(); + NBTTagList var2 = par0ItemStack.itemID == Item.enchantedBook.itemID + ? Item.enchantedBook.func_92110_g(par0ItemStack) + : par0ItemStack.getEnchantmentTagList(); + + if (var2 != null) { + for (int var3 = 0; var3 < var2.tagCount(); ++var3) { + short var4 = ((NBTTagCompound) var2.tagAt(var3)).getShort("id"); + short var5 = ((NBTTagCompound) var2.tagAt(var3)).getShort("lvl"); + var1.put(Integer.valueOf(var4), Integer.valueOf(var5)); + } + } + + return var1; + } + + /** + * Set the enchantments for the specified stack. + */ + public static void setEnchantments(Map par0Map, ItemStack par1ItemStack) { + NBTTagList var2 = new NBTTagList(); + Iterator var3 = par0Map.keySet().iterator(); + + while (var3.hasNext()) { + int var4 = ((Integer) var3.next()).intValue(); + NBTTagCompound var5 = new NBTTagCompound(); + var5.setShort("id", (short) var4); + var5.setShort("lvl", (short) ((Integer) par0Map.get(Integer.valueOf(var4))).intValue()); + var2.appendTag(var5); + + if (par1ItemStack.itemID == Item.enchantedBook.itemID) { + Item.enchantedBook.func_92115_a(par1ItemStack, + new EnchantmentData(var4, ((Integer) par0Map.get(Integer.valueOf(var4))).intValue())); + } + } + + if (var2.tagCount() > 0) { + if (par1ItemStack.itemID != Item.enchantedBook.itemID) { + par1ItemStack.setTagInfo("ench", var2); + } + } else if (par1ItemStack.hasTagCompound()) { + par1ItemStack.getTagCompound().removeTag("ench"); + } + } + + /** + * Returns the biggest level of the enchantment on the array of ItemStack + * passed. + */ + public static int getMaxEnchantmentLevel(int par0, ItemStack[] par1ArrayOfItemStack) { + if (par1ArrayOfItemStack == null) { + return 0; + } else { + int var2 = 0; + ItemStack[] var3 = par1ArrayOfItemStack; + int var4 = par1ArrayOfItemStack.length; + + for (int var5 = 0; var5 < var4; ++var5) { + ItemStack var6 = var3[var5]; + int var7 = getEnchantmentLevel(par0, var6); + + if (var7 > var2) { + var2 = var7; + } + } + + return var2; + } + } + + /** + * Executes the enchantment modifier on the ItemStack passed. + */ + private static void applyEnchantmentModifier(IEnchantmentModifier par0IEnchantmentModifier, + ItemStack par1ItemStack) { + if (par1ItemStack != null) { + NBTTagList var2 = par1ItemStack.getEnchantmentTagList(); + + if (var2 != null) { + for (int var3 = 0; var3 < var2.tagCount(); ++var3) { + short var4 = ((NBTTagCompound) var2.tagAt(var3)).getShort("id"); + short var5 = ((NBTTagCompound) var2.tagAt(var3)).getShort("lvl"); + + if (Enchantment.enchantmentsList[var4] != null) { + par0IEnchantmentModifier.calculateModifier(Enchantment.enchantmentsList[var4], var5); + } + } + } + } + } + + /** + * Executes the enchantment modifier on the array of ItemStack passed. + */ + private static void applyEnchantmentModifierArray(IEnchantmentModifier par0IEnchantmentModifier, + ItemStack[] par1ArrayOfItemStack) { + ItemStack[] var2 = par1ArrayOfItemStack; + int var3 = par1ArrayOfItemStack.length; + + for (int var4 = 0; var4 < var3; ++var4) { + ItemStack var5 = var2[var4]; + applyEnchantmentModifier(par0IEnchantmentModifier, var5); + } + } + + /** + * Returns the modifier of protection enchantments on armors equipped on player. + */ + public static int getEnchantmentModifierDamage(ItemStack[] par0ArrayOfItemStack, DamageSource par1DamageSource) { + enchantmentModifierDamage.damageModifier = 0; + enchantmentModifierDamage.source = par1DamageSource; + applyEnchantmentModifierArray(enchantmentModifierDamage, par0ArrayOfItemStack); + + if (enchantmentModifierDamage.damageModifier > 25) { + enchantmentModifierDamage.damageModifier = 25; + } + + return (enchantmentModifierDamage.damageModifier + 1 >> 1) + + enchantmentRand.nextInt((enchantmentModifierDamage.damageModifier >> 1) + 1); + } + + /** + * Return the (magic) extra damage of the enchantments on player equipped item. + */ + public static int getEnchantmentModifierLiving(EntityLiving par0EntityLiving, EntityLiving par1EntityLiving) { + enchantmentModifierLiving.livingModifier = 0; + enchantmentModifierLiving.entityLiving = par1EntityLiving; + applyEnchantmentModifier(enchantmentModifierLiving, par0EntityLiving.getHeldItem()); + return enchantmentModifierLiving.livingModifier > 0 + ? 1 + enchantmentRand.nextInt(enchantmentModifierLiving.livingModifier) + : 0; + } + + /** + * Returns the knockback value of enchantments on equipped player item. + */ + public static int getKnockbackModifier(EntityLiving par0EntityLiving, EntityLiving par1EntityLiving) { + return getEnchantmentLevel(Enchantment.knockback.effectId, par0EntityLiving.getHeldItem()); + } + + public static int getFireAspectModifier(EntityLiving par0EntityLiving) { + return getEnchantmentLevel(Enchantment.fireAspect.effectId, par0EntityLiving.getHeldItem()); + } + + /** + * Returns the 'Water Breathing' modifier of enchantments on player equipped + * armors. + */ + public static int getRespiration(EntityLiving par0EntityLiving) { + return getMaxEnchantmentLevel(Enchantment.respiration.effectId, par0EntityLiving.getInventory()); + } + + /** + * Return the extra efficiency of tools based on enchantments on equipped player + * item. + */ + public static int getEfficiencyModifier(EntityLiving par0EntityLiving) { + return getEnchantmentLevel(Enchantment.efficiency.effectId, par0EntityLiving.getHeldItem()); + } + + /** + * Returns the silk touch status of enchantments on current equipped item of + * player. + */ + public static boolean getSilkTouchModifier(EntityLiving par0EntityLiving) { + return getEnchantmentLevel(Enchantment.silkTouch.effectId, par0EntityLiving.getHeldItem()) > 0; + } + + /** + * Returns the fortune enchantment modifier of the current equipped item of + * player. + */ + public static int getFortuneModifier(EntityLiving par0EntityLiving) { + return getEnchantmentLevel(Enchantment.fortune.effectId, par0EntityLiving.getHeldItem()); + } + + /** + * Returns the looting enchantment modifier of the current equipped item of + * player. + */ + public static int getLootingModifier(EntityLiving par0EntityLiving) { + return getEnchantmentLevel(Enchantment.looting.effectId, par0EntityLiving.getHeldItem()); + } + + /** + * Returns the aqua affinity status of enchantments on current equipped item of + * player. + */ + public static boolean getAquaAffinityModifier(EntityLiving par0EntityLiving) { + return getMaxEnchantmentLevel(Enchantment.aquaAffinity.effectId, par0EntityLiving.getInventory()) > 0; + } + + public static int func_92098_i(EntityLiving par0EntityLiving) { + return getMaxEnchantmentLevel(Enchantment.thorns.effectId, par0EntityLiving.getInventory()); + } + + public static ItemStack func_92099_a(Enchantment par0Enchantment, EntityLiving par1EntityLiving) { + ItemStack[] var2 = par1EntityLiving.getInventory(); + int var3 = var2.length; + + for (int var4 = 0; var4 < var3; ++var4) { + ItemStack var5 = var2[var4]; + + if (var5 != null && getEnchantmentLevel(par0Enchantment.effectId, var5) > 0) { + return var5; + } + } + + return null; + } + + /** + * Returns the enchantability of itemstack, it's uses a singular formula for + * each index (2nd parameter: 0, 1 and 2), cutting to the max enchantability + * power of the table (3rd parameter) + */ + public static int calcItemStackEnchantability(Random par0Random, int par1, int par2, ItemStack par3ItemStack) { + Item var4 = par3ItemStack.getItem(); + int var5 = var4.getItemEnchantability(); + + if (var5 <= 0) { + return 0; + } else { + if (par2 > 15) { + par2 = 15; + } + + int var6 = par0Random.nextInt(8) + 1 + (par2 >> 1) + par0Random.nextInt(par2 + 1); + return par1 == 0 ? Math.max(var6 / 3, 1) : (par1 == 1 ? var6 * 2 / 3 + 1 : Math.max(var6, par2 * 2)); + } + } + + /** + * Adds a random enchantment to the specified item. Args: random, itemStack, + * enchantabilityLevel + */ + public static ItemStack addRandomEnchantment(Random par0Random, ItemStack par1ItemStack, int par2) { + List var3 = buildEnchantmentList(par0Random, par1ItemStack, par2); + boolean var4 = par1ItemStack.itemID == Item.book.itemID; + + if (var4) { + par1ItemStack.itemID = Item.enchantedBook.itemID; + } + + if (var3 != null) { + Iterator var5 = var3.iterator(); + + while (var5.hasNext()) { + EnchantmentData var6 = (EnchantmentData) var5.next(); + + if (var4) { + Item.enchantedBook.func_92115_a(par1ItemStack, var6); + } else { + par1ItemStack.addEnchantment(var6.enchantmentobj, var6.enchantmentLevel); + } + } + } + + return par1ItemStack; + } + + /** + * Create a list of random EnchantmentData (enchantments) that can be added + * together to the ItemStack, the 3rd parameter is the total enchantability + * level. + */ + public static List buildEnchantmentList(Random par0Random, ItemStack par1ItemStack, int par2) { + Item var3 = par1ItemStack.getItem(); + int var4 = var3.getItemEnchantability(); + + if (var4 <= 0) { + return null; + } else { + var4 /= 2; + var4 = 1 + par0Random.nextInt((var4 >> 1) + 1) + par0Random.nextInt((var4 >> 1) + 1); + int var5 = var4 + par2; + float var6 = (par0Random.nextFloat() + par0Random.nextFloat() - 1.0F) * 0.15F; + int var7 = (int) ((float) var5 * (1.0F + var6) + 0.5F); + + if (var7 < 1) { + var7 = 1; + } + + ArrayList var8 = null; + Map var9 = mapEnchantmentData(var7, par1ItemStack); + + if (var9 != null && !var9.isEmpty()) { + EnchantmentData var10 = (EnchantmentData) WeightedRandom.getRandomItem(par0Random, var9.values()); + + if (var10 != null) { + var8 = new ArrayList(); + var8.add(var10); + + for (int var11 = var7; par0Random.nextInt(50) <= var11; var11 >>= 1) { + Iterator var12 = var9.keySet().iterator(); + + while (var12.hasNext()) { + Integer var13 = (Integer) var12.next(); + boolean var14 = true; + Iterator var15 = var8.iterator(); + + while (true) { + if (var15.hasNext()) { + EnchantmentData var16 = (EnchantmentData) var15.next(); + + if (var16.enchantmentobj + .canApplyTogether(Enchantment.enchantmentsList[var13.intValue()])) { + continue; + } + + var14 = false; + } + + if (!var14) { + var12.remove(); + } + + break; + } + } + + if (!var9.isEmpty()) { + EnchantmentData var17 = (EnchantmentData) WeightedRandom.getRandomItem(par0Random, + var9.values()); + var8.add(var17); + } + } + } + } + + return var8; + } + } + + /** + * Creates a 'Map' of EnchantmentData (enchantments) possible to add on the + * ItemStack and the enchantability level passed. + */ + public static Map mapEnchantmentData(int par0, ItemStack par1ItemStack) { + Item var2 = par1ItemStack.getItem(); + HashMap var3 = null; + boolean var4 = par1ItemStack.itemID == Item.book.itemID; + Enchantment[] var5 = Enchantment.enchantmentsList; + int var6 = var5.length; + + for (int var7 = 0; var7 < var6; ++var7) { + Enchantment var8 = var5[var7]; + + if (var8 != null && (var8.type.canEnchantItem(var2) || var4)) { + for (int var9 = var8.getMinLevel(); var9 <= var8.getMaxLevel(); ++var9) { + if (par0 >= var8.getMinEnchantability(var9) && par0 <= var8.getMaxEnchantability(var9)) { + if (var3 == null) { + var3 = new HashMap(); + } + + var3.put(Integer.valueOf(var8.effectId), new EnchantmentData(var8, var9)); + } + } + } + } + + return var3; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EnchantmentKnockback.java b/sp-server/src/main/java/net/minecraft/src/EnchantmentKnockback.java new file mode 100644 index 0000000..2e3bfb2 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EnchantmentKnockback.java @@ -0,0 +1,31 @@ +package net.minecraft.src; + +public class EnchantmentKnockback extends Enchantment { + protected EnchantmentKnockback(int par1, int par2) { + super(par1, par2, EnumEnchantmentType.weapon); + this.setName("knockback"); + } + + /** + * Returns the minimal value of enchantability needed on the enchantment level + * passed. + */ + public int getMinEnchantability(int par1) { + return 5 + 20 * (par1 - 1); + } + + /** + * Returns the maximum value of enchantability nedded on the enchantment level + * passed. + */ + public int getMaxEnchantability(int par1) { + return super.getMinEnchantability(par1) + 50; + } + + /** + * Returns the maximum level that the enchantment can have. + */ + public int getMaxLevel() { + return 2; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EnchantmentLootBonus.java b/sp-server/src/main/java/net/minecraft/src/EnchantmentLootBonus.java new file mode 100644 index 0000000..f91e1da --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EnchantmentLootBonus.java @@ -0,0 +1,43 @@ +package net.minecraft.src; + +public class EnchantmentLootBonus extends Enchantment { + protected EnchantmentLootBonus(int par1, int par2, EnumEnchantmentType par3EnumEnchantmentType) { + super(par1, par2, par3EnumEnchantmentType); + this.setName("lootBonus"); + + if (par3EnumEnchantmentType == EnumEnchantmentType.digger) { + this.setName("lootBonusDigger"); + } + } + + /** + * Returns the minimal value of enchantability needed on the enchantment level + * passed. + */ + public int getMinEnchantability(int par1) { + return 15 + (par1 - 1) * 9; + } + + /** + * Returns the maximum value of enchantability nedded on the enchantment level + * passed. + */ + public int getMaxEnchantability(int par1) { + return super.getMinEnchantability(par1) + 50; + } + + /** + * Returns the maximum level that the enchantment can have. + */ + public int getMaxLevel() { + return 3; + } + + /** + * Determines if the enchantment passed can be applyied together with this + * enchantment. + */ + public boolean canApplyTogether(Enchantment par1Enchantment) { + return super.canApplyTogether(par1Enchantment) && par1Enchantment.effectId != silkTouch.effectId; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EnchantmentModifierDamage.java b/sp-server/src/main/java/net/minecraft/src/EnchantmentModifierDamage.java new file mode 100644 index 0000000..7be4638 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EnchantmentModifierDamage.java @@ -0,0 +1,30 @@ +package net.minecraft.src; + +final class EnchantmentModifierDamage implements IEnchantmentModifier { + /** + * Used to calculate the damage modifier (extra armor) on enchantments that the + * player have on equipped armors. + */ + public int damageModifier; + + /** + * Used as parameter to calculate the damage modifier (extra armor) on + * enchantments that the player have on equipped armors. + */ + public DamageSource source; + + private EnchantmentModifierDamage() { + } + + /** + * Generic method use to calculate modifiers of offensive or defensive + * enchantment values. + */ + public void calculateModifier(Enchantment par1Enchantment, int par2) { + this.damageModifier += par1Enchantment.calcModifierDamage(par2, this.source); + } + + EnchantmentModifierDamage(Empty3 par1Empty3) { + this(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EnchantmentModifierLiving.java b/sp-server/src/main/java/net/minecraft/src/EnchantmentModifierLiving.java new file mode 100644 index 0000000..883a005 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EnchantmentModifierLiving.java @@ -0,0 +1,25 @@ +package net.minecraft.src; + +final class EnchantmentModifierLiving implements IEnchantmentModifier { + /** + * Used to calculate the (magic) extra damage based on enchantments of current + * equipped player item. + */ + public int livingModifier; + public EntityLiving entityLiving; + + private EnchantmentModifierLiving() { + } + + /** + * Generic method use to calculate modifiers of offensive or defensive + * enchantment values. + */ + public void calculateModifier(Enchantment par1Enchantment, int par2) { + this.livingModifier += par1Enchantment.calcModifierLiving(par2, this.entityLiving); + } + + EnchantmentModifierLiving(Empty3 par1Empty3) { + this(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EnchantmentOxygen.java b/sp-server/src/main/java/net/minecraft/src/EnchantmentOxygen.java new file mode 100644 index 0000000..4c0f1bb --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EnchantmentOxygen.java @@ -0,0 +1,31 @@ +package net.minecraft.src; + +public class EnchantmentOxygen extends Enchantment { + public EnchantmentOxygen(int par1, int par2) { + super(par1, par2, EnumEnchantmentType.armor_head); + this.setName("oxygen"); + } + + /** + * Returns the minimal value of enchantability needed on the enchantment level + * passed. + */ + public int getMinEnchantability(int par1) { + return 10 * par1; + } + + /** + * Returns the maximum value of enchantability nedded on the enchantment level + * passed. + */ + public int getMaxEnchantability(int par1) { + return this.getMinEnchantability(par1) + 30; + } + + /** + * Returns the maximum level that the enchantment can have. + */ + public int getMaxLevel() { + return 3; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EnchantmentProtection.java b/sp-server/src/main/java/net/minecraft/src/EnchantmentProtection.java new file mode 100644 index 0000000..99ceb5e --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EnchantmentProtection.java @@ -0,0 +1,126 @@ +package net.minecraft.src; + +public class EnchantmentProtection extends Enchantment { + /** Holds the name to be translated of each protection type. */ + private static final String[] protectionName = new String[] { "all", "fire", "fall", "explosion", "projectile" }; + + /** + * Holds the base factor of enchantability needed to be able to use the enchant. + */ + private static final int[] baseEnchantability = new int[] { 1, 10, 5, 5, 3 }; + + /** + * Holds how much each level increased the enchantability factor to be able to + * use this enchant. + */ + private static final int[] levelEnchantability = new int[] { 11, 8, 6, 8, 6 }; + + /** + * Used on the formula of base enchantability, this is the 'window' factor of + * values to be able to use thing enchant. + */ + private static final int[] thresholdEnchantability = new int[] { 20, 12, 10, 12, 15 }; + + /** + * Defines the type of protection of the enchantment, 0 = all, 1 = fire, 2 = + * fall (feather fall), 3 = explosion and 4 = projectile. + */ + public final int protectionType; + + public EnchantmentProtection(int par1, int par2, int par3) { + super(par1, par2, EnumEnchantmentType.armor); + this.protectionType = par3; + + if (par3 == 2) { + this.type = EnumEnchantmentType.armor_feet; + } + } + + /** + * Returns the minimal value of enchantability needed on the enchantment level + * passed. + */ + public int getMinEnchantability(int par1) { + return baseEnchantability[this.protectionType] + (par1 - 1) * levelEnchantability[this.protectionType]; + } + + /** + * Returns the maximum value of enchantability nedded on the enchantment level + * passed. + */ + public int getMaxEnchantability(int par1) { + return this.getMinEnchantability(par1) + thresholdEnchantability[this.protectionType]; + } + + /** + * Returns the maximum level that the enchantment can have. + */ + public int getMaxLevel() { + return 4; + } + + /** + * Calculates de damage protection of the enchantment based on level and damage + * source passed. + */ + public int calcModifierDamage(int par1, DamageSource par2DamageSource) { + if (par2DamageSource.canHarmInCreative()) { + return 0; + } else { + float var3 = (float) (6 + par1 * par1) / 3.0F; + return this.protectionType == 0 ? MathHelper.floor_float(var3 * 0.75F) + : (this.protectionType == 1 && par2DamageSource.isFireDamage() + ? MathHelper.floor_float(var3 * 1.25F) + : (this.protectionType == 2 && par2DamageSource == DamageSource.fall + ? MathHelper.floor_float(var3 * 2.5F) + : (this.protectionType == 3 && par2DamageSource.isExplosion() + ? MathHelper.floor_float(var3 * 1.5F) + : (this.protectionType == 4 && par2DamageSource.isProjectile() + ? MathHelper.floor_float(var3 * 1.5F) + : 0)))); + } + } + + /** + * Return the name of key in translation table of this enchantment. + */ + public String getName() { + return "enchantment.protect." + protectionName[this.protectionType]; + } + + /** + * Determines if the enchantment passed can be applyied together with this + * enchantment. + */ + public boolean canApplyTogether(Enchantment par1Enchantment) { + if (par1Enchantment instanceof EnchantmentProtection) { + EnchantmentProtection var2 = (EnchantmentProtection) par1Enchantment; + return var2.protectionType == this.protectionType ? false + : this.protectionType == 2 || var2.protectionType == 2; + } else { + return super.canApplyTogether(par1Enchantment); + } + } + + public static int func_92093_a(Entity par0Entity, int par1) { + int var2 = EnchantmentHelper.getMaxEnchantmentLevel(Enchantment.fireProtection.effectId, + par0Entity.getInventory()); + + if (var2 > 0) { + par1 -= MathHelper.floor_float((float) par1 * (float) var2 * 0.15F); + } + + return par1; + } + + public static double func_92092_a(Entity par0Entity, double par1) { + int var3 = EnchantmentHelper.getMaxEnchantmentLevel(Enchantment.blastProtection.effectId, + par0Entity.getInventory()); + + if (var3 > 0) { + par1 -= (double) MathHelper.floor_double(par1 * (double) ((float) var3 * 0.15F)); + } + + return par1; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EnchantmentThorns.java b/sp-server/src/main/java/net/minecraft/src/EnchantmentThorns.java new file mode 100644 index 0000000..fc9a8e3 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EnchantmentThorns.java @@ -0,0 +1,62 @@ +package net.minecraft.src; + +import java.util.Random; + +public class EnchantmentThorns extends Enchantment { + public EnchantmentThorns(int par1, int par2) { + super(par1, par2, EnumEnchantmentType.armor_torso); + this.setName("thorns"); + } + + /** + * Returns the minimal value of enchantability needed on the enchantment level + * passed. + */ + public int getMinEnchantability(int par1) { + return 10 + 20 * (par1 - 1); + } + + /** + * Returns the maximum value of enchantability nedded on the enchantment level + * passed. + */ + public int getMaxEnchantability(int par1) { + return super.getMinEnchantability(par1) + 50; + } + + /** + * Returns the maximum level that the enchantment can have. + */ + public int getMaxLevel() { + return 3; + } + + public boolean func_92089_a(ItemStack par1ItemStack) { + return par1ItemStack.getItem() instanceof ItemArmor ? true : super.func_92089_a(par1ItemStack); + } + + public static boolean func_92094_a(int par0, Random par1Random) { + return par0 <= 0 ? false : par1Random.nextFloat() < 0.15F * (float) par0; + } + + public static int func_92095_b(int par0, Random par1Random) { + return par0 > 10 ? par0 - 10 : 1 + par1Random.nextInt(4); + } + + public static void func_92096_a(Entity par0Entity, EntityLiving par1EntityLiving, Random par2Random) { + int var3 = EnchantmentHelper.func_92098_i(par1EntityLiving); + ItemStack var4 = EnchantmentHelper.func_92099_a(Enchantment.thorns, par1EntityLiving); + + if (func_92094_a(var3, par2Random)) { + par0Entity.attackEntityFrom(DamageSource.causeThornsDamage(par1EntityLiving), + func_92095_b(var3, par2Random)); + par0Entity.playSound("damage.thorns", 0.5F, 1.0F); + + if (var4 != null) { + var4.damageItem(3, par1EntityLiving); + } + } else if (var4 != null) { + var4.damageItem(1, par1EntityLiving); + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EnchantmentUntouching.java b/sp-server/src/main/java/net/minecraft/src/EnchantmentUntouching.java new file mode 100644 index 0000000..bd53660 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EnchantmentUntouching.java @@ -0,0 +1,43 @@ +package net.minecraft.src; + +public class EnchantmentUntouching extends Enchantment { + protected EnchantmentUntouching(int par1, int par2) { + super(par1, par2, EnumEnchantmentType.digger); + this.setName("untouching"); + } + + /** + * Returns the minimal value of enchantability needed on the enchantment level + * passed. + */ + public int getMinEnchantability(int par1) { + return 15; + } + + /** + * Returns the maximum value of enchantability nedded on the enchantment level + * passed. + */ + public int getMaxEnchantability(int par1) { + return super.getMinEnchantability(par1) + 50; + } + + /** + * Returns the maximum level that the enchantment can have. + */ + public int getMaxLevel() { + return 1; + } + + /** + * Determines if the enchantment passed can be applyied together with this + * enchantment. + */ + public boolean canApplyTogether(Enchantment par1Enchantment) { + return super.canApplyTogether(par1Enchantment) && par1Enchantment.effectId != fortune.effectId; + } + + public boolean func_92089_a(ItemStack par1ItemStack) { + return par1ItemStack.getItem().itemID == Item.shears.itemID ? true : super.func_92089_a(par1ItemStack); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EnchantmentWaterWorker.java b/sp-server/src/main/java/net/minecraft/src/EnchantmentWaterWorker.java new file mode 100644 index 0000000..2b03536 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EnchantmentWaterWorker.java @@ -0,0 +1,31 @@ +package net.minecraft.src; + +public class EnchantmentWaterWorker extends Enchantment { + public EnchantmentWaterWorker(int par1, int par2) { + super(par1, par2, EnumEnchantmentType.armor_head); + this.setName("waterWorker"); + } + + /** + * Returns the minimal value of enchantability needed on the enchantment level + * passed. + */ + public int getMinEnchantability(int par1) { + return 1; + } + + /** + * Returns the maximum value of enchantability nedded on the enchantment level + * passed. + */ + public int getMaxEnchantability(int par1) { + return this.getMinEnchantability(par1) + 40; + } + + /** + * Returns the maximum level that the enchantment can have. + */ + public int getMaxLevel() { + return 1; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/Entity.java b/sp-server/src/main/java/net/minecraft/src/Entity.java new file mode 100644 index 0000000..0e81db1 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/Entity.java @@ -0,0 +1,1988 @@ +package net.minecraft.src; + +import java.util.List; +import java.util.Random; +import java.util.UUID; +import net.minecraft.server.MinecraftServer; + +public abstract class Entity { + private static int nextEntityID = 0; + public int entityId; + public double renderDistanceWeight; + + /** + * Blocks entities from spawning when they do their AABB check to make sure the + * spot is clear of entities that can prevent spawning. + */ + public boolean preventEntitySpawning; + + /** The entity that is riding this entity */ + public Entity riddenByEntity; + + /** The entity we are currently riding */ + public Entity ridingEntity; + public boolean field_98038_p; + + /** Reference to the World object. */ + public World worldObj; + public double prevPosX; + public double prevPosY; + public double prevPosZ; + + /** Entity position X */ + public double posX; + + /** Entity position Y */ + public double posY; + + /** Entity position Z */ + public double posZ; + + /** Entity motion X */ + public double motionX; + + /** Entity motion Y */ + public double motionY; + + /** Entity motion Z */ + public double motionZ; + + /** Entity rotation Yaw */ + public float rotationYaw; + + /** Entity rotation Pitch */ + public float rotationPitch; + public float prevRotationYaw; + public float prevRotationPitch; + + /** Axis aligned bounding box. */ + public final AxisAlignedBB boundingBox; + public boolean onGround; + + /** + * True if after a move this entity has collided with something on X- or Z-axis + */ + public boolean isCollidedHorizontally; + + /** + * True if after a move this entity has collided with something on Y-axis + */ + public boolean isCollidedVertically; + + /** + * True if after a move this entity has collided with something either + * vertically or horizontally + */ + public boolean isCollided; + public boolean velocityChanged; + protected boolean isInWeb; + public boolean field_70135_K; + + /** + * gets set by setEntityDead, so this must be the flag whether an Entity is dead + * (inactive may be better term) + */ + public boolean isDead; + public float yOffset; + + /** How wide this entity is considered to be */ + public float width; + + /** How high this entity is considered to be */ + public float height; + + /** The previous ticks distance walked multiplied by 0.6 */ + public float prevDistanceWalkedModified; + + /** The distance walked multiplied by 0.6 */ + public float distanceWalkedModified; + public float distanceWalkedOnStepModified; + public float fallDistance; + + /** + * The distance that has to be exceeded in order to triger a new step sound and + * an onEntityWalking event on a block + */ + private int nextStepDistance; + + /** + * The entity's X coordinate at the previous tick, used to calculate position + * during rendering routines + */ + public double lastTickPosX; + + /** + * The entity's Y coordinate at the previous tick, used to calculate position + * during rendering routines + */ + public double lastTickPosY; + + /** + * The entity's Z coordinate at the previous tick, used to calculate position + * during rendering routines + */ + public double lastTickPosZ; + public float ySize; + + /** + * How high this entity can step up when running into a block to try to get over + * it (currently make note the entity will always step up this amount and not + * just the amount needed) + */ + public float stepHeight; + + /** + * Whether this entity won't clip with collision or not (make note it won't + * disable gravity) + */ + public boolean noClip; + + /** + * Reduces the velocity applied by entity collisions by the specified percent. + */ + public float entityCollisionReduction; + protected Random rand; + + /** How many ticks has this entity had ran since being alive */ + public int ticksExisted; + + /** + * The amount of ticks you have to stand inside of fire before be set on fire + */ + public int fireResistance; + private int fire; + + /** + * Whether this entity is currently inside of water (if it handles water + * movement that is) + */ + protected boolean inWater; + + /** + * Remaining time an entity will be "immune" to further damage after being hurt. + */ + public int hurtResistantTime; + private boolean firstUpdate; + protected boolean isImmuneToFire; + protected DataWatcher dataWatcher; + private double entityRiderPitchDelta; + private double entityRiderYawDelta; + + /** Has this entity been added to the chunk its within */ + public boolean addedToChunk; + public int chunkCoordX; + public int chunkCoordY; + public int chunkCoordZ; + + /** + * Render entity even if it is outside the camera frustum. Only true in + * EntityFish for now. Used in RenderGlobal: render if ignoreFrustumCheck or in + * frustum. + */ + public boolean ignoreFrustumCheck; + public boolean isAirBorne; + public int timeUntilPortal; + + /** Whether the entity is inside a Portal */ + protected boolean inPortal; + protected int timeInPortal; + + /** Which dimension the player is in (-1 = the Nether, 0 = normal world) */ + public int dimension; + protected int teleportDirection; + private boolean invulnerable; + private UUID entityUniqueID; + public EnumEntitySize myEntitySize; + + public Entity(World par1World) { + this.entityId = nextEntityID++; + this.renderDistanceWeight = 1.0D; + this.preventEntitySpawning = false; + this.boundingBox = AxisAlignedBB.getBoundingBox(0.0D, 0.0D, 0.0D, 0.0D, 0.0D, 0.0D); + this.onGround = false; + this.isCollided = false; + this.velocityChanged = false; + this.field_70135_K = true; + this.isDead = false; + this.yOffset = 0.0F; + this.width = 0.6F; + this.height = 1.8F; + this.prevDistanceWalkedModified = 0.0F; + this.distanceWalkedModified = 0.0F; + this.distanceWalkedOnStepModified = 0.0F; + this.fallDistance = 0.0F; + this.nextStepDistance = 1; + this.ySize = 0.0F; + this.stepHeight = 0.0F; + this.noClip = false; + this.entityCollisionReduction = 0.0F; + this.rand = new Random(); + this.ticksExisted = 0; + this.fireResistance = 1; + this.fire = 0; + this.inWater = false; + this.hurtResistantTime = 0; + this.firstUpdate = true; + this.isImmuneToFire = false; + this.dataWatcher = new DataWatcher(); + this.addedToChunk = false; + this.teleportDirection = 0; + this.invulnerable = false; + this.entityUniqueID = UUID.randomUUID(); + this.myEntitySize = EnumEntitySize.SIZE_2; + this.worldObj = par1World; + this.setPosition(0.0D, 0.0D, 0.0D); + + if (par1World != null) { + this.dimension = par1World.provider.dimensionId; + } + + this.dataWatcher.addObject(0, Byte.valueOf((byte) 0)); + this.dataWatcher.addObject(1, Short.valueOf((short) 300)); + this.entityInit(); + } + + protected abstract void entityInit(); + + public DataWatcher getDataWatcher() { + return this.dataWatcher; + } + + public boolean equals(Object par1Obj) { + return par1Obj instanceof Entity ? ((Entity) par1Obj).entityId == this.entityId : false; + } + + public int hashCode() { + return this.entityId; + } + + /** + * Will get destroyed next tick. + */ + public void setDead() { + this.isDead = true; + } + + /** + * Sets the width and height of the entity. Args: width, height + */ + protected void setSize(float par1, float par2) { + if (par1 != this.width || par2 != this.height) { + this.width = par1; + this.height = par2; + this.boundingBox.maxX = this.boundingBox.minX + (double) this.width; + this.boundingBox.maxZ = this.boundingBox.minZ + (double) this.width; + this.boundingBox.maxY = this.boundingBox.minY + (double) this.height; + } + + float var3 = par1 % 2.0F; + + if ((double) var3 < 0.375D) { + this.myEntitySize = EnumEntitySize.SIZE_1; + } else if ((double) var3 < 0.75D) { + this.myEntitySize = EnumEntitySize.SIZE_2; + } else if ((double) var3 < 1.0D) { + this.myEntitySize = EnumEntitySize.SIZE_3; + } else if ((double) var3 < 1.375D) { + this.myEntitySize = EnumEntitySize.SIZE_4; + } else if ((double) var3 < 1.75D) { + this.myEntitySize = EnumEntitySize.SIZE_5; + } else { + this.myEntitySize = EnumEntitySize.SIZE_6; + } + } + + /** + * Sets the rotation of the entity. Args: yaw, pitch (both in degrees) + */ + protected void setRotation(float par1, float par2) { + this.rotationYaw = par1 % 360.0F; + this.rotationPitch = par2 % 360.0F; + } + + /** + * Sets the x,y,z of the entity from the given parameters. Also seems to set up + * a bounding box. + */ + public void setPosition(double par1, double par3, double par5) { + this.posX = par1; + this.posY = par3; + this.posZ = par5; + float var7 = this.width / 2.0F; + float var8 = this.height; + this.boundingBox.setBounds(par1 - (double) var7, par3 - (double) this.yOffset + (double) this.ySize, + par5 - (double) var7, par1 + (double) var7, + par3 - (double) this.yOffset + (double) this.ySize + (double) var8, par5 + (double) var7); + } + + /** + * Called to update the entity's position/logic. + */ + public void onUpdate() { + this.onEntityUpdate(); + } + + /** + * Gets called every tick from main Entity class + */ + public void onEntityUpdate() { + this.worldObj.theProfiler.startSection("entityBaseTick"); + + if (this.ridingEntity != null && this.ridingEntity.isDead) { + this.ridingEntity = null; + } + + this.prevDistanceWalkedModified = this.distanceWalkedModified; + this.prevPosX = this.posX; + this.prevPosY = this.posY; + this.prevPosZ = this.posZ; + this.prevRotationPitch = this.rotationPitch; + this.prevRotationYaw = this.rotationYaw; + int var2; + + if (!this.worldObj.isRemote && this.worldObj instanceof WorldServer) { + this.worldObj.theProfiler.startSection("portal"); + MinecraftServer var1 = ((WorldServer) this.worldObj).getMinecraftServer(); + var2 = this.getMaxInPortalTime(); + + if (this.inPortal) { + if (var1.getAllowNether()) { + if (this.ridingEntity == null && this.timeInPortal++ >= var2) { + this.timeInPortal = var2; + this.timeUntilPortal = this.getPortalCooldown(); + byte var3; + + if (this.worldObj.provider.dimensionId == -1) { + var3 = 0; + } else { + var3 = -1; + } + + this.travelToTheEnd(var3); + } + + this.inPortal = false; + } + } else { + if (this.timeInPortal > 0) { + this.timeInPortal -= 4; + } + + if (this.timeInPortal < 0) { + this.timeInPortal = 0; + } + } + + if (this.timeUntilPortal > 0) { + --this.timeUntilPortal; + } + + this.worldObj.theProfiler.endSection(); + } + + if (this.isSprinting() && !this.isInWater()) { + int var5 = MathHelper.floor_double(this.posX); + var2 = MathHelper.floor_double(this.posY - 0.20000000298023224D - (double) this.yOffset); + int var6 = MathHelper.floor_double(this.posZ); + int var4 = this.worldObj.getBlockId(var5, var2, var6); + + if (var4 > 0) { + this.worldObj.spawnParticle( + "tilecrack_" + var4 + "_" + this.worldObj.getBlockMetadata(var5, var2, var6), + this.posX + ((double) this.rand.nextFloat() - 0.5D) * (double) this.width, + this.boundingBox.minY + 0.1D, + this.posZ + ((double) this.rand.nextFloat() - 0.5D) * (double) this.width, -this.motionX * 4.0D, + 1.5D, -this.motionZ * 4.0D); + } + } + + this.handleWaterMovement(); + + if (this.worldObj.isRemote) { + this.fire = 0; + } else if (this.fire > 0) { + if (this.isImmuneToFire) { + this.fire -= 4; + + if (this.fire < 0) { + this.fire = 0; + } + } else { + if (this.fire % 20 == 0) { + this.attackEntityFrom(DamageSource.onFire, 1); + } + + --this.fire; + } + } + + if (this.handleLavaMovement()) { + this.setOnFireFromLava(); + this.fallDistance *= 0.5F; + } + + if (this.posY < -64.0D) { + this.kill(); + } + + if (!this.worldObj.isRemote) { + this.setFlag(0, this.fire > 0); + this.setFlag(2, this.ridingEntity != null); + } + + this.firstUpdate = false; + this.worldObj.theProfiler.endSection(); + } + + /** + * Return the amount of time this entity should stay in a portal before being + * transported. + */ + public int getMaxInPortalTime() { + return 0; + } + + /** + * Called whenever the entity is walking inside of lava. + */ + protected void setOnFireFromLava() { + if (!this.isImmuneToFire) { + this.attackEntityFrom(DamageSource.lava, 4); + this.setFire(15); + } + } + + /** + * Sets entity to burn for x amount of seconds, cannot lower amount of existing + * fire. + */ + public void setFire(int par1) { + int var2 = par1 * 20; + var2 = EnchantmentProtection.func_92093_a(this, var2); + + if (this.fire < var2) { + this.fire = var2; + } + } + + /** + * Removes fire from entity. + */ + public void extinguish() { + this.fire = 0; + } + + /** + * sets the dead flag. Used when you fall off the bottom of the world. + */ + protected void kill() { + this.setDead(); + } + + /** + * Checks if the offset position from the entity's current position is inside of + * liquid. Args: x, y, z + */ + public boolean isOffsetPositionInLiquid(double par1, double par3, double par5) { + AxisAlignedBB var7 = this.boundingBox.getOffsetBoundingBox(par1, par3, par5); + List var8 = this.worldObj.getCollidingBoundingBoxes(this, var7); + return !var8.isEmpty() ? false : !this.worldObj.isAnyLiquid(var7); + } + + /** + * Tries to moves the entity by the passed in displacement. Args: x, y, z + */ + public void moveEntity(double par1, double par3, double par5) { + if (this.noClip) { + this.boundingBox.offset(par1, par3, par5); + this.posX = (this.boundingBox.minX + this.boundingBox.maxX) / 2.0D; + this.posY = this.boundingBox.minY + (double) this.yOffset - (double) this.ySize; + this.posZ = (this.boundingBox.minZ + this.boundingBox.maxZ) / 2.0D; + } else { + this.worldObj.theProfiler.startSection("move"); + this.ySize *= 0.4F; + double var7 = this.posX; + double var9 = this.posY; + double var11 = this.posZ; + + if (this.isInWeb) { + this.isInWeb = false; + par1 *= 0.25D; + par3 *= 0.05000000074505806D; + par5 *= 0.25D; + this.motionX = 0.0D; + this.motionY = 0.0D; + this.motionZ = 0.0D; + } + + double var13 = par1; + double var15 = par3; + double var17 = par5; + AxisAlignedBB var19 = this.boundingBox.copy(); + boolean var20 = this.onGround && this.isSneaking() && this instanceof EntityPlayer; + + if (var20) { + double var21; + + for (var21 = 0.05D; par1 != 0.0D && this.worldObj + .getCollidingBoundingBoxes(this, this.boundingBox.getOffsetBoundingBox(par1, -1.0D, 0.0D)) + .isEmpty(); var13 = par1) { + if (par1 < var21 && par1 >= -var21) { + par1 = 0.0D; + } else if (par1 > 0.0D) { + par1 -= var21; + } else { + par1 += var21; + } + } + + for (; par5 != 0.0D && this.worldObj + .getCollidingBoundingBoxes(this, this.boundingBox.getOffsetBoundingBox(0.0D, -1.0D, par5)) + .isEmpty(); var17 = par5) { + if (par5 < var21 && par5 >= -var21) { + par5 = 0.0D; + } else if (par5 > 0.0D) { + par5 -= var21; + } else { + par5 += var21; + } + } + + while (par1 != 0.0D && par5 != 0.0D && this.worldObj + .getCollidingBoundingBoxes(this, this.boundingBox.getOffsetBoundingBox(par1, -1.0D, par5)) + .isEmpty()) { + if (par1 < var21 && par1 >= -var21) { + par1 = 0.0D; + } else if (par1 > 0.0D) { + par1 -= var21; + } else { + par1 += var21; + } + + if (par5 < var21 && par5 >= -var21) { + par5 = 0.0D; + } else if (par5 > 0.0D) { + par5 -= var21; + } else { + par5 += var21; + } + + var13 = par1; + var17 = par5; + } + } + + List var34 = this.worldObj.getCollidingBoundingBoxes(this, this.boundingBox.addCoord(par1, par3, par5)); + + for (int var22 = 0; var22 < var34.size(); ++var22) { + par3 = ((AxisAlignedBB) var34.get(var22)).calculateYOffset(this.boundingBox, par3); + } + + this.boundingBox.offset(0.0D, par3, 0.0D); + + if (!this.field_70135_K && var15 != par3) { + par5 = 0.0D; + par3 = 0.0D; + par1 = 0.0D; + } + + boolean var35 = this.onGround || var15 != par3 && var15 < 0.0D; + int var23; + + for (var23 = 0; var23 < var34.size(); ++var23) { + par1 = ((AxisAlignedBB) var34.get(var23)).calculateXOffset(this.boundingBox, par1); + } + + this.boundingBox.offset(par1, 0.0D, 0.0D); + + if (!this.field_70135_K && var13 != par1) { + par5 = 0.0D; + par3 = 0.0D; + par1 = 0.0D; + } + + for (var23 = 0; var23 < var34.size(); ++var23) { + par5 = ((AxisAlignedBB) var34.get(var23)).calculateZOffset(this.boundingBox, par5); + } + + this.boundingBox.offset(0.0D, 0.0D, par5); + + if (!this.field_70135_K && var17 != par5) { + par5 = 0.0D; + par3 = 0.0D; + par1 = 0.0D; + } + + double var25; + double var27; + int var30; + double var36; + + if (this.stepHeight > 0.0F && var35 && (var20 || this.ySize < 0.05F) && (var13 != par1 || var17 != par5)) { + var36 = par1; + var25 = par3; + var27 = par5; + par1 = var13; + par3 = (double) this.stepHeight; + par5 = var17; + AxisAlignedBB var29 = this.boundingBox.copy(); + this.boundingBox.setBB(var19); + var34 = this.worldObj.getCollidingBoundingBoxes(this, this.boundingBox.addCoord(var13, par3, var17)); + + for (var30 = 0; var30 < var34.size(); ++var30) { + par3 = ((AxisAlignedBB) var34.get(var30)).calculateYOffset(this.boundingBox, par3); + } + + this.boundingBox.offset(0.0D, par3, 0.0D); + + if (!this.field_70135_K && var15 != par3) { + par5 = 0.0D; + par3 = 0.0D; + par1 = 0.0D; + } + + for (var30 = 0; var30 < var34.size(); ++var30) { + par1 = ((AxisAlignedBB) var34.get(var30)).calculateXOffset(this.boundingBox, par1); + } + + this.boundingBox.offset(par1, 0.0D, 0.0D); + + if (!this.field_70135_K && var13 != par1) { + par5 = 0.0D; + par3 = 0.0D; + par1 = 0.0D; + } + + for (var30 = 0; var30 < var34.size(); ++var30) { + par5 = ((AxisAlignedBB) var34.get(var30)).calculateZOffset(this.boundingBox, par5); + } + + this.boundingBox.offset(0.0D, 0.0D, par5); + + if (!this.field_70135_K && var17 != par5) { + par5 = 0.0D; + par3 = 0.0D; + par1 = 0.0D; + } + + if (!this.field_70135_K && var15 != par3) { + par5 = 0.0D; + par3 = 0.0D; + par1 = 0.0D; + } else { + par3 = (double) (-this.stepHeight); + + for (var30 = 0; var30 < var34.size(); ++var30) { + par3 = ((AxisAlignedBB) var34.get(var30)).calculateYOffset(this.boundingBox, par3); + } + + this.boundingBox.offset(0.0D, par3, 0.0D); + } + + if (var36 * var36 + var27 * var27 >= par1 * par1 + par5 * par5) { + par1 = var36; + par3 = var25; + par5 = var27; + this.boundingBox.setBB(var29); + } + } + + this.worldObj.theProfiler.endSection(); + this.worldObj.theProfiler.startSection("rest"); + this.posX = (this.boundingBox.minX + this.boundingBox.maxX) / 2.0D; + this.posY = this.boundingBox.minY + (double) this.yOffset - (double) this.ySize; + this.posZ = (this.boundingBox.minZ + this.boundingBox.maxZ) / 2.0D; + this.isCollidedHorizontally = var13 != par1 || var17 != par5; + this.isCollidedVertically = var15 != par3; + this.onGround = var15 != par3 && var15 < 0.0D; + this.isCollided = this.isCollidedHorizontally || this.isCollidedVertically; + this.updateFallState(par3, this.onGround); + + if (var13 != par1) { + this.motionX = 0.0D; + } + + if (var15 != par3) { + this.motionY = 0.0D; + } + + if (var17 != par5) { + this.motionZ = 0.0D; + } + + var36 = this.posX - var7; + var25 = this.posY - var9; + var27 = this.posZ - var11; + + if (this.canTriggerWalking() && !var20 && this.ridingEntity == null) { + int var37 = MathHelper.floor_double(this.posX); + var30 = MathHelper.floor_double(this.posY - 0.20000000298023224D - (double) this.yOffset); + int var31 = MathHelper.floor_double(this.posZ); + int var32 = this.worldObj.getBlockId(var37, var30, var31); + + if (var32 == 0) { + int var33 = this.worldObj.blockGetRenderType(var37, var30 - 1, var31); + + if (var33 == 11 || var33 == 32 || var33 == 21) { + var32 = this.worldObj.getBlockId(var37, var30 - 1, var31); + } + } + + if (var32 != Block.ladder.blockID) { + var25 = 0.0D; + } + + this.distanceWalkedModified = (float) ((double) this.distanceWalkedModified + + (double) MathHelper.sqrt_double(var36 * var36 + var27 * var27) * 0.6D); + this.distanceWalkedOnStepModified = (float) ((double) this.distanceWalkedOnStepModified + + (double) MathHelper.sqrt_double(var36 * var36 + var25 * var25 + var27 * var27) * 0.6D); + + if (this.distanceWalkedOnStepModified > (float) this.nextStepDistance && var32 > 0) { + this.nextStepDistance = (int) this.distanceWalkedOnStepModified + 1; + + if (this.isInWater()) { + float var39 = MathHelper.sqrt_double(this.motionX * this.motionX * 0.20000000298023224D + + this.motionY * this.motionY + this.motionZ * this.motionZ * 0.20000000298023224D) + * 0.35F; + + if (var39 > 1.0F) { + var39 = 1.0F; + } + + this.playSound("liquid.swim", var39, + 1.0F + (this.rand.nextFloat() - this.rand.nextFloat()) * 0.4F); + } + + this.playStepSound(var37, var30, var31, var32); + Block.blocksList[var32].onEntityWalking(this.worldObj, var37, var30, var31, this); + } + } + + this.doBlockCollisions(); + boolean var38 = this.isWet(); + + if (this.worldObj.isBoundingBoxBurning(this.boundingBox.contract(0.001D, 0.001D, 0.001D))) { + this.dealFireDamage(1); + + if (!var38) { + ++this.fire; + + if (this.fire == 0) { + this.setFire(8); + } + } + } else if (this.fire <= 0) { + this.fire = -this.fireResistance; + } + + if (var38 && this.fire > 0) { + this.playSound("random.fizz", 0.7F, 1.6F + (this.rand.nextFloat() - this.rand.nextFloat()) * 0.4F); + this.fire = -this.fireResistance; + } + + this.worldObj.theProfiler.endSection(); + } + } + + /** + * Checks for block collisions, and calls the associated onBlockCollided method + * for the collided block. + */ + protected void doBlockCollisions() { + int var1 = MathHelper.floor_double(this.boundingBox.minX + 0.001D); + int var2 = MathHelper.floor_double(this.boundingBox.minY + 0.001D); + int var3 = MathHelper.floor_double(this.boundingBox.minZ + 0.001D); + int var4 = MathHelper.floor_double(this.boundingBox.maxX - 0.001D); + int var5 = MathHelper.floor_double(this.boundingBox.maxY - 0.001D); + int var6 = MathHelper.floor_double(this.boundingBox.maxZ - 0.001D); + + if (this.worldObj.checkChunksExist(var1, var2, var3, var4, var5, var6)) { + for (int var7 = var1; var7 <= var4; ++var7) { + for (int var8 = var2; var8 <= var5; ++var8) { + for (int var9 = var3; var9 <= var6; ++var9) { + int var10 = this.worldObj.getBlockId(var7, var8, var9); + + if (var10 > 0) { + Block.blocksList[var10].onEntityCollidedWithBlock(this.worldObj, var7, var8, var9, this); + } + } + } + } + } + } + + /** + * Plays step sound at given x, y, z for the entity + */ + protected void playStepSound(int par1, int par2, int par3, int par4) { + StepSound var5 = Block.blocksList[par4].stepSound; + + if (this.worldObj.getBlockId(par1, par2 + 1, par3) == Block.snow.blockID) { + var5 = Block.snow.stepSound; + this.playSound(var5.getStepSound(), var5.getVolume() * 0.15F, var5.getPitch()); + } else if (!Block.blocksList[par4].blockMaterial.isLiquid()) { + this.playSound(var5.getStepSound(), var5.getVolume() * 0.15F, var5.getPitch()); + } + } + + public void playSound(String par1Str, float par2, float par3) { + this.worldObj.playSoundAtEntity(this, par1Str, par2, par3); + } + + /** + * returns if this entity triggers Block.onEntityWalking on the blocks they walk + * on. used for spiders and wolves to prevent them from trampling crops + */ + protected boolean canTriggerWalking() { + return true; + } + + /** + * Takes in the distance the entity has fallen this tick and whether its on the + * ground to update the fall distance and deal fall damage if landing on the + * ground. Args: distanceFallenThisTick, onGround + */ + protected void updateFallState(double par1, boolean par3) { + if (par3) { + if (this.fallDistance > 0.0F) { + this.fall(this.fallDistance); + this.fallDistance = 0.0F; + } + } else if (par1 < 0.0D) { + this.fallDistance = (float) ((double) this.fallDistance - par1); + } + } + + /** + * returns the bounding box for this entity + */ + public AxisAlignedBB getBoundingBox() { + return null; + } + + /** + * Will deal the specified amount of damage to the entity if the entity isn't + * immune to fire damage. Args: amountDamage + */ + protected void dealFireDamage(int par1) { + if (!this.isImmuneToFire) { + this.attackEntityFrom(DamageSource.inFire, par1); + } + } + + public final boolean isImmuneToFire() { + return this.isImmuneToFire; + } + + /** + * Called when the mob is falling. Calculates and applies fall damage. + */ + protected void fall(float par1) { + if (this.riddenByEntity != null) { + this.riddenByEntity.fall(par1); + } + } + + /** + * Checks if this entity is either in water or on an open air block in rain + * (used in wolves). + */ + public boolean isWet() { + return this.inWater + || this.worldObj.canLightningStrikeAt(MathHelper.floor_double(this.posX), + MathHelper.floor_double(this.posY), MathHelper.floor_double(this.posZ)) + || this.worldObj.canLightningStrikeAt(MathHelper.floor_double(this.posX), + MathHelper.floor_double(this.posY + (double) this.height), MathHelper.floor_double(this.posZ)); + } + + /** + * Checks if this entity is inside water (if inWater field is true as a result + * of handleWaterMovement() returning true) + */ + public boolean isInWater() { + return this.inWater; + } + + /** + * Returns if this entity is in water and will end up adding the waters velocity + * to the entity + */ + public boolean handleWaterMovement() { + if (this.worldObj.handleMaterialAcceleration( + this.boundingBox.expand(0.0D, -0.4000000059604645D, 0.0D).contract(0.001D, 0.001D, 0.001D), + Material.water, this)) { + if (!this.inWater && !this.firstUpdate) { + float var1 = MathHelper.sqrt_double(this.motionX * this.motionX * 0.20000000298023224D + + this.motionY * this.motionY + this.motionZ * this.motionZ * 0.20000000298023224D) * 0.2F; + + if (var1 > 1.0F) { + var1 = 1.0F; + } + + this.playSound("liquid.splash", var1, 1.0F + (this.rand.nextFloat() - this.rand.nextFloat()) * 0.4F); + float var2 = (float) MathHelper.floor_double(this.boundingBox.minY); + int var3; + float var4; + float var5; + + for (var3 = 0; (float) var3 < 1.0F + this.width * 20.0F; ++var3) { + var4 = (this.rand.nextFloat() * 2.0F - 1.0F) * this.width; + var5 = (this.rand.nextFloat() * 2.0F - 1.0F) * this.width; + this.worldObj.spawnParticle("bubble", this.posX + (double) var4, (double) (var2 + 1.0F), + this.posZ + (double) var5, this.motionX, + this.motionY - (double) (this.rand.nextFloat() * 0.2F), this.motionZ); + } + + for (var3 = 0; (float) var3 < 1.0F + this.width * 20.0F; ++var3) { + var4 = (this.rand.nextFloat() * 2.0F - 1.0F) * this.width; + var5 = (this.rand.nextFloat() * 2.0F - 1.0F) * this.width; + this.worldObj.spawnParticle("splash", this.posX + (double) var4, (double) (var2 + 1.0F), + this.posZ + (double) var5, this.motionX, this.motionY, this.motionZ); + } + } + + this.fallDistance = 0.0F; + this.inWater = true; + this.fire = 0; + } else { + this.inWater = false; + } + + return this.inWater; + } + + /** + * Checks if the current block the entity is within of the specified material + * type + */ + public boolean isInsideOfMaterial(Material par1Material) { + double var2 = this.posY + (double) this.getEyeHeight(); + int var4 = MathHelper.floor_double(this.posX); + int var5 = MathHelper.floor_float((float) MathHelper.floor_double(var2)); + int var6 = MathHelper.floor_double(this.posZ); + int var7 = this.worldObj.getBlockId(var4, var5, var6); + + if (var7 != 0 && Block.blocksList[var7].blockMaterial == par1Material) { + float var8 = BlockFluid.getFluidHeightPercent(this.worldObj.getBlockMetadata(var4, var5, var6)) + - 0.11111111F; + float var9 = (float) (var5 + 1) - var8; + return var2 < (double) var9; + } else { + return false; + } + } + + public float getEyeHeight() { + return 0.0F; + } + + /** + * Whether or not the current entity is in lava + */ + public boolean handleLavaMovement() { + return this.worldObj.isMaterialInBB( + this.boundingBox.expand(-0.10000000149011612D, -0.4000000059604645D, -0.10000000149011612D), + Material.lava); + } + + /** + * Used in both water and by flying objects + */ + public void moveFlying(float par1, float par2, float par3) { + float var4 = par1 * par1 + par2 * par2; + + if (var4 >= 1.0E-4F) { + var4 = MathHelper.sqrt_float(var4); + + if (var4 < 1.0F) { + var4 = 1.0F; + } + + var4 = par3 / var4; + par1 *= var4; + par2 *= var4; + float var5 = MathHelper.sin(this.rotationYaw * (float) Math.PI / 180.0F); + float var6 = MathHelper.cos(this.rotationYaw * (float) Math.PI / 180.0F); + this.motionX += (double) (par1 * var6 - par2 * var5); + this.motionZ += (double) (par2 * var6 + par1 * var5); + } + } + + /** + * Gets how bright this entity is. + */ + public float getBrightness(float par1) { + int var2 = MathHelper.floor_double(this.posX); + int var3 = MathHelper.floor_double(this.posZ); + + if (this.worldObj.blockExists(var2, 0, var3)) { + double var4 = (this.boundingBox.maxY - this.boundingBox.minY) * 0.66D; + int var6 = MathHelper.floor_double(this.posY - (double) this.yOffset + var4); + return this.worldObj.getLightBrightness(var2, var6, var3); + } else { + return 0.0F; + } + } + + /** + * Sets the reference to the World object. + */ + public void setWorld(World par1World) { + this.worldObj = par1World; + } + + /** + * Sets the entity's position and rotation. Args: posX, posY, posZ, yaw, pitch + */ + public void setPositionAndRotation(double par1, double par3, double par5, float par7, float par8) { + this.prevPosX = this.posX = par1; + this.prevPosY = this.posY = par3; + this.prevPosZ = this.posZ = par5; + this.prevRotationYaw = this.rotationYaw = par7; + this.prevRotationPitch = this.rotationPitch = par8; + this.ySize = 0.0F; + double var9 = (double) (this.prevRotationYaw - par7); + + if (var9 < -180.0D) { + this.prevRotationYaw += 360.0F; + } + + if (var9 >= 180.0D) { + this.prevRotationYaw -= 360.0F; + } + + this.setPosition(this.posX, this.posY, this.posZ); + this.setRotation(par7, par8); + } + + /** + * Sets the location and Yaw/Pitch of an entity in the world + */ + public void setLocationAndAngles(double par1, double par3, double par5, float par7, float par8) { + this.lastTickPosX = this.prevPosX = this.posX = par1; + this.lastTickPosY = this.prevPosY = this.posY = par3 + (double) this.yOffset; + this.lastTickPosZ = this.prevPosZ = this.posZ = par5; + this.rotationYaw = par7; + this.rotationPitch = par8; + this.setPosition(this.posX, this.posY, this.posZ); + } + + /** + * Returns the distance to the entity. Args: entity + */ + public float getDistanceToEntity(Entity par1Entity) { + float var2 = (float) (this.posX - par1Entity.posX); + float var3 = (float) (this.posY - par1Entity.posY); + float var4 = (float) (this.posZ - par1Entity.posZ); + return MathHelper.sqrt_float(var2 * var2 + var3 * var3 + var4 * var4); + } + + /** + * Gets the squared distance to the position. Args: x, y, z + */ + public double getDistanceSq(double par1, double par3, double par5) { + double var7 = this.posX - par1; + double var9 = this.posY - par3; + double var11 = this.posZ - par5; + return var7 * var7 + var9 * var9 + var11 * var11; + } + + /** + * Gets the distance to the position. Args: x, y, z + */ + public double getDistance(double par1, double par3, double par5) { + double var7 = this.posX - par1; + double var9 = this.posY - par3; + double var11 = this.posZ - par5; + return (double) MathHelper.sqrt_double(var7 * var7 + var9 * var9 + var11 * var11); + } + + /** + * Returns the squared distance to the entity. Args: entity + */ + public double getDistanceSqToEntity(Entity par1Entity) { + double var2 = this.posX - par1Entity.posX; + double var4 = this.posY - par1Entity.posY; + double var6 = this.posZ - par1Entity.posZ; + return var2 * var2 + var4 * var4 + var6 * var6; + } + + /** + * Called by a player entity when they collide with an entity + */ + public void onCollideWithPlayer(EntityPlayer par1EntityPlayer) { + } + + /** + * Applies a velocity to each of the entities pushing them away from each other. + * Args: entity + */ + public void applyEntityCollision(Entity par1Entity) { + if (par1Entity.riddenByEntity != this && par1Entity.ridingEntity != this) { + double var2 = par1Entity.posX - this.posX; + double var4 = par1Entity.posZ - this.posZ; + double var6 = MathHelper.abs_max(var2, var4); + + if (var6 >= 0.009999999776482582D) { + var6 = (double) MathHelper.sqrt_double(var6); + var2 /= var6; + var4 /= var6; + double var8 = 1.0D / var6; + + if (var8 > 1.0D) { + var8 = 1.0D; + } + + var2 *= var8; + var4 *= var8; + var2 *= 0.05000000074505806D; + var4 *= 0.05000000074505806D; + var2 *= (double) (1.0F - this.entityCollisionReduction); + var4 *= (double) (1.0F - this.entityCollisionReduction); + this.addVelocity(-var2, 0.0D, -var4); + par1Entity.addVelocity(var2, 0.0D, var4); + } + } + } + + /** + * Adds to the current velocity of the entity. Args: x, y, z + */ + public void addVelocity(double par1, double par3, double par5) { + this.motionX += par1; + this.motionY += par3; + this.motionZ += par5; + this.isAirBorne = true; + } + + /** + * Sets that this entity has been attacked. + */ + protected void setBeenAttacked() { + this.velocityChanged = true; + } + + /** + * Called when the entity is attacked. + */ + public boolean attackEntityFrom(DamageSource par1DamageSource, int par2) { + if (this.isEntityInvulnerable()) { + return false; + } else { + this.setBeenAttacked(); + return false; + } + } + + /** + * Returns true if other Entities should be prevented from moving through this + * Entity. + */ + public boolean canBeCollidedWith() { + return false; + } + + /** + * Returns true if this entity should push and be pushed by other entities when + * colliding. + */ + public boolean canBePushed() { + return false; + } + + /** + * Adds a value to the player score. Currently not actually used and the entity + * passed in does nothing. Args: entity, scoreToAdd + */ + public void addToPlayerScore(Entity par1Entity, int par2) { + } + + public boolean addNotRiddenEntityID(NBTTagCompound par1NBTTagCompound) { + String var2 = this.getEntityString(); + + if (!this.isDead && var2 != null) { + par1NBTTagCompound.setString("id", var2); + this.writeToNBT(par1NBTTagCompound); + return true; + } else { + return false; + } + } + + /** + * adds the ID of this entity to the NBT given + */ + public boolean addEntityID(NBTTagCompound par1NBTTagCompound) { + String var2 = this.getEntityString(); + + if (!this.isDead && var2 != null && this.riddenByEntity == null) { + par1NBTTagCompound.setString("id", var2); + this.writeToNBT(par1NBTTagCompound); + return true; + } else { + return false; + } + } + + /** + * Save the entity to NBT (calls an abstract helper method to write extra data) + */ + public void writeToNBT(NBTTagCompound par1NBTTagCompound) { + try { + par1NBTTagCompound.setTag("Pos", + this.newDoubleNBTList(new double[] { this.posX, this.posY + (double) this.ySize, this.posZ })); + par1NBTTagCompound.setTag("Motion", + this.newDoubleNBTList(new double[] { this.motionX, this.motionY, this.motionZ })); + par1NBTTagCompound.setTag("Rotation", + this.newFloatNBTList(new float[] { this.rotationYaw, this.rotationPitch })); + par1NBTTagCompound.setFloat("FallDistance", this.fallDistance); + par1NBTTagCompound.setShort("Fire", (short) this.fire); + par1NBTTagCompound.setShort("Air", (short) this.getAir()); + par1NBTTagCompound.setBoolean("OnGround", this.onGround); + par1NBTTagCompound.setInteger("Dimension", this.dimension); + par1NBTTagCompound.setBoolean("Invulnerable", this.invulnerable); + par1NBTTagCompound.setInteger("PortalCooldown", this.timeUntilPortal); + par1NBTTagCompound.setLong("UUIDMost", this.entityUniqueID.getMostSignificantBits()); + par1NBTTagCompound.setLong("UUIDLeast", this.entityUniqueID.getLeastSignificantBits()); + this.writeEntityToNBT(par1NBTTagCompound); + + if (this.ridingEntity != null) { + NBTTagCompound var2 = new NBTTagCompound("Riding"); + + if (this.ridingEntity.addNotRiddenEntityID(var2)) { + par1NBTTagCompound.setTag("Riding", var2); + } + } + } catch (Throwable var5) { + CrashReport var3 = CrashReport.makeCrashReport(var5, "Saving entity NBT"); + CrashReportCategory var4 = var3.makeCategory("Entity being saved"); + this.func_85029_a(var4); + throw new ReportedException(var3); + } + } + + /** + * Reads the entity from NBT (calls an abstract helper method to read + * specialized data) + */ + public void readFromNBT(NBTTagCompound par1NBTTagCompound) { + try { + NBTTagList var2 = par1NBTTagCompound.getTagList("Pos"); + NBTTagList var6 = par1NBTTagCompound.getTagList("Motion"); + NBTTagList var7 = par1NBTTagCompound.getTagList("Rotation"); + this.motionX = ((NBTTagDouble) var6.tagAt(0)).data; + this.motionY = ((NBTTagDouble) var6.tagAt(1)).data; + this.motionZ = ((NBTTagDouble) var6.tagAt(2)).data; + + if (Math.abs(this.motionX) > 10.0D) { + this.motionX = 0.0D; + } + + if (Math.abs(this.motionY) > 10.0D) { + this.motionY = 0.0D; + } + + if (Math.abs(this.motionZ) > 10.0D) { + this.motionZ = 0.0D; + } + + this.prevPosX = this.lastTickPosX = this.posX = ((NBTTagDouble) var2.tagAt(0)).data; + this.prevPosY = this.lastTickPosY = this.posY = ((NBTTagDouble) var2.tagAt(1)).data; + this.prevPosZ = this.lastTickPosZ = this.posZ = ((NBTTagDouble) var2.tagAt(2)).data; + this.prevRotationYaw = this.rotationYaw = ((NBTTagFloat) var7.tagAt(0)).data; + this.prevRotationPitch = this.rotationPitch = ((NBTTagFloat) var7.tagAt(1)).data; + this.fallDistance = par1NBTTagCompound.getFloat("FallDistance"); + this.fire = par1NBTTagCompound.getShort("Fire"); + this.setAir(par1NBTTagCompound.getShort("Air")); + this.onGround = par1NBTTagCompound.getBoolean("OnGround"); + this.dimension = par1NBTTagCompound.getInteger("Dimension"); + this.invulnerable = par1NBTTagCompound.getBoolean("Invulnerable"); + this.timeUntilPortal = par1NBTTagCompound.getInteger("PortalCooldown"); + + if (par1NBTTagCompound.hasKey("UUIDMost") && par1NBTTagCompound.hasKey("UUIDLeast")) { + this.entityUniqueID = new UUID(par1NBTTagCompound.getLong("UUIDMost"), + par1NBTTagCompound.getLong("UUIDLeast")); + } + + this.setPosition(this.posX, this.posY, this.posZ); + this.setRotation(this.rotationYaw, this.rotationPitch); + this.readEntityFromNBT(par1NBTTagCompound); + } catch (Throwable var5) { + CrashReport var3 = CrashReport.makeCrashReport(var5, "Loading entity NBT"); + CrashReportCategory var4 = var3.makeCategory("Entity being loaded"); + this.func_85029_a(var4); + throw new ReportedException(var3); + } + } + + /** + * Returns the string that identifies this Entity's class + */ + protected final String getEntityString() { + return EntityList.getEntityString(this); + } + + /** + * (abstract) Protected helper method to read subclass entity data from NBT. + */ + protected abstract void readEntityFromNBT(NBTTagCompound var1); + + /** + * (abstract) Protected helper method to write subclass entity data to NBT. + */ + protected abstract void writeEntityToNBT(NBTTagCompound var1); + + /** + * creates a NBT list from the array of doubles passed to this function + */ + protected NBTTagList newDoubleNBTList(double... par1ArrayOfDouble) { + NBTTagList var2 = new NBTTagList(); + double[] var3 = par1ArrayOfDouble; + int var4 = par1ArrayOfDouble.length; + + for (int var5 = 0; var5 < var4; ++var5) { + double var6 = var3[var5]; + var2.appendTag(new NBTTagDouble((String) null, var6)); + } + + return var2; + } + + /** + * Returns a new NBTTagList filled with the specified floats + */ + protected NBTTagList newFloatNBTList(float... par1ArrayOfFloat) { + NBTTagList var2 = new NBTTagList(); + float[] var3 = par1ArrayOfFloat; + int var4 = par1ArrayOfFloat.length; + + for (int var5 = 0; var5 < var4; ++var5) { + float var6 = var3[var5]; + var2.appendTag(new NBTTagFloat((String) null, var6)); + } + + return var2; + } + + /** + * Drops an item stack at the entity's position. Args: itemID, count + */ + public EntityItem dropItem(int par1, int par2) { + return this.dropItemWithOffset(par1, par2, 0.0F); + } + + /** + * Drops an item stack with a specified y offset. Args: itemID, count, yOffset + */ + public EntityItem dropItemWithOffset(int par1, int par2, float par3) { + return this.entityDropItem(new ItemStack(par1, par2, 0), par3); + } + + /** + * Drops an item at the position of the entity. + */ + public EntityItem entityDropItem(ItemStack par1ItemStack, float par2) { + EntityItem var3 = new EntityItem(this.worldObj, this.posX, this.posY + (double) par2, this.posZ, par1ItemStack); + var3.delayBeforeCanPickup = 10; + this.worldObj.spawnEntityInWorld(var3); + return var3; + } + + /** + * Checks whether target entity is alive. + */ + public boolean isEntityAlive() { + return !this.isDead; + } + + /** + * Checks if this entity is inside of an opaque block + */ + public boolean isEntityInsideOpaqueBlock() { + for (int var1 = 0; var1 < 8; ++var1) { + float var2 = ((float) ((var1 >> 0) % 2) - 0.5F) * this.width * 0.8F; + float var3 = ((float) ((var1 >> 1) % 2) - 0.5F) * 0.1F; + float var4 = ((float) ((var1 >> 2) % 2) - 0.5F) * this.width * 0.8F; + int var5 = MathHelper.floor_double(this.posX + (double) var2); + int var6 = MathHelper.floor_double(this.posY + (double) this.getEyeHeight() + (double) var3); + int var7 = MathHelper.floor_double(this.posZ + (double) var4); + + if (this.worldObj.isBlockNormalCube(var5, var6, var7)) { + return true; + } + } + + return false; + } + + /** + * Called when a player interacts with a mob. e.g. gets milk from a cow, gets + * into the saddle on a pig. + */ + public boolean interact(EntityPlayer par1EntityPlayer) { + return false; + } + + /** + * Returns a boundingBox used to collide the entity with other entities and + * blocks. This enables the entity to be pushable on contact, like boats or + * minecarts. + */ + public AxisAlignedBB getCollisionBox(Entity par1Entity) { + return null; + } + + /** + * Handles updating while being ridden by an entity + */ + public void updateRidden() { + if (this.ridingEntity.isDead) { + this.ridingEntity = null; + } else { + this.motionX = 0.0D; + this.motionY = 0.0D; + this.motionZ = 0.0D; + this.onUpdate(); + + if (this.ridingEntity != null) { + this.ridingEntity.updateRiderPosition(); + this.entityRiderYawDelta += (double) (this.ridingEntity.rotationYaw + - this.ridingEntity.prevRotationYaw); + + for (this.entityRiderPitchDelta += (double) (this.ridingEntity.rotationPitch + - this.ridingEntity.prevRotationPitch); this.entityRiderYawDelta >= 180.0D; this.entityRiderYawDelta -= 360.0D) { + ; + } + + while (this.entityRiderYawDelta < -180.0D) { + this.entityRiderYawDelta += 360.0D; + } + + while (this.entityRiderPitchDelta >= 180.0D) { + this.entityRiderPitchDelta -= 360.0D; + } + + while (this.entityRiderPitchDelta < -180.0D) { + this.entityRiderPitchDelta += 360.0D; + } + + double var1 = this.entityRiderYawDelta * 0.5D; + double var3 = this.entityRiderPitchDelta * 0.5D; + float var5 = 10.0F; + + if (var1 > (double) var5) { + var1 = (double) var5; + } + + if (var1 < (double) (-var5)) { + var1 = (double) (-var5); + } + + if (var3 > (double) var5) { + var3 = (double) var5; + } + + if (var3 < (double) (-var5)) { + var3 = (double) (-var5); + } + + this.entityRiderYawDelta -= var1; + this.entityRiderPitchDelta -= var3; + this.rotationYaw = (float) ((double) this.rotationYaw + var1); + this.rotationPitch = (float) ((double) this.rotationPitch + var3); + } + } + } + + public void updateRiderPosition() { + if (this.riddenByEntity != null) { + if (!(this.riddenByEntity instanceof EntityPlayer) + || !((EntityPlayer) this.riddenByEntity).func_71066_bF()) { + this.riddenByEntity.lastTickPosX = this.lastTickPosX; + this.riddenByEntity.lastTickPosY = this.lastTickPosY + this.getMountedYOffset() + + this.riddenByEntity.getYOffset(); + this.riddenByEntity.lastTickPosZ = this.lastTickPosZ; + } + + this.riddenByEntity.setPosition(this.posX, + this.posY + this.getMountedYOffset() + this.riddenByEntity.getYOffset(), this.posZ); + } + } + + /** + * Returns the Y Offset of this entity. + */ + public double getYOffset() { + return (double) this.yOffset; + } + + /** + * Returns the Y offset from the entity's position for any entity riding this + * one. + */ + public double getMountedYOffset() { + return (double) this.height * 0.75D; + } + + /** + * Called when a player mounts an entity. e.g. mounts a pig, mounts a boat. + */ + public void mountEntity(Entity par1Entity) { + this.entityRiderPitchDelta = 0.0D; + this.entityRiderYawDelta = 0.0D; + + if (par1Entity == null) { + if (this.ridingEntity != null) { + this.setLocationAndAngles(this.ridingEntity.posX, + this.ridingEntity.boundingBox.minY + (double) this.ridingEntity.height, this.ridingEntity.posZ, + this.rotationYaw, this.rotationPitch); + this.ridingEntity.riddenByEntity = null; + } + + this.ridingEntity = null; + } else { + if (this.ridingEntity != null) { + this.ridingEntity.riddenByEntity = null; + } + + this.ridingEntity = par1Entity; + par1Entity.riddenByEntity = this; + } + } + + /** + * Called when a player unounts an entity. + */ + public void unmountEntity(Entity par1Entity) { + double var3 = this.posX; + double var5 = this.posY; + double var7 = this.posZ; + + if (par1Entity != null) { + var3 = par1Entity.posX; + var5 = par1Entity.boundingBox.minY + (double) par1Entity.height; + var7 = par1Entity.posZ; + } + + for (double var9 = -1.5D; var9 < 2.0D; ++var9) { + for (double var11 = -1.5D; var11 < 2.0D; ++var11) { + if (var9 != 0.0D || var11 != 0.0D) { + int var13 = (int) (this.posX + var9); + int var14 = (int) (this.posZ + var11); + AxisAlignedBB var2 = this.boundingBox.getOffsetBoundingBox(var9, 1.0D, var11); + + if (this.worldObj.getCollidingBlockBounds(var2).isEmpty()) { + if (this.worldObj.doesBlockHaveSolidTopSurface(var13, (int) this.posY, var14)) { + this.setLocationAndAngles(this.posX + var9, this.posY + 1.0D, this.posZ + var11, + this.rotationYaw, this.rotationPitch); + return; + } + + if (this.worldObj.doesBlockHaveSolidTopSurface(var13, (int) this.posY - 1, var14) + || this.worldObj.getBlockMaterial(var13, (int) this.posY - 1, + var14) == Material.water) { + var3 = this.posX + var9; + var5 = this.posY + 1.0D; + var7 = this.posZ + var11; + } + } + } + } + } + + this.setLocationAndAngles(var3, var5, var7, this.rotationYaw, this.rotationPitch); + } + + public float getCollisionBorderSize() { + return 0.1F; + } + + /** + * returns a (normalized) vector of where this entity is looking + */ + public Vec3 getLookVec() { + return null; + } + + /** + * Called by portal blocks when an entity is within it. + */ + public void setInPortal() { + if (this.timeUntilPortal > 0) { + this.timeUntilPortal = this.getPortalCooldown(); + } else { + double var1 = this.prevPosX - this.posX; + double var3 = this.prevPosZ - this.posZ; + + if (!this.worldObj.isRemote && !this.inPortal) { + this.teleportDirection = Direction.getMovementDirection(var1, var3); + } + + this.inPortal = true; + } + } + + /** + * Return the amount of cooldown before this entity can use a portal again. + */ + public int getPortalCooldown() { + return 900; + } + + /** + * returns the inventory of this entity (only used in EntityPlayerMP it seems) + */ + public ItemStack[] getInventory() { + return null; + } + + /** + * Sets the held item, or an armor slot. Slot 0 is held item. Slot 1-4 is armor. + * Params: Item, slot + */ + public void setCurrentItemOrArmor(int par1, ItemStack par2ItemStack) { + } + + /** + * Returns true if the entity is on fire. Used by render to add the fire effect + * on rendering. + */ + public boolean isBurning() { + return this.fire > 0 || this.getFlag(0); + } + + /** + * Returns true if the entity is riding another entity, used by render to rotate + * the legs to be in 'sit' position for players. + */ + public boolean isRiding() { + return this.ridingEntity != null || this.getFlag(2); + } + + /** + * Returns if this entity is sneaking. + */ + public boolean isSneaking() { + return this.getFlag(1); + } + + /** + * Sets the sneaking flag. + */ + public void setSneaking(boolean par1) { + this.setFlag(1, par1); + } + + /** + * Get if the Entity is sprinting. + */ + public boolean isSprinting() { + return this.getFlag(3); + } + + /** + * Set sprinting switch for Entity. + */ + public void setSprinting(boolean par1) { + this.setFlag(3, par1); + } + + public boolean isInvisible() { + return this.getFlag(5); + } + + public void setInvisible(boolean par1) { + this.setFlag(5, par1); + } + + public void setEating(boolean par1) { + this.setFlag(4, par1); + } + + /** + * Returns true if the flag is active for the entity. Known flags: 0) is + * burning; 1) is sneaking; 2) is riding something; 3) is sprinting; 4) is + * eating + */ + protected boolean getFlag(int par1) { + return (this.dataWatcher.getWatchableObjectByte(0) & 1 << par1) != 0; + } + + /** + * Enable or disable a entity flag, see getEntityFlag to read the know flags. + */ + protected void setFlag(int par1, boolean par2) { + byte var3 = this.dataWatcher.getWatchableObjectByte(0); + + if (par2) { + this.dataWatcher.updateObject(0, Byte.valueOf((byte) (var3 | 1 << par1))); + } else { + this.dataWatcher.updateObject(0, Byte.valueOf((byte) (var3 & ~(1 << par1)))); + } + } + + public int getAir() { + return this.dataWatcher.getWatchableObjectShort(1); + } + + public void setAir(int par1) { + this.dataWatcher.updateObject(1, Short.valueOf((short) par1)); + } + + /** + * Called when a lightning bolt hits the entity. + */ + public void onStruckByLightning(EntityLightningBolt par1EntityLightningBolt) { + this.dealFireDamage(5); + ++this.fire; + + if (this.fire == 0) { + this.setFire(8); + } + } + + /** + * This method gets called when the entity kills another one. + */ + public void onKillEntity(EntityLiving par1EntityLiving) { + } + + /** + * Adds velocity to push the entity out of blocks at the specified x, y, z + * position Args: x, y, z + */ + protected boolean pushOutOfBlocks(double par1, double par3, double par5) { + int var7 = MathHelper.floor_double(par1); + int var8 = MathHelper.floor_double(par3); + int var9 = MathHelper.floor_double(par5); + double var10 = par1 - (double) var7; + double var12 = par3 - (double) var8; + double var14 = par5 - (double) var9; + List var16 = this.worldObj.getCollidingBlockBounds(this.boundingBox); + + if (var16.isEmpty() && !this.worldObj.func_85174_u(var7, var8, var9)) { + return false; + } else { + boolean var17 = !this.worldObj.func_85174_u(var7 - 1, var8, var9); + boolean var18 = !this.worldObj.func_85174_u(var7 + 1, var8, var9); + boolean var19 = !this.worldObj.func_85174_u(var7, var8 - 1, var9); + boolean var20 = !this.worldObj.func_85174_u(var7, var8 + 1, var9); + boolean var21 = !this.worldObj.func_85174_u(var7, var8, var9 - 1); + boolean var22 = !this.worldObj.func_85174_u(var7, var8, var9 + 1); + byte var23 = 3; + double var24 = 9999.0D; + + if (var17 && var10 < var24) { + var24 = var10; + var23 = 0; + } + + if (var18 && 1.0D - var10 < var24) { + var24 = 1.0D - var10; + var23 = 1; + } + + if (var20 && 1.0D - var12 < var24) { + var24 = 1.0D - var12; + var23 = 3; + } + + if (var21 && var14 < var24) { + var24 = var14; + var23 = 4; + } + + if (var22 && 1.0D - var14 < var24) { + var24 = 1.0D - var14; + var23 = 5; + } + + float var26 = this.rand.nextFloat() * 0.2F + 0.1F; + + if (var23 == 0) { + this.motionX = (double) (-var26); + } + + if (var23 == 1) { + this.motionX = (double) var26; + } + + if (var23 == 2) { + this.motionY = (double) (-var26); + } + + if (var23 == 3) { + this.motionY = (double) var26; + } + + if (var23 == 4) { + this.motionZ = (double) (-var26); + } + + if (var23 == 5) { + this.motionZ = (double) var26; + } + + return true; + } + } + + /** + * Sets the Entity inside a web block. + */ + public void setInWeb() { + this.isInWeb = true; + this.fallDistance = 0.0F; + } + + /** + * Gets the username of the entity. + */ + public String getEntityName() { + String var1 = EntityList.getEntityString(this); + + if (var1 == null) { + var1 = "generic"; + } + + return StatCollector.translateToLocal("entity." + var1 + ".name"); + } + + /** + * Return the Entity parts making up this Entity (currently only for dragons) + */ + public Entity[] getParts() { + return null; + } + + /** + * Returns true if Entity argument is equal to this Entity + */ + public boolean isEntityEqual(Entity par1Entity) { + return this == par1Entity; + } + + public float getRotationYawHead() { + return 0.0F; + } + + /** + * If returns false, the item will not inflict any damage against entities. + */ + public boolean canAttackWithItem() { + return true; + } + + public boolean func_85031_j(Entity par1Entity) { + return false; + } + + public String toString() { + return String.format("%s[\'%s\'/%d, l=\'%s\', x=%.2f, y=%.2f, z=%.2f]", + new Object[] { this.getClass().getSimpleName(), this.getEntityName(), Integer.valueOf(this.entityId), + this.worldObj == null ? "~NULL~" : this.worldObj.getWorldInfo().getWorldName(), + Double.valueOf(this.posX), Double.valueOf(this.posY), Double.valueOf(this.posZ) }); + } + + /** + * Return whether this entity is invulnerable to damage. + */ + public boolean isEntityInvulnerable() { + return this.invulnerable; + } + + public void func_82149_j(Entity par1Entity) { + this.setLocationAndAngles(par1Entity.posX, par1Entity.posY, par1Entity.posZ, par1Entity.rotationYaw, + par1Entity.rotationPitch); + } + + /** + * Copies important data from another entity to this entity. Used when + * teleporting entities between worlds, as this actually deletes the teleporting + * entity and re-creates it on the other side. Params: Entity to copy from, + * unused (always true) + */ + public void copyDataFrom(Entity par1Entity, boolean par2) { + NBTTagCompound var3 = new NBTTagCompound(); + par1Entity.writeToNBT(var3); + this.readFromNBT(var3); + this.timeUntilPortal = par1Entity.timeUntilPortal; + this.teleportDirection = par1Entity.teleportDirection; + } + + public void travelToTheEnd(int par1) { + if (!this.worldObj.isRemote && !this.isDead) { + this.worldObj.theProfiler.startSection("changeDimension"); + MinecraftServer var2 = MinecraftServer.getServer(); + int var3 = this.dimension; + WorldServer var4 = var2.worldServerForDimension(var3); + WorldServer var5 = var2.worldServerForDimension(par1); + this.dimension = par1; + this.worldObj.removeEntity(this); + this.isDead = false; + this.worldObj.theProfiler.startSection("reposition"); + var2.getConfigurationManager().transferEntityToWorld(this, var3, var4, var5); + this.worldObj.theProfiler.endStartSection("reloading"); + Entity var6 = EntityList.createEntityByName(EntityList.getEntityString(this), var5); + + if (var6 != null) { + var6.copyDataFrom(this, true); + var5.spawnEntityInWorld(var6); + } + + this.isDead = true; + this.worldObj.theProfiler.endSection(); + var4.resetUpdateEntityTick(); + var5.resetUpdateEntityTick(); + this.worldObj.theProfiler.endSection(); + } + } + + public float func_82146_a(Explosion par1Explosion, World par2World, int par3, int par4, int par5, Block par6Block) { + return par6Block.getExplosionResistance(this); + } + + public boolean func_96091_a(Explosion par1Explosion, World par2World, int par3, int par4, int par5, int par6, + float par7) { + return true; + } + + public int func_82143_as() { + return 3; + } + + public int getTeleportDirection() { + return this.teleportDirection; + } + + /** + * Return whether this entity should NOT trigger a pressure plate or a tripwire. + */ + public boolean doesEntityNotTriggerPressurePlate() { + return false; + } + + public void func_85029_a(CrashReportCategory par1CrashReportCategory) { + par1CrashReportCategory.addCrashSectionCallable("Entity Type", new CallableEntityType(this)); + par1CrashReportCategory.addCrashSection("Entity ID", Integer.valueOf(this.entityId)); + par1CrashReportCategory.addCrashSectionCallable("Entity Name", new CallableEntityName(this)); + par1CrashReportCategory.addCrashSection("Entity\'s Exact location", String.format("%.2f, %.2f, %.2f", + new Object[] { Double.valueOf(this.posX), Double.valueOf(this.posY), Double.valueOf(this.posZ) })); + par1CrashReportCategory.addCrashSection("Entity\'s Block location", + CrashReportCategory.getLocationInfo(MathHelper.floor_double(this.posX), + MathHelper.floor_double(this.posY), MathHelper.floor_double(this.posZ))); + par1CrashReportCategory.addCrashSection("Entity\'s Momentum", String.format("%.2f, %.2f, %.2f", new Object[] { + Double.valueOf(this.motionX), Double.valueOf(this.motionY), Double.valueOf(this.motionZ) })); + } + + public boolean func_96092_aw() { + return true; + } + + /** + * Returns the translated name of the entity. + */ + public String getTranslatedEntityName() { + return this.getEntityName(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityAIArrowAttack.java b/sp-server/src/main/java/net/minecraft/src/EntityAIArrowAttack.java new file mode 100644 index 0000000..39cbf28 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityAIArrowAttack.java @@ -0,0 +1,129 @@ +package net.minecraft.src; + +public class EntityAIArrowAttack extends EntityAIBase { + /** The entity the AI instance has been applied to */ + private final EntityLiving entityHost; + + /** + * The entity (as a RangedAttackMob) the AI instance has been applied to. + */ + private final IRangedAttackMob rangedAttackEntityHost; + private EntityLiving attackTarget; + + /** + * A decrementing tick that spawns a ranged attack once this value reaches 0. It + * is then set back to the maxRangedAttackTime. + */ + private int rangedAttackTime; + private float entityMoveSpeed; + private int field_75318_f; + private int field_96561_g; + + /** + * The maximum time the AI has to wait before peforming another ranged attack. + */ + private int maxRangedAttackTime; + private float field_96562_i; + private float field_82642_h; + + public EntityAIArrowAttack(IRangedAttackMob par1IRangedAttackMob, float par2, int par3, float par4) { + this(par1IRangedAttackMob, par2, par3, par3, par4); + } + + public EntityAIArrowAttack(IRangedAttackMob par1IRangedAttackMob, float par2, int par3, int par4, float par5) { + this.rangedAttackTime = -1; + this.field_75318_f = 0; + + if (!(par1IRangedAttackMob instanceof EntityLiving)) { + throw new IllegalArgumentException("ArrowAttackGoal requires Mob implements RangedAttackMob"); + } else { + this.rangedAttackEntityHost = par1IRangedAttackMob; + this.entityHost = (EntityLiving) par1IRangedAttackMob; + this.entityMoveSpeed = par2; + this.field_96561_g = par3; + this.maxRangedAttackTime = par4; + this.field_96562_i = par5; + this.field_82642_h = par5 * par5; + this.setMutexBits(3); + } + } + + /** + * Returns whether the EntityAIBase should begin execution. + */ + public boolean shouldExecute() { + EntityLiving var1 = this.entityHost.getAttackTarget(); + + if (var1 == null) { + return false; + } else { + this.attackTarget = var1; + return true; + } + } + + /** + * Returns whether an in-progress EntityAIBase should continue executing + */ + public boolean continueExecuting() { + return this.shouldExecute() || !this.entityHost.getNavigator().noPath(); + } + + /** + * Resets the task + */ + public void resetTask() { + this.attackTarget = null; + this.field_75318_f = 0; + this.rangedAttackTime = -1; + } + + /** + * Updates the task + */ + public void updateTask() { + double var1 = this.entityHost.getDistanceSq(this.attackTarget.posX, this.attackTarget.boundingBox.minY, + this.attackTarget.posZ); + boolean var3 = this.entityHost.getEntitySenses().canSee(this.attackTarget); + + if (var3) { + ++this.field_75318_f; + } else { + this.field_75318_f = 0; + } + + if (var1 <= (double) this.field_82642_h && this.field_75318_f >= 20) { + this.entityHost.getNavigator().clearPathEntity(); + } else { + this.entityHost.getNavigator().tryMoveToEntityLiving(this.attackTarget, this.entityMoveSpeed); + } + + this.entityHost.getLookHelper().setLookPositionWithEntity(this.attackTarget, 30.0F, 30.0F); + float var4; + + if (--this.rangedAttackTime == 0) { + if (var1 > (double) this.field_82642_h || !var3) { + return; + } + + var4 = MathHelper.sqrt_double(var1) / this.field_96562_i; + float var5 = var4; + + if (var4 < 0.1F) { + var5 = 0.1F; + } + + if (var5 > 1.0F) { + var5 = 1.0F; + } + + this.rangedAttackEntityHost.attackEntityWithRangedAttack(this.attackTarget, var5); + this.rangedAttackTime = MathHelper.floor_float( + var4 * (float) (this.maxRangedAttackTime - this.field_96561_g) + (float) this.field_96561_g); + } else if (this.rangedAttackTime < 0) { + var4 = MathHelper.sqrt_double(var1) / this.field_96562_i; + this.rangedAttackTime = MathHelper.floor_float( + var4 * (float) (this.maxRangedAttackTime - this.field_96561_g) + (float) this.field_96561_g); + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityAIAttackOnCollide.java b/sp-server/src/main/java/net/minecraft/src/EntityAIAttackOnCollide.java new file mode 100644 index 0000000..28a0b61 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityAIAttackOnCollide.java @@ -0,0 +1,109 @@ +package net.minecraft.src; + +public class EntityAIAttackOnCollide extends EntityAIBase { + World worldObj; + EntityLiving attacker; + EntityLiving entityTarget; + + /** + * An amount of decrementing ticks that allows the entity to attack once the + * tick reaches 0. + */ + int attackTick; + float field_75440_e; + boolean field_75437_f; + + /** The PathEntity of our entity. */ + PathEntity entityPathEntity; + Class classTarget; + private int field_75445_i; + + public EntityAIAttackOnCollide(EntityLiving par1EntityLiving, Class par2Class, float par3, boolean par4) { + this(par1EntityLiving, par3, par4); + this.classTarget = par2Class; + } + + public EntityAIAttackOnCollide(EntityLiving par1EntityLiving, float par2, boolean par3) { + this.attackTick = 0; + this.attacker = par1EntityLiving; + this.worldObj = par1EntityLiving.worldObj; + this.field_75440_e = par2; + this.field_75437_f = par3; + this.setMutexBits(3); + } + + /** + * Returns whether the EntityAIBase should begin execution. + */ + public boolean shouldExecute() { + EntityLiving var1 = this.attacker.getAttackTarget(); + + if (var1 == null) { + return false; + } else if (this.classTarget != null && !this.classTarget.isAssignableFrom(var1.getClass())) { + return false; + } else { + this.entityTarget = var1; + this.entityPathEntity = this.attacker.getNavigator().getPathToEntityLiving(this.entityTarget); + return this.entityPathEntity != null; + } + } + + /** + * Returns whether an in-progress EntityAIBase should continue executing + */ + public boolean continueExecuting() { + EntityLiving var1 = this.attacker.getAttackTarget(); + return var1 == null ? false + : (!this.entityTarget.isEntityAlive() ? false + : (!this.field_75437_f ? !this.attacker.getNavigator().noPath() + : this.attacker.isWithinHomeDistance(MathHelper.floor_double(this.entityTarget.posX), + MathHelper.floor_double(this.entityTarget.posY), + MathHelper.floor_double(this.entityTarget.posZ)))); + } + + /** + * Execute a one shot task or start executing a continuous task + */ + public void startExecuting() { + this.attacker.getNavigator().setPath(this.entityPathEntity, this.field_75440_e); + this.field_75445_i = 0; + } + + /** + * Resets the task + */ + public void resetTask() { + this.entityTarget = null; + this.attacker.getNavigator().clearPathEntity(); + } + + /** + * Updates the task + */ + public void updateTask() { + this.attacker.getLookHelper().setLookPositionWithEntity(this.entityTarget, 30.0F, 30.0F); + + if ((this.field_75437_f || this.attacker.getEntitySenses().canSee(this.entityTarget)) + && --this.field_75445_i <= 0) { + this.field_75445_i = 4 + this.attacker.getRNG().nextInt(7); + this.attacker.getNavigator().tryMoveToEntityLiving(this.entityTarget, this.field_75440_e); + } + + this.attackTick = Math.max(this.attackTick - 1, 0); + double var1 = (double) (this.attacker.width * 2.0F * this.attacker.width * 2.0F); + + if (this.attacker.getDistanceSq(this.entityTarget.posX, this.entityTarget.boundingBox.minY, + this.entityTarget.posZ) <= var1) { + if (this.attackTick <= 0) { + this.attackTick = 20; + + if (this.attacker.getHeldItem() != null) { + this.attacker.swingItem(); + } + + this.attacker.attackEntityAsMob(this.entityTarget); + } + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityAIAvoidEntity.java b/sp-server/src/main/java/net/minecraft/src/EntityAIAvoidEntity.java new file mode 100644 index 0000000..8373979 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityAIAvoidEntity.java @@ -0,0 +1,112 @@ +package net.minecraft.src; + +import java.util.List; + +public class EntityAIAvoidEntity extends EntityAIBase { + public final IEntitySelector field_98218_a = new EntityAIAvoidEntitySelector(this); + + /** The entity we are attached to */ + private EntityCreature theEntity; + private float farSpeed; + private float nearSpeed; + private Entity closestLivingEntity; + private float distanceFromEntity; + + /** The PathEntity of our entity */ + private PathEntity entityPathEntity; + + /** The PathNavigate of our entity */ + private PathNavigate entityPathNavigate; + + /** The class of the entity we should avoid */ + private Class targetEntityClass; + + public EntityAIAvoidEntity(EntityCreature par1EntityCreature, Class par2Class, float par3, float par4, float par5) { + this.theEntity = par1EntityCreature; + this.targetEntityClass = par2Class; + this.distanceFromEntity = par3; + this.farSpeed = par4; + this.nearSpeed = par5; + this.entityPathNavigate = par1EntityCreature.getNavigator(); + this.setMutexBits(1); + } + + /** + * Returns whether the EntityAIBase should begin execution. + */ + public boolean shouldExecute() { + if (this.targetEntityClass == EntityPlayer.class) { + if (this.theEntity instanceof EntityTameable && ((EntityTameable) this.theEntity).isTamed()) { + return false; + } + + this.closestLivingEntity = this.theEntity.worldObj.getClosestPlayerToEntity(this.theEntity, + (double) this.distanceFromEntity); + + if (this.closestLivingEntity == null) { + return false; + } + } else { + List var1 = this.theEntity.worldObj.selectEntitiesWithinAABB(this.targetEntityClass, + this.theEntity.boundingBox.expand((double) this.distanceFromEntity, 3.0D, + (double) this.distanceFromEntity), + this.field_98218_a); + + if (var1.isEmpty()) { + return false; + } + + this.closestLivingEntity = (Entity) var1.get(0); + } + + Vec3 var2 = RandomPositionGenerator.findRandomTargetBlockAwayFrom(this.theEntity, 16, 7, + this.theEntity.worldObj.getWorldVec3Pool().getVecFromPool(this.closestLivingEntity.posX, + this.closestLivingEntity.posY, this.closestLivingEntity.posZ)); + + if (var2 == null) { + return false; + } else if (this.closestLivingEntity.getDistanceSq(var2.xCoord, var2.yCoord, + var2.zCoord) < this.closestLivingEntity.getDistanceSqToEntity(this.theEntity)) { + return false; + } else { + this.entityPathEntity = this.entityPathNavigate.getPathToXYZ(var2.xCoord, var2.yCoord, var2.zCoord); + return this.entityPathEntity == null ? false : this.entityPathEntity.isDestinationSame(var2); + } + } + + /** + * Returns whether an in-progress EntityAIBase should continue executing + */ + public boolean continueExecuting() { + return !this.entityPathNavigate.noPath(); + } + + /** + * Execute a one shot task or start executing a continuous task + */ + public void startExecuting() { + this.entityPathNavigate.setPath(this.entityPathEntity, this.farSpeed); + } + + /** + * Resets the task + */ + public void resetTask() { + this.closestLivingEntity = null; + } + + /** + * Updates the task + */ + public void updateTask() { + if (this.theEntity.getDistanceSqToEntity(this.closestLivingEntity) < 49.0D) { + this.theEntity.getNavigator().setSpeed(this.nearSpeed); + } else { + this.theEntity.getNavigator().setSpeed(this.farSpeed); + } + } + + static EntityCreature func_98217_a(EntityAIAvoidEntity par0EntityAIAvoidEntity) { + return par0EntityAIAvoidEntity.theEntity; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityAIAvoidEntitySelector.java b/sp-server/src/main/java/net/minecraft/src/EntityAIAvoidEntitySelector.java new file mode 100644 index 0000000..129cad9 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityAIAvoidEntitySelector.java @@ -0,0 +1,17 @@ +package net.minecraft.src; + +class EntityAIAvoidEntitySelector implements IEntitySelector { + final EntityAIAvoidEntity entityAvoiderAI; + + EntityAIAvoidEntitySelector(EntityAIAvoidEntity par1EntityAIAvoidEntity) { + this.entityAvoiderAI = par1EntityAIAvoidEntity; + } + + /** + * Return whether the specified entity is applicable to this filter. + */ + public boolean isEntityApplicable(Entity par1Entity) { + return par1Entity.isEntityAlive() + && EntityAIAvoidEntity.func_98217_a(this.entityAvoiderAI).getEntitySenses().canSee(par1Entity); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityAIBase.java b/sp-server/src/main/java/net/minecraft/src/EntityAIBase.java new file mode 100644 index 0000000..e85a254 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityAIBase.java @@ -0,0 +1,65 @@ +package net.minecraft.src; + +public abstract class EntityAIBase { + /** + * A bitmask telling which other tasks may not run concurrently. The test is a + * simple bitwise AND - if it yields zero, the two tasks may run concurrently, + * if not - they must run exclusively from each other. + */ + private int mutexBits = 0; + + /** + * Returns whether the EntityAIBase should begin execution. + */ + public abstract boolean shouldExecute(); + + /** + * Returns whether an in-progress EntityAIBase should continue executing + */ + public boolean continueExecuting() { + return this.shouldExecute(); + } + + /** + * Returns whether the task requires multiple updates or not + */ + public boolean isContinuous() { + return true; + } + + /** + * Execute a one shot task or start executing a continuous task + */ + public void startExecuting() { + } + + /** + * Resets the task + */ + public void resetTask() { + } + + /** + * Updates the task + */ + public void updateTask() { + } + + /** + * Sets a bitmask telling which other tasks may not run concurrently. The test + * is a simple bitwise AND - if it yields zero, the two tasks may run + * concurrently, if not - they must run exclusively from each other. + */ + public void setMutexBits(int par1) { + this.mutexBits = par1; + } + + /** + * Get a bitmask telling which other tasks may not run concurrently. The test is + * a simple bitwise AND - if it yields zero, the two tasks may run concurrently, + * if not - they must run exclusively from each other. + */ + public int getMutexBits() { + return this.mutexBits; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityAIBeg.java b/sp-server/src/main/java/net/minecraft/src/EntityAIBeg.java new file mode 100644 index 0000000..d8080c1 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityAIBeg.java @@ -0,0 +1,70 @@ +package net.minecraft.src; + +public class EntityAIBeg extends EntityAIBase { + private EntityWolf theWolf; + private EntityPlayer thePlayer; + private World worldObject; + private float minPlayerDistance; + private int field_75384_e; + + public EntityAIBeg(EntityWolf par1EntityWolf, float par2) { + this.theWolf = par1EntityWolf; + this.worldObject = par1EntityWolf.worldObj; + this.minPlayerDistance = par2; + this.setMutexBits(2); + } + + /** + * Returns whether the EntityAIBase should begin execution. + */ + public boolean shouldExecute() { + this.thePlayer = this.worldObject.getClosestPlayerToEntity(this.theWolf, (double) this.minPlayerDistance); + return this.thePlayer == null ? false : this.hasPlayerGotBoneInHand(this.thePlayer); + } + + /** + * Returns whether an in-progress EntityAIBase should continue executing + */ + public boolean continueExecuting() { + return !this.thePlayer.isEntityAlive() ? false + : (this.theWolf.getDistanceSqToEntity( + this.thePlayer) > (double) (this.minPlayerDistance * this.minPlayerDistance) ? false + : this.field_75384_e > 0 && this.hasPlayerGotBoneInHand(this.thePlayer)); + } + + /** + * Execute a one shot task or start executing a continuous task + */ + public void startExecuting() { + this.theWolf.func_70918_i(true); + this.field_75384_e = 40 + this.theWolf.getRNG().nextInt(40); + } + + /** + * Resets the task + */ + public void resetTask() { + this.theWolf.func_70918_i(false); + this.thePlayer = null; + } + + /** + * Updates the task + */ + public void updateTask() { + this.theWolf.getLookHelper().setLookPosition(this.thePlayer.posX, + this.thePlayer.posY + (double) this.thePlayer.getEyeHeight(), this.thePlayer.posZ, 10.0F, + (float) this.theWolf.getVerticalFaceSpeed()); + --this.field_75384_e; + } + + /** + * Gets if the Player has the Bone in the hand. + */ + private boolean hasPlayerGotBoneInHand(EntityPlayer par1EntityPlayer) { + ItemStack var2 = par1EntityPlayer.inventory.getCurrentItem(); + return var2 == null ? false + : (!this.theWolf.isTamed() && var2.itemID == Item.bone.itemID ? true + : this.theWolf.isBreedingItem(var2)); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityAIBreakDoor.java b/sp-server/src/main/java/net/minecraft/src/EntityAIBreakDoor.java new file mode 100644 index 0000000..f82e42c --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityAIBreakDoor.java @@ -0,0 +1,74 @@ +package net.minecraft.src; + +public class EntityAIBreakDoor extends EntityAIDoorInteract { + private int breakingTime; + private int field_75358_j = -1; + + public EntityAIBreakDoor(EntityLiving par1EntityLiving) { + super(par1EntityLiving); + } + + /** + * Returns whether the EntityAIBase should begin execution. + */ + public boolean shouldExecute() { + return !super.shouldExecute() ? false + : (!this.theEntity.worldObj.getGameRules().getGameRuleBooleanValue("mobGriefing") ? false + : !this.targetDoor.isDoorOpen(this.theEntity.worldObj, this.entityPosX, this.entityPosY, + this.entityPosZ)); + } + + /** + * Execute a one shot task or start executing a continuous task + */ + public void startExecuting() { + super.startExecuting(); + this.breakingTime = 0; + } + + /** + * Returns whether an in-progress EntityAIBase should continue executing + */ + public boolean continueExecuting() { + double var1 = this.theEntity.getDistanceSq((double) this.entityPosX, (double) this.entityPosY, + (double) this.entityPosZ); + return this.breakingTime <= 240 && !this.targetDoor.isDoorOpen(this.theEntity.worldObj, this.entityPosX, + this.entityPosY, this.entityPosZ) && var1 < 4.0D; + } + + /** + * Resets the task + */ + public void resetTask() { + super.resetTask(); + this.theEntity.worldObj.destroyBlockInWorldPartially(this.theEntity.entityId, this.entityPosX, this.entityPosY, + this.entityPosZ, -1); + } + + /** + * Updates the task + */ + public void updateTask() { + super.updateTask(); + + if (this.theEntity.getRNG().nextInt(20) == 0) { + this.theEntity.worldObj.playAuxSFX(1010, this.entityPosX, this.entityPosY, this.entityPosZ, 0); + } + + ++this.breakingTime; + int var1 = (int) ((float) this.breakingTime / 240.0F * 10.0F); + + if (var1 != this.field_75358_j) { + this.theEntity.worldObj.destroyBlockInWorldPartially(this.theEntity.entityId, this.entityPosX, + this.entityPosY, this.entityPosZ, var1); + this.field_75358_j = var1; + } + + if (this.breakingTime == 240 && this.theEntity.worldObj.difficultySetting == 3) { + this.theEntity.worldObj.setBlockToAir(this.entityPosX, this.entityPosY, this.entityPosZ); + this.theEntity.worldObj.playAuxSFX(1012, this.entityPosX, this.entityPosY, this.entityPosZ, 0); + this.theEntity.worldObj.playAuxSFX(2001, this.entityPosX, this.entityPosY, this.entityPosZ, + this.targetDoor.blockID); + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityAIControlledByPlayer.java b/sp-server/src/main/java/net/minecraft/src/EntityAIControlledByPlayer.java new file mode 100644 index 0000000..b8fd495 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityAIControlledByPlayer.java @@ -0,0 +1,198 @@ +package net.minecraft.src; + +public class EntityAIControlledByPlayer extends EntityAIBase { + private final EntityLiving thisEntity; + private final float maxSpeed; + private float currentSpeed = 0.0F; + + /** Whether the entity's speed is boosted. */ + private boolean speedBoosted = false; + + /** + * Counter for speed boosting, upon reaching maxSpeedBoostTime the speed boost + * will be disabled + */ + private int speedBoostTime = 0; + + /** Maximum time the entity's speed should be boosted for. */ + private int maxSpeedBoostTime = 0; + + public EntityAIControlledByPlayer(EntityLiving par1EntityLiving, float par2) { + this.thisEntity = par1EntityLiving; + this.maxSpeed = par2; + this.setMutexBits(7); + } + + /** + * Execute a one shot task or start executing a continuous task + */ + public void startExecuting() { + this.currentSpeed = 0.0F; + } + + /** + * Resets the task + */ + public void resetTask() { + this.speedBoosted = false; + this.currentSpeed = 0.0F; + } + + /** + * Returns whether the EntityAIBase should begin execution. + */ + public boolean shouldExecute() { + return this.thisEntity.isEntityAlive() && this.thisEntity.riddenByEntity != null + && this.thisEntity.riddenByEntity instanceof EntityPlayer + && (this.speedBoosted || this.thisEntity.canBeSteered()); + } + + /** + * Updates the task + */ + public void updateTask() { + EntityPlayer var1 = (EntityPlayer) this.thisEntity.riddenByEntity; + EntityCreature var2 = (EntityCreature) this.thisEntity; + float var3 = MathHelper.wrapAngleTo180_float(var1.rotationYaw - this.thisEntity.rotationYaw) * 0.5F; + + if (var3 > 5.0F) { + var3 = 5.0F; + } + + if (var3 < -5.0F) { + var3 = -5.0F; + } + + this.thisEntity.rotationYaw = MathHelper.wrapAngleTo180_float(this.thisEntity.rotationYaw + var3); + + if (this.currentSpeed < this.maxSpeed) { + this.currentSpeed += (this.maxSpeed - this.currentSpeed) * 0.01F; + } + + if (this.currentSpeed > this.maxSpeed) { + this.currentSpeed = this.maxSpeed; + } + + int var4 = MathHelper.floor_double(this.thisEntity.posX); + int var5 = MathHelper.floor_double(this.thisEntity.posY); + int var6 = MathHelper.floor_double(this.thisEntity.posZ); + float var7 = this.currentSpeed; + + if (this.speedBoosted) { + if (this.speedBoostTime++ > this.maxSpeedBoostTime) { + this.speedBoosted = false; + } + + var7 += var7 * 1.15F + * MathHelper.sin((float) this.speedBoostTime / (float) this.maxSpeedBoostTime * (float) Math.PI); + } + + float var8 = 0.91F; + + if (this.thisEntity.onGround) { + var8 = 0.54600006F; + int var9 = this.thisEntity.worldObj.getBlockId(MathHelper.floor_float((float) var4), + MathHelper.floor_float((float) var5) - 1, MathHelper.floor_float((float) var6)); + + if (var9 > 0) { + var8 = Block.blocksList[var9].slipperiness * 0.91F; + } + } + + float var23 = 0.16277136F / (var8 * var8 * var8); + float var10 = MathHelper.sin(var2.rotationYaw * (float) Math.PI / 180.0F); + float var11 = MathHelper.cos(var2.rotationYaw * (float) Math.PI / 180.0F); + float var12 = var2.getAIMoveSpeed() * var23; + float var13 = Math.max(var7, 1.0F); + var13 = var12 / var13; + float var14 = var7 * var13; + float var15 = -(var14 * var10); + float var16 = var14 * var11; + + if (MathHelper.abs(var15) > MathHelper.abs(var16)) { + if (var15 < 0.0F) { + var15 -= this.thisEntity.width / 2.0F; + } + + if (var15 > 0.0F) { + var15 += this.thisEntity.width / 2.0F; + } + + var16 = 0.0F; + } else { + var15 = 0.0F; + + if (var16 < 0.0F) { + var16 -= this.thisEntity.width / 2.0F; + } + + if (var16 > 0.0F) { + var16 += this.thisEntity.width / 2.0F; + } + } + + int var17 = MathHelper.floor_double(this.thisEntity.posX + (double) var15); + int var18 = MathHelper.floor_double(this.thisEntity.posZ + (double) var16); + PathPoint var19 = new PathPoint(MathHelper.floor_float(this.thisEntity.width + 1.0F), + MathHelper.floor_float(this.thisEntity.height + var1.height + 1.0F), + MathHelper.floor_float(this.thisEntity.width + 1.0F)); + + if (var4 != var17 || var6 != var18) { + int var20 = this.thisEntity.worldObj.getBlockId(var4, var5, var6); + int var21 = this.thisEntity.worldObj.getBlockId(var4, var5 - 1, var6); + boolean var22 = this.func_98216_b(var20) || Block.blocksList[var20] == null && this.func_98216_b(var21); + + if (!var22 && PathFinder.func_82565_a(this.thisEntity, var17, var5, var18, var19, false, false, true) == 0 + && PathFinder.func_82565_a(this.thisEntity, var4, var5 + 1, var6, var19, false, false, true) == 1 + && PathFinder.func_82565_a(this.thisEntity, var17, var5 + 1, var18, var19, false, false, + true) == 1) { + var2.getJumpHelper().setJumping(); + } + } + + if (!var1.capabilities.isCreativeMode && this.currentSpeed >= this.maxSpeed * 0.5F + && this.thisEntity.getRNG().nextFloat() < 0.006F && !this.speedBoosted) { + ItemStack var24 = var1.getHeldItem(); + + if (var24 != null && var24.itemID == Item.carrotOnAStick.itemID) { + var24.damageItem(1, var1); + + if (var24.stackSize == 0) { + ItemStack var25 = new ItemStack(Item.fishingRod); + var25.setTagCompound(var24.stackTagCompound); + var1.inventory.mainInventory[var1.inventory.currentItem] = var25; + } + } + } + + this.thisEntity.moveEntityWithHeading(0.0F, var7); + } + + private boolean func_98216_b(int par1) { + return Block.blocksList[par1] != null + && (Block.blocksList[par1].getRenderType() == 10 || Block.blocksList[par1] instanceof BlockHalfSlab); + } + + /** + * Return whether the entity's speed is boosted. + */ + public boolean isSpeedBoosted() { + return this.speedBoosted; + } + + /** + * Boost the entity's movement speed. + */ + public void boostSpeed() { + this.speedBoosted = true; + this.speedBoostTime = 0; + this.maxSpeedBoostTime = this.thisEntity.getRNG().nextInt(841) + 140; + } + + /** + * Return whether the entity is being controlled by a player. + */ + public boolean isControlledByPlayer() { + return !this.isSpeedBoosted() && this.currentSpeed > this.maxSpeed * 0.3F; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityAICreeperSwell.java b/sp-server/src/main/java/net/minecraft/src/EntityAICreeperSwell.java new file mode 100644 index 0000000..9e80db2 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityAICreeperSwell.java @@ -0,0 +1,56 @@ +package net.minecraft.src; + +public class EntityAICreeperSwell extends EntityAIBase { + /** The creeper that is swelling. */ + EntityCreeper swellingCreeper; + + /** + * The creeper's attack target. This is used for the changing of the creeper's + * state. + */ + EntityLiving creeperAttackTarget; + + public EntityAICreeperSwell(EntityCreeper par1EntityCreeper) { + this.swellingCreeper = par1EntityCreeper; + this.setMutexBits(1); + } + + /** + * Returns whether the EntityAIBase should begin execution. + */ + public boolean shouldExecute() { + EntityLiving var1 = this.swellingCreeper.getAttackTarget(); + return this.swellingCreeper.getCreeperState() > 0 + || var1 != null && this.swellingCreeper.getDistanceSqToEntity(var1) < 9.0D; + } + + /** + * Execute a one shot task or start executing a continuous task + */ + public void startExecuting() { + this.swellingCreeper.getNavigator().clearPathEntity(); + this.creeperAttackTarget = this.swellingCreeper.getAttackTarget(); + } + + /** + * Resets the task + */ + public void resetTask() { + this.creeperAttackTarget = null; + } + + /** + * Updates the task + */ + public void updateTask() { + if (this.creeperAttackTarget == null) { + this.swellingCreeper.setCreeperState(-1); + } else if (this.swellingCreeper.getDistanceSqToEntity(this.creeperAttackTarget) > 49.0D) { + this.swellingCreeper.setCreeperState(-1); + } else if (!this.swellingCreeper.getEntitySenses().canSee(this.creeperAttackTarget)) { + this.swellingCreeper.setCreeperState(-1); + } else { + this.swellingCreeper.setCreeperState(1); + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityAIDefendVillage.java b/sp-server/src/main/java/net/minecraft/src/EntityAIDefendVillage.java new file mode 100644 index 0000000..bfa8121 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityAIDefendVillage.java @@ -0,0 +1,49 @@ +package net.minecraft.src; + +public class EntityAIDefendVillage extends EntityAITarget { + EntityIronGolem irongolem; + + /** + * The aggressor of the iron golem's village which is now the golem's attack + * target. + */ + EntityLiving villageAgressorTarget; + + public EntityAIDefendVillage(EntityIronGolem par1EntityIronGolem) { + super(par1EntityIronGolem, 16.0F, false, true); + this.irongolem = par1EntityIronGolem; + this.setMutexBits(1); + } + + /** + * Returns whether the EntityAIBase should begin execution. + */ + public boolean shouldExecute() { + Village var1 = this.irongolem.getVillage(); + + if (var1 == null) { + return false; + } else { + this.villageAgressorTarget = var1.findNearestVillageAggressor(this.irongolem); + + if (!this.isSuitableTarget(this.villageAgressorTarget, false)) { + if (this.taskOwner.getRNG().nextInt(20) == 0) { + this.villageAgressorTarget = var1.func_82685_c(this.irongolem); + return this.isSuitableTarget(this.villageAgressorTarget, false); + } else { + return false; + } + } else { + return true; + } + } + } + + /** + * Execute a one shot task or start executing a continuous task + */ + public void startExecuting() { + this.irongolem.setAttackTarget(this.villageAgressorTarget); + super.startExecuting(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityAIDoorInteract.java b/sp-server/src/main/java/net/minecraft/src/EntityAIDoorInteract.java new file mode 100644 index 0000000..4c3babf --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityAIDoorInteract.java @@ -0,0 +1,97 @@ +package net.minecraft.src; + +public abstract class EntityAIDoorInteract extends EntityAIBase { + protected EntityLiving theEntity; + protected int entityPosX; + protected int entityPosY; + protected int entityPosZ; + protected BlockDoor targetDoor; + + /** + * If is true then the Entity has stopped Door Interaction and compoleted the + * task. + */ + boolean hasStoppedDoorInteraction; + float entityPositionX; + float entityPositionZ; + + public EntityAIDoorInteract(EntityLiving par1EntityLiving) { + this.theEntity = par1EntityLiving; + } + + /** + * Returns whether the EntityAIBase should begin execution. + */ + public boolean shouldExecute() { + if (!this.theEntity.isCollidedHorizontally) { + return false; + } else { + PathNavigate var1 = this.theEntity.getNavigator(); + PathEntity var2 = var1.getPath(); + + if (var2 != null && !var2.isFinished() && var1.getCanBreakDoors()) { + for (int var3 = 0; var3 < Math.min(var2.getCurrentPathIndex() + 2, + var2.getCurrentPathLength()); ++var3) { + PathPoint var4 = var2.getPathPointFromIndex(var3); + this.entityPosX = var4.xCoord; + this.entityPosY = var4.yCoord + 1; + this.entityPosZ = var4.zCoord; + + if (this.theEntity.getDistanceSq((double) this.entityPosX, this.theEntity.posY, + (double) this.entityPosZ) <= 2.25D) { + this.targetDoor = this.findUsableDoor(this.entityPosX, this.entityPosY, this.entityPosZ); + + if (this.targetDoor != null) { + return true; + } + } + } + + this.entityPosX = MathHelper.floor_double(this.theEntity.posX); + this.entityPosY = MathHelper.floor_double(this.theEntity.posY + 1.0D); + this.entityPosZ = MathHelper.floor_double(this.theEntity.posZ); + this.targetDoor = this.findUsableDoor(this.entityPosX, this.entityPosY, this.entityPosZ); + return this.targetDoor != null; + } else { + return false; + } + } + } + + /** + * Returns whether an in-progress EntityAIBase should continue executing + */ + public boolean continueExecuting() { + return !this.hasStoppedDoorInteraction; + } + + /** + * Execute a one shot task or start executing a continuous task + */ + public void startExecuting() { + this.hasStoppedDoorInteraction = false; + this.entityPositionX = (float) ((double) ((float) this.entityPosX + 0.5F) - this.theEntity.posX); + this.entityPositionZ = (float) ((double) ((float) this.entityPosZ + 0.5F) - this.theEntity.posZ); + } + + /** + * Updates the task + */ + public void updateTask() { + float var1 = (float) ((double) ((float) this.entityPosX + 0.5F) - this.theEntity.posX); + float var2 = (float) ((double) ((float) this.entityPosZ + 0.5F) - this.theEntity.posZ); + float var3 = this.entityPositionX * var1 + this.entityPositionZ * var2; + + if (var3 < 0.0F) { + this.hasStoppedDoorInteraction = true; + } + } + + /** + * Determines if a door can be broken with AI. + */ + private BlockDoor findUsableDoor(int par1, int par2, int par3) { + int var4 = this.theEntity.worldObj.getBlockId(par1, par2, par3); + return var4 != Block.doorWood.blockID ? null : (BlockDoor) Block.blocksList[var4]; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityAIEatGrass.java b/sp-server/src/main/java/net/minecraft/src/EntityAIEatGrass.java new file mode 100644 index 0000000..8901170 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityAIEatGrass.java @@ -0,0 +1,80 @@ +package net.minecraft.src; + +public class EntityAIEatGrass extends EntityAIBase { + private EntityLiving theEntity; + private World theWorld; + + /** A decrementing tick used for the sheep's head offset and animation. */ + int eatGrassTick = 0; + + public EntityAIEatGrass(EntityLiving par1EntityLiving) { + this.theEntity = par1EntityLiving; + this.theWorld = par1EntityLiving.worldObj; + this.setMutexBits(7); + } + + /** + * Returns whether the EntityAIBase should begin execution. + */ + public boolean shouldExecute() { + if (this.theEntity.getRNG().nextInt(this.theEntity.isChild() ? 50 : 1000) != 0) { + return false; + } else { + int var1 = MathHelper.floor_double(this.theEntity.posX); + int var2 = MathHelper.floor_double(this.theEntity.posY); + int var3 = MathHelper.floor_double(this.theEntity.posZ); + return this.theWorld.getBlockId(var1, var2, var3) == Block.tallGrass.blockID + && this.theWorld.getBlockMetadata(var1, var2, var3) == 1 ? true + : this.theWorld.getBlockId(var1, var2 - 1, var3) == Block.grass.blockID; + } + } + + /** + * Execute a one shot task or start executing a continuous task + */ + public void startExecuting() { + this.eatGrassTick = 40; + this.theWorld.setEntityState(this.theEntity, (byte) 10); + this.theEntity.getNavigator().clearPathEntity(); + } + + /** + * Resets the task + */ + public void resetTask() { + this.eatGrassTick = 0; + } + + /** + * Returns whether an in-progress EntityAIBase should continue executing + */ + public boolean continueExecuting() { + return this.eatGrassTick > 0; + } + + public int getEatGrassTick() { + return this.eatGrassTick; + } + + /** + * Updates the task + */ + public void updateTask() { + this.eatGrassTick = Math.max(0, this.eatGrassTick - 1); + + if (this.eatGrassTick == 4) { + int var1 = MathHelper.floor_double(this.theEntity.posX); + int var2 = MathHelper.floor_double(this.theEntity.posY); + int var3 = MathHelper.floor_double(this.theEntity.posZ); + + if (this.theWorld.getBlockId(var1, var2, var3) == Block.tallGrass.blockID) { + this.theWorld.destroyBlock(var1, var2, var3, false); + this.theEntity.eatGrassBonus(); + } else if (this.theWorld.getBlockId(var1, var2 - 1, var3) == Block.grass.blockID) { + this.theWorld.playAuxSFX(2001, var1, var2 - 1, var3, Block.grass.blockID); + this.theWorld.setBlock(var1, var2 - 1, var3, Block.dirt.blockID, 0, 2); + this.theEntity.eatGrassBonus(); + } + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityAIFleeSun.java b/sp-server/src/main/java/net/minecraft/src/EntityAIFleeSun.java new file mode 100644 index 0000000..488502e --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityAIFleeSun.java @@ -0,0 +1,75 @@ +package net.minecraft.src; + +import java.util.Random; + +public class EntityAIFleeSun extends EntityAIBase { + private EntityCreature theCreature; + private double shelterX; + private double shelterY; + private double shelterZ; + private float movementSpeed; + private World theWorld; + + public EntityAIFleeSun(EntityCreature par1EntityCreature, float par2) { + this.theCreature = par1EntityCreature; + this.movementSpeed = par2; + this.theWorld = par1EntityCreature.worldObj; + this.setMutexBits(1); + } + + /** + * Returns whether the EntityAIBase should begin execution. + */ + public boolean shouldExecute() { + if (!this.theWorld.isDaytime()) { + return false; + } else if (!this.theCreature.isBurning()) { + return false; + } else if (!this.theWorld.canBlockSeeTheSky(MathHelper.floor_double(this.theCreature.posX), + (int) this.theCreature.boundingBox.minY, MathHelper.floor_double(this.theCreature.posZ))) { + return false; + } else { + Vec3 var1 = this.findPossibleShelter(); + + if (var1 == null) { + return false; + } else { + this.shelterX = var1.xCoord; + this.shelterY = var1.yCoord; + this.shelterZ = var1.zCoord; + return true; + } + } + } + + /** + * Returns whether an in-progress EntityAIBase should continue executing + */ + public boolean continueExecuting() { + return !this.theCreature.getNavigator().noPath(); + } + + /** + * Execute a one shot task or start executing a continuous task + */ + public void startExecuting() { + this.theCreature.getNavigator().tryMoveToXYZ(this.shelterX, this.shelterY, this.shelterZ, this.movementSpeed); + } + + private Vec3 findPossibleShelter() { + Random var1 = this.theCreature.getRNG(); + + for (int var2 = 0; var2 < 10; ++var2) { + int var3 = MathHelper.floor_double(this.theCreature.posX + (double) var1.nextInt(20) - 10.0D); + int var4 = MathHelper.floor_double(this.theCreature.boundingBox.minY + (double) var1.nextInt(6) - 3.0D); + int var5 = MathHelper.floor_double(this.theCreature.posZ + (double) var1.nextInt(20) - 10.0D); + + if (!this.theWorld.canBlockSeeTheSky(var3, var4, var5) + && this.theCreature.getBlockPathWeight(var3, var4, var5) < 0.0F) { + return this.theWorld.getWorldVec3Pool().getVecFromPool((double) var3, (double) var4, (double) var5); + } + } + + return null; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityAIFollowGolem.java b/sp-server/src/main/java/net/minecraft/src/EntityAIFollowGolem.java new file mode 100644 index 0000000..34acc6b --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityAIFollowGolem.java @@ -0,0 +1,88 @@ +package net.minecraft.src; + +import java.util.Iterator; +import java.util.List; + +public class EntityAIFollowGolem extends EntityAIBase { + private EntityVillager theVillager; + private EntityIronGolem theGolem; + private int takeGolemRoseTick; + private boolean tookGolemRose = false; + + public EntityAIFollowGolem(EntityVillager par1EntityVillager) { + this.theVillager = par1EntityVillager; + this.setMutexBits(3); + } + + /** + * Returns whether the EntityAIBase should begin execution. + */ + public boolean shouldExecute() { + if (this.theVillager.getGrowingAge() >= 0) { + return false; + } else if (!this.theVillager.worldObj.isDaytime()) { + return false; + } else { + List var1 = this.theVillager.worldObj.getEntitiesWithinAABB(EntityIronGolem.class, + this.theVillager.boundingBox.expand(6.0D, 2.0D, 6.0D)); + + if (var1.isEmpty()) { + return false; + } else { + Iterator var2 = var1.iterator(); + + while (var2.hasNext()) { + EntityIronGolem var3 = (EntityIronGolem) var2.next(); + + if (var3.getHoldRoseTick() > 0) { + this.theGolem = var3; + break; + } + } + + return this.theGolem != null; + } + } + } + + /** + * Returns whether an in-progress EntityAIBase should continue executing + */ + public boolean continueExecuting() { + return this.theGolem.getHoldRoseTick() > 0; + } + + /** + * Execute a one shot task or start executing a continuous task + */ + public void startExecuting() { + this.takeGolemRoseTick = this.theVillager.getRNG().nextInt(320); + this.tookGolemRose = false; + this.theGolem.getNavigator().clearPathEntity(); + } + + /** + * Resets the task + */ + public void resetTask() { + this.theGolem = null; + this.theVillager.getNavigator().clearPathEntity(); + } + + /** + * Updates the task + */ + public void updateTask() { + this.theVillager.getLookHelper().setLookPositionWithEntity(this.theGolem, 30.0F, 30.0F); + + if (this.theGolem.getHoldRoseTick() == this.takeGolemRoseTick) { + this.theVillager.getNavigator().tryMoveToEntityLiving(this.theGolem, 0.15F); + this.tookGolemRose = true; + } + + if (this.tookGolemRose && this.theVillager.getDistanceSqToEntity(this.theGolem) < 4.0D) { + this.theGolem.setHoldingRose(false); + this.theVillager.getNavigator().clearPathEntity(); + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityAIFollowOwner.java b/sp-server/src/main/java/net/minecraft/src/EntityAIFollowOwner.java new file mode 100644 index 0000000..bff6142 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityAIFollowOwner.java @@ -0,0 +1,106 @@ +package net.minecraft.src; + +public class EntityAIFollowOwner extends EntityAIBase { + private EntityTameable thePet; + private EntityLiving theOwner; + World theWorld; + private float field_75336_f; + private PathNavigate petPathfinder; + private int field_75343_h; + float maxDist; + float minDist; + private boolean field_75344_i; + + public EntityAIFollowOwner(EntityTameable par1EntityTameable, float par2, float par3, float par4) { + this.thePet = par1EntityTameable; + this.theWorld = par1EntityTameable.worldObj; + this.field_75336_f = par2; + this.petPathfinder = par1EntityTameable.getNavigator(); + this.minDist = par3; + this.maxDist = par4; + this.setMutexBits(3); + } + + /** + * Returns whether the EntityAIBase should begin execution. + */ + public boolean shouldExecute() { + EntityLiving var1 = this.thePet.getOwner(); + + if (var1 == null) { + return false; + } else if (this.thePet.isSitting()) { + return false; + } else if (this.thePet.getDistanceSqToEntity(var1) < (double) (this.minDist * this.minDist)) { + return false; + } else { + this.theOwner = var1; + return true; + } + } + + /** + * Returns whether an in-progress EntityAIBase should continue executing + */ + public boolean continueExecuting() { + return !this.petPathfinder.noPath() + && this.thePet.getDistanceSqToEntity(this.theOwner) > (double) (this.maxDist * this.maxDist) + && !this.thePet.isSitting(); + } + + /** + * Execute a one shot task or start executing a continuous task + */ + public void startExecuting() { + this.field_75343_h = 0; + this.field_75344_i = this.thePet.getNavigator().getAvoidsWater(); + this.thePet.getNavigator().setAvoidsWater(false); + } + + /** + * Resets the task + */ + public void resetTask() { + this.theOwner = null; + this.petPathfinder.clearPathEntity(); + this.thePet.getNavigator().setAvoidsWater(this.field_75344_i); + } + + /** + * Updates the task + */ + public void updateTask() { + this.thePet.getLookHelper().setLookPositionWithEntity(this.theOwner, 10.0F, + (float) this.thePet.getVerticalFaceSpeed()); + + if (!this.thePet.isSitting()) { + if (--this.field_75343_h <= 0) { + this.field_75343_h = 10; + + if (!this.petPathfinder.tryMoveToEntityLiving(this.theOwner, this.field_75336_f)) { + if (this.thePet.getDistanceSqToEntity(this.theOwner) >= 144.0D) { + int var1 = MathHelper.floor_double(this.theOwner.posX) - 2; + int var2 = MathHelper.floor_double(this.theOwner.posZ) - 2; + int var3 = MathHelper.floor_double(this.theOwner.boundingBox.minY); + + for (int var4 = 0; var4 <= 4; ++var4) { + for (int var5 = 0; var5 <= 4; ++var5) { + if ((var4 < 1 || var5 < 1 || var4 > 3 || var5 > 3) + && this.theWorld.doesBlockHaveSolidTopSurface(var1 + var4, var3 - 1, + var2 + var5) + && !this.theWorld.isBlockNormalCube(var1 + var4, var3, var2 + var5) + && !this.theWorld.isBlockNormalCube(var1 + var4, var3 + 1, var2 + var5)) { + this.thePet.setLocationAndAngles((double) ((float) (var1 + var4) + 0.5F), + (double) var3, (double) ((float) (var2 + var5) + 0.5F), + this.thePet.rotationYaw, this.thePet.rotationPitch); + this.petPathfinder.clearPathEntity(); + return; + } + } + } + } + } + } + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityAIFollowParent.java b/sp-server/src/main/java/net/minecraft/src/EntityAIFollowParent.java new file mode 100644 index 0000000..5d4d9e1 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityAIFollowParent.java @@ -0,0 +1,90 @@ +package net.minecraft.src; + +import java.util.Iterator; +import java.util.List; + +public class EntityAIFollowParent extends EntityAIBase { + /** The child that is following its parent. */ + EntityAnimal childAnimal; + EntityAnimal parentAnimal; + float field_75347_c; + private int field_75345_d; + + public EntityAIFollowParent(EntityAnimal par1EntityAnimal, float par2) { + this.childAnimal = par1EntityAnimal; + this.field_75347_c = par2; + } + + /** + * Returns whether the EntityAIBase should begin execution. + */ + public boolean shouldExecute() { + if (this.childAnimal.getGrowingAge() >= 0) { + return false; + } else { + List var1 = this.childAnimal.worldObj.getEntitiesWithinAABB(this.childAnimal.getClass(), + this.childAnimal.boundingBox.expand(8.0D, 4.0D, 8.0D)); + EntityAnimal var2 = null; + double var3 = Double.MAX_VALUE; + Iterator var5 = var1.iterator(); + + while (var5.hasNext()) { + EntityAnimal var6 = (EntityAnimal) var5.next(); + + if (var6.getGrowingAge() >= 0) { + double var7 = this.childAnimal.getDistanceSqToEntity(var6); + + if (var7 <= var3) { + var3 = var7; + var2 = var6; + } + } + } + + if (var2 == null) { + return false; + } else if (var3 < 9.0D) { + return false; + } else { + this.parentAnimal = var2; + return true; + } + } + } + + /** + * Returns whether an in-progress EntityAIBase should continue executing + */ + public boolean continueExecuting() { + if (!this.parentAnimal.isEntityAlive()) { + return false; + } else { + double var1 = this.childAnimal.getDistanceSqToEntity(this.parentAnimal); + return var1 >= 9.0D && var1 <= 256.0D; + } + } + + /** + * Execute a one shot task or start executing a continuous task + */ + public void startExecuting() { + this.field_75345_d = 0; + } + + /** + * Resets the task + */ + public void resetTask() { + this.parentAnimal = null; + } + + /** + * Updates the task + */ + public void updateTask() { + if (--this.field_75345_d <= 0) { + this.field_75345_d = 10; + this.childAnimal.getNavigator().tryMoveToEntityLiving(this.parentAnimal, this.field_75347_c); + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityAIHurtByTarget.java b/sp-server/src/main/java/net/minecraft/src/EntityAIHurtByTarget.java new file mode 100644 index 0000000..feee351 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityAIHurtByTarget.java @@ -0,0 +1,68 @@ +package net.minecraft.src; + +import java.util.Iterator; +import java.util.List; + +public class EntityAIHurtByTarget extends EntityAITarget { + boolean field_75312_a; + + /** The PathNavigate of our entity. */ + EntityLiving entityPathNavigate; + + public EntityAIHurtByTarget(EntityLiving par1EntityLiving, boolean par2) { + super(par1EntityLiving, 16.0F, false); + this.field_75312_a = par2; + this.setMutexBits(1); + } + + /** + * Returns whether the EntityAIBase should begin execution. + */ + public boolean shouldExecute() { + return this.isSuitableTarget(this.taskOwner.getAITarget(), true); + } + + /** + * Returns whether an in-progress EntityAIBase should continue executing + */ + public boolean continueExecuting() { + return this.taskOwner.getAITarget() != null && this.taskOwner.getAITarget() != this.entityPathNavigate; + } + + /** + * Execute a one shot task or start executing a continuous task + */ + public void startExecuting() { + this.taskOwner.setAttackTarget(this.taskOwner.getAITarget()); + this.entityPathNavigate = this.taskOwner.getAITarget(); + + if (this.field_75312_a) { + List var1 = this.taskOwner.worldObj.getEntitiesWithinAABB(this.taskOwner.getClass(), + AxisAlignedBB.getAABBPool() + .getAABB(this.taskOwner.posX, this.taskOwner.posY, this.taskOwner.posZ, + this.taskOwner.posX + 1.0D, this.taskOwner.posY + 1.0D, this.taskOwner.posZ + 1.0D) + .expand((double) this.targetDistance, 10.0D, (double) this.targetDistance)); + Iterator var2 = var1.iterator(); + + while (var2.hasNext()) { + EntityLiving var3 = (EntityLiving) var2.next(); + + if (this.taskOwner != var3 && var3.getAttackTarget() == null) { + var3.setAttackTarget(this.taskOwner.getAITarget()); + } + } + } + + super.startExecuting(); + } + + /** + * Resets the task + */ + public void resetTask() { + if (this.taskOwner.getAttackTarget() != null && this.taskOwner.getAttackTarget() instanceof EntityPlayer + && ((EntityPlayer) this.taskOwner.getAttackTarget()).capabilities.disableDamage) { + super.resetTask(); + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityAILeapAtTarget.java b/sp-server/src/main/java/net/minecraft/src/EntityAILeapAtTarget.java new file mode 100644 index 0000000..83cdcde --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityAILeapAtTarget.java @@ -0,0 +1,55 @@ +package net.minecraft.src; + +public class EntityAILeapAtTarget extends EntityAIBase { + /** The entity that is leaping. */ + EntityLiving leaper; + + /** The entity that the leaper is leaping towards. */ + EntityLiving leapTarget; + + /** The entity's motionY after leaping. */ + float leapMotionY; + + public EntityAILeapAtTarget(EntityLiving par1EntityLiving, float par2) { + this.leaper = par1EntityLiving; + this.leapMotionY = par2; + this.setMutexBits(5); + } + + /** + * Returns whether the EntityAIBase should begin execution. + */ + public boolean shouldExecute() { + this.leapTarget = this.leaper.getAttackTarget(); + + if (this.leapTarget == null) { + return false; + } else { + double var1 = this.leaper.getDistanceSqToEntity(this.leapTarget); + return var1 >= 4.0D && var1 <= 16.0D + ? (!this.leaper.onGround ? false : this.leaper.getRNG().nextInt(5) == 0) + : false; + } + } + + /** + * Returns whether an in-progress EntityAIBase should continue executing + */ + public boolean continueExecuting() { + return !this.leaper.onGround; + } + + /** + * Execute a one shot task or start executing a continuous task + */ + public void startExecuting() { + double var1 = this.leapTarget.posX - this.leaper.posX; + double var3 = this.leapTarget.posZ - this.leaper.posZ; + float var5 = MathHelper.sqrt_double(var1 * var1 + var3 * var3); + this.leaper.motionX += var1 / (double) var5 * 0.5D * 0.800000011920929D + + this.leaper.motionX * 0.20000000298023224D; + this.leaper.motionZ += var3 / (double) var5 * 0.5D * 0.800000011920929D + + this.leaper.motionZ * 0.20000000298023224D; + this.leaper.motionY = (double) this.leapMotionY; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityAILookAtTradePlayer.java b/sp-server/src/main/java/net/minecraft/src/EntityAILookAtTradePlayer.java new file mode 100644 index 0000000..c0d438a --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityAILookAtTradePlayer.java @@ -0,0 +1,22 @@ +package net.minecraft.src; + +public class EntityAILookAtTradePlayer extends EntityAIWatchClosest { + private final EntityVillager theMerchant; + + public EntityAILookAtTradePlayer(EntityVillager par1EntityVillager) { + super(par1EntityVillager, EntityPlayer.class, 8.0F); + this.theMerchant = par1EntityVillager; + } + + /** + * Returns whether the EntityAIBase should begin execution. + */ + public boolean shouldExecute() { + if (this.theMerchant.isTrading()) { + this.closestEntity = this.theMerchant.getCustomer(); + return true; + } else { + return false; + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityAILookAtVillager.java b/sp-server/src/main/java/net/minecraft/src/EntityAILookAtVillager.java new file mode 100644 index 0000000..37c4ab5 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityAILookAtVillager.java @@ -0,0 +1,58 @@ +package net.minecraft.src; + +public class EntityAILookAtVillager extends EntityAIBase { + private EntityIronGolem theGolem; + private EntityVillager theVillager; + private int lookTime; + + public EntityAILookAtVillager(EntityIronGolem par1EntityIronGolem) { + this.theGolem = par1EntityIronGolem; + this.setMutexBits(3); + } + + /** + * Returns whether the EntityAIBase should begin execution. + */ + public boolean shouldExecute() { + if (!this.theGolem.worldObj.isDaytime()) { + return false; + } else if (this.theGolem.getRNG().nextInt(8000) != 0) { + return false; + } else { + this.theVillager = (EntityVillager) this.theGolem.worldObj.findNearestEntityWithinAABB(EntityVillager.class, + this.theGolem.boundingBox.expand(6.0D, 2.0D, 6.0D), this.theGolem); + return this.theVillager != null; + } + } + + /** + * Returns whether an in-progress EntityAIBase should continue executing + */ + public boolean continueExecuting() { + return this.lookTime > 0; + } + + /** + * Execute a one shot task or start executing a continuous task + */ + public void startExecuting() { + this.lookTime = 400; + this.theGolem.setHoldingRose(true); + } + + /** + * Resets the task + */ + public void resetTask() { + this.theGolem.setHoldingRose(false); + this.theVillager = null; + } + + /** + * Updates the task + */ + public void updateTask() { + this.theGolem.getLookHelper().setLookPositionWithEntity(this.theVillager, 30.0F, 30.0F); + --this.lookTime; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityAILookIdle.java b/sp-server/src/main/java/net/minecraft/src/EntityAILookIdle.java new file mode 100644 index 0000000..2e49999 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityAILookIdle.java @@ -0,0 +1,56 @@ +package net.minecraft.src; + +public class EntityAILookIdle extends EntityAIBase { + /** The entity that is looking idle. */ + private EntityLiving idleEntity; + + /** X offset to look at */ + private double lookX; + + /** Z offset to look at */ + private double lookZ; + + /** + * A decrementing tick that stops the entity from being idle once it reaches 0. + */ + private int idleTime = 0; + + public EntityAILookIdle(EntityLiving par1EntityLiving) { + this.idleEntity = par1EntityLiving; + this.setMutexBits(3); + } + + /** + * Returns whether the EntityAIBase should begin execution. + */ + public boolean shouldExecute() { + return this.idleEntity.getRNG().nextFloat() < 0.02F; + } + + /** + * Returns whether an in-progress EntityAIBase should continue executing + */ + public boolean continueExecuting() { + return this.idleTime >= 0; + } + + /** + * Execute a one shot task or start executing a continuous task + */ + public void startExecuting() { + double var1 = (Math.PI * 2D) * this.idleEntity.getRNG().nextDouble(); + this.lookX = Math.cos(var1); + this.lookZ = Math.sin(var1); + this.idleTime = 20 + this.idleEntity.getRNG().nextInt(20); + } + + /** + * Updates the task + */ + public void updateTask() { + --this.idleTime; + this.idleEntity.getLookHelper().setLookPosition(this.idleEntity.posX + this.lookX, + this.idleEntity.posY + (double) this.idleEntity.getEyeHeight(), this.idleEntity.posZ + this.lookZ, + 10.0F, (float) this.idleEntity.getVerticalFaceSpeed()); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityAIMate.java b/sp-server/src/main/java/net/minecraft/src/EntityAIMate.java new file mode 100644 index 0000000..87fcf8e --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityAIMate.java @@ -0,0 +1,126 @@ +package net.minecraft.src; + +import java.util.Iterator; +import java.util.List; +import java.util.Random; + +public class EntityAIMate extends EntityAIBase { + private EntityAnimal theAnimal; + World theWorld; + private EntityAnimal targetMate; + + /** + * Delay preventing a baby from spawning immediately when two mate-able animals + * find each other. + */ + int spawnBabyDelay = 0; + + /** The speed the creature moves at during mating behavior. */ + float moveSpeed; + + public EntityAIMate(EntityAnimal par1EntityAnimal, float par2) { + this.theAnimal = par1EntityAnimal; + this.theWorld = par1EntityAnimal.worldObj; + this.moveSpeed = par2; + this.setMutexBits(3); + } + + /** + * Returns whether the EntityAIBase should begin execution. + */ + public boolean shouldExecute() { + if (!this.theAnimal.isInLove()) { + return false; + } else { + this.targetMate = this.getNearbyMate(); + return this.targetMate != null; + } + } + + /** + * Returns whether an in-progress EntityAIBase should continue executing + */ + public boolean continueExecuting() { + return this.targetMate.isEntityAlive() && this.targetMate.isInLove() && this.spawnBabyDelay < 60; + } + + /** + * Resets the task + */ + public void resetTask() { + this.targetMate = null; + this.spawnBabyDelay = 0; + } + + /** + * Updates the task + */ + public void updateTask() { + this.theAnimal.getLookHelper().setLookPositionWithEntity(this.targetMate, 10.0F, + (float) this.theAnimal.getVerticalFaceSpeed()); + this.theAnimal.getNavigator().tryMoveToEntityLiving(this.targetMate, this.moveSpeed); + ++this.spawnBabyDelay; + + if (this.spawnBabyDelay >= 60 && this.theAnimal.getDistanceSqToEntity(this.targetMate) < 9.0D) { + this.spawnBaby(); + } + } + + /** + * Loops through nearby animals and finds another animal of the same type that + * can be mated with. Returns the first valid mate found. + */ + private EntityAnimal getNearbyMate() { + float var1 = 8.0F; + List var2 = this.theWorld.getEntitiesWithinAABB(this.theAnimal.getClass(), + this.theAnimal.boundingBox.expand((double) var1, (double) var1, (double) var1)); + double var3 = Double.MAX_VALUE; + EntityAnimal var5 = null; + Iterator var6 = var2.iterator(); + + while (var6.hasNext()) { + EntityAnimal var7 = (EntityAnimal) var6.next(); + + if (this.theAnimal.canMateWith(var7) && this.theAnimal.getDistanceSqToEntity(var7) < var3) { + var5 = var7; + var3 = this.theAnimal.getDistanceSqToEntity(var7); + } + } + + return var5; + } + + /** + * Spawns a baby animal of the same type. + */ + private void spawnBaby() { + EntityAgeable var1 = this.theAnimal.createChild(this.targetMate); + + if (var1 != null) { + this.theAnimal.setGrowingAge(6000); + this.targetMate.setGrowingAge(6000); + this.theAnimal.resetInLove(); + this.targetMate.resetInLove(); + var1.setGrowingAge(-24000); + var1.setLocationAndAngles(this.theAnimal.posX, this.theAnimal.posY, this.theAnimal.posZ, 0.0F, 0.0F); + this.theWorld.spawnEntityInWorld(var1); + Random var2 = this.theAnimal.getRNG(); + + for (int var3 = 0; var3 < 7; ++var3) { + double var4 = var2.nextGaussian() * 0.02D; + double var6 = var2.nextGaussian() * 0.02D; + double var8 = var2.nextGaussian() * 0.02D; + this.theWorld.spawnParticle("heart", + this.theAnimal.posX + (double) (var2.nextFloat() * this.theAnimal.width * 2.0F) + - (double) this.theAnimal.width, + this.theAnimal.posY + 0.5D + (double) (var2.nextFloat() * this.theAnimal.height), + this.theAnimal.posZ + (double) (var2.nextFloat() * this.theAnimal.width * 2.0F) + - (double) this.theAnimal.width, + var4, var6, var8); + } + + this.theWorld.spawnEntityInWorld(new EntityXPOrb(this.theWorld, this.theAnimal.posX, this.theAnimal.posY, + this.theAnimal.posZ, var2.nextInt(7) + 1)); + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityAIMoveIndoors.java b/sp-server/src/main/java/net/minecraft/src/EntityAIMoveIndoors.java new file mode 100644 index 0000000..a12ba6a --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityAIMoveIndoors.java @@ -0,0 +1,80 @@ +package net.minecraft.src; + +public class EntityAIMoveIndoors extends EntityAIBase { + private EntityCreature entityObj; + private VillageDoorInfo doorInfo; + private int insidePosX = -1; + private int insidePosZ = -1; + + public EntityAIMoveIndoors(EntityCreature par1EntityCreature) { + this.entityObj = par1EntityCreature; + this.setMutexBits(1); + } + + /** + * Returns whether the EntityAIBase should begin execution. + */ + public boolean shouldExecute() { + if ((!this.entityObj.worldObj.isDaytime() || this.entityObj.worldObj.isRaining()) + && !this.entityObj.worldObj.provider.hasNoSky) { + if (this.entityObj.getRNG().nextInt(50) != 0) { + return false; + } else if (this.insidePosX != -1 && this.entityObj.getDistanceSq((double) this.insidePosX, + this.entityObj.posY, (double) this.insidePosZ) < 4.0D) { + return false; + } else { + Village var1 = this.entityObj.worldObj.villageCollectionObj.findNearestVillage( + MathHelper.floor_double(this.entityObj.posX), MathHelper.floor_double(this.entityObj.posY), + MathHelper.floor_double(this.entityObj.posZ), 14); + + if (var1 == null) { + return false; + } else { + this.doorInfo = var1.findNearestDoorUnrestricted(MathHelper.floor_double(this.entityObj.posX), + MathHelper.floor_double(this.entityObj.posY), MathHelper.floor_double(this.entityObj.posZ)); + return this.doorInfo != null; + } + } + } else { + return false; + } + } + + /** + * Returns whether an in-progress EntityAIBase should continue executing + */ + public boolean continueExecuting() { + return !this.entityObj.getNavigator().noPath(); + } + + /** + * Execute a one shot task or start executing a continuous task + */ + public void startExecuting() { + this.insidePosX = -1; + + if (this.entityObj.getDistanceSq((double) this.doorInfo.getInsidePosX(), (double) this.doorInfo.posY, + (double) this.doorInfo.getInsidePosZ()) > 256.0D) { + Vec3 var1 = RandomPositionGenerator.findRandomTargetBlockTowards(this.entityObj, 14, 3, + this.entityObj.worldObj.getWorldVec3Pool().getVecFromPool( + (double) this.doorInfo.getInsidePosX() + 0.5D, (double) this.doorInfo.getInsidePosY(), + (double) this.doorInfo.getInsidePosZ() + 0.5D)); + + if (var1 != null) { + this.entityObj.getNavigator().tryMoveToXYZ(var1.xCoord, var1.yCoord, var1.zCoord, 0.3F); + } + } else { + this.entityObj.getNavigator().tryMoveToXYZ((double) this.doorInfo.getInsidePosX() + 0.5D, + (double) this.doorInfo.getInsidePosY(), (double) this.doorInfo.getInsidePosZ() + 0.5D, 0.3F); + } + } + + /** + * Resets the task + */ + public void resetTask() { + this.insidePosX = this.doorInfo.getInsidePosX(); + this.insidePosZ = this.doorInfo.getInsidePosZ(); + this.doorInfo = null; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityAIMoveThroughVillage.java b/sp-server/src/main/java/net/minecraft/src/EntityAIMoveThroughVillage.java new file mode 100644 index 0000000..c785df2 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityAIMoveThroughVillage.java @@ -0,0 +1,144 @@ +package net.minecraft.src; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +public class EntityAIMoveThroughVillage extends EntityAIBase { + private EntityCreature theEntity; + private float movementSpeed; + + /** The PathNavigate of our entity. */ + private PathEntity entityPathNavigate; + private VillageDoorInfo doorInfo; + private boolean isNocturnal; + private List doorList = new ArrayList(); + + public EntityAIMoveThroughVillage(EntityCreature par1EntityCreature, float par2, boolean par3) { + this.theEntity = par1EntityCreature; + this.movementSpeed = par2; + this.isNocturnal = par3; + this.setMutexBits(1); + } + + /** + * Returns whether the EntityAIBase should begin execution. + */ + public boolean shouldExecute() { + this.func_75414_f(); + + if (this.isNocturnal && this.theEntity.worldObj.isDaytime()) { + return false; + } else { + Village var1 = this.theEntity.worldObj.villageCollectionObj.findNearestVillage( + MathHelper.floor_double(this.theEntity.posX), MathHelper.floor_double(this.theEntity.posY), + MathHelper.floor_double(this.theEntity.posZ), 0); + + if (var1 == null) { + return false; + } else { + this.doorInfo = this.func_75412_a(var1); + + if (this.doorInfo == null) { + return false; + } else { + boolean var2 = this.theEntity.getNavigator().getCanBreakDoors(); + this.theEntity.getNavigator().setBreakDoors(false); + this.entityPathNavigate = this.theEntity.getNavigator().getPathToXYZ((double) this.doorInfo.posX, + (double) this.doorInfo.posY, (double) this.doorInfo.posZ); + this.theEntity.getNavigator().setBreakDoors(var2); + + if (this.entityPathNavigate != null) { + return true; + } else { + Vec3 var3 = RandomPositionGenerator.findRandomTargetBlockTowards(this.theEntity, 10, 7, + this.theEntity.worldObj.getWorldVec3Pool().getVecFromPool((double) this.doorInfo.posX, + (double) this.doorInfo.posY, (double) this.doorInfo.posZ)); + + if (var3 == null) { + return false; + } else { + this.theEntity.getNavigator().setBreakDoors(false); + this.entityPathNavigate = this.theEntity.getNavigator().getPathToXYZ(var3.xCoord, + var3.yCoord, var3.zCoord); + this.theEntity.getNavigator().setBreakDoors(var2); + return this.entityPathNavigate != null; + } + } + } + } + } + } + + /** + * Returns whether an in-progress EntityAIBase should continue executing + */ + public boolean continueExecuting() { + if (this.theEntity.getNavigator().noPath()) { + return false; + } else { + float var1 = this.theEntity.width + 4.0F; + return this.theEntity.getDistanceSq((double) this.doorInfo.posX, (double) this.doorInfo.posY, + (double) this.doorInfo.posZ) > (double) (var1 * var1); + } + } + + /** + * Execute a one shot task or start executing a continuous task + */ + public void startExecuting() { + this.theEntity.getNavigator().setPath(this.entityPathNavigate, this.movementSpeed); + } + + /** + * Resets the task + */ + public void resetTask() { + if (this.theEntity.getNavigator().noPath() || this.theEntity.getDistanceSq((double) this.doorInfo.posX, + (double) this.doorInfo.posY, (double) this.doorInfo.posZ) < 16.0D) { + this.doorList.add(this.doorInfo); + } + } + + private VillageDoorInfo func_75412_a(Village par1Village) { + VillageDoorInfo var2 = null; + int var3 = Integer.MAX_VALUE; + List var4 = par1Village.getVillageDoorInfoList(); + Iterator var5 = var4.iterator(); + + while (var5.hasNext()) { + VillageDoorInfo var6 = (VillageDoorInfo) var5.next(); + int var7 = var6.getDistanceSquared(MathHelper.floor_double(this.theEntity.posX), + MathHelper.floor_double(this.theEntity.posY), MathHelper.floor_double(this.theEntity.posZ)); + + if (var7 < var3 && !this.func_75413_a(var6)) { + var2 = var6; + var3 = var7; + } + } + + return var2; + } + + private boolean func_75413_a(VillageDoorInfo par1VillageDoorInfo) { + Iterator var2 = this.doorList.iterator(); + VillageDoorInfo var3; + + do { + if (!var2.hasNext()) { + return false; + } + + var3 = (VillageDoorInfo) var2.next(); + } while (par1VillageDoorInfo.posX != var3.posX || par1VillageDoorInfo.posY != var3.posY + || par1VillageDoorInfo.posZ != var3.posZ); + + return true; + } + + private void func_75414_f() { + if (this.doorList.size() > 15) { + this.doorList.remove(0); + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityAIMoveTowardsTarget.java b/sp-server/src/main/java/net/minecraft/src/EntityAIMoveTowardsTarget.java new file mode 100644 index 0000000..f10effc --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityAIMoveTowardsTarget.java @@ -0,0 +1,67 @@ +package net.minecraft.src; + +public class EntityAIMoveTowardsTarget extends EntityAIBase { + private EntityCreature theEntity; + private EntityLiving targetEntity; + private double movePosX; + private double movePosY; + private double movePosZ; + private float field_75425_f; + private float field_75426_g; + + public EntityAIMoveTowardsTarget(EntityCreature par1EntityCreature, float par2, float par3) { + this.theEntity = par1EntityCreature; + this.field_75425_f = par2; + this.field_75426_g = par3; + this.setMutexBits(1); + } + + /** + * Returns whether the EntityAIBase should begin execution. + */ + public boolean shouldExecute() { + this.targetEntity = this.theEntity.getAttackTarget(); + + if (this.targetEntity == null) { + return false; + } else if (this.targetEntity + .getDistanceSqToEntity(this.theEntity) > (double) (this.field_75426_g * this.field_75426_g)) { + return false; + } else { + Vec3 var1 = RandomPositionGenerator.findRandomTargetBlockTowards(this.theEntity, 16, 7, + this.theEntity.worldObj.getWorldVec3Pool().getVecFromPool(this.targetEntity.posX, + this.targetEntity.posY, this.targetEntity.posZ)); + + if (var1 == null) { + return false; + } else { + this.movePosX = var1.xCoord; + this.movePosY = var1.yCoord; + this.movePosZ = var1.zCoord; + return true; + } + } + } + + /** + * Returns whether an in-progress EntityAIBase should continue executing + */ + public boolean continueExecuting() { + return !this.theEntity.getNavigator().noPath() && this.targetEntity.isEntityAlive() && this.targetEntity + .getDistanceSqToEntity(this.theEntity) < (double) (this.field_75426_g * this.field_75426_g); + } + + /** + * Resets the task + */ + public void resetTask() { + this.targetEntity = null; + } + + /** + * Execute a one shot task or start executing a continuous task + */ + public void startExecuting() { + this.theEntity.getNavigator().tryMoveToXYZ(this.movePosX, this.movePosY, this.movePosZ, this.field_75425_f); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityAIMoveTwardsRestriction.java b/sp-server/src/main/java/net/minecraft/src/EntityAIMoveTwardsRestriction.java new file mode 100644 index 0000000..f8f1c1d --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityAIMoveTwardsRestriction.java @@ -0,0 +1,52 @@ +package net.minecraft.src; + +public class EntityAIMoveTwardsRestriction extends EntityAIBase { + private EntityCreature theEntity; + private double movePosX; + private double movePosY; + private double movePosZ; + private float movementSpeed; + + public EntityAIMoveTwardsRestriction(EntityCreature par1EntityCreature, float par2) { + this.theEntity = par1EntityCreature; + this.movementSpeed = par2; + this.setMutexBits(1); + } + + /** + * Returns whether the EntityAIBase should begin execution. + */ + public boolean shouldExecute() { + if (this.theEntity.isWithinHomeDistanceCurrentPosition()) { + return false; + } else { + ChunkCoordinates var1 = this.theEntity.getHomePosition(); + Vec3 var2 = RandomPositionGenerator.findRandomTargetBlockTowards(this.theEntity, 16, 7, + this.theEntity.worldObj.getWorldVec3Pool().getVecFromPool((double) var1.posX, (double) var1.posY, + (double) var1.posZ)); + + if (var2 == null) { + return false; + } else { + this.movePosX = var2.xCoord; + this.movePosY = var2.yCoord; + this.movePosZ = var2.zCoord; + return true; + } + } + } + + /** + * Returns whether an in-progress EntityAIBase should continue executing + */ + public boolean continueExecuting() { + return !this.theEntity.getNavigator().noPath(); + } + + /** + * Execute a one shot task or start executing a continuous task + */ + public void startExecuting() { + this.theEntity.getNavigator().tryMoveToXYZ(this.movePosX, this.movePosY, this.movePosZ, this.movementSpeed); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityAINearestAttackableTarget.java b/sp-server/src/main/java/net/minecraft/src/EntityAINearestAttackableTarget.java new file mode 100644 index 0000000..57dd7f1 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityAINearestAttackableTarget.java @@ -0,0 +1,82 @@ +package net.minecraft.src; + +import java.util.Collections; +import java.util.Iterator; +import java.util.List; + +public class EntityAINearestAttackableTarget extends EntityAITarget { + EntityLiving targetEntity; + Class targetClass; + int targetChance; + private final IEntitySelector field_82643_g; + + /** Instance of EntityAINearestAttackableTargetSorter. */ + private EntityAINearestAttackableTargetSorter theNearestAttackableTargetSorter; + + public EntityAINearestAttackableTarget(EntityLiving par1EntityLiving, Class par2Class, float par3, int par4, + boolean par5) { + this(par1EntityLiving, par2Class, par3, par4, par5, false); + } + + public EntityAINearestAttackableTarget(EntityLiving par1EntityLiving, Class par2Class, float par3, int par4, + boolean par5, boolean par6) { + this(par1EntityLiving, par2Class, par3, par4, par5, par6, (IEntitySelector) null); + } + + public EntityAINearestAttackableTarget(EntityLiving par1, Class par2, float par3, int par4, boolean par5, + boolean par6, IEntitySelector par7IEntitySelector) { + super(par1, par3, par5, par6); + this.targetClass = par2; + this.targetDistance = par3; + this.targetChance = par4; + this.theNearestAttackableTargetSorter = new EntityAINearestAttackableTargetSorter(this, par1); + this.field_82643_g = par7IEntitySelector; + this.setMutexBits(1); + } + + /** + * Returns whether the EntityAIBase should begin execution. + */ + public boolean shouldExecute() { + if (this.targetChance > 0 && this.taskOwner.getRNG().nextInt(this.targetChance) != 0) { + return false; + } else { + if (this.targetClass == EntityPlayer.class) { + EntityPlayer var1 = this.taskOwner.worldObj.getClosestVulnerablePlayerToEntity(this.taskOwner, + (double) this.targetDistance); + + if (this.isSuitableTarget(var1, false)) { + this.targetEntity = var1; + return true; + } + } else { + List var5 = this.taskOwner.worldObj.selectEntitiesWithinAABB(this.targetClass, + this.taskOwner.boundingBox.expand((double) this.targetDistance, 4.0D, + (double) this.targetDistance), + this.field_82643_g); + Collections.sort(var5, this.theNearestAttackableTargetSorter); + Iterator var2 = var5.iterator(); + + while (var2.hasNext()) { + Entity var3 = (Entity) var2.next(); + EntityLiving var4 = (EntityLiving) var3; + + if (this.isSuitableTarget(var4, false)) { + this.targetEntity = var4; + return true; + } + } + } + + return false; + } + } + + /** + * Execute a one shot task or start executing a continuous task + */ + public void startExecuting() { + this.taskOwner.setAttackTarget(this.targetEntity); + super.startExecuting(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityAINearestAttackableTargetSorter.java b/sp-server/src/main/java/net/minecraft/src/EntityAINearestAttackableTargetSorter.java new file mode 100644 index 0000000..b9c8650 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityAINearestAttackableTargetSorter.java @@ -0,0 +1,25 @@ +package net.minecraft.src; + +import java.util.Comparator; + +public class EntityAINearestAttackableTargetSorter implements Comparator { + private Entity theEntity; + + final EntityAINearestAttackableTarget parent; + + public EntityAINearestAttackableTargetSorter(EntityAINearestAttackableTarget par1EntityAINearestAttackableTarget, + Entity par2Entity) { + this.parent = par1EntityAINearestAttackableTarget; + this.theEntity = par2Entity; + } + + public int compareDistanceSq(Entity par1Entity, Entity par2Entity) { + double var3 = this.theEntity.getDistanceSqToEntity(par1Entity); + double var5 = this.theEntity.getDistanceSqToEntity(par2Entity); + return var3 < var5 ? -1 : (var3 > var5 ? 1 : 0); + } + + public int compare(Object par1Obj, Object par2Obj) { + return this.compareDistanceSq((Entity) par1Obj, (Entity) par2Obj); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityAIOcelotAttack.java b/sp-server/src/main/java/net/minecraft/src/EntityAIOcelotAttack.java new file mode 100644 index 0000000..5a5dc5c --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityAIOcelotAttack.java @@ -0,0 +1,72 @@ +package net.minecraft.src; + +public class EntityAIOcelotAttack extends EntityAIBase { + World theWorld; + EntityLiving theEntity; + EntityLiving theVictim; + int attackCountdown = 0; + + public EntityAIOcelotAttack(EntityLiving par1EntityLiving) { + this.theEntity = par1EntityLiving; + this.theWorld = par1EntityLiving.worldObj; + this.setMutexBits(3); + } + + /** + * Returns whether the EntityAIBase should begin execution. + */ + public boolean shouldExecute() { + EntityLiving var1 = this.theEntity.getAttackTarget(); + + if (var1 == null) { + return false; + } else { + this.theVictim = var1; + return true; + } + } + + /** + * Returns whether an in-progress EntityAIBase should continue executing + */ + public boolean continueExecuting() { + return !this.theVictim.isEntityAlive() ? false + : (this.theEntity.getDistanceSqToEntity(this.theVictim) > 225.0D ? false + : !this.theEntity.getNavigator().noPath() || this.shouldExecute()); + } + + /** + * Resets the task + */ + public void resetTask() { + this.theVictim = null; + this.theEntity.getNavigator().clearPathEntity(); + } + + /** + * Updates the task + */ + public void updateTask() { + this.theEntity.getLookHelper().setLookPositionWithEntity(this.theVictim, 30.0F, 30.0F); + double var1 = (double) (this.theEntity.width * 2.0F * this.theEntity.width * 2.0F); + double var3 = this.theEntity.getDistanceSq(this.theVictim.posX, this.theVictim.boundingBox.minY, + this.theVictim.posZ); + float var5 = 0.23F; + + if (var3 > var1 && var3 < 16.0D) { + var5 = 0.4F; + } else if (var3 < 225.0D) { + var5 = 0.18F; + } + + this.theEntity.getNavigator().tryMoveToEntityLiving(this.theVictim, var5); + this.attackCountdown = Math.max(this.attackCountdown - 1, 0); + + if (var3 <= var1) { + if (this.attackCountdown <= 0) { + this.attackCountdown = 20; + this.theEntity.attackEntityAsMob(this.theVictim); + } + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityAIOcelotSit.java b/sp-server/src/main/java/net/minecraft/src/EntityAIOcelotSit.java new file mode 100644 index 0000000..8c7fc6c --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityAIOcelotSit.java @@ -0,0 +1,138 @@ +package net.minecraft.src; + +public class EntityAIOcelotSit extends EntityAIBase { + private final EntityOcelot theOcelot; + private final float field_75404_b; + + /** Tracks for how long the task has been executing */ + private int currentTick = 0; + private int field_75402_d = 0; + + /** For how long the Ocelot should be sitting */ + private int maxSittingTicks = 0; + + /** X Coordinate of a nearby sitable block */ + private int sitableBlockX = 0; + + /** Y Coordinate of a nearby sitable block */ + private int sitableBlockY = 0; + + /** Z Coordinate of a nearby sitable block */ + private int sitableBlockZ = 0; + + public EntityAIOcelotSit(EntityOcelot par1EntityOcelot, float par2) { + this.theOcelot = par1EntityOcelot; + this.field_75404_b = par2; + this.setMutexBits(5); + } + + /** + * Returns whether the EntityAIBase should begin execution. + */ + public boolean shouldExecute() { + return this.theOcelot.isTamed() && !this.theOcelot.isSitting() + && this.theOcelot.getRNG().nextDouble() <= 0.006500000134110451D + && this.getNearbySitableBlockDistance(); + } + + /** + * Returns whether an in-progress EntityAIBase should continue executing + */ + public boolean continueExecuting() { + return this.currentTick <= this.maxSittingTicks && this.field_75402_d <= 60 && this + .isSittableBlock(this.theOcelot.worldObj, this.sitableBlockX, this.sitableBlockY, this.sitableBlockZ); + } + + /** + * Execute a one shot task or start executing a continuous task + */ + public void startExecuting() { + this.theOcelot.getNavigator().tryMoveToXYZ((double) ((float) this.sitableBlockX) + 0.5D, + (double) (this.sitableBlockY + 1), (double) ((float) this.sitableBlockZ) + 0.5D, this.field_75404_b); + this.currentTick = 0; + this.field_75402_d = 0; + this.maxSittingTicks = this.theOcelot.getRNG().nextInt(this.theOcelot.getRNG().nextInt(1200) + 1200) + 1200; + this.theOcelot.func_70907_r().setSitting(false); + } + + /** + * Resets the task + */ + public void resetTask() { + this.theOcelot.setSitting(false); + } + + /** + * Updates the task + */ + public void updateTask() { + ++this.currentTick; + this.theOcelot.func_70907_r().setSitting(false); + + if (this.theOcelot.getDistanceSq((double) this.sitableBlockX, (double) (this.sitableBlockY + 1), + (double) this.sitableBlockZ) > 1.0D) { + this.theOcelot.setSitting(false); + this.theOcelot.getNavigator().tryMoveToXYZ((double) ((float) this.sitableBlockX) + 0.5D, + (double) (this.sitableBlockY + 1), (double) ((float) this.sitableBlockZ) + 0.5D, + this.field_75404_b); + ++this.field_75402_d; + } else if (!this.theOcelot.isSitting()) { + this.theOcelot.setSitting(true); + } else { + --this.field_75402_d; + } + } + + /** + * Searches for a block to sit on within a 8 block range, returns 0 if none + * found + */ + private boolean getNearbySitableBlockDistance() { + int var1 = (int) this.theOcelot.posY; + double var2 = 2.147483647E9D; + + for (int var4 = (int) this.theOcelot.posX - 8; (double) var4 < this.theOcelot.posX + 8.0D; ++var4) { + for (int var5 = (int) this.theOcelot.posZ - 8; (double) var5 < this.theOcelot.posZ + 8.0D; ++var5) { + if (this.isSittableBlock(this.theOcelot.worldObj, var4, var1, var5) + && this.theOcelot.worldObj.isAirBlock(var4, var1 + 1, var5)) { + double var6 = this.theOcelot.getDistanceSq((double) var4, (double) var1, (double) var5); + + if (var6 < var2) { + this.sitableBlockX = var4; + this.sitableBlockY = var1; + this.sitableBlockZ = var5; + var2 = var6; + } + } + } + } + + return var2 < 2.147483647E9D; + } + + /** + * Determines whether the Ocelot wants to sit on the block at given coordinate + */ + private boolean isSittableBlock(World par1World, int par2, int par3, int par4) { + int var5 = par1World.getBlockId(par2, par3, par4); + int var6 = par1World.getBlockMetadata(par2, par3, par4); + + if (var5 == Block.chest.blockID) { + TileEntityChest var7 = (TileEntityChest) par1World.getBlockTileEntity(par2, par3, par4); + + if (var7.numUsingPlayers < 1) { + return true; + } + } else { + if (var5 == Block.furnaceBurning.blockID) { + return true; + } + + if (var5 == Block.bed.blockID && !BlockBed.isBlockHeadOfBed(var6)) { + return true; + } + } + + return false; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityAIOpenDoor.java b/sp-server/src/main/java/net/minecraft/src/EntityAIOpenDoor.java new file mode 100644 index 0000000..1322b73 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityAIOpenDoor.java @@ -0,0 +1,46 @@ +package net.minecraft.src; + +public class EntityAIOpenDoor extends EntityAIDoorInteract { + boolean field_75361_i; + int field_75360_j; + + public EntityAIOpenDoor(EntityLiving par1EntityLiving, boolean par2) { + super(par1EntityLiving); + this.theEntity = par1EntityLiving; + this.field_75361_i = par2; + } + + /** + * Returns whether an in-progress EntityAIBase should continue executing + */ + public boolean continueExecuting() { + return this.field_75361_i && this.field_75360_j > 0 && super.continueExecuting(); + } + + /** + * Execute a one shot task or start executing a continuous task + */ + public void startExecuting() { + this.field_75360_j = 20; + this.targetDoor.onPoweredBlockChange(this.theEntity.worldObj, this.entityPosX, this.entityPosY, this.entityPosZ, + true); + } + + /** + * Resets the task + */ + public void resetTask() { + if (this.field_75361_i) { + this.targetDoor.onPoweredBlockChange(this.theEntity.worldObj, this.entityPosX, this.entityPosY, + this.entityPosZ, false); + } + } + + /** + * Updates the task + */ + public void updateTask() { + --this.field_75360_j; + super.updateTask(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityAIOwnerHurtByTarget.java b/sp-server/src/main/java/net/minecraft/src/EntityAIOwnerHurtByTarget.java new file mode 100644 index 0000000..24b6915 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityAIOwnerHurtByTarget.java @@ -0,0 +1,38 @@ +package net.minecraft.src; + +public class EntityAIOwnerHurtByTarget extends EntityAITarget { + EntityTameable theDefendingTameable; + EntityLiving theOwnerAttacker; + + public EntityAIOwnerHurtByTarget(EntityTameable par1EntityTameable) { + super(par1EntityTameable, 32.0F, false); + this.theDefendingTameable = par1EntityTameable; + this.setMutexBits(1); + } + + /** + * Returns whether the EntityAIBase should begin execution. + */ + public boolean shouldExecute() { + if (!this.theDefendingTameable.isTamed()) { + return false; + } else { + EntityLiving var1 = this.theDefendingTameable.getOwner(); + + if (var1 == null) { + return false; + } else { + this.theOwnerAttacker = var1.getAITarget(); + return this.isSuitableTarget(this.theOwnerAttacker, false); + } + } + } + + /** + * Execute a one shot task or start executing a continuous task + */ + public void startExecuting() { + this.taskOwner.setAttackTarget(this.theOwnerAttacker); + super.startExecuting(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityAIOwnerHurtTarget.java b/sp-server/src/main/java/net/minecraft/src/EntityAIOwnerHurtTarget.java new file mode 100644 index 0000000..d85bb99 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityAIOwnerHurtTarget.java @@ -0,0 +1,38 @@ +package net.minecraft.src; + +public class EntityAIOwnerHurtTarget extends EntityAITarget { + EntityTameable theEntityTameable; + EntityLiving theTarget; + + public EntityAIOwnerHurtTarget(EntityTameable par1EntityTameable) { + super(par1EntityTameable, 32.0F, false); + this.theEntityTameable = par1EntityTameable; + this.setMutexBits(1); + } + + /** + * Returns whether the EntityAIBase should begin execution. + */ + public boolean shouldExecute() { + if (!this.theEntityTameable.isTamed()) { + return false; + } else { + EntityLiving var1 = this.theEntityTameable.getOwner(); + + if (var1 == null) { + return false; + } else { + this.theTarget = var1.getLastAttackingEntity(); + return this.isSuitableTarget(this.theTarget, false); + } + } + } + + /** + * Execute a one shot task or start executing a continuous task + */ + public void startExecuting() { + this.taskOwner.setAttackTarget(this.theTarget); + super.startExecuting(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityAIPanic.java b/sp-server/src/main/java/net/minecraft/src/EntityAIPanic.java new file mode 100644 index 0000000..196cf8d --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityAIPanic.java @@ -0,0 +1,49 @@ +package net.minecraft.src; + +public class EntityAIPanic extends EntityAIBase { + private EntityCreature theEntityCreature; + private float speed; + private double randPosX; + private double randPosY; + private double randPosZ; + + public EntityAIPanic(EntityCreature par1EntityCreature, float par2) { + this.theEntityCreature = par1EntityCreature; + this.speed = par2; + this.setMutexBits(1); + } + + /** + * Returns whether the EntityAIBase should begin execution. + */ + public boolean shouldExecute() { + if (this.theEntityCreature.getAITarget() == null && !this.theEntityCreature.isBurning()) { + return false; + } else { + Vec3 var1 = RandomPositionGenerator.findRandomTarget(this.theEntityCreature, 5, 4); + + if (var1 == null) { + return false; + } else { + this.randPosX = var1.xCoord; + this.randPosY = var1.yCoord; + this.randPosZ = var1.zCoord; + return true; + } + } + } + + /** + * Execute a one shot task or start executing a continuous task + */ + public void startExecuting() { + this.theEntityCreature.getNavigator().tryMoveToXYZ(this.randPosX, this.randPosY, this.randPosZ, this.speed); + } + + /** + * Returns whether an in-progress EntityAIBase should continue executing + */ + public boolean continueExecuting() { + return !this.theEntityCreature.getNavigator().noPath(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityAIPlay.java b/sp-server/src/main/java/net/minecraft/src/EntityAIPlay.java new file mode 100644 index 0000000..916d958 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityAIPlay.java @@ -0,0 +1,103 @@ +package net.minecraft.src; + +import java.util.Iterator; +import java.util.List; + +public class EntityAIPlay extends EntityAIBase { + private EntityVillager villagerObj; + private EntityLiving targetVillager; + private float field_75261_c; + private int playTime; + + public EntityAIPlay(EntityVillager par1EntityVillager, float par2) { + this.villagerObj = par1EntityVillager; + this.field_75261_c = par2; + this.setMutexBits(1); + } + + /** + * Returns whether the EntityAIBase should begin execution. + */ + public boolean shouldExecute() { + if (this.villagerObj.getGrowingAge() >= 0) { + return false; + } else if (this.villagerObj.getRNG().nextInt(400) != 0) { + return false; + } else { + List var1 = this.villagerObj.worldObj.getEntitiesWithinAABB(EntityVillager.class, + this.villagerObj.boundingBox.expand(6.0D, 3.0D, 6.0D)); + double var2 = Double.MAX_VALUE; + Iterator var4 = var1.iterator(); + + while (var4.hasNext()) { + EntityVillager var5 = (EntityVillager) var4.next(); + + if (var5 != this.villagerObj && !var5.isPlaying() && var5.getGrowingAge() < 0) { + double var6 = var5.getDistanceSqToEntity(this.villagerObj); + + if (var6 <= var2) { + var2 = var6; + this.targetVillager = var5; + } + } + } + + if (this.targetVillager == null) { + Vec3 var8 = RandomPositionGenerator.findRandomTarget(this.villagerObj, 16, 3); + + if (var8 == null) { + return false; + } + } + + return true; + } + } + + /** + * Returns whether an in-progress EntityAIBase should continue executing + */ + public boolean continueExecuting() { + return this.playTime > 0; + } + + /** + * Execute a one shot task or start executing a continuous task + */ + public void startExecuting() { + if (this.targetVillager != null) { + this.villagerObj.setPlaying(true); + } + + this.playTime = 1000; + } + + /** + * Resets the task + */ + public void resetTask() { + this.villagerObj.setPlaying(false); + this.targetVillager = null; + } + + /** + * Updates the task + */ + public void updateTask() { + --this.playTime; + + if (this.targetVillager != null) { + if (this.villagerObj.getDistanceSqToEntity(this.targetVillager) > 4.0D) { + this.villagerObj.getNavigator().tryMoveToEntityLiving(this.targetVillager, this.field_75261_c); + } + } else if (this.villagerObj.getNavigator().noPath()) { + Vec3 var1 = RandomPositionGenerator.findRandomTarget(this.villagerObj, 16, 3); + + if (var1 == null) { + return; + } + + this.villagerObj.getNavigator().tryMoveToXYZ(var1.xCoord, var1.yCoord, var1.zCoord, this.field_75261_c); + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityAIRestrictOpenDoor.java b/sp-server/src/main/java/net/minecraft/src/EntityAIRestrictOpenDoor.java new file mode 100644 index 0000000..afbe620 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityAIRestrictOpenDoor.java @@ -0,0 +1,67 @@ +package net.minecraft.src; + +public class EntityAIRestrictOpenDoor extends EntityAIBase { + private EntityCreature entityObj; + private VillageDoorInfo frontDoor; + + public EntityAIRestrictOpenDoor(EntityCreature par1EntityCreature) { + this.entityObj = par1EntityCreature; + } + + /** + * Returns whether the EntityAIBase should begin execution. + */ + public boolean shouldExecute() { + if (this.entityObj.worldObj.isDaytime()) { + return false; + } else { + Village var1 = this.entityObj.worldObj.villageCollectionObj.findNearestVillage( + MathHelper.floor_double(this.entityObj.posX), MathHelper.floor_double(this.entityObj.posY), + MathHelper.floor_double(this.entityObj.posZ), 16); + + if (var1 == null) { + return false; + } else { + this.frontDoor = var1.findNearestDoor(MathHelper.floor_double(this.entityObj.posX), + MathHelper.floor_double(this.entityObj.posY), MathHelper.floor_double(this.entityObj.posZ)); + return this.frontDoor == null ? false + : (double) this.frontDoor.getInsideDistanceSquare(MathHelper.floor_double(this.entityObj.posX), + MathHelper.floor_double(this.entityObj.posY), + MathHelper.floor_double(this.entityObj.posZ)) < 2.25D; + } + } + } + + /** + * Returns whether an in-progress EntityAIBase should continue executing + */ + public boolean continueExecuting() { + return this.entityObj.worldObj.isDaytime() ? false + : !this.frontDoor.isDetachedFromVillageFlag && this.frontDoor.isInside( + MathHelper.floor_double(this.entityObj.posX), MathHelper.floor_double(this.entityObj.posZ)); + } + + /** + * Execute a one shot task or start executing a continuous task + */ + public void startExecuting() { + this.entityObj.getNavigator().setBreakDoors(false); + this.entityObj.getNavigator().setEnterDoors(false); + } + + /** + * Resets the task + */ + public void resetTask() { + this.entityObj.getNavigator().setBreakDoors(true); + this.entityObj.getNavigator().setEnterDoors(true); + this.frontDoor = null; + } + + /** + * Updates the task + */ + public void updateTask() { + this.frontDoor.incrementDoorOpeningRestrictionCounter(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityAIRestrictSun.java b/sp-server/src/main/java/net/minecraft/src/EntityAIRestrictSun.java new file mode 100644 index 0000000..fe4e1bb --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityAIRestrictSun.java @@ -0,0 +1,30 @@ +package net.minecraft.src; + +public class EntityAIRestrictSun extends EntityAIBase { + private EntityCreature theEntity; + + public EntityAIRestrictSun(EntityCreature par1EntityCreature) { + this.theEntity = par1EntityCreature; + } + + /** + * Returns whether the EntityAIBase should begin execution. + */ + public boolean shouldExecute() { + return this.theEntity.worldObj.isDaytime(); + } + + /** + * Execute a one shot task or start executing a continuous task + */ + public void startExecuting() { + this.theEntity.getNavigator().setAvoidSun(true); + } + + /** + * Resets the task + */ + public void resetTask() { + this.theEntity.getNavigator().setAvoidSun(false); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityAISit.java b/sp-server/src/main/java/net/minecraft/src/EntityAISit.java new file mode 100644 index 0000000..7e4882c --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityAISit.java @@ -0,0 +1,53 @@ +package net.minecraft.src; + +public class EntityAISit extends EntityAIBase { + private EntityTameable theEntity; + + /** If the EntityTameable is sitting. */ + private boolean isSitting = false; + + public EntityAISit(EntityTameable par1EntityTameable) { + this.theEntity = par1EntityTameable; + this.setMutexBits(5); + } + + /** + * Returns whether the EntityAIBase should begin execution. + */ + public boolean shouldExecute() { + if (!this.theEntity.isTamed()) { + return false; + } else if (this.theEntity.isInWater()) { + return false; + } else if (!this.theEntity.onGround) { + return false; + } else { + EntityLiving var1 = this.theEntity.getOwner(); + return var1 == null ? true + : (this.theEntity.getDistanceSqToEntity(var1) < 144.0D && var1.getAITarget() != null ? false + : this.isSitting); + } + } + + /** + * Execute a one shot task or start executing a continuous task + */ + public void startExecuting() { + this.theEntity.getNavigator().clearPathEntity(); + this.theEntity.setSitting(true); + } + + /** + * Resets the task + */ + public void resetTask() { + this.theEntity.setSitting(false); + } + + /** + * Sets the sitting flag. + */ + public void setSitting(boolean par1) { + this.isSitting = par1; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityAISwimming.java b/sp-server/src/main/java/net/minecraft/src/EntityAISwimming.java new file mode 100644 index 0000000..dbcdd6a --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityAISwimming.java @@ -0,0 +1,27 @@ +package net.minecraft.src; + +public class EntityAISwimming extends EntityAIBase { + private EntityLiving theEntity; + + public EntityAISwimming(EntityLiving par1EntityLiving) { + this.theEntity = par1EntityLiving; + this.setMutexBits(4); + par1EntityLiving.getNavigator().setCanSwim(true); + } + + /** + * Returns whether the EntityAIBase should begin execution. + */ + public boolean shouldExecute() { + return this.theEntity.isInWater() || this.theEntity.handleLavaMovement(); + } + + /** + * Updates the task + */ + public void updateTask() { + if (this.theEntity.getRNG().nextFloat() < 0.8F) { + this.theEntity.getJumpHelper().setJumping(); + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityAITarget.java b/sp-server/src/main/java/net/minecraft/src/EntityAITarget.java new file mode 100644 index 0000000..279e661 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityAITarget.java @@ -0,0 +1,143 @@ +package net.minecraft.src; + +public abstract class EntityAITarget extends EntityAIBase { + /** The entity that this task belongs to */ + protected EntityLiving taskOwner; + protected float targetDistance; + + /** + * If true, EntityAI targets must be able to be seen (cannot be blocked by + * walls) to be suitable targets. + */ + protected boolean shouldCheckSight; + private boolean field_75303_a; + private int field_75301_b; + private int field_75302_c; + private int field_75298_g; + + public EntityAITarget(EntityLiving par1EntityLiving, float par2, boolean par3) { + this(par1EntityLiving, par2, par3, false); + } + + public EntityAITarget(EntityLiving par1EntityLiving, float par2, boolean par3, boolean par4) { + this.field_75301_b = 0; + this.field_75302_c = 0; + this.field_75298_g = 0; + this.taskOwner = par1EntityLiving; + this.targetDistance = par2; + this.shouldCheckSight = par3; + this.field_75303_a = par4; + } + + /** + * Returns whether an in-progress EntityAIBase should continue executing + */ + public boolean continueExecuting() { + EntityLiving var1 = this.taskOwner.getAttackTarget(); + + if (var1 == null) { + return false; + } else if (!var1.isEntityAlive()) { + return false; + } else if (this.taskOwner.getDistanceSqToEntity(var1) > (double) (this.targetDistance * this.targetDistance)) { + return false; + } else { + if (this.shouldCheckSight) { + if (this.taskOwner.getEntitySenses().canSee(var1)) { + this.field_75298_g = 0; + } else if (++this.field_75298_g > 60) { + return false; + } + } + + return true; + } + } + + /** + * Execute a one shot task or start executing a continuous task + */ + public void startExecuting() { + this.field_75301_b = 0; + this.field_75302_c = 0; + this.field_75298_g = 0; + } + + /** + * Resets the task + */ + public void resetTask() { + this.taskOwner.setAttackTarget((EntityLiving) null); + } + + /** + * A method used to see if an entity is a suitable target through a number of + * checks. + */ + protected boolean isSuitableTarget(EntityLiving par1EntityLiving, boolean par2) { + if (par1EntityLiving == null) { + return false; + } else if (par1EntityLiving == this.taskOwner) { + return false; + } else if (!par1EntityLiving.isEntityAlive()) { + return false; + } else if (!this.taskOwner.canAttackClass(par1EntityLiving.getClass())) { + return false; + } else { + if (this.taskOwner instanceof EntityTameable && ((EntityTameable) this.taskOwner).isTamed()) { + if (par1EntityLiving instanceof EntityTameable && ((EntityTameable) par1EntityLiving).isTamed()) { + return false; + } + + if (par1EntityLiving == ((EntityTameable) this.taskOwner).getOwner()) { + return false; + } + } else if (par1EntityLiving instanceof EntityPlayer && !par2 + && ((EntityPlayer) par1EntityLiving).capabilities.disableDamage) { + return false; + } + + if (!this.taskOwner.isWithinHomeDistance(MathHelper.floor_double(par1EntityLiving.posX), + MathHelper.floor_double(par1EntityLiving.posY), MathHelper.floor_double(par1EntityLiving.posZ))) { + return false; + } else if (this.shouldCheckSight && !this.taskOwner.getEntitySenses().canSee(par1EntityLiving)) { + return false; + } else { + if (this.field_75303_a) { + if (--this.field_75302_c <= 0) { + this.field_75301_b = 0; + } + + if (this.field_75301_b == 0) { + this.field_75301_b = this.func_75295_a(par1EntityLiving) ? 1 : 2; + } + + if (this.field_75301_b == 2) { + return false; + } + } + + return true; + } + } + } + + private boolean func_75295_a(EntityLiving par1EntityLiving) { + this.field_75302_c = 10 + this.taskOwner.getRNG().nextInt(5); + PathEntity var2 = this.taskOwner.getNavigator().getPathToEntityLiving(par1EntityLiving); + + if (var2 == null) { + return false; + } else { + PathPoint var3 = var2.getFinalPathPoint(); + + if (var3 == null) { + return false; + } else { + int var4 = var3.xCoord - MathHelper.floor_double(par1EntityLiving.posX); + int var5 = var3.zCoord - MathHelper.floor_double(par1EntityLiving.posZ); + return (double) (var4 * var4 + var5 * var5) <= 2.25D; + } + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityAITargetNonTamed.java b/sp-server/src/main/java/net/minecraft/src/EntityAITargetNonTamed.java new file mode 100644 index 0000000..9079c77 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityAITargetNonTamed.java @@ -0,0 +1,18 @@ +package net.minecraft.src; + +public class EntityAITargetNonTamed extends EntityAINearestAttackableTarget { + private EntityTameable theTameable; + + public EntityAITargetNonTamed(EntityTameable par1EntityTameable, Class par2Class, float par3, int par4, + boolean par5) { + super(par1EntityTameable, par2Class, par3, par4, par5); + this.theTameable = par1EntityTameable; + } + + /** + * Returns whether the EntityAIBase should begin execution. + */ + public boolean shouldExecute() { + return this.theTameable.isTamed() ? false : super.shouldExecute(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityAITaskEntry.java b/sp-server/src/main/java/net/minecraft/src/EntityAITaskEntry.java new file mode 100644 index 0000000..5f9022a --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityAITaskEntry.java @@ -0,0 +1,18 @@ +package net.minecraft.src; + +class EntityAITaskEntry { + /** The EntityAIBase object. */ + public EntityAIBase action; + + /** Priority of the EntityAIBase */ + public int priority; + + /** The EntityAITasks object of which this is an entry. */ + final EntityAITasks tasks; + + public EntityAITaskEntry(EntityAITasks par1EntityAITasks, int par2, EntityAIBase par3EntityAIBase) { + this.tasks = par1EntityAITasks; + this.priority = par2; + this.action = par3EntityAIBase; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityAITasks.java b/sp-server/src/main/java/net/minecraft/src/EntityAITasks.java new file mode 100644 index 0000000..745b5fb --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityAITasks.java @@ -0,0 +1,156 @@ +package net.minecraft.src; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +public class EntityAITasks { + /** A list of EntityAITaskEntrys in EntityAITasks. */ + private List taskEntries = new ArrayList(); + + /** A list of EntityAITaskEntrys that are currently being executed. */ + private List executingTaskEntries = new ArrayList(); + + /** Instance of Profiler. */ + private final Profiler theProfiler; + private int field_75778_d = 0; + private int field_75779_e = 3; + + public EntityAITasks(Profiler par1Profiler) { + this.theProfiler = par1Profiler; + } + + public void addTask(int par1, EntityAIBase par2EntityAIBase) { + this.taskEntries.add(new EntityAITaskEntry(this, par1, par2EntityAIBase)); + } + + /** + * removes the indicated task from the entity's AI tasks. + */ + public void removeTask(EntityAIBase par1EntityAIBase) { + Iterator var2 = this.taskEntries.iterator(); + + while (var2.hasNext()) { + EntityAITaskEntry var3 = (EntityAITaskEntry) var2.next(); + EntityAIBase var4 = var3.action; + + if (var4 == par1EntityAIBase) { + if (this.executingTaskEntries.contains(var3)) { + var4.resetTask(); + this.executingTaskEntries.remove(var3); + } + + var2.remove(); + } + } + } + + public void onUpdateTasks() { + ArrayList var1 = new ArrayList(); + Iterator var2; + EntityAITaskEntry var3; + + if (this.field_75778_d++ % this.field_75779_e == 0) { + var2 = this.taskEntries.iterator(); + + while (var2.hasNext()) { + var3 = (EntityAITaskEntry) var2.next(); + boolean var4 = this.executingTaskEntries.contains(var3); + + if (var4) { + if (this.canUse(var3) && this.canContinue(var3)) { + continue; + } + + var3.action.resetTask(); + this.executingTaskEntries.remove(var3); + } + + if (this.canUse(var3) && var3.action.shouldExecute()) { + var1.add(var3); + this.executingTaskEntries.add(var3); + } + } + } else { + var2 = this.executingTaskEntries.iterator(); + + while (var2.hasNext()) { + var3 = (EntityAITaskEntry) var2.next(); + + if (!var3.action.continueExecuting()) { + var3.action.resetTask(); + var2.remove(); + } + } + } + + this.theProfiler.startSection("goalStart"); + var2 = var1.iterator(); + + while (var2.hasNext()) { + var3 = (EntityAITaskEntry) var2.next(); + this.theProfiler.startSection(var3.action.getClass().getSimpleName()); + var3.action.startExecuting(); + this.theProfiler.endSection(); + } + + this.theProfiler.endSection(); + this.theProfiler.startSection("goalTick"); + var2 = this.executingTaskEntries.iterator(); + + while (var2.hasNext()) { + var3 = (EntityAITaskEntry) var2.next(); + var3.action.updateTask(); + } + + this.theProfiler.endSection(); + } + + /** + * Determine if a specific AI Task should continue being executed. + */ + private boolean canContinue(EntityAITaskEntry par1EntityAITaskEntry) { + this.theProfiler.startSection("canContinue"); + boolean var2 = par1EntityAITaskEntry.action.continueExecuting(); + this.theProfiler.endSection(); + return var2; + } + + /** + * Determine if a specific AI Task can be executed, which means that all running + * higher (= lower int value) priority tasks are compatible with it or all lower + * priority tasks can be interrupted. + */ + private boolean canUse(EntityAITaskEntry par1EntityAITaskEntry) { + this.theProfiler.startSection("canUse"); + Iterator var2 = this.taskEntries.iterator(); + + while (var2.hasNext()) { + EntityAITaskEntry var3 = (EntityAITaskEntry) var2.next(); + + if (var3 != par1EntityAITaskEntry) { + if (par1EntityAITaskEntry.priority >= var3.priority) { + if (this.executingTaskEntries.contains(var3) + && !this.areTasksCompatible(par1EntityAITaskEntry, var3)) { + this.theProfiler.endSection(); + return false; + } + } else if (this.executingTaskEntries.contains(var3) && !var3.action.isContinuous()) { + this.theProfiler.endSection(); + return false; + } + } + } + + this.theProfiler.endSection(); + return true; + } + + /** + * Returns whether two EntityAITaskEntries can be executed concurrently + */ + private boolean areTasksCompatible(EntityAITaskEntry par1EntityAITaskEntry, + EntityAITaskEntry par2EntityAITaskEntry) { + return (par1EntityAITaskEntry.action.getMutexBits() & par2EntityAITaskEntry.action.getMutexBits()) == 0; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityAITempt.java b/sp-server/src/main/java/net/minecraft/src/EntityAITempt.java new file mode 100644 index 0000000..8dfc924 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityAITempt.java @@ -0,0 +1,132 @@ +package net.minecraft.src; + +public class EntityAITempt extends EntityAIBase { + /** The entity using this AI that is tempted by the player. */ + private EntityCreature temptedEntity; + private float field_75282_b; + private double field_75283_c; + private double field_75280_d; + private double field_75281_e; + private double field_75278_f; + private double field_75279_g; + + /** The player that is tempting the entity that is using this AI. */ + private EntityPlayer temptingPlayer; + + /** + * A counter that is decremented each time the shouldExecute method is called. + * The shouldExecute method will always return false if delayTemptCounter is + * greater than 0. + */ + private int delayTemptCounter = 0; + private boolean field_75287_j; + + /** + * This field saves the ID of the items that can be used to breed entities with + * this behaviour. + */ + private int breedingFood; + + /** + * Whether the entity using this AI will be scared by the tempter's sudden + * movement. + */ + private boolean scaredByPlayerMovement; + private boolean field_75286_m; + + public EntityAITempt(EntityCreature par1EntityCreature, float par2, int par3, boolean par4) { + this.temptedEntity = par1EntityCreature; + this.field_75282_b = par2; + this.breedingFood = par3; + this.scaredByPlayerMovement = par4; + this.setMutexBits(3); + } + + /** + * Returns whether the EntityAIBase should begin execution. + */ + public boolean shouldExecute() { + if (this.delayTemptCounter > 0) { + --this.delayTemptCounter; + return false; + } else { + this.temptingPlayer = this.temptedEntity.worldObj.getClosestPlayerToEntity(this.temptedEntity, 10.0D); + + if (this.temptingPlayer == null) { + return false; + } else { + ItemStack var1 = this.temptingPlayer.getCurrentEquippedItem(); + return var1 == null ? false : var1.itemID == this.breedingFood; + } + } + } + + /** + * Returns whether an in-progress EntityAIBase should continue executing + */ + public boolean continueExecuting() { + if (this.scaredByPlayerMovement) { + if (this.temptedEntity.getDistanceSqToEntity(this.temptingPlayer) < 36.0D) { + if (this.temptingPlayer.getDistanceSq(this.field_75283_c, this.field_75280_d, + this.field_75281_e) > 0.010000000000000002D) { + return false; + } + + if (Math.abs((double) this.temptingPlayer.rotationPitch - this.field_75278_f) > 5.0D + || Math.abs((double) this.temptingPlayer.rotationYaw - this.field_75279_g) > 5.0D) { + return false; + } + } else { + this.field_75283_c = this.temptingPlayer.posX; + this.field_75280_d = this.temptingPlayer.posY; + this.field_75281_e = this.temptingPlayer.posZ; + } + + this.field_75278_f = (double) this.temptingPlayer.rotationPitch; + this.field_75279_g = (double) this.temptingPlayer.rotationYaw; + } + + return this.shouldExecute(); + } + + /** + * Execute a one shot task or start executing a continuous task + */ + public void startExecuting() { + this.field_75283_c = this.temptingPlayer.posX; + this.field_75280_d = this.temptingPlayer.posY; + this.field_75281_e = this.temptingPlayer.posZ; + this.field_75287_j = true; + this.field_75286_m = this.temptedEntity.getNavigator().getAvoidsWater(); + this.temptedEntity.getNavigator().setAvoidsWater(false); + } + + /** + * Resets the task + */ + public void resetTask() { + this.temptingPlayer = null; + this.temptedEntity.getNavigator().clearPathEntity(); + this.delayTemptCounter = 100; + this.field_75287_j = false; + this.temptedEntity.getNavigator().setAvoidsWater(this.field_75286_m); + } + + /** + * Updates the task + */ + public void updateTask() { + this.temptedEntity.getLookHelper().setLookPositionWithEntity(this.temptingPlayer, 30.0F, + (float) this.temptedEntity.getVerticalFaceSpeed()); + + if (this.temptedEntity.getDistanceSqToEntity(this.temptingPlayer) < 6.25D) { + this.temptedEntity.getNavigator().clearPathEntity(); + } else { + this.temptedEntity.getNavigator().tryMoveToEntityLiving(this.temptingPlayer, this.field_75282_b); + } + } + + public boolean func_75277_f() { + return this.field_75287_j; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityAITradePlayer.java b/sp-server/src/main/java/net/minecraft/src/EntityAITradePlayer.java new file mode 100644 index 0000000..79eaaf0 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityAITradePlayer.java @@ -0,0 +1,44 @@ +package net.minecraft.src; + +public class EntityAITradePlayer extends EntityAIBase { + private EntityVillager villager; + + public EntityAITradePlayer(EntityVillager par1EntityVillager) { + this.villager = par1EntityVillager; + this.setMutexBits(5); + } + + /** + * Returns whether the EntityAIBase should begin execution. + */ + public boolean shouldExecute() { + if (!this.villager.isEntityAlive()) { + return false; + } else if (this.villager.isInWater()) { + return false; + } else if (!this.villager.onGround) { + return false; + } else if (this.villager.velocityChanged) { + return false; + } else { + EntityPlayer var1 = this.villager.getCustomer(); + return var1 == null ? false + : (this.villager.getDistanceSqToEntity(var1) > 16.0D ? false + : var1.openContainer instanceof Container); + } + } + + /** + * Execute a one shot task or start executing a continuous task + */ + public void startExecuting() { + this.villager.getNavigator().clearPathEntity(); + } + + /** + * Resets the task + */ + public void resetTask() { + this.villager.setCustomer((EntityPlayer) null); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityAIVillagerMate.java b/sp-server/src/main/java/net/minecraft/src/EntityAIVillagerMate.java new file mode 100644 index 0000000..eb27369 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityAIVillagerMate.java @@ -0,0 +1,108 @@ +package net.minecraft.src; + +public class EntityAIVillagerMate extends EntityAIBase { + private EntityVillager villagerObj; + private EntityVillager mate; + private World worldObj; + private int matingTimeout = 0; + Village villageObj; + + public EntityAIVillagerMate(EntityVillager par1EntityVillager) { + this.villagerObj = par1EntityVillager; + this.worldObj = par1EntityVillager.worldObj; + this.setMutexBits(3); + } + + /** + * Returns whether the EntityAIBase should begin execution. + */ + public boolean shouldExecute() { + if (this.villagerObj.getGrowingAge() != 0) { + return false; + } else if (this.villagerObj.getRNG().nextInt(500) != 0) { + return false; + } else { + this.villageObj = this.worldObj.villageCollectionObj.findNearestVillage( + MathHelper.floor_double(this.villagerObj.posX), MathHelper.floor_double(this.villagerObj.posY), + MathHelper.floor_double(this.villagerObj.posZ), 0); + + if (this.villageObj == null) { + return false; + } else if (!this.checkSufficientDoorsPresentForNewVillager()) { + return false; + } else { + Entity var1 = this.worldObj.findNearestEntityWithinAABB(EntityVillager.class, + this.villagerObj.boundingBox.expand(8.0D, 3.0D, 8.0D), this.villagerObj); + + if (var1 == null) { + return false; + } else { + this.mate = (EntityVillager) var1; + return this.mate.getGrowingAge() == 0; + } + } + } + } + + /** + * Execute a one shot task or start executing a continuous task + */ + public void startExecuting() { + this.matingTimeout = 300; + this.villagerObj.setMating(true); + } + + /** + * Resets the task + */ + public void resetTask() { + this.villageObj = null; + this.mate = null; + this.villagerObj.setMating(false); + } + + /** + * Returns whether an in-progress EntityAIBase should continue executing + */ + public boolean continueExecuting() { + return this.matingTimeout >= 0 && this.checkSufficientDoorsPresentForNewVillager() + && this.villagerObj.getGrowingAge() == 0; + } + + /** + * Updates the task + */ + public void updateTask() { + --this.matingTimeout; + this.villagerObj.getLookHelper().setLookPositionWithEntity(this.mate, 10.0F, 30.0F); + + if (this.villagerObj.getDistanceSqToEntity(this.mate) > 2.25D) { + this.villagerObj.getNavigator().tryMoveToEntityLiving(this.mate, 0.25F); + } else if (this.matingTimeout == 0 && this.mate.isMating()) { + this.giveBirth(); + } + + if (this.villagerObj.getRNG().nextInt(35) == 0) { + this.worldObj.setEntityState(this.villagerObj, (byte) 12); + } + } + + private boolean checkSufficientDoorsPresentForNewVillager() { + if (!this.villageObj.isMatingSeason()) { + return false; + } else { + int var1 = (int) ((double) ((float) this.villageObj.getNumVillageDoors()) * 0.35D); + return this.villageObj.getNumVillagers() < var1; + } + } + + private void giveBirth() { + EntityVillager var1 = this.villagerObj.func_90012_b(this.mate); + this.mate.setGrowingAge(6000); + this.villagerObj.setGrowingAge(6000); + var1.setGrowingAge(-24000); + var1.setLocationAndAngles(this.villagerObj.posX, this.villagerObj.posY, this.villagerObj.posZ, 0.0F, 0.0F); + this.worldObj.spawnEntityInWorld(var1); + this.worldObj.setEntityState(var1, (byte) 12); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityAIWander.java b/sp-server/src/main/java/net/minecraft/src/EntityAIWander.java new file mode 100644 index 0000000..c3f48db --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityAIWander.java @@ -0,0 +1,51 @@ +package net.minecraft.src; + +public class EntityAIWander extends EntityAIBase { + private EntityCreature entity; + private double xPosition; + private double yPosition; + private double zPosition; + private float speed; + + public EntityAIWander(EntityCreature par1EntityCreature, float par2) { + this.entity = par1EntityCreature; + this.speed = par2; + this.setMutexBits(1); + } + + /** + * Returns whether the EntityAIBase should begin execution. + */ + public boolean shouldExecute() { + if (this.entity.getAge() >= 100) { + return false; + } else if (this.entity.getRNG().nextInt(120) != 0) { + return false; + } else { + Vec3 var1 = RandomPositionGenerator.findRandomTarget(this.entity, 10, 7); + + if (var1 == null) { + return false; + } else { + this.xPosition = var1.xCoord; + this.yPosition = var1.yCoord; + this.zPosition = var1.zCoord; + return true; + } + } + } + + /** + * Returns whether an in-progress EntityAIBase should continue executing + */ + public boolean continueExecuting() { + return !this.entity.getNavigator().noPath(); + } + + /** + * Execute a one shot task or start executing a continuous task + */ + public void startExecuting() { + this.entity.getNavigator().tryMoveToXYZ(this.xPosition, this.yPosition, this.zPosition, this.speed); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityAIWatchClosest.java b/sp-server/src/main/java/net/minecraft/src/EntityAIWatchClosest.java new file mode 100644 index 0000000..8cb045e --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityAIWatchClosest.java @@ -0,0 +1,84 @@ +package net.minecraft.src; + +public class EntityAIWatchClosest extends EntityAIBase { + private EntityLiving theWatcher; + + /** The closest entity which is being watched by this one. */ + protected Entity closestEntity; + private float field_75333_c; + private int lookTime; + private float field_75331_e; + private Class watchedClass; + + public EntityAIWatchClosest(EntityLiving par1EntityLiving, Class par2Class, float par3) { + this.theWatcher = par1EntityLiving; + this.watchedClass = par2Class; + this.field_75333_c = par3; + this.field_75331_e = 0.02F; + this.setMutexBits(2); + } + + public EntityAIWatchClosest(EntityLiving par1EntityLiving, Class par2Class, float par3, float par4) { + this.theWatcher = par1EntityLiving; + this.watchedClass = par2Class; + this.field_75333_c = par3; + this.field_75331_e = par4; + this.setMutexBits(2); + } + + /** + * Returns whether the EntityAIBase should begin execution. + */ + public boolean shouldExecute() { + if (this.theWatcher.getRNG().nextFloat() >= this.field_75331_e) { + return false; + } else { + if (this.watchedClass == EntityPlayer.class) { + this.closestEntity = this.theWatcher.worldObj.getClosestPlayerToEntity(this.theWatcher, + (double) this.field_75333_c); + } else { + this.closestEntity = this.theWatcher.worldObj.findNearestEntityWithinAABB(this.watchedClass, + this.theWatcher.boundingBox.expand((double) this.field_75333_c, 3.0D, + (double) this.field_75333_c), + this.theWatcher); + } + + return this.closestEntity != null; + } + } + + /** + * Returns whether an in-progress EntityAIBase should continue executing + */ + public boolean continueExecuting() { + return !this.closestEntity.isEntityAlive() ? false + : (this.theWatcher + .getDistanceSqToEntity(this.closestEntity) > (double) (this.field_75333_c * this.field_75333_c) + ? false + : this.lookTime > 0); + } + + /** + * Execute a one shot task or start executing a continuous task + */ + public void startExecuting() { + this.lookTime = 40 + this.theWatcher.getRNG().nextInt(40); + } + + /** + * Resets the task + */ + public void resetTask() { + this.closestEntity = null; + } + + /** + * Updates the task + */ + public void updateTask() { + this.theWatcher.getLookHelper().setLookPosition(this.closestEntity.posX, + this.closestEntity.posY + (double) this.closestEntity.getEyeHeight(), this.closestEntity.posZ, 10.0F, + (float) this.theWatcher.getVerticalFaceSpeed()); + --this.lookTime; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityAIWatchClosest2.java b/sp-server/src/main/java/net/minecraft/src/EntityAIWatchClosest2.java new file mode 100644 index 0000000..8315273 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityAIWatchClosest2.java @@ -0,0 +1,8 @@ +package net.minecraft.src; + +public class EntityAIWatchClosest2 extends EntityAIWatchClosest { + public EntityAIWatchClosest2(EntityLiving par1EntityLiving, Class par2Class, float par3, float par4) { + super(par1EntityLiving, par2Class, par3, par4); + this.setMutexBits(3); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityAgeable.java b/sp-server/src/main/java/net/minecraft/src/EntityAgeable.java new file mode 100644 index 0000000..1b130d1 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityAgeable.java @@ -0,0 +1,141 @@ +package net.minecraft.src; + +public abstract class EntityAgeable extends EntityCreature { + private float field_98056_d = -1.0F; + private float field_98057_e; + + public EntityAgeable(World par1World) { + super(par1World); + } + + public abstract EntityAgeable createChild(EntityAgeable var1); + + /** + * Called when a player interacts with a mob. e.g. gets milk from a cow, gets + * into the saddle on a pig. + */ + public boolean interact(EntityPlayer par1EntityPlayer) { + ItemStack var2 = par1EntityPlayer.inventory.getCurrentItem(); + + if (var2 != null && var2.itemID == Item.monsterPlacer.itemID && !this.worldObj.isRemote) { + Class var3 = EntityList.getClassFromID(var2.getItemDamage()); + + if (var3 != null && var3.isAssignableFrom(this.getClass())) { + EntityAgeable var4 = this.createChild(this); + + if (var4 != null) { + var4.setGrowingAge(-24000); + var4.setLocationAndAngles(this.posX, this.posY, this.posZ, 0.0F, 0.0F); + this.worldObj.spawnEntityInWorld(var4); + + if (var2.hasDisplayName()) { + var4.func_94058_c(var2.getDisplayName()); + } + + if (!par1EntityPlayer.capabilities.isCreativeMode) { + --var2.stackSize; + + if (var2.stackSize <= 0) { + par1EntityPlayer.inventory.setInventorySlotContents(par1EntityPlayer.inventory.currentItem, + (ItemStack) null); + } + } + } + } + } + + return super.interact(par1EntityPlayer); + } + + protected void entityInit() { + super.entityInit(); + this.dataWatcher.addObject(12, new Integer(0)); + } + + /** + * The age value may be negative or positive or zero. If it's negative, it get's + * incremented on each tick, if it's positive, it get's decremented each tick. + * Don't confuse this with EntityLiving.getAge. With a negative value the Entity + * is considered a child. + */ + public int getGrowingAge() { + return this.dataWatcher.getWatchableObjectInt(12); + } + + /** + * The age value may be negative or positive or zero. If it's negative, it get's + * incremented on each tick, if it's positive, it get's decremented each tick. + * With a negative value the Entity is considered a child. + */ + public void setGrowingAge(int par1) { + this.dataWatcher.updateObject(12, Integer.valueOf(par1)); + this.func_98054_a(this.isChild()); + } + + /** + * (abstract) Protected helper method to write subclass entity data to NBT. + */ + public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) { + super.writeEntityToNBT(par1NBTTagCompound); + par1NBTTagCompound.setInteger("Age", this.getGrowingAge()); + } + + /** + * (abstract) Protected helper method to read subclass entity data from NBT. + */ + public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) { + super.readEntityFromNBT(par1NBTTagCompound); + this.setGrowingAge(par1NBTTagCompound.getInteger("Age")); + } + + /** + * Called frequently so the entity can update its state every tick as required. + * For example, zombies and skeletons use this to react to sunlight and start to + * burn. + */ + public void onLivingUpdate() { + super.onLivingUpdate(); + + if (this.worldObj.isRemote) { + this.func_98054_a(this.isChild()); + } else { + int var1 = this.getGrowingAge(); + + if (var1 < 0) { + ++var1; + this.setGrowingAge(var1); + } else if (var1 > 0) { + --var1; + this.setGrowingAge(var1); + } + } + } + + /** + * If Animal, checks if the age timer is negative + */ + public boolean isChild() { + return this.getGrowingAge() < 0; + } + + public void func_98054_a(boolean par1) { + this.func_98055_j(par1 ? 0.5F : 1.0F); + } + + /** + * Sets the width and height of the entity. Args: width, height + */ + protected final void setSize(float par1, float par2) { + boolean var3 = this.field_98056_d > 0.0F; + this.field_98056_d = par1; + this.field_98057_e = par2; + + if (!var3) { + this.func_98055_j(1.0F); + } + } + + private void func_98055_j(float par1) { + super.setSize(this.field_98056_d * par1, this.field_98057_e * par1); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityAmbientCreature.java b/sp-server/src/main/java/net/minecraft/src/EntityAmbientCreature.java new file mode 100644 index 0000000..9c21b83 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityAmbientCreature.java @@ -0,0 +1,7 @@ +package net.minecraft.src; + +public abstract class EntityAmbientCreature extends EntityLiving implements IAnimals { + public EntityAmbientCreature(World par1World) { + super(par1World); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityAnimal.java b/sp-server/src/main/java/net/minecraft/src/EntityAnimal.java new file mode 100644 index 0000000..bab58db --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityAnimal.java @@ -0,0 +1,338 @@ +package net.minecraft.src; + +import java.util.List; + +public abstract class EntityAnimal extends EntityAgeable implements IAnimals { + private int inLove; + + /** + * This is representation of a counter for reproduction progress. (Note that + * this is different from the inLove which represent being in Love-Mode) + */ + private int breeding = 0; + + public EntityAnimal(World par1World) { + super(par1World); + } + + /** + * main AI tick function, replaces updateEntityActionState + */ + protected void updateAITick() { + if (this.getGrowingAge() != 0) { + this.inLove = 0; + } + + super.updateAITick(); + } + + /** + * Called frequently so the entity can update its state every tick as required. + * For example, zombies and skeletons use this to react to sunlight and start to + * burn. + */ + public void onLivingUpdate() { + super.onLivingUpdate(); + + if (this.getGrowingAge() != 0) { + this.inLove = 0; + } + + if (this.inLove > 0) { + --this.inLove; + String var1 = "heart"; + + if (this.inLove % 10 == 0) { + double var2 = this.rand.nextGaussian() * 0.02D; + double var4 = this.rand.nextGaussian() * 0.02D; + double var6 = this.rand.nextGaussian() * 0.02D; + this.worldObj.spawnParticle(var1, + this.posX + (double) (this.rand.nextFloat() * this.width * 2.0F) - (double) this.width, + this.posY + 0.5D + (double) (this.rand.nextFloat() * this.height), + this.posZ + (double) (this.rand.nextFloat() * this.width * 2.0F) - (double) this.width, var2, + var4, var6); + } + } else { + this.breeding = 0; + } + } + + /** + * Basic mob attack. Default to touch of death in EntityCreature. Overridden by + * each mob to define their attack. + */ + protected void attackEntity(Entity par1Entity, float par2) { + if (par1Entity instanceof EntityPlayer) { + if (par2 < 3.0F) { + double var3 = par1Entity.posX - this.posX; + double var5 = par1Entity.posZ - this.posZ; + this.rotationYaw = (float) (Math.atan2(var5, var3) * 180.0D / Math.PI) - 90.0F; + this.hasAttacked = true; + } + + EntityPlayer var7 = (EntityPlayer) par1Entity; + + if (var7.getCurrentEquippedItem() == null || !this.isBreedingItem(var7.getCurrentEquippedItem())) { + this.entityToAttack = null; + } + } else if (par1Entity instanceof EntityAnimal) { + EntityAnimal var8 = (EntityAnimal) par1Entity; + + if (this.getGrowingAge() > 0 && var8.getGrowingAge() < 0) { + if ((double) par2 < 2.5D) { + this.hasAttacked = true; + } + } else if (this.inLove > 0 && var8.inLove > 0) { + if (var8.entityToAttack == null) { + var8.entityToAttack = this; + } + + if (var8.entityToAttack == this && (double) par2 < 3.5D) { + ++var8.inLove; + ++this.inLove; + ++this.breeding; + + if (this.breeding % 4 == 0) { + this.worldObj.spawnParticle("heart", + this.posX + (double) (this.rand.nextFloat() * this.width * 2.0F) - (double) this.width, + this.posY + 0.5D + (double) (this.rand.nextFloat() * this.height), + this.posZ + (double) (this.rand.nextFloat() * this.width * 2.0F) - (double) this.width, + 0.0D, 0.0D, 0.0D); + } + + if (this.breeding == 60) { + this.procreate((EntityAnimal) par1Entity); + } + } else { + this.breeding = 0; + } + } else { + this.breeding = 0; + this.entityToAttack = null; + } + } + } + + /** + * Creates a baby animal according to the animal type of the target at the + * actual position and spawns 'love' particles. + */ + private void procreate(EntityAnimal par1EntityAnimal) { + EntityAgeable var2 = this.createChild(par1EntityAnimal); + + if (var2 != null) { + this.setGrowingAge(6000); + par1EntityAnimal.setGrowingAge(6000); + this.inLove = 0; + this.breeding = 0; + this.entityToAttack = null; + par1EntityAnimal.entityToAttack = null; + par1EntityAnimal.breeding = 0; + par1EntityAnimal.inLove = 0; + var2.setGrowingAge(-24000); + var2.setLocationAndAngles(this.posX, this.posY, this.posZ, this.rotationYaw, this.rotationPitch); + + for (int var3 = 0; var3 < 7; ++var3) { + double var4 = this.rand.nextGaussian() * 0.02D; + double var6 = this.rand.nextGaussian() * 0.02D; + double var8 = this.rand.nextGaussian() * 0.02D; + this.worldObj.spawnParticle("heart", + this.posX + (double) (this.rand.nextFloat() * this.width * 2.0F) - (double) this.width, + this.posY + 0.5D + (double) (this.rand.nextFloat() * this.height), + this.posZ + (double) (this.rand.nextFloat() * this.width * 2.0F) - (double) this.width, var4, + var6, var8); + } + + this.worldObj.spawnEntityInWorld(var2); + } + } + + /** + * Called when the entity is attacked. + */ + public boolean attackEntityFrom(DamageSource par1DamageSource, int par2) { + if (this.isEntityInvulnerable()) { + return false; + } else { + this.fleeingTick = 60; + this.entityToAttack = null; + this.inLove = 0; + return super.attackEntityFrom(par1DamageSource, par2); + } + } + + /** + * Takes a coordinate in and returns a weight to determine how likely this + * creature will try to path to the block. Args: x, y, z + */ + public float getBlockPathWeight(int par1, int par2, int par3) { + return this.worldObj.getBlockId(par1, par2 - 1, par3) == Block.grass.blockID ? 10.0F + : this.worldObj.getLightBrightness(par1, par2, par3) - 0.5F; + } + + /** + * (abstract) Protected helper method to write subclass entity data to NBT. + */ + public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) { + super.writeEntityToNBT(par1NBTTagCompound); + par1NBTTagCompound.setInteger("InLove", this.inLove); + } + + /** + * (abstract) Protected helper method to read subclass entity data from NBT. + */ + public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) { + super.readEntityFromNBT(par1NBTTagCompound); + this.inLove = par1NBTTagCompound.getInteger("InLove"); + } + + /** + * Finds the closest player within 16 blocks to attack, or null if this Entity + * isn't interested in attacking (Animals, Spiders at day, peaceful PigZombies). + */ + protected Entity findPlayerToAttack() { + if (this.fleeingTick > 0) { + return null; + } else { + float var1 = 8.0F; + List var2; + int var3; + EntityAnimal var4; + + if (this.inLove > 0) { + var2 = this.worldObj.getEntitiesWithinAABB(this.getClass(), + this.boundingBox.expand((double) var1, (double) var1, (double) var1)); + + for (var3 = 0; var3 < var2.size(); ++var3) { + var4 = (EntityAnimal) var2.get(var3); + + if (var4 != this && var4.inLove > 0) { + return var4; + } + } + } else if (this.getGrowingAge() == 0) { + var2 = this.worldObj.getEntitiesWithinAABB(EntityPlayer.class, + this.boundingBox.expand((double) var1, (double) var1, (double) var1)); + + for (var3 = 0; var3 < var2.size(); ++var3) { + EntityPlayer var5 = (EntityPlayer) var2.get(var3); + + if (var5.getCurrentEquippedItem() != null && this.isBreedingItem(var5.getCurrentEquippedItem())) { + return var5; + } + } + } else if (this.getGrowingAge() > 0) { + var2 = this.worldObj.getEntitiesWithinAABB(this.getClass(), + this.boundingBox.expand((double) var1, (double) var1, (double) var1)); + + for (var3 = 0; var3 < var2.size(); ++var3) { + var4 = (EntityAnimal) var2.get(var3); + + if (var4 != this && var4.getGrowingAge() < 0) { + return var4; + } + } + } + + return null; + } + } + + /** + * Checks if the entity's current position is a valid location to spawn this + * entity. + */ + public boolean getCanSpawnHere() { + int var1 = MathHelper.floor_double(this.posX); + int var2 = MathHelper.floor_double(this.boundingBox.minY); + int var3 = MathHelper.floor_double(this.posZ); + return this.worldObj.getBlockId(var1, var2 - 1, var3) == Block.grass.blockID + && this.worldObj.getFullBlockLightValue(var1, var2, var3) > 8 && super.getCanSpawnHere(); + } + + /** + * Get number of ticks, at least during which the living entity will be silent. + */ + public int getTalkInterval() { + return 120; + } + + /** + * Determines if an entity can be despawned, used on idle far away entities + */ + protected boolean canDespawn() { + return false; + } + + /** + * Get the experience points the entity currently has. + */ + protected int getExperiencePoints(EntityPlayer par1EntityPlayer) { + return 1 + this.worldObj.rand.nextInt(3); + } + + /** + * Checks if the parameter is an item which this animal can be fed to breed it + * (wheat, carrots or seeds depending on the animal type) + */ + public boolean isBreedingItem(ItemStack par1ItemStack) { + return par1ItemStack.itemID == Item.wheat.itemID; + } + + /** + * Called when a player interacts with a mob. e.g. gets milk from a cow, gets + * into the saddle on a pig. + */ + public boolean interact(EntityPlayer par1EntityPlayer) { + ItemStack var2 = par1EntityPlayer.inventory.getCurrentItem(); + + if (var2 != null && this.isBreedingItem(var2) && this.getGrowingAge() == 0 && this.inLove <= 0) { + if (!par1EntityPlayer.capabilities.isCreativeMode) { + --var2.stackSize; + + if (var2.stackSize <= 0) { + par1EntityPlayer.inventory.setInventorySlotContents(par1EntityPlayer.inventory.currentItem, + (ItemStack) null); + } + } + + this.inLove = 600; + this.entityToAttack = null; + + for (int var3 = 0; var3 < 7; ++var3) { + double var4 = this.rand.nextGaussian() * 0.02D; + double var6 = this.rand.nextGaussian() * 0.02D; + double var8 = this.rand.nextGaussian() * 0.02D; + this.worldObj.spawnParticle("heart", + this.posX + (double) (this.rand.nextFloat() * this.width * 2.0F) - (double) this.width, + this.posY + 0.5D + (double) (this.rand.nextFloat() * this.height), + this.posZ + (double) (this.rand.nextFloat() * this.width * 2.0F) - (double) this.width, var4, + var6, var8); + } + + return true; + } else { + return super.interact(par1EntityPlayer); + } + } + + /** + * Returns if the entity is currently in 'love mode'. + */ + public boolean isInLove() { + return this.inLove > 0; + } + + public void resetInLove() { + this.inLove = 0; + } + + /** + * Returns true if the mob is currently able to mate with the specified mob. + */ + public boolean canMateWith(EntityAnimal par1EntityAnimal) { + return par1EntityAnimal == this ? false + : (par1EntityAnimal.getClass() != this.getClass() ? false + : this.isInLove() && par1EntityAnimal.isInLove()); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityArrow.java b/sp-server/src/main/java/net/minecraft/src/EntityArrow.java new file mode 100644 index 0000000..8ed639e --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityArrow.java @@ -0,0 +1,496 @@ +package net.minecraft.src; + +import java.util.List; + +public class EntityArrow extends Entity implements IProjectile { + private int xTile = -1; + private int yTile = -1; + private int zTile = -1; + private int inTile = 0; + private int inData = 0; + private boolean inGround = false; + + /** 1 if the player can pick up the arrow */ + public int canBePickedUp = 0; + + /** Seems to be some sort of timer for animating an arrow. */ + public int arrowShake = 0; + + /** The owner of this arrow. */ + public Entity shootingEntity; + private int ticksInGround; + private int ticksInAir = 0; + private double damage = 2.0D; + + /** The amount of knockback an arrow applies when it hits a mob. */ + private int knockbackStrength; + + public EntityArrow(World par1World) { + super(par1World); + this.renderDistanceWeight = 10.0D; + this.setSize(0.5F, 0.5F); + } + + public EntityArrow(World par1World, double par2, double par4, double par6) { + super(par1World); + this.renderDistanceWeight = 10.0D; + this.setSize(0.5F, 0.5F); + this.setPosition(par2, par4, par6); + this.yOffset = 0.0F; + } + + public EntityArrow(World par1World, EntityLiving par2EntityLiving, EntityLiving par3EntityLiving, float par4, + float par5) { + super(par1World); + this.renderDistanceWeight = 10.0D; + this.shootingEntity = par2EntityLiving; + + if (par2EntityLiving instanceof EntityPlayer) { + this.canBePickedUp = 1; + } + + this.posY = par2EntityLiving.posY + (double) par2EntityLiving.getEyeHeight() - 0.10000000149011612D; + double var6 = par3EntityLiving.posX - par2EntityLiving.posX; + double var8 = par3EntityLiving.boundingBox.minY + (double) (par3EntityLiving.height / 3.0F) - this.posY; + double var10 = par3EntityLiving.posZ - par2EntityLiving.posZ; + double var12 = (double) MathHelper.sqrt_double(var6 * var6 + var10 * var10); + + if (var12 >= 1.0E-7D) { + float var14 = (float) (Math.atan2(var10, var6) * 180.0D / Math.PI) - 90.0F; + float var15 = (float) (-(Math.atan2(var8, var12) * 180.0D / Math.PI)); + double var16 = var6 / var12; + double var18 = var10 / var12; + this.setLocationAndAngles(par2EntityLiving.posX + var16, this.posY, par2EntityLiving.posZ + var18, var14, + var15); + this.yOffset = 0.0F; + float var20 = (float) var12 * 0.2F; + this.setThrowableHeading(var6, var8 + (double) var20, var10, par4, par5); + } + } + + public EntityArrow(World par1World, EntityLiving par2EntityLiving, float par3) { + super(par1World); + this.renderDistanceWeight = 10.0D; + this.shootingEntity = par2EntityLiving; + + if (par2EntityLiving instanceof EntityPlayer) { + this.canBePickedUp = 1; + } + + this.setSize(0.5F, 0.5F); + this.setLocationAndAngles(par2EntityLiving.posX, + par2EntityLiving.posY + (double) par2EntityLiving.getEyeHeight(), par2EntityLiving.posZ, + par2EntityLiving.rotationYaw, par2EntityLiving.rotationPitch); + this.posX -= (double) (MathHelper.cos(this.rotationYaw / 180.0F * (float) Math.PI) * 0.16F); + this.posY -= 0.10000000149011612D; + this.posZ -= (double) (MathHelper.sin(this.rotationYaw / 180.0F * (float) Math.PI) * 0.16F); + this.setPosition(this.posX, this.posY, this.posZ); + this.yOffset = 0.0F; + this.motionX = (double) (-MathHelper.sin(this.rotationYaw / 180.0F * (float) Math.PI) + * MathHelper.cos(this.rotationPitch / 180.0F * (float) Math.PI)); + this.motionZ = (double) (MathHelper.cos(this.rotationYaw / 180.0F * (float) Math.PI) + * MathHelper.cos(this.rotationPitch / 180.0F * (float) Math.PI)); + this.motionY = (double) (-MathHelper.sin(this.rotationPitch / 180.0F * (float) Math.PI)); + this.setThrowableHeading(this.motionX, this.motionY, this.motionZ, par3 * 1.5F, 1.0F); + } + + protected void entityInit() { + this.dataWatcher.addObject(16, Byte.valueOf((byte) 0)); + } + + /** + * Similar to setArrowHeading, it's point the throwable entity to a x, y, z + * direction. + */ + public void setThrowableHeading(double par1, double par3, double par5, float par7, float par8) { + float var9 = MathHelper.sqrt_double(par1 * par1 + par3 * par3 + par5 * par5); + par1 /= (double) var9; + par3 /= (double) var9; + par5 /= (double) var9; + par1 += this.rand.nextGaussian() * (double) (this.rand.nextBoolean() ? -1 : 1) * 0.007499999832361937D + * (double) par8; + par3 += this.rand.nextGaussian() * (double) (this.rand.nextBoolean() ? -1 : 1) * 0.007499999832361937D + * (double) par8; + par5 += this.rand.nextGaussian() * (double) (this.rand.nextBoolean() ? -1 : 1) * 0.007499999832361937D + * (double) par8; + par1 *= (double) par7; + par3 *= (double) par7; + par5 *= (double) par7; + this.motionX = par1; + this.motionY = par3; + this.motionZ = par5; + float var10 = MathHelper.sqrt_double(par1 * par1 + par5 * par5); + this.prevRotationYaw = this.rotationYaw = (float) (Math.atan2(par1, par5) * 180.0D / Math.PI); + this.prevRotationPitch = this.rotationPitch = (float) (Math.atan2(par3, (double) var10) * 180.0D / Math.PI); + this.ticksInGround = 0; + } + + /** + * Called to update the entity's position/logic. + */ + public void onUpdate() { + super.onUpdate(); + + if (this.prevRotationPitch == 0.0F && this.prevRotationYaw == 0.0F) { + float var1 = MathHelper.sqrt_double(this.motionX * this.motionX + this.motionZ * this.motionZ); + this.prevRotationYaw = this.rotationYaw = (float) (Math.atan2(this.motionX, this.motionZ) * 180.0D + / Math.PI); + this.prevRotationPitch = this.rotationPitch = (float) (Math.atan2(this.motionY, (double) var1) * 180.0D + / Math.PI); + } + + int var16 = this.worldObj.getBlockId(this.xTile, this.yTile, this.zTile); + + if (var16 > 0) { + Block.blocksList[var16].setBlockBoundsBasedOnState(this.worldObj, this.xTile, this.yTile, this.zTile); + AxisAlignedBB var2 = Block.blocksList[var16].getCollisionBoundingBoxFromPool(this.worldObj, this.xTile, + this.yTile, this.zTile); + + if (var2 != null && var2 + .isVecInside(this.worldObj.getWorldVec3Pool().getVecFromPool(this.posX, this.posY, this.posZ))) { + this.inGround = true; + } + } + + if (this.arrowShake > 0) { + --this.arrowShake; + } + + if (this.inGround) { + int var18 = this.worldObj.getBlockId(this.xTile, this.yTile, this.zTile); + int var19 = this.worldObj.getBlockMetadata(this.xTile, this.yTile, this.zTile); + + if (var18 == this.inTile && var19 == this.inData) { + ++this.ticksInGround; + + if (this.ticksInGround == 1200) { + this.setDead(); + } + } else { + this.inGround = false; + this.motionX *= (double) (this.rand.nextFloat() * 0.2F); + this.motionY *= (double) (this.rand.nextFloat() * 0.2F); + this.motionZ *= (double) (this.rand.nextFloat() * 0.2F); + this.ticksInGround = 0; + this.ticksInAir = 0; + } + } else { + ++this.ticksInAir; + Vec3 var17 = this.worldObj.getWorldVec3Pool().getVecFromPool(this.posX, this.posY, this.posZ); + Vec3 var3 = this.worldObj.getWorldVec3Pool().getVecFromPool(this.posX + this.motionX, + this.posY + this.motionY, this.posZ + this.motionZ); + MovingObjectPosition var4 = this.worldObj.rayTraceBlocks_do_do(var17, var3, false, true); + var17 = this.worldObj.getWorldVec3Pool().getVecFromPool(this.posX, this.posY, this.posZ); + var3 = this.worldObj.getWorldVec3Pool().getVecFromPool(this.posX + this.motionX, this.posY + this.motionY, + this.posZ + this.motionZ); + + if (var4 != null) { + var3 = this.worldObj.getWorldVec3Pool().getVecFromPool(var4.hitVec.xCoord, var4.hitVec.yCoord, + var4.hitVec.zCoord); + } + + Entity var5 = null; + List var6 = this.worldObj.getEntitiesWithinAABBExcludingEntity(this, + this.boundingBox.addCoord(this.motionX, this.motionY, this.motionZ).expand(1.0D, 1.0D, 1.0D)); + double var7 = 0.0D; + int var9; + float var11; + + for (var9 = 0; var9 < var6.size(); ++var9) { + Entity var10 = (Entity) var6.get(var9); + + if (var10.canBeCollidedWith() && (var10 != this.shootingEntity || this.ticksInAir >= 5)) { + var11 = 0.3F; + AxisAlignedBB var12 = var10.boundingBox.expand((double) var11, (double) var11, (double) var11); + MovingObjectPosition var13 = var12.calculateIntercept(var17, var3); + + if (var13 != null) { + double var14 = var17.distanceTo(var13.hitVec); + + if (var14 < var7 || var7 == 0.0D) { + var5 = var10; + var7 = var14; + } + } + } + } + + if (var5 != null) { + var4 = new MovingObjectPosition(var5); + } + + if (var4 != null && var4.entityHit != null && var4.entityHit instanceof EntityPlayer) { + EntityPlayer var20 = (EntityPlayer) var4.entityHit; + + if (var20.capabilities.disableDamage || this.shootingEntity instanceof EntityPlayer + && !((EntityPlayer) this.shootingEntity).func_96122_a(var20)) { + var4 = null; + } + } + + float var21; + float var27; + + if (var4 != null) { + if (var4.entityHit != null) { + var21 = MathHelper.sqrt_double( + this.motionX * this.motionX + this.motionY * this.motionY + this.motionZ * this.motionZ); + int var22 = MathHelper.ceiling_double_int((double) var21 * this.damage); + + if (this.getIsCritical()) { + var22 += this.rand.nextInt(var22 / 2 + 2); + } + + DamageSource var23 = null; + + if (this.shootingEntity == null) { + var23 = DamageSource.causeArrowDamage(this, this); + } else { + var23 = DamageSource.causeArrowDamage(this, this.shootingEntity); + } + + if (this.isBurning() && !(var4.entityHit instanceof EntityEnderman)) { + var4.entityHit.setFire(5); + } + + if (var4.entityHit.attackEntityFrom(var23, var22)) { + if (var4.entityHit instanceof EntityLiving) { + EntityLiving var25 = (EntityLiving) var4.entityHit; + + if (!this.worldObj.isRemote) { + var25.setArrowCountInEntity(var25.getArrowCountInEntity() + 1); + } + + if (this.knockbackStrength > 0) { + var27 = MathHelper + .sqrt_double(this.motionX * this.motionX + this.motionZ * this.motionZ); + + if (var27 > 0.0F) { + var4.entityHit.addVelocity( + this.motionX * (double) this.knockbackStrength * 0.6000000238418579D + / (double) var27, + 0.1D, this.motionZ * (double) this.knockbackStrength * 0.6000000238418579D + / (double) var27); + } + } + + if (this.shootingEntity != null) { + EnchantmentThorns.func_92096_a(this.shootingEntity, var25, this.rand); + } + + if (this.shootingEntity != null && var4.entityHit != this.shootingEntity + && var4.entityHit instanceof EntityPlayer + && this.shootingEntity instanceof EntityPlayerMP) { + ((EntityPlayerMP) this.shootingEntity).playerNetServerHandler + .sendPacket(new Packet70GameEvent(6, 0)); + } + } + + this.playSound("random.bowhit", 1.0F, 1.2F / (this.rand.nextFloat() * 0.2F + 0.9F)); + + if (!(var4.entityHit instanceof EntityEnderman)) { + this.setDead(); + } + } else { + this.motionX *= -0.10000000149011612D; + this.motionY *= -0.10000000149011612D; + this.motionZ *= -0.10000000149011612D; + this.rotationYaw += 180.0F; + this.prevRotationYaw += 180.0F; + this.ticksInAir = 0; + } + } else { + this.xTile = var4.blockX; + this.yTile = var4.blockY; + this.zTile = var4.blockZ; + this.inTile = this.worldObj.getBlockId(this.xTile, this.yTile, this.zTile); + this.inData = this.worldObj.getBlockMetadata(this.xTile, this.yTile, this.zTile); + this.motionX = (double) ((float) (var4.hitVec.xCoord - this.posX)); + this.motionY = (double) ((float) (var4.hitVec.yCoord - this.posY)); + this.motionZ = (double) ((float) (var4.hitVec.zCoord - this.posZ)); + var21 = MathHelper.sqrt_double( + this.motionX * this.motionX + this.motionY * this.motionY + this.motionZ * this.motionZ); + this.posX -= this.motionX / (double) var21 * 0.05000000074505806D; + this.posY -= this.motionY / (double) var21 * 0.05000000074505806D; + this.posZ -= this.motionZ / (double) var21 * 0.05000000074505806D; + this.playSound("random.bowhit", 1.0F, 1.2F / (this.rand.nextFloat() * 0.2F + 0.9F)); + this.inGround = true; + this.arrowShake = 7; + this.setIsCritical(false); + + if (this.inTile != 0) { + Block.blocksList[this.inTile].onEntityCollidedWithBlock(this.worldObj, this.xTile, this.yTile, + this.zTile, this); + } + } + } + + if (this.getIsCritical()) { + for (var9 = 0; var9 < 4; ++var9) { + this.worldObj.spawnParticle("crit", this.posX + this.motionX * (double) var9 / 4.0D, + this.posY + this.motionY * (double) var9 / 4.0D, + this.posZ + this.motionZ * (double) var9 / 4.0D, -this.motionX, -this.motionY + 0.2D, + -this.motionZ); + } + } + + this.posX += this.motionX; + this.posY += this.motionY; + this.posZ += this.motionZ; + var21 = MathHelper.sqrt_double(this.motionX * this.motionX + this.motionZ * this.motionZ); + this.rotationYaw = (float) (Math.atan2(this.motionX, this.motionZ) * 180.0D / Math.PI); + + for (this.rotationPitch = (float) (Math.atan2(this.motionY, (double) var21) * 180.0D + / Math.PI); this.rotationPitch + - this.prevRotationPitch < -180.0F; this.prevRotationPitch -= 360.0F) { + ; + } + + while (this.rotationPitch - this.prevRotationPitch >= 180.0F) { + this.prevRotationPitch += 360.0F; + } + + while (this.rotationYaw - this.prevRotationYaw < -180.0F) { + this.prevRotationYaw -= 360.0F; + } + + while (this.rotationYaw - this.prevRotationYaw >= 180.0F) { + this.prevRotationYaw += 360.0F; + } + + this.rotationPitch = this.prevRotationPitch + (this.rotationPitch - this.prevRotationPitch) * 0.2F; + this.rotationYaw = this.prevRotationYaw + (this.rotationYaw - this.prevRotationYaw) * 0.2F; + float var24 = 0.99F; + var11 = 0.05F; + + if (this.isInWater()) { + for (int var26 = 0; var26 < 4; ++var26) { + var27 = 0.25F; + this.worldObj.spawnParticle("bubble", this.posX - this.motionX * (double) var27, + this.posY - this.motionY * (double) var27, this.posZ - this.motionZ * (double) var27, + this.motionX, this.motionY, this.motionZ); + } + + var24 = 0.8F; + } + + this.motionX *= (double) var24; + this.motionY *= (double) var24; + this.motionZ *= (double) var24; + this.motionY -= (double) var11; + this.setPosition(this.posX, this.posY, this.posZ); + this.doBlockCollisions(); + } + } + + /** + * (abstract) Protected helper method to write subclass entity data to NBT. + */ + public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) { + par1NBTTagCompound.setShort("xTile", (short) this.xTile); + par1NBTTagCompound.setShort("yTile", (short) this.yTile); + par1NBTTagCompound.setShort("zTile", (short) this.zTile); + par1NBTTagCompound.setByte("inTile", (byte) this.inTile); + par1NBTTagCompound.setByte("inData", (byte) this.inData); + par1NBTTagCompound.setByte("shake", (byte) this.arrowShake); + par1NBTTagCompound.setByte("inGround", (byte) (this.inGround ? 1 : 0)); + par1NBTTagCompound.setByte("pickup", (byte) this.canBePickedUp); + par1NBTTagCompound.setDouble("damage", this.damage); + } + + /** + * (abstract) Protected helper method to read subclass entity data from NBT. + */ + public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) { + this.xTile = par1NBTTagCompound.getShort("xTile"); + this.yTile = par1NBTTagCompound.getShort("yTile"); + this.zTile = par1NBTTagCompound.getShort("zTile"); + this.inTile = par1NBTTagCompound.getByte("inTile") & 255; + this.inData = par1NBTTagCompound.getByte("inData") & 255; + this.arrowShake = par1NBTTagCompound.getByte("shake") & 255; + this.inGround = par1NBTTagCompound.getByte("inGround") == 1; + + if (par1NBTTagCompound.hasKey("damage")) { + this.damage = par1NBTTagCompound.getDouble("damage"); + } + + if (par1NBTTagCompound.hasKey("pickup")) { + this.canBePickedUp = par1NBTTagCompound.getByte("pickup"); + } else if (par1NBTTagCompound.hasKey("player")) { + this.canBePickedUp = par1NBTTagCompound.getBoolean("player") ? 1 : 0; + } + } + + /** + * Called by a player entity when they collide with an entity + */ + public void onCollideWithPlayer(EntityPlayer par1EntityPlayer) { + if (!this.worldObj.isRemote && this.inGround && this.arrowShake <= 0) { + boolean var2 = this.canBePickedUp == 1 + || this.canBePickedUp == 2 && par1EntityPlayer.capabilities.isCreativeMode; + + if (this.canBePickedUp == 1 + && !par1EntityPlayer.inventory.addItemStackToInventory(new ItemStack(Item.arrow, 1))) { + var2 = false; + } + + if (var2) { + this.playSound("random.pop", 0.2F, + ((this.rand.nextFloat() - this.rand.nextFloat()) * 0.7F + 1.0F) * 2.0F); + par1EntityPlayer.onItemPickup(this, 1); + this.setDead(); + } + } + } + + /** + * returns if this entity triggers Block.onEntityWalking on the blocks they walk + * on. used for spiders and wolves to prevent them from trampling crops + */ + protected boolean canTriggerWalking() { + return false; + } + + public void setDamage(double par1) { + this.damage = par1; + } + + public double getDamage() { + return this.damage; + } + + /** + * Sets the amount of knockback the arrow applies when it hits a mob. + */ + public void setKnockbackStrength(int par1) { + this.knockbackStrength = par1; + } + + /** + * If returns false, the item will not inflict any damage against entities. + */ + public boolean canAttackWithItem() { + return false; + } + + /** + * Whether the arrow has a stream of critical hit particles flying behind it. + */ + public void setIsCritical(boolean par1) { + byte var2 = this.dataWatcher.getWatchableObjectByte(16); + + if (par1) { + this.dataWatcher.updateObject(16, Byte.valueOf((byte) (var2 | 1))); + } else { + this.dataWatcher.updateObject(16, Byte.valueOf((byte) (var2 & -2))); + } + } + + /** + * Whether the arrow has a stream of critical hit particles flying behind it. + */ + public boolean getIsCritical() { + byte var1 = this.dataWatcher.getWatchableObjectByte(16); + return (var1 & 1) != 0; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityBat.java b/sp-server/src/main/java/net/minecraft/src/EntityBat.java new file mode 100644 index 0000000..2a80260 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityBat.java @@ -0,0 +1,253 @@ +package net.minecraft.src; + +import java.util.Calendar; + +public class EntityBat extends EntityAmbientCreature { + /** Coordinates of where the bat spawned. */ + private ChunkCoordinates spawnPosition; + + public EntityBat(World par1World) { + super(par1World); + this.texture = "/mob/bat.png"; + this.setSize(0.5F, 0.9F); + this.setIsBatHanging(true); + } + + protected void entityInit() { + super.entityInit(); + this.dataWatcher.addObject(16, new Byte((byte) 0)); + } + + /** + * Returns the volume for the sounds this mob makes. + */ + protected float getSoundVolume() { + return 0.1F; + } + + /** + * Gets the pitch of living sounds in living entities. + */ + protected float getSoundPitch() { + return super.getSoundPitch() * 0.95F; + } + + /** + * Returns the sound this mob makes while it's alive. + */ + protected String getLivingSound() { + return this.getIsBatHanging() && this.rand.nextInt(4) != 0 ? null : "mob.bat.idle"; + } + + /** + * Returns the sound this mob makes when it is hurt. + */ + protected String getHurtSound() { + return "mob.bat.hurt"; + } + + /** + * Returns the sound this mob makes on death. + */ + protected String getDeathSound() { + return "mob.bat.death"; + } + + /** + * Returns true if this entity should push and be pushed by other entities when + * colliding. + */ + public boolean canBePushed() { + return false; + } + + protected void collideWithEntity(Entity par1Entity) { + } + + protected void func_85033_bc() { + } + + public int getMaxHealth() { + return 6; + } + + public boolean getIsBatHanging() { + return (this.dataWatcher.getWatchableObjectByte(16) & 1) != 0; + } + + public void setIsBatHanging(boolean par1) { + byte var2 = this.dataWatcher.getWatchableObjectByte(16); + + if (par1) { + this.dataWatcher.updateObject(16, Byte.valueOf((byte) (var2 | 1))); + } else { + this.dataWatcher.updateObject(16, Byte.valueOf((byte) (var2 & -2))); + } + } + + /** + * Returns true if the newer Entity AI code should be run + */ + protected boolean isAIEnabled() { + return true; + } + + /** + * Called to update the entity's position/logic. + */ + public void onUpdate() { + super.onUpdate(); + + if (this.getIsBatHanging()) { + this.motionX = this.motionY = this.motionZ = 0.0D; + this.posY = (double) MathHelper.floor_double(this.posY) + 1.0D - (double) this.height; + } else { + this.motionY *= 0.6000000238418579D; + } + } + + protected void updateAITasks() { + super.updateAITasks(); + + if (this.getIsBatHanging()) { + if (!this.worldObj.isBlockNormalCube(MathHelper.floor_double(this.posX), (int) this.posY + 1, + MathHelper.floor_double(this.posZ))) { + this.setIsBatHanging(false); + this.worldObj.playAuxSFXAtEntity((EntityPlayer) null, 1015, (int) this.posX, (int) this.posY, + (int) this.posZ, 0); + } else { + if (this.rand.nextInt(200) == 0) { + this.rotationYawHead = (float) this.rand.nextInt(360); + } + + if (this.worldObj.getClosestPlayerToEntity(this, 4.0D) != null) { + this.setIsBatHanging(false); + this.worldObj.playAuxSFXAtEntity((EntityPlayer) null, 1015, (int) this.posX, (int) this.posY, + (int) this.posZ, 0); + } + } + } else { + if (this.spawnPosition != null && (!this.worldObj.isAirBlock(this.spawnPosition.posX, + this.spawnPosition.posY, this.spawnPosition.posZ) || this.spawnPosition.posY < 1)) { + this.spawnPosition = null; + } + + if (this.spawnPosition == null || this.rand.nextInt(30) == 0 || this.spawnPosition + .getDistanceSquared((int) this.posX, (int) this.posY, (int) this.posZ) < 4.0F) { + this.spawnPosition = new ChunkCoordinates((int) this.posX + this.rand.nextInt(7) - this.rand.nextInt(7), + (int) this.posY + this.rand.nextInt(6) - 2, + (int) this.posZ + this.rand.nextInt(7) - this.rand.nextInt(7)); + } + + double var1 = (double) this.spawnPosition.posX + 0.5D - this.posX; + double var3 = (double) this.spawnPosition.posY + 0.1D - this.posY; + double var5 = (double) this.spawnPosition.posZ + 0.5D - this.posZ; + this.motionX += (Math.signum(var1) * 0.5D - this.motionX) * 0.10000000149011612D; + this.motionY += (Math.signum(var3) * 0.699999988079071D - this.motionY) * 0.10000000149011612D; + this.motionZ += (Math.signum(var5) * 0.5D - this.motionZ) * 0.10000000149011612D; + float var7 = (float) (Math.atan2(this.motionZ, this.motionX) * 180.0D / Math.PI) - 90.0F; + float var8 = MathHelper.wrapAngleTo180_float(var7 - this.rotationYaw); + this.moveForward = 0.5F; + this.rotationYaw += var8; + + if (this.rand.nextInt(100) == 0 && this.worldObj.isBlockNormalCube(MathHelper.floor_double(this.posX), + (int) this.posY + 1, MathHelper.floor_double(this.posZ))) { + this.setIsBatHanging(true); + } + } + } + + /** + * returns if this entity triggers Block.onEntityWalking on the blocks they walk + * on. used for spiders and wolves to prevent them from trampling crops + */ + protected boolean canTriggerWalking() { + return false; + } + + /** + * Called when the mob is falling. Calculates and applies fall damage. + */ + protected void fall(float par1) { + } + + /** + * Takes in the distance the entity has fallen this tick and whether its on the + * ground to update the fall distance and deal fall damage if landing on the + * ground. Args: distanceFallenThisTick, onGround + */ + protected void updateFallState(double par1, boolean par3) { + } + + /** + * Return whether this entity should NOT trigger a pressure plate or a tripwire. + */ + public boolean doesEntityNotTriggerPressurePlate() { + return true; + } + + /** + * Called when the entity is attacked. + */ + public boolean attackEntityFrom(DamageSource par1DamageSource, int par2) { + if (this.isEntityInvulnerable()) { + return false; + } else { + if (!this.worldObj.isRemote && this.getIsBatHanging()) { + this.setIsBatHanging(false); + } + + return super.attackEntityFrom(par1DamageSource, par2); + } + } + + /** + * (abstract) Protected helper method to read subclass entity data from NBT. + */ + public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) { + super.readEntityFromNBT(par1NBTTagCompound); + this.dataWatcher.updateObject(16, Byte.valueOf(par1NBTTagCompound.getByte("BatFlags"))); + } + + /** + * (abstract) Protected helper method to write subclass entity data to NBT. + */ + public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) { + super.writeEntityToNBT(par1NBTTagCompound); + par1NBTTagCompound.setByte("BatFlags", this.dataWatcher.getWatchableObjectByte(16)); + } + + /** + * Checks if the entity's current position is a valid location to spawn this + * entity. + */ + public boolean getCanSpawnHere() { + int var1 = MathHelper.floor_double(this.boundingBox.minY); + + if (var1 >= 63) { + return false; + } else { + int var2 = MathHelper.floor_double(this.posX); + int var3 = MathHelper.floor_double(this.posZ); + int var4 = this.worldObj.getBlockLightValue(var2, var1, var3); + byte var5 = 4; + Calendar var6 = this.worldObj.getCurrentDate(); + + if ((var6.get(2) + 1 != 10 || var6.get(5) < 20) && (var6.get(2) + 1 != 11 || var6.get(5) > 3)) { + if (this.rand.nextBoolean()) { + return false; + } + } else { + var5 = 7; + } + + return var4 > this.rand.nextInt(var5) ? false : super.getCanSpawnHere(); + } + } + + /** + * Initialize this creature. + */ + public void initCreature() { + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityBlaze.java b/sp-server/src/main/java/net/minecraft/src/EntityBlaze.java new file mode 100644 index 0000000..a6554b0 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityBlaze.java @@ -0,0 +1,210 @@ +package net.minecraft.src; + +public class EntityBlaze extends EntityMob { + /** Random offset used in floating behaviour */ + private float heightOffset = 0.5F; + + /** ticks until heightOffset is randomized */ + private int heightOffsetUpdateTime; + private int field_70846_g; + + public EntityBlaze(World par1World) { + super(par1World); + this.texture = "/mob/fire.png"; + this.isImmuneToFire = true; + this.experienceValue = 10; + } + + public int getMaxHealth() { + return 20; + } + + protected void entityInit() { + super.entityInit(); + this.dataWatcher.addObject(16, new Byte((byte) 0)); + } + + /** + * Returns the sound this mob makes while it's alive. + */ + protected String getLivingSound() { + return "mob.blaze.breathe"; + } + + /** + * Returns the sound this mob makes when it is hurt. + */ + protected String getHurtSound() { + return "mob.blaze.hit"; + } + + /** + * Returns the sound this mob makes on death. + */ + protected String getDeathSound() { + return "mob.blaze.death"; + } + + /** + * Gets how bright this entity is. + */ + public float getBrightness(float par1) { + return 1.0F; + } + + /** + * Called frequently so the entity can update its state every tick as required. + * For example, zombies and skeletons use this to react to sunlight and start to + * burn. + */ + public void onLivingUpdate() { + if (!this.worldObj.isRemote) { + if (this.isWet()) { + this.attackEntityFrom(DamageSource.drown, 1); + } + + --this.heightOffsetUpdateTime; + + if (this.heightOffsetUpdateTime <= 0) { + this.heightOffsetUpdateTime = 100; + this.heightOffset = 0.5F + (float) this.rand.nextGaussian() * 3.0F; + } + + if (this.getEntityToAttack() != null + && this.getEntityToAttack().posY + (double) this.getEntityToAttack().getEyeHeight() > this.posY + + (double) this.getEyeHeight() + (double) this.heightOffset) { + this.motionY += (0.30000001192092896D - this.motionY) * 0.30000001192092896D; + } + } + + if (this.rand.nextInt(24) == 0) { + this.worldObj.playSoundEffect(this.posX + 0.5D, this.posY + 0.5D, this.posZ + 0.5D, "fire.fire", + 1.0F + this.rand.nextFloat(), this.rand.nextFloat() * 0.7F + 0.3F); + } + + if (!this.onGround && this.motionY < 0.0D) { + this.motionY *= 0.6D; + } + + for (int var1 = 0; var1 < 2; ++var1) { + this.worldObj.spawnParticle("largesmoke", this.posX + (this.rand.nextDouble() - 0.5D) * (double) this.width, + this.posY + this.rand.nextDouble() * (double) this.height, + this.posZ + (this.rand.nextDouble() - 0.5D) * (double) this.width, 0.0D, 0.0D, 0.0D); + } + + super.onLivingUpdate(); + } + + /** + * Basic mob attack. Default to touch of death in EntityCreature. Overridden by + * each mob to define their attack. + */ + protected void attackEntity(Entity par1Entity, float par2) { + if (this.attackTime <= 0 && par2 < 2.0F && par1Entity.boundingBox.maxY > this.boundingBox.minY + && par1Entity.boundingBox.minY < this.boundingBox.maxY) { + this.attackTime = 20; + this.attackEntityAsMob(par1Entity); + } else if (par2 < 30.0F) { + double var3 = par1Entity.posX - this.posX; + double var5 = par1Entity.boundingBox.minY + (double) (par1Entity.height / 2.0F) + - (this.posY + (double) (this.height / 2.0F)); + double var7 = par1Entity.posZ - this.posZ; + + if (this.attackTime == 0) { + ++this.field_70846_g; + + if (this.field_70846_g == 1) { + this.attackTime = 60; + this.func_70844_e(true); + } else if (this.field_70846_g <= 4) { + this.attackTime = 6; + } else { + this.attackTime = 100; + this.field_70846_g = 0; + this.func_70844_e(false); + } + + if (this.field_70846_g > 1) { + float var9 = MathHelper.sqrt_float(par2) * 0.5F; + this.worldObj.playAuxSFXAtEntity((EntityPlayer) null, 1009, (int) this.posX, (int) this.posY, + (int) this.posZ, 0); + + for (int var10 = 0; var10 < 1; ++var10) { + EntitySmallFireball var11 = new EntitySmallFireball(this.worldObj, this, + var3 + this.rand.nextGaussian() * (double) var9, var5, + var7 + this.rand.nextGaussian() * (double) var9); + var11.posY = this.posY + (double) (this.height / 2.0F) + 0.5D; + this.worldObj.spawnEntityInWorld(var11); + } + } + } + + this.rotationYaw = (float) (Math.atan2(var7, var3) * 180.0D / Math.PI) - 90.0F; + this.hasAttacked = true; + } + } + + /** + * Called when the mob is falling. Calculates and applies fall damage. + */ + protected void fall(float par1) { + } + + /** + * Returns the item ID for the item the mob drops on death. + */ + protected int getDropItemId() { + return Item.blazeRod.itemID; + } + + /** + * Returns true if the entity is on fire. Used by render to add the fire effect + * on rendering. + */ + public boolean isBurning() { + return this.func_70845_n(); + } + + /** + * Drop 0-2 items of this living's type + */ + protected void dropFewItems(boolean par1, int par2) { + if (par1) { + int var3 = this.rand.nextInt(2 + par2); + + for (int var4 = 0; var4 < var3; ++var4) { + this.dropItem(Item.blazeRod.itemID, 1); + } + } + } + + public boolean func_70845_n() { + return (this.dataWatcher.getWatchableObjectByte(16) & 1) != 0; + } + + public void func_70844_e(boolean par1) { + byte var2 = this.dataWatcher.getWatchableObjectByte(16); + + if (par1) { + var2 = (byte) (var2 | 1); + } else { + var2 &= -2; + } + + this.dataWatcher.updateObject(16, Byte.valueOf(var2)); + } + + /** + * Checks to make sure the light is not too bright where the mob is spawning + */ + protected boolean isValidLightLevel() { + return true; + } + + /** + * Returns the amount of damage a mob should deal. + */ + public int getAttackStrength(Entity par1Entity) { + return 6; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityBoat.java b/sp-server/src/main/java/net/minecraft/src/EntityBoat.java new file mode 100644 index 0000000..9dabeee --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityBoat.java @@ -0,0 +1,420 @@ +package net.minecraft.src; + +import java.util.List; + +public class EntityBoat extends Entity { + private boolean field_70279_a; + private double speedMultiplier; + private int boatPosRotationIncrements; + private double boatX; + private double boatY; + private double boatZ; + private double boatYaw; + private double boatPitch; + + public EntityBoat(World par1World) { + super(par1World); + this.field_70279_a = true; + this.speedMultiplier = 0.07D; + this.preventEntitySpawning = true; + this.setSize(1.5F, 0.6F); + this.yOffset = this.height / 2.0F; + } + + /** + * returns if this entity triggers Block.onEntityWalking on the blocks they walk + * on. used for spiders and wolves to prevent them from trampling crops + */ + protected boolean canTriggerWalking() { + return false; + } + + protected void entityInit() { + this.dataWatcher.addObject(17, new Integer(0)); + this.dataWatcher.addObject(18, new Integer(1)); + this.dataWatcher.addObject(19, new Integer(0)); + } + + /** + * Returns a boundingBox used to collide the entity with other entities and + * blocks. This enables the entity to be pushable on contact, like boats or + * minecarts. + */ + public AxisAlignedBB getCollisionBox(Entity par1Entity) { + return par1Entity.boundingBox; + } + + /** + * returns the bounding box for this entity + */ + public AxisAlignedBB getBoundingBox() { + return this.boundingBox; + } + + /** + * Returns true if this entity should push and be pushed by other entities when + * colliding. + */ + public boolean canBePushed() { + return true; + } + + public EntityBoat(World par1World, double par2, double par4, double par6) { + this(par1World); + this.setPosition(par2, par4 + (double) this.yOffset, par6); + this.motionX = 0.0D; + this.motionY = 0.0D; + this.motionZ = 0.0D; + this.prevPosX = par2; + this.prevPosY = par4; + this.prevPosZ = par6; + } + + /** + * Returns the Y offset from the entity's position for any entity riding this + * one. + */ + public double getMountedYOffset() { + return (double) this.height * 0.0D - 0.30000001192092896D; + } + + /** + * Called when the entity is attacked. + */ + public boolean attackEntityFrom(DamageSource par1DamageSource, int par2) { + if (this.isEntityInvulnerable()) { + return false; + } else if (!this.worldObj.isRemote && !this.isDead) { + this.setForwardDirection(-this.getForwardDirection()); + this.setTimeSinceHit(10); + this.setDamageTaken(this.getDamageTaken() + par2 * 10); + this.setBeenAttacked(); + boolean var3 = par1DamageSource.getEntity() instanceof EntityPlayer + && ((EntityPlayer) par1DamageSource.getEntity()).capabilities.isCreativeMode; + + if (var3 || this.getDamageTaken() > 40) { + if (this.riddenByEntity != null) { + this.riddenByEntity.mountEntity(this); + } + + if (!var3) { + this.dropItemWithOffset(Item.boat.itemID, 1, 0.0F); + } + + this.setDead(); + } + + return true; + } else { + return true; + } + } + + /** + * Returns true if other Entities should be prevented from moving through this + * Entity. + */ + public boolean canBeCollidedWith() { + return !this.isDead; + } + + /** + * Called to update the entity's position/logic. + */ + public void onUpdate() { + super.onUpdate(); + + if (this.getTimeSinceHit() > 0) { + this.setTimeSinceHit(this.getTimeSinceHit() - 1); + } + + if (this.getDamageTaken() > 0) { + this.setDamageTaken(this.getDamageTaken() - 1); + } + + this.prevPosX = this.posX; + this.prevPosY = this.posY; + this.prevPosZ = this.posZ; + byte var1 = 5; + double var2 = 0.0D; + + for (int var4 = 0; var4 < var1; ++var4) { + double var5 = this.boundingBox.minY + + (this.boundingBox.maxY - this.boundingBox.minY) * (double) (var4 + 0) / (double) var1 - 0.125D; + double var7 = this.boundingBox.minY + + (this.boundingBox.maxY - this.boundingBox.minY) * (double) (var4 + 1) / (double) var1 - 0.125D; + AxisAlignedBB var9 = AxisAlignedBB.getAABBPool().getAABB(this.boundingBox.minX, var5, this.boundingBox.minZ, + this.boundingBox.maxX, var7, this.boundingBox.maxZ); + + if (this.worldObj.isAABBInMaterial(var9, Material.water)) { + var2 += 1.0D / (double) var1; + } + } + + double var23 = Math.sqrt(this.motionX * this.motionX + this.motionZ * this.motionZ); + double var6; + double var8; + + if (var23 > 0.26249999999999996D) { + var6 = Math.cos((double) this.rotationYaw * Math.PI / 180.0D); + var8 = Math.sin((double) this.rotationYaw * Math.PI / 180.0D); + + for (int var10 = 0; (double) var10 < 1.0D + var23 * 60.0D; ++var10) { + double var11 = (double) (this.rand.nextFloat() * 2.0F - 1.0F); + double var13 = (double) (this.rand.nextInt(2) * 2 - 1) * 0.7D; + double var15; + double var17; + + if (this.rand.nextBoolean()) { + var15 = this.posX - var6 * var11 * 0.8D + var8 * var13; + var17 = this.posZ - var8 * var11 * 0.8D - var6 * var13; + this.worldObj.spawnParticle("splash", var15, this.posY - 0.125D, var17, this.motionX, this.motionY, + this.motionZ); + } else { + var15 = this.posX + var6 + var8 * var11 * 0.7D; + var17 = this.posZ + var8 - var6 * var11 * 0.7D; + this.worldObj.spawnParticle("splash", var15, this.posY - 0.125D, var17, this.motionX, this.motionY, + this.motionZ); + } + } + } + + double var12; + double var25; + + if (this.worldObj.isRemote && this.field_70279_a) { + if (this.boatPosRotationIncrements > 0) { + var6 = this.posX + (this.boatX - this.posX) / (double) this.boatPosRotationIncrements; + var8 = this.posY + (this.boatY - this.posY) / (double) this.boatPosRotationIncrements; + var25 = this.posZ + (this.boatZ - this.posZ) / (double) this.boatPosRotationIncrements; + var12 = MathHelper.wrapAngleTo180_double(this.boatYaw - (double) this.rotationYaw); + this.rotationYaw = (float) ((double) this.rotationYaw + + var12 / (double) this.boatPosRotationIncrements); + this.rotationPitch = (float) ((double) this.rotationPitch + + (this.boatPitch - (double) this.rotationPitch) / (double) this.boatPosRotationIncrements); + --this.boatPosRotationIncrements; + this.setPosition(var6, var8, var25); + this.setRotation(this.rotationYaw, this.rotationPitch); + } else { + var6 = this.posX + this.motionX; + var8 = this.posY + this.motionY; + var25 = this.posZ + this.motionZ; + this.setPosition(var6, var8, var25); + + if (this.onGround) { + this.motionX *= 0.5D; + this.motionY *= 0.5D; + this.motionZ *= 0.5D; + } + + this.motionX *= 0.9900000095367432D; + this.motionY *= 0.949999988079071D; + this.motionZ *= 0.9900000095367432D; + } + } else { + if (var2 < 1.0D) { + var6 = var2 * 2.0D - 1.0D; + this.motionY += 0.03999999910593033D * var6; + } else { + if (this.motionY < 0.0D) { + this.motionY /= 2.0D; + } + + this.motionY += 0.007000000216066837D; + } + + if (this.riddenByEntity != null) { + this.motionX += this.riddenByEntity.motionX * this.speedMultiplier; + this.motionZ += this.riddenByEntity.motionZ * this.speedMultiplier; + } + + var6 = Math.sqrt(this.motionX * this.motionX + this.motionZ * this.motionZ); + + if (var6 > 0.35D) { + var8 = 0.35D / var6; + this.motionX *= var8; + this.motionZ *= var8; + var6 = 0.35D; + } + + if (var6 > var23 && this.speedMultiplier < 0.35D) { + this.speedMultiplier += (0.35D - this.speedMultiplier) / 35.0D; + + if (this.speedMultiplier > 0.35D) { + this.speedMultiplier = 0.35D; + } + } else { + this.speedMultiplier -= (this.speedMultiplier - 0.07D) / 35.0D; + + if (this.speedMultiplier < 0.07D) { + this.speedMultiplier = 0.07D; + } + } + + if (this.onGround) { + this.motionX *= 0.5D; + this.motionY *= 0.5D; + this.motionZ *= 0.5D; + } + + this.moveEntity(this.motionX, this.motionY, this.motionZ); + + if (this.isCollidedHorizontally && var23 > 0.2D) { + if (!this.worldObj.isRemote && !this.isDead) { + this.setDead(); + int var24; + + for (var24 = 0; var24 < 3; ++var24) { + this.dropItemWithOffset(Block.planks.blockID, 1, 0.0F); + } + + for (var24 = 0; var24 < 2; ++var24) { + this.dropItemWithOffset(Item.stick.itemID, 1, 0.0F); + } + } + } else { + this.motionX *= 0.9900000095367432D; + this.motionY *= 0.949999988079071D; + this.motionZ *= 0.9900000095367432D; + } + + this.rotationPitch = 0.0F; + var8 = (double) this.rotationYaw; + var25 = this.prevPosX - this.posX; + var12 = this.prevPosZ - this.posZ; + + if (var25 * var25 + var12 * var12 > 0.001D) { + var8 = (double) ((float) (Math.atan2(var12, var25) * 180.0D / Math.PI)); + } + + double var14 = MathHelper.wrapAngleTo180_double(var8 - (double) this.rotationYaw); + + if (var14 > 20.0D) { + var14 = 20.0D; + } + + if (var14 < -20.0D) { + var14 = -20.0D; + } + + this.rotationYaw = (float) ((double) this.rotationYaw + var14); + this.setRotation(this.rotationYaw, this.rotationPitch); + + if (!this.worldObj.isRemote) { + List var16 = this.worldObj.getEntitiesWithinAABBExcludingEntity(this, + this.boundingBox.expand(0.20000000298023224D, 0.0D, 0.20000000298023224D)); + int var26; + + if (var16 != null && !var16.isEmpty()) { + for (var26 = 0; var26 < var16.size(); ++var26) { + Entity var18 = (Entity) var16.get(var26); + + if (var18 != this.riddenByEntity && var18.canBePushed() && var18 instanceof EntityBoat) { + var18.applyEntityCollision(this); + } + } + } + + for (var26 = 0; var26 < 4; ++var26) { + int var27 = MathHelper.floor_double(this.posX + ((double) (var26 % 2) - 0.5D) * 0.8D); + int var19 = MathHelper.floor_double(this.posZ + ((double) (var26 / 2) - 0.5D) * 0.8D); + + for (int var20 = 0; var20 < 2; ++var20) { + int var21 = MathHelper.floor_double(this.posY) + var20; + int var22 = this.worldObj.getBlockId(var27, var21, var19); + + if (var22 == Block.snow.blockID) { + this.worldObj.setBlockToAir(var27, var21, var19); + } else if (var22 == Block.waterlily.blockID) { + this.worldObj.destroyBlock(var27, var21, var19, true); + } + } + } + + if (this.riddenByEntity != null && this.riddenByEntity.isDead) { + this.riddenByEntity = null; + } + } + } + } + + public void updateRiderPosition() { + if (this.riddenByEntity != null) { + double var1 = Math.cos((double) this.rotationYaw * Math.PI / 180.0D) * 0.4D; + double var3 = Math.sin((double) this.rotationYaw * Math.PI / 180.0D) * 0.4D; + this.riddenByEntity.setPosition(this.posX + var1, + this.posY + this.getMountedYOffset() + this.riddenByEntity.getYOffset(), this.posZ + var3); + } + } + + /** + * (abstract) Protected helper method to write subclass entity data to NBT. + */ + protected void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) { + } + + /** + * (abstract) Protected helper method to read subclass entity data from NBT. + */ + protected void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) { + } + + /** + * Called when a player interacts with a mob. e.g. gets milk from a cow, gets + * into the saddle on a pig. + */ + public boolean interact(EntityPlayer par1EntityPlayer) { + if (this.riddenByEntity != null && this.riddenByEntity instanceof EntityPlayer + && this.riddenByEntity != par1EntityPlayer) { + return true; + } else { + if (!this.worldObj.isRemote) { + par1EntityPlayer.mountEntity(this); + } + + return true; + } + } + + /** + * Sets the damage taken from the last hit. + */ + public void setDamageTaken(int par1) { + this.dataWatcher.updateObject(19, Integer.valueOf(par1)); + } + + /** + * Gets the damage taken from the last hit. + */ + public int getDamageTaken() { + return this.dataWatcher.getWatchableObjectInt(19); + } + + /** + * Sets the time to count down from since the last time entity was hit. + */ + public void setTimeSinceHit(int par1) { + this.dataWatcher.updateObject(17, Integer.valueOf(par1)); + } + + /** + * Gets the time since the last hit. + */ + public int getTimeSinceHit() { + return this.dataWatcher.getWatchableObjectInt(17); + } + + /** + * Sets the forward direction of the entity. + */ + public void setForwardDirection(int par1) { + this.dataWatcher.updateObject(18, Integer.valueOf(par1)); + } + + /** + * Gets the forward direction of the entity. + */ + public int getForwardDirection() { + return this.dataWatcher.getWatchableObjectInt(18); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityBodyHelper.java b/sp-server/src/main/java/net/minecraft/src/EntityBodyHelper.java new file mode 100644 index 0000000..cd5674d --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityBodyHelper.java @@ -0,0 +1,55 @@ +package net.minecraft.src; + +public class EntityBodyHelper { + /** Instance of EntityLiving. */ + private EntityLiving theLiving; + private int field_75666_b = 0; + private float field_75667_c = 0.0F; + + public EntityBodyHelper(EntityLiving par1EntityLiving) { + this.theLiving = par1EntityLiving; + } + + public void func_75664_a() { + double var1 = this.theLiving.posX - this.theLiving.prevPosX; + double var3 = this.theLiving.posZ - this.theLiving.prevPosZ; + + if (var1 * var1 + var3 * var3 > 2.500000277905201E-7D) { + this.theLiving.renderYawOffset = this.theLiving.rotationYaw; + this.theLiving.rotationYawHead = this.func_75665_a(this.theLiving.renderYawOffset, + this.theLiving.rotationYawHead, 75.0F); + this.field_75667_c = this.theLiving.rotationYawHead; + this.field_75666_b = 0; + } else { + float var5 = 75.0F; + + if (Math.abs(this.theLiving.rotationYawHead - this.field_75667_c) > 15.0F) { + this.field_75666_b = 0; + this.field_75667_c = this.theLiving.rotationYawHead; + } else { + ++this.field_75666_b; + + if (this.field_75666_b > 10) { + var5 = Math.max(1.0F - (float) (this.field_75666_b - 10) / 10.0F, 0.0F) * 75.0F; + } + } + + this.theLiving.renderYawOffset = this.func_75665_a(this.theLiving.rotationYawHead, + this.theLiving.renderYawOffset, var5); + } + } + + private float func_75665_a(float par1, float par2, float par3) { + float var4 = MathHelper.wrapAngleTo180_float(par1 - par2); + + if (var4 < -par3) { + var4 = -par3; + } + + if (var4 >= par3) { + var4 = par3; + } + + return par1 - var4; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityCaveSpider.java b/sp-server/src/main/java/net/minecraft/src/EntityCaveSpider.java new file mode 100644 index 0000000..bc81c07 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityCaveSpider.java @@ -0,0 +1,43 @@ +package net.minecraft.src; + +public class EntityCaveSpider extends EntitySpider { + public EntityCaveSpider(World par1World) { + super(par1World); + this.texture = "/mob/cavespider.png"; + this.setSize(0.7F, 0.5F); + } + + public int getMaxHealth() { + return 12; + } + + public boolean attackEntityAsMob(Entity par1Entity) { + if (super.attackEntityAsMob(par1Entity)) { + if (par1Entity instanceof EntityLiving) { + byte var2 = 0; + + if (this.worldObj.difficultySetting > 1) { + if (this.worldObj.difficultySetting == 2) { + var2 = 7; + } else if (this.worldObj.difficultySetting == 3) { + var2 = 15; + } + } + + if (var2 > 0) { + ((EntityLiving) par1Entity).addPotionEffect(new PotionEffect(Potion.poison.id, var2 * 20, 0)); + } + } + + return true; + } else { + return false; + } + } + + /** + * Initialize this creature. + */ + public void initCreature() { + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityChicken.java b/sp-server/src/main/java/net/minecraft/src/EntityChicken.java new file mode 100644 index 0000000..e5f04a3 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityChicken.java @@ -0,0 +1,156 @@ +package net.minecraft.src; + +public class EntityChicken extends EntityAnimal { + public boolean field_70885_d = false; + public float field_70886_e = 0.0F; + public float destPos = 0.0F; + public float field_70884_g; + public float field_70888_h; + public float field_70889_i = 1.0F; + + /** The time until the next egg is spawned. */ + public int timeUntilNextEgg; + + public EntityChicken(World par1World) { + super(par1World); + this.texture = "/mob/chicken.png"; + this.setSize(0.3F, 0.7F); + this.timeUntilNextEgg = this.rand.nextInt(6000) + 6000; + float var2 = 0.25F; + this.tasks.addTask(0, new EntityAISwimming(this)); + this.tasks.addTask(1, new EntityAIPanic(this, 0.38F)); + this.tasks.addTask(2, new EntityAIMate(this, var2)); + this.tasks.addTask(3, new EntityAITempt(this, 0.25F, Item.seeds.itemID, false)); + this.tasks.addTask(4, new EntityAIFollowParent(this, 0.28F)); + this.tasks.addTask(5, new EntityAIWander(this, var2)); + this.tasks.addTask(6, new EntityAIWatchClosest(this, EntityPlayer.class, 6.0F)); + this.tasks.addTask(7, new EntityAILookIdle(this)); + } + + /** + * Returns true if the newer Entity AI code should be run + */ + public boolean isAIEnabled() { + return true; + } + + public int getMaxHealth() { + return 4; + } + + /** + * Called frequently so the entity can update its state every tick as required. + * For example, zombies and skeletons use this to react to sunlight and start to + * burn. + */ + public void onLivingUpdate() { + super.onLivingUpdate(); + this.field_70888_h = this.field_70886_e; + this.field_70884_g = this.destPos; + this.destPos = (float) ((double) this.destPos + (double) (this.onGround ? -1 : 4) * 0.3D); + + if (this.destPos < 0.0F) { + this.destPos = 0.0F; + } + + if (this.destPos > 1.0F) { + this.destPos = 1.0F; + } + + if (!this.onGround && this.field_70889_i < 1.0F) { + this.field_70889_i = 1.0F; + } + + this.field_70889_i = (float) ((double) this.field_70889_i * 0.9D); + + if (!this.onGround && this.motionY < 0.0D) { + this.motionY *= 0.6D; + } + + this.field_70886_e += this.field_70889_i * 2.0F; + + if (!this.isChild() && !this.worldObj.isRemote && --this.timeUntilNextEgg <= 0) { + this.playSound("mob.chicken.plop", 1.0F, (this.rand.nextFloat() - this.rand.nextFloat()) * 0.2F + 1.0F); + this.dropItem(Item.egg.itemID, 1); + this.timeUntilNextEgg = this.rand.nextInt(6000) + 6000; + } + } + + /** + * Called when the mob is falling. Calculates and applies fall damage. + */ + protected void fall(float par1) { + } + + /** + * Returns the sound this mob makes while it's alive. + */ + protected String getLivingSound() { + return "mob.chicken.say"; + } + + /** + * Returns the sound this mob makes when it is hurt. + */ + protected String getHurtSound() { + return "mob.chicken.hurt"; + } + + /** + * Returns the sound this mob makes on death. + */ + protected String getDeathSound() { + return "mob.chicken.hurt"; + } + + /** + * Plays step sound at given x, y, z for the entity + */ + protected void playStepSound(int par1, int par2, int par3, int par4) { + this.playSound("mob.chicken.step", 0.15F, 1.0F); + } + + /** + * Returns the item ID for the item the mob drops on death. + */ + protected int getDropItemId() { + return Item.feather.itemID; + } + + /** + * Drop 0-2 items of this living's type + */ + protected void dropFewItems(boolean par1, int par2) { + int var3 = this.rand.nextInt(3) + this.rand.nextInt(1 + par2); + + for (int var4 = 0; var4 < var3; ++var4) { + this.dropItem(Item.feather.itemID, 1); + } + + if (this.isBurning()) { + this.dropItem(Item.chickenCooked.itemID, 1); + } else { + this.dropItem(Item.chickenRaw.itemID, 1); + } + } + + /** + * This function is used when two same-species animals in 'love mode' breed to + * generate the new baby animal. + */ + public EntityChicken spawnBabyAnimal(EntityAgeable par1EntityAgeable) { + return new EntityChicken(this.worldObj); + } + + /** + * Checks if the parameter is an item which this animal can be fed to breed it + * (wheat, carrots or seeds depending on the animal type) + */ + public boolean isBreedingItem(ItemStack par1ItemStack) { + return par1ItemStack != null && par1ItemStack.getItem() instanceof ItemSeeds; + } + + public EntityAgeable createChild(EntityAgeable par1EntityAgeable) { + return this.spawnBabyAnimal(par1EntityAgeable); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityCow.java b/sp-server/src/main/java/net/minecraft/src/EntityCow.java new file mode 100644 index 0000000..08a9973 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityCow.java @@ -0,0 +1,126 @@ +package net.minecraft.src; + +public class EntityCow extends EntityAnimal { + public EntityCow(World par1World) { + super(par1World); + this.texture = "/mob/cow.png"; + this.setSize(0.9F, 1.3F); + this.getNavigator().setAvoidsWater(true); + this.tasks.addTask(0, new EntityAISwimming(this)); + this.tasks.addTask(1, new EntityAIPanic(this, 0.38F)); + this.tasks.addTask(2, new EntityAIMate(this, 0.2F)); + this.tasks.addTask(3, new EntityAITempt(this, 0.25F, Item.wheat.itemID, false)); + this.tasks.addTask(4, new EntityAIFollowParent(this, 0.25F)); + this.tasks.addTask(5, new EntityAIWander(this, 0.2F)); + this.tasks.addTask(6, new EntityAIWatchClosest(this, EntityPlayer.class, 6.0F)); + this.tasks.addTask(7, new EntityAILookIdle(this)); + } + + /** + * Returns true if the newer Entity AI code should be run + */ + public boolean isAIEnabled() { + return true; + } + + public int getMaxHealth() { + return 10; + } + + /** + * Returns the sound this mob makes while it's alive. + */ + protected String getLivingSound() { + return "mob.cow.say"; + } + + /** + * Returns the sound this mob makes when it is hurt. + */ + protected String getHurtSound() { + return "mob.cow.hurt"; + } + + /** + * Returns the sound this mob makes on death. + */ + protected String getDeathSound() { + return "mob.cow.hurt"; + } + + /** + * Plays step sound at given x, y, z for the entity + */ + protected void playStepSound(int par1, int par2, int par3, int par4) { + this.playSound("mob.cow.step", 0.15F, 1.0F); + } + + /** + * Returns the volume for the sounds this mob makes. + */ + protected float getSoundVolume() { + return 0.4F; + } + + /** + * Returns the item ID for the item the mob drops on death. + */ + protected int getDropItemId() { + return Item.leather.itemID; + } + + /** + * Drop 0-2 items of this living's type + */ + protected void dropFewItems(boolean par1, int par2) { + int var3 = this.rand.nextInt(3) + this.rand.nextInt(1 + par2); + int var4; + + for (var4 = 0; var4 < var3; ++var4) { + this.dropItem(Item.leather.itemID, 1); + } + + var3 = this.rand.nextInt(3) + 1 + this.rand.nextInt(1 + par2); + + for (var4 = 0; var4 < var3; ++var4) { + if (this.isBurning()) { + this.dropItem(Item.beefCooked.itemID, 1); + } else { + this.dropItem(Item.beefRaw.itemID, 1); + } + } + } + + /** + * Called when a player interacts with a mob. e.g. gets milk from a cow, gets + * into the saddle on a pig. + */ + public boolean interact(EntityPlayer par1EntityPlayer) { + ItemStack var2 = par1EntityPlayer.inventory.getCurrentItem(); + + if (var2 != null && var2.itemID == Item.bucketEmpty.itemID) { + if (--var2.stackSize <= 0) { + par1EntityPlayer.inventory.setInventorySlotContents(par1EntityPlayer.inventory.currentItem, + new ItemStack(Item.bucketMilk)); + } else if (!par1EntityPlayer.inventory.addItemStackToInventory(new ItemStack(Item.bucketMilk))) { + par1EntityPlayer.dropPlayerItem(new ItemStack(Item.bucketMilk.itemID, 1, 0)); + } + + return true; + } else { + return super.interact(par1EntityPlayer); + } + } + + /** + * This function is used when two same-species animals in 'love mode' breed to + * generate the new baby animal. + */ + public EntityCow spawnBabyAnimal(EntityAgeable par1EntityAgeable) { + return new EntityCow(this.worldObj); + } + + public EntityAgeable createChild(EntityAgeable par1EntityAgeable) { + return this.spawnBabyAnimal(par1EntityAgeable); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityCreature.java b/sp-server/src/main/java/net/minecraft/src/EntityCreature.java new file mode 100644 index 0000000..8fa676d --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityCreature.java @@ -0,0 +1,252 @@ +package net.minecraft.src; + +public abstract class EntityCreature extends EntityLiving { + private PathEntity pathToEntity; + + /** The Entity this EntityCreature is set to attack. */ + protected Entity entityToAttack; + + /** + * returns true if a creature has attacked recently only used for creepers and + * skeletons + */ + protected boolean hasAttacked = false; + + /** Used to make a creature speed up and wander away when hit. */ + protected int fleeingTick = 0; + + public EntityCreature(World par1World) { + super(par1World); + } + + /** + * Disables a mob's ability to move on its own while true. + */ + protected boolean isMovementCeased() { + return false; + } + + protected void updateEntityActionState() { + this.worldObj.theProfiler.startSection("ai"); + + if (this.fleeingTick > 0) { + --this.fleeingTick; + } + + this.hasAttacked = this.isMovementCeased(); + float var1 = 16.0F; + + if (this.entityToAttack == null) { + this.entityToAttack = this.findPlayerToAttack(); + + if (this.entityToAttack != null) { + this.pathToEntity = this.worldObj.getPathEntityToEntity(this, this.entityToAttack, var1, true, false, + false, true); + } + } else if (this.entityToAttack.isEntityAlive()) { + float var2 = this.entityToAttack.getDistanceToEntity(this); + + if (this.canEntityBeSeen(this.entityToAttack)) { + this.attackEntity(this.entityToAttack, var2); + } + } else { + this.entityToAttack = null; + } + + this.worldObj.theProfiler.endSection(); + + if (!this.hasAttacked && this.entityToAttack != null + && (this.pathToEntity == null || this.rand.nextInt(20) == 0)) { + this.pathToEntity = this.worldObj.getPathEntityToEntity(this, this.entityToAttack, var1, true, false, false, + true); + } else if (!this.hasAttacked && (this.pathToEntity == null && this.rand.nextInt(180) == 0 + || this.rand.nextInt(120) == 0 || this.fleeingTick > 0) && this.entityAge < 100) { + this.updateWanderPath(); + } + + int var21 = MathHelper.floor_double(this.boundingBox.minY + 0.5D); + boolean var3 = this.isInWater(); + boolean var4 = this.handleLavaMovement(); + this.rotationPitch = 0.0F; + + if (this.pathToEntity != null && this.rand.nextInt(100) != 0) { + this.worldObj.theProfiler.startSection("followpath"); + Vec3 var5 = this.pathToEntity.getPosition(this); + double var6 = (double) (this.width * 2.0F); + + while (var5 != null && var5.squareDistanceTo(this.posX, var5.yCoord, this.posZ) < var6 * var6) { + this.pathToEntity.incrementPathIndex(); + + if (this.pathToEntity.isFinished()) { + var5 = null; + this.pathToEntity = null; + } else { + var5 = this.pathToEntity.getPosition(this); + } + } + + this.isJumping = false; + + if (var5 != null) { + double var8 = var5.xCoord - this.posX; + double var10 = var5.zCoord - this.posZ; + double var12 = var5.yCoord - (double) var21; + float var14 = (float) (Math.atan2(var10, var8) * 180.0D / Math.PI) - 90.0F; + float var15 = MathHelper.wrapAngleTo180_float(var14 - this.rotationYaw); + this.moveForward = this.moveSpeed; + + if (var15 > 30.0F) { + var15 = 30.0F; + } + + if (var15 < -30.0F) { + var15 = -30.0F; + } + + this.rotationYaw += var15; + + if (this.hasAttacked && this.entityToAttack != null) { + double var16 = this.entityToAttack.posX - this.posX; + double var18 = this.entityToAttack.posZ - this.posZ; + float var20 = this.rotationYaw; + this.rotationYaw = (float) (Math.atan2(var18, var16) * 180.0D / Math.PI) - 90.0F; + var15 = (var20 - this.rotationYaw + 90.0F) * (float) Math.PI / 180.0F; + this.moveStrafing = -MathHelper.sin(var15) * this.moveForward * 1.0F; + this.moveForward = MathHelper.cos(var15) * this.moveForward * 1.0F; + } + + if (var12 > 0.0D) { + this.isJumping = true; + } + } + + if (this.entityToAttack != null) { + this.faceEntity(this.entityToAttack, 30.0F, 30.0F); + } + + if (this.isCollidedHorizontally && !this.hasPath()) { + this.isJumping = true; + } + + if (this.rand.nextFloat() < 0.8F && (var3 || var4)) { + this.isJumping = true; + } + + this.worldObj.theProfiler.endSection(); + } else { + super.updateEntityActionState(); + this.pathToEntity = null; + } + } + + /** + * Time remaining during which the Animal is sped up and flees. + */ + protected void updateWanderPath() { + this.worldObj.theProfiler.startSection("stroll"); + boolean var1 = false; + int var2 = -1; + int var3 = -1; + int var4 = -1; + float var5 = -99999.0F; + + for (int var6 = 0; var6 < 10; ++var6) { + int var7 = MathHelper.floor_double(this.posX + (double) this.rand.nextInt(13) - 6.0D); + int var8 = MathHelper.floor_double(this.posY + (double) this.rand.nextInt(7) - 3.0D); + int var9 = MathHelper.floor_double(this.posZ + (double) this.rand.nextInt(13) - 6.0D); + float var10 = this.getBlockPathWeight(var7, var8, var9); + + if (var10 > var5) { + var5 = var10; + var2 = var7; + var3 = var8; + var4 = var9; + var1 = true; + } + } + + if (var1) { + this.pathToEntity = this.worldObj.getEntityPathToXYZ(this, var2, var3, var4, 10.0F, true, false, false, + true); + } + + this.worldObj.theProfiler.endSection(); + } + + /** + * Basic mob attack. Default to touch of death in EntityCreature. Overridden by + * each mob to define their attack. + */ + protected void attackEntity(Entity par1Entity, float par2) { + } + + /** + * Takes a coordinate in and returns a weight to determine how likely this + * creature will try to path to the block. Args: x, y, z + */ + public float getBlockPathWeight(int par1, int par2, int par3) { + return 0.0F; + } + + /** + * Finds the closest player within 16 blocks to attack, or null if this Entity + * isn't interested in attacking (Animals, Spiders at day, peaceful PigZombies). + */ + protected Entity findPlayerToAttack() { + return null; + } + + /** + * Checks if the entity's current position is a valid location to spawn this + * entity. + */ + public boolean getCanSpawnHere() { + int var1 = MathHelper.floor_double(this.posX); + int var2 = MathHelper.floor_double(this.boundingBox.minY); + int var3 = MathHelper.floor_double(this.posZ); + return super.getCanSpawnHere() && this.getBlockPathWeight(var1, var2, var3) >= 0.0F; + } + + /** + * if the entity got a PathEntity it returns true, else false + */ + public boolean hasPath() { + return this.pathToEntity != null; + } + + /** + * sets the pathToEntity + */ + public void setPathToEntity(PathEntity par1PathEntity) { + this.pathToEntity = par1PathEntity; + } + + /** + * returns the target Entity + */ + public Entity getEntityToAttack() { + return this.entityToAttack; + } + + /** + * Sets the entity which is to be attacked. + */ + public void setTarget(Entity par1Entity) { + this.entityToAttack = par1Entity; + } + + /** + * This method returns a value to be applied directly to entity speed, this + * factor is less than 1 when a slowdown potion effect is applied, more than 1 + * when a haste potion effect is applied and 2 for fleeing entities. + */ + public float getSpeedModifier() { + float var1 = super.getSpeedModifier(); + + if (this.fleeingTick > 0 && !this.isAIEnabled()) { + var1 *= 2.0F; + } + + return var1; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityCreeper.java b/sp-server/src/main/java/net/minecraft/src/EntityCreeper.java new file mode 100644 index 0000000..e5a58b9 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityCreeper.java @@ -0,0 +1,201 @@ +package net.minecraft.src; + +public class EntityCreeper extends EntityMob { + /** + * Time when this creeper was last in an active state (Messed up code here, + * probably causes creeper animation to go weird) + */ + private int lastActiveTime; + + /** + * The amount of time since the creeper was close enough to the player to ignite + */ + private int timeSinceIgnited; + private int fuseTime = 30; + + /** Explosion radius for this creeper. */ + private int explosionRadius = 3; + + public EntityCreeper(World par1World) { + super(par1World); + this.texture = "/mob/creeper.png"; + this.tasks.addTask(1, new EntityAISwimming(this)); + this.tasks.addTask(2, new EntityAICreeperSwell(this)); + this.tasks.addTask(3, new EntityAIAvoidEntity(this, EntityOcelot.class, 6.0F, 0.25F, 0.3F)); + this.tasks.addTask(4, new EntityAIAttackOnCollide(this, 0.25F, false)); + this.tasks.addTask(5, new EntityAIWander(this, 0.2F)); + this.tasks.addTask(6, new EntityAIWatchClosest(this, EntityPlayer.class, 8.0F)); + this.tasks.addTask(6, new EntityAILookIdle(this)); + this.targetTasks.addTask(1, new EntityAINearestAttackableTarget(this, EntityPlayer.class, 16.0F, 0, true)); + this.targetTasks.addTask(2, new EntityAIHurtByTarget(this, false)); + } + + /** + * Returns true if the newer Entity AI code should be run + */ + public boolean isAIEnabled() { + return true; + } + + public int func_82143_as() { + return this.getAttackTarget() == null ? 3 : 3 + (this.health - 1); + } + + /** + * Called when the mob is falling. Calculates and applies fall damage. + */ + protected void fall(float par1) { + super.fall(par1); + this.timeSinceIgnited = (int) ((float) this.timeSinceIgnited + par1 * 1.5F); + + if (this.timeSinceIgnited > this.fuseTime - 5) { + this.timeSinceIgnited = this.fuseTime - 5; + } + } + + public int getMaxHealth() { + return 20; + } + + protected void entityInit() { + super.entityInit(); + this.dataWatcher.addObject(16, Byte.valueOf((byte) -1)); + this.dataWatcher.addObject(17, Byte.valueOf((byte) 0)); + } + + /** + * (abstract) Protected helper method to write subclass entity data to NBT. + */ + public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) { + super.writeEntityToNBT(par1NBTTagCompound); + + if (this.dataWatcher.getWatchableObjectByte(17) == 1) { + par1NBTTagCompound.setBoolean("powered", true); + } + + par1NBTTagCompound.setShort("Fuse", (short) this.fuseTime); + par1NBTTagCompound.setByte("ExplosionRadius", (byte) this.explosionRadius); + } + + /** + * (abstract) Protected helper method to read subclass entity data from NBT. + */ + public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) { + super.readEntityFromNBT(par1NBTTagCompound); + this.dataWatcher.updateObject(17, Byte.valueOf((byte) (par1NBTTagCompound.getBoolean("powered") ? 1 : 0))); + + if (par1NBTTagCompound.hasKey("Fuse")) { + this.fuseTime = par1NBTTagCompound.getShort("Fuse"); + } + + if (par1NBTTagCompound.hasKey("ExplosionRadius")) { + this.explosionRadius = par1NBTTagCompound.getByte("ExplosionRadius"); + } + } + + /** + * Called to update the entity's position/logic. + */ + public void onUpdate() { + if (this.isEntityAlive()) { + this.lastActiveTime = this.timeSinceIgnited; + int var1 = this.getCreeperState(); + + if (var1 > 0 && this.timeSinceIgnited == 0) { + this.playSound("random.fuse", 1.0F, 0.5F); + } + + this.timeSinceIgnited += var1; + + if (this.timeSinceIgnited < 0) { + this.timeSinceIgnited = 0; + } + + if (this.timeSinceIgnited >= this.fuseTime) { + this.timeSinceIgnited = this.fuseTime; + + if (!this.worldObj.isRemote) { + boolean var2 = this.worldObj.getGameRules().getGameRuleBooleanValue("mobGriefing"); + + if (this.getPowered()) { + this.worldObj.createExplosion(this, this.posX, this.posY, this.posZ, + (float) (this.explosionRadius * 2), var2); + } else { + this.worldObj.createExplosion(this, this.posX, this.posY, this.posZ, + (float) this.explosionRadius, var2); + } + + this.setDead(); + } + } + } + + super.onUpdate(); + } + + /** + * Returns the sound this mob makes when it is hurt. + */ + protected String getHurtSound() { + return "mob.creeper.say"; + } + + /** + * Returns the sound this mob makes on death. + */ + protected String getDeathSound() { + return "mob.creeper.death"; + } + + /** + * Called when the mob's health reaches 0. + */ + public void onDeath(DamageSource par1DamageSource) { + super.onDeath(par1DamageSource); + + if (par1DamageSource.getEntity() instanceof EntitySkeleton) { + int var2 = Item.record13.itemID + this.rand.nextInt(Item.recordWait.itemID - Item.record13.itemID + 1); + this.dropItem(var2, 1); + } + } + + public boolean attackEntityAsMob(Entity par1Entity) { + return true; + } + + /** + * Returns true if the creeper is powered by a lightning bolt. + */ + public boolean getPowered() { + return this.dataWatcher.getWatchableObjectByte(17) == 1; + } + + /** + * Returns the item ID for the item the mob drops on death. + */ + protected int getDropItemId() { + return Item.gunpowder.itemID; + } + + /** + * Returns the current state of creeper, -1 is idle, 1 is 'in fuse' + */ + public int getCreeperState() { + return this.dataWatcher.getWatchableObjectByte(16); + } + + /** + * Sets the state of creeper, -1 to idle and 1 to be 'in fuse' + */ + public void setCreeperState(int par1) { + this.dataWatcher.updateObject(16, Byte.valueOf((byte) par1)); + } + + /** + * Called when a lightning bolt hits the entity. + */ + public void onStruckByLightning(EntityLightningBolt par1EntityLightningBolt) { + super.onStruckByLightning(par1EntityLightningBolt); + this.dataWatcher.updateObject(17, Byte.valueOf((byte) 1)); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityDamageSource.java b/sp-server/src/main/java/net/minecraft/src/EntityDamageSource.java new file mode 100644 index 0000000..91f6a30 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityDamageSource.java @@ -0,0 +1,41 @@ +package net.minecraft.src; + +public class EntityDamageSource extends DamageSource { + protected Entity damageSourceEntity; + + public EntityDamageSource(String par1Str, Entity par2Entity) { + super(par1Str); + this.damageSourceEntity = par2Entity; + } + + public Entity getEntity() { + return this.damageSourceEntity; + } + + /** + * Returns the message to be displayed on player death. + */ + public String getDeathMessage(EntityLiving par1EntityLiving) { + ItemStack var2 = this.damageSourceEntity instanceof EntityLiving + ? ((EntityLiving) this.damageSourceEntity).getHeldItem() + : null; + String var3 = "death.attack." + this.damageType; + String var4 = var3 + ".item"; + return var2 != null && var2.hasDisplayName() && StatCollector.func_94522_b(var4) + ? StatCollector.translateToLocalFormatted(var4, + new Object[] { par1EntityLiving.getTranslatedEntityName(), + this.damageSourceEntity.getTranslatedEntityName(), var2.getDisplayName() }) + : StatCollector.translateToLocalFormatted(var3, + new Object[] { par1EntityLiving.getTranslatedEntityName(), + this.damageSourceEntity.getTranslatedEntityName() }); + } + + /** + * Return whether this damage source will have its damage amount scaled based on + * the current difficulty. + */ + public boolean isDifficultyScaled() { + return this.damageSourceEntity != null && this.damageSourceEntity instanceof EntityLiving + && !(this.damageSourceEntity instanceof EntityPlayer); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityDamageSourceIndirect.java b/sp-server/src/main/java/net/minecraft/src/EntityDamageSourceIndirect.java new file mode 100644 index 0000000..8a57f4b --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityDamageSourceIndirect.java @@ -0,0 +1,36 @@ +package net.minecraft.src; + +public class EntityDamageSourceIndirect extends EntityDamageSource { + private Entity indirectEntity; + + public EntityDamageSourceIndirect(String par1Str, Entity par2Entity, Entity par3Entity) { + super(par1Str, par2Entity); + this.indirectEntity = par3Entity; + } + + public Entity getSourceOfDamage() { + return this.damageSourceEntity; + } + + public Entity getEntity() { + return this.indirectEntity; + } + + /** + * Returns the message to be displayed on player death. + */ + public String getDeathMessage(EntityLiving par1EntityLiving) { + String var2 = this.indirectEntity == null ? this.damageSourceEntity.getTranslatedEntityName() + : this.indirectEntity.getTranslatedEntityName(); + ItemStack var3 = this.indirectEntity instanceof EntityLiving + ? ((EntityLiving) this.indirectEntity).getHeldItem() + : null; + String var4 = "death.attack." + this.damageType; + String var5 = var4 + ".item"; + return var3 != null && var3.hasDisplayName() && StatCollector.func_94522_b(var5) + ? StatCollector.translateToLocalFormatted(var5, + new Object[] { par1EntityLiving.getTranslatedEntityName(), var2, var3.getDisplayName() }) + : StatCollector.translateToLocalFormatted(var4, + new Object[] { par1EntityLiving.getTranslatedEntityName(), var2 }); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityDragon.java b/sp-server/src/main/java/net/minecraft/src/EntityDragon.java new file mode 100644 index 0000000..25b5f05 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityDragon.java @@ -0,0 +1,696 @@ +package net.minecraft.src; + +import java.util.Iterator; +import java.util.List; + +public class EntityDragon extends EntityLiving implements IEntityMultiPart { + public double targetX; + public double targetY; + public double targetZ; + + /** + * Ring buffer array for the last 64 Y-positions and yaw rotations. Used to + * calculate offsets for the animations. + */ + public double[][] ringBuffer = new double[64][3]; + + /** + * Index into the ring buffer. Incremented once per tick and restarts at 0 once + * it reaches the end of the buffer. + */ + public int ringBufferIndex = -1; + + /** An array containing all body parts of this dragon */ + public EntityDragonPart[] dragonPartArray; + + /** The head bounding box of a dragon */ + public EntityDragonPart dragonPartHead; + + /** The body bounding box of a dragon */ + public EntityDragonPart dragonPartBody; + public EntityDragonPart dragonPartTail1; + public EntityDragonPart dragonPartTail2; + public EntityDragonPart dragonPartTail3; + public EntityDragonPart dragonPartWing1; + public EntityDragonPart dragonPartWing2; + + /** Animation time at previous tick. */ + public float prevAnimTime = 0.0F; + + /** + * Animation time, used to control the speed of the animation cycles (wings + * flapping, jaw opening, etc.) + */ + public float animTime = 0.0F; + + /** Force selecting a new flight target at next tick if set to true. */ + public boolean forceNewTarget = false; + + /** + * Activated if the dragon is flying though obsidian, white stone or bedrock. + * Slows movement and animation speed. + */ + public boolean slowed = false; + private Entity target; + public int deathTicks = 0; + + /** The current endercrystal that is healing this dragon */ + public EntityEnderCrystal healingEnderCrystal = null; + + public EntityDragon(World par1World) { + super(par1World); + this.dragonPartArray = new EntityDragonPart[] { + this.dragonPartHead = new EntityDragonPart(this, "head", 6.0F, 6.0F), + this.dragonPartBody = new EntityDragonPart(this, "body", 8.0F, 8.0F), + this.dragonPartTail1 = new EntityDragonPart(this, "tail", 4.0F, 4.0F), + this.dragonPartTail2 = new EntityDragonPart(this, "tail", 4.0F, 4.0F), + this.dragonPartTail3 = new EntityDragonPart(this, "tail", 4.0F, 4.0F), + this.dragonPartWing1 = new EntityDragonPart(this, "wing", 4.0F, 4.0F), + this.dragonPartWing2 = new EntityDragonPart(this, "wing", 4.0F, 4.0F) }; + this.setEntityHealth(this.getMaxHealth()); + this.texture = "/mob/enderdragon/ender.png"; + this.setSize(16.0F, 8.0F); + this.noClip = true; + this.isImmuneToFire = true; + this.targetY = 100.0D; + this.ignoreFrustumCheck = true; + } + + public int getMaxHealth() { + return 200; + } + + protected void entityInit() { + super.entityInit(); + this.dataWatcher.addObject(16, new Integer(this.getMaxHealth())); + } + + /** + * Returns a double[3] array with movement offsets, used to calculate trailing + * tail/neck positions. [0] = yaw offset, [1] = y offset, [2] = unused, always + * 0. Parameters: buffer index offset, partial ticks. + */ + public double[] getMovementOffsets(int par1, float par2) { + if (this.health <= 0) { + par2 = 0.0F; + } + + par2 = 1.0F - par2; + int var3 = this.ringBufferIndex - par1 * 1 & 63; + int var4 = this.ringBufferIndex - par1 * 1 - 1 & 63; + double[] var5 = new double[3]; + double var6 = this.ringBuffer[var3][0]; + double var8 = MathHelper.wrapAngleTo180_double(this.ringBuffer[var4][0] - var6); + var5[0] = var6 + var8 * (double) par2; + var6 = this.ringBuffer[var3][1]; + var8 = this.ringBuffer[var4][1] - var6; + var5[1] = var6 + var8 * (double) par2; + var5[2] = this.ringBuffer[var3][2] + (this.ringBuffer[var4][2] - this.ringBuffer[var3][2]) * (double) par2; + return var5; + } + + /** + * Called frequently so the entity can update its state every tick as required. + * For example, zombies and skeletons use this to react to sunlight and start to + * burn. + */ + public void onLivingUpdate() { + float var1; + float var2; + + if (!this.worldObj.isRemote) { + this.dataWatcher.updateObject(16, Integer.valueOf(this.health)); + } else { + var1 = MathHelper.cos(this.animTime * (float) Math.PI * 2.0F); + var2 = MathHelper.cos(this.prevAnimTime * (float) Math.PI * 2.0F); + + if (var2 <= -0.3F && var1 >= -0.3F) { + this.worldObj.playSound(this.posX, this.posY, this.posZ, "mob.enderdragon.wings", 5.0F, + 0.8F + this.rand.nextFloat() * 0.3F, false); + } + } + + this.prevAnimTime = this.animTime; + float var3; + + if (this.health <= 0) { + var1 = (this.rand.nextFloat() - 0.5F) * 8.0F; + var2 = (this.rand.nextFloat() - 0.5F) * 4.0F; + var3 = (this.rand.nextFloat() - 0.5F) * 8.0F; + this.worldObj.spawnParticle("largeexplode", this.posX + (double) var1, this.posY + 2.0D + (double) var2, + this.posZ + (double) var3, 0.0D, 0.0D, 0.0D); + } else { + this.updateDragonEnderCrystal(); + var1 = 0.2F / (MathHelper.sqrt_double(this.motionX * this.motionX + this.motionZ * this.motionZ) * 10.0F + + 1.0F); + var1 *= (float) Math.pow(2.0D, this.motionY); + + if (this.slowed) { + this.animTime += var1 * 0.5F; + } else { + this.animTime += var1; + } + + this.rotationYaw = MathHelper.wrapAngleTo180_float(this.rotationYaw); + + if (this.ringBufferIndex < 0) { + for (int var25 = 0; var25 < this.ringBuffer.length; ++var25) { + this.ringBuffer[var25][0] = (double) this.rotationYaw; + this.ringBuffer[var25][1] = this.posY; + } + } + + if (++this.ringBufferIndex == this.ringBuffer.length) { + this.ringBufferIndex = 0; + } + + this.ringBuffer[this.ringBufferIndex][0] = (double) this.rotationYaw; + this.ringBuffer[this.ringBufferIndex][1] = this.posY; + double var4; + double var6; + double var8; + double var26; + float var31; + + if (this.worldObj.isRemote) { + if (this.newPosRotationIncrements > 0) { + var26 = this.posX + (this.newPosX - this.posX) / (double) this.newPosRotationIncrements; + var4 = this.posY + (this.newPosY - this.posY) / (double) this.newPosRotationIncrements; + var6 = this.posZ + (this.newPosZ - this.posZ) / (double) this.newPosRotationIncrements; + var8 = MathHelper.wrapAngleTo180_double(this.newRotationYaw - (double) this.rotationYaw); + this.rotationYaw = (float) ((double) this.rotationYaw + + var8 / (double) this.newPosRotationIncrements); + this.rotationPitch = (float) ((double) this.rotationPitch + + (this.newRotationPitch - (double) this.rotationPitch) + / (double) this.newPosRotationIncrements); + --this.newPosRotationIncrements; + this.setPosition(var26, var4, var6); + this.setRotation(this.rotationYaw, this.rotationPitch); + } + } else { + var26 = this.targetX - this.posX; + var4 = this.targetY - this.posY; + var6 = this.targetZ - this.posZ; + var8 = var26 * var26 + var4 * var4 + var6 * var6; + + if (this.target != null) { + this.targetX = this.target.posX; + this.targetZ = this.target.posZ; + double var10 = this.targetX - this.posX; + double var12 = this.targetZ - this.posZ; + double var14 = Math.sqrt(var10 * var10 + var12 * var12); + double var16 = 0.4000000059604645D + var14 / 80.0D - 1.0D; + + if (var16 > 10.0D) { + var16 = 10.0D; + } + + this.targetY = this.target.boundingBox.minY + var16; + } else { + this.targetX += this.rand.nextGaussian() * 2.0D; + this.targetZ += this.rand.nextGaussian() * 2.0D; + } + + if (this.forceNewTarget || var8 < 100.0D || var8 > 22500.0D || this.isCollidedHorizontally + || this.isCollidedVertically) { + this.setNewTarget(); + } + + var4 /= (double) MathHelper.sqrt_double(var26 * var26 + var6 * var6); + var31 = 0.6F; + + if (var4 < (double) (-var31)) { + var4 = (double) (-var31); + } + + if (var4 > (double) var31) { + var4 = (double) var31; + } + + this.motionY += var4 * 0.10000000149011612D; + this.rotationYaw = MathHelper.wrapAngleTo180_float(this.rotationYaw); + double var11 = 180.0D - Math.atan2(var26, var6) * 180.0D / Math.PI; + double var13 = MathHelper.wrapAngleTo180_double(var11 - (double) this.rotationYaw); + + if (var13 > 50.0D) { + var13 = 50.0D; + } + + if (var13 < -50.0D) { + var13 = -50.0D; + } + + Vec3 var15 = this.worldObj.getWorldVec3Pool() + .getVecFromPool(this.targetX - this.posX, this.targetY - this.posY, this.targetZ - this.posZ) + .normalize(); + Vec3 var39 = this.worldObj.getWorldVec3Pool() + .getVecFromPool((double) MathHelper.sin(this.rotationYaw * (float) Math.PI / 180.0F), + this.motionY, (double) (-MathHelper.cos(this.rotationYaw * (float) Math.PI / 180.0F))) + .normalize(); + float var17 = (float) (var39.dotProduct(var15) + 0.5D) / 1.5F; + + if (var17 < 0.0F) { + var17 = 0.0F; + } + + this.randomYawVelocity *= 0.8F; + float var18 = MathHelper.sqrt_double(this.motionX * this.motionX + this.motionZ * this.motionZ) * 1.0F + + 1.0F; + double var19 = Math.sqrt(this.motionX * this.motionX + this.motionZ * this.motionZ) * 1.0D + 1.0D; + + if (var19 > 40.0D) { + var19 = 40.0D; + } + + this.randomYawVelocity = (float) ((double) this.randomYawVelocity + + var13 * (0.699999988079071D / var19 / (double) var18)); + this.rotationYaw += this.randomYawVelocity * 0.1F; + float var21 = (float) (2.0D / (var19 + 1.0D)); + float var22 = 0.06F; + this.moveFlying(0.0F, -1.0F, var22 * (var17 * var21 + (1.0F - var21))); + + if (this.slowed) { + this.moveEntity(this.motionX * 0.800000011920929D, this.motionY * 0.800000011920929D, + this.motionZ * 0.800000011920929D); + } else { + this.moveEntity(this.motionX, this.motionY, this.motionZ); + } + + Vec3 var23 = this.worldObj.getWorldVec3Pool().getVecFromPool(this.motionX, this.motionY, this.motionZ) + .normalize(); + float var24 = (float) (var23.dotProduct(var39) + 1.0D) / 2.0F; + var24 = 0.8F + 0.15F * var24; + this.motionX *= (double) var24; + this.motionZ *= (double) var24; + this.motionY *= 0.9100000262260437D; + } + + this.renderYawOffset = this.rotationYaw; + this.dragonPartHead.width = this.dragonPartHead.height = 3.0F; + this.dragonPartTail1.width = this.dragonPartTail1.height = 2.0F; + this.dragonPartTail2.width = this.dragonPartTail2.height = 2.0F; + this.dragonPartTail3.width = this.dragonPartTail3.height = 2.0F; + this.dragonPartBody.height = 3.0F; + this.dragonPartBody.width = 5.0F; + this.dragonPartWing1.height = 2.0F; + this.dragonPartWing1.width = 4.0F; + this.dragonPartWing2.height = 3.0F; + this.dragonPartWing2.width = 4.0F; + var2 = (float) (this.getMovementOffsets(5, 1.0F)[1] - this.getMovementOffsets(10, 1.0F)[1]) * 10.0F / 180.0F + * (float) Math.PI; + var3 = MathHelper.cos(var2); + float var27 = -MathHelper.sin(var2); + float var5 = this.rotationYaw * (float) Math.PI / 180.0F; + float var28 = MathHelper.sin(var5); + float var7 = MathHelper.cos(var5); + this.dragonPartBody.onUpdate(); + this.dragonPartBody.setLocationAndAngles(this.posX + (double) (var28 * 0.5F), this.posY, + this.posZ - (double) (var7 * 0.5F), 0.0F, 0.0F); + this.dragonPartWing1.onUpdate(); + this.dragonPartWing1.setLocationAndAngles(this.posX + (double) (var7 * 4.5F), this.posY + 2.0D, + this.posZ + (double) (var28 * 4.5F), 0.0F, 0.0F); + this.dragonPartWing2.onUpdate(); + this.dragonPartWing2.setLocationAndAngles(this.posX - (double) (var7 * 4.5F), this.posY + 2.0D, + this.posZ - (double) (var28 * 4.5F), 0.0F, 0.0F); + + if (!this.worldObj.isRemote && this.hurtTime == 0) { + this.collideWithEntities(this.worldObj.getEntitiesWithinAABBExcludingEntity(this, + this.dragonPartWing1.boundingBox.expand(4.0D, 2.0D, 4.0D).offset(0.0D, -2.0D, 0.0D))); + this.collideWithEntities(this.worldObj.getEntitiesWithinAABBExcludingEntity(this, + this.dragonPartWing2.boundingBox.expand(4.0D, 2.0D, 4.0D).offset(0.0D, -2.0D, 0.0D))); + this.attackEntitiesInList(this.worldObj.getEntitiesWithinAABBExcludingEntity(this, + this.dragonPartHead.boundingBox.expand(1.0D, 1.0D, 1.0D))); + } + + double[] var29 = this.getMovementOffsets(5, 1.0F); + double[] var9 = this.getMovementOffsets(0, 1.0F); + var31 = MathHelper.sin(this.rotationYaw * (float) Math.PI / 180.0F - this.randomYawVelocity * 0.01F); + float var33 = MathHelper.cos(this.rotationYaw * (float) Math.PI / 180.0F - this.randomYawVelocity * 0.01F); + this.dragonPartHead.onUpdate(); + this.dragonPartHead.setLocationAndAngles(this.posX + (double) (var31 * 5.5F * var3), + this.posY + (var9[1] - var29[1]) * 1.0D + (double) (var27 * 5.5F), + this.posZ - (double) (var33 * 5.5F * var3), 0.0F, 0.0F); + + for (int var30 = 0; var30 < 3; ++var30) { + EntityDragonPart var32 = null; + + if (var30 == 0) { + var32 = this.dragonPartTail1; + } + + if (var30 == 1) { + var32 = this.dragonPartTail2; + } + + if (var30 == 2) { + var32 = this.dragonPartTail3; + } + + double[] var34 = this.getMovementOffsets(12 + var30 * 2, 1.0F); + float var35 = this.rotationYaw * (float) Math.PI / 180.0F + + this.simplifyAngle(var34[0] - var29[0]) * (float) Math.PI / 180.0F * 1.0F; + float var37 = MathHelper.sin(var35); + float var36 = MathHelper.cos(var35); + float var38 = 1.5F; + float var40 = (float) (var30 + 1) * 2.0F; + var32.onUpdate(); + var32.setLocationAndAngles(this.posX - (double) ((var28 * var38 + var37 * var40) * var3), + this.posY + (var34[1] - var29[1]) * 1.0D - (double) ((var40 + var38) * var27) + 1.5D, + this.posZ + (double) ((var7 * var38 + var36 * var40) * var3), 0.0F, 0.0F); + } + + if (!this.worldObj.isRemote) { + this.slowed = this.destroyBlocksInAABB(this.dragonPartHead.boundingBox) + | this.destroyBlocksInAABB(this.dragonPartBody.boundingBox); + } + } + } + + /** + * Updates the state of the enderdragon's current endercrystal. + */ + private void updateDragonEnderCrystal() { + if (this.healingEnderCrystal != null) { + if (this.healingEnderCrystal.isDead) { + if (!this.worldObj.isRemote) { + this.attackEntityFromPart(this.dragonPartHead, DamageSource.setExplosionSource((Explosion) null), + 10); + } + + this.healingEnderCrystal = null; + } else if (this.ticksExisted % 10 == 0 && this.getHealth() < this.getMaxHealth()) { + this.setEntityHealth(this.getHealth() + 1); + } + } + + if (this.rand.nextInt(10) == 0) { + float var1 = 32.0F; + List var2 = this.worldObj.getEntitiesWithinAABB(EntityEnderCrystal.class, + this.boundingBox.expand((double) var1, (double) var1, (double) var1)); + EntityEnderCrystal var3 = null; + double var4 = Double.MAX_VALUE; + Iterator var6 = var2.iterator(); + + while (var6.hasNext()) { + EntityEnderCrystal var7 = (EntityEnderCrystal) var6.next(); + double var8 = var7.getDistanceSqToEntity(this); + + if (var8 < var4) { + var4 = var8; + var3 = var7; + } + } + + this.healingEnderCrystal = var3; + } + } + + /** + * Pushes all entities inside the list away from the enderdragon. + */ + private void collideWithEntities(List par1List) { + double var2 = (this.dragonPartBody.boundingBox.minX + this.dragonPartBody.boundingBox.maxX) / 2.0D; + double var4 = (this.dragonPartBody.boundingBox.minZ + this.dragonPartBody.boundingBox.maxZ) / 2.0D; + Iterator var6 = par1List.iterator(); + + while (var6.hasNext()) { + Entity var7 = (Entity) var6.next(); + + if (var7 instanceof EntityLiving) { + double var8 = var7.posX - var2; + double var10 = var7.posZ - var4; + double var12 = var8 * var8 + var10 * var10; + var7.addVelocity(var8 / var12 * 4.0D, 0.20000000298023224D, var10 / var12 * 4.0D); + } + } + } + + /** + * Attacks all entities inside this list, dealing 5 hearts of damage. + */ + private void attackEntitiesInList(List par1List) { + for (int var2 = 0; var2 < par1List.size(); ++var2) { + Entity var3 = (Entity) par1List.get(var2); + + if (var3 instanceof EntityLiving) { + var3.attackEntityFrom(DamageSource.causeMobDamage(this), 10); + } + } + } + + /** + * Sets a new target for the flight AI. It can be a random coordinate or a + * nearby player. + */ + private void setNewTarget() { + this.forceNewTarget = false; + + if (this.rand.nextInt(2) == 0 && !this.worldObj.playerEntities.isEmpty()) { + this.target = (Entity) this.worldObj.playerEntities + .get(this.rand.nextInt(this.worldObj.playerEntities.size())); + } else { + boolean var1 = false; + + do { + this.targetX = 0.0D; + this.targetY = (double) (70.0F + this.rand.nextFloat() * 50.0F); + this.targetZ = 0.0D; + this.targetX += (double) (this.rand.nextFloat() * 120.0F - 60.0F); + this.targetZ += (double) (this.rand.nextFloat() * 120.0F - 60.0F); + double var2 = this.posX - this.targetX; + double var4 = this.posY - this.targetY; + double var6 = this.posZ - this.targetZ; + var1 = var2 * var2 + var4 * var4 + var6 * var6 > 100.0D; + } while (!var1); + + this.target = null; + } + } + + /** + * Simplifies the value of a number by adding/subtracting 180 to the point that + * the number is between -180 and 180. + */ + private float simplifyAngle(double par1) { + return (float) MathHelper.wrapAngleTo180_double(par1); + } + + /** + * Destroys all blocks that aren't associated with 'The End' inside the given + * bounding box. + */ + private boolean destroyBlocksInAABB(AxisAlignedBB par1AxisAlignedBB) { + int var2 = MathHelper.floor_double(par1AxisAlignedBB.minX); + int var3 = MathHelper.floor_double(par1AxisAlignedBB.minY); + int var4 = MathHelper.floor_double(par1AxisAlignedBB.minZ); + int var5 = MathHelper.floor_double(par1AxisAlignedBB.maxX); + int var6 = MathHelper.floor_double(par1AxisAlignedBB.maxY); + int var7 = MathHelper.floor_double(par1AxisAlignedBB.maxZ); + boolean var8 = false; + boolean var9 = false; + + for (int var10 = var2; var10 <= var5; ++var10) { + for (int var11 = var3; var11 <= var6; ++var11) { + for (int var12 = var4; var12 <= var7; ++var12) { + int var13 = this.worldObj.getBlockId(var10, var11, var12); + + if (var13 != 0) { + if (var13 != Block.obsidian.blockID && var13 != Block.whiteStone.blockID + && var13 != Block.bedrock.blockID + && this.worldObj.getGameRules().getGameRuleBooleanValue("mobGriefing")) { + var9 = this.worldObj.setBlockToAir(var10, var11, var12) || var9; + } else { + var8 = true; + } + } + } + } + } + + if (var9) { + double var16 = par1AxisAlignedBB.minX + + (par1AxisAlignedBB.maxX - par1AxisAlignedBB.minX) * (double) this.rand.nextFloat(); + double var17 = par1AxisAlignedBB.minY + + (par1AxisAlignedBB.maxY - par1AxisAlignedBB.minY) * (double) this.rand.nextFloat(); + double var14 = par1AxisAlignedBB.minZ + + (par1AxisAlignedBB.maxZ - par1AxisAlignedBB.minZ) * (double) this.rand.nextFloat(); + this.worldObj.spawnParticle("largeexplode", var16, var17, var14, 0.0D, 0.0D, 0.0D); + } + + return var8; + } + + public boolean attackEntityFromPart(EntityDragonPart par1EntityDragonPart, DamageSource par2DamageSource, + int par3) { + if (par1EntityDragonPart != this.dragonPartHead) { + par3 = par3 / 4 + 1; + } + + float var4 = this.rotationYaw * (float) Math.PI / 180.0F; + float var5 = MathHelper.sin(var4); + float var6 = MathHelper.cos(var4); + this.targetX = this.posX + (double) (var5 * 5.0F) + (double) ((this.rand.nextFloat() - 0.5F) * 2.0F); + this.targetY = this.posY + (double) (this.rand.nextFloat() * 3.0F) + 1.0D; + this.targetZ = this.posZ - (double) (var6 * 5.0F) + (double) ((this.rand.nextFloat() - 0.5F) * 2.0F); + this.target = null; + + if (par2DamageSource.getEntity() instanceof EntityPlayer || par2DamageSource.isExplosion()) { + this.func_82195_e(par2DamageSource, par3); + } + + return true; + } + + /** + * Called when the entity is attacked. + */ + public boolean attackEntityFrom(DamageSource par1DamageSource, int par2) { + return false; + } + + protected boolean func_82195_e(DamageSource par1DamageSource, int par2) { + return super.attackEntityFrom(par1DamageSource, par2); + } + + /** + * handles entity death timer, experience orb and particle creation + */ + protected void onDeathUpdate() { + ++this.deathTicks; + + if (this.deathTicks >= 180 && this.deathTicks <= 200) { + float var1 = (this.rand.nextFloat() - 0.5F) * 8.0F; + float var2 = (this.rand.nextFloat() - 0.5F) * 4.0F; + float var3 = (this.rand.nextFloat() - 0.5F) * 8.0F; + this.worldObj.spawnParticle("hugeexplosion", this.posX + (double) var1, this.posY + 2.0D + (double) var2, + this.posZ + (double) var3, 0.0D, 0.0D, 0.0D); + } + + int var4; + int var5; + + if (!this.worldObj.isRemote) { + if (this.deathTicks > 150 && this.deathTicks % 5 == 0) { + var4 = 1000; + + while (var4 > 0) { + var5 = EntityXPOrb.getXPSplit(var4); + var4 -= var5; + this.worldObj + .spawnEntityInWorld(new EntityXPOrb(this.worldObj, this.posX, this.posY, this.posZ, var5)); + } + } + + if (this.deathTicks == 1) { + this.worldObj.func_82739_e(1018, (int) this.posX, (int) this.posY, (int) this.posZ, 0); + } + } + + this.moveEntity(0.0D, 0.10000000149011612D, 0.0D); + this.renderYawOffset = this.rotationYaw += 20.0F; + + if (this.deathTicks == 200 && !this.worldObj.isRemote) { + var4 = 2000; + + while (var4 > 0) { + var5 = EntityXPOrb.getXPSplit(var4); + var4 -= var5; + this.worldObj.spawnEntityInWorld(new EntityXPOrb(this.worldObj, this.posX, this.posY, this.posZ, var5)); + } + + this.createEnderPortal(MathHelper.floor_double(this.posX), MathHelper.floor_double(this.posZ)); + this.setDead(); + } + } + + /** + * Creates the ender portal leading back to the normal world after defeating the + * enderdragon. + */ + private void createEnderPortal(int par1, int par2) { + byte var3 = 64; + BlockEndPortal.bossDefeated = true; + byte var4 = 4; + + for (int var5 = var3 - 1; var5 <= var3 + 32; ++var5) { + for (int var6 = par1 - var4; var6 <= par1 + var4; ++var6) { + for (int var7 = par2 - var4; var7 <= par2 + var4; ++var7) { + double var8 = (double) (var6 - par1); + double var10 = (double) (var7 - par2); + double var12 = var8 * var8 + var10 * var10; + + if (var12 <= ((double) var4 - 0.5D) * ((double) var4 - 0.5D)) { + if (var5 < var3) { + if (var12 <= ((double) (var4 - 1) - 0.5D) * ((double) (var4 - 1) - 0.5D)) { + this.worldObj.setBlock(var6, var5, var7, Block.bedrock.blockID); + } + } else if (var5 > var3) { + this.worldObj.setBlock(var6, var5, var7, 0); + } else if (var12 > ((double) (var4 - 1) - 0.5D) * ((double) (var4 - 1) - 0.5D)) { + this.worldObj.setBlock(var6, var5, var7, Block.bedrock.blockID); + } else { + this.worldObj.setBlock(var6, var5, var7, Block.endPortal.blockID); + } + } + } + } + } + + this.worldObj.setBlock(par1, var3 + 0, par2, Block.bedrock.blockID); + this.worldObj.setBlock(par1, var3 + 1, par2, Block.bedrock.blockID); + this.worldObj.setBlock(par1, var3 + 2, par2, Block.bedrock.blockID); + this.worldObj.setBlock(par1 - 1, var3 + 2, par2, Block.torchWood.blockID); + this.worldObj.setBlock(par1 + 1, var3 + 2, par2, Block.torchWood.blockID); + this.worldObj.setBlock(par1, var3 + 2, par2 - 1, Block.torchWood.blockID); + this.worldObj.setBlock(par1, var3 + 2, par2 + 1, Block.torchWood.blockID); + this.worldObj.setBlock(par1, var3 + 3, par2, Block.bedrock.blockID); + this.worldObj.setBlock(par1, var3 + 4, par2, Block.dragonEgg.blockID); + BlockEndPortal.bossDefeated = false; + } + + /** + * Makes the entity despawn if requirements are reached + */ + protected void despawnEntity() { + } + + /** + * Return the Entity parts making up this Entity (currently only for dragons) + */ + public Entity[] getParts() { + return this.dragonPartArray; + } + + /** + * Returns true if other Entities should be prevented from moving through this + * Entity. + */ + public boolean canBeCollidedWith() { + return false; + } + + public World func_82194_d() { + return this.worldObj; + } + + /** + * Returns the sound this mob makes while it's alive. + */ + protected String getLivingSound() { + return "mob.enderdragon.growl"; + } + + /** + * Returns the sound this mob makes when it is hurt. + */ + protected String getHurtSound() { + return "mob.enderdragon.hit"; + } + + /** + * Returns the volume for the sounds this mob makes. + */ + protected float getSoundVolume() { + return 5.0F; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityDragonPart.java b/sp-server/src/main/java/net/minecraft/src/EntityDragonPart.java new file mode 100644 index 0000000..ad6b552 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityDragonPart.java @@ -0,0 +1,54 @@ +package net.minecraft.src; + +public class EntityDragonPart extends Entity { + /** The dragon entity this dragon part belongs to */ + public final IEntityMultiPart entityDragonObj; + + /** The name of the Dragon Part */ + public final String name; + + public EntityDragonPart(IEntityMultiPart par1, String par2, float par3, float par4) { + super(par1.func_82194_d()); + this.setSize(par3, par4); + this.entityDragonObj = par1; + this.name = par2; + } + + protected void entityInit() { + } + + /** + * (abstract) Protected helper method to read subclass entity data from NBT. + */ + protected void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) { + } + + /** + * (abstract) Protected helper method to write subclass entity data to NBT. + */ + protected void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) { + } + + /** + * Returns true if other Entities should be prevented from moving through this + * Entity. + */ + public boolean canBeCollidedWith() { + return true; + } + + /** + * Called when the entity is attacked. + */ + public boolean attackEntityFrom(DamageSource par1DamageSource, int par2) { + return this.isEntityInvulnerable() ? false + : this.entityDragonObj.attackEntityFromPart(this, par1DamageSource, par2); + } + + /** + * Returns true if Entity argument is equal to this Entity + */ + public boolean isEntityEqual(Entity par1Entity) { + return this == par1Entity || this.entityDragonObj == par1Entity; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityEgg.java b/sp-server/src/main/java/net/minecraft/src/EntityEgg.java new file mode 100644 index 0000000..19a564f --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityEgg.java @@ -0,0 +1,48 @@ +package net.minecraft.src; + +public class EntityEgg extends EntityThrowable { + public EntityEgg(World par1World) { + super(par1World); + } + + public EntityEgg(World par1World, EntityLiving par2EntityLiving) { + super(par1World, par2EntityLiving); + } + + public EntityEgg(World par1World, double par2, double par4, double par6) { + super(par1World, par2, par4, par6); + } + + /** + * Called when this EntityThrowable hits a block or entity. + */ + protected void onImpact(MovingObjectPosition par1MovingObjectPosition) { + if (par1MovingObjectPosition.entityHit != null) { + par1MovingObjectPosition.entityHit.attackEntityFrom(DamageSource.causeThrownDamage(this, this.getThrower()), + 0); + } + + if (!this.worldObj.isRemote && this.rand.nextInt(8) == 0) { + byte var2 = 1; + + if (this.rand.nextInt(32) == 0) { + var2 = 4; + } + + for (int var3 = 0; var3 < var2; ++var3) { + EntityChicken var4 = new EntityChicken(this.worldObj); + var4.setGrowingAge(-24000); + var4.setLocationAndAngles(this.posX, this.posY, this.posZ, this.rotationYaw, 0.0F); + this.worldObj.spawnEntityInWorld(var4); + } + } + + for (int var5 = 0; var5 < 8; ++var5) { + this.worldObj.spawnParticle("snowballpoof", this.posX, this.posY, this.posZ, 0.0D, 0.0D, 0.0D); + } + + if (!this.worldObj.isRemote) { + this.setDead(); + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityEggInfo.java b/sp-server/src/main/java/net/minecraft/src/EntityEggInfo.java new file mode 100644 index 0000000..51417a3 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityEggInfo.java @@ -0,0 +1,18 @@ +package net.minecraft.src; + +public class EntityEggInfo { + /** The entityID of the spawned mob */ + public int spawnedID; + + /** Base color of the egg */ + public int primaryColor; + + /** Color of the egg spots */ + public int secondaryColor; + + public EntityEggInfo(int par1, int par2, int par3) { + this.spawnedID = par1; + this.primaryColor = par2; + this.secondaryColor = par3; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityEnderCrystal.java b/sp-server/src/main/java/net/minecraft/src/EntityEnderCrystal.java new file mode 100644 index 0000000..1d1080e --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityEnderCrystal.java @@ -0,0 +1,89 @@ +package net.minecraft.src; + +public class EntityEnderCrystal extends Entity { + /** Used to create the rotation animation when rendering the crystal. */ + public int innerRotation = 0; + public int health; + + public EntityEnderCrystal(World par1World) { + super(par1World); + this.preventEntitySpawning = true; + this.setSize(2.0F, 2.0F); + this.yOffset = this.height / 2.0F; + this.health = 5; + this.innerRotation = this.rand.nextInt(100000); + } + + /** + * returns if this entity triggers Block.onEntityWalking on the blocks they walk + * on. used for spiders and wolves to prevent them from trampling crops + */ + protected boolean canTriggerWalking() { + return false; + } + + protected void entityInit() { + this.dataWatcher.addObject(8, Integer.valueOf(this.health)); + } + + /** + * Called to update the entity's position/logic. + */ + public void onUpdate() { + this.prevPosX = this.posX; + this.prevPosY = this.posY; + this.prevPosZ = this.posZ; + ++this.innerRotation; + this.dataWatcher.updateObject(8, Integer.valueOf(this.health)); + int var1 = MathHelper.floor_double(this.posX); + int var2 = MathHelper.floor_double(this.posY); + int var3 = MathHelper.floor_double(this.posZ); + + if (this.worldObj.getBlockId(var1, var2, var3) != Block.fire.blockID) { + this.worldObj.setBlock(var1, var2, var3, Block.fire.blockID); + } + } + + /** + * (abstract) Protected helper method to write subclass entity data to NBT. + */ + protected void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) { + } + + /** + * (abstract) Protected helper method to read subclass entity data from NBT. + */ + protected void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) { + } + + /** + * Returns true if other Entities should be prevented from moving through this + * Entity. + */ + public boolean canBeCollidedWith() { + return true; + } + + /** + * Called when the entity is attacked. + */ + public boolean attackEntityFrom(DamageSource par1DamageSource, int par2) { + if (this.isEntityInvulnerable()) { + return false; + } else { + if (!this.isDead && !this.worldObj.isRemote) { + this.health = 0; + + if (this.health <= 0) { + this.setDead(); + + if (!this.worldObj.isRemote) { + this.worldObj.createExplosion((Entity) null, this.posX, this.posY, this.posZ, 6.0F, true); + } + } + } + + return true; + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityEnderEye.java b/sp-server/src/main/java/net/minecraft/src/EntityEnderEye.java new file mode 100644 index 0000000..2ab756b --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityEnderEye.java @@ -0,0 +1,171 @@ +package net.minecraft.src; + +public class EntityEnderEye extends Entity { + public int field_70226_a = 0; + + /** 'x' location the eye should float towards. */ + private double targetX; + + /** 'y' location the eye should float towards. */ + private double targetY; + + /** 'z' location the eye should float towards. */ + private double targetZ; + private int despawnTimer; + private boolean shatterOrDrop; + + public EntityEnderEye(World par1World) { + super(par1World); + this.setSize(0.25F, 0.25F); + } + + protected void entityInit() { + } + + public EntityEnderEye(World par1World, double par2, double par4, double par6) { + super(par1World); + this.despawnTimer = 0; + this.setSize(0.25F, 0.25F); + this.setPosition(par2, par4, par6); + this.yOffset = 0.0F; + } + + /** + * The location the eye should float/move towards. Currently used for moving + * towards the nearest stronghold. Args: strongholdX, strongholdY, strongholdZ + */ + public void moveTowards(double par1, int par3, double par4) { + double var6 = par1 - this.posX; + double var8 = par4 - this.posZ; + float var10 = MathHelper.sqrt_double(var6 * var6 + var8 * var8); + + if (var10 > 12.0F) { + this.targetX = this.posX + var6 / (double) var10 * 12.0D; + this.targetZ = this.posZ + var8 / (double) var10 * 12.0D; + this.targetY = this.posY + 8.0D; + } else { + this.targetX = par1; + this.targetY = (double) par3; + this.targetZ = par4; + } + + this.despawnTimer = 0; + this.shatterOrDrop = this.rand.nextInt(5) > 0; + } + + /** + * Called to update the entity's position/logic. + */ + public void onUpdate() { + this.lastTickPosX = this.posX; + this.lastTickPosY = this.posY; + this.lastTickPosZ = this.posZ; + super.onUpdate(); + this.posX += this.motionX; + this.posY += this.motionY; + this.posZ += this.motionZ; + float var1 = MathHelper.sqrt_double(this.motionX * this.motionX + this.motionZ * this.motionZ); + this.rotationYaw = (float) (Math.atan2(this.motionX, this.motionZ) * 180.0D / Math.PI); + + for (this.rotationPitch = (float) (Math.atan2(this.motionY, (double) var1) * 180.0D + / Math.PI); this.rotationPitch - this.prevRotationPitch < -180.0F; this.prevRotationPitch -= 360.0F) { + ; + } + + while (this.rotationPitch - this.prevRotationPitch >= 180.0F) { + this.prevRotationPitch += 360.0F; + } + + while (this.rotationYaw - this.prevRotationYaw < -180.0F) { + this.prevRotationYaw -= 360.0F; + } + + while (this.rotationYaw - this.prevRotationYaw >= 180.0F) { + this.prevRotationYaw += 360.0F; + } + + this.rotationPitch = this.prevRotationPitch + (this.rotationPitch - this.prevRotationPitch) * 0.2F; + this.rotationYaw = this.prevRotationYaw + (this.rotationYaw - this.prevRotationYaw) * 0.2F; + + if (!this.worldObj.isRemote) { + double var2 = this.targetX - this.posX; + double var4 = this.targetZ - this.posZ; + float var6 = (float) Math.sqrt(var2 * var2 + var4 * var4); + float var7 = (float) Math.atan2(var4, var2); + double var8 = (double) var1 + (double) (var6 - var1) * 0.0025D; + + if (var6 < 1.0F) { + var8 *= 0.8D; + this.motionY *= 0.8D; + } + + this.motionX = Math.cos((double) var7) * var8; + this.motionZ = Math.sin((double) var7) * var8; + + if (this.posY < this.targetY) { + this.motionY += (1.0D - this.motionY) * 0.014999999664723873D; + } else { + this.motionY += (-1.0D - this.motionY) * 0.014999999664723873D; + } + } + + float var10 = 0.25F; + + if (this.isInWater()) { + for (int var3 = 0; var3 < 4; ++var3) { + this.worldObj.spawnParticle("bubble", this.posX - this.motionX * (double) var10, + this.posY - this.motionY * (double) var10, this.posZ - this.motionZ * (double) var10, + this.motionX, this.motionY, this.motionZ); + } + } else { + this.worldObj.spawnParticle("portal", + this.posX - this.motionX * (double) var10 + this.rand.nextDouble() * 0.6D - 0.3D, + this.posY - this.motionY * (double) var10 - 0.5D, + this.posZ - this.motionZ * (double) var10 + this.rand.nextDouble() * 0.6D - 0.3D, this.motionX, + this.motionY, this.motionZ); + } + + if (!this.worldObj.isRemote) { + this.setPosition(this.posX, this.posY, this.posZ); + ++this.despawnTimer; + + if (this.despawnTimer > 80 && !this.worldObj.isRemote) { + this.setDead(); + + if (this.shatterOrDrop) { + this.worldObj.spawnEntityInWorld(new EntityItem(this.worldObj, this.posX, this.posY, this.posZ, + new ItemStack(Item.eyeOfEnder))); + } else { + this.worldObj.playAuxSFX(2003, (int) Math.round(this.posX), (int) Math.round(this.posY), + (int) Math.round(this.posZ), 0); + } + } + } + } + + /** + * (abstract) Protected helper method to write subclass entity data to NBT. + */ + public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) { + } + + /** + * (abstract) Protected helper method to read subclass entity data from NBT. + */ + public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) { + } + + /** + * Gets how bright this entity is. + */ + public float getBrightness(float par1) { + return 1.0F; + } + + /** + * If returns false, the item will not inflict any damage against entities. + */ + public boolean canAttackWithItem() { + return false; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityEnderPearl.java b/sp-server/src/main/java/net/minecraft/src/EntityEnderPearl.java new file mode 100644 index 0000000..faaaed2 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityEnderPearl.java @@ -0,0 +1,40 @@ +package net.minecraft.src; + +public class EntityEnderPearl extends EntityThrowable { + public EntityEnderPearl(World par1World) { + super(par1World); + } + + public EntityEnderPearl(World par1World, EntityLiving par2EntityLiving) { + super(par1World, par2EntityLiving); + } + + /** + * Called when this EntityThrowable hits a block or entity. + */ + protected void onImpact(MovingObjectPosition par1MovingObjectPosition) { + if (par1MovingObjectPosition.entityHit != null) { + par1MovingObjectPosition.entityHit.attackEntityFrom(DamageSource.causeThrownDamage(this, this.getThrower()), + 0); + } + + for (int var2 = 0; var2 < 32; ++var2) { + this.worldObj.spawnParticle("portal", this.posX, this.posY + this.rand.nextDouble() * 2.0D, this.posZ, + this.rand.nextGaussian(), 0.0D, this.rand.nextGaussian()); + } + + if (!this.worldObj.isRemote) { + if (this.getThrower() != null && this.getThrower() instanceof EntityPlayerMP) { + EntityPlayerMP var3 = (EntityPlayerMP) this.getThrower(); + + if (!var3.playerNetServerHandler.connectionClosed && var3.worldObj == this.worldObj) { + this.getThrower().setPositionAndUpdate(this.posX, this.posY, this.posZ); + this.getThrower().fallDistance = 0.0F; + this.getThrower().attackEntityFrom(DamageSource.fall, 5); + } + } + + this.setDead(); + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityEnderman.java b/sp-server/src/main/java/net/minecraft/src/EntityEnderman.java new file mode 100644 index 0000000..b2e705f --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityEnderman.java @@ -0,0 +1,432 @@ +package net.minecraft.src; + +public class EntityEnderman extends EntityMob { + private static boolean[] carriableBlocks = new boolean[256]; + + /** + * Counter to delay the teleportation of an enderman towards the currently + * attacked target + */ + private int teleportDelay = 0; + private int field_70826_g = 0; + private boolean field_104003_g; + + public EntityEnderman(World par1World) { + super(par1World); + this.texture = "/mob/enderman.png"; + this.moveSpeed = 0.2F; + this.setSize(0.6F, 2.9F); + this.stepHeight = 1.0F; + } + + public int getMaxHealth() { + return 40; + } + + protected void entityInit() { + super.entityInit(); + this.dataWatcher.addObject(16, new Byte((byte) 0)); + this.dataWatcher.addObject(17, new Byte((byte) 0)); + this.dataWatcher.addObject(18, new Byte((byte) 0)); + } + + /** + * (abstract) Protected helper method to write subclass entity data to NBT. + */ + public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) { + super.writeEntityToNBT(par1NBTTagCompound); + par1NBTTagCompound.setShort("carried", (short) this.getCarried()); + par1NBTTagCompound.setShort("carriedData", (short) this.getCarryingData()); + } + + /** + * (abstract) Protected helper method to read subclass entity data from NBT. + */ + public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) { + super.readEntityFromNBT(par1NBTTagCompound); + this.setCarried(par1NBTTagCompound.getShort("carried")); + this.setCarryingData(par1NBTTagCompound.getShort("carriedData")); + } + + /** + * Finds the closest player within 16 blocks to attack, or null if this Entity + * isn't interested in attacking (Animals, Spiders at day, peaceful PigZombies). + */ + protected Entity findPlayerToAttack() { + EntityPlayer var1 = this.worldObj.getClosestVulnerablePlayerToEntity(this, 64.0D); + + if (var1 != null) { + if (this.shouldAttackPlayer(var1)) { + this.field_104003_g = true; + + if (this.field_70826_g == 0) { + this.worldObj.playSoundAtEntity(var1, "mob.endermen.stare", 1.0F, 1.0F); + } + + if (this.field_70826_g++ == 5) { + this.field_70826_g = 0; + this.setScreaming(true); + return var1; + } + } else { + this.field_70826_g = 0; + } + } + + return null; + } + + /** + * Checks to see if this enderman should be attacking this player + */ + private boolean shouldAttackPlayer(EntityPlayer par1EntityPlayer) { + ItemStack var2 = par1EntityPlayer.inventory.armorInventory[3]; + + if (var2 != null && var2.itemID == Block.pumpkin.blockID) { + return false; + } else { + Vec3 var3 = par1EntityPlayer.getLook(1.0F).normalize(); + Vec3 var4 = this.worldObj.getWorldVec3Pool().getVecFromPool(this.posX - par1EntityPlayer.posX, + this.boundingBox.minY + (double) (this.height / 2.0F) + - (par1EntityPlayer.posY + (double) par1EntityPlayer.getEyeHeight()), + this.posZ - par1EntityPlayer.posZ); + double var5 = var4.lengthVector(); + var4 = var4.normalize(); + double var7 = var3.dotProduct(var4); + return var7 > 1.0D - 0.025D / var5 ? par1EntityPlayer.canEntityBeSeen(this) : false; + } + } + + /** + * Called frequently so the entity can update its state every tick as required. + * For example, zombies and skeletons use this to react to sunlight and start to + * burn. + */ + public void onLivingUpdate() { + if (this.isWet()) { + this.attackEntityFrom(DamageSource.drown, 1); + } + + this.moveSpeed = this.entityToAttack != null ? 6.5F : 0.3F; + int var1; + + if (!this.worldObj.isRemote && this.worldObj.getGameRules().getGameRuleBooleanValue("mobGriefing")) { + int var2; + int var3; + int var4; + + if (this.getCarried() == 0) { + if (this.rand.nextInt(20) == 0) { + var1 = MathHelper.floor_double(this.posX - 2.0D + this.rand.nextDouble() * 4.0D); + var2 = MathHelper.floor_double(this.posY + this.rand.nextDouble() * 3.0D); + var3 = MathHelper.floor_double(this.posZ - 2.0D + this.rand.nextDouble() * 4.0D); + var4 = this.worldObj.getBlockId(var1, var2, var3); + + if (carriableBlocks[var4]) { + this.setCarried(this.worldObj.getBlockId(var1, var2, var3)); + this.setCarryingData(this.worldObj.getBlockMetadata(var1, var2, var3)); + this.worldObj.setBlock(var1, var2, var3, 0); + } + } + } else if (this.rand.nextInt(2000) == 0) { + var1 = MathHelper.floor_double(this.posX - 1.0D + this.rand.nextDouble() * 2.0D); + var2 = MathHelper.floor_double(this.posY + this.rand.nextDouble() * 2.0D); + var3 = MathHelper.floor_double(this.posZ - 1.0D + this.rand.nextDouble() * 2.0D); + var4 = this.worldObj.getBlockId(var1, var2, var3); + int var5 = this.worldObj.getBlockId(var1, var2 - 1, var3); + + if (var4 == 0 && var5 > 0 && Block.blocksList[var5].renderAsNormalBlock()) { + this.worldObj.setBlock(var1, var2, var3, this.getCarried(), this.getCarryingData(), 3); + this.setCarried(0); + } + } + } + + for (var1 = 0; var1 < 2; ++var1) { + this.worldObj.spawnParticle("portal", this.posX + (this.rand.nextDouble() - 0.5D) * (double) this.width, + this.posY + this.rand.nextDouble() * (double) this.height - 0.25D, + this.posZ + (this.rand.nextDouble() - 0.5D) * (double) this.width, + (this.rand.nextDouble() - 0.5D) * 2.0D, -this.rand.nextDouble(), + (this.rand.nextDouble() - 0.5D) * 2.0D); + } + + if (this.worldObj.isDaytime() && !this.worldObj.isRemote) { + float var6 = this.getBrightness(1.0F); + + if (var6 > 0.5F + && this.worldObj.canBlockSeeTheSky(MathHelper.floor_double(this.posX), + MathHelper.floor_double(this.posY), MathHelper.floor_double(this.posZ)) + && this.rand.nextFloat() * 30.0F < (var6 - 0.4F) * 2.0F) { + this.entityToAttack = null; + this.setScreaming(false); + this.field_104003_g = false; + this.teleportRandomly(); + } + } + + if (this.isWet() || this.isBurning()) { + this.entityToAttack = null; + this.setScreaming(false); + this.field_104003_g = false; + this.teleportRandomly(); + } + + if (this.isScreaming() && !this.field_104003_g && this.rand.nextInt(100) == 0) { + this.setScreaming(false); + } + + this.isJumping = false; + + if (this.entityToAttack != null) { + this.faceEntity(this.entityToAttack, 100.0F, 100.0F); + } + + if (!this.worldObj.isRemote && this.isEntityAlive()) { + if (this.entityToAttack != null) { + if (this.entityToAttack instanceof EntityPlayer + && this.shouldAttackPlayer((EntityPlayer) this.entityToAttack)) { + this.moveStrafing = this.moveForward = 0.0F; + this.moveSpeed = 0.0F; + + if (this.entityToAttack.getDistanceSqToEntity(this) < 16.0D) { + this.teleportRandomly(); + } + + this.teleportDelay = 0; + } else if (this.entityToAttack.getDistanceSqToEntity(this) > 256.0D && this.teleportDelay++ >= 30 + && this.teleportToEntity(this.entityToAttack)) { + this.teleportDelay = 0; + } + } else { + this.setScreaming(false); + this.teleportDelay = 0; + } + } + + super.onLivingUpdate(); + } + + /** + * Teleport the enderman to a random nearby position + */ + protected boolean teleportRandomly() { + double var1 = this.posX + (this.rand.nextDouble() - 0.5D) * 64.0D; + double var3 = this.posY + (double) (this.rand.nextInt(64) - 32); + double var5 = this.posZ + (this.rand.nextDouble() - 0.5D) * 64.0D; + return this.teleportTo(var1, var3, var5); + } + + /** + * Teleport the enderman to another entity + */ + protected boolean teleportToEntity(Entity par1Entity) { + Vec3 var2 = this.worldObj.getWorldVec3Pool().getVecFromPool(this.posX - par1Entity.posX, this.boundingBox.minY + + (double) (this.height / 2.0F) - par1Entity.posY + (double) par1Entity.getEyeHeight(), + this.posZ - par1Entity.posZ); + var2 = var2.normalize(); + double var3 = 16.0D; + double var5 = this.posX + (this.rand.nextDouble() - 0.5D) * 8.0D - var2.xCoord * var3; + double var7 = this.posY + (double) (this.rand.nextInt(16) - 8) - var2.yCoord * var3; + double var9 = this.posZ + (this.rand.nextDouble() - 0.5D) * 8.0D - var2.zCoord * var3; + return this.teleportTo(var5, var7, var9); + } + + /** + * Teleport the enderman + */ + protected boolean teleportTo(double par1, double par3, double par5) { + double var7 = this.posX; + double var9 = this.posY; + double var11 = this.posZ; + this.posX = par1; + this.posY = par3; + this.posZ = par5; + boolean var13 = false; + int var14 = MathHelper.floor_double(this.posX); + int var15 = MathHelper.floor_double(this.posY); + int var16 = MathHelper.floor_double(this.posZ); + int var18; + + if (this.worldObj.blockExists(var14, var15, var16)) { + boolean var17 = false; + + while (!var17 && var15 > 0) { + var18 = this.worldObj.getBlockId(var14, var15 - 1, var16); + + if (var18 != 0 && Block.blocksList[var18].blockMaterial.blocksMovement()) { + var17 = true; + } else { + --this.posY; + --var15; + } + } + + if (var17) { + this.setPosition(this.posX, this.posY, this.posZ); + + if (this.worldObj.getCollidingBoundingBoxes(this, this.boundingBox).isEmpty() + && !this.worldObj.isAnyLiquid(this.boundingBox)) { + var13 = true; + } + } + } + + if (!var13) { + this.setPosition(var7, var9, var11); + return false; + } else { + short var30 = 128; + + for (var18 = 0; var18 < var30; ++var18) { + double var19 = (double) var18 / ((double) var30 - 1.0D); + float var21 = (this.rand.nextFloat() - 0.5F) * 0.2F; + float var22 = (this.rand.nextFloat() - 0.5F) * 0.2F; + float var23 = (this.rand.nextFloat() - 0.5F) * 0.2F; + double var24 = var7 + (this.posX - var7) * var19 + + (this.rand.nextDouble() - 0.5D) * (double) this.width * 2.0D; + double var26 = var9 + (this.posY - var9) * var19 + this.rand.nextDouble() * (double) this.height; + double var28 = var11 + (this.posZ - var11) * var19 + + (this.rand.nextDouble() - 0.5D) * (double) this.width * 2.0D; + this.worldObj.spawnParticle("portal", var24, var26, var28, (double) var21, (double) var22, + (double) var23); + } + + this.worldObj.playSoundEffect(var7, var9, var11, "mob.endermen.portal", 1.0F, 1.0F); + this.playSound("mob.endermen.portal", 1.0F, 1.0F); + return true; + } + } + + /** + * Returns the sound this mob makes while it's alive. + */ + protected String getLivingSound() { + return this.isScreaming() ? "mob.endermen.scream" : "mob.endermen.idle"; + } + + /** + * Returns the sound this mob makes when it is hurt. + */ + protected String getHurtSound() { + return "mob.endermen.hit"; + } + + /** + * Returns the sound this mob makes on death. + */ + protected String getDeathSound() { + return "mob.endermen.death"; + } + + /** + * Returns the item ID for the item the mob drops on death. + */ + protected int getDropItemId() { + return Item.enderPearl.itemID; + } + + /** + * Drop 0-2 items of this living's type + */ + protected void dropFewItems(boolean par1, int par2) { + int var3 = this.getDropItemId(); + + if (var3 > 0) { + int var4 = this.rand.nextInt(2 + par2); + + for (int var5 = 0; var5 < var4; ++var5) { + this.dropItem(var3, 1); + } + } + } + + /** + * Set the id of the block an enderman carries + */ + public void setCarried(int par1) { + this.dataWatcher.updateObject(16, Byte.valueOf((byte) (par1 & 255))); + } + + /** + * Get the id of the block an enderman carries + */ + public int getCarried() { + return this.dataWatcher.getWatchableObjectByte(16); + } + + /** + * Set the metadata of the block an enderman carries + */ + public void setCarryingData(int par1) { + this.dataWatcher.updateObject(17, Byte.valueOf((byte) (par1 & 255))); + } + + /** + * Get the metadata of the block an enderman carries + */ + public int getCarryingData() { + return this.dataWatcher.getWatchableObjectByte(17); + } + + /** + * Called when the entity is attacked. + */ + public boolean attackEntityFrom(DamageSource par1DamageSource, int par2) { + if (this.isEntityInvulnerable()) { + return false; + } else { + this.setScreaming(true); + + if (par1DamageSource instanceof EntityDamageSource + && par1DamageSource.getEntity() instanceof EntityPlayer) { + this.field_104003_g = true; + } + + if (par1DamageSource instanceof EntityDamageSourceIndirect) { + this.field_104003_g = false; + + for (int var3 = 0; var3 < 64; ++var3) { + if (this.teleportRandomly()) { + return true; + } + } + + return false; + } else { + return super.attackEntityFrom(par1DamageSource, par2); + } + } + } + + public boolean isScreaming() { + return this.dataWatcher.getWatchableObjectByte(18) > 0; + } + + public void setScreaming(boolean par1) { + this.dataWatcher.updateObject(18, Byte.valueOf((byte) (par1 ? 1 : 0))); + } + + /** + * Returns the amount of damage a mob should deal. + */ + public int getAttackStrength(Entity par1Entity) { + return 7; + } + + static { + carriableBlocks[Block.grass.blockID] = true; + carriableBlocks[Block.dirt.blockID] = true; + carriableBlocks[Block.sand.blockID] = true; + carriableBlocks[Block.gravel.blockID] = true; + carriableBlocks[Block.plantYellow.blockID] = true; + carriableBlocks[Block.plantRed.blockID] = true; + carriableBlocks[Block.mushroomBrown.blockID] = true; + carriableBlocks[Block.mushroomRed.blockID] = true; + carriableBlocks[Block.tnt.blockID] = true; + carriableBlocks[Block.cactus.blockID] = true; + carriableBlocks[Block.blockClay.blockID] = true; + carriableBlocks[Block.pumpkin.blockID] = true; + carriableBlocks[Block.melon.blockID] = true; + carriableBlocks[Block.mycelium.blockID] = true; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityExpBottle.java b/sp-server/src/main/java/net/minecraft/src/EntityExpBottle.java new file mode 100644 index 0000000..255e103 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityExpBottle.java @@ -0,0 +1,49 @@ +package net.minecraft.src; + +public class EntityExpBottle extends EntityThrowable { + public EntityExpBottle(World par1World) { + super(par1World); + } + + public EntityExpBottle(World par1World, EntityLiving par2EntityLiving) { + super(par1World, par2EntityLiving); + } + + public EntityExpBottle(World par1World, double par2, double par4, double par6) { + super(par1World, par2, par4, par6); + } + + /** + * Gets the amount of gravity to apply to the thrown entity with each tick. + */ + protected float getGravityVelocity() { + return 0.07F; + } + + protected float func_70182_d() { + return 0.7F; + } + + protected float func_70183_g() { + return -20.0F; + } + + /** + * Called when this EntityThrowable hits a block or entity. + */ + protected void onImpact(MovingObjectPosition par1MovingObjectPosition) { + if (!this.worldObj.isRemote) { + this.worldObj.playAuxSFX(2002, (int) Math.round(this.posX), (int) Math.round(this.posY), + (int) Math.round(this.posZ), 0); + int var2 = 3 + this.worldObj.rand.nextInt(5) + this.worldObj.rand.nextInt(5); + + while (var2 > 0) { + int var3 = EntityXPOrb.getXPSplit(var2); + var2 -= var3; + this.worldObj.spawnEntityInWorld(new EntityXPOrb(this.worldObj, this.posX, this.posY, this.posZ, var3)); + } + + this.setDead(); + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityFallingSand.java b/sp-server/src/main/java/net/minecraft/src/EntityFallingSand.java new file mode 100644 index 0000000..9dee990 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityFallingSand.java @@ -0,0 +1,266 @@ +package net.minecraft.src; + +import java.util.ArrayList; +import java.util.Iterator; + +public class EntityFallingSand extends Entity { + public int blockID; + public int metadata; + + /** How long the block has been falling for. */ + public int fallTime; + public boolean shouldDropItem; + private boolean isBreakingAnvil; + private boolean isAnvil; + + /** Maximum amount of damage dealt to entities hit by falling block */ + private int fallHurtMax; + + /** Actual damage dealt to entities hit by falling block */ + private float fallHurtAmount; + public NBTTagCompound fallingBlockTileEntityData; + + public EntityFallingSand(World par1World) { + super(par1World); + this.fallTime = 0; + this.shouldDropItem = true; + this.isBreakingAnvil = false; + this.isAnvil = false; + this.fallHurtMax = 40; + this.fallHurtAmount = 2.0F; + this.fallingBlockTileEntityData = null; + } + + public EntityFallingSand(World par1World, double par2, double par4, double par6, int par8) { + this(par1World, par2, par4, par6, par8, 0); + } + + public EntityFallingSand(World par1World, double par2, double par4, double par6, int par8, int par9) { + super(par1World); + this.fallTime = 0; + this.shouldDropItem = true; + this.isBreakingAnvil = false; + this.isAnvil = false; + this.fallHurtMax = 40; + this.fallHurtAmount = 2.0F; + this.fallingBlockTileEntityData = null; + this.blockID = par8; + this.metadata = par9; + this.preventEntitySpawning = true; + this.setSize(0.98F, 0.98F); + this.yOffset = this.height / 2.0F; + this.setPosition(par2, par4, par6); + this.motionX = 0.0D; + this.motionY = 0.0D; + this.motionZ = 0.0D; + this.prevPosX = par2; + this.prevPosY = par4; + this.prevPosZ = par6; + } + + /** + * returns if this entity triggers Block.onEntityWalking on the blocks they walk + * on. used for spiders and wolves to prevent them from trampling crops + */ + protected boolean canTriggerWalking() { + return false; + } + + protected void entityInit() { + } + + /** + * Returns true if other Entities should be prevented from moving through this + * Entity. + */ + public boolean canBeCollidedWith() { + return !this.isDead; + } + + /** + * Called to update the entity's position/logic. + */ + public void onUpdate() { + if (this.blockID == 0) { + this.setDead(); + } else { + this.prevPosX = this.posX; + this.prevPosY = this.posY; + this.prevPosZ = this.posZ; + ++this.fallTime; + this.motionY -= 0.03999999910593033D; + this.moveEntity(this.motionX, this.motionY, this.motionZ); + this.motionX *= 0.9800000190734863D; + this.motionY *= 0.9800000190734863D; + this.motionZ *= 0.9800000190734863D; + + if (!this.worldObj.isRemote) { + int var1 = MathHelper.floor_double(this.posX); + int var2 = MathHelper.floor_double(this.posY); + int var3 = MathHelper.floor_double(this.posZ); + + if (this.fallTime == 1) { + if (this.worldObj.getBlockId(var1, var2, var3) != this.blockID) { + this.setDead(); + return; + } + + this.worldObj.setBlockToAir(var1, var2, var3); + } + + if (this.onGround) { + this.motionX *= 0.699999988079071D; + this.motionZ *= 0.699999988079071D; + this.motionY *= -0.5D; + + if (this.worldObj.getBlockId(var1, var2, var3) != Block.pistonMoving.blockID) { + this.setDead(); + + if (!this.isBreakingAnvil + && this.worldObj.canPlaceEntityOnSide(this.blockID, var1, var2, var3, true, 1, + (Entity) null, (ItemStack) null) + && !BlockSand.canFallBelow(this.worldObj, var1, var2 - 1, var3) + && this.worldObj.setBlock(var1, var2, var3, this.blockID, this.metadata, 3)) { + if (Block.blocksList[this.blockID] instanceof BlockSand) { + ((BlockSand) Block.blocksList[this.blockID]).onFinishFalling(this.worldObj, var1, var2, + var3, this.metadata); + } + + if (this.fallingBlockTileEntityData != null + && Block.blocksList[this.blockID] instanceof ITileEntityProvider) { + TileEntity var4 = this.worldObj.getBlockTileEntity(var1, var2, var3); + + if (var4 != null) { + NBTTagCompound var5 = new NBTTagCompound(); + var4.writeToNBT(var5); + Iterator var6 = this.fallingBlockTileEntityData.getTags().iterator(); + + while (var6.hasNext()) { + NBTBase var7 = (NBTBase) var6.next(); + + if (!var7.getName().equals("x") && !var7.getName().equals("y") + && !var7.getName().equals("z")) { + var5.setTag(var7.getName(), var7.copy()); + } + } + + var4.readFromNBT(var5); + var4.onInventoryChanged(); + } + } + } else if (this.shouldDropItem && !this.isBreakingAnvil) { + this.entityDropItem(new ItemStack(this.blockID, 1, + Block.blocksList[this.blockID].damageDropped(this.metadata)), 0.0F); + } + } + } else if (this.fallTime > 100 && !this.worldObj.isRemote && (var2 < 1 || var2 > 256) + || this.fallTime > 600) { + if (this.shouldDropItem) { + this.entityDropItem(new ItemStack(this.blockID, 1, + Block.blocksList[this.blockID].damageDropped(this.metadata)), 0.0F); + } + + this.setDead(); + } + } + } + } + + /** + * Called when the mob is falling. Calculates and applies fall damage. + */ + protected void fall(float par1) { + if (this.isAnvil) { + int var2 = MathHelper.ceiling_float_int(par1 - 1.0F); + + if (var2 > 0) { + ArrayList var3 = new ArrayList( + this.worldObj.getEntitiesWithinAABBExcludingEntity(this, this.boundingBox)); + DamageSource var4 = this.blockID == Block.anvil.blockID ? DamageSource.anvil + : DamageSource.fallingBlock; + Iterator var5 = var3.iterator(); + + while (var5.hasNext()) { + Entity var6 = (Entity) var5.next(); + var6.attackEntityFrom(var4, + Math.min(MathHelper.floor_float((float) var2 * this.fallHurtAmount), this.fallHurtMax)); + } + + if (this.blockID == Block.anvil.blockID + && (double) this.rand.nextFloat() < 0.05000000074505806D + (double) var2 * 0.05D) { + int var7 = this.metadata >> 2; + int var8 = this.metadata & 3; + ++var7; + + if (var7 > 2) { + this.isBreakingAnvil = true; + } else { + this.metadata = var8 | var7 << 2; + } + } + } + } + } + + /** + * (abstract) Protected helper method to write subclass entity data to NBT. + */ + protected void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) { + par1NBTTagCompound.setByte("Tile", (byte) this.blockID); + par1NBTTagCompound.setInteger("TileID", this.blockID); + par1NBTTagCompound.setByte("Data", (byte) this.metadata); + par1NBTTagCompound.setByte("Time", (byte) this.fallTime); + par1NBTTagCompound.setBoolean("DropItem", this.shouldDropItem); + par1NBTTagCompound.setBoolean("HurtEntities", this.isAnvil); + par1NBTTagCompound.setFloat("FallHurtAmount", this.fallHurtAmount); + par1NBTTagCompound.setInteger("FallHurtMax", this.fallHurtMax); + + if (this.fallingBlockTileEntityData != null) { + par1NBTTagCompound.setCompoundTag("TileEntityData", this.fallingBlockTileEntityData); + } + } + + /** + * (abstract) Protected helper method to read subclass entity data from NBT. + */ + protected void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) { + if (par1NBTTagCompound.hasKey("TileID")) { + this.blockID = par1NBTTagCompound.getInteger("TileID"); + } else { + this.blockID = par1NBTTagCompound.getByte("Tile") & 255; + } + + this.metadata = par1NBTTagCompound.getByte("Data") & 255; + this.fallTime = par1NBTTagCompound.getByte("Time") & 255; + + if (par1NBTTagCompound.hasKey("HurtEntities")) { + this.isAnvil = par1NBTTagCompound.getBoolean("HurtEntities"); + this.fallHurtAmount = par1NBTTagCompound.getFloat("FallHurtAmount"); + this.fallHurtMax = par1NBTTagCompound.getInteger("FallHurtMax"); + } else if (this.blockID == Block.anvil.blockID) { + this.isAnvil = true; + } + + if (par1NBTTagCompound.hasKey("DropItem")) { + this.shouldDropItem = par1NBTTagCompound.getBoolean("DropItem"); + } + + if (par1NBTTagCompound.hasKey("TileEntityData")) { + this.fallingBlockTileEntityData = par1NBTTagCompound.getCompoundTag("TileEntityData"); + } + + if (this.blockID == 0) { + this.blockID = Block.sand.blockID; + } + } + + public void setIsAnvil(boolean par1) { + this.isAnvil = par1; + } + + public void func_85029_a(CrashReportCategory par1CrashReportCategory) { + super.func_85029_a(par1CrashReportCategory); + par1CrashReportCategory.addCrashSection("Immitating block ID", Integer.valueOf(this.blockID)); + par1CrashReportCategory.addCrashSection("Immitating block data", Integer.valueOf(this.metadata)); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityFireball.java b/sp-server/src/main/java/net/minecraft/src/EntityFireball.java new file mode 100644 index 0000000..7e698c3 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityFireball.java @@ -0,0 +1,280 @@ +package net.minecraft.src; + +import java.util.List; + +public abstract class EntityFireball extends Entity { + private int xTile = -1; + private int yTile = -1; + private int zTile = -1; + private int inTile = 0; + private boolean inGround = false; + public EntityLiving shootingEntity; + private int ticksAlive; + private int ticksInAir = 0; + public double accelerationX; + public double accelerationY; + public double accelerationZ; + + public EntityFireball(World par1World) { + super(par1World); + this.setSize(1.0F, 1.0F); + } + + protected void entityInit() { + } + + public EntityFireball(World par1World, double par2, double par4, double par6, double par8, double par10, + double par12) { + super(par1World); + this.setSize(1.0F, 1.0F); + this.setLocationAndAngles(par2, par4, par6, this.rotationYaw, this.rotationPitch); + this.setPosition(par2, par4, par6); + double var14 = (double) MathHelper.sqrt_double(par8 * par8 + par10 * par10 + par12 * par12); + this.accelerationX = par8 / var14 * 0.1D; + this.accelerationY = par10 / var14 * 0.1D; + this.accelerationZ = par12 / var14 * 0.1D; + } + + public EntityFireball(World par1World, EntityLiving par2EntityLiving, double par3, double par5, double par7) { + super(par1World); + this.shootingEntity = par2EntityLiving; + this.setSize(1.0F, 1.0F); + this.setLocationAndAngles(par2EntityLiving.posX, par2EntityLiving.posY, par2EntityLiving.posZ, + par2EntityLiving.rotationYaw, par2EntityLiving.rotationPitch); + this.setPosition(this.posX, this.posY, this.posZ); + this.yOffset = 0.0F; + this.motionX = this.motionY = this.motionZ = 0.0D; + par3 += this.rand.nextGaussian() * 0.4D; + par5 += this.rand.nextGaussian() * 0.4D; + par7 += this.rand.nextGaussian() * 0.4D; + double var9 = (double) MathHelper.sqrt_double(par3 * par3 + par5 * par5 + par7 * par7); + this.accelerationX = par3 / var9 * 0.1D; + this.accelerationY = par5 / var9 * 0.1D; + this.accelerationZ = par7 / var9 * 0.1D; + } + + /** + * Called to update the entity's position/logic. + */ + public void onUpdate() { + if (!this.worldObj.isRemote && (this.shootingEntity != null && this.shootingEntity.isDead + || !this.worldObj.blockExists((int) this.posX, (int) this.posY, (int) this.posZ))) { + this.setDead(); + } else { + super.onUpdate(); + this.setFire(1); + + if (this.inGround) { + int var1 = this.worldObj.getBlockId(this.xTile, this.yTile, this.zTile); + + if (var1 == this.inTile) { + ++this.ticksAlive; + + if (this.ticksAlive == 600) { + this.setDead(); + } + + return; + } + + this.inGround = false; + this.motionX *= (double) (this.rand.nextFloat() * 0.2F); + this.motionY *= (double) (this.rand.nextFloat() * 0.2F); + this.motionZ *= (double) (this.rand.nextFloat() * 0.2F); + this.ticksAlive = 0; + this.ticksInAir = 0; + } else { + ++this.ticksInAir; + } + + Vec3 var15 = this.worldObj.getWorldVec3Pool().getVecFromPool(this.posX, this.posY, this.posZ); + Vec3 var2 = this.worldObj.getWorldVec3Pool().getVecFromPool(this.posX + this.motionX, + this.posY + this.motionY, this.posZ + this.motionZ); + MovingObjectPosition var3 = this.worldObj.rayTraceBlocks(var15, var2); + var15 = this.worldObj.getWorldVec3Pool().getVecFromPool(this.posX, this.posY, this.posZ); + var2 = this.worldObj.getWorldVec3Pool().getVecFromPool(this.posX + this.motionX, this.posY + this.motionY, + this.posZ + this.motionZ); + + if (var3 != null) { + var2 = this.worldObj.getWorldVec3Pool().getVecFromPool(var3.hitVec.xCoord, var3.hitVec.yCoord, + var3.hitVec.zCoord); + } + + Entity var4 = null; + List var5 = this.worldObj.getEntitiesWithinAABBExcludingEntity(this, + this.boundingBox.addCoord(this.motionX, this.motionY, this.motionZ).expand(1.0D, 1.0D, 1.0D)); + double var6 = 0.0D; + + for (int var8 = 0; var8 < var5.size(); ++var8) { + Entity var9 = (Entity) var5.get(var8); + + if (var9.canBeCollidedWith() && (!var9.isEntityEqual(this.shootingEntity) || this.ticksInAir >= 25)) { + float var10 = 0.3F; + AxisAlignedBB var11 = var9.boundingBox.expand((double) var10, (double) var10, (double) var10); + MovingObjectPosition var12 = var11.calculateIntercept(var15, var2); + + if (var12 != null) { + double var13 = var15.distanceTo(var12.hitVec); + + if (var13 < var6 || var6 == 0.0D) { + var4 = var9; + var6 = var13; + } + } + } + } + + if (var4 != null) { + var3 = new MovingObjectPosition(var4); + } + + if (var3 != null) { + this.onImpact(var3); + } + + this.posX += this.motionX; + this.posY += this.motionY; + this.posZ += this.motionZ; + float var16 = MathHelper.sqrt_double(this.motionX * this.motionX + this.motionZ * this.motionZ); + this.rotationYaw = (float) (Math.atan2(this.motionZ, this.motionX) * 180.0D / Math.PI) + 90.0F; + + for (this.rotationPitch = (float) (Math.atan2((double) var16, this.motionY) * 180.0D / Math.PI) + - 90.0F; this.rotationPitch - this.prevRotationPitch < -180.0F; this.prevRotationPitch -= 360.0F) { + ; + } + + while (this.rotationPitch - this.prevRotationPitch >= 180.0F) { + this.prevRotationPitch += 360.0F; + } + + while (this.rotationYaw - this.prevRotationYaw < -180.0F) { + this.prevRotationYaw -= 360.0F; + } + + while (this.rotationYaw - this.prevRotationYaw >= 180.0F) { + this.prevRotationYaw += 360.0F; + } + + this.rotationPitch = this.prevRotationPitch + (this.rotationPitch - this.prevRotationPitch) * 0.2F; + this.rotationYaw = this.prevRotationYaw + (this.rotationYaw - this.prevRotationYaw) * 0.2F; + float var17 = this.getMotionFactor(); + + if (this.isInWater()) { + for (int var18 = 0; var18 < 4; ++var18) { + float var19 = 0.25F; + this.worldObj.spawnParticle("bubble", this.posX - this.motionX * (double) var19, + this.posY - this.motionY * (double) var19, this.posZ - this.motionZ * (double) var19, + this.motionX, this.motionY, this.motionZ); + } + + var17 = 0.8F; + } + + this.motionX += this.accelerationX; + this.motionY += this.accelerationY; + this.motionZ += this.accelerationZ; + this.motionX *= (double) var17; + this.motionY *= (double) var17; + this.motionZ *= (double) var17; + this.worldObj.spawnParticle("smoke", this.posX, this.posY + 0.5D, this.posZ, 0.0D, 0.0D, 0.0D); + this.setPosition(this.posX, this.posY, this.posZ); + } + } + + /** + * Return the motion factor for this projectile. The factor is multiplied by the + * original motion. + */ + protected float getMotionFactor() { + return 0.95F; + } + + /** + * Called when this EntityFireball hits a block or entity. + */ + protected abstract void onImpact(MovingObjectPosition var1); + + /** + * (abstract) Protected helper method to write subclass entity data to NBT. + */ + public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) { + par1NBTTagCompound.setShort("xTile", (short) this.xTile); + par1NBTTagCompound.setShort("yTile", (short) this.yTile); + par1NBTTagCompound.setShort("zTile", (short) this.zTile); + par1NBTTagCompound.setByte("inTile", (byte) this.inTile); + par1NBTTagCompound.setByte("inGround", (byte) (this.inGround ? 1 : 0)); + par1NBTTagCompound.setTag("direction", + this.newDoubleNBTList(new double[] { this.motionX, this.motionY, this.motionZ })); + } + + /** + * (abstract) Protected helper method to read subclass entity data from NBT. + */ + public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) { + this.xTile = par1NBTTagCompound.getShort("xTile"); + this.yTile = par1NBTTagCompound.getShort("yTile"); + this.zTile = par1NBTTagCompound.getShort("zTile"); + this.inTile = par1NBTTagCompound.getByte("inTile") & 255; + this.inGround = par1NBTTagCompound.getByte("inGround") == 1; + + if (par1NBTTagCompound.hasKey("direction")) { + NBTTagList var2 = par1NBTTagCompound.getTagList("direction"); + this.motionX = ((NBTTagDouble) var2.tagAt(0)).data; + this.motionY = ((NBTTagDouble) var2.tagAt(1)).data; + this.motionZ = ((NBTTagDouble) var2.tagAt(2)).data; + } else { + this.setDead(); + } + } + + /** + * Returns true if other Entities should be prevented from moving through this + * Entity. + */ + public boolean canBeCollidedWith() { + return true; + } + + public float getCollisionBorderSize() { + return 1.0F; + } + + /** + * Called when the entity is attacked. + */ + public boolean attackEntityFrom(DamageSource par1DamageSource, int par2) { + if (this.isEntityInvulnerable()) { + return false; + } else { + this.setBeenAttacked(); + + if (par1DamageSource.getEntity() != null) { + Vec3 var3 = par1DamageSource.getEntity().getLookVec(); + + if (var3 != null) { + this.motionX = var3.xCoord; + this.motionY = var3.yCoord; + this.motionZ = var3.zCoord; + this.accelerationX = this.motionX * 0.1D; + this.accelerationY = this.motionY * 0.1D; + this.accelerationZ = this.motionZ * 0.1D; + } + + if (par1DamageSource.getEntity() instanceof EntityLiving) { + this.shootingEntity = (EntityLiving) par1DamageSource.getEntity(); + } + + return true; + } else { + return false; + } + } + } + + /** + * Gets how bright this entity is. + */ + public float getBrightness(float par1) { + return 1.0F; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityFireworkRocket.java b/sp-server/src/main/java/net/minecraft/src/EntityFireworkRocket.java new file mode 100644 index 0000000..f102cd8 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityFireworkRocket.java @@ -0,0 +1,143 @@ +package net.minecraft.src; + +public class EntityFireworkRocket extends Entity { + /** The age of the firework in ticks. */ + private int fireworkAge; + + /** + * The lifetime of the firework in ticks. When the age reaches the lifetime the + * firework explodes. + */ + private int lifetime; + + public EntityFireworkRocket(World par1World) { + super(par1World); + this.setSize(0.25F, 0.25F); + } + + protected void entityInit() { + this.dataWatcher.addObjectByDataType(8, 5); + } + + public EntityFireworkRocket(World par1World, double par2, double par4, double par6, ItemStack par8ItemStack) { + super(par1World); + this.fireworkAge = 0; + this.setSize(0.25F, 0.25F); + this.setPosition(par2, par4, par6); + this.yOffset = 0.0F; + int var9 = 1; + + if (par8ItemStack != null && par8ItemStack.hasTagCompound()) { + this.dataWatcher.updateObject(8, par8ItemStack); + NBTTagCompound var10 = par8ItemStack.getTagCompound(); + NBTTagCompound var11 = var10.getCompoundTag("Fireworks"); + + if (var11 != null) { + var9 += var11.getByte("Flight"); + } + } + + this.motionX = this.rand.nextGaussian() * 0.001D; + this.motionZ = this.rand.nextGaussian() * 0.001D; + this.motionY = 0.05D; + this.lifetime = 10 * var9 + this.rand.nextInt(6) + this.rand.nextInt(7); + } + + /** + * Called to update the entity's position/logic. + */ + public void onUpdate() { + this.lastTickPosX = this.posX; + this.lastTickPosY = this.posY; + this.lastTickPosZ = this.posZ; + super.onUpdate(); + this.motionX *= 1.15D; + this.motionZ *= 1.15D; + this.motionY += 0.04D; + this.moveEntity(this.motionX, this.motionY, this.motionZ); + float var1 = MathHelper.sqrt_double(this.motionX * this.motionX + this.motionZ * this.motionZ); + this.rotationYaw = (float) (Math.atan2(this.motionX, this.motionZ) * 180.0D / Math.PI); + + for (this.rotationPitch = (float) (Math.atan2(this.motionY, (double) var1) * 180.0D + / Math.PI); this.rotationPitch - this.prevRotationPitch < -180.0F; this.prevRotationPitch -= 360.0F) { + ; + } + + while (this.rotationPitch - this.prevRotationPitch >= 180.0F) { + this.prevRotationPitch += 360.0F; + } + + while (this.rotationYaw - this.prevRotationYaw < -180.0F) { + this.prevRotationYaw -= 360.0F; + } + + while (this.rotationYaw - this.prevRotationYaw >= 180.0F) { + this.prevRotationYaw += 360.0F; + } + + this.rotationPitch = this.prevRotationPitch + (this.rotationPitch - this.prevRotationPitch) * 0.2F; + this.rotationYaw = this.prevRotationYaw + (this.rotationYaw - this.prevRotationYaw) * 0.2F; + + if (this.fireworkAge == 0) { + this.worldObj.playSoundAtEntity(this, "fireworks.launch", 3.0F, 1.0F); + } + + ++this.fireworkAge; + + if (this.worldObj.isRemote && this.fireworkAge % 2 < 2) { + this.worldObj.spawnParticle("fireworksSpark", this.posX, this.posY - 0.3D, this.posZ, + this.rand.nextGaussian() * 0.05D, -this.motionY * 0.5D, this.rand.nextGaussian() * 0.05D); + } + + if (!this.worldObj.isRemote && this.fireworkAge > this.lifetime) { + this.worldObj.setEntityState(this, (byte) 17); + this.setDead(); + } + } + + /** + * (abstract) Protected helper method to write subclass entity data to NBT. + */ + public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) { + par1NBTTagCompound.setInteger("Life", this.fireworkAge); + par1NBTTagCompound.setInteger("LifeTime", this.lifetime); + ItemStack var2 = this.dataWatcher.getWatchableObjectItemStack(8); + + if (var2 != null) { + NBTTagCompound var3 = new NBTTagCompound(); + var2.writeToNBT(var3); + par1NBTTagCompound.setCompoundTag("FireworksItem", var3); + } + } + + /** + * (abstract) Protected helper method to read subclass entity data from NBT. + */ + public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) { + this.fireworkAge = par1NBTTagCompound.getInteger("Life"); + this.lifetime = par1NBTTagCompound.getInteger("LifeTime"); + NBTTagCompound var2 = par1NBTTagCompound.getCompoundTag("FireworksItem"); + + if (var2 != null) { + ItemStack var3 = ItemStack.loadItemStackFromNBT(var2); + + if (var3 != null) { + this.dataWatcher.updateObject(8, var3); + } + } + } + + /** + * Gets how bright this entity is. + */ + public float getBrightness(float par1) { + return super.getBrightness(par1); + } + + /** + * If returns false, the item will not inflict any damage against entities. + */ + public boolean canAttackWithItem() { + return false; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityFishHook.java b/sp-server/src/main/java/net/minecraft/src/EntityFishHook.java new file mode 100644 index 0000000..435608b --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityFishHook.java @@ -0,0 +1,392 @@ +package net.minecraft.src; + +import java.util.List; + +public class EntityFishHook extends Entity { + /** The tile this entity is on, X position */ + private int xTile = -1; + + /** The tile this entity is on, Y position */ + private int yTile = -1; + + /** The tile this entity is on, Z position */ + private int zTile = -1; + private int inTile = 0; + private boolean inGround = false; + public int shake = 0; + public EntityPlayer angler; + private int ticksInGround; + private int ticksInAir = 0; + + /** the number of ticks remaining until this fish can no longer be caught */ + private int ticksCatchable = 0; + + /** the bobber that the fish hit */ + public Entity bobber = null; + private int fishPosRotationIncrements; + private double fishX; + private double fishY; + private double fishZ; + private double fishYaw; + private double fishPitch; + + public EntityFishHook(World par1World) { + super(par1World); + this.setSize(0.25F, 0.25F); + this.ignoreFrustumCheck = true; + } + + public EntityFishHook(World par1World, EntityPlayer par2EntityPlayer) { + super(par1World); + this.ignoreFrustumCheck = true; + this.angler = par2EntityPlayer; + this.angler.fishEntity = this; + this.setSize(0.25F, 0.25F); + this.setLocationAndAngles(par2EntityPlayer.posX, + par2EntityPlayer.posY + 1.62D - (double) par2EntityPlayer.yOffset, par2EntityPlayer.posZ, + par2EntityPlayer.rotationYaw, par2EntityPlayer.rotationPitch); + this.posX -= (double) (MathHelper.cos(this.rotationYaw / 180.0F * (float) Math.PI) * 0.16F); + this.posY -= 0.10000000149011612D; + this.posZ -= (double) (MathHelper.sin(this.rotationYaw / 180.0F * (float) Math.PI) * 0.16F); + this.setPosition(this.posX, this.posY, this.posZ); + this.yOffset = 0.0F; + float var3 = 0.4F; + this.motionX = (double) (-MathHelper.sin(this.rotationYaw / 180.0F * (float) Math.PI) + * MathHelper.cos(this.rotationPitch / 180.0F * (float) Math.PI) * var3); + this.motionZ = (double) (MathHelper.cos(this.rotationYaw / 180.0F * (float) Math.PI) + * MathHelper.cos(this.rotationPitch / 180.0F * (float) Math.PI) * var3); + this.motionY = (double) (-MathHelper.sin(this.rotationPitch / 180.0F * (float) Math.PI) * var3); + this.calculateVelocity(this.motionX, this.motionY, this.motionZ, 1.5F, 1.0F); + } + + protected void entityInit() { + } + + public void calculateVelocity(double par1, double par3, double par5, float par7, float par8) { + float var9 = MathHelper.sqrt_double(par1 * par1 + par3 * par3 + par5 * par5); + par1 /= (double) var9; + par3 /= (double) var9; + par5 /= (double) var9; + par1 += this.rand.nextGaussian() * 0.007499999832361937D * (double) par8; + par3 += this.rand.nextGaussian() * 0.007499999832361937D * (double) par8; + par5 += this.rand.nextGaussian() * 0.007499999832361937D * (double) par8; + par1 *= (double) par7; + par3 *= (double) par7; + par5 *= (double) par7; + this.motionX = par1; + this.motionY = par3; + this.motionZ = par5; + float var10 = MathHelper.sqrt_double(par1 * par1 + par5 * par5); + this.prevRotationYaw = this.rotationYaw = (float) (Math.atan2(par1, par5) * 180.0D / Math.PI); + this.prevRotationPitch = this.rotationPitch = (float) (Math.atan2(par3, (double) var10) * 180.0D / Math.PI); + this.ticksInGround = 0; + } + + /** + * Called to update the entity's position/logic. + */ + public void onUpdate() { + super.onUpdate(); + + if (this.fishPosRotationIncrements > 0) { + double var21 = this.posX + (this.fishX - this.posX) / (double) this.fishPosRotationIncrements; + double var22 = this.posY + (this.fishY - this.posY) / (double) this.fishPosRotationIncrements; + double var23 = this.posZ + (this.fishZ - this.posZ) / (double) this.fishPosRotationIncrements; + double var7 = MathHelper.wrapAngleTo180_double(this.fishYaw - (double) this.rotationYaw); + this.rotationYaw = (float) ((double) this.rotationYaw + var7 / (double) this.fishPosRotationIncrements); + this.rotationPitch = (float) ((double) this.rotationPitch + + (this.fishPitch - (double) this.rotationPitch) / (double) this.fishPosRotationIncrements); + --this.fishPosRotationIncrements; + this.setPosition(var21, var22, var23); + this.setRotation(this.rotationYaw, this.rotationPitch); + } else { + if (!this.worldObj.isRemote) { + ItemStack var1 = this.angler.getCurrentEquippedItem(); + + if (this.angler.isDead || !this.angler.isEntityAlive() || var1 == null + || var1.getItem() != Item.fishingRod || this.getDistanceSqToEntity(this.angler) > 1024.0D) { + this.setDead(); + this.angler.fishEntity = null; + return; + } + + if (this.bobber != null) { + if (!this.bobber.isDead) { + this.posX = this.bobber.posX; + this.posY = this.bobber.boundingBox.minY + (double) this.bobber.height * 0.8D; + this.posZ = this.bobber.posZ; + return; + } + + this.bobber = null; + } + } + + if (this.shake > 0) { + --this.shake; + } + + if (this.inGround) { + int var19 = this.worldObj.getBlockId(this.xTile, this.yTile, this.zTile); + + if (var19 == this.inTile) { + ++this.ticksInGround; + + if (this.ticksInGround == 1200) { + this.setDead(); + } + + return; + } + + this.inGround = false; + this.motionX *= (double) (this.rand.nextFloat() * 0.2F); + this.motionY *= (double) (this.rand.nextFloat() * 0.2F); + this.motionZ *= (double) (this.rand.nextFloat() * 0.2F); + this.ticksInGround = 0; + this.ticksInAir = 0; + } else { + ++this.ticksInAir; + } + + Vec3 var20 = this.worldObj.getWorldVec3Pool().getVecFromPool(this.posX, this.posY, this.posZ); + Vec3 var2 = this.worldObj.getWorldVec3Pool().getVecFromPool(this.posX + this.motionX, + this.posY + this.motionY, this.posZ + this.motionZ); + MovingObjectPosition var3 = this.worldObj.rayTraceBlocks(var20, var2); + var20 = this.worldObj.getWorldVec3Pool().getVecFromPool(this.posX, this.posY, this.posZ); + var2 = this.worldObj.getWorldVec3Pool().getVecFromPool(this.posX + this.motionX, this.posY + this.motionY, + this.posZ + this.motionZ); + + if (var3 != null) { + var2 = this.worldObj.getWorldVec3Pool().getVecFromPool(var3.hitVec.xCoord, var3.hitVec.yCoord, + var3.hitVec.zCoord); + } + + Entity var4 = null; + List var5 = this.worldObj.getEntitiesWithinAABBExcludingEntity(this, + this.boundingBox.addCoord(this.motionX, this.motionY, this.motionZ).expand(1.0D, 1.0D, 1.0D)); + double var6 = 0.0D; + double var13; + + for (int var8 = 0; var8 < var5.size(); ++var8) { + Entity var9 = (Entity) var5.get(var8); + + if (var9.canBeCollidedWith() && (var9 != this.angler || this.ticksInAir >= 5)) { + float var10 = 0.3F; + AxisAlignedBB var11 = var9.boundingBox.expand((double) var10, (double) var10, (double) var10); + MovingObjectPosition var12 = var11.calculateIntercept(var20, var2); + + if (var12 != null) { + var13 = var20.distanceTo(var12.hitVec); + + if (var13 < var6 || var6 == 0.0D) { + var4 = var9; + var6 = var13; + } + } + } + } + + if (var4 != null) { + var3 = new MovingObjectPosition(var4); + } + + if (var3 != null) { + if (var3.entityHit != null) { + if (var3.entityHit.attackEntityFrom(DamageSource.causeThrownDamage(this, this.angler), 0)) { + this.bobber = var3.entityHit; + } + } else { + this.inGround = true; + } + } + + if (!this.inGround) { + this.moveEntity(this.motionX, this.motionY, this.motionZ); + float var24 = MathHelper.sqrt_double(this.motionX * this.motionX + this.motionZ * this.motionZ); + this.rotationYaw = (float) (Math.atan2(this.motionX, this.motionZ) * 180.0D / Math.PI); + + for (this.rotationPitch = (float) (Math.atan2(this.motionY, (double) var24) * 180.0D + / Math.PI); this.rotationPitch + - this.prevRotationPitch < -180.0F; this.prevRotationPitch -= 360.0F) { + ; + } + + while (this.rotationPitch - this.prevRotationPitch >= 180.0F) { + this.prevRotationPitch += 360.0F; + } + + while (this.rotationYaw - this.prevRotationYaw < -180.0F) { + this.prevRotationYaw -= 360.0F; + } + + while (this.rotationYaw - this.prevRotationYaw >= 180.0F) { + this.prevRotationYaw += 360.0F; + } + + this.rotationPitch = this.prevRotationPitch + (this.rotationPitch - this.prevRotationPitch) * 0.2F; + this.rotationYaw = this.prevRotationYaw + (this.rotationYaw - this.prevRotationYaw) * 0.2F; + float var25 = 0.92F; + + if (this.onGround || this.isCollidedHorizontally) { + var25 = 0.5F; + } + + byte var26 = 5; + double var27 = 0.0D; + + for (int var28 = 0; var28 < var26; ++var28) { + double var14 = this.boundingBox.minY + + (this.boundingBox.maxY - this.boundingBox.minY) * (double) (var28 + 0) / (double) var26 + - 0.125D + 0.125D; + double var16 = this.boundingBox.minY + + (this.boundingBox.maxY - this.boundingBox.minY) * (double) (var28 + 1) / (double) var26 + - 0.125D + 0.125D; + AxisAlignedBB var18 = AxisAlignedBB.getAABBPool().getAABB(this.boundingBox.minX, var14, + this.boundingBox.minZ, this.boundingBox.maxX, var16, this.boundingBox.maxZ); + + if (this.worldObj.isAABBInMaterial(var18, Material.water)) { + var27 += 1.0D / (double) var26; + } + } + + if (var27 > 0.0D) { + if (this.ticksCatchable > 0) { + --this.ticksCatchable; + } else { + short var29 = 500; + + if (this.worldObj.canLightningStrikeAt(MathHelper.floor_double(this.posX), + MathHelper.floor_double(this.posY) + 1, MathHelper.floor_double(this.posZ))) { + var29 = 300; + } + + if (this.rand.nextInt(var29) == 0) { + this.ticksCatchable = this.rand.nextInt(30) + 10; + this.motionY -= 0.20000000298023224D; + this.playSound("random.splash", 0.25F, + 1.0F + (this.rand.nextFloat() - this.rand.nextFloat()) * 0.4F); + float var30 = (float) MathHelper.floor_double(this.boundingBox.minY); + int var15; + float var17; + float var31; + + for (var15 = 0; (float) var15 < 1.0F + this.width * 20.0F; ++var15) { + var31 = (this.rand.nextFloat() * 2.0F - 1.0F) * this.width; + var17 = (this.rand.nextFloat() * 2.0F - 1.0F) * this.width; + this.worldObj.spawnParticle("bubble", this.posX + (double) var31, + (double) (var30 + 1.0F), this.posZ + (double) var17, this.motionX, + this.motionY - (double) (this.rand.nextFloat() * 0.2F), this.motionZ); + } + + for (var15 = 0; (float) var15 < 1.0F + this.width * 20.0F; ++var15) { + var31 = (this.rand.nextFloat() * 2.0F - 1.0F) * this.width; + var17 = (this.rand.nextFloat() * 2.0F - 1.0F) * this.width; + this.worldObj.spawnParticle("splash", this.posX + (double) var31, + (double) (var30 + 1.0F), this.posZ + (double) var17, this.motionX, this.motionY, + this.motionZ); + } + } + } + } + + if (this.ticksCatchable > 0) { + this.motionY -= (double) (this.rand.nextFloat() * this.rand.nextFloat() * this.rand.nextFloat()) + * 0.2D; + } + + var13 = var27 * 2.0D - 1.0D; + this.motionY += 0.03999999910593033D * var13; + + if (var27 > 0.0D) { + var25 = (float) ((double) var25 * 0.9D); + this.motionY *= 0.8D; + } + + this.motionX *= (double) var25; + this.motionY *= (double) var25; + this.motionZ *= (double) var25; + this.setPosition(this.posX, this.posY, this.posZ); + } + } + } + + /** + * (abstract) Protected helper method to write subclass entity data to NBT. + */ + public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) { + par1NBTTagCompound.setShort("xTile", (short) this.xTile); + par1NBTTagCompound.setShort("yTile", (short) this.yTile); + par1NBTTagCompound.setShort("zTile", (short) this.zTile); + par1NBTTagCompound.setByte("inTile", (byte) this.inTile); + par1NBTTagCompound.setByte("shake", (byte) this.shake); + par1NBTTagCompound.setByte("inGround", (byte) (this.inGround ? 1 : 0)); + } + + /** + * (abstract) Protected helper method to read subclass entity data from NBT. + */ + public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) { + this.xTile = par1NBTTagCompound.getShort("xTile"); + this.yTile = par1NBTTagCompound.getShort("yTile"); + this.zTile = par1NBTTagCompound.getShort("zTile"); + this.inTile = par1NBTTagCompound.getByte("inTile") & 255; + this.shake = par1NBTTagCompound.getByte("shake") & 255; + this.inGround = par1NBTTagCompound.getByte("inGround") == 1; + } + + public int catchFish() { + if (this.worldObj.isRemote) { + return 0; + } else { + byte var1 = 0; + + if (this.bobber != null) { + double var2 = this.angler.posX - this.posX; + double var4 = this.angler.posY - this.posY; + double var6 = this.angler.posZ - this.posZ; + double var8 = (double) MathHelper.sqrt_double(var2 * var2 + var4 * var4 + var6 * var6); + double var10 = 0.1D; + this.bobber.motionX += var2 * var10; + this.bobber.motionY += var4 * var10 + (double) MathHelper.sqrt_double(var8) * 0.08D; + this.bobber.motionZ += var6 * var10; + var1 = 3; + } else if (this.ticksCatchable > 0) { + EntityItem var13 = new EntityItem(this.worldObj, this.posX, this.posY, this.posZ, + new ItemStack(Item.fishRaw)); + double var3 = this.angler.posX - this.posX; + double var5 = this.angler.posY - this.posY; + double var7 = this.angler.posZ - this.posZ; + double var9 = (double) MathHelper.sqrt_double(var3 * var3 + var5 * var5 + var7 * var7); + double var11 = 0.1D; + var13.motionX = var3 * var11; + var13.motionY = var5 * var11 + (double) MathHelper.sqrt_double(var9) * 0.08D; + var13.motionZ = var7 * var11; + this.worldObj.spawnEntityInWorld(var13); + this.angler.addStat(StatList.fishCaughtStat, 1); + this.angler.worldObj.spawnEntityInWorld(new EntityXPOrb(this.angler.worldObj, this.angler.posX, + this.angler.posY + 0.5D, this.angler.posZ + 0.5D, this.rand.nextInt(6) + 1)); + var1 = 1; + } + + if (this.inGround) { + var1 = 2; + } + + this.setDead(); + this.angler.fishEntity = null; + return var1; + } + } + + /** + * Will get destroyed next tick. + */ + public void setDead() { + super.setDead(); + + if (this.angler != null) { + this.angler.fishEntity = null; + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityFlying.java b/sp-server/src/main/java/net/minecraft/src/EntityFlying.java new file mode 100644 index 0000000..a5a7ab6 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityFlying.java @@ -0,0 +1,90 @@ +package net.minecraft.src; + +public abstract class EntityFlying extends EntityLiving { + public EntityFlying(World par1World) { + super(par1World); + } + + /** + * Called when the mob is falling. Calculates and applies fall damage. + */ + protected void fall(float par1) { + } + + /** + * Takes in the distance the entity has fallen this tick and whether its on the + * ground to update the fall distance and deal fall damage if landing on the + * ground. Args: distanceFallenThisTick, onGround + */ + protected void updateFallState(double par1, boolean par3) { + } + + /** + * Moves the entity based on the specified heading. Args: strafe, forward + */ + public void moveEntityWithHeading(float par1, float par2) { + if (this.isInWater()) { + this.moveFlying(par1, par2, 0.02F); + this.moveEntity(this.motionX, this.motionY, this.motionZ); + this.motionX *= 0.800000011920929D; + this.motionY *= 0.800000011920929D; + this.motionZ *= 0.800000011920929D; + } else if (this.handleLavaMovement()) { + this.moveFlying(par1, par2, 0.02F); + this.moveEntity(this.motionX, this.motionY, this.motionZ); + this.motionX *= 0.5D; + this.motionY *= 0.5D; + this.motionZ *= 0.5D; + } else { + float var3 = 0.91F; + + if (this.onGround) { + var3 = 0.54600006F; + int var4 = this.worldObj.getBlockId(MathHelper.floor_double(this.posX), + MathHelper.floor_double(this.boundingBox.minY) - 1, MathHelper.floor_double(this.posZ)); + + if (var4 > 0) { + var3 = Block.blocksList[var4].slipperiness * 0.91F; + } + } + + float var8 = 0.16277136F / (var3 * var3 * var3); + this.moveFlying(par1, par2, this.onGround ? 0.1F * var8 : 0.02F); + var3 = 0.91F; + + if (this.onGround) { + var3 = 0.54600006F; + int var5 = this.worldObj.getBlockId(MathHelper.floor_double(this.posX), + MathHelper.floor_double(this.boundingBox.minY) - 1, MathHelper.floor_double(this.posZ)); + + if (var5 > 0) { + var3 = Block.blocksList[var5].slipperiness * 0.91F; + } + } + + this.moveEntity(this.motionX, this.motionY, this.motionZ); + this.motionX *= (double) var3; + this.motionY *= (double) var3; + this.motionZ *= (double) var3; + } + + this.prevLimbYaw = this.limbYaw; + double var10 = this.posX - this.prevPosX; + double var9 = this.posZ - this.prevPosZ; + float var7 = MathHelper.sqrt_double(var10 * var10 + var9 * var9) * 4.0F; + + if (var7 > 1.0F) { + var7 = 1.0F; + } + + this.limbYaw += (var7 - this.limbYaw) * 0.4F; + this.limbSwing += this.limbYaw; + } + + /** + * returns true if this entity is by a ladder, false otherwise + */ + public boolean isOnLadder() { + return false; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityGhast.java b/sp-server/src/main/java/net/minecraft/src/EntityGhast.java new file mode 100644 index 0000000..49f0dcf --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityGhast.java @@ -0,0 +1,263 @@ +package net.minecraft.src; + +public class EntityGhast extends EntityFlying implements IMob { + public int courseChangeCooldown = 0; + public double waypointX; + public double waypointY; + public double waypointZ; + private Entity targetedEntity = null; + + /** Cooldown time between target loss and new target aquirement. */ + private int aggroCooldown = 0; + public int prevAttackCounter = 0; + public int attackCounter = 0; + + /** The explosion radius of spawned fireballs. */ + private int explosionStrength = 1; + + public EntityGhast(World par1World) { + super(par1World); + this.texture = "/mob/ghast.png"; + this.setSize(4.0F, 4.0F); + this.isImmuneToFire = true; + this.experienceValue = 5; + } + + /** + * Called when the entity is attacked. + */ + public boolean attackEntityFrom(DamageSource par1DamageSource, int par2) { + if (this.isEntityInvulnerable()) { + return false; + } else if ("fireball".equals(par1DamageSource.getDamageType()) + && par1DamageSource.getEntity() instanceof EntityPlayer) { + super.attackEntityFrom(par1DamageSource, 1000); + ((EntityPlayer) par1DamageSource.getEntity()).triggerAchievement(AchievementList.ghast); + return true; + } else { + return super.attackEntityFrom(par1DamageSource, par2); + } + } + + protected void entityInit() { + super.entityInit(); + this.dataWatcher.addObject(16, Byte.valueOf((byte) 0)); + } + + public int getMaxHealth() { + return 10; + } + + /** + * Called to update the entity's position/logic. + */ + public void onUpdate() { + super.onUpdate(); + byte var1 = this.dataWatcher.getWatchableObjectByte(16); + this.texture = var1 == 1 ? "/mob/ghast_fire.png" : "/mob/ghast.png"; + } + + protected void updateEntityActionState() { + if (!this.worldObj.isRemote && this.worldObj.difficultySetting == 0) { + this.setDead(); + } + + this.despawnEntity(); + this.prevAttackCounter = this.attackCounter; + double var1 = this.waypointX - this.posX; + double var3 = this.waypointY - this.posY; + double var5 = this.waypointZ - this.posZ; + double var7 = var1 * var1 + var3 * var3 + var5 * var5; + + if (var7 < 1.0D || var7 > 3600.0D) { + this.waypointX = this.posX + (double) ((this.rand.nextFloat() * 2.0F - 1.0F) * 16.0F); + this.waypointY = this.posY + (double) ((this.rand.nextFloat() * 2.0F - 1.0F) * 16.0F); + this.waypointZ = this.posZ + (double) ((this.rand.nextFloat() * 2.0F - 1.0F) * 16.0F); + } + + if (this.courseChangeCooldown-- <= 0) { + this.courseChangeCooldown += this.rand.nextInt(5) + 2; + var7 = (double) MathHelper.sqrt_double(var7); + + if (this.isCourseTraversable(this.waypointX, this.waypointY, this.waypointZ, var7)) { + this.motionX += var1 / var7 * 0.1D; + this.motionY += var3 / var7 * 0.1D; + this.motionZ += var5 / var7 * 0.1D; + } else { + this.waypointX = this.posX; + this.waypointY = this.posY; + this.waypointZ = this.posZ; + } + } + + if (this.targetedEntity != null && this.targetedEntity.isDead) { + this.targetedEntity = null; + } + + if (this.targetedEntity == null || this.aggroCooldown-- <= 0) { + this.targetedEntity = this.worldObj.getClosestVulnerablePlayerToEntity(this, 100.0D); + + if (this.targetedEntity != null) { + this.aggroCooldown = 20; + } + } + + double var9 = 64.0D; + + if (this.targetedEntity != null && this.targetedEntity.getDistanceSqToEntity(this) < var9 * var9) { + double var11 = this.targetedEntity.posX - this.posX; + double var13 = this.targetedEntity.boundingBox.minY + (double) (this.targetedEntity.height / 2.0F) + - (this.posY + (double) (this.height / 2.0F)); + double var15 = this.targetedEntity.posZ - this.posZ; + this.renderYawOffset = this.rotationYaw = -((float) Math.atan2(var11, var15)) * 180.0F / (float) Math.PI; + + if (this.canEntityBeSeen(this.targetedEntity)) { + if (this.attackCounter == 10) { + this.worldObj.playAuxSFXAtEntity((EntityPlayer) null, 1007, (int) this.posX, (int) this.posY, + (int) this.posZ, 0); + } + + ++this.attackCounter; + + if (this.attackCounter == 20) { + this.worldObj.playAuxSFXAtEntity((EntityPlayer) null, 1008, (int) this.posX, (int) this.posY, + (int) this.posZ, 0); + EntityLargeFireball var17 = new EntityLargeFireball(this.worldObj, this, var11, var13, var15); + var17.field_92057_e = this.explosionStrength; + double var18 = 4.0D; + Vec3 var20 = this.getLook(1.0F); + var17.posX = this.posX + var20.xCoord * var18; + var17.posY = this.posY + (double) (this.height / 2.0F) + 0.5D; + var17.posZ = this.posZ + var20.zCoord * var18; + this.worldObj.spawnEntityInWorld(var17); + this.attackCounter = -40; + } + } else if (this.attackCounter > 0) { + --this.attackCounter; + } + } else { + this.renderYawOffset = this.rotationYaw = -((float) Math.atan2(this.motionX, this.motionZ)) * 180.0F + / (float) Math.PI; + + if (this.attackCounter > 0) { + --this.attackCounter; + } + } + + if (!this.worldObj.isRemote) { + byte var21 = this.dataWatcher.getWatchableObjectByte(16); + byte var12 = (byte) (this.attackCounter > 10 ? 1 : 0); + + if (var21 != var12) { + this.dataWatcher.updateObject(16, Byte.valueOf(var12)); + } + } + } + + /** + * True if the ghast has an unobstructed line of travel to the waypoint. + */ + private boolean isCourseTraversable(double par1, double par3, double par5, double par7) { + double var9 = (this.waypointX - this.posX) / par7; + double var11 = (this.waypointY - this.posY) / par7; + double var13 = (this.waypointZ - this.posZ) / par7; + AxisAlignedBB var15 = this.boundingBox.copy(); + + for (int var16 = 1; (double) var16 < par7; ++var16) { + var15.offset(var9, var11, var13); + + if (!this.worldObj.getCollidingBoundingBoxes(this, var15).isEmpty()) { + return false; + } + } + + return true; + } + + /** + * Returns the sound this mob makes while it's alive. + */ + protected String getLivingSound() { + return "mob.ghast.moan"; + } + + /** + * Returns the sound this mob makes when it is hurt. + */ + protected String getHurtSound() { + return "mob.ghast.scream"; + } + + /** + * Returns the sound this mob makes on death. + */ + protected String getDeathSound() { + return "mob.ghast.death"; + } + + /** + * Returns the item ID for the item the mob drops on death. + */ + protected int getDropItemId() { + return Item.gunpowder.itemID; + } + + /** + * Drop 0-2 items of this living's type + */ + protected void dropFewItems(boolean par1, int par2) { + int var3 = this.rand.nextInt(2) + this.rand.nextInt(1 + par2); + int var4; + + for (var4 = 0; var4 < var3; ++var4) { + this.dropItem(Item.ghastTear.itemID, 1); + } + + var3 = this.rand.nextInt(3) + this.rand.nextInt(1 + par2); + + for (var4 = 0; var4 < var3; ++var4) { + this.dropItem(Item.gunpowder.itemID, 1); + } + } + + /** + * Returns the volume for the sounds this mob makes. + */ + protected float getSoundVolume() { + return 10.0F; + } + + /** + * Checks if the entity's current position is a valid location to spawn this + * entity. + */ + public boolean getCanSpawnHere() { + return this.rand.nextInt(20) == 0 && super.getCanSpawnHere() && this.worldObj.difficultySetting > 0; + } + + /** + * Will return how many at most can spawn in a chunk at once. + */ + public int getMaxSpawnedInChunk() { + return 1; + } + + /** + * (abstract) Protected helper method to write subclass entity data to NBT. + */ + public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) { + super.writeEntityToNBT(par1NBTTagCompound); + par1NBTTagCompound.setInteger("ExplosionPower", this.explosionStrength); + } + + /** + * (abstract) Protected helper method to read subclass entity data from NBT. + */ + public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) { + super.readEntityFromNBT(par1NBTTagCompound); + + if (par1NBTTagCompound.hasKey("ExplosionPower")) { + this.explosionStrength = par1NBTTagCompound.getInteger("ExplosionPower"); + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityGiantZombie.java b/sp-server/src/main/java/net/minecraft/src/EntityGiantZombie.java new file mode 100644 index 0000000..0b5571f --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityGiantZombie.java @@ -0,0 +1,30 @@ +package net.minecraft.src; + +public class EntityGiantZombie extends EntityMob { + public EntityGiantZombie(World par1World) { + super(par1World); + this.texture = "/mob/zombie.png"; + this.moveSpeed = 0.5F; + this.yOffset *= 6.0F; + this.setSize(this.width * 6.0F, this.height * 6.0F); + } + + public int getMaxHealth() { + return 100; + } + + /** + * Takes a coordinate in and returns a weight to determine how likely this + * creature will try to path to the block. Args: x, y, z + */ + public float getBlockPathWeight(int par1, int par2, int par3) { + return this.worldObj.getLightBrightness(par1, par2, par3) - 0.5F; + } + + /** + * Returns the amount of damage a mob should deal. + */ + public int getAttackStrength(Entity par1Entity) { + return 50; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityGolem.java b/sp-server/src/main/java/net/minecraft/src/EntityGolem.java new file mode 100644 index 0000000..f5f881e --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityGolem.java @@ -0,0 +1,48 @@ +package net.minecraft.src; + +public abstract class EntityGolem extends EntityCreature implements IAnimals { + public EntityGolem(World par1World) { + super(par1World); + } + + /** + * Called when the mob is falling. Calculates and applies fall damage. + */ + protected void fall(float par1) { + } + + /** + * Returns the sound this mob makes while it's alive. + */ + protected String getLivingSound() { + return "none"; + } + + /** + * Returns the sound this mob makes when it is hurt. + */ + protected String getHurtSound() { + return "none"; + } + + /** + * Returns the sound this mob makes on death. + */ + protected String getDeathSound() { + return "none"; + } + + /** + * Get number of ticks, at least during which the living entity will be silent. + */ + public int getTalkInterval() { + return 120; + } + + /** + * Determines if an entity can be despawned, used on idle far away entities + */ + protected boolean canDespawn() { + return false; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityHanging.java b/sp-server/src/main/java/net/minecraft/src/EntityHanging.java new file mode 100644 index 0000000..2c28a94 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityHanging.java @@ -0,0 +1,301 @@ +package net.minecraft.src; + +import java.util.Iterator; +import java.util.List; + +public abstract class EntityHanging extends Entity { + private int tickCounter1; + public int hangingDirection; + public int xPosition; + public int yPosition; + public int zPosition; + + public EntityHanging(World par1World) { + super(par1World); + this.tickCounter1 = 0; + this.hangingDirection = 0; + this.yOffset = 0.0F; + this.setSize(0.5F, 0.5F); + } + + public EntityHanging(World par1World, int par2, int par3, int par4, int par5) { + this(par1World); + this.xPosition = par2; + this.yPosition = par3; + this.zPosition = par4; + } + + protected void entityInit() { + } + + public void setDirection(int par1) { + this.hangingDirection = par1; + this.prevRotationYaw = this.rotationYaw = (float) (par1 * 90); + float var2 = (float) this.func_82329_d(); + float var3 = (float) this.func_82330_g(); + float var4 = (float) this.func_82329_d(); + + if (par1 != 2 && par1 != 0) { + var2 = 0.5F; + } else { + var4 = 0.5F; + this.rotationYaw = this.prevRotationYaw = (float) (Direction.footInvisibleFaceRemap[par1] * 90); + } + + var2 /= 32.0F; + var3 /= 32.0F; + var4 /= 32.0F; + float var5 = (float) this.xPosition + 0.5F; + float var6 = (float) this.yPosition + 0.5F; + float var7 = (float) this.zPosition + 0.5F; + float var8 = 0.5625F; + + if (par1 == 2) { + var7 -= var8; + } + + if (par1 == 1) { + var5 -= var8; + } + + if (par1 == 0) { + var7 += var8; + } + + if (par1 == 3) { + var5 += var8; + } + + if (par1 == 2) { + var5 -= this.func_70517_b(this.func_82329_d()); + } + + if (par1 == 1) { + var7 += this.func_70517_b(this.func_82329_d()); + } + + if (par1 == 0) { + var5 += this.func_70517_b(this.func_82329_d()); + } + + if (par1 == 3) { + var7 -= this.func_70517_b(this.func_82329_d()); + } + + var6 += this.func_70517_b(this.func_82330_g()); + this.setPosition((double) var5, (double) var6, (double) var7); + float var9 = -0.03125F; + this.boundingBox.setBounds((double) (var5 - var2 - var9), (double) (var6 - var3 - var9), + (double) (var7 - var4 - var9), (double) (var5 + var2 + var9), (double) (var6 + var3 + var9), + (double) (var7 + var4 + var9)); + } + + private float func_70517_b(int par1) { + return par1 == 32 ? 0.5F : (par1 == 64 ? 0.5F : 0.0F); + } + + /** + * Called to update the entity's position/logic. + */ + public void onUpdate() { + if (this.tickCounter1++ == 100 && !this.worldObj.isRemote) { + this.tickCounter1 = 0; + + if (!this.isDead && !this.onValidSurface()) { + this.setDead(); + this.dropItemStack(); + } + } + } + + /** + * checks to make sure painting can be placed there + */ + public boolean onValidSurface() { + if (!this.worldObj.getCollidingBoundingBoxes(this, this.boundingBox).isEmpty()) { + return false; + } else { + int var1 = Math.max(1, this.func_82329_d() / 16); + int var2 = Math.max(1, this.func_82330_g() / 16); + int var3 = this.xPosition; + int var4 = this.yPosition; + int var5 = this.zPosition; + + if (this.hangingDirection == 2) { + var3 = MathHelper.floor_double(this.posX - (double) ((float) this.func_82329_d() / 32.0F)); + } + + if (this.hangingDirection == 1) { + var5 = MathHelper.floor_double(this.posZ - (double) ((float) this.func_82329_d() / 32.0F)); + } + + if (this.hangingDirection == 0) { + var3 = MathHelper.floor_double(this.posX - (double) ((float) this.func_82329_d() / 32.0F)); + } + + if (this.hangingDirection == 3) { + var5 = MathHelper.floor_double(this.posZ - (double) ((float) this.func_82329_d() / 32.0F)); + } + + var4 = MathHelper.floor_double(this.posY - (double) ((float) this.func_82330_g() / 32.0F)); + + for (int var6 = 0; var6 < var1; ++var6) { + for (int var7 = 0; var7 < var2; ++var7) { + Material var8; + + if (this.hangingDirection != 2 && this.hangingDirection != 0) { + var8 = this.worldObj.getBlockMaterial(this.xPosition, var4 + var7, var5 + var6); + } else { + var8 = this.worldObj.getBlockMaterial(var3 + var6, var4 + var7, this.zPosition); + } + + if (!var8.isSolid()) { + return false; + } + } + } + + List var9 = this.worldObj.getEntitiesWithinAABBExcludingEntity(this, this.boundingBox); + Iterator var10 = var9.iterator(); + Entity var11; + + do { + if (!var10.hasNext()) { + return true; + } + + var11 = (Entity) var10.next(); + } while (!(var11 instanceof EntityHanging)); + + return false; + } + } + + /** + * Returns true if other Entities should be prevented from moving through this + * Entity. + */ + public boolean canBeCollidedWith() { + return true; + } + + public boolean func_85031_j(Entity par1Entity) { + return par1Entity instanceof EntityPlayer + ? this.attackEntityFrom(DamageSource.causePlayerDamage((EntityPlayer) par1Entity), 0) + : false; + } + + /** + * Called when the entity is attacked. + */ + public boolean attackEntityFrom(DamageSource par1DamageSource, int par2) { + if (this.isEntityInvulnerable()) { + return false; + } else { + if (!this.isDead && !this.worldObj.isRemote) { + this.setDead(); + this.setBeenAttacked(); + EntityPlayer var3 = null; + + if (par1DamageSource.getEntity() instanceof EntityPlayer) { + var3 = (EntityPlayer) par1DamageSource.getEntity(); + } + + if (var3 != null && var3.capabilities.isCreativeMode) { + return true; + } + + this.dropItemStack(); + } + + return true; + } + } + + /** + * Tries to moves the entity by the passed in displacement. Args: x, y, z + */ + public void moveEntity(double par1, double par3, double par5) { + if (!this.worldObj.isRemote && !this.isDead && par1 * par1 + par3 * par3 + par5 * par5 > 0.0D) { + this.setDead(); + this.dropItemStack(); + } + } + + /** + * Adds to the current velocity of the entity. Args: x, y, z + */ + public void addVelocity(double par1, double par3, double par5) { + if (!this.worldObj.isRemote && !this.isDead && par1 * par1 + par3 * par3 + par5 * par5 > 0.0D) { + this.setDead(); + this.dropItemStack(); + } + } + + /** + * (abstract) Protected helper method to write subclass entity data to NBT. + */ + public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) { + par1NBTTagCompound.setByte("Direction", (byte) this.hangingDirection); + par1NBTTagCompound.setInteger("TileX", this.xPosition); + par1NBTTagCompound.setInteger("TileY", this.yPosition); + par1NBTTagCompound.setInteger("TileZ", this.zPosition); + + switch (this.hangingDirection) { + case 0: + par1NBTTagCompound.setByte("Dir", (byte) 2); + break; + + case 1: + par1NBTTagCompound.setByte("Dir", (byte) 1); + break; + + case 2: + par1NBTTagCompound.setByte("Dir", (byte) 0); + break; + + case 3: + par1NBTTagCompound.setByte("Dir", (byte) 3); + } + } + + /** + * (abstract) Protected helper method to read subclass entity data from NBT. + */ + public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) { + if (par1NBTTagCompound.hasKey("Direction")) { + this.hangingDirection = par1NBTTagCompound.getByte("Direction"); + } else { + switch (par1NBTTagCompound.getByte("Dir")) { + case 0: + this.hangingDirection = 2; + break; + + case 1: + this.hangingDirection = 1; + break; + + case 2: + this.hangingDirection = 0; + break; + + case 3: + this.hangingDirection = 3; + } + } + + this.xPosition = par1NBTTagCompound.getInteger("TileX"); + this.yPosition = par1NBTTagCompound.getInteger("TileY"); + this.zPosition = par1NBTTagCompound.getInteger("TileZ"); + this.setDirection(this.hangingDirection); + } + + public abstract int func_82329_d(); + + public abstract int func_82330_g(); + + /** + * Drop the item currently on this item frame. + */ + public abstract void dropItemStack(); +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityIronGolem.java b/sp-server/src/main/java/net/minecraft/src/EntityIronGolem.java new file mode 100644 index 0000000..31a0306 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityIronGolem.java @@ -0,0 +1,236 @@ +package net.minecraft.src; + +public class EntityIronGolem extends EntityGolem { + /** deincrements, and a distance-to-home check is done at 0 */ + private int homeCheckTimer = 0; + Village villageObj = null; + private int attackTimer; + private int holdRoseTick; + + public EntityIronGolem(World par1World) { + super(par1World); + this.texture = "/mob/villager_golem.png"; + this.setSize(1.4F, 2.9F); + this.getNavigator().setAvoidsWater(true); + this.tasks.addTask(1, new EntityAIAttackOnCollide(this, 0.25F, true)); + this.tasks.addTask(2, new EntityAIMoveTowardsTarget(this, 0.22F, 32.0F)); + this.tasks.addTask(3, new EntityAIMoveThroughVillage(this, 0.16F, true)); + this.tasks.addTask(4, new EntityAIMoveTwardsRestriction(this, 0.16F)); + this.tasks.addTask(5, new EntityAILookAtVillager(this)); + this.tasks.addTask(6, new EntityAIWander(this, 0.16F)); + this.tasks.addTask(7, new EntityAIWatchClosest(this, EntityPlayer.class, 6.0F)); + this.tasks.addTask(8, new EntityAILookIdle(this)); + this.targetTasks.addTask(1, new EntityAIDefendVillage(this)); + this.targetTasks.addTask(2, new EntityAIHurtByTarget(this, false)); + this.targetTasks.addTask(3, + new EntityAINearestAttackableTarget(this, EntityLiving.class, 16.0F, 0, false, true, IMob.mobSelector)); + } + + protected void entityInit() { + super.entityInit(); + this.dataWatcher.addObject(16, Byte.valueOf((byte) 0)); + } + + /** + * Returns true if the newer Entity AI code should be run + */ + public boolean isAIEnabled() { + return true; + } + + /** + * main AI tick function, replaces updateEntityActionState + */ + protected void updateAITick() { + if (--this.homeCheckTimer <= 0) { + this.homeCheckTimer = 70 + this.rand.nextInt(50); + this.villageObj = this.worldObj.villageCollectionObj.findNearestVillage(MathHelper.floor_double(this.posX), + MathHelper.floor_double(this.posY), MathHelper.floor_double(this.posZ), 32); + + if (this.villageObj == null) { + this.detachHome(); + } else { + ChunkCoordinates var1 = this.villageObj.getCenter(); + this.setHomeArea(var1.posX, var1.posY, var1.posZ, + (int) ((float) this.villageObj.getVillageRadius() * 0.6F)); + } + } + + super.updateAITick(); + } + + public int getMaxHealth() { + return 100; + } + + /** + * Decrements the entity's air supply when underwater + */ + protected int decreaseAirSupply(int par1) { + return par1; + } + + protected void collideWithEntity(Entity par1Entity) { + if (par1Entity instanceof IMob && this.getRNG().nextInt(20) == 0) { + this.setAttackTarget((EntityLiving) par1Entity); + } + + super.collideWithEntity(par1Entity); + } + + /** + * Called frequently so the entity can update its state every tick as required. + * For example, zombies and skeletons use this to react to sunlight and start to + * burn. + */ + public void onLivingUpdate() { + super.onLivingUpdate(); + + if (this.attackTimer > 0) { + --this.attackTimer; + } + + if (this.holdRoseTick > 0) { + --this.holdRoseTick; + } + + if (this.motionX * this.motionX + this.motionZ * this.motionZ > 2.500000277905201E-7D + && this.rand.nextInt(5) == 0) { + int var1 = MathHelper.floor_double(this.posX); + int var2 = MathHelper.floor_double(this.posY - 0.20000000298023224D - (double) this.yOffset); + int var3 = MathHelper.floor_double(this.posZ); + int var4 = this.worldObj.getBlockId(var1, var2, var3); + + if (var4 > 0) { + this.worldObj.spawnParticle( + "tilecrack_" + var4 + "_" + this.worldObj.getBlockMetadata(var1, var2, var3), + this.posX + ((double) this.rand.nextFloat() - 0.5D) * (double) this.width, + this.boundingBox.minY + 0.1D, + this.posZ + ((double) this.rand.nextFloat() - 0.5D) * (double) this.width, + 4.0D * ((double) this.rand.nextFloat() - 0.5D), 0.5D, + ((double) this.rand.nextFloat() - 0.5D) * 4.0D); + } + } + } + + /** + * Returns true if this entity can attack entities of the specified class. + */ + public boolean canAttackClass(Class par1Class) { + return this.isPlayerCreated() && EntityPlayer.class.isAssignableFrom(par1Class) ? false + : super.canAttackClass(par1Class); + } + + /** + * (abstract) Protected helper method to write subclass entity data to NBT. + */ + public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) { + super.writeEntityToNBT(par1NBTTagCompound); + par1NBTTagCompound.setBoolean("PlayerCreated", this.isPlayerCreated()); + } + + /** + * (abstract) Protected helper method to read subclass entity data from NBT. + */ + public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) { + super.readEntityFromNBT(par1NBTTagCompound); + this.setPlayerCreated(par1NBTTagCompound.getBoolean("PlayerCreated")); + } + + public boolean attackEntityAsMob(Entity par1Entity) { + this.attackTimer = 10; + this.worldObj.setEntityState(this, (byte) 4); + boolean var2 = par1Entity.attackEntityFrom(DamageSource.causeMobDamage(this), 7 + this.rand.nextInt(15)); + + if (var2) { + par1Entity.motionY += 0.4000000059604645D; + } + + this.playSound("mob.irongolem.throw", 1.0F, 1.0F); + return var2; + } + + public Village getVillage() { + return this.villageObj; + } + + public void setHoldingRose(boolean par1) { + this.holdRoseTick = par1 ? 400 : 0; + this.worldObj.setEntityState(this, (byte) 11); + } + + /** + * Returns the sound this mob makes while it's alive. + */ + protected String getLivingSound() { + return "none"; + } + + /** + * Returns the sound this mob makes when it is hurt. + */ + protected String getHurtSound() { + return "mob.irongolem.hit"; + } + + /** + * Returns the sound this mob makes on death. + */ + protected String getDeathSound() { + return "mob.irongolem.death"; + } + + /** + * Plays step sound at given x, y, z for the entity + */ + protected void playStepSound(int par1, int par2, int par3, int par4) { + this.playSound("mob.irongolem.walk", 1.0F, 1.0F); + } + + /** + * Drop 0-2 items of this living's type + */ + protected void dropFewItems(boolean par1, int par2) { + int var3 = this.rand.nextInt(3); + int var4; + + for (var4 = 0; var4 < var3; ++var4) { + this.dropItem(Block.plantRed.blockID, 1); + } + + var4 = 3 + this.rand.nextInt(3); + + for (int var5 = 0; var5 < var4; ++var5) { + this.dropItem(Item.ingotIron.itemID, 1); + } + } + + public int getHoldRoseTick() { + return this.holdRoseTick; + } + + public boolean isPlayerCreated() { + return (this.dataWatcher.getWatchableObjectByte(16) & 1) != 0; + } + + public void setPlayerCreated(boolean par1) { + byte var2 = this.dataWatcher.getWatchableObjectByte(16); + + if (par1) { + this.dataWatcher.updateObject(16, Byte.valueOf((byte) (var2 | 1))); + } else { + this.dataWatcher.updateObject(16, Byte.valueOf((byte) (var2 & -2))); + } + } + + /** + * Called when the mob's health reaches 0. + */ + public void onDeath(DamageSource par1DamageSource) { + if (!this.isPlayerCreated() && this.attackingPlayer != null && this.villageObj != null) { + this.villageObj.setReputationForPlayer(this.attackingPlayer.getCommandSenderName(), -5); + } + + super.onDeath(par1DamageSource); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityItem.java b/sp-server/src/main/java/net/minecraft/src/EntityItem.java new file mode 100644 index 0000000..ee07f8a --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityItem.java @@ -0,0 +1,326 @@ +package net.minecraft.src; + +import java.util.Iterator; + +public class EntityItem extends Entity { + /** + * The age of this EntityItem (used to animate it up and down as well as expire + * it) + */ + public int age; + public int delayBeforeCanPickup; + + /** The health of this EntityItem. (For example, damage for tools) */ + private int health; + + /** The EntityItem's random initial float height. */ + public float hoverStart; + + public EntityItem(World par1World, double par2, double par4, double par6) { + super(par1World); + this.age = 0; + this.health = 5; + this.hoverStart = (float) (Math.random() * Math.PI * 2.0D); + this.setSize(0.25F, 0.25F); + this.yOffset = this.height / 2.0F; + this.setPosition(par2, par4, par6); + this.rotationYaw = (float) (Math.random() * 360.0D); + this.motionX = (double) ((float) (Math.random() * 0.20000000298023224D - 0.10000000149011612D)); + this.motionY = 0.20000000298023224D; + this.motionZ = (double) ((float) (Math.random() * 0.20000000298023224D - 0.10000000149011612D)); + } + + public EntityItem(World par1World, double par2, double par4, double par6, ItemStack par8ItemStack) { + this(par1World, par2, par4, par6); + this.setEntityItemStack(par8ItemStack); + } + + /** + * returns if this entity triggers Block.onEntityWalking on the blocks they walk + * on. used for spiders and wolves to prevent them from trampling crops + */ + protected boolean canTriggerWalking() { + return false; + } + + public EntityItem(World par1World) { + super(par1World); + this.age = 0; + this.health = 5; + this.hoverStart = (float) (Math.random() * Math.PI * 2.0D); + this.setSize(0.25F, 0.25F); + this.yOffset = this.height / 2.0F; + } + + protected void entityInit() { + this.getDataWatcher().addObjectByDataType(10, 5); + } + + /** + * Called to update the entity's position/logic. + */ + public void onUpdate() { + super.onUpdate(); + + if (this.delayBeforeCanPickup > 0) { + --this.delayBeforeCanPickup; + } + + this.prevPosX = this.posX; + this.prevPosY = this.posY; + this.prevPosZ = this.posZ; + this.motionY -= 0.03999999910593033D; + this.noClip = this.pushOutOfBlocks(this.posX, (this.boundingBox.minY + this.boundingBox.maxY) / 2.0D, + this.posZ); + this.moveEntity(this.motionX, this.motionY, this.motionZ); + boolean var1 = (int) this.prevPosX != (int) this.posX || (int) this.prevPosY != (int) this.posY + || (int) this.prevPosZ != (int) this.posZ; + + if (var1 || this.ticksExisted % 25 == 0) { + if (this.worldObj.getBlockMaterial(MathHelper.floor_double(this.posX), MathHelper.floor_double(this.posY), + MathHelper.floor_double(this.posZ)) == Material.lava) { + this.motionY = 0.20000000298023224D; + this.motionX = (double) ((this.rand.nextFloat() - this.rand.nextFloat()) * 0.2F); + this.motionZ = (double) ((this.rand.nextFloat() - this.rand.nextFloat()) * 0.2F); + this.playSound("random.fizz", 0.4F, 2.0F + this.rand.nextFloat() * 0.4F); + } + + if (!this.worldObj.isRemote) { + this.searchForOtherItemsNearby(); + } + } + + float var2 = 0.98F; + + if (this.onGround) { + var2 = 0.58800006F; + int var3 = this.worldObj.getBlockId(MathHelper.floor_double(this.posX), + MathHelper.floor_double(this.boundingBox.minY) - 1, MathHelper.floor_double(this.posZ)); + + if (var3 > 0) { + var2 = Block.blocksList[var3].slipperiness * 0.98F; + } + } + + this.motionX *= (double) var2; + this.motionY *= 0.9800000190734863D; + this.motionZ *= (double) var2; + + if (this.onGround) { + this.motionY *= -0.5D; + } + + ++this.age; + + if (!this.worldObj.isRemote && this.age >= 6000) { + this.setDead(); + } + } + + /** + * Looks for other itemstacks nearby and tries to stack them together + */ + private void searchForOtherItemsNearby() { + Iterator var1 = this.worldObj.getEntitiesWithinAABB(EntityItem.class, this.boundingBox.expand(0.5D, 0.0D, 0.5D)) + .iterator(); + + while (var1.hasNext()) { + EntityItem var2 = (EntityItem) var1.next(); + this.combineItems(var2); + } + } + + /** + * Tries to merge this item with the item passed as the parameter. Returns true + * if successful. Either this item or the other item will be removed from the + * world. + */ + public boolean combineItems(EntityItem par1EntityItem) { + if (par1EntityItem == this) { + return false; + } else if (par1EntityItem.isEntityAlive() && this.isEntityAlive()) { + ItemStack var2 = this.getEntityItem(); + ItemStack var3 = par1EntityItem.getEntityItem(); + + if (var3.getItem() != var2.getItem()) { + return false; + } else if (var3.hasTagCompound() ^ var2.hasTagCompound()) { + return false; + } else if (var3.hasTagCompound() && !var3.getTagCompound().equals(var2.getTagCompound())) { + return false; + } else if (var3.getItem().getHasSubtypes() && var3.getItemDamage() != var2.getItemDamage()) { + return false; + } else if (var3.stackSize < var2.stackSize) { + return par1EntityItem.combineItems(this); + } else if (var3.stackSize + var2.stackSize > var3.getMaxStackSize()) { + return false; + } else { + var3.stackSize += var2.stackSize; + par1EntityItem.delayBeforeCanPickup = Math.max(par1EntityItem.delayBeforeCanPickup, + this.delayBeforeCanPickup); + par1EntityItem.age = Math.min(par1EntityItem.age, this.age); + par1EntityItem.setEntityItemStack(var3); + this.setDead(); + return true; + } + } else { + return false; + } + } + + /** + * sets the age of the item so that it'll despawn one minute after it has been + * dropped (instead of five). Used when items are dropped from players in + * creative mode + */ + public void setAgeToCreativeDespawnTime() { + this.age = 4800; + } + + /** + * Returns if this entity is in water and will end up adding the waters velocity + * to the entity + */ + public boolean handleWaterMovement() { + return this.worldObj.handleMaterialAcceleration(this.boundingBox, Material.water, this); + } + + /** + * Will deal the specified amount of damage to the entity if the entity isn't + * immune to fire damage. Args: amountDamage + */ + protected void dealFireDamage(int par1) { + this.attackEntityFrom(DamageSource.inFire, par1); + } + + /** + * Called when the entity is attacked. + */ + public boolean attackEntityFrom(DamageSource par1DamageSource, int par2) { + if (this.isEntityInvulnerable()) { + return false; + } else if (this.getEntityItem() != null && this.getEntityItem().itemID == Item.netherStar.itemID + && par1DamageSource.isExplosion()) { + return false; + } else { + this.setBeenAttacked(); + this.health -= par2; + + if (this.health <= 0) { + this.setDead(); + } + + return false; + } + } + + /** + * (abstract) Protected helper method to write subclass entity data to NBT. + */ + public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) { + par1NBTTagCompound.setShort("Health", (short) ((byte) this.health)); + par1NBTTagCompound.setShort("Age", (short) this.age); + + if (this.getEntityItem() != null) { + par1NBTTagCompound.setCompoundTag("Item", this.getEntityItem().writeToNBT(new NBTTagCompound())); + } + } + + /** + * (abstract) Protected helper method to read subclass entity data from NBT. + */ + public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) { + this.health = par1NBTTagCompound.getShort("Health") & 255; + this.age = par1NBTTagCompound.getShort("Age"); + NBTTagCompound var2 = par1NBTTagCompound.getCompoundTag("Item"); + this.setEntityItemStack(ItemStack.loadItemStackFromNBT(var2)); + + if (this.getEntityItem() == null) { + this.setDead(); + } + } + + /** + * Called by a player entity when they collide with an entity + */ + public void onCollideWithPlayer(EntityPlayer par1EntityPlayer) { + if (!this.worldObj.isRemote) { + ItemStack var2 = this.getEntityItem(); + int var3 = var2.stackSize; + + if (this.delayBeforeCanPickup == 0 && par1EntityPlayer.inventory.addItemStackToInventory(var2)) { + if (var2.itemID == Block.wood.blockID) { + par1EntityPlayer.triggerAchievement(AchievementList.mineWood); + } + + if (var2.itemID == Item.leather.itemID) { + par1EntityPlayer.triggerAchievement(AchievementList.killCow); + } + + if (var2.itemID == Item.diamond.itemID) { + par1EntityPlayer.triggerAchievement(AchievementList.diamonds); + } + + if (var2.itemID == Item.blazeRod.itemID) { + par1EntityPlayer.triggerAchievement(AchievementList.blazeRod); + } + + this.playSound("random.pop", 0.2F, + ((this.rand.nextFloat() - this.rand.nextFloat()) * 0.7F + 1.0F) * 2.0F); + par1EntityPlayer.onItemPickup(this, var3); + + if (var2.stackSize <= 0) { + this.setDead(); + } + } + } + } + + /** + * Gets the username of the entity. + */ + public String getEntityName() { + return StatCollector.translateToLocal("item." + this.getEntityItem().getItemName()); + } + + /** + * If returns false, the item will not inflict any damage against entities. + */ + public boolean canAttackWithItem() { + return false; + } + + public void travelToTheEnd(int par1) { + super.travelToTheEnd(par1); + + if (!this.worldObj.isRemote) { + this.searchForOtherItemsNearby(); + } + } + + /** + * Returns the ItemStack corresponding to the Entity (Note: if no item exists, + * will log an error but still return an ItemStack containing Block.stone) + */ + public ItemStack getEntityItem() { + ItemStack var1 = this.getDataWatcher().getWatchableObjectItemStack(10); + + if (var1 == null) { + if (this.worldObj != null) { + this.worldObj.getWorldLogAgent().logSevere("Item entity " + this.entityId + " has no item?!"); + } + + return new ItemStack(Block.stone); + } else { + return var1; + } + } + + /** + * Sets the ItemStack for this entity + */ + public void setEntityItemStack(ItemStack par1ItemStack) { + this.getDataWatcher().updateObject(10, par1ItemStack); + this.getDataWatcher().setObjectWatched(10); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityItemFrame.java b/sp-server/src/main/java/net/minecraft/src/EntityItemFrame.java new file mode 100644 index 0000000..2d40c57 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityItemFrame.java @@ -0,0 +1,119 @@ +package net.minecraft.src; + +public class EntityItemFrame extends EntityHanging { + /** Chance for this item frame's item to drop from the frame. */ + private float itemDropChance = 1.0F; + + public EntityItemFrame(World par1World) { + super(par1World); + } + + public EntityItemFrame(World par1World, int par2, int par3, int par4, int par5) { + super(par1World, par2, par3, par4, par5); + this.setDirection(par5); + } + + protected void entityInit() { + this.getDataWatcher().addObjectByDataType(2, 5); + this.getDataWatcher().addObject(3, Byte.valueOf((byte) 0)); + } + + public int func_82329_d() { + return 9; + } + + public int func_82330_g() { + return 9; + } + + /** + * Drop the item currently on this item frame. + */ + public void dropItemStack() { + this.entityDropItem(new ItemStack(Item.itemFrame), 0.0F); + ItemStack var1 = this.getDisplayedItem(); + + if (var1 != null && this.rand.nextFloat() < this.itemDropChance) { + var1 = var1.copy(); + var1.setItemFrame((EntityItemFrame) null); + this.entityDropItem(var1, 0.0F); + } + } + + public ItemStack getDisplayedItem() { + return this.getDataWatcher().getWatchableObjectItemStack(2); + } + + public void setDisplayedItem(ItemStack par1ItemStack) { + par1ItemStack = par1ItemStack.copy(); + par1ItemStack.stackSize = 1; + par1ItemStack.setItemFrame(this); + this.getDataWatcher().updateObject(2, par1ItemStack); + this.getDataWatcher().setObjectWatched(2); + } + + /** + * Return the rotation of the item currently on this frame. + */ + public int getRotation() { + return this.getDataWatcher().getWatchableObjectByte(3); + } + + public void setItemRotation(int par1) { + this.getDataWatcher().updateObject(3, Byte.valueOf((byte) (par1 % 4))); + } + + /** + * (abstract) Protected helper method to write subclass entity data to NBT. + */ + public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) { + if (this.getDisplayedItem() != null) { + par1NBTTagCompound.setCompoundTag("Item", this.getDisplayedItem().writeToNBT(new NBTTagCompound())); + par1NBTTagCompound.setByte("ItemRotation", (byte) this.getRotation()); + par1NBTTagCompound.setFloat("ItemDropChance", this.itemDropChance); + } + + super.writeEntityToNBT(par1NBTTagCompound); + } + + /** + * (abstract) Protected helper method to read subclass entity data from NBT. + */ + public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) { + NBTTagCompound var2 = par1NBTTagCompound.getCompoundTag("Item"); + + if (var2 != null && !var2.hasNoTags()) { + this.setDisplayedItem(ItemStack.loadItemStackFromNBT(var2)); + this.setItemRotation(par1NBTTagCompound.getByte("ItemRotation")); + + if (par1NBTTagCompound.hasKey("ItemDropChance")) { + this.itemDropChance = par1NBTTagCompound.getFloat("ItemDropChance"); + } + } + + super.readEntityFromNBT(par1NBTTagCompound); + } + + /** + * Called when a player interacts with a mob. e.g. gets milk from a cow, gets + * into the saddle on a pig. + */ + public boolean interact(EntityPlayer par1EntityPlayer) { + if (this.getDisplayedItem() == null) { + ItemStack var2 = par1EntityPlayer.getHeldItem(); + + if (var2 != null && !this.worldObj.isRemote) { + this.setDisplayedItem(var2); + + if (!par1EntityPlayer.capabilities.isCreativeMode && --var2.stackSize <= 0) { + par1EntityPlayer.inventory.setInventorySlotContents(par1EntityPlayer.inventory.currentItem, + (ItemStack) null); + } + } + } else if (!this.worldObj.isRemote) { + this.setItemRotation(this.getRotation() + 1); + } + + return true; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityJumpHelper.java b/sp-server/src/main/java/net/minecraft/src/EntityJumpHelper.java new file mode 100644 index 0000000..3914cfe --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityJumpHelper.java @@ -0,0 +1,22 @@ +package net.minecraft.src; + +public class EntityJumpHelper { + private EntityLiving entity; + private boolean isJumping = false; + + public EntityJumpHelper(EntityLiving par1EntityLiving) { + this.entity = par1EntityLiving; + } + + public void setJumping() { + this.isJumping = true; + } + + /** + * Called to actually make the entity jump if isJumping is true. + */ + public void doJump() { + this.entity.setJumping(this.isJumping); + this.isJumping = false; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityLargeFireball.java b/sp-server/src/main/java/net/minecraft/src/EntityLargeFireball.java new file mode 100644 index 0000000..35f2b9e --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityLargeFireball.java @@ -0,0 +1,48 @@ +package net.minecraft.src; + +public class EntityLargeFireball extends EntityFireball { + public int field_92057_e = 1; + + public EntityLargeFireball(World par1World) { + super(par1World); + } + + public EntityLargeFireball(World par1World, EntityLiving par2EntityLiving, double par3, double par5, double par7) { + super(par1World, par2EntityLiving, par3, par5, par7); + } + + /** + * Called when this EntityFireball hits a block or entity. + */ + protected void onImpact(MovingObjectPosition par1MovingObjectPosition) { + if (!this.worldObj.isRemote) { + if (par1MovingObjectPosition.entityHit != null) { + par1MovingObjectPosition.entityHit + .attackEntityFrom(DamageSource.causeFireballDamage(this, this.shootingEntity), 6); + } + + this.worldObj.newExplosion((Entity) null, this.posX, this.posY, this.posZ, (float) this.field_92057_e, true, + this.worldObj.getGameRules().getGameRuleBooleanValue("mobGriefing")); + this.setDead(); + } + } + + /** + * (abstract) Protected helper method to write subclass entity data to NBT. + */ + public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) { + super.writeEntityToNBT(par1NBTTagCompound); + par1NBTTagCompound.setInteger("ExplosionPower", this.field_92057_e); + } + + /** + * (abstract) Protected helper method to read subclass entity data from NBT. + */ + public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) { + super.readEntityFromNBT(par1NBTTagCompound); + + if (par1NBTTagCompound.hasKey("ExplosionPower")) { + this.field_92057_e = par1NBTTagCompound.getInteger("ExplosionPower"); + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityLightningBolt.java b/sp-server/src/main/java/net/minecraft/src/EntityLightningBolt.java new file mode 100644 index 0000000..95cb030 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityLightningBolt.java @@ -0,0 +1,123 @@ +package net.minecraft.src; + +import java.util.List; + +public class EntityLightningBolt extends EntityWeatherEffect { + /** + * Declares which state the lightning bolt is in. Whether it's in the air, hit + * the ground, etc. + */ + private int lightningState; + + /** + * A random long that is used to change the vertex of the lightning rendered in + * RenderLightningBolt + */ + public long boltVertex = 0L; + + /** + * Determines the time before the EntityLightningBolt is destroyed. It is a + * random integer decremented over time. + */ + private int boltLivingTime; + + public EntityLightningBolt(World par1World, double par2, double par4, double par6) { + super(par1World); + this.setLocationAndAngles(par2, par4, par6, 0.0F, 0.0F); + this.lightningState = 2; + this.boltVertex = this.rand.nextLong(); + this.boltLivingTime = this.rand.nextInt(3) + 1; + + if (!par1World.isRemote && par1World.difficultySetting >= 2 && par1World.doChunksNearChunkExist( + MathHelper.floor_double(par2), MathHelper.floor_double(par4), MathHelper.floor_double(par6), 10)) { + int var8 = MathHelper.floor_double(par2); + int var9 = MathHelper.floor_double(par4); + int var10 = MathHelper.floor_double(par6); + + if (par1World.getBlockId(var8, var9, var10) == 0 + && Block.fire.canPlaceBlockAt(par1World, var8, var9, var10)) { + par1World.setBlock(var8, var9, var10, Block.fire.blockID); + } + + for (var8 = 0; var8 < 4; ++var8) { + var9 = MathHelper.floor_double(par2) + this.rand.nextInt(3) - 1; + var10 = MathHelper.floor_double(par4) + this.rand.nextInt(3) - 1; + int var11 = MathHelper.floor_double(par6) + this.rand.nextInt(3) - 1; + + if (par1World.getBlockId(var9, var10, var11) == 0 + && Block.fire.canPlaceBlockAt(par1World, var9, var10, var11)) { + par1World.setBlock(var9, var10, var11, Block.fire.blockID); + } + } + } + } + + /** + * Called to update the entity's position/logic. + */ + public void onUpdate() { + super.onUpdate(); + + if (this.lightningState == 2) { + this.worldObj.playSoundEffect(this.posX, this.posY, this.posZ, "ambient.weather.thunder", 10000.0F, + 0.8F + this.rand.nextFloat() * 0.2F); + this.worldObj.playSoundEffect(this.posX, this.posY, this.posZ, "random.explode", 2.0F, + 0.5F + this.rand.nextFloat() * 0.2F); + } + + --this.lightningState; + + if (this.lightningState < 0) { + if (this.boltLivingTime == 0) { + this.setDead(); + } else if (this.lightningState < -this.rand.nextInt(10)) { + --this.boltLivingTime; + this.lightningState = 1; + this.boltVertex = this.rand.nextLong(); + + if (!this.worldObj.isRemote && this.worldObj.doChunksNearChunkExist(MathHelper.floor_double(this.posX), + MathHelper.floor_double(this.posY), MathHelper.floor_double(this.posZ), 10)) { + int var1 = MathHelper.floor_double(this.posX); + int var2 = MathHelper.floor_double(this.posY); + int var3 = MathHelper.floor_double(this.posZ); + + if (this.worldObj.getBlockId(var1, var2, var3) == 0 + && Block.fire.canPlaceBlockAt(this.worldObj, var1, var2, var3)) { + this.worldObj.setBlock(var1, var2, var3, Block.fire.blockID); + } + } + } + } + + if (this.lightningState >= 0) { + if (this.worldObj.isRemote) { + this.worldObj.lastLightningBolt = 2; + } else { + double var6 = 3.0D; + List var7 = this.worldObj.getEntitiesWithinAABBExcludingEntity(this, + AxisAlignedBB.getAABBPool().getAABB(this.posX - var6, this.posY - var6, this.posZ - var6, + this.posX + var6, this.posY + 6.0D + var6, this.posZ + var6)); + + for (int var4 = 0; var4 < var7.size(); ++var4) { + Entity var5 = (Entity) var7.get(var4); + var5.onStruckByLightning(this); + } + } + } + } + + protected void entityInit() { + } + + /** + * (abstract) Protected helper method to read subclass entity data from NBT. + */ + protected void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) { + } + + /** + * (abstract) Protected helper method to write subclass entity data to NBT. + */ + protected void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) { + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityList.java b/sp-server/src/main/java/net/minecraft/src/EntityList.java new file mode 100644 index 0000000..071c102 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityList.java @@ -0,0 +1,219 @@ +package net.minecraft.src; + +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.Map; + +public class EntityList { + /** Provides a mapping between entity classes and a string */ + private static Map stringToClassMapping = new HashMap(); + + /** Provides a mapping between a string and an entity classes */ + private static Map classToStringMapping = new HashMap(); + + /** provides a mapping between an entityID and an Entity Class */ + private static Map IDtoClassMapping = new HashMap(); + + /** provides a mapping between an Entity Class and an entity ID */ + private static Map classToIDMapping = new HashMap(); + + /** Maps entity names to their numeric identifiers */ + private static Map stringToIDMapping = new HashMap(); + + /** This is a HashMap of the Creative Entity Eggs/Spawners. */ + public static HashMap entityEggs = new LinkedHashMap(); + + /** + * adds a mapping between Entity classes and both a string representation and an + * ID + */ + private static void addMapping(Class par0Class, String par1Str, int par2) { + stringToClassMapping.put(par1Str, par0Class); + classToStringMapping.put(par0Class, par1Str); + IDtoClassMapping.put(Integer.valueOf(par2), par0Class); + classToIDMapping.put(par0Class, Integer.valueOf(par2)); + stringToIDMapping.put(par1Str, Integer.valueOf(par2)); + } + + /** + * Adds a entity mapping with egg info. + */ + private static void addMapping(Class par0Class, String par1Str, int par2, int par3, int par4) { + addMapping(par0Class, par1Str, par2); + entityEggs.put(Integer.valueOf(par2), new EntityEggInfo(par2, par3, par4)); + } + + /** + * Create a new instance of an entity in the world by using the entity name. + */ + public static Entity createEntityByName(String par0Str, World par1World) { + Entity var2 = null; + + try { + Class var3 = (Class) stringToClassMapping.get(par0Str); + + if (var3 != null) { + var2 = (Entity) var3.getConstructor(new Class[] { World.class }) + .newInstance(new Object[] { par1World }); + } + } catch (Exception var4) { + var4.printStackTrace(); + } + + return var2; + } + + /** + * create a new instance of an entity from NBT store + */ + public static Entity createEntityFromNBT(NBTTagCompound par0NBTTagCompound, World par1World) { + Entity var2 = null; + + if ("Minecart".equals(par0NBTTagCompound.getString("id"))) { + switch (par0NBTTagCompound.getInteger("Type")) { + case 0: + par0NBTTagCompound.setString("id", "MinecartRideable"); + break; + + case 1: + par0NBTTagCompound.setString("id", "MinecartChest"); + break; + + case 2: + par0NBTTagCompound.setString("id", "MinecartFurnace"); + } + + par0NBTTagCompound.removeTag("Type"); + } + + try { + Class var3 = (Class) stringToClassMapping.get(par0NBTTagCompound.getString("id")); + + if (var3 != null) { + var2 = (Entity) var3.getConstructor(new Class[] { World.class }) + .newInstance(new Object[] { par1World }); + } + } catch (Exception var4) { + var4.printStackTrace(); + } + + if (var2 != null) { + var2.readFromNBT(par0NBTTagCompound); + } else { + par1World.getWorldLogAgent().func_98236_b("Skipping Entity with id " + par0NBTTagCompound.getString("id")); + } + + return var2; + } + + /** + * Create a new instance of an entity in the world by using an entity ID. + */ + public static Entity createEntityByID(int par0, World par1World) { + Entity var2 = null; + + try { + Class var3 = getClassFromID(par0); + + if (var3 != null) { + var2 = (Entity) var3.getConstructor(new Class[] { World.class }) + .newInstance(new Object[] { par1World }); + } + } catch (Exception var4) { + var4.printStackTrace(); + } + + if (var2 == null) { + par1World.getWorldLogAgent().func_98236_b("Skipping Entity with id " + par0); + } + + return var2; + } + + /** + * gets the entityID of a specific entity + */ + public static int getEntityID(Entity par0Entity) { + Class var1 = par0Entity.getClass(); + return classToIDMapping.containsKey(var1) ? ((Integer) classToIDMapping.get(var1)).intValue() : 0; + } + + /** + * Return the class assigned to this entity ID. + */ + public static Class getClassFromID(int par0) { + return (Class) IDtoClassMapping.get(Integer.valueOf(par0)); + } + + /** + * Gets the string representation of a specific entity. + */ + public static String getEntityString(Entity par0Entity) { + return (String) classToStringMapping.get(par0Entity.getClass()); + } + + /** + * Finds the class using IDtoClassMapping and classToStringMapping + */ + public static String getStringFromID(int par0) { + Class var1 = getClassFromID(par0); + return var1 != null ? (String) classToStringMapping.get(var1) : null; + } + + static { + addMapping(EntityItem.class, "Item", 1); + addMapping(EntityXPOrb.class, "XPOrb", 2); + addMapping(EntityPainting.class, "Painting", 9); + addMapping(EntityArrow.class, "Arrow", 10); + addMapping(EntitySnowball.class, "Snowball", 11); + addMapping(EntityLargeFireball.class, "Fireball", 12); + addMapping(EntitySmallFireball.class, "SmallFireball", 13); + addMapping(EntityEnderPearl.class, "ThrownEnderpearl", 14); + addMapping(EntityEnderEye.class, "EyeOfEnderSignal", 15); + addMapping(EntityPotion.class, "ThrownPotion", 16); + addMapping(EntityExpBottle.class, "ThrownExpBottle", 17); + addMapping(EntityItemFrame.class, "ItemFrame", 18); + addMapping(EntityWitherSkull.class, "WitherSkull", 19); + addMapping(EntityTNTPrimed.class, "PrimedTnt", 20); + addMapping(EntityFallingSand.class, "FallingSand", 21); + addMapping(EntityFireworkRocket.class, "FireworksRocketEntity", 22); + addMapping(EntityBoat.class, "Boat", 41); + addMapping(EntityMinecartEmpty.class, "MinecartRideable", 42); + addMapping(EntityMinecartChest.class, "MinecartChest", 43); + addMapping(EntityMinecartFurnace.class, "MinecartFurnace", 44); + addMapping(EntityMinecartTNT.class, "MinecartTNT", 45); + addMapping(EntityMinecartHopper.class, "MinecartHopper", 46); + addMapping(EntityMinecartMobSpawner.class, "MinecartSpawner", 47); + addMapping(EntityLiving.class, "Mob", 48); + addMapping(EntityMob.class, "Monster", 49); + addMapping(EntityCreeper.class, "Creeper", 50, 894731, 0); + addMapping(EntitySkeleton.class, "Skeleton", 51, 12698049, 4802889); + addMapping(EntitySpider.class, "Spider", 52, 3419431, 11013646); + addMapping(EntityGiantZombie.class, "Giant", 53); + addMapping(EntityZombie.class, "Zombie", 54, 44975, 7969893); + addMapping(EntitySlime.class, "Slime", 55, 5349438, 8306542); + addMapping(EntityGhast.class, "Ghast", 56, 16382457, 12369084); + addMapping(EntityPigZombie.class, "PigZombie", 57, 15373203, 5009705); + addMapping(EntityEnderman.class, "Enderman", 58, 1447446, 0); + addMapping(EntityCaveSpider.class, "CaveSpider", 59, 803406, 11013646); + addMapping(EntitySilverfish.class, "Silverfish", 60, 7237230, 3158064); + addMapping(EntityBlaze.class, "Blaze", 61, 16167425, 16775294); + addMapping(EntityMagmaCube.class, "LavaSlime", 62, 3407872, 16579584); + addMapping(EntityDragon.class, "EnderDragon", 63); + addMapping(EntityWither.class, "WitherBoss", 64); + addMapping(EntityBat.class, "Bat", 65, 4996656, 986895); + addMapping(EntityWitch.class, "Witch", 66, 3407872, 5349438); + addMapping(EntityPig.class, "Pig", 90, 15771042, 14377823); + addMapping(EntitySheep.class, "Sheep", 91, 15198183, 16758197); + addMapping(EntityCow.class, "Cow", 92, 4470310, 10592673); + addMapping(EntityChicken.class, "Chicken", 93, 10592673, 16711680); + addMapping(EntitySquid.class, "Squid", 94, 2243405, 7375001); + addMapping(EntityWolf.class, "Wolf", 95, 14144467, 13545366); + addMapping(EntityMooshroom.class, "MushroomCow", 96, 10489616, 12040119); + addMapping(EntitySnowman.class, "SnowMan", 97); + addMapping(EntityOcelot.class, "Ozelot", 98, 15720061, 5653556); + addMapping(EntityIronGolem.class, "VillagerGolem", 99); + addMapping(EntityVillager.class, "Villager", 120, 5651507, 12422002); + addMapping(EntityEnderCrystal.class, "EnderCrystal", 200); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityLiving.java b/sp-server/src/main/java/net/minecraft/src/EntityLiving.java new file mode 100644 index 0000000..8c33fc3 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityLiving.java @@ -0,0 +1,2503 @@ +package net.minecraft.src; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Random; + +public abstract class EntityLiving extends Entity { + /** + * An array of probabilities that determines whether a random enchantment should + * be added to the held item. Indexed by difficulty. + */ + private static final float[] enchantmentProbability = new float[] { 0.0F, 0.0F, 0.1F, 0.2F }; + + /** Probability to get enchanted armor */ + private static final float[] armorEnchantmentProbability = new float[] { 0.0F, 0.0F, 0.25F, 0.5F }; + + /** Probability to get armor */ + private static final float[] armorProbability = new float[] { 0.0F, 0.0F, 0.05F, 0.07F }; + + /** Probability to pick up loot */ + public static final float[] pickUpLootProability = new float[] { 0.0F, 0.1F, 0.15F, 0.45F }; + public int maxHurtResistantTime = 20; + public float field_70769_ao; + public float field_70770_ap; + public float renderYawOffset = 0.0F; + public float prevRenderYawOffset = 0.0F; + + /** Entity head rotation yaw */ + public float rotationYawHead = 0.0F; + + /** Entity head rotation yaw at previous tick */ + public float prevRotationYawHead = 0.0F; + protected float field_70768_au; + protected float field_70766_av; + protected float field_70764_aw; + protected float field_70763_ax; + protected boolean field_70753_ay = true; + + /** the path for the texture of this entityLiving */ + protected String texture = "/mob/char.png"; + protected boolean field_70740_aA = true; + protected float field_70741_aB = 0.0F; + + /** + * a string holding the type of entity it is currently only implemented in + * entityPlayer(as 'humanoid') + */ + protected String entityType = null; + protected float field_70743_aD = 1.0F; + + /** The score value of the Mob, the amount of points the mob is worth. */ + protected int scoreValue = 0; + protected float field_70745_aF = 0.0F; + + /** + * A factor used to determine how far this entity will move each tick if it is + * walking on land. Adjusted by speed, and slipperiness of the current block. + */ + public float landMovementFactor = 0.1F; + + /** + * A factor used to determine how far this entity will move each tick if it is + * jumping or falling. + */ + public float jumpMovementFactor = 0.02F; + public float prevSwingProgress; + public float swingProgress; + protected int health = this.getMaxHealth(); + public int prevHealth; + + /** + * in each step in the damage calculations, this is set to the 'carryover' that + * would result if someone was damaged .25 hearts (for example), and added to + * the damage in the next step + */ + protected int carryoverDamage; + + /** Number of ticks since this EntityLiving last produced its sound */ + public int livingSoundTime; + + /** + * The amount of time remaining this entity should act 'hurt'. (Visual + * appearance of red tint) + */ + public int hurtTime; + + /** What the hurt time was max set to last. */ + public int maxHurtTime; + + /** The yaw at which this entity was last attacked from. */ + public float attackedAtYaw = 0.0F; + + /** + * The amount of time remaining this entity should act 'dead', i.e. have a + * corpse in the world. + */ + public int deathTime = 0; + public int attackTime = 0; + public float prevCameraPitch; + public float cameraPitch; + + /** + * This gets set on entity death, but never used. Looks like a duplicate of + * isDead + */ + protected boolean dead = false; + + /** The experience points the Entity gives. */ + protected int experienceValue; + public int field_70731_aW = -1; + public float field_70730_aX = (float) (Math.random() * 0.8999999761581421D + 0.10000000149011612D); + public float prevLimbYaw; + public float limbYaw; + + /** + * Only relevant when limbYaw is not 0(the entity is moving). Influences where + * in its swing legs and arms currently are. + */ + public float limbSwing; + + /** The most recent player that has attacked this entity */ + protected EntityPlayer attackingPlayer = null; + + /** + * Set to 60 when hit by the player or the player's wolf, then decrements. Used + * to determine whether the entity should drop items on death. + */ + protected int recentlyHit = 0; + + /** is only being set, has no uses as of MC 1.1 */ + private EntityLiving entityLivingToAttack = null; + private int revengeTimer = 0; + private EntityLiving lastAttackingEntity = null; + public int arrowHitTimer = 0; + protected HashMap activePotionsMap = new HashMap(); + + /** Whether the DataWatcher needs to be updated with the active potions */ + private boolean potionsNeedUpdate = true; + private int field_70748_f; + private EntityLookHelper lookHelper; + private EntityMoveHelper moveHelper; + + /** Entity jumping helper */ + private EntityJumpHelper jumpHelper; + private EntityBodyHelper bodyHelper; + private PathNavigate navigator; + protected final EntityAITasks tasks; + protected final EntityAITasks targetTasks; + + /** The active target the Task system uses for tracking */ + private EntityLiving attackTarget; + private EntitySenses senses; + private float AIMoveSpeed; + private ChunkCoordinates homePosition = new ChunkCoordinates(0, 0, 0); + + /** If -1 there is no maximum distance */ + private float maximumHomeDistance = -1.0F; + + /** Equipment (armor and held item) for this entity. */ + private ItemStack[] equipment = new ItemStack[5]; + + /** Chances for each equipment piece from dropping when this entity dies. */ + protected float[] equipmentDropChances = new float[5]; + + /** The equipment this mob was previously wearing, used for syncing. */ + private ItemStack[] previousEquipment = new ItemStack[5]; + + /** Whether an arm swing is currently in progress. */ + public boolean isSwingInProgress = false; + public int swingProgressInt = 0; + + /** Whether this entity can pick up items from the ground. */ + private boolean canPickUpLoot = false; + + /** Whether this entity should NOT despawn. */ + private boolean persistenceRequired = false; + protected final CombatTracker field_94063_bt = new CombatTracker(this); + + /** + * The number of updates over which the new position and rotation are to be + * applied to the entity. + */ + protected int newPosRotationIncrements; + + /** The new X position to be applied to the entity. */ + protected double newPosX; + + /** The new Y position to be applied to the entity. */ + protected double newPosY; + + /** The new Z position to be applied to the entity. */ + protected double newPosZ; + + /** The new yaw rotation to be applied to the entity. */ + protected double newRotationYaw; + + /** The new yaw rotation to be applied to the entity. */ + protected double newRotationPitch; + float field_70706_bo = 0.0F; + + /** Amount of damage taken in last hit, in half-hearts */ + protected int lastDamage = 0; + + /** The age of this EntityLiving (used to determine when it dies) */ + protected int entityAge = 0; + protected float moveStrafing; + protected float moveForward; + protected float randomYawVelocity; + + /** used to check whether entity is jumping. */ + protected boolean isJumping = false; + protected float defaultPitch = 0.0F; + protected float moveSpeed = 0.7F; + + /** Number of ticks since last jump */ + private int jumpTicks = 0; + + /** This entity's current target. */ + private Entity currentTarget; + + /** How long to keep a specific target entity */ + protected int numTicksToChaseTarget = 0; + + public EntityLiving(World par1World) { + super(par1World); + this.preventEntitySpawning = true; + this.tasks = new EntityAITasks( + par1World != null && par1World.theProfiler != null ? par1World.theProfiler : null); + this.targetTasks = new EntityAITasks( + par1World != null && par1World.theProfiler != null ? par1World.theProfiler : null); + this.lookHelper = new EntityLookHelper(this); + this.moveHelper = new EntityMoveHelper(this); + this.jumpHelper = new EntityJumpHelper(this); + this.bodyHelper = new EntityBodyHelper(this); + this.navigator = new PathNavigate(this, par1World, (float) this.func_96121_ay()); + this.senses = new EntitySenses(this); + this.field_70770_ap = (float) (Math.random() + 1.0D) * 0.01F; + this.setPosition(this.posX, this.posY, this.posZ); + this.field_70769_ao = (float) Math.random() * 12398.0F; + this.rotationYaw = (float) (Math.random() * Math.PI * 2.0D); + this.rotationYawHead = this.rotationYaw; + + for (int var2 = 0; var2 < this.equipmentDropChances.length; ++var2) { + this.equipmentDropChances[var2] = 0.085F; + } + + this.stepHeight = 0.5F; + } + + protected int func_96121_ay() { + return 16; + } + + public EntityLookHelper getLookHelper() { + return this.lookHelper; + } + + public EntityMoveHelper getMoveHelper() { + return this.moveHelper; + } + + public EntityJumpHelper getJumpHelper() { + return this.jumpHelper; + } + + public PathNavigate getNavigator() { + return this.navigator; + } + + /** + * returns the EntitySenses Object for the EntityLiving + */ + public EntitySenses getEntitySenses() { + return this.senses; + } + + public Random getRNG() { + return this.rand; + } + + public EntityLiving getAITarget() { + return this.entityLivingToAttack; + } + + public EntityLiving getLastAttackingEntity() { + return this.lastAttackingEntity; + } + + public void setLastAttackingEntity(Entity par1Entity) { + if (par1Entity instanceof EntityLiving) { + this.lastAttackingEntity = (EntityLiving) par1Entity; + } + } + + public int getAge() { + return this.entityAge; + } + + public float getRotationYawHead() { + return this.rotationYawHead; + } + + /** + * the movespeed used for the new AI system + */ + public float getAIMoveSpeed() { + return this.AIMoveSpeed; + } + + /** + * set the movespeed used for the new AI system + */ + public void setAIMoveSpeed(float par1) { + this.AIMoveSpeed = par1; + this.setMoveForward(par1); + } + + public boolean attackEntityAsMob(Entity par1Entity) { + this.setLastAttackingEntity(par1Entity); + return false; + } + + /** + * Gets the active target the Task system uses for tracking + */ + public EntityLiving getAttackTarget() { + return this.attackTarget; + } + + /** + * Sets the active target the Task system uses for tracking + */ + public void setAttackTarget(EntityLiving par1EntityLiving) { + this.attackTarget = par1EntityLiving; + } + + /** + * Returns true if this entity can attack entities of the specified class. + */ + public boolean canAttackClass(Class par1Class) { + return EntityCreeper.class != par1Class && EntityGhast.class != par1Class; + } + + /** + * This function applies the benefits of growing back wool and faster growing up + * to the acting entity. (This function is used in the AIEatGrass) + */ + public void eatGrassBonus() { + } + + /** + * Takes in the distance the entity has fallen this tick and whether its on the + * ground to update the fall distance and deal fall damage if landing on the + * ground. Args: distanceFallenThisTick, onGround + */ + protected void updateFallState(double par1, boolean par3) { + if (!this.isInWater()) { + this.handleWaterMovement(); + } + + if (par3 && this.fallDistance > 0.0F) { + int var4 = MathHelper.floor_double(this.posX); + int var5 = MathHelper.floor_double(this.posY - 0.20000000298023224D - (double) this.yOffset); + int var6 = MathHelper.floor_double(this.posZ); + int var7 = this.worldObj.getBlockId(var4, var5, var6); + + if (var7 == 0) { + int var8 = this.worldObj.blockGetRenderType(var4, var5 - 1, var6); + + if (var8 == 11 || var8 == 32 || var8 == 21) { + var7 = this.worldObj.getBlockId(var4, var5 - 1, var6); + } + } + + if (var7 > 0) { + Block.blocksList[var7].onFallenUpon(this.worldObj, var4, var5, var6, this, this.fallDistance); + } + } + + super.updateFallState(par1, par3); + } + + /** + * Returns true if entity is within home distance from current position + */ + public boolean isWithinHomeDistanceCurrentPosition() { + return this.isWithinHomeDistance(MathHelper.floor_double(this.posX), MathHelper.floor_double(this.posY), + MathHelper.floor_double(this.posZ)); + } + + public boolean isWithinHomeDistance(int par1, int par2, int par3) { + return this.maximumHomeDistance == -1.0F ? true + : this.homePosition.getDistanceSquared(par1, par2, par3) < this.maximumHomeDistance + * this.maximumHomeDistance; + } + + public void setHomeArea(int par1, int par2, int par3, int par4) { + this.homePosition.set(par1, par2, par3); + this.maximumHomeDistance = (float) par4; + } + + public ChunkCoordinates getHomePosition() { + return this.homePosition; + } + + public float getMaximumHomeDistance() { + return this.maximumHomeDistance; + } + + public void detachHome() { + this.maximumHomeDistance = -1.0F; + } + + public boolean hasHome() { + return this.maximumHomeDistance != -1.0F; + } + + public void setRevengeTarget(EntityLiving par1EntityLiving) { + this.entityLivingToAttack = par1EntityLiving; + this.revengeTimer = this.entityLivingToAttack != null ? 100 : 0; + } + + protected void entityInit() { + this.dataWatcher.addObject(8, Integer.valueOf(this.field_70748_f)); + this.dataWatcher.addObject(9, Byte.valueOf((byte) 0)); + this.dataWatcher.addObject(10, Byte.valueOf((byte) 0)); + this.dataWatcher.addObject(6, Byte.valueOf((byte) 0)); + this.dataWatcher.addObject(5, ""); + } + + /** + * returns true if the entity provided in the argument can be seen. (Raytrace) + */ + public boolean canEntityBeSeen(Entity par1Entity) { + return this.worldObj.rayTraceBlocks( + this.worldObj.getWorldVec3Pool().getVecFromPool(this.posX, this.posY + (double) this.getEyeHeight(), + this.posZ), + this.worldObj.getWorldVec3Pool().getVecFromPool(par1Entity.posX, + par1Entity.posY + (double) par1Entity.getEyeHeight(), par1Entity.posZ)) == null; + } + + /** + * Returns true if other Entities should be prevented from moving through this + * Entity. + */ + public boolean canBeCollidedWith() { + return !this.isDead; + } + + /** + * Returns true if this entity should push and be pushed by other entities when + * colliding. + */ + public boolean canBePushed() { + return !this.isDead; + } + + public float getEyeHeight() { + return this.height * 0.85F; + } + + /** + * Get number of ticks, at least during which the living entity will be silent. + */ + public int getTalkInterval() { + return 80; + } + + /** + * Plays living's sound at its position + */ + public void playLivingSound() { + String var1 = this.getLivingSound(); + + if (var1 != null) { + this.playSound(var1, this.getSoundVolume(), this.getSoundPitch()); + } + } + + /** + * Gets called every tick from main Entity class + */ + public void onEntityUpdate() { + this.prevSwingProgress = this.swingProgress; + super.onEntityUpdate(); + this.worldObj.theProfiler.startSection("mobBaseTick"); + + if (this.isEntityAlive() && this.rand.nextInt(1000) < this.livingSoundTime++) { + this.livingSoundTime = -this.getTalkInterval(); + this.playLivingSound(); + } + + if (this.isEntityAlive() && this.isEntityInsideOpaqueBlock()) { + this.attackEntityFrom(DamageSource.inWall, 1); + } + + if (this.isImmuneToFire() || this.worldObj.isRemote) { + this.extinguish(); + } + + boolean var1 = this instanceof EntityPlayer && ((EntityPlayer) this).capabilities.disableDamage; + + if (this.isEntityAlive() && this.isInsideOfMaterial(Material.water) && !this.canBreatheUnderwater() + && !this.activePotionsMap.containsKey(Integer.valueOf(Potion.waterBreathing.id)) && !var1) { + this.setAir(this.decreaseAirSupply(this.getAir())); + + if (this.getAir() == -20) { + this.setAir(0); + + for (int var2 = 0; var2 < 8; ++var2) { + float var3 = this.rand.nextFloat() - this.rand.nextFloat(); + float var4 = this.rand.nextFloat() - this.rand.nextFloat(); + float var5 = this.rand.nextFloat() - this.rand.nextFloat(); + this.worldObj.spawnParticle("bubble", this.posX + (double) var3, this.posY + (double) var4, + this.posZ + (double) var5, this.motionX, this.motionY, this.motionZ); + } + + this.attackEntityFrom(DamageSource.drown, 2); + } + + this.extinguish(); + } else { + this.setAir(300); + } + + this.prevCameraPitch = this.cameraPitch; + + if (this.attackTime > 0) { + --this.attackTime; + } + + if (this.hurtTime > 0) { + --this.hurtTime; + } + + if (this.hurtResistantTime > 0) { + --this.hurtResistantTime; + } + + if (this.health <= 0) { + this.onDeathUpdate(); + } + + if (this.recentlyHit > 0) { + --this.recentlyHit; + } else { + this.attackingPlayer = null; + } + + if (this.lastAttackingEntity != null && !this.lastAttackingEntity.isEntityAlive()) { + this.lastAttackingEntity = null; + } + + if (this.entityLivingToAttack != null) { + if (!this.entityLivingToAttack.isEntityAlive()) { + this.setRevengeTarget((EntityLiving) null); + } else if (this.revengeTimer > 0) { + --this.revengeTimer; + } else { + this.setRevengeTarget((EntityLiving) null); + } + } + + this.updatePotionEffects(); + this.field_70763_ax = this.field_70764_aw; + this.prevRenderYawOffset = this.renderYawOffset; + this.prevRotationYawHead = this.rotationYawHead; + this.prevRotationYaw = this.rotationYaw; + this.prevRotationPitch = this.rotationPitch; + this.worldObj.theProfiler.endSection(); + } + + /** + * handles entity death timer, experience orb and particle creation + */ + protected void onDeathUpdate() { + ++this.deathTime; + + if (this.deathTime == 20) { + int var1; + + if (!this.worldObj.isRemote && (this.recentlyHit > 0 || this.isPlayer()) && !this.isChild() + && this.worldObj.getGameRules().getGameRuleBooleanValue("doMobLoot")) { + var1 = this.getExperiencePoints(this.attackingPlayer); + + while (var1 > 0) { + int var2 = EntityXPOrb.getXPSplit(var1); + var1 -= var2; + this.worldObj + .spawnEntityInWorld(new EntityXPOrb(this.worldObj, this.posX, this.posY, this.posZ, var2)); + } + } + + this.setDead(); + + for (var1 = 0; var1 < 20; ++var1) { + double var8 = this.rand.nextGaussian() * 0.02D; + double var4 = this.rand.nextGaussian() * 0.02D; + double var6 = this.rand.nextGaussian() * 0.02D; + this.worldObj.spawnParticle("explode", + this.posX + (double) (this.rand.nextFloat() * this.width * 2.0F) - (double) this.width, + this.posY + (double) (this.rand.nextFloat() * this.height), + this.posZ + (double) (this.rand.nextFloat() * this.width * 2.0F) - (double) this.width, var8, + var4, var6); + } + } + } + + /** + * Decrements the entity's air supply when underwater + */ + protected int decreaseAirSupply(int par1) { + int var2 = EnchantmentHelper.getRespiration(this); + return var2 > 0 && this.rand.nextInt(var2 + 1) > 0 ? par1 : par1 - 1; + } + + /** + * Get the experience points the entity currently has. + */ + protected int getExperiencePoints(EntityPlayer par1EntityPlayer) { + if (this.experienceValue > 0) { + int var2 = this.experienceValue; + ItemStack[] var3 = this.getInventory(); + + for (int var4 = 0; var4 < var3.length; ++var4) { + if (var3[var4] != null && this.equipmentDropChances[var4] <= 1.0F) { + var2 += 1 + this.rand.nextInt(3); + } + } + + return var2; + } else { + return this.experienceValue; + } + } + + /** + * Only use is to identify if class is an instance of player for experience + * dropping + */ + protected boolean isPlayer() { + return false; + } + + /** + * Spawns an explosion particle around the Entity's location + */ + public void spawnExplosionParticle() { + for (int var1 = 0; var1 < 20; ++var1) { + double var2 = this.rand.nextGaussian() * 0.02D; + double var4 = this.rand.nextGaussian() * 0.02D; + double var6 = this.rand.nextGaussian() * 0.02D; + double var8 = 10.0D; + this.worldObj.spawnParticle("explode", + this.posX + (double) (this.rand.nextFloat() * this.width * 2.0F) - (double) this.width + - var2 * var8, + this.posY + (double) (this.rand.nextFloat() * this.height) - var4 * var8, this.posZ + + (double) (this.rand.nextFloat() * this.width * 2.0F) - (double) this.width - var6 * var8, + var2, var4, var6); + } + } + + /** + * Handles updating while being ridden by an entity + */ + public void updateRidden() { + super.updateRidden(); + this.field_70768_au = this.field_70766_av; + this.field_70766_av = 0.0F; + this.fallDistance = 0.0F; + } + + /** + * Called to update the entity's position/logic. + */ + public void onUpdate() { + super.onUpdate(); + + if (!this.worldObj.isRemote) { + int var1; + + for (var1 = 0; var1 < 5; ++var1) { + ItemStack var2 = this.getEquipmentInSlot(var1); + + if (!ItemStack.areItemStacksEqual(var2, this.previousEquipment[var1])) { + ((WorldServer) this.worldObj).getEntityTracker().sendPacketToTrackedPlayers(this, + new Packet5PlayerInventory(this.entityId, var1, var2)); + this.previousEquipment[var1] = var2 == null ? null : var2.copy(); + } + } + + var1 = this.getArrowCountInEntity(); + + if (var1 > 0) { + if (this.arrowHitTimer <= 0) { + this.arrowHitTimer = 20 * (30 - var1); + } + + --this.arrowHitTimer; + + if (this.arrowHitTimer <= 0) { + this.setArrowCountInEntity(var1 - 1); + } + } + } + + this.onLivingUpdate(); + double var12 = this.posX - this.prevPosX; + double var3 = this.posZ - this.prevPosZ; + float var5 = (float) (var12 * var12 + var3 * var3); + float var6 = this.renderYawOffset; + float var7 = 0.0F; + this.field_70768_au = this.field_70766_av; + float var8 = 0.0F; + + if (var5 > 0.0025000002F) { + var8 = 1.0F; + var7 = (float) Math.sqrt((double) var5) * 3.0F; + var6 = (float) Math.atan2(var3, var12) * 180.0F / (float) Math.PI - 90.0F; + } + + if (this.swingProgress > 0.0F) { + var6 = this.rotationYaw; + } + + if (!this.onGround) { + var8 = 0.0F; + } + + this.field_70766_av += (var8 - this.field_70766_av) * 0.3F; + this.worldObj.theProfiler.startSection("headTurn"); + + if (this.isAIEnabled()) { + this.bodyHelper.func_75664_a(); + } else { + float var9 = MathHelper.wrapAngleTo180_float(var6 - this.renderYawOffset); + this.renderYawOffset += var9 * 0.3F; + float var10 = MathHelper.wrapAngleTo180_float(this.rotationYaw - this.renderYawOffset); + boolean var11 = var10 < -90.0F || var10 >= 90.0F; + + if (var10 < -75.0F) { + var10 = -75.0F; + } + + if (var10 >= 75.0F) { + var10 = 75.0F; + } + + this.renderYawOffset = this.rotationYaw - var10; + + if (var10 * var10 > 2500.0F) { + this.renderYawOffset += var10 * 0.2F; + } + + if (var11) { + var7 *= -1.0F; + } + } + + this.worldObj.theProfiler.endSection(); + this.worldObj.theProfiler.startSection("rangeChecks"); + + while (this.rotationYaw - this.prevRotationYaw < -180.0F) { + this.prevRotationYaw -= 360.0F; + } + + while (this.rotationYaw - this.prevRotationYaw >= 180.0F) { + this.prevRotationYaw += 360.0F; + } + + while (this.renderYawOffset - this.prevRenderYawOffset < -180.0F) { + this.prevRenderYawOffset -= 360.0F; + } + + while (this.renderYawOffset - this.prevRenderYawOffset >= 180.0F) { + this.prevRenderYawOffset += 360.0F; + } + + while (this.rotationPitch - this.prevRotationPitch < -180.0F) { + this.prevRotationPitch -= 360.0F; + } + + while (this.rotationPitch - this.prevRotationPitch >= 180.0F) { + this.prevRotationPitch += 360.0F; + } + + while (this.rotationYawHead - this.prevRotationYawHead < -180.0F) { + this.prevRotationYawHead -= 360.0F; + } + + while (this.rotationYawHead - this.prevRotationYawHead >= 180.0F) { + this.prevRotationYawHead += 360.0F; + } + + this.worldObj.theProfiler.endSection(); + this.field_70764_aw += var7; + } + + /** + * Heal living entity (param: amount of half-hearts) + */ + public void heal(int par1) { + if (this.health > 0) { + this.setEntityHealth(this.getHealth() + par1); + + if (this.health > this.getMaxHealth()) { + this.setEntityHealth(this.getMaxHealth()); + } + + this.hurtResistantTime = this.maxHurtResistantTime / 2; + } + } + + public abstract int getMaxHealth(); + + public int getHealth() { + return this.health; + } + + public void setEntityHealth(int par1) { + this.health = par1; + + if (par1 > this.getMaxHealth()) { + par1 = this.getMaxHealth(); + } + } + + /** + * Called when the entity is attacked. + */ + public boolean attackEntityFrom(DamageSource par1DamageSource, int par2) { + if (this.isEntityInvulnerable()) { + return false; + } else if (this.worldObj.isRemote) { + return false; + } else { + this.entityAge = 0; + + if (this.health <= 0) { + return false; + } else if (par1DamageSource.isFireDamage() && this.isPotionActive(Potion.fireResistance)) { + return false; + } else { + if ((par1DamageSource == DamageSource.anvil || par1DamageSource == DamageSource.fallingBlock) + && this.getEquipmentInSlot(4) != null) { + this.getEquipmentInSlot(4).damageItem(par2 * 4 + this.rand.nextInt(par2 * 2), this); + par2 = (int) ((float) par2 * 0.75F); + } + + this.limbYaw = 1.5F; + boolean var3 = true; + + if ((float) this.hurtResistantTime > (float) this.maxHurtResistantTime / 2.0F) { + if (par2 <= this.lastDamage) { + return false; + } + + this.damageEntity(par1DamageSource, par2 - this.lastDamage); + this.lastDamage = par2; + var3 = false; + } else { + this.lastDamage = par2; + this.prevHealth = this.health; + this.hurtResistantTime = this.maxHurtResistantTime; + this.damageEntity(par1DamageSource, par2); + this.hurtTime = this.maxHurtTime = 10; + } + + this.attackedAtYaw = 0.0F; + Entity var4 = par1DamageSource.getEntity(); + + if (var4 != null) { + if (var4 instanceof EntityLiving) { + this.setRevengeTarget((EntityLiving) var4); + } + + if (var4 instanceof EntityPlayer) { + this.recentlyHit = 100; + this.attackingPlayer = (EntityPlayer) var4; + } else if (var4 instanceof EntityWolf) { + EntityWolf var5 = (EntityWolf) var4; + + if (var5.isTamed()) { + this.recentlyHit = 100; + this.attackingPlayer = null; + } + } + } + + if (var3) { + this.worldObj.setEntityState(this, (byte) 2); + + if (par1DamageSource != DamageSource.drown) { + this.setBeenAttacked(); + } + + if (var4 != null) { + double var9 = var4.posX - this.posX; + double var7; + + for (var7 = var4.posZ - this.posZ; var9 * var9 + + var7 * var7 < 1.0E-4D; var7 = (Math.random() - Math.random()) * 0.01D) { + var9 = (Math.random() - Math.random()) * 0.01D; + } + + this.attackedAtYaw = (float) (Math.atan2(var7, var9) * 180.0D / Math.PI) - this.rotationYaw; + this.knockBack(var4, par2, var9, var7); + } else { + this.attackedAtYaw = (float) ((int) (Math.random() * 2.0D) * 180); + } + } + + if (this.health <= 0) { + if (var3) { + this.playSound(this.getDeathSound(), this.getSoundVolume(), this.getSoundPitch()); + } + + this.onDeath(par1DamageSource); + } else if (var3) { + this.playSound(this.getHurtSound(), this.getSoundVolume(), this.getSoundPitch()); + } + + return true; + } + } + } + + /** + * Gets the pitch of living sounds in living entities. + */ + protected float getSoundPitch() { + return this.isChild() ? (this.rand.nextFloat() - this.rand.nextFloat()) * 0.2F + 1.5F + : (this.rand.nextFloat() - this.rand.nextFloat()) * 0.2F + 1.0F; + } + + /** + * Returns the current armor value as determined by a call to + * InventoryPlayer.getTotalArmorValue + */ + public int getTotalArmorValue() { + int var1 = 0; + ItemStack[] var2 = this.getInventory(); + int var3 = var2.length; + + for (int var4 = 0; var4 < var3; ++var4) { + ItemStack var5 = var2[var4]; + + if (var5 != null && var5.getItem() instanceof ItemArmor) { + int var6 = ((ItemArmor) var5.getItem()).damageReduceAmount; + var1 += var6; + } + } + + return var1; + } + + protected void damageArmor(int par1) { + } + + /** + * Reduces damage, depending on armor + */ + protected int applyArmorCalculations(DamageSource par1DamageSource, int par2) { + if (!par1DamageSource.isUnblockable()) { + int var3 = 25 - this.getTotalArmorValue(); + int var4 = par2 * var3 + this.carryoverDamage; + this.damageArmor(par2); + par2 = var4 / 25; + this.carryoverDamage = var4 % 25; + } + + return par2; + } + + /** + * Reduces damage, depending on potions + */ + protected int applyPotionDamageCalculations(DamageSource par1DamageSource, int par2) { + int var3; + int var4; + int var5; + + if (this.isPotionActive(Potion.resistance)) { + var3 = (this.getActivePotionEffect(Potion.resistance).getAmplifier() + 1) * 5; + var4 = 25 - var3; + var5 = par2 * var4 + this.carryoverDamage; + par2 = var5 / 25; + this.carryoverDamage = var5 % 25; + } + + if (par2 <= 0) { + return 0; + } else { + var3 = EnchantmentHelper.getEnchantmentModifierDamage(this.getInventory(), par1DamageSource); + + if (var3 > 20) { + var3 = 20; + } + + if (var3 > 0 && var3 <= 20) { + var4 = 25 - var3; + var5 = par2 * var4 + this.carryoverDamage; + par2 = var5 / 25; + this.carryoverDamage = var5 % 25; + } + + return par2; + } + } + + /** + * Deals damage to the entity. If its a EntityPlayer then will take damage from + * the armor first and then health second with the reduced value. Args: + * damageAmount + */ + protected void damageEntity(DamageSource par1DamageSource, int par2) { + if (!this.isEntityInvulnerable()) { + par2 = this.applyArmorCalculations(par1DamageSource, par2); + par2 = this.applyPotionDamageCalculations(par1DamageSource, par2); + int var3 = this.getHealth(); + this.health -= par2; + this.field_94063_bt.func_94547_a(par1DamageSource, var3, par2); + } + } + + /** + * Returns the volume for the sounds this mob makes. + */ + protected float getSoundVolume() { + return 1.0F; + } + + /** + * Returns the sound this mob makes while it's alive. + */ + protected String getLivingSound() { + return null; + } + + /** + * Returns the sound this mob makes when it is hurt. + */ + protected String getHurtSound() { + return "damage.hit"; + } + + /** + * Returns the sound this mob makes on death. + */ + protected String getDeathSound() { + return "damage.hit"; + } + + /** + * knocks back this entity + */ + public void knockBack(Entity par1Entity, int par2, double par3, double par5) { + this.isAirBorne = true; + float var7 = MathHelper.sqrt_double(par3 * par3 + par5 * par5); + float var8 = 0.4F; + this.motionX /= 2.0D; + this.motionY /= 2.0D; + this.motionZ /= 2.0D; + this.motionX -= par3 / (double) var7 * (double) var8; + this.motionY += (double) var8; + this.motionZ -= par5 / (double) var7 * (double) var8; + + if (this.motionY > 0.4000000059604645D) { + this.motionY = 0.4000000059604645D; + } + } + + /** + * Called when the mob's health reaches 0. + */ + public void onDeath(DamageSource par1DamageSource) { + Entity var2 = par1DamageSource.getEntity(); + EntityLiving var3 = this.func_94060_bK(); + + if (this.scoreValue >= 0 && var3 != null) { + var3.addToPlayerScore(this, this.scoreValue); + } + + if (var2 != null) { + var2.onKillEntity(this); + } + + this.dead = true; + + if (!this.worldObj.isRemote) { + int var4 = 0; + + if (var2 instanceof EntityPlayer) { + var4 = EnchantmentHelper.getLootingModifier((EntityLiving) var2); + } + + if (!this.isChild() && this.worldObj.getGameRules().getGameRuleBooleanValue("doMobLoot")) { + this.dropFewItems(this.recentlyHit > 0, var4); + this.dropEquipment(this.recentlyHit > 0, var4); + + if (this.recentlyHit > 0) { + int var5 = this.rand.nextInt(200) - var4; + + if (var5 < 5) { + this.dropRareDrop(var5 <= 0 ? 1 : 0); + } + } + } + } + + this.worldObj.setEntityState(this, (byte) 3); + } + + protected void dropRareDrop(int par1) { + } + + /** + * Drop 0-2 items of this living's type + */ + protected void dropFewItems(boolean par1, int par2) { + int var3 = this.getDropItemId(); + + if (var3 > 0) { + int var4 = this.rand.nextInt(3); + + if (par2 > 0) { + var4 += this.rand.nextInt(par2 + 1); + } + + for (int var5 = 0; var5 < var4; ++var5) { + this.dropItem(var3, 1); + } + } + } + + /** + * Returns the item ID for the item the mob drops on death. + */ + protected int getDropItemId() { + return 0; + } + + /** + * Called when the mob is falling. Calculates and applies fall damage. + */ + protected void fall(float par1) { + super.fall(par1); + int var2 = MathHelper.ceiling_float_int(par1 - 3.0F); + + if (var2 > 0) { + if (var2 > 4) { + this.playSound("damage.fallbig", 1.0F, 1.0F); + } else { + this.playSound("damage.fallsmall", 1.0F, 1.0F); + } + + this.attackEntityFrom(DamageSource.fall, var2); + int var3 = this.worldObj.getBlockId(MathHelper.floor_double(this.posX), + MathHelper.floor_double(this.posY - 0.20000000298023224D - (double) this.yOffset), + MathHelper.floor_double(this.posZ)); + + if (var3 > 0) { + StepSound var4 = Block.blocksList[var3].stepSound; + this.playSound(var4.getStepSound(), var4.getVolume() * 0.5F, var4.getPitch() * 0.75F); + } + } + } + + /** + * Moves the entity based on the specified heading. Args: strafe, forward + */ + public void moveEntityWithHeading(float par1, float par2) { + double var9; + + if (this.isInWater() && (!(this instanceof EntityPlayer) || !((EntityPlayer) this).capabilities.isFlying)) { + var9 = this.posY; + this.moveFlying(par1, par2, this.isAIEnabled() ? 0.04F : 0.02F); + this.moveEntity(this.motionX, this.motionY, this.motionZ); + this.motionX *= 0.800000011920929D; + this.motionY *= 0.800000011920929D; + this.motionZ *= 0.800000011920929D; + this.motionY -= 0.02D; + + if (this.isCollidedHorizontally && this.isOffsetPositionInLiquid(this.motionX, + this.motionY + 0.6000000238418579D - this.posY + var9, this.motionZ)) { + this.motionY = 0.30000001192092896D; + } + } else if (this.handleLavaMovement() + && (!(this instanceof EntityPlayer) || !((EntityPlayer) this).capabilities.isFlying)) { + var9 = this.posY; + this.moveFlying(par1, par2, 0.02F); + this.moveEntity(this.motionX, this.motionY, this.motionZ); + this.motionX *= 0.5D; + this.motionY *= 0.5D; + this.motionZ *= 0.5D; + this.motionY -= 0.02D; + + if (this.isCollidedHorizontally && this.isOffsetPositionInLiquid(this.motionX, + this.motionY + 0.6000000238418579D - this.posY + var9, this.motionZ)) { + this.motionY = 0.30000001192092896D; + } + } else { + float var3 = 0.91F; + + if (this.onGround) { + var3 = 0.54600006F; + int var4 = this.worldObj.getBlockId(MathHelper.floor_double(this.posX), + MathHelper.floor_double(this.boundingBox.minY) - 1, MathHelper.floor_double(this.posZ)); + + if (var4 > 0) { + var3 = Block.blocksList[var4].slipperiness * 0.91F; + } + } + + float var8 = 0.16277136F / (var3 * var3 * var3); + float var5; + + if (this.onGround) { + if (this.isAIEnabled()) { + var5 = this.getAIMoveSpeed(); + } else { + var5 = this.landMovementFactor; + } + + var5 *= var8; + } else { + var5 = this.jumpMovementFactor; + } + + this.moveFlying(par1, par2, var5); + var3 = 0.91F; + + if (this.onGround) { + var3 = 0.54600006F; + int var6 = this.worldObj.getBlockId(MathHelper.floor_double(this.posX), + MathHelper.floor_double(this.boundingBox.minY) - 1, MathHelper.floor_double(this.posZ)); + + if (var6 > 0) { + var3 = Block.blocksList[var6].slipperiness * 0.91F; + } + } + + if (this.isOnLadder()) { + float var10 = 0.15F; + + if (this.motionX < (double) (-var10)) { + this.motionX = (double) (-var10); + } + + if (this.motionX > (double) var10) { + this.motionX = (double) var10; + } + + if (this.motionZ < (double) (-var10)) { + this.motionZ = (double) (-var10); + } + + if (this.motionZ > (double) var10) { + this.motionZ = (double) var10; + } + + this.fallDistance = 0.0F; + + if (this.motionY < -0.15D) { + this.motionY = -0.15D; + } + + boolean var7 = this.isSneaking() && this instanceof EntityPlayer; + + if (var7 && this.motionY < 0.0D) { + this.motionY = 0.0D; + } + } + + this.moveEntity(this.motionX, this.motionY, this.motionZ); + + if (this.isCollidedHorizontally && this.isOnLadder()) { + this.motionY = 0.2D; + } + + if (this.worldObj.isRemote && (!this.worldObj.blockExists((int) this.posX, 0, (int) this.posZ) + || !this.worldObj.getChunkFromBlockCoords((int) this.posX, (int) this.posZ).isChunkLoaded)) { + if (this.posY > 0.0D) { + this.motionY = -0.1D; + } else { + this.motionY = 0.0D; + } + } else { + this.motionY -= 0.08D; + } + + this.motionY *= 0.9800000190734863D; + this.motionX *= (double) var3; + this.motionZ *= (double) var3; + } + + this.prevLimbYaw = this.limbYaw; + var9 = this.posX - this.prevPosX; + double var11 = this.posZ - this.prevPosZ; + float var12 = MathHelper.sqrt_double(var9 * var9 + var11 * var11) * 4.0F; + + if (var12 > 1.0F) { + var12 = 1.0F; + } + + this.limbYaw += (var12 - this.limbYaw) * 0.4F; + this.limbSwing += this.limbYaw; + } + + /** + * returns true if this entity is by a ladder, false otherwise + */ + public boolean isOnLadder() { + int var1 = MathHelper.floor_double(this.posX); + int var2 = MathHelper.floor_double(this.boundingBox.minY); + int var3 = MathHelper.floor_double(this.posZ); + int var4 = this.worldObj.getBlockId(var1, var2, var3); + return var4 == Block.ladder.blockID || var4 == Block.vine.blockID; + } + + /** + * (abstract) Protected helper method to write subclass entity data to NBT. + */ + public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) { + if (this.health < -32768) { + this.health = -32768; + } + + par1NBTTagCompound.setShort("Health", (short) this.health); + par1NBTTagCompound.setShort("HurtTime", (short) this.hurtTime); + par1NBTTagCompound.setShort("DeathTime", (short) this.deathTime); + par1NBTTagCompound.setShort("AttackTime", (short) this.attackTime); + par1NBTTagCompound.setBoolean("CanPickUpLoot", this.canPickUpLoot()); + par1NBTTagCompound.setBoolean("PersistenceRequired", this.persistenceRequired); + NBTTagList var2 = new NBTTagList(); + + for (int var3 = 0; var3 < this.equipment.length; ++var3) { + NBTTagCompound var4 = new NBTTagCompound(); + + if (this.equipment[var3] != null) { + this.equipment[var3].writeToNBT(var4); + } + + var2.appendTag(var4); + } + + par1NBTTagCompound.setTag("Equipment", var2); + NBTTagList var6; + + if (!this.activePotionsMap.isEmpty()) { + var6 = new NBTTagList(); + Iterator var7 = this.activePotionsMap.values().iterator(); + + while (var7.hasNext()) { + PotionEffect var5 = (PotionEffect) var7.next(); + var6.appendTag(var5.writeCustomPotionEffectToNBT(new NBTTagCompound())); + } + + par1NBTTagCompound.setTag("ActiveEffects", var6); + } + + var6 = new NBTTagList(); + + for (int var8 = 0; var8 < this.equipmentDropChances.length; ++var8) { + var6.appendTag(new NBTTagFloat(var8 + "", this.equipmentDropChances[var8])); + } + + par1NBTTagCompound.setTag("DropChances", var6); + par1NBTTagCompound.setString("CustomName", this.func_94057_bL()); + par1NBTTagCompound.setBoolean("CustomNameVisible", this.func_94062_bN()); + } + + /** + * (abstract) Protected helper method to read subclass entity data from NBT. + */ + public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) { + this.health = par1NBTTagCompound.getShort("Health"); + + if (!par1NBTTagCompound.hasKey("Health")) { + this.health = this.getMaxHealth(); + } + + this.hurtTime = par1NBTTagCompound.getShort("HurtTime"); + this.deathTime = par1NBTTagCompound.getShort("DeathTime"); + this.attackTime = par1NBTTagCompound.getShort("AttackTime"); + this.setCanPickUpLoot(par1NBTTagCompound.getBoolean("CanPickUpLoot")); + this.persistenceRequired = par1NBTTagCompound.getBoolean("PersistenceRequired"); + + if (par1NBTTagCompound.hasKey("CustomName") && par1NBTTagCompound.getString("CustomName").length() > 0) { + this.func_94058_c(par1NBTTagCompound.getString("CustomName")); + } + + this.func_94061_f(par1NBTTagCompound.getBoolean("CustomNameVisible")); + NBTTagList var2; + int var3; + + if (par1NBTTagCompound.hasKey("Equipment")) { + var2 = par1NBTTagCompound.getTagList("Equipment"); + + for (var3 = 0; var3 < this.equipment.length; ++var3) { + this.equipment[var3] = ItemStack.loadItemStackFromNBT((NBTTagCompound) var2.tagAt(var3)); + } + } + + if (par1NBTTagCompound.hasKey("ActiveEffects")) { + var2 = par1NBTTagCompound.getTagList("ActiveEffects"); + + for (var3 = 0; var3 < var2.tagCount(); ++var3) { + NBTTagCompound var4 = (NBTTagCompound) var2.tagAt(var3); + PotionEffect var5 = PotionEffect.readCustomPotionEffectFromNBT(var4); + this.activePotionsMap.put(Integer.valueOf(var5.getPotionID()), var5); + } + } + + if (par1NBTTagCompound.hasKey("DropChances")) { + var2 = par1NBTTagCompound.getTagList("DropChances"); + + for (var3 = 0; var3 < var2.tagCount(); ++var3) { + this.equipmentDropChances[var3] = ((NBTTagFloat) var2.tagAt(var3)).data; + } + } + } + + /** + * Checks whether target entity is alive. + */ + public boolean isEntityAlive() { + return !this.isDead && this.health > 0; + } + + public boolean canBreatheUnderwater() { + return false; + } + + public void setMoveForward(float par1) { + this.moveForward = par1; + } + + public void setJumping(boolean par1) { + this.isJumping = par1; + } + + /** + * Called frequently so the entity can update its state every tick as required. + * For example, zombies and skeletons use this to react to sunlight and start to + * burn. + */ + public void onLivingUpdate() { + if (this.jumpTicks > 0) { + --this.jumpTicks; + } + + if (this.newPosRotationIncrements > 0) { + double var1 = this.posX + (this.newPosX - this.posX) / (double) this.newPosRotationIncrements; + double var3 = this.posY + (this.newPosY - this.posY) / (double) this.newPosRotationIncrements; + double var5 = this.posZ + (this.newPosZ - this.posZ) / (double) this.newPosRotationIncrements; + double var7 = MathHelper.wrapAngleTo180_double(this.newRotationYaw - (double) this.rotationYaw); + this.rotationYaw = (float) ((double) this.rotationYaw + var7 / (double) this.newPosRotationIncrements); + this.rotationPitch = (float) ((double) this.rotationPitch + + (this.newRotationPitch - (double) this.rotationPitch) / (double) this.newPosRotationIncrements); + --this.newPosRotationIncrements; + this.setPosition(var1, var3, var5); + this.setRotation(this.rotationYaw, this.rotationPitch); + } else if (!this.isClientWorld()) { + this.motionX *= 0.98D; + this.motionY *= 0.98D; + this.motionZ *= 0.98D; + } + + if (Math.abs(this.motionX) < 0.005D) { + this.motionX = 0.0D; + } + + if (Math.abs(this.motionY) < 0.005D) { + this.motionY = 0.0D; + } + + if (Math.abs(this.motionZ) < 0.005D) { + this.motionZ = 0.0D; + } + + this.worldObj.theProfiler.startSection("ai"); + + if (this.isMovementBlocked()) { + this.isJumping = false; + this.moveStrafing = 0.0F; + this.moveForward = 0.0F; + this.randomYawVelocity = 0.0F; + } else if (this.isClientWorld()) { + if (this.isAIEnabled()) { + this.worldObj.theProfiler.startSection("newAi"); + this.updateAITasks(); + this.worldObj.theProfiler.endSection(); + } else { + this.worldObj.theProfiler.startSection("oldAi"); + this.updateEntityActionState(); + this.worldObj.theProfiler.endSection(); + this.rotationYawHead = this.rotationYaw; + } + } + + this.worldObj.theProfiler.endSection(); + this.worldObj.theProfiler.startSection("jump"); + + if (this.isJumping) { + if (!this.isInWater() && !this.handleLavaMovement()) { + if (this.onGround && this.jumpTicks == 0) { + this.jump(); + this.jumpTicks = 10; + } + } else { + this.motionY += 0.03999999910593033D; + } + } else { + this.jumpTicks = 0; + } + + this.worldObj.theProfiler.endSection(); + this.worldObj.theProfiler.startSection("travel"); + this.moveStrafing *= 0.98F; + this.moveForward *= 0.98F; + this.randomYawVelocity *= 0.9F; + float var11 = this.landMovementFactor; + this.landMovementFactor *= this.getSpeedModifier(); + this.moveEntityWithHeading(this.moveStrafing, this.moveForward); + this.landMovementFactor = var11; + this.worldObj.theProfiler.endSection(); + this.worldObj.theProfiler.startSection("push"); + + if (!this.worldObj.isRemote) { + this.func_85033_bc(); + } + + this.worldObj.theProfiler.endSection(); + this.worldObj.theProfiler.startSection("looting"); + + if (!this.worldObj.isRemote && this.canPickUpLoot() && !this.dead + && this.worldObj.getGameRules().getGameRuleBooleanValue("mobGriefing")) { + List var2 = this.worldObj.getEntitiesWithinAABB(EntityItem.class, + this.boundingBox.expand(1.0D, 0.0D, 1.0D)); + Iterator var12 = var2.iterator(); + + while (var12.hasNext()) { + EntityItem var4 = (EntityItem) var12.next(); + + if (!var4.isDead && var4.getEntityItem() != null) { + ItemStack var13 = var4.getEntityItem(); + int var6 = getArmorPosition(var13); + + if (var6 > -1) { + boolean var14 = true; + ItemStack var8 = this.getEquipmentInSlot(var6); + + if (var8 != null) { + if (var6 == 0) { + if (var13.getItem() instanceof ItemSword && !(var8.getItem() instanceof ItemSword)) { + var14 = true; + } else if (var13.getItem() instanceof ItemSword + && var8.getItem() instanceof ItemSword) { + ItemSword var9 = (ItemSword) var13.getItem(); + ItemSword var10 = (ItemSword) var8.getItem(); + + if (var9.func_82803_g() == var10.func_82803_g()) { + var14 = var13.getItemDamage() > var8.getItemDamage() + || var13.hasTagCompound() && !var8.hasTagCompound(); + } else { + var14 = var9.func_82803_g() > var10.func_82803_g(); + } + } else { + var14 = false; + } + } else if (var13.getItem() instanceof ItemArmor && !(var8.getItem() instanceof ItemArmor)) { + var14 = true; + } else if (var13.getItem() instanceof ItemArmor && var8.getItem() instanceof ItemArmor) { + ItemArmor var15 = (ItemArmor) var13.getItem(); + ItemArmor var16 = (ItemArmor) var8.getItem(); + + if (var15.damageReduceAmount == var16.damageReduceAmount) { + var14 = var13.getItemDamage() > var8.getItemDamage() + || var13.hasTagCompound() && !var8.hasTagCompound(); + } else { + var14 = var15.damageReduceAmount > var16.damageReduceAmount; + } + } else { + var14 = false; + } + } + + if (var14) { + if (var8 != null && this.rand.nextFloat() - 0.1F < this.equipmentDropChances[var6]) { + this.entityDropItem(var8, 0.0F); + } + + this.setCurrentItemOrArmor(var6, var13); + this.equipmentDropChances[var6] = 2.0F; + this.persistenceRequired = true; + this.onItemPickup(var4, 1); + var4.setDead(); + } + } + } + } + } + + this.worldObj.theProfiler.endSection(); + } + + protected void func_85033_bc() { + List var1 = this.worldObj.getEntitiesWithinAABBExcludingEntity(this, + this.boundingBox.expand(0.20000000298023224D, 0.0D, 0.20000000298023224D)); + + if (var1 != null && !var1.isEmpty()) { + for (int var2 = 0; var2 < var1.size(); ++var2) { + Entity var3 = (Entity) var1.get(var2); + + if (var3.canBePushed()) { + this.collideWithEntity(var3); + } + } + } + } + + protected void collideWithEntity(Entity par1Entity) { + par1Entity.applyEntityCollision(this); + } + + /** + * Returns true if the newer Entity AI code should be run + */ + protected boolean isAIEnabled() { + return false; + } + + /** + * Returns whether the entity is in a local (client) world + */ + protected boolean isClientWorld() { + return !this.worldObj.isRemote; + } + + /** + * Dead and sleeping entities cannot move + */ + protected boolean isMovementBlocked() { + return this.health <= 0; + } + + public boolean isBlocking() { + return false; + } + + /** + * Causes this entity to do an upwards motion (jumping). + */ + protected void jump() { + this.motionY = 0.41999998688697815D; + + if (this.isPotionActive(Potion.jump)) { + this.motionY += (double) ((float) (this.getActivePotionEffect(Potion.jump).getAmplifier() + 1) * 0.1F); + } + + if (this.isSprinting()) { + float var1 = this.rotationYaw * 0.017453292F; + this.motionX -= (double) (MathHelper.sin(var1) * 0.2F); + this.motionZ += (double) (MathHelper.cos(var1) * 0.2F); + } + + this.isAirBorne = true; + } + + /** + * Determines if an entity can be despawned, used on idle far away entities + */ + protected boolean canDespawn() { + return true; + } + + /** + * Makes the entity despawn if requirements are reached + */ + protected void despawnEntity() { + if (!this.persistenceRequired) { + EntityPlayer var1 = this.worldObj.getClosestPlayerToEntity(this, -1.0D); + + if (var1 != null) { + double var2 = var1.posX - this.posX; + double var4 = var1.posY - this.posY; + double var6 = var1.posZ - this.posZ; + double var8 = var2 * var2 + var4 * var4 + var6 * var6; + + if (this.canDespawn() && var8 > 16384.0D) { + this.setDead(); + } + + if (this.entityAge > 600 && this.rand.nextInt(800) == 0 && var8 > 1024.0D && this.canDespawn()) { + this.setDead(); + } else if (var8 < 1024.0D) { + this.entityAge = 0; + } + } + } + } + + protected void updateAITasks() { + ++this.entityAge; + this.worldObj.theProfiler.startSection("checkDespawn"); + this.despawnEntity(); + this.worldObj.theProfiler.endSection(); + this.worldObj.theProfiler.startSection("sensing"); + this.senses.clearSensingCache(); + this.worldObj.theProfiler.endSection(); + this.worldObj.theProfiler.startSection("targetSelector"); + this.targetTasks.onUpdateTasks(); + this.worldObj.theProfiler.endSection(); + this.worldObj.theProfiler.startSection("goalSelector"); + this.tasks.onUpdateTasks(); + this.worldObj.theProfiler.endSection(); + this.worldObj.theProfiler.startSection("navigation"); + this.navigator.onUpdateNavigation(); + this.worldObj.theProfiler.endSection(); + this.worldObj.theProfiler.startSection("mob tick"); + this.updateAITick(); + this.worldObj.theProfiler.endSection(); + this.worldObj.theProfiler.startSection("controls"); + this.worldObj.theProfiler.startSection("move"); + this.moveHelper.onUpdateMoveHelper(); + this.worldObj.theProfiler.endStartSection("look"); + this.lookHelper.onUpdateLook(); + this.worldObj.theProfiler.endStartSection("jump"); + this.jumpHelper.doJump(); + this.worldObj.theProfiler.endSection(); + this.worldObj.theProfiler.endSection(); + } + + /** + * main AI tick function, replaces updateEntityActionState + */ + protected void updateAITick() { + } + + protected void updateEntityActionState() { + ++this.entityAge; + this.despawnEntity(); + this.moveStrafing = 0.0F; + this.moveForward = 0.0F; + float var1 = 8.0F; + + if (this.rand.nextFloat() < 0.02F) { + EntityPlayer var2 = this.worldObj.getClosestPlayerToEntity(this, (double) var1); + + if (var2 != null) { + this.currentTarget = var2; + this.numTicksToChaseTarget = 10 + this.rand.nextInt(20); + } else { + this.randomYawVelocity = (this.rand.nextFloat() - 0.5F) * 20.0F; + } + } + + if (this.currentTarget != null) { + this.faceEntity(this.currentTarget, 10.0F, (float) this.getVerticalFaceSpeed()); + + if (this.numTicksToChaseTarget-- <= 0 || this.currentTarget.isDead + || this.currentTarget.getDistanceSqToEntity(this) > (double) (var1 * var1)) { + this.currentTarget = null; + } + } else { + if (this.rand.nextFloat() < 0.05F) { + this.randomYawVelocity = (this.rand.nextFloat() - 0.5F) * 20.0F; + } + + this.rotationYaw += this.randomYawVelocity; + this.rotationPitch = this.defaultPitch; + } + + boolean var4 = this.isInWater(); + boolean var3 = this.handleLavaMovement(); + + if (var4 || var3) { + this.isJumping = this.rand.nextFloat() < 0.8F; + } + } + + /** + * Updates the arm swing progress counters and animation progress + */ + protected void updateArmSwingProgress() { + int var1 = this.getArmSwingAnimationEnd(); + + if (this.isSwingInProgress) { + ++this.swingProgressInt; + + if (this.swingProgressInt >= var1) { + this.swingProgressInt = 0; + this.isSwingInProgress = false; + } + } else { + this.swingProgressInt = 0; + } + + this.swingProgress = (float) this.swingProgressInt / (float) var1; + } + + /** + * The speed it takes to move the entityliving's rotationPitch through the + * faceEntity method. This is only currently use in wolves. + */ + public int getVerticalFaceSpeed() { + return 40; + } + + /** + * Changes pitch and yaw so that the entity calling the function is facing the + * entity provided as an argument. + */ + public void faceEntity(Entity par1Entity, float par2, float par3) { + double var4 = par1Entity.posX - this.posX; + double var8 = par1Entity.posZ - this.posZ; + double var6; + + if (par1Entity instanceof EntityLiving) { + EntityLiving var10 = (EntityLiving) par1Entity; + var6 = var10.posY + (double) var10.getEyeHeight() - (this.posY + (double) this.getEyeHeight()); + } else { + var6 = (par1Entity.boundingBox.minY + par1Entity.boundingBox.maxY) / 2.0D + - (this.posY + (double) this.getEyeHeight()); + } + + double var14 = (double) MathHelper.sqrt_double(var4 * var4 + var8 * var8); + float var12 = (float) (Math.atan2(var8, var4) * 180.0D / Math.PI) - 90.0F; + float var13 = (float) (-(Math.atan2(var6, var14) * 180.0D / Math.PI)); + this.rotationPitch = this.updateRotation(this.rotationPitch, var13, par3); + this.rotationYaw = this.updateRotation(this.rotationYaw, var12, par2); + } + + /** + * Arguments: current rotation, intended rotation, max increment. + */ + private float updateRotation(float par1, float par2, float par3) { + float var4 = MathHelper.wrapAngleTo180_float(par2 - par1); + + if (var4 > par3) { + var4 = par3; + } + + if (var4 < -par3) { + var4 = -par3; + } + + return par1 + var4; + } + + /** + * Checks if the entity's current position is a valid location to spawn this + * entity. + */ + public boolean getCanSpawnHere() { + return this.worldObj.checkNoEntityCollision(this.boundingBox) + && this.worldObj.getCollidingBoundingBoxes(this, this.boundingBox).isEmpty() + && !this.worldObj.isAnyLiquid(this.boundingBox); + } + + /** + * sets the dead flag. Used when you fall off the bottom of the world. + */ + protected void kill() { + this.attackEntityFrom(DamageSource.outOfWorld, 4); + } + + /** + * returns a (normalized) vector of where this entity is looking + */ + public Vec3 getLookVec() { + return this.getLook(1.0F); + } + + /** + * interpolated look vector + */ + public Vec3 getLook(float par1) { + float var2; + float var3; + float var4; + float var5; + + if (par1 == 1.0F) { + var2 = MathHelper.cos(-this.rotationYaw * 0.017453292F - (float) Math.PI); + var3 = MathHelper.sin(-this.rotationYaw * 0.017453292F - (float) Math.PI); + var4 = -MathHelper.cos(-this.rotationPitch * 0.017453292F); + var5 = MathHelper.sin(-this.rotationPitch * 0.017453292F); + return this.worldObj.getWorldVec3Pool().getVecFromPool((double) (var3 * var4), (double) var5, + (double) (var2 * var4)); + } else { + var2 = this.prevRotationPitch + (this.rotationPitch - this.prevRotationPitch) * par1; + var3 = this.prevRotationYaw + (this.rotationYaw - this.prevRotationYaw) * par1; + var4 = MathHelper.cos(-var3 * 0.017453292F - (float) Math.PI); + var5 = MathHelper.sin(-var3 * 0.017453292F - (float) Math.PI); + float var6 = -MathHelper.cos(-var2 * 0.017453292F); + float var7 = MathHelper.sin(-var2 * 0.017453292F); + return this.worldObj.getWorldVec3Pool().getVecFromPool((double) (var5 * var6), (double) var7, + (double) (var4 * var6)); + } + } + + /** + * Will return how many at most can spawn in a chunk at once. + */ + public int getMaxSpawnedInChunk() { + return 4; + } + + /** + * Returns whether player is sleeping or not + */ + public boolean isPlayerSleeping() { + return false; + } + + protected void updatePotionEffects() { + Iterator var1 = this.activePotionsMap.keySet().iterator(); + + while (var1.hasNext()) { + Integer var2 = (Integer) var1.next(); + PotionEffect var3 = (PotionEffect) this.activePotionsMap.get(var2); + + try { + if (!var3.onUpdate(this)) { + if (!this.worldObj.isRemote) { + var1.remove(); + this.onFinishedPotionEffect(var3); + } + } else if (var3.getDuration() % 600 == 0) { + this.onChangedPotionEffect(var3); + } + } catch (Throwable var11) { + CrashReport var5 = CrashReport.makeCrashReport(var11, "Ticking mob effect instance"); + CrashReportCategory var6 = var5.makeCategory("Mob effect being ticked"); + var6.addCrashSectionCallable("Effect Name", new CallableEffectName(this, var3)); + var6.addCrashSectionCallable("Effect ID", new CallableEffectID(this, var3)); + var6.addCrashSectionCallable("Effect Duration", new CallableEffectDuration(this, var3)); + var6.addCrashSectionCallable("Effect Amplifier", new CallableEffectAmplifier(this, var3)); + var6.addCrashSectionCallable("Effect is Splash", new CallableEffectIsSplash(this, var3)); + var6.addCrashSectionCallable("Effect is Ambient", new CallableEffectIsAmbient(this, var3)); + throw new ReportedException(var5); + } + } + + int var12; + + if (this.potionsNeedUpdate) { + if (!this.worldObj.isRemote) { + if (this.activePotionsMap.isEmpty()) { + this.dataWatcher.updateObject(9, Byte.valueOf((byte) 0)); + this.dataWatcher.updateObject(8, Integer.valueOf(0)); + this.setInvisible(false); + } else { + var12 = PotionHelper.calcPotionLiquidColor(this.activePotionsMap.values()); + this.dataWatcher.updateObject(9, + Byte.valueOf((byte) (PotionHelper.func_82817_b(this.activePotionsMap.values()) ? 1 : 0))); + this.dataWatcher.updateObject(8, Integer.valueOf(var12)); + this.setInvisible(this.isPotionActive(Potion.invisibility.id)); + } + } + + this.potionsNeedUpdate = false; + } + + var12 = this.dataWatcher.getWatchableObjectInt(8); + boolean var13 = this.dataWatcher.getWatchableObjectByte(9) > 0; + + if (var12 > 0) { + boolean var4 = false; + + if (!this.isInvisible()) { + var4 = this.rand.nextBoolean(); + } else { + var4 = this.rand.nextInt(15) == 0; + } + + if (var13) { + var4 &= this.rand.nextInt(5) == 0; + } + + if (var4 && var12 > 0) { + double var14 = (double) (var12 >> 16 & 255) / 255.0D; + double var7 = (double) (var12 >> 8 & 255) / 255.0D; + double var9 = (double) (var12 >> 0 & 255) / 255.0D; + this.worldObj.spawnParticle(var13 ? "mobSpellAmbient" : "mobSpell", + this.posX + (this.rand.nextDouble() - 0.5D) * (double) this.width, + this.posY + this.rand.nextDouble() * (double) this.height - (double) this.yOffset, + this.posZ + (this.rand.nextDouble() - 0.5D) * (double) this.width, var14, var7, var9); + } + } + } + + public void clearActivePotions() { + Iterator var1 = this.activePotionsMap.keySet().iterator(); + + while (var1.hasNext()) { + Integer var2 = (Integer) var1.next(); + PotionEffect var3 = (PotionEffect) this.activePotionsMap.get(var2); + + if (!this.worldObj.isRemote) { + var1.remove(); + this.onFinishedPotionEffect(var3); + } + } + } + + public Collection getActivePotionEffects() { + return this.activePotionsMap.values(); + } + + public boolean isPotionActive(int par1) { + return this.activePotionsMap.containsKey(Integer.valueOf(par1)); + } + + public boolean isPotionActive(Potion par1Potion) { + return this.activePotionsMap.containsKey(Integer.valueOf(par1Potion.id)); + } + + /** + * returns the PotionEffect for the supplied Potion if it is active, null + * otherwise. + */ + public PotionEffect getActivePotionEffect(Potion par1Potion) { + return (PotionEffect) this.activePotionsMap.get(Integer.valueOf(par1Potion.id)); + } + + /** + * adds a PotionEffect to the entity + */ + public void addPotionEffect(PotionEffect par1PotionEffect) { + if (this.isPotionApplicable(par1PotionEffect)) { + if (this.activePotionsMap.containsKey(Integer.valueOf(par1PotionEffect.getPotionID()))) { + ((PotionEffect) this.activePotionsMap.get(Integer.valueOf(par1PotionEffect.getPotionID()))) + .combine(par1PotionEffect); + this.onChangedPotionEffect( + (PotionEffect) this.activePotionsMap.get(Integer.valueOf(par1PotionEffect.getPotionID()))); + } else { + this.activePotionsMap.put(Integer.valueOf(par1PotionEffect.getPotionID()), par1PotionEffect); + this.onNewPotionEffect(par1PotionEffect); + } + } + } + + public boolean isPotionApplicable(PotionEffect par1PotionEffect) { + if (this.getCreatureAttribute() == EnumCreatureAttribute.UNDEAD) { + int var2 = par1PotionEffect.getPotionID(); + + if (var2 == Potion.regeneration.id || var2 == Potion.poison.id) { + return false; + } + } + + return true; + } + + /** + * Returns true if this entity is undead. + */ + public boolean isEntityUndead() { + return this.getCreatureAttribute() == EnumCreatureAttribute.UNDEAD; + } + + /** + * Remove the specified potion effect from this entity. + */ + public void removePotionEffect(int par1) { + PotionEffect var2 = (PotionEffect) this.activePotionsMap.remove(Integer.valueOf(par1)); + + if (var2 != null) { + this.onFinishedPotionEffect(var2); + } + } + + protected void onNewPotionEffect(PotionEffect par1PotionEffect) { + this.potionsNeedUpdate = true; + } + + protected void onChangedPotionEffect(PotionEffect par1PotionEffect) { + this.potionsNeedUpdate = true; + } + + protected void onFinishedPotionEffect(PotionEffect par1PotionEffect) { + this.potionsNeedUpdate = true; + } + + /** + * This method returns a value to be applied directly to entity speed, this + * factor is less than 1 when a slowdown potion effect is applied, more than 1 + * when a haste potion effect is applied and 2 for fleeing entities. + */ + public float getSpeedModifier() { + float var1 = 1.0F; + + if (this.isPotionActive(Potion.moveSpeed)) { + var1 *= 1.0F + 0.2F * (float) (this.getActivePotionEffect(Potion.moveSpeed).getAmplifier() + 1); + } + + if (this.isPotionActive(Potion.moveSlowdown)) { + var1 *= 1.0F - 0.15F * (float) (this.getActivePotionEffect(Potion.moveSlowdown).getAmplifier() + 1); + } + + if (var1 < 0.0F) { + var1 = 0.0F; + } + + return var1; + } + + /** + * Sets the position of the entity and updates the 'last' variables + */ + public void setPositionAndUpdate(double par1, double par3, double par5) { + this.setLocationAndAngles(par1, par3, par5, this.rotationYaw, this.rotationPitch); + } + + /** + * If Animal, checks if the age timer is negative + */ + public boolean isChild() { + return false; + } + + /** + * Get this Entity's EnumCreatureAttribute + */ + public EnumCreatureAttribute getCreatureAttribute() { + return EnumCreatureAttribute.UNDEFINED; + } + + /** + * Renders broken item particles using the given ItemStack + */ + public void renderBrokenItemStack(ItemStack par1ItemStack) { + this.playSound("random.break", 0.8F, 0.8F + this.worldObj.rand.nextFloat() * 0.4F); + + for (int var2 = 0; var2 < 5; ++var2) { + Vec3 var3 = this.worldObj.getWorldVec3Pool().getVecFromPool(((double) this.rand.nextFloat() - 0.5D) * 0.1D, + Math.random() * 0.1D + 0.1D, 0.0D); + var3.rotateAroundX(-this.rotationPitch * (float) Math.PI / 180.0F); + var3.rotateAroundY(-this.rotationYaw * (float) Math.PI / 180.0F); + Vec3 var4 = this.worldObj.getWorldVec3Pool().getVecFromPool(((double) this.rand.nextFloat() - 0.5D) * 0.3D, + (double) (-this.rand.nextFloat()) * 0.6D - 0.3D, 0.6D); + var4.rotateAroundX(-this.rotationPitch * (float) Math.PI / 180.0F); + var4.rotateAroundY(-this.rotationYaw * (float) Math.PI / 180.0F); + var4 = var4.addVector(this.posX, this.posY + (double) this.getEyeHeight(), this.posZ); + this.worldObj.spawnParticle("iconcrack_" + par1ItemStack.getItem().itemID, var4.xCoord, var4.yCoord, + var4.zCoord, var3.xCoord, var3.yCoord + 0.05D, var3.zCoord); + } + } + + public int func_82143_as() { + if (this.getAttackTarget() == null) { + return 3; + } else { + int var1 = (int) ((float) this.health - (float) this.getMaxHealth() * 0.33F); + var1 -= (3 - this.worldObj.difficultySetting) * 4; + + if (var1 < 0) { + var1 = 0; + } + + return var1 + 3; + } + } + + /** + * Returns the item that this EntityLiving is holding, if any. + */ + public ItemStack getHeldItem() { + return this.equipment[0]; + } + + /** + * 0: Tool in Hand; 1-4: Armor + */ + public ItemStack getEquipmentInSlot(int par1) { + return this.equipment[par1]; + } + + public ItemStack getCurrentArmor(int par1) { + return this.equipment[par1 + 1]; + } + + /** + * Sets the held item, or an armor slot. Slot 0 is held item. Slot 1-4 is armor. + * Params: Item, slot + */ + public void setCurrentItemOrArmor(int par1, ItemStack par2ItemStack) { + this.equipment[par1] = par2ItemStack; + } + + /** + * returns the inventory of this entity (only used in EntityPlayerMP it seems) + */ + public ItemStack[] getInventory() { + return this.equipment; + } + + /** + * Drop the equipment for this entity. + */ + protected void dropEquipment(boolean par1, int par2) { + for (int var3 = 0; var3 < this.getInventory().length; ++var3) { + ItemStack var4 = this.getEquipmentInSlot(var3); + boolean var5 = this.equipmentDropChances[var3] > 1.0F; + + if (var4 != null && (par1 || var5) + && this.rand.nextFloat() - (float) par2 * 0.01F < this.equipmentDropChances[var3]) { + if (!var5 && var4.isItemStackDamageable()) { + int var6 = Math.max(var4.getMaxDamage() - 25, 1); + int var7 = var4.getMaxDamage() - this.rand.nextInt(this.rand.nextInt(var6) + 1); + + if (var7 > var6) { + var7 = var6; + } + + if (var7 < 1) { + var7 = 1; + } + + var4.setItemDamage(var7); + } + + this.entityDropItem(var4, 0.0F); + } + } + } + + /** + * Makes entity wear random armor based on difficulty + */ + protected void addRandomArmor() { + if (this.rand.nextFloat() < armorProbability[this.worldObj.difficultySetting]) { + int var1 = this.rand.nextInt(2); + float var2 = this.worldObj.difficultySetting == 3 ? 0.1F : 0.25F; + + if (this.rand.nextFloat() < 0.095F) { + ++var1; + } + + if (this.rand.nextFloat() < 0.095F) { + ++var1; + } + + if (this.rand.nextFloat() < 0.095F) { + ++var1; + } + + for (int var3 = 3; var3 >= 0; --var3) { + ItemStack var4 = this.getCurrentArmor(var3); + + if (var3 < 3 && this.rand.nextFloat() < var2) { + break; + } + + if (var4 == null) { + Item var5 = getArmorItemForSlot(var3 + 1, var1); + + if (var5 != null) { + this.setCurrentItemOrArmor(var3 + 1, new ItemStack(var5)); + } + } + } + } + } + + /** + * Called whenever an item is picked up from walking over it. Args: + * pickedUpEntity, stackSize + */ + public void onItemPickup(Entity par1Entity, int par2) { + if (!par1Entity.isDead && !this.worldObj.isRemote) { + EntityTracker var3 = ((WorldServer) this.worldObj).getEntityTracker(); + + if (par1Entity instanceof EntityItem) { + var3.sendPacketToTrackedPlayers(par1Entity, new Packet22Collect(par1Entity.entityId, this.entityId)); + } + + if (par1Entity instanceof EntityArrow) { + var3.sendPacketToTrackedPlayers(par1Entity, new Packet22Collect(par1Entity.entityId, this.entityId)); + } + + if (par1Entity instanceof EntityXPOrb) { + var3.sendPacketToTrackedPlayers(par1Entity, new Packet22Collect(par1Entity.entityId, this.entityId)); + } + } + } + + public static int getArmorPosition(ItemStack par0ItemStack) { + if (par0ItemStack.itemID != Block.pumpkin.blockID && par0ItemStack.itemID != Item.skull.itemID) { + if (par0ItemStack.getItem() instanceof ItemArmor) { + switch (((ItemArmor) par0ItemStack.getItem()).armorType) { + case 0: + return 4; + + case 1: + return 3; + + case 2: + return 2; + + case 3: + return 1; + } + } + + return 0; + } else { + return 4; + } + } + + /** + * Params: Armor slot, Item tier + */ + public static Item getArmorItemForSlot(int par0, int par1) { + switch (par0) { + case 4: + if (par1 == 0) { + return Item.helmetLeather; + } else if (par1 == 1) { + return Item.helmetGold; + } else if (par1 == 2) { + return Item.helmetChain; + } else if (par1 == 3) { + return Item.helmetIron; + } else if (par1 == 4) { + return Item.helmetDiamond; + } + + case 3: + if (par1 == 0) { + return Item.plateLeather; + } else if (par1 == 1) { + return Item.plateGold; + } else if (par1 == 2) { + return Item.plateChain; + } else if (par1 == 3) { + return Item.plateIron; + } else if (par1 == 4) { + return Item.plateDiamond; + } + + case 2: + if (par1 == 0) { + return Item.legsLeather; + } else if (par1 == 1) { + return Item.legsGold; + } else if (par1 == 2) { + return Item.legsChain; + } else if (par1 == 3) { + return Item.legsIron; + } else if (par1 == 4) { + return Item.legsDiamond; + } + + case 1: + if (par1 == 0) { + return Item.bootsLeather; + } else if (par1 == 1) { + return Item.bootsGold; + } else if (par1 == 2) { + return Item.bootsChain; + } else if (par1 == 3) { + return Item.bootsIron; + } else if (par1 == 4) { + return Item.bootsDiamond; + } + + default: + return null; + } + } + + protected void func_82162_bC() { + if (this.getHeldItem() != null + && this.rand.nextFloat() < enchantmentProbability[this.worldObj.difficultySetting]) { + EnchantmentHelper.addRandomEnchantment(this.rand, this.getHeldItem(), + 5 + this.worldObj.difficultySetting * this.rand.nextInt(6)); + } + + for (int var1 = 0; var1 < 4; ++var1) { + ItemStack var2 = this.getCurrentArmor(var1); + + if (var2 != null && this.rand.nextFloat() < armorEnchantmentProbability[this.worldObj.difficultySetting]) { + EnchantmentHelper.addRandomEnchantment(this.rand, var2, + 5 + this.worldObj.difficultySetting * this.rand.nextInt(6)); + } + } + } + + /** + * Initialize this creature. + */ + public void initCreature() { + } + + /** + * Returns an integer indicating the end point of the swing animation, used by + * {@link #swingProgress} to provide a progress indicator. Takes dig speed + * enchantments into account. + */ + private int getArmSwingAnimationEnd() { + return this.isPotionActive(Potion.digSpeed) + ? 6 - (1 + this.getActivePotionEffect(Potion.digSpeed).getAmplifier()) * 1 + : (this.isPotionActive(Potion.digSlowdown) + ? 6 + (1 + this.getActivePotionEffect(Potion.digSlowdown).getAmplifier()) * 2 + : 6); + } + + /** + * Swings the item the player is holding. + */ + public void swingItem() { + if (!this.isSwingInProgress || this.swingProgressInt >= this.getArmSwingAnimationEnd() / 2 + || this.swingProgressInt < 0) { + this.swingProgressInt = -1; + this.isSwingInProgress = true; + + if (this.worldObj instanceof WorldServer) { + ((WorldServer) this.worldObj).getEntityTracker().sendPacketToTrackedPlayers(this, + new Packet18Animation(this, 1)); + } + } + } + + /** + * returns true if all the conditions for steering the entity are met. For pigs, + * this is true if it is being ridden by a player and the player is holding a + * carrot-on-a-stick + */ + public boolean canBeSteered() { + return false; + } + + /** + * counts the amount of arrows stuck in the entity. getting hit by arrows + * increases this, used in rendering + */ + public final int getArrowCountInEntity() { + return this.dataWatcher.getWatchableObjectByte(10); + } + + /** + * sets the amount of arrows stuck in the entity. used for rendering those + */ + public final void setArrowCountInEntity(int par1) { + this.dataWatcher.updateObject(10, Byte.valueOf((byte) par1)); + } + + public EntityLiving func_94060_bK() { + return (EntityLiving) (this.field_94063_bt.func_94550_c() != null ? this.field_94063_bt.func_94550_c() + : (this.attackingPlayer != null ? this.attackingPlayer + : (this.entityLivingToAttack != null ? this.entityLivingToAttack : null))); + } + + /** + * Gets the username of the entity. + */ + public String getEntityName() { + return this.func_94056_bM() ? this.func_94057_bL() : super.getEntityName(); + } + + public void func_94058_c(String par1Str) { + this.dataWatcher.updateObject(5, par1Str); + } + + public String func_94057_bL() { + return this.dataWatcher.getWatchableObjectString(5); + } + + public boolean func_94056_bM() { + return this.dataWatcher.getWatchableObjectString(5).length() > 0; + } + + public void func_94061_f(boolean par1) { + this.dataWatcher.updateObject(6, Byte.valueOf((byte) (par1 ? 1 : 0))); + } + + public boolean func_94062_bN() { + return this.dataWatcher.getWatchableObjectByte(6) == 1; + } + + public void func_96120_a(int par1, float par2) { + this.equipmentDropChances[par1] = par2; + } + + public boolean canPickUpLoot() { + return this.canPickUpLoot; + } + + public void setCanPickUpLoot(boolean par1) { + this.canPickUpLoot = par1; + } + + public boolean func_104002_bU() { + return this.persistenceRequired; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityLookHelper.java b/sp-server/src/main/java/net/minecraft/src/EntityLookHelper.java new file mode 100644 index 0000000..3401023 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityLookHelper.java @@ -0,0 +1,105 @@ +package net.minecraft.src; + +public class EntityLookHelper { + private EntityLiving entity; + + /** + * The amount of change that is made each update for an entity facing a + * direction. + */ + private float deltaLookYaw; + + /** + * The amount of change that is made each update for an entity facing a + * direction. + */ + private float deltaLookPitch; + + /** Whether or not the entity is trying to look at something. */ + private boolean isLooking = false; + private double posX; + private double posY; + private double posZ; + + public EntityLookHelper(EntityLiving par1EntityLiving) { + this.entity = par1EntityLiving; + } + + /** + * Sets position to look at using entity + */ + public void setLookPositionWithEntity(Entity par1Entity, float par2, float par3) { + this.posX = par1Entity.posX; + + if (par1Entity instanceof EntityLiving) { + this.posY = par1Entity.posY + (double) par1Entity.getEyeHeight(); + } else { + this.posY = (par1Entity.boundingBox.minY + par1Entity.boundingBox.maxY) / 2.0D; + } + + this.posZ = par1Entity.posZ; + this.deltaLookYaw = par2; + this.deltaLookPitch = par3; + this.isLooking = true; + } + + /** + * Sets position to look at + */ + public void setLookPosition(double par1, double par3, double par5, float par7, float par8) { + this.posX = par1; + this.posY = par3; + this.posZ = par5; + this.deltaLookYaw = par7; + this.deltaLookPitch = par8; + this.isLooking = true; + } + + /** + * Updates look + */ + public void onUpdateLook() { + this.entity.rotationPitch = 0.0F; + + if (this.isLooking) { + this.isLooking = false; + double var1 = this.posX - this.entity.posX; + double var3 = this.posY - (this.entity.posY + (double) this.entity.getEyeHeight()); + double var5 = this.posZ - this.entity.posZ; + double var7 = (double) MathHelper.sqrt_double(var1 * var1 + var5 * var5); + float var9 = (float) (Math.atan2(var5, var1) * 180.0D / Math.PI) - 90.0F; + float var10 = (float) (-(Math.atan2(var3, var7) * 180.0D / Math.PI)); + this.entity.rotationPitch = this.updateRotation(this.entity.rotationPitch, var10, this.deltaLookPitch); + this.entity.rotationYawHead = this.updateRotation(this.entity.rotationYawHead, var9, this.deltaLookYaw); + } else { + this.entity.rotationYawHead = this.updateRotation(this.entity.rotationYawHead, this.entity.renderYawOffset, + 10.0F); + } + + float var11 = MathHelper.wrapAngleTo180_float(this.entity.rotationYawHead - this.entity.renderYawOffset); + + if (!this.entity.getNavigator().noPath()) { + if (var11 < -75.0F) { + this.entity.rotationYawHead = this.entity.renderYawOffset - 75.0F; + } + + if (var11 > 75.0F) { + this.entity.rotationYawHead = this.entity.renderYawOffset + 75.0F; + } + } + } + + private float updateRotation(float par1, float par2, float par3) { + float var4 = MathHelper.wrapAngleTo180_float(par2 - par1); + + if (var4 > par3) { + var4 = par3; + } + + if (var4 < -par3) { + var4 = -par3; + } + + return par1 + var4; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityMagmaCube.java b/sp-server/src/main/java/net/minecraft/src/EntityMagmaCube.java new file mode 100644 index 0000000..cdfd03c --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityMagmaCube.java @@ -0,0 +1,157 @@ +package net.minecraft.src; + +public class EntityMagmaCube extends EntitySlime { + public EntityMagmaCube(World par1World) { + super(par1World); + this.texture = "/mob/lava.png"; + this.isImmuneToFire = true; + this.landMovementFactor = 0.2F; + } + + /** + * Checks if the entity's current position is a valid location to spawn this + * entity. + */ + public boolean getCanSpawnHere() { + return this.worldObj.difficultySetting > 0 && this.worldObj.checkNoEntityCollision(this.boundingBox) + && this.worldObj.getCollidingBoundingBoxes(this, this.boundingBox).isEmpty() + && !this.worldObj.isAnyLiquid(this.boundingBox); + } + + /** + * Returns the current armor value as determined by a call to + * InventoryPlayer.getTotalArmorValue + */ + public int getTotalArmorValue() { + return this.getSlimeSize() * 3; + } + + /** + * Gets how bright this entity is. + */ + public float getBrightness(float par1) { + return 1.0F; + } + + /** + * Returns the name of a particle effect that may be randomly created by + * EntitySlime.onUpdate() + */ + protected String getSlimeParticle() { + return "flame"; + } + + protected EntitySlime createInstance() { + return new EntityMagmaCube(this.worldObj); + } + + /** + * Returns the item ID for the item the mob drops on death. + */ + protected int getDropItemId() { + return Item.magmaCream.itemID; + } + + /** + * Drop 0-2 items of this living's type + */ + protected void dropFewItems(boolean par1, int par2) { + int var3 = this.getDropItemId(); + + if (var3 > 0 && this.getSlimeSize() > 1) { + int var4 = this.rand.nextInt(4) - 2; + + if (par2 > 0) { + var4 += this.rand.nextInt(par2 + 1); + } + + for (int var5 = 0; var5 < var4; ++var5) { + this.dropItem(var3, 1); + } + } + } + + /** + * Returns true if the entity is on fire. Used by render to add the fire effect + * on rendering. + */ + public boolean isBurning() { + return false; + } + + /** + * Gets the amount of time the slime needs to wait between jumps. + */ + protected int getJumpDelay() { + return super.getJumpDelay() * 4; + } + + protected void func_70808_l() { + this.field_70813_a *= 0.9F; + } + + /** + * Causes this entity to do an upwards motion (jumping). + */ + protected void jump() { + this.motionY = (double) (0.42F + (float) this.getSlimeSize() * 0.1F); + this.isAirBorne = true; + } + + /** + * Called when the mob is falling. Calculates and applies fall damage. + */ + protected void fall(float par1) { + } + + /** + * Indicates weather the slime is able to damage the player (based upon the + * slime's size) + */ + protected boolean canDamagePlayer() { + return true; + } + + /** + * Gets the amount of damage dealt to the player when "attacked" by the slime. + */ + protected int getAttackStrength() { + return super.getAttackStrength() + 2; + } + + /** + * Returns the sound this mob makes when it is hurt. + */ + protected String getHurtSound() { + return "mob.slime." + (this.getSlimeSize() > 1 ? "big" : "small"); + } + + /** + * Returns the sound this mob makes on death. + */ + protected String getDeathSound() { + return "mob.slime." + (this.getSlimeSize() > 1 ? "big" : "small"); + } + + /** + * Returns the name of the sound played when the slime jumps. + */ + protected String getJumpSound() { + return this.getSlimeSize() > 1 ? "mob.magmacube.big" : "mob.magmacube.small"; + } + + /** + * Whether or not the current entity is in lava + */ + public boolean handleLavaMovement() { + return false; + } + + /** + * Returns true if the slime makes a sound when it lands after a jump (based + * upon the slime's size) + */ + protected boolean makesSoundOnLand() { + return true; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityMinecart.java b/sp-server/src/main/java/net/minecraft/src/EntityMinecart.java new file mode 100644 index 0000000..2e1889b --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityMinecart.java @@ -0,0 +1,888 @@ +package net.minecraft.src; + +import java.util.List; +import net.minecraft.server.MinecraftServer; + +public abstract class EntityMinecart extends Entity { + private boolean isInReverse; + private final IUpdatePlayerListBox field_82344_g; + private String entityName; + + /** Minecart rotational logic matrix */ + private static final int[][][] matrix = new int[][][] { { { 0, 0, -1 }, { 0, 0, 1 } }, + { { -1, 0, 0 }, { 1, 0, 0 } }, { { -1, -1, 0 }, { 1, 0, 0 } }, { { -1, 0, 0 }, { 1, -1, 0 } }, + { { 0, 0, -1 }, { 0, -1, 1 } }, { { 0, -1, -1 }, { 0, 0, 1 } }, { { 0, 0, 1 }, { 1, 0, 0 } }, + { { 0, 0, 1 }, { -1, 0, 0 } }, { { 0, 0, -1 }, { -1, 0, 0 } }, { { 0, 0, -1 }, { 1, 0, 0 } } }; + + /** appears to be the progress of the turn */ + private int turnProgress; + private double minecartX; + private double minecartY; + private double minecartZ; + private double minecartYaw; + private double minecartPitch; + + public EntityMinecart(World par1World) { + super(par1World); + this.isInReverse = false; + this.preventEntitySpawning = true; + this.setSize(0.98F, 0.7F); + this.yOffset = this.height / 2.0F; + this.field_82344_g = par1World != null ? par1World.func_82735_a(this) : null; + } + + /** + * Creates a new minecart of the specified type in the specified location in the + * given world. par0World - world to create the minecart in, double + * par1,par3,par5 represent x,y,z respectively. int par7 specifies the type: 1 + * for MinecartChest, 2 for MinecartFurnace, 3 for MinecartTNT, 4 for + * MinecartMobSpawner, 5 for MinecartHopper and 0 for a standard empty minecart + */ + public static EntityMinecart createMinecart(World par0World, double par1, double par3, double par5, int par7) { + switch (par7) { + case 1: + return new EntityMinecartChest(par0World, par1, par3, par5); + + case 2: + return new EntityMinecartFurnace(par0World, par1, par3, par5); + + case 3: + return new EntityMinecartTNT(par0World, par1, par3, par5); + + case 4: + return new EntityMinecartMobSpawner(par0World, par1, par3, par5); + + case 5: + return new EntityMinecartHopper(par0World, par1, par3, par5); + + default: + return new EntityMinecartEmpty(par0World, par1, par3, par5); + } + } + + /** + * returns if this entity triggers Block.onEntityWalking on the blocks they walk + * on. used for spiders and wolves to prevent them from trampling crops + */ + protected boolean canTriggerWalking() { + return false; + } + + protected void entityInit() { + this.dataWatcher.addObject(17, new Integer(0)); + this.dataWatcher.addObject(18, new Integer(1)); + this.dataWatcher.addObject(19, new Integer(0)); + this.dataWatcher.addObject(20, new Integer(0)); + this.dataWatcher.addObject(21, new Integer(6)); + this.dataWatcher.addObject(22, Byte.valueOf((byte) 0)); + } + + /** + * Returns a boundingBox used to collide the entity with other entities and + * blocks. This enables the entity to be pushable on contact, like boats or + * minecarts. + */ + public AxisAlignedBB getCollisionBox(Entity par1Entity) { + return par1Entity.canBePushed() ? par1Entity.boundingBox : null; + } + + /** + * returns the bounding box for this entity + */ + public AxisAlignedBB getBoundingBox() { + return null; + } + + /** + * Returns true if this entity should push and be pushed by other entities when + * colliding. + */ + public boolean canBePushed() { + return true; + } + + public EntityMinecart(World par1World, double par2, double par4, double par6) { + this(par1World); + this.setPosition(par2, par4 + (double) this.yOffset, par6); + this.motionX = 0.0D; + this.motionY = 0.0D; + this.motionZ = 0.0D; + this.prevPosX = par2; + this.prevPosY = par4; + this.prevPosZ = par6; + } + + /** + * Returns the Y offset from the entity's position for any entity riding this + * one. + */ + public double getMountedYOffset() { + return (double) this.height * 0.0D - 0.30000001192092896D; + } + + /** + * Called when the entity is attacked. + */ + public boolean attackEntityFrom(DamageSource par1DamageSource, int par2) { + if (!this.worldObj.isRemote && !this.isDead) { + if (this.isEntityInvulnerable()) { + return false; + } else { + this.setRollingDirection(-this.getRollingDirection()); + this.setRollingAmplitude(10); + this.setBeenAttacked(); + this.setDamage(this.getDamage() + par2 * 10); + boolean var3 = par1DamageSource.getEntity() instanceof EntityPlayer + && ((EntityPlayer) par1DamageSource.getEntity()).capabilities.isCreativeMode; + + if (var3 || this.getDamage() > 40) { + if (this.riddenByEntity != null) { + this.riddenByEntity.mountEntity(this); + } + + if (var3 && !this.isInvNameLocalized()) { + this.setDead(); + } else { + this.killMinecart(par1DamageSource); + } + } + + return true; + } + } else { + return true; + } + } + + public void killMinecart(DamageSource par1DamageSource) { + this.setDead(); + ItemStack var2 = new ItemStack(Item.minecartEmpty, 1); + + if (this.entityName != null) { + var2.setItemName(this.entityName); + } + + this.entityDropItem(var2, 0.0F); + } + + /** + * Returns true if other Entities should be prevented from moving through this + * Entity. + */ + public boolean canBeCollidedWith() { + return !this.isDead; + } + + /** + * Will get destroyed next tick. + */ + public void setDead() { + super.setDead(); + + if (this.field_82344_g != null) { + this.field_82344_g.update(); + } + } + + /** + * Called to update the entity's position/logic. + */ + public void onUpdate() { + if (this.field_82344_g != null) { + this.field_82344_g.update(); + } + + if (this.getRollingAmplitude() > 0) { + this.setRollingAmplitude(this.getRollingAmplitude() - 1); + } + + if (this.getDamage() > 0) { + this.setDamage(this.getDamage() - 1); + } + + if (this.posY < -64.0D) { + this.kill(); + } + + int var2; + + if (!this.worldObj.isRemote && this.worldObj instanceof WorldServer) { + this.worldObj.theProfiler.startSection("portal"); + MinecraftServer var1 = ((WorldServer) this.worldObj).getMinecraftServer(); + var2 = this.getMaxInPortalTime(); + + if (this.inPortal) { + if (var1.getAllowNether()) { + if (this.ridingEntity == null && this.timeInPortal++ >= var2) { + this.timeInPortal = var2; + this.timeUntilPortal = this.getPortalCooldown(); + byte var3; + + if (this.worldObj.provider.dimensionId == -1) { + var3 = 0; + } else { + var3 = -1; + } + + this.travelToTheEnd(var3); + } + + this.inPortal = false; + } + } else { + if (this.timeInPortal > 0) { + this.timeInPortal -= 4; + } + + if (this.timeInPortal < 0) { + this.timeInPortal = 0; + } + } + + if (this.timeUntilPortal > 0) { + --this.timeUntilPortal; + } + + this.worldObj.theProfiler.endSection(); + } + + if (this.worldObj.isRemote) { + if (this.turnProgress > 0) { + double var19 = this.posX + (this.minecartX - this.posX) / (double) this.turnProgress; + double var21 = this.posY + (this.minecartY - this.posY) / (double) this.turnProgress; + double var5 = this.posZ + (this.minecartZ - this.posZ) / (double) this.turnProgress; + double var7 = MathHelper.wrapAngleTo180_double(this.minecartYaw - (double) this.rotationYaw); + this.rotationYaw = (float) ((double) this.rotationYaw + var7 / (double) this.turnProgress); + this.rotationPitch = (float) ((double) this.rotationPitch + + (this.minecartPitch - (double) this.rotationPitch) / (double) this.turnProgress); + --this.turnProgress; + this.setPosition(var19, var21, var5); + this.setRotation(this.rotationYaw, this.rotationPitch); + } else { + this.setPosition(this.posX, this.posY, this.posZ); + this.setRotation(this.rotationYaw, this.rotationPitch); + } + } else { + this.prevPosX = this.posX; + this.prevPosY = this.posY; + this.prevPosZ = this.posZ; + this.motionY -= 0.03999999910593033D; + int var18 = MathHelper.floor_double(this.posX); + var2 = MathHelper.floor_double(this.posY); + int var20 = MathHelper.floor_double(this.posZ); + + if (BlockRailBase.isRailBlockAt(this.worldObj, var18, var2 - 1, var20)) { + --var2; + } + + double var4 = 0.4D; + double var6 = 0.0078125D; + int var8 = this.worldObj.getBlockId(var18, var2, var20); + + if (BlockRailBase.isRailBlock(var8)) { + int var9 = this.worldObj.getBlockMetadata(var18, var2, var20); + this.updateOnTrack(var18, var2, var20, var4, var6, var8, var9); + + if (var8 == Block.railActivator.blockID) { + this.onActivatorRailPass(var18, var2, var20, (var9 & 8) != 0); + } + } else { + this.func_94088_b(var4); + } + + this.doBlockCollisions(); + this.rotationPitch = 0.0F; + double var22 = this.prevPosX - this.posX; + double var11 = this.prevPosZ - this.posZ; + + if (var22 * var22 + var11 * var11 > 0.001D) { + this.rotationYaw = (float) (Math.atan2(var11, var22) * 180.0D / Math.PI); + + if (this.isInReverse) { + this.rotationYaw += 180.0F; + } + } + + double var13 = (double) MathHelper.wrapAngleTo180_float(this.rotationYaw - this.prevRotationYaw); + + if (var13 < -170.0D || var13 >= 170.0D) { + this.rotationYaw += 180.0F; + this.isInReverse = !this.isInReverse; + } + + this.setRotation(this.rotationYaw, this.rotationPitch); + List var15 = this.worldObj.getEntitiesWithinAABBExcludingEntity(this, + this.boundingBox.expand(0.20000000298023224D, 0.0D, 0.20000000298023224D)); + + if (var15 != null && !var15.isEmpty()) { + for (int var16 = 0; var16 < var15.size(); ++var16) { + Entity var17 = (Entity) var15.get(var16); + + if (var17 != this.riddenByEntity && var17.canBePushed() && var17 instanceof EntityMinecart) { + var17.applyEntityCollision(this); + } + } + } + + if (this.riddenByEntity != null && this.riddenByEntity.isDead) { + if (this.riddenByEntity.ridingEntity == this) { + this.riddenByEntity.ridingEntity = null; + } + + this.riddenByEntity = null; + } + } + } + + /** + * Called every tick the minecart is on an activator rail. Args: x, y, z, is the + * rail receiving power + */ + public void onActivatorRailPass(int par1, int par2, int par3, boolean par4) { + } + + protected void func_94088_b(double par1) { + if (this.motionX < -par1) { + this.motionX = -par1; + } + + if (this.motionX > par1) { + this.motionX = par1; + } + + if (this.motionZ < -par1) { + this.motionZ = -par1; + } + + if (this.motionZ > par1) { + this.motionZ = par1; + } + + if (this.onGround) { + this.motionX *= 0.5D; + this.motionY *= 0.5D; + this.motionZ *= 0.5D; + } + + this.moveEntity(this.motionX, this.motionY, this.motionZ); + + if (!this.onGround) { + this.motionX *= 0.949999988079071D; + this.motionY *= 0.949999988079071D; + this.motionZ *= 0.949999988079071D; + } + } + + protected void updateOnTrack(int par1, int par2, int par3, double par4, double par6, int par8, int par9) { + this.fallDistance = 0.0F; + Vec3 var10 = this.func_70489_a(this.posX, this.posY, this.posZ); + this.posY = (double) par2; + boolean var11 = false; + boolean var12 = false; + + if (par8 == Block.railPowered.blockID) { + var11 = (par9 & 8) != 0; + var12 = !var11; + } + + if (((BlockRailBase) Block.blocksList[par8]).isPowered()) { + par9 &= 7; + } + + if (par9 >= 2 && par9 <= 5) { + this.posY = (double) (par2 + 1); + } + + if (par9 == 2) { + this.motionX -= par6; + } + + if (par9 == 3) { + this.motionX += par6; + } + + if (par9 == 4) { + this.motionZ += par6; + } + + if (par9 == 5) { + this.motionZ -= par6; + } + + int[][] var13 = matrix[par9]; + double var14 = (double) (var13[1][0] - var13[0][0]); + double var16 = (double) (var13[1][2] - var13[0][2]); + double var18 = Math.sqrt(var14 * var14 + var16 * var16); + double var20 = this.motionX * var14 + this.motionZ * var16; + + if (var20 < 0.0D) { + var14 = -var14; + var16 = -var16; + } + + double var22 = Math.sqrt(this.motionX * this.motionX + this.motionZ * this.motionZ); + + if (var22 > 2.0D) { + var22 = 2.0D; + } + + this.motionX = var22 * var14 / var18; + this.motionZ = var22 * var16 / var18; + double var24; + double var26; + + if (this.riddenByEntity != null) { + var24 = this.riddenByEntity.motionX * this.riddenByEntity.motionX + + this.riddenByEntity.motionZ * this.riddenByEntity.motionZ; + var26 = this.motionX * this.motionX + this.motionZ * this.motionZ; + + if (var24 > 1.0E-4D && var26 < 0.01D) { + this.motionX += this.riddenByEntity.motionX * 0.1D; + this.motionZ += this.riddenByEntity.motionZ * 0.1D; + var12 = false; + } + } + + if (var12) { + var24 = Math.sqrt(this.motionX * this.motionX + this.motionZ * this.motionZ); + + if (var24 < 0.03D) { + this.motionX *= 0.0D; + this.motionY *= 0.0D; + this.motionZ *= 0.0D; + } else { + this.motionX *= 0.5D; + this.motionY *= 0.0D; + this.motionZ *= 0.5D; + } + } + + var24 = 0.0D; + var26 = (double) par1 + 0.5D + (double) var13[0][0] * 0.5D; + double var28 = (double) par3 + 0.5D + (double) var13[0][2] * 0.5D; + double var30 = (double) par1 + 0.5D + (double) var13[1][0] * 0.5D; + double var32 = (double) par3 + 0.5D + (double) var13[1][2] * 0.5D; + var14 = var30 - var26; + var16 = var32 - var28; + double var34; + double var36; + + if (var14 == 0.0D) { + this.posX = (double) par1 + 0.5D; + var24 = this.posZ - (double) par3; + } else if (var16 == 0.0D) { + this.posZ = (double) par3 + 0.5D; + var24 = this.posX - (double) par1; + } else { + var34 = this.posX - var26; + var36 = this.posZ - var28; + var24 = (var34 * var14 + var36 * var16) * 2.0D; + } + + this.posX = var26 + var14 * var24; + this.posZ = var28 + var16 * var24; + this.setPosition(this.posX, this.posY + (double) this.yOffset, this.posZ); + var34 = this.motionX; + var36 = this.motionZ; + + if (this.riddenByEntity != null) { + var34 *= 0.75D; + var36 *= 0.75D; + } + + if (var34 < -par4) { + var34 = -par4; + } + + if (var34 > par4) { + var34 = par4; + } + + if (var36 < -par4) { + var36 = -par4; + } + + if (var36 > par4) { + var36 = par4; + } + + this.moveEntity(var34, 0.0D, var36); + + if (var13[0][1] != 0 && MathHelper.floor_double(this.posX) - par1 == var13[0][0] + && MathHelper.floor_double(this.posZ) - par3 == var13[0][2]) { + this.setPosition(this.posX, this.posY + (double) var13[0][1], this.posZ); + } else if (var13[1][1] != 0 && MathHelper.floor_double(this.posX) - par1 == var13[1][0] + && MathHelper.floor_double(this.posZ) - par3 == var13[1][2]) { + this.setPosition(this.posX, this.posY + (double) var13[1][1], this.posZ); + } + + this.applyDrag(); + Vec3 var38 = this.func_70489_a(this.posX, this.posY, this.posZ); + + if (var38 != null && var10 != null) { + double var39 = (var10.yCoord - var38.yCoord) * 0.05D; + var22 = Math.sqrt(this.motionX * this.motionX + this.motionZ * this.motionZ); + + if (var22 > 0.0D) { + this.motionX = this.motionX / var22 * (var22 + var39); + this.motionZ = this.motionZ / var22 * (var22 + var39); + } + + this.setPosition(this.posX, var38.yCoord, this.posZ); + } + + int var45 = MathHelper.floor_double(this.posX); + int var40 = MathHelper.floor_double(this.posZ); + + if (var45 != par1 || var40 != par3) { + var22 = Math.sqrt(this.motionX * this.motionX + this.motionZ * this.motionZ); + this.motionX = var22 * (double) (var45 - par1); + this.motionZ = var22 * (double) (var40 - par3); + } + + if (var11) { + double var41 = Math.sqrt(this.motionX * this.motionX + this.motionZ * this.motionZ); + + if (var41 > 0.01D) { + double var43 = 0.06D; + this.motionX += this.motionX / var41 * var43; + this.motionZ += this.motionZ / var41 * var43; + } else if (par9 == 1) { + if (this.worldObj.isBlockNormalCube(par1 - 1, par2, par3)) { + this.motionX = 0.02D; + } else if (this.worldObj.isBlockNormalCube(par1 + 1, par2, par3)) { + this.motionX = -0.02D; + } + } else if (par9 == 0) { + if (this.worldObj.isBlockNormalCube(par1, par2, par3 - 1)) { + this.motionZ = 0.02D; + } else if (this.worldObj.isBlockNormalCube(par1, par2, par3 + 1)) { + this.motionZ = -0.02D; + } + } + } + } + + protected void applyDrag() { + if (this.riddenByEntity != null) { + this.motionX *= 0.996999979019165D; + this.motionY *= 0.0D; + this.motionZ *= 0.996999979019165D; + } else { + this.motionX *= 0.9599999785423279D; + this.motionY *= 0.0D; + this.motionZ *= 0.9599999785423279D; + } + } + + public Vec3 func_70489_a(double par1, double par3, double par5) { + int var7 = MathHelper.floor_double(par1); + int var8 = MathHelper.floor_double(par3); + int var9 = MathHelper.floor_double(par5); + + if (BlockRailBase.isRailBlockAt(this.worldObj, var7, var8 - 1, var9)) { + --var8; + } + + int var10 = this.worldObj.getBlockId(var7, var8, var9); + + if (BlockRailBase.isRailBlock(var10)) { + int var11 = this.worldObj.getBlockMetadata(var7, var8, var9); + par3 = (double) var8; + + if (((BlockRailBase) Block.blocksList[var10]).isPowered()) { + var11 &= 7; + } + + if (var11 >= 2 && var11 <= 5) { + par3 = (double) (var8 + 1); + } + + int[][] var12 = matrix[var11]; + double var13 = 0.0D; + double var15 = (double) var7 + 0.5D + (double) var12[0][0] * 0.5D; + double var17 = (double) var8 + 0.5D + (double) var12[0][1] * 0.5D; + double var19 = (double) var9 + 0.5D + (double) var12[0][2] * 0.5D; + double var21 = (double) var7 + 0.5D + (double) var12[1][0] * 0.5D; + double var23 = (double) var8 + 0.5D + (double) var12[1][1] * 0.5D; + double var25 = (double) var9 + 0.5D + (double) var12[1][2] * 0.5D; + double var27 = var21 - var15; + double var29 = (var23 - var17) * 2.0D; + double var31 = var25 - var19; + + if (var27 == 0.0D) { + par1 = (double) var7 + 0.5D; + var13 = par5 - (double) var9; + } else if (var31 == 0.0D) { + par5 = (double) var9 + 0.5D; + var13 = par1 - (double) var7; + } else { + double var33 = par1 - var15; + double var35 = par5 - var19; + var13 = (var33 * var27 + var35 * var31) * 2.0D; + } + + par1 = var15 + var27 * var13; + par3 = var17 + var29 * var13; + par5 = var19 + var31 * var13; + + if (var29 < 0.0D) { + ++par3; + } + + if (var29 > 0.0D) { + par3 += 0.5D; + } + + return this.worldObj.getWorldVec3Pool().getVecFromPool(par1, par3, par5); + } else { + return null; + } + } + + /** + * (abstract) Protected helper method to read subclass entity data from NBT. + */ + protected void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) { + if (par1NBTTagCompound.getBoolean("CustomDisplayTile")) { + this.setDisplayTile(par1NBTTagCompound.getInteger("DisplayTile")); + this.setDisplayTileData(par1NBTTagCompound.getInteger("DisplayData")); + this.setDisplayTileOffset(par1NBTTagCompound.getInteger("DisplayOffset")); + } + + if (par1NBTTagCompound.hasKey("CustomName") && par1NBTTagCompound.getString("CustomName").length() > 0) { + this.entityName = par1NBTTagCompound.getString("CustomName"); + } + } + + /** + * (abstract) Protected helper method to write subclass entity data to NBT. + */ + protected void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) { + if (this.hasDisplayTile()) { + par1NBTTagCompound.setBoolean("CustomDisplayTile", true); + par1NBTTagCompound.setInteger("DisplayTile", + this.getDisplayTile() == null ? 0 : this.getDisplayTile().blockID); + par1NBTTagCompound.setInteger("DisplayData", this.getDisplayTileData()); + par1NBTTagCompound.setInteger("DisplayOffset", this.getDisplayTileOffset()); + } + + if (this.entityName != null && this.entityName.length() > 0) { + par1NBTTagCompound.setString("CustomName", this.entityName); + } + } + + /** + * Applies a velocity to each of the entities pushing them away from each other. + * Args: entity + */ + public void applyEntityCollision(Entity par1Entity) { + if (!this.worldObj.isRemote) { + if (par1Entity != this.riddenByEntity) { + if (par1Entity instanceof EntityLiving && !(par1Entity instanceof EntityPlayer) + && !(par1Entity instanceof EntityIronGolem) && this.getMinecartType() == 0 + && this.motionX * this.motionX + this.motionZ * this.motionZ > 0.01D + && this.riddenByEntity == null && par1Entity.ridingEntity == null) { + par1Entity.mountEntity(this); + } + + double var2 = par1Entity.posX - this.posX; + double var4 = par1Entity.posZ - this.posZ; + double var6 = var2 * var2 + var4 * var4; + + if (var6 >= 9.999999747378752E-5D) { + var6 = (double) MathHelper.sqrt_double(var6); + var2 /= var6; + var4 /= var6; + double var8 = 1.0D / var6; + + if (var8 > 1.0D) { + var8 = 1.0D; + } + + var2 *= var8; + var4 *= var8; + var2 *= 0.10000000149011612D; + var4 *= 0.10000000149011612D; + var2 *= (double) (1.0F - this.entityCollisionReduction); + var4 *= (double) (1.0F - this.entityCollisionReduction); + var2 *= 0.5D; + var4 *= 0.5D; + + if (par1Entity instanceof EntityMinecart) { + double var10 = par1Entity.posX - this.posX; + double var12 = par1Entity.posZ - this.posZ; + Vec3 var14 = this.worldObj.getWorldVec3Pool().getVecFromPool(var10, 0.0D, var12).normalize(); + Vec3 var15 = this.worldObj.getWorldVec3Pool() + .getVecFromPool((double) MathHelper.cos(this.rotationYaw * (float) Math.PI / 180.0F), + 0.0D, (double) MathHelper.sin(this.rotationYaw * (float) Math.PI / 180.0F)) + .normalize(); + double var16 = Math.abs(var14.dotProduct(var15)); + + if (var16 < 0.800000011920929D) { + return; + } + + double var18 = par1Entity.motionX + this.motionX; + double var20 = par1Entity.motionZ + this.motionZ; + + if (((EntityMinecart) par1Entity).getMinecartType() == 2 && this.getMinecartType() != 2) { + this.motionX *= 0.20000000298023224D; + this.motionZ *= 0.20000000298023224D; + this.addVelocity(par1Entity.motionX - var2, 0.0D, par1Entity.motionZ - var4); + par1Entity.motionX *= 0.949999988079071D; + par1Entity.motionZ *= 0.949999988079071D; + } else if (((EntityMinecart) par1Entity).getMinecartType() != 2 + && this.getMinecartType() == 2) { + par1Entity.motionX *= 0.20000000298023224D; + par1Entity.motionZ *= 0.20000000298023224D; + par1Entity.addVelocity(this.motionX + var2, 0.0D, this.motionZ + var4); + this.motionX *= 0.949999988079071D; + this.motionZ *= 0.949999988079071D; + } else { + var18 /= 2.0D; + var20 /= 2.0D; + this.motionX *= 0.20000000298023224D; + this.motionZ *= 0.20000000298023224D; + this.addVelocity(var18 - var2, 0.0D, var20 - var4); + par1Entity.motionX *= 0.20000000298023224D; + par1Entity.motionZ *= 0.20000000298023224D; + par1Entity.addVelocity(var18 + var2, 0.0D, var20 + var4); + } + } else { + this.addVelocity(-var2, 0.0D, -var4); + par1Entity.addVelocity(var2 / 4.0D, 0.0D, var4 / 4.0D); + } + } + } + } + } + + /** + * Sets the current amount of damage the minecart has taken. Decreases over + * time. The cart breaks when this is over 40. + */ + public void setDamage(int par1) { + this.dataWatcher.updateObject(19, Integer.valueOf(par1)); + } + + /** + * Gets the current amount of damage the minecart has taken. Decreases over + * time. The cart breaks when this is over 40. + */ + public int getDamage() { + return this.dataWatcher.getWatchableObjectInt(19); + } + + /** + * Sets the rolling amplitude the cart rolls while being attacked. + */ + public void setRollingAmplitude(int par1) { + this.dataWatcher.updateObject(17, Integer.valueOf(par1)); + } + + /** + * Gets the rolling amplitude the cart rolls while being attacked. + */ + public int getRollingAmplitude() { + return this.dataWatcher.getWatchableObjectInt(17); + } + + /** + * Sets the rolling direction the cart rolls while being attacked. Can be 1 or + * -1. + */ + public void setRollingDirection(int par1) { + this.dataWatcher.updateObject(18, Integer.valueOf(par1)); + } + + /** + * Gets the rolling direction the cart rolls while being attacked. Can be 1 or + * -1. + */ + public int getRollingDirection() { + return this.dataWatcher.getWatchableObjectInt(18); + } + + public abstract int getMinecartType(); + + public Block getDisplayTile() { + if (!this.hasDisplayTile()) { + return this.getDefaultDisplayTile(); + } else { + int var1 = this.getDataWatcher().getWatchableObjectInt(20) & 65535; + return var1 > 0 && var1 < Block.blocksList.length ? Block.blocksList[var1] : null; + } + } + + public Block getDefaultDisplayTile() { + return null; + } + + public int getDisplayTileData() { + return !this.hasDisplayTile() ? this.getDefaultDisplayTileData() + : this.getDataWatcher().getWatchableObjectInt(20) >> 16; + } + + public int getDefaultDisplayTileData() { + return 0; + } + + public int getDisplayTileOffset() { + return !this.hasDisplayTile() ? this.getDefaultDisplayTileOffset() + : this.getDataWatcher().getWatchableObjectInt(21); + } + + public int getDefaultDisplayTileOffset() { + return 6; + } + + public void setDisplayTile(int par1) { + this.getDataWatcher().updateObject(20, Integer.valueOf(par1 & 65535 | this.getDisplayTileData() << 16)); + this.setHasDisplayTile(true); + } + + public void setDisplayTileData(int par1) { + Block var2 = this.getDisplayTile(); + int var3 = var2 == null ? 0 : var2.blockID; + this.getDataWatcher().updateObject(20, Integer.valueOf(var3 & 65535 | par1 << 16)); + this.setHasDisplayTile(true); + } + + public void setDisplayTileOffset(int par1) { + this.getDataWatcher().updateObject(21, Integer.valueOf(par1)); + this.setHasDisplayTile(true); + } + + public boolean hasDisplayTile() { + return this.getDataWatcher().getWatchableObjectByte(22) == 1; + } + + public void setHasDisplayTile(boolean par1) { + this.getDataWatcher().updateObject(22, Byte.valueOf((byte) (par1 ? 1 : 0))); + } + + public void func_96094_a(String par1Str) { + this.entityName = par1Str; + } + + /** + * Gets the username of the entity. + */ + public String getEntityName() { + return this.entityName != null ? this.entityName : super.getEntityName(); + } + + /** + * If this returns false, the inventory name will be used as an unlocalized + * name, and translated into the player's language. Otherwise it will be used + * directly. + */ + public boolean isInvNameLocalized() { + return this.entityName != null; + } + + public String func_95999_t() { + return this.entityName; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityMinecartChest.java b/sp-server/src/main/java/net/minecraft/src/EntityMinecartChest.java new file mode 100644 index 0000000..caf61c6 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityMinecartChest.java @@ -0,0 +1,35 @@ +package net.minecraft.src; + +public class EntityMinecartChest extends EntityMinecartContainer { + public EntityMinecartChest(World par1World) { + super(par1World); + } + + public EntityMinecartChest(World par1, double par2, double par4, double par6) { + super(par1, par2, par4, par6); + } + + public void killMinecart(DamageSource par1DamageSource) { + super.killMinecart(par1DamageSource); + this.dropItemWithOffset(Block.chest.blockID, 1, 0.0F); + } + + /** + * Returns the number of slots in the inventory. + */ + public int getSizeInventory() { + return 27; + } + + public int getMinecartType() { + return 1; + } + + public Block getDefaultDisplayTile() { + return Block.chest; + } + + public int getDefaultDisplayTileOffset() { + return 8; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityMinecartContainer.java b/sp-server/src/main/java/net/minecraft/src/EntityMinecartContainer.java new file mode 100644 index 0000000..35bbda1 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityMinecartContainer.java @@ -0,0 +1,256 @@ +package net.minecraft.src; + +public abstract class EntityMinecartContainer extends EntityMinecart implements IInventory { + private ItemStack[] minecartContainerItems = new ItemStack[36]; + + /** + * Whether the minecart should not drop its content when flagged as dead. + */ + private boolean preventContentDropping = true; + + public EntityMinecartContainer(World par1World) { + super(par1World); + } + + public EntityMinecartContainer(World par1World, double par2, double par4, double par6) { + super(par1World, par2, par4, par6); + } + + public void killMinecart(DamageSource par1DamageSource) { + super.killMinecart(par1DamageSource); + + for (int var2 = 0; var2 < this.getSizeInventory(); ++var2) { + ItemStack var3 = this.getStackInSlot(var2); + + if (var3 != null) { + float var4 = this.rand.nextFloat() * 0.8F + 0.1F; + float var5 = this.rand.nextFloat() * 0.8F + 0.1F; + float var6 = this.rand.nextFloat() * 0.8F + 0.1F; + + while (var3.stackSize > 0) { + int var7 = this.rand.nextInt(21) + 10; + + if (var7 > var3.stackSize) { + var7 = var3.stackSize; + } + + var3.stackSize -= var7; + EntityItem var8 = new EntityItem(this.worldObj, this.posX + (double) var4, + this.posY + (double) var5, this.posZ + (double) var6, + new ItemStack(var3.itemID, var7, var3.getItemDamage())); + float var9 = 0.05F; + var8.motionX = (double) ((float) this.rand.nextGaussian() * var9); + var8.motionY = (double) ((float) this.rand.nextGaussian() * var9 + 0.2F); + var8.motionZ = (double) ((float) this.rand.nextGaussian() * var9); + this.worldObj.spawnEntityInWorld(var8); + } + } + } + } + + /** + * Returns the stack in slot i + */ + public ItemStack getStackInSlot(int par1) { + return this.minecartContainerItems[par1]; + } + + /** + * Removes from an inventory slot (first arg) up to a specified number (second + * arg) of items and returns them in a new stack. + */ + public ItemStack decrStackSize(int par1, int par2) { + if (this.minecartContainerItems[par1] != null) { + ItemStack var3; + + if (this.minecartContainerItems[par1].stackSize <= par2) { + var3 = this.minecartContainerItems[par1]; + this.minecartContainerItems[par1] = null; + return var3; + } else { + var3 = this.minecartContainerItems[par1].splitStack(par2); + + if (this.minecartContainerItems[par1].stackSize == 0) { + this.minecartContainerItems[par1] = null; + } + + return var3; + } + } else { + return null; + } + } + + /** + * When some containers are closed they call this on each slot, then drop + * whatever it returns as an EntityItem - like when you close a workbench GUI. + */ + public ItemStack getStackInSlotOnClosing(int par1) { + if (this.minecartContainerItems[par1] != null) { + ItemStack var2 = this.minecartContainerItems[par1]; + this.minecartContainerItems[par1] = null; + return var2; + } else { + return null; + } + } + + /** + * Sets the given item stack to the specified slot in the inventory (can be + * crafting or armor sections). + */ + public void setInventorySlotContents(int par1, ItemStack par2ItemStack) { + this.minecartContainerItems[par1] = par2ItemStack; + + if (par2ItemStack != null && par2ItemStack.stackSize > this.getInventoryStackLimit()) { + par2ItemStack.stackSize = this.getInventoryStackLimit(); + } + } + + /** + * Called when an the contents of an Inventory change, usually + */ + public void onInventoryChanged() { + } + + /** + * Do not make give this method the name canInteractWith because it clashes with + * Container + */ + public boolean isUseableByPlayer(EntityPlayer par1EntityPlayer) { + return this.isDead ? false : par1EntityPlayer.getDistanceSqToEntity(this) <= 64.0D; + } + + public void openChest() { + } + + public void closeChest() { + } + + /** + * Returns true if automation is allowed to insert the given stack (ignoring + * stack size) into the given slot. + */ + public boolean isStackValidForSlot(int par1, ItemStack par2ItemStack) { + return true; + } + + /** + * Returns the name of the inventory. + */ + public String getInvName() { + return this.isInvNameLocalized() ? this.func_95999_t() : "container.minecart"; + } + + /** + * Returns the maximum stack size for a inventory slot. Seems to always be 64, + * possibly will be extended. *Isn't this more of a set than a get?* + */ + public int getInventoryStackLimit() { + return 64; + } + + public void travelToTheEnd(int par1) { + this.preventContentDropping = false; + super.travelToTheEnd(par1); + } + + /** + * Will get destroyed next tick. + */ + public void setDead() { + if (this.preventContentDropping) { + for (int var1 = 0; var1 < this.getSizeInventory(); ++var1) { + ItemStack var2 = this.getStackInSlot(var1); + + if (var2 != null) { + float var3 = this.rand.nextFloat() * 0.8F + 0.1F; + float var4 = this.rand.nextFloat() * 0.8F + 0.1F; + float var5 = this.rand.nextFloat() * 0.8F + 0.1F; + + while (var2.stackSize > 0) { + int var6 = this.rand.nextInt(21) + 10; + + if (var6 > var2.stackSize) { + var6 = var2.stackSize; + } + + var2.stackSize -= var6; + EntityItem var7 = new EntityItem(this.worldObj, this.posX + (double) var3, + this.posY + (double) var4, this.posZ + (double) var5, + new ItemStack(var2.itemID, var6, var2.getItemDamage())); + + if (var2.hasTagCompound()) { + var7.getEntityItem().setTagCompound((NBTTagCompound) var2.getTagCompound().copy()); + } + + float var8 = 0.05F; + var7.motionX = (double) ((float) this.rand.nextGaussian() * var8); + var7.motionY = (double) ((float) this.rand.nextGaussian() * var8 + 0.2F); + var7.motionZ = (double) ((float) this.rand.nextGaussian() * var8); + this.worldObj.spawnEntityInWorld(var7); + } + } + } + } + + super.setDead(); + } + + /** + * (abstract) Protected helper method to write subclass entity data to NBT. + */ + protected void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) { + super.writeEntityToNBT(par1NBTTagCompound); + NBTTagList var2 = new NBTTagList(); + + for (int var3 = 0; var3 < this.minecartContainerItems.length; ++var3) { + if (this.minecartContainerItems[var3] != null) { + NBTTagCompound var4 = new NBTTagCompound(); + var4.setByte("Slot", (byte) var3); + this.minecartContainerItems[var3].writeToNBT(var4); + var2.appendTag(var4); + } + } + + par1NBTTagCompound.setTag("Items", var2); + } + + /** + * (abstract) Protected helper method to read subclass entity data from NBT. + */ + protected void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) { + super.readEntityFromNBT(par1NBTTagCompound); + NBTTagList var2 = par1NBTTagCompound.getTagList("Items"); + this.minecartContainerItems = new ItemStack[this.getSizeInventory()]; + + for (int var3 = 0; var3 < var2.tagCount(); ++var3) { + NBTTagCompound var4 = (NBTTagCompound) var2.tagAt(var3); + int var5 = var4.getByte("Slot") & 255; + + if (var5 >= 0 && var5 < this.minecartContainerItems.length) { + this.minecartContainerItems[var5] = ItemStack.loadItemStackFromNBT(var4); + } + } + } + + /** + * Called when a player interacts with a mob. e.g. gets milk from a cow, gets + * into the saddle on a pig. + */ + public boolean interact(EntityPlayer par1EntityPlayer) { + if (!this.worldObj.isRemote) { + par1EntityPlayer.displayGUIChest(this); + } + + return true; + } + + protected void applyDrag() { + int var1 = 15 - Container.calcRedstoneFromInventory(this); + float var2 = 0.98F + (float) var1 * 0.001F; + this.motionX *= (double) var2; + this.motionY *= 0.0D; + this.motionZ *= (double) var2; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityMinecartEmpty.java b/sp-server/src/main/java/net/minecraft/src/EntityMinecartEmpty.java new file mode 100644 index 0000000..575208f --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityMinecartEmpty.java @@ -0,0 +1,34 @@ +package net.minecraft.src; + +public class EntityMinecartEmpty extends EntityMinecart { + public EntityMinecartEmpty(World par1World) { + super(par1World); + } + + public EntityMinecartEmpty(World par1, double par2, double par4, double par6) { + super(par1, par2, par4, par6); + } + + /** + * Called when a player interacts with a mob. e.g. gets milk from a cow, gets + * into the saddle on a pig. + */ + public boolean interact(EntityPlayer par1EntityPlayer) { + if (this.riddenByEntity != null && this.riddenByEntity instanceof EntityPlayer + && this.riddenByEntity != par1EntityPlayer) { + return true; + } else if (this.riddenByEntity != null && this.riddenByEntity != par1EntityPlayer) { + return false; + } else { + if (!this.worldObj.isRemote) { + par1EntityPlayer.mountEntity(this); + } + + return true; + } + } + + public int getMinecartType() { + return 0; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityMinecartFurnace.java b/sp-server/src/main/java/net/minecraft/src/EntityMinecartFurnace.java new file mode 100644 index 0000000..486ad03 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityMinecartFurnace.java @@ -0,0 +1,155 @@ +package net.minecraft.src; + +public class EntityMinecartFurnace extends EntityMinecart { + private int fuel = 0; + public double pushX; + public double pushZ; + + public EntityMinecartFurnace(World par1World) { + super(par1World); + } + + public EntityMinecartFurnace(World par1World, double par2, double par4, double par6) { + super(par1World, par2, par4, par6); + } + + public int getMinecartType() { + return 2; + } + + protected void entityInit() { + super.entityInit(); + this.dataWatcher.addObject(16, new Byte((byte) 0)); + } + + /** + * Called to update the entity's position/logic. + */ + public void onUpdate() { + super.onUpdate(); + + if (this.fuel > 0) { + --this.fuel; + } + + if (this.fuel <= 0) { + this.pushX = this.pushZ = 0.0D; + } + + this.setMinecartPowered(this.fuel > 0); + + if (this.isMinecartPowered() && this.rand.nextInt(4) == 0) { + this.worldObj.spawnParticle("largesmoke", this.posX, this.posY + 0.8D, this.posZ, 0.0D, 0.0D, 0.0D); + } + } + + public void killMinecart(DamageSource par1DamageSource) { + super.killMinecart(par1DamageSource); + + if (!par1DamageSource.isExplosion()) { + this.entityDropItem(new ItemStack(Block.furnaceIdle, 1), 0.0F); + } + } + + protected void updateOnTrack(int par1, int par2, int par3, double par4, double par6, int par8, int par9) { + super.updateOnTrack(par1, par2, par3, par4, par6, par8, par9); + double var10 = this.pushX * this.pushX + this.pushZ * this.pushZ; + + if (var10 > 1.0E-4D && this.motionX * this.motionX + this.motionZ * this.motionZ > 0.001D) { + var10 = (double) MathHelper.sqrt_double(var10); + this.pushX /= var10; + this.pushZ /= var10; + + if (this.pushX * this.motionX + this.pushZ * this.motionZ < 0.0D) { + this.pushX = 0.0D; + this.pushZ = 0.0D; + } else { + this.pushX = this.motionX; + this.pushZ = this.motionZ; + } + } + } + + protected void applyDrag() { + double var1 = this.pushX * this.pushX + this.pushZ * this.pushZ; + + if (var1 > 1.0E-4D) { + var1 = (double) MathHelper.sqrt_double(var1); + this.pushX /= var1; + this.pushZ /= var1; + double var3 = 0.05D; + this.motionX *= 0.800000011920929D; + this.motionY *= 0.0D; + this.motionZ *= 0.800000011920929D; + this.motionX += this.pushX * var3; + this.motionZ += this.pushZ * var3; + } else { + this.motionX *= 0.9800000190734863D; + this.motionY *= 0.0D; + this.motionZ *= 0.9800000190734863D; + } + + super.applyDrag(); + } + + /** + * Called when a player interacts with a mob. e.g. gets milk from a cow, gets + * into the saddle on a pig. + */ + public boolean interact(EntityPlayer par1EntityPlayer) { + ItemStack var2 = par1EntityPlayer.inventory.getCurrentItem(); + + if (var2 != null && var2.itemID == Item.coal.itemID) { + if (--var2.stackSize == 0) { + par1EntityPlayer.inventory.setInventorySlotContents(par1EntityPlayer.inventory.currentItem, + (ItemStack) null); + } + + this.fuel += 3600; + } + + this.pushX = this.posX - par1EntityPlayer.posX; + this.pushZ = this.posZ - par1EntityPlayer.posZ; + return true; + } + + /** + * (abstract) Protected helper method to write subclass entity data to NBT. + */ + protected void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) { + super.writeEntityToNBT(par1NBTTagCompound); + par1NBTTagCompound.setDouble("PushX", this.pushX); + par1NBTTagCompound.setDouble("PushZ", this.pushZ); + par1NBTTagCompound.setShort("Fuel", (short) this.fuel); + } + + /** + * (abstract) Protected helper method to read subclass entity data from NBT. + */ + protected void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) { + super.readEntityFromNBT(par1NBTTagCompound); + this.pushX = par1NBTTagCompound.getDouble("PushX"); + this.pushZ = par1NBTTagCompound.getDouble("PushZ"); + this.fuel = par1NBTTagCompound.getShort("Fuel"); + } + + protected boolean isMinecartPowered() { + return (this.dataWatcher.getWatchableObjectByte(16) & 1) != 0; + } + + protected void setMinecartPowered(boolean par1) { + if (par1) { + this.dataWatcher.updateObject(16, Byte.valueOf((byte) (this.dataWatcher.getWatchableObjectByte(16) | 1))); + } else { + this.dataWatcher.updateObject(16, Byte.valueOf((byte) (this.dataWatcher.getWatchableObjectByte(16) & -2))); + } + } + + public Block getDefaultDisplayTile() { + return Block.furnaceBurning; + } + + public int getDefaultDisplayTileData() { + return 2; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityMinecartHopper.java b/sp-server/src/main/java/net/minecraft/src/EntityMinecartHopper.java new file mode 100644 index 0000000..592044a --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityMinecartHopper.java @@ -0,0 +1,172 @@ +package net.minecraft.src; + +import java.util.List; + +public class EntityMinecartHopper extends EntityMinecartContainer implements Hopper { + /** Whether this hopper minecart is being blocked by an activator rail. */ + private boolean isBlocked = true; + private int transferTicker = -1; + + public EntityMinecartHopper(World par1World) { + super(par1World); + } + + public EntityMinecartHopper(World par1World, double par2, double par4, double par6) { + super(par1World, par2, par4, par6); + } + + public int getMinecartType() { + return 5; + } + + public Block getDefaultDisplayTile() { + return Block.hopperBlock; + } + + public int getDefaultDisplayTileOffset() { + return 1; + } + + /** + * Returns the number of slots in the inventory. + */ + public int getSizeInventory() { + return 5; + } + + /** + * Called when a player interacts with a mob. e.g. gets milk from a cow, gets + * into the saddle on a pig. + */ + public boolean interact(EntityPlayer par1EntityPlayer) { + if (!this.worldObj.isRemote) { + par1EntityPlayer.displayGUIHopperMinecart(this); + } + + return true; + } + + /** + * Called every tick the minecart is on an activator rail. Args: x, y, z, is the + * rail receiving power + */ + public void onActivatorRailPass(int par1, int par2, int par3, boolean par4) { + boolean var5 = !par4; + + if (var5 != this.getBlocked()) { + this.setBlocked(var5); + } + } + + /** + * Get whether this hopper minecart is being blocked by an activator rail. + */ + public boolean getBlocked() { + return this.isBlocked; + } + + /** + * Set whether this hopper minecart is being blocked by an activator rail. + */ + public void setBlocked(boolean par1) { + this.isBlocked = par1; + } + + /** + * Returns the worldObj for this tileEntity. + */ + public World getWorldObj() { + return this.worldObj; + } + + /** + * Gets the world X position for this hopper entity. + */ + public double getXPos() { + return this.posX; + } + + /** + * Gets the world Y position for this hopper entity. + */ + public double getYPos() { + return this.posY; + } + + /** + * Gets the world Z position for this hopper entity. + */ + public double getZPos() { + return this.posZ; + } + + /** + * Called to update the entity's position/logic. + */ + public void onUpdate() { + super.onUpdate(); + + if (!this.worldObj.isRemote && this.isEntityAlive() && this.getBlocked()) { + --this.transferTicker; + + if (!this.canTransfer()) { + this.setTransferTicker(0); + + if (this.func_96112_aD()) { + this.setTransferTicker(4); + this.onInventoryChanged(); + } + } + } + } + + public boolean func_96112_aD() { + if (TileEntityHopper.suckItemsIntoHopper(this)) { + return true; + } else { + List var1 = this.worldObj.selectEntitiesWithinAABB(EntityItem.class, + this.boundingBox.expand(0.25D, 0.0D, 0.25D), IEntitySelector.selectAnything); + + if (var1.size() > 0) { + TileEntityHopper.func_96114_a(this, (EntityItem) var1.get(0)); + } + + return false; + } + } + + public void killMinecart(DamageSource par1DamageSource) { + super.killMinecart(par1DamageSource); + this.dropItemWithOffset(Block.hopperBlock.blockID, 1, 0.0F); + } + + /** + * (abstract) Protected helper method to write subclass entity data to NBT. + */ + protected void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) { + super.writeEntityToNBT(par1NBTTagCompound); + par1NBTTagCompound.setInteger("TransferCooldown", this.transferTicker); + } + + /** + * (abstract) Protected helper method to read subclass entity data from NBT. + */ + protected void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) { + super.readEntityFromNBT(par1NBTTagCompound); + this.transferTicker = par1NBTTagCompound.getInteger("TransferCooldown"); + } + + /** + * Sets the transfer ticker, used to determine the delay between transfers. + */ + public void setTransferTicker(int par1) { + this.transferTicker = par1; + } + + /** + * Returns whether the hopper cart can currently transfer an item. + */ + public boolean canTransfer() { + return this.transferTicker > 0; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityMinecartMobSpawner.java b/sp-server/src/main/java/net/minecraft/src/EntityMinecartMobSpawner.java new file mode 100644 index 0000000..8276dcb --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityMinecartMobSpawner.java @@ -0,0 +1,46 @@ +package net.minecraft.src; + +public class EntityMinecartMobSpawner extends EntityMinecart { + /** Mob spawner logic for this spawner minecart. */ + private final MobSpawnerBaseLogic mobSpawnerLogic = new EntityMinecartMobSpawnerLogic(this); + + public EntityMinecartMobSpawner(World par1World) { + super(par1World); + } + + public EntityMinecartMobSpawner(World par1World, double par2, double par4, double par6) { + super(par1World, par2, par4, par6); + } + + public int getMinecartType() { + return 4; + } + + public Block getDefaultDisplayTile() { + return Block.mobSpawner; + } + + /** + * (abstract) Protected helper method to read subclass entity data from NBT. + */ + protected void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) { + super.readEntityFromNBT(par1NBTTagCompound); + this.mobSpawnerLogic.readFromNBT(par1NBTTagCompound); + } + + /** + * (abstract) Protected helper method to write subclass entity data to NBT. + */ + protected void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) { + super.writeEntityToNBT(par1NBTTagCompound); + this.mobSpawnerLogic.writeToNBT(par1NBTTagCompound); + } + + /** + * Called to update the entity's position/logic. + */ + public void onUpdate() { + super.onUpdate(); + this.mobSpawnerLogic.updateSpawner(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityMinecartMobSpawnerLogic.java b/sp-server/src/main/java/net/minecraft/src/EntityMinecartMobSpawnerLogic.java new file mode 100644 index 0000000..ff71e7e --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityMinecartMobSpawnerLogic.java @@ -0,0 +1,30 @@ +package net.minecraft.src; + +class EntityMinecartMobSpawnerLogic extends MobSpawnerBaseLogic { + /** The spawner minecart using this mob spawner logic. */ + final EntityMinecartMobSpawner spawnerMinecart; + + EntityMinecartMobSpawnerLogic(EntityMinecartMobSpawner par1EntityMinecartMobSpawner) { + this.spawnerMinecart = par1EntityMinecartMobSpawner; + } + + public void func_98267_a(int par1) { + this.spawnerMinecart.worldObj.setEntityState(this.spawnerMinecart, (byte) par1); + } + + public World getSpawnerWorld() { + return this.spawnerMinecart.worldObj; + } + + public int getSpawnerX() { + return MathHelper.floor_double(this.spawnerMinecart.posX); + } + + public int getSpawnerY() { + return MathHelper.floor_double(this.spawnerMinecart.posY); + } + + public int getSpawnerZ() { + return MathHelper.floor_double(this.spawnerMinecart.posZ); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityMinecartTNT.java b/sp-server/src/main/java/net/minecraft/src/EntityMinecartTNT.java new file mode 100644 index 0000000..bc35bf2 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityMinecartTNT.java @@ -0,0 +1,147 @@ +package net.minecraft.src; + +public class EntityMinecartTNT extends EntityMinecart { + private int minecartTNTFuse = -1; + + public EntityMinecartTNT(World par1) { + super(par1); + } + + public EntityMinecartTNT(World par1, double par2, double par4, double par6) { + super(par1, par2, par4, par6); + } + + public int getMinecartType() { + return 3; + } + + public Block getDefaultDisplayTile() { + return Block.tnt; + } + + /** + * Called to update the entity's position/logic. + */ + public void onUpdate() { + super.onUpdate(); + + if (this.minecartTNTFuse > 0) { + --this.minecartTNTFuse; + this.worldObj.spawnParticle("smoke", this.posX, this.posY + 0.5D, this.posZ, 0.0D, 0.0D, 0.0D); + } else if (this.minecartTNTFuse == 0) { + this.explodeCart(this.motionX * this.motionX + this.motionZ * this.motionZ); + } + + if (this.isCollidedHorizontally) { + double var1 = this.motionX * this.motionX + this.motionZ * this.motionZ; + + if (var1 >= 0.009999999776482582D) { + this.explodeCart(var1); + } + } + } + + public void killMinecart(DamageSource par1DamageSource) { + super.killMinecart(par1DamageSource); + double var2 = this.motionX * this.motionX + this.motionZ * this.motionZ; + + if (!par1DamageSource.isExplosion()) { + this.entityDropItem(new ItemStack(Block.tnt, 1), 0.0F); + } + + if (par1DamageSource.isFireDamage() || par1DamageSource.isExplosion() || var2 >= 0.009999999776482582D) { + this.explodeCart(var2); + } + } + + /** + * Makes the minecart explode. + */ + protected void explodeCart(double par1) { + if (!this.worldObj.isRemote) { + double var3 = Math.sqrt(par1); + + if (var3 > 5.0D) { + var3 = 5.0D; + } + + this.worldObj.createExplosion(this, this.posX, this.posY, this.posZ, + (float) (4.0D + this.rand.nextDouble() * 1.5D * var3), true); + this.setDead(); + } + } + + /** + * Called when the mob is falling. Calculates and applies fall damage. + */ + protected void fall(float par1) { + if (par1 >= 3.0F) { + float var2 = par1 / 10.0F; + this.explodeCart((double) (var2 * var2)); + } + + super.fall(par1); + } + + /** + * Called every tick the minecart is on an activator rail. Args: x, y, z, is the + * rail receiving power + */ + public void onActivatorRailPass(int par1, int par2, int par3, boolean par4) { + if (par4 && this.minecartTNTFuse < 0) { + this.ignite(); + } + } + + /** + * Ignites this TNT cart. + */ + public void ignite() { + this.minecartTNTFuse = 80; + + if (!this.worldObj.isRemote) { + this.worldObj.setEntityState(this, (byte) 10); + this.worldObj.playSoundAtEntity(this, "random.fuse", 1.0F, 1.0F); + } + } + + /** + * Returns true if the TNT minecart is ignited. + */ + public boolean isIgnited() { + return this.minecartTNTFuse > -1; + } + + public float func_82146_a(Explosion par1Explosion, World par2World, int par3, int par4, int par5, Block par6Block) { + return this.isIgnited() && (BlockRailBase.isRailBlock(par6Block.blockID) + || BlockRailBase.isRailBlockAt(par2World, par3, par4 + 1, par5)) ? 0.0F + : super.func_82146_a(par1Explosion, par2World, par3, par4, par5, par6Block); + } + + public boolean func_96091_a(Explosion par1Explosion, World par2World, int par3, int par4, int par5, int par6, + float par7) { + return this.isIgnited() + && (BlockRailBase.isRailBlock(par6) || BlockRailBase.isRailBlockAt(par2World, par3, par4 + 1, par5)) + ? false + : super.func_96091_a(par1Explosion, par2World, par3, par4, par5, par6, par7); + } + + /** + * (abstract) Protected helper method to read subclass entity data from NBT. + */ + protected void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) { + super.readEntityFromNBT(par1NBTTagCompound); + + if (par1NBTTagCompound.hasKey("TNTFuse")) { + this.minecartTNTFuse = par1NBTTagCompound.getInteger("TNTFuse"); + } + } + + /** + * (abstract) Protected helper method to write subclass entity data to NBT. + */ + protected void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) { + super.writeEntityToNBT(par1NBTTagCompound); + par1NBTTagCompound.setInteger("TNTFuse", this.minecartTNTFuse); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityMob.java b/sp-server/src/main/java/net/minecraft/src/EntityMob.java new file mode 100644 index 0000000..25b3a46 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityMob.java @@ -0,0 +1,170 @@ +package net.minecraft.src; + +public abstract class EntityMob extends EntityCreature implements IMob { + public EntityMob(World par1World) { + super(par1World); + this.experienceValue = 5; + } + + /** + * Called frequently so the entity can update its state every tick as required. + * For example, zombies and skeletons use this to react to sunlight and start to + * burn. + */ + public void onLivingUpdate() { + this.updateArmSwingProgress(); + float var1 = this.getBrightness(1.0F); + + if (var1 > 0.5F) { + this.entityAge += 2; + } + + super.onLivingUpdate(); + } + + /** + * Called to update the entity's position/logic. + */ + public void onUpdate() { + super.onUpdate(); + + if (!this.worldObj.isRemote && this.worldObj.difficultySetting == 0) { + this.setDead(); + } + } + + /** + * Finds the closest player within 16 blocks to attack, or null if this Entity + * isn't interested in attacking (Animals, Spiders at day, peaceful PigZombies). + */ + protected Entity findPlayerToAttack() { + EntityPlayer var1 = this.worldObj.getClosestVulnerablePlayerToEntity(this, 16.0D); + return var1 != null && this.canEntityBeSeen(var1) ? var1 : null; + } + + /** + * Called when the entity is attacked. + */ + public boolean attackEntityFrom(DamageSource par1DamageSource, int par2) { + if (this.isEntityInvulnerable()) { + return false; + } else if (super.attackEntityFrom(par1DamageSource, par2)) { + Entity var3 = par1DamageSource.getEntity(); + + if (this.riddenByEntity != var3 && this.ridingEntity != var3) { + if (var3 != this) { + this.entityToAttack = var3; + } + + return true; + } else { + return true; + } + } else { + return false; + } + } + + public boolean attackEntityAsMob(Entity par1Entity) { + int var2 = this.getAttackStrength(par1Entity); + + if (this.isPotionActive(Potion.damageBoost)) { + var2 += 3 << this.getActivePotionEffect(Potion.damageBoost).getAmplifier(); + } + + if (this.isPotionActive(Potion.weakness)) { + var2 -= 2 << this.getActivePotionEffect(Potion.weakness).getAmplifier(); + } + + int var3 = 0; + + if (par1Entity instanceof EntityLiving) { + var2 += EnchantmentHelper.getEnchantmentModifierLiving(this, (EntityLiving) par1Entity); + var3 += EnchantmentHelper.getKnockbackModifier(this, (EntityLiving) par1Entity); + } + + boolean var4 = par1Entity.attackEntityFrom(DamageSource.causeMobDamage(this), var2); + + if (var4) { + if (var3 > 0) { + par1Entity.addVelocity( + (double) (-MathHelper.sin(this.rotationYaw * (float) Math.PI / 180.0F) * (float) var3 * 0.5F), + 0.1D, + (double) (MathHelper.cos(this.rotationYaw * (float) Math.PI / 180.0F) * (float) var3 * 0.5F)); + this.motionX *= 0.6D; + this.motionZ *= 0.6D; + } + + int var5 = EnchantmentHelper.getFireAspectModifier(this); + + if (var5 > 0) { + par1Entity.setFire(var5 * 4); + } + + if (par1Entity instanceof EntityLiving) { + EnchantmentThorns.func_92096_a(this, (EntityLiving) par1Entity, this.rand); + } + } + + return var4; + } + + /** + * Basic mob attack. Default to touch of death in EntityCreature. Overridden by + * each mob to define their attack. + */ + protected void attackEntity(Entity par1Entity, float par2) { + if (this.attackTime <= 0 && par2 < 2.0F && par1Entity.boundingBox.maxY > this.boundingBox.minY + && par1Entity.boundingBox.minY < this.boundingBox.maxY) { + this.attackTime = 20; + this.attackEntityAsMob(par1Entity); + } + } + + /** + * Takes a coordinate in and returns a weight to determine how likely this + * creature will try to path to the block. Args: x, y, z + */ + public float getBlockPathWeight(int par1, int par2, int par3) { + return 0.5F - this.worldObj.getLightBrightness(par1, par2, par3); + } + + /** + * Checks to make sure the light is not too bright where the mob is spawning + */ + protected boolean isValidLightLevel() { + int var1 = MathHelper.floor_double(this.posX); + int var2 = MathHelper.floor_double(this.boundingBox.minY); + int var3 = MathHelper.floor_double(this.posZ); + + if (this.worldObj.getSavedLightValue(EnumSkyBlock.Sky, var1, var2, var3) > this.rand.nextInt(32)) { + return false; + } else { + int var4 = this.worldObj.getBlockLightValue(var1, var2, var3); + + if (this.worldObj.isThundering()) { + int var5 = this.worldObj.skylightSubtracted; + this.worldObj.skylightSubtracted = 10; + var4 = this.worldObj.getBlockLightValue(var1, var2, var3); + this.worldObj.skylightSubtracted = var5; + } + + return var4 <= this.rand.nextInt(8); + } + } + + /** + * Checks if the entity's current position is a valid location to spawn this + * entity. + */ + public boolean getCanSpawnHere() { + return this.isValidLightLevel() && super.getCanSpawnHere(); + } + + /** + * Returns the amount of damage a mob should deal. + */ + public int getAttackStrength(Entity par1Entity) { + return 2; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityMooshroom.java b/sp-server/src/main/java/net/minecraft/src/EntityMooshroom.java new file mode 100644 index 0000000..55d9552 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityMooshroom.java @@ -0,0 +1,70 @@ +package net.minecraft.src; + +public class EntityMooshroom extends EntityCow { + public EntityMooshroom(World par1World) { + super(par1World); + this.texture = "/mob/redcow.png"; + this.setSize(0.9F, 1.3F); + } + + /** + * Called when a player interacts with a mob. e.g. gets milk from a cow, gets + * into the saddle on a pig. + */ + public boolean interact(EntityPlayer par1EntityPlayer) { + ItemStack var2 = par1EntityPlayer.inventory.getCurrentItem(); + + if (var2 != null && var2.itemID == Item.bowlEmpty.itemID && this.getGrowingAge() >= 0) { + if (var2.stackSize == 1) { + par1EntityPlayer.inventory.setInventorySlotContents(par1EntityPlayer.inventory.currentItem, + new ItemStack(Item.bowlSoup)); + return true; + } + + if (par1EntityPlayer.inventory.addItemStackToInventory(new ItemStack(Item.bowlSoup)) + && !par1EntityPlayer.capabilities.isCreativeMode) { + par1EntityPlayer.inventory.decrStackSize(par1EntityPlayer.inventory.currentItem, 1); + return true; + } + } + + if (var2 != null && var2.itemID == Item.shears.itemID && this.getGrowingAge() >= 0) { + this.setDead(); + this.worldObj.spawnParticle("largeexplode", this.posX, this.posY + (double) (this.height / 2.0F), this.posZ, + 0.0D, 0.0D, 0.0D); + + if (!this.worldObj.isRemote) { + EntityCow var3 = new EntityCow(this.worldObj); + var3.setLocationAndAngles(this.posX, this.posY, this.posZ, this.rotationYaw, this.rotationPitch); + var3.setEntityHealth(this.getHealth()); + var3.renderYawOffset = this.renderYawOffset; + this.worldObj.spawnEntityInWorld(var3); + + for (int var4 = 0; var4 < 5; ++var4) { + this.worldObj.spawnEntityInWorld(new EntityItem(this.worldObj, this.posX, + this.posY + (double) this.height, this.posZ, new ItemStack(Block.mushroomRed))); + } + } + + return true; + } else { + return super.interact(par1EntityPlayer); + } + } + + public EntityMooshroom func_94900_c(EntityAgeable par1EntityAgeable) { + return new EntityMooshroom(this.worldObj); + } + + /** + * This function is used when two same-species animals in 'love mode' breed to + * generate the new baby animal. + */ + public EntityCow spawnBabyAnimal(EntityAgeable par1EntityAgeable) { + return this.func_94900_c(par1EntityAgeable); + } + + public EntityAgeable createChild(EntityAgeable par1EntityAgeable) { + return this.func_94900_c(par1EntityAgeable); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityMoveHelper.java b/sp-server/src/main/java/net/minecraft/src/EntityMoveHelper.java new file mode 100644 index 0000000..64fec06 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityMoveHelper.java @@ -0,0 +1,79 @@ +package net.minecraft.src; + +public class EntityMoveHelper { + /** The EntityLiving that is being moved */ + private EntityLiving entity; + private double posX; + private double posY; + private double posZ; + + /** The speed at which the entity should move */ + private float speed; + private boolean update = false; + + public EntityMoveHelper(EntityLiving par1EntityLiving) { + this.entity = par1EntityLiving; + this.posX = par1EntityLiving.posX; + this.posY = par1EntityLiving.posY; + this.posZ = par1EntityLiving.posZ; + } + + public boolean isUpdating() { + return this.update; + } + + public float getSpeed() { + return this.speed; + } + + /** + * Sets the speed and location to move to + */ + public void setMoveTo(double par1, double par3, double par5, float par7) { + this.posX = par1; + this.posY = par3; + this.posZ = par5; + this.speed = par7; + this.update = true; + } + + public void onUpdateMoveHelper() { + this.entity.setMoveForward(0.0F); + + if (this.update) { + this.update = false; + int var1 = MathHelper.floor_double(this.entity.boundingBox.minY + 0.5D); + double var2 = this.posX - this.entity.posX; + double var4 = this.posZ - this.entity.posZ; + double var6 = this.posY - (double) var1; + double var8 = var2 * var2 + var6 * var6 + var4 * var4; + + if (var8 >= 2.500000277905201E-7D) { + float var10 = (float) (Math.atan2(var4, var2) * 180.0D / Math.PI) - 90.0F; + this.entity.rotationYaw = this.limitAngle(this.entity.rotationYaw, var10, 30.0F); + this.entity.setAIMoveSpeed(this.speed * this.entity.getSpeedModifier()); + + if (var6 > 0.0D && var2 * var2 + var4 * var4 < 1.0D) { + this.entity.getJumpHelper().setJumping(); + } + } + } + } + + /** + * Limits the given angle to a upper and lower limit. + */ + private float limitAngle(float par1, float par2, float par3) { + float var4 = MathHelper.wrapAngleTo180_float(par2 - par1); + + if (var4 > par3) { + var4 = par3; + } + + if (var4 < -par3) { + var4 = -par3; + } + + return par1 + var4; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityOcelot.java b/sp-server/src/main/java/net/minecraft/src/EntityOcelot.java new file mode 100644 index 0000000..e7ed760 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityOcelot.java @@ -0,0 +1,301 @@ +package net.minecraft.src; + +public class EntityOcelot extends EntityTameable { + /** + * The tempt AI task for this mob, used to prevent taming while it is fleeing. + */ + private EntityAITempt aiTempt; + + public EntityOcelot(World par1World) { + super(par1World); + this.texture = "/mob/ozelot.png"; + this.setSize(0.6F, 0.8F); + this.getNavigator().setAvoidsWater(true); + this.tasks.addTask(1, new EntityAISwimming(this)); + this.tasks.addTask(2, this.aiSit); + this.tasks.addTask(3, this.aiTempt = new EntityAITempt(this, 0.18F, Item.fishRaw.itemID, true)); + this.tasks.addTask(4, new EntityAIAvoidEntity(this, EntityPlayer.class, 16.0F, 0.23F, 0.4F)); + this.tasks.addTask(5, new EntityAIFollowOwner(this, 0.3F, 10.0F, 5.0F)); + this.tasks.addTask(6, new EntityAIOcelotSit(this, 0.4F)); + this.tasks.addTask(7, new EntityAILeapAtTarget(this, 0.3F)); + this.tasks.addTask(8, new EntityAIOcelotAttack(this)); + this.tasks.addTask(9, new EntityAIMate(this, 0.23F)); + this.tasks.addTask(10, new EntityAIWander(this, 0.23F)); + this.tasks.addTask(11, new EntityAIWatchClosest(this, EntityPlayer.class, 10.0F)); + this.targetTasks.addTask(1, new EntityAITargetNonTamed(this, EntityChicken.class, 14.0F, 750, false)); + } + + protected void entityInit() { + super.entityInit(); + this.dataWatcher.addObject(18, Byte.valueOf((byte) 0)); + } + + /** + * main AI tick function, replaces updateEntityActionState + */ + public void updateAITick() { + if (this.getMoveHelper().isUpdating()) { + float var1 = this.getMoveHelper().getSpeed(); + + if (var1 == 0.18F) { + this.setSneaking(true); + this.setSprinting(false); + } else if (var1 == 0.4F) { + this.setSneaking(false); + this.setSprinting(true); + } else { + this.setSneaking(false); + this.setSprinting(false); + } + } else { + this.setSneaking(false); + this.setSprinting(false); + } + } + + /** + * Determines if an entity can be despawned, used on idle far away entities + */ + protected boolean canDespawn() { + return !this.isTamed(); + } + + /** + * Returns true if the newer Entity AI code should be run + */ + public boolean isAIEnabled() { + return true; + } + + public int getMaxHealth() { + return 10; + } + + /** + * Called when the mob is falling. Calculates and applies fall damage. + */ + protected void fall(float par1) { + } + + /** + * (abstract) Protected helper method to write subclass entity data to NBT. + */ + public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) { + super.writeEntityToNBT(par1NBTTagCompound); + par1NBTTagCompound.setInteger("CatType", this.getTameSkin()); + } + + /** + * (abstract) Protected helper method to read subclass entity data from NBT. + */ + public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) { + super.readEntityFromNBT(par1NBTTagCompound); + this.setTameSkin(par1NBTTagCompound.getInteger("CatType")); + } + + /** + * Returns the sound this mob makes while it's alive. + */ + protected String getLivingSound() { + return this.isTamed() + ? (this.isInLove() ? "mob.cat.purr" : (this.rand.nextInt(4) == 0 ? "mob.cat.purreow" : "mob.cat.meow")) + : ""; + } + + /** + * Returns the sound this mob makes when it is hurt. + */ + protected String getHurtSound() { + return "mob.cat.hitt"; + } + + /** + * Returns the sound this mob makes on death. + */ + protected String getDeathSound() { + return "mob.cat.hitt"; + } + + /** + * Returns the volume for the sounds this mob makes. + */ + protected float getSoundVolume() { + return 0.4F; + } + + /** + * Returns the item ID for the item the mob drops on death. + */ + protected int getDropItemId() { + return Item.leather.itemID; + } + + public boolean attackEntityAsMob(Entity par1Entity) { + return par1Entity.attackEntityFrom(DamageSource.causeMobDamage(this), 3); + } + + /** + * Called when the entity is attacked. + */ + public boolean attackEntityFrom(DamageSource par1DamageSource, int par2) { + if (this.isEntityInvulnerable()) { + return false; + } else { + this.aiSit.setSitting(false); + return super.attackEntityFrom(par1DamageSource, par2); + } + } + + /** + * Drop 0-2 items of this living's type + */ + protected void dropFewItems(boolean par1, int par2) { + } + + /** + * Called when a player interacts with a mob. e.g. gets milk from a cow, gets + * into the saddle on a pig. + */ + public boolean interact(EntityPlayer par1EntityPlayer) { + ItemStack var2 = par1EntityPlayer.inventory.getCurrentItem(); + + if (this.isTamed()) { + if (par1EntityPlayer.username.equalsIgnoreCase(this.getOwnerName()) && !this.worldObj.isRemote + && !this.isBreedingItem(var2)) { + this.aiSit.setSitting(!this.isSitting()); + } + } else if (this.aiTempt.func_75277_f() && var2 != null && var2.itemID == Item.fishRaw.itemID + && par1EntityPlayer.getDistanceSqToEntity(this) < 9.0D) { + if (!par1EntityPlayer.capabilities.isCreativeMode) { + --var2.stackSize; + } + + if (var2.stackSize <= 0) { + par1EntityPlayer.inventory.setInventorySlotContents(par1EntityPlayer.inventory.currentItem, + (ItemStack) null); + } + + if (!this.worldObj.isRemote) { + if (this.rand.nextInt(3) == 0) { + this.setTamed(true); + this.setTameSkin(1 + this.worldObj.rand.nextInt(3)); + this.setOwner(par1EntityPlayer.username); + this.playTameEffect(true); + this.aiSit.setSitting(true); + this.worldObj.setEntityState(this, (byte) 7); + } else { + this.playTameEffect(false); + this.worldObj.setEntityState(this, (byte) 6); + } + } + + return true; + } + + return super.interact(par1EntityPlayer); + } + + /** + * This function is used when two same-species animals in 'love mode' breed to + * generate the new baby animal. + */ + public EntityOcelot spawnBabyAnimal(EntityAgeable par1EntityAgeable) { + EntityOcelot var2 = new EntityOcelot(this.worldObj); + + if (this.isTamed()) { + var2.setOwner(this.getOwnerName()); + var2.setTamed(true); + var2.setTameSkin(this.getTameSkin()); + } + + return var2; + } + + /** + * Checks if the parameter is an item which this animal can be fed to breed it + * (wheat, carrots or seeds depending on the animal type) + */ + public boolean isBreedingItem(ItemStack par1ItemStack) { + return par1ItemStack != null && par1ItemStack.itemID == Item.fishRaw.itemID; + } + + /** + * Returns true if the mob is currently able to mate with the specified mob. + */ + public boolean canMateWith(EntityAnimal par1EntityAnimal) { + if (par1EntityAnimal == this) { + return false; + } else if (!this.isTamed()) { + return false; + } else if (!(par1EntityAnimal instanceof EntityOcelot)) { + return false; + } else { + EntityOcelot var2 = (EntityOcelot) par1EntityAnimal; + return !var2.isTamed() ? false : this.isInLove() && var2.isInLove(); + } + } + + public int getTameSkin() { + return this.dataWatcher.getWatchableObjectByte(18); + } + + public void setTameSkin(int par1) { + this.dataWatcher.updateObject(18, Byte.valueOf((byte) par1)); + } + + /** + * Checks if the entity's current position is a valid location to spawn this + * entity. + */ + public boolean getCanSpawnHere() { + if (this.worldObj.rand.nextInt(3) == 0) { + return false; + } else { + if (this.worldObj.checkNoEntityCollision(this.boundingBox) + && this.worldObj.getCollidingBoundingBoxes(this, this.boundingBox).isEmpty() + && !this.worldObj.isAnyLiquid(this.boundingBox)) { + int var1 = MathHelper.floor_double(this.posX); + int var2 = MathHelper.floor_double(this.boundingBox.minY); + int var3 = MathHelper.floor_double(this.posZ); + + if (var2 < 63) { + return false; + } + + int var4 = this.worldObj.getBlockId(var1, var2 - 1, var3); + + if (var4 == Block.grass.blockID || var4 == Block.leaves.blockID) { + return true; + } + } + + return false; + } + } + + /** + * Gets the username of the entity. + */ + public String getEntityName() { + return this.func_94056_bM() ? this.func_94057_bL() + : (this.isTamed() ? "entity.Cat.name" : super.getEntityName()); + } + + /** + * Initialize this creature. + */ + public void initCreature() { + if (this.worldObj.rand.nextInt(7) == 0) { + for (int var1 = 0; var1 < 2; ++var1) { + EntityOcelot var2 = new EntityOcelot(this.worldObj); + var2.setLocationAndAngles(this.posX, this.posY, this.posZ, this.rotationYaw, 0.0F); + var2.setGrowingAge(-24000); + this.worldObj.spawnEntityInWorld(var2); + } + } + } + + public EntityAgeable createChild(EntityAgeable par1EntityAgeable) { + return this.spawnBabyAnimal(par1EntityAgeable); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityPainting.java b/sp-server/src/main/java/net/minecraft/src/EntityPainting.java new file mode 100644 index 0000000..879ab62 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityPainting.java @@ -0,0 +1,80 @@ +package net.minecraft.src; + +import java.util.ArrayList; + +public class EntityPainting extends EntityHanging { + public EnumArt art; + + public EntityPainting(World par1World) { + super(par1World); + } + + public EntityPainting(World par1World, int par2, int par3, int par4, int par5) { + super(par1World, par2, par3, par4, par5); + ArrayList var6 = new ArrayList(); + EnumArt[] var7 = EnumArt.values(); + int var8 = var7.length; + + for (int var9 = 0; var9 < var8; ++var9) { + EnumArt var10 = var7[var9]; + this.art = var10; + this.setDirection(par5); + + if (this.onValidSurface()) { + var6.add(var10); + } + } + + if (!var6.isEmpty()) { + this.art = (EnumArt) var6.get(this.rand.nextInt(var6.size())); + } + + this.setDirection(par5); + } + + /** + * (abstract) Protected helper method to write subclass entity data to NBT. + */ + public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) { + par1NBTTagCompound.setString("Motive", this.art.title); + super.writeEntityToNBT(par1NBTTagCompound); + } + + /** + * (abstract) Protected helper method to read subclass entity data from NBT. + */ + public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) { + String var2 = par1NBTTagCompound.getString("Motive"); + EnumArt[] var3 = EnumArt.values(); + int var4 = var3.length; + + for (int var5 = 0; var5 < var4; ++var5) { + EnumArt var6 = var3[var5]; + + if (var6.title.equals(var2)) { + this.art = var6; + } + } + + if (this.art == null) { + this.art = EnumArt.Kebab; + } + + super.readEntityFromNBT(par1NBTTagCompound); + } + + public int func_82329_d() { + return this.art.sizeX; + } + + public int func_82330_g() { + return this.art.sizeY; + } + + /** + * Drop the item currently on this item frame. + */ + public void dropItemStack() { + this.entityDropItem(new ItemStack(Item.painting), 0.0F); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityPig.java b/sp-server/src/main/java/net/minecraft/src/EntityPig.java new file mode 100644 index 0000000..6f35887 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityPig.java @@ -0,0 +1,208 @@ +package net.minecraft.src; + +public class EntityPig extends EntityAnimal { + /** AI task for player control. */ + private final EntityAIControlledByPlayer aiControlledByPlayer; + + public EntityPig(World par1World) { + super(par1World); + this.texture = "/mob/pig.png"; + this.setSize(0.9F, 0.9F); + this.getNavigator().setAvoidsWater(true); + float var2 = 0.25F; + this.tasks.addTask(0, new EntityAISwimming(this)); + this.tasks.addTask(1, new EntityAIPanic(this, 0.38F)); + this.tasks.addTask(2, this.aiControlledByPlayer = new EntityAIControlledByPlayer(this, 0.34F)); + this.tasks.addTask(3, new EntityAIMate(this, var2)); + this.tasks.addTask(4, new EntityAITempt(this, 0.3F, Item.carrotOnAStick.itemID, false)); + this.tasks.addTask(4, new EntityAITempt(this, 0.3F, Item.carrot.itemID, false)); + this.tasks.addTask(5, new EntityAIFollowParent(this, 0.28F)); + this.tasks.addTask(6, new EntityAIWander(this, var2)); + this.tasks.addTask(7, new EntityAIWatchClosest(this, EntityPlayer.class, 6.0F)); + this.tasks.addTask(8, new EntityAILookIdle(this)); + } + + /** + * Returns true if the newer Entity AI code should be run + */ + public boolean isAIEnabled() { + return true; + } + + public int getMaxHealth() { + return 10; + } + + protected void updateAITasks() { + super.updateAITasks(); + } + + /** + * returns true if all the conditions for steering the entity are met. For pigs, + * this is true if it is being ridden by a player and the player is holding a + * carrot-on-a-stick + */ + public boolean canBeSteered() { + ItemStack var1 = ((EntityPlayer) this.riddenByEntity).getHeldItem(); + return var1 != null && var1.itemID == Item.carrotOnAStick.itemID; + } + + protected void entityInit() { + super.entityInit(); + this.dataWatcher.addObject(16, Byte.valueOf((byte) 0)); + } + + /** + * (abstract) Protected helper method to write subclass entity data to NBT. + */ + public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) { + super.writeEntityToNBT(par1NBTTagCompound); + par1NBTTagCompound.setBoolean("Saddle", this.getSaddled()); + } + + /** + * (abstract) Protected helper method to read subclass entity data from NBT. + */ + public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) { + super.readEntityFromNBT(par1NBTTagCompound); + this.setSaddled(par1NBTTagCompound.getBoolean("Saddle")); + } + + /** + * Returns the sound this mob makes while it's alive. + */ + protected String getLivingSound() { + return "mob.pig.say"; + } + + /** + * Returns the sound this mob makes when it is hurt. + */ + protected String getHurtSound() { + return "mob.pig.say"; + } + + /** + * Returns the sound this mob makes on death. + */ + protected String getDeathSound() { + return "mob.pig.death"; + } + + /** + * Plays step sound at given x, y, z for the entity + */ + protected void playStepSound(int par1, int par2, int par3, int par4) { + this.playSound("mob.pig.step", 0.15F, 1.0F); + } + + /** + * Called when a player interacts with a mob. e.g. gets milk from a cow, gets + * into the saddle on a pig. + */ + public boolean interact(EntityPlayer par1EntityPlayer) { + if (super.interact(par1EntityPlayer)) { + return true; + } else if (this.getSaddled() && !this.worldObj.isRemote + && (this.riddenByEntity == null || this.riddenByEntity == par1EntityPlayer)) { + par1EntityPlayer.mountEntity(this); + return true; + } else { + return false; + } + } + + /** + * Returns the item ID for the item the mob drops on death. + */ + protected int getDropItemId() { + return this.isBurning() ? Item.porkCooked.itemID : Item.porkRaw.itemID; + } + + /** + * Drop 0-2 items of this living's type + */ + protected void dropFewItems(boolean par1, int par2) { + int var3 = this.rand.nextInt(3) + 1 + this.rand.nextInt(1 + par2); + + for (int var4 = 0; var4 < var3; ++var4) { + if (this.isBurning()) { + this.dropItem(Item.porkCooked.itemID, 1); + } else { + this.dropItem(Item.porkRaw.itemID, 1); + } + } + + if (this.getSaddled()) { + this.dropItem(Item.saddle.itemID, 1); + } + } + + /** + * Returns true if the pig is saddled. + */ + public boolean getSaddled() { + return (this.dataWatcher.getWatchableObjectByte(16) & 1) != 0; + } + + /** + * Set or remove the saddle of the pig. + */ + public void setSaddled(boolean par1) { + if (par1) { + this.dataWatcher.updateObject(16, Byte.valueOf((byte) 1)); + } else { + this.dataWatcher.updateObject(16, Byte.valueOf((byte) 0)); + } + } + + /** + * Called when a lightning bolt hits the entity. + */ + public void onStruckByLightning(EntityLightningBolt par1EntityLightningBolt) { + if (!this.worldObj.isRemote) { + EntityPigZombie var2 = new EntityPigZombie(this.worldObj); + var2.setLocationAndAngles(this.posX, this.posY, this.posZ, this.rotationYaw, this.rotationPitch); + this.worldObj.spawnEntityInWorld(var2); + this.setDead(); + } + } + + /** + * Called when the mob is falling. Calculates and applies fall damage. + */ + protected void fall(float par1) { + super.fall(par1); + + if (par1 > 5.0F && this.riddenByEntity instanceof EntityPlayer) { + ((EntityPlayer) this.riddenByEntity).triggerAchievement(AchievementList.flyPig); + } + } + + /** + * This function is used when two same-species animals in 'love mode' breed to + * generate the new baby animal. + */ + public EntityPig spawnBabyAnimal(EntityAgeable par1EntityAgeable) { + return new EntityPig(this.worldObj); + } + + /** + * Checks if the parameter is an item which this animal can be fed to breed it + * (wheat, carrots or seeds depending on the animal type) + */ + public boolean isBreedingItem(ItemStack par1ItemStack) { + return par1ItemStack != null && par1ItemStack.itemID == Item.carrot.itemID; + } + + /** + * Return the AI task for player control. + */ + public EntityAIControlledByPlayer getAIControlledByPlayer() { + return this.aiControlledByPlayer; + } + + public EntityAgeable createChild(EntityAgeable par1EntityAgeable) { + return this.spawnBabyAnimal(par1EntityAgeable); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityPigZombie.java b/sp-server/src/main/java/net/minecraft/src/EntityPigZombie.java new file mode 100644 index 0000000..d1574a0 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityPigZombie.java @@ -0,0 +1,199 @@ +package net.minecraft.src; + +import java.util.List; + +public class EntityPigZombie extends EntityZombie { + /** Above zero if this PigZombie is Angry. */ + private int angerLevel = 0; + + /** A random delay until this PigZombie next makes a sound. */ + private int randomSoundDelay = 0; + + public EntityPigZombie(World par1World) { + super(par1World); + this.texture = "/mob/pigzombie.png"; + this.moveSpeed = 0.5F; + this.isImmuneToFire = true; + } + + /** + * Returns true if the newer Entity AI code should be run + */ + protected boolean isAIEnabled() { + return false; + } + + /** + * Called to update the entity's position/logic. + */ + public void onUpdate() { + this.moveSpeed = this.entityToAttack != null ? 0.95F : 0.5F; + + if (this.randomSoundDelay > 0 && --this.randomSoundDelay == 0) { + this.playSound("mob.zombiepig.zpigangry", this.getSoundVolume() * 2.0F, + ((this.rand.nextFloat() - this.rand.nextFloat()) * 0.2F + 1.0F) * 1.8F); + } + + super.onUpdate(); + } + + /** + * Checks if the entity's current position is a valid location to spawn this + * entity. + */ + public boolean getCanSpawnHere() { + return this.worldObj.difficultySetting > 0 && this.worldObj.checkNoEntityCollision(this.boundingBox) + && this.worldObj.getCollidingBoundingBoxes(this, this.boundingBox).isEmpty() + && !this.worldObj.isAnyLiquid(this.boundingBox); + } + + /** + * (abstract) Protected helper method to write subclass entity data to NBT. + */ + public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) { + super.writeEntityToNBT(par1NBTTagCompound); + par1NBTTagCompound.setShort("Anger", (short) this.angerLevel); + } + + /** + * (abstract) Protected helper method to read subclass entity data from NBT. + */ + public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) { + super.readEntityFromNBT(par1NBTTagCompound); + this.angerLevel = par1NBTTagCompound.getShort("Anger"); + } + + /** + * Finds the closest player within 16 blocks to attack, or null if this Entity + * isn't interested in attacking (Animals, Spiders at day, peaceful PigZombies). + */ + protected Entity findPlayerToAttack() { + return this.angerLevel == 0 ? null : super.findPlayerToAttack(); + } + + /** + * Called when the entity is attacked. + */ + public boolean attackEntityFrom(DamageSource par1DamageSource, int par2) { + if (this.isEntityInvulnerable()) { + return false; + } else { + Entity var3 = par1DamageSource.getEntity(); + + if (var3 instanceof EntityPlayer) { + List var4 = this.worldObj.getEntitiesWithinAABBExcludingEntity(this, + this.boundingBox.expand(32.0D, 32.0D, 32.0D)); + + for (int var5 = 0; var5 < var4.size(); ++var5) { + Entity var6 = (Entity) var4.get(var5); + + if (var6 instanceof EntityPigZombie) { + EntityPigZombie var7 = (EntityPigZombie) var6; + var7.becomeAngryAt(var3); + } + } + + this.becomeAngryAt(var3); + } + + return super.attackEntityFrom(par1DamageSource, par2); + } + } + + /** + * Causes this PigZombie to become angry at the supplied Entity (which will be a + * player). + */ + private void becomeAngryAt(Entity par1Entity) { + this.entityToAttack = par1Entity; + this.angerLevel = 400 + this.rand.nextInt(400); + this.randomSoundDelay = this.rand.nextInt(40); + } + + /** + * Returns the sound this mob makes while it's alive. + */ + protected String getLivingSound() { + return "mob.zombiepig.zpig"; + } + + /** + * Returns the sound this mob makes when it is hurt. + */ + protected String getHurtSound() { + return "mob.zombiepig.zpighurt"; + } + + /** + * Returns the sound this mob makes on death. + */ + protected String getDeathSound() { + return "mob.zombiepig.zpigdeath"; + } + + /** + * Drop 0-2 items of this living's type + */ + protected void dropFewItems(boolean par1, int par2) { + int var3 = this.rand.nextInt(2 + par2); + int var4; + + for (var4 = 0; var4 < var3; ++var4) { + this.dropItem(Item.rottenFlesh.itemID, 1); + } + + var3 = this.rand.nextInt(2 + par2); + + for (var4 = 0; var4 < var3; ++var4) { + this.dropItem(Item.goldNugget.itemID, 1); + } + } + + /** + * Called when a player interacts with a mob. e.g. gets milk from a cow, gets + * into the saddle on a pig. + */ + public boolean interact(EntityPlayer par1EntityPlayer) { + return false; + } + + protected void dropRareDrop(int par1) { + this.dropItem(Item.ingotGold.itemID, 1); + } + + /** + * Returns the item ID for the item the mob drops on death. + */ + protected int getDropItemId() { + return Item.rottenFlesh.itemID; + } + + /** + * Makes entity wear random armor based on difficulty + */ + protected void addRandomArmor() { + this.setCurrentItemOrArmor(0, new ItemStack(Item.swordGold)); + } + + /** + * Initialize this creature. + */ + public void initCreature() { + super.initCreature(); + this.setVillager(false); + } + + /** + * Returns the amount of damage a mob should deal. + */ + public int getAttackStrength(Entity par1Entity) { + ItemStack var2 = this.getHeldItem(); + int var3 = 5; + + if (var2 != null) { + var3 += var2.getDamageVsEntity(this); + } + + return var3; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityPlayer.java b/sp-server/src/main/java/net/minecraft/src/EntityPlayer.java new file mode 100644 index 0000000..7270da9 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityPlayer.java @@ -0,0 +1,1798 @@ +package net.minecraft.src; + +import java.util.Collection; +import java.util.Iterator; +import java.util.List; + +public abstract class EntityPlayer extends EntityLiving implements ICommandSender { + /** Inventory of the player */ + public InventoryPlayer inventory = new InventoryPlayer(this); + private InventoryEnderChest theInventoryEnderChest = new InventoryEnderChest(); + + /** + * The Container for the player's inventory (which opens when they press E) + */ + public Container inventoryContainer; + + /** The Container the player has open. */ + public Container openContainer; + + /** The food object of the player, the general hunger logic. */ + protected FoodStats foodStats = new FoodStats(); + + /** + * Used to tell if the player pressed jump twice. If this is at 0 and it's + * pressed (And they are allowed to fly, as defined in the player's + * movementInput) it sets this to 7. If it's pressed and it's greater than 0 + * enable fly. + */ + protected int flyToggleTimer = 0; + public byte field_71098_bD = 0; + public float prevCameraYaw; + public float cameraYaw; + public String username; + + /** + * Used by EntityPlayer to prevent too many xp orbs from getting absorbed at + * once. + */ + public int xpCooldown = 0; + public double field_71091_bM; + public double field_71096_bN; + public double field_71097_bO; + public double field_71094_bP; + public double field_71095_bQ; + public double field_71085_bR; + + /** Boolean value indicating weather a player is sleeping or not */ + protected boolean sleeping; + + /** the current location of the player */ + public ChunkCoordinates playerLocation; + private int sleepTimer; + public float field_71079_bU; + public float field_71089_bV; + + /** holds the spawn chunk of the player */ + private ChunkCoordinates spawnChunk; + + /** + * Whether this player's spawn point is forced, preventing execution of bed + * checks. + */ + private boolean spawnForced; + + /** Holds the coordinate of the player when enter a minecraft to ride. */ + private ChunkCoordinates startMinecartRidingCoordinate; + + /** The player's capabilities. (See class PlayerCapabilities) */ + public PlayerCapabilities capabilities = new PlayerCapabilities(); + + /** The current experience level the player is on. */ + public int experienceLevel; + + /** + * The total amount of experience the player has. This also includes the amount + * of experience within their Experience Bar. + */ + public int experienceTotal; + + /** + * The current amount of experience the player has within their Experience Bar. + */ + public float experience; + + /** + * This is the item that is in use when the player is holding down the + * useItemButton (e.g., bow, food, sword) + */ + private ItemStack itemInUse; + + /** + * This field starts off equal to getMaxItemUseDuration and is decremented on + * each tick + */ + private int itemInUseCount; + protected float speedOnGround = 0.1F; + protected float speedInAir = 0.02F; + private int field_82249_h = 0; + + /** + * An instance of a fishing rod's hook. If this isn't null, the icon image of + * the fishing rod is slightly different + */ + public EntityFishHook fishEntity = null; + + public EntityPlayer(World par1World) { + super(par1World); + this.inventoryContainer = new ContainerPlayer(this.inventory, !par1World.isRemote, this); + this.openContainer = this.inventoryContainer; + this.yOffset = 1.62F; + ChunkCoordinates var2 = par1World.getSpawnPoint(); + this.setLocationAndAngles((double) var2.posX + 0.5D, (double) (var2.posY + 1), (double) var2.posZ + 0.5D, 0.0F, + 0.0F); + this.entityType = "humanoid"; + this.field_70741_aB = 180.0F; + this.fireResistance = 20; + this.texture = "/mob/char.png"; + } + + public int getMaxHealth() { + return 20; + } + + protected void entityInit() { + super.entityInit(); + this.dataWatcher.addObject(16, Byte.valueOf((byte) 0)); + this.dataWatcher.addObject(17, Byte.valueOf((byte) 0)); + this.dataWatcher.addObject(18, Integer.valueOf(0)); + } + + /** + * Checks if the entity is currently using an item (e.g., bow, food, sword) by + * holding down the useItemButton + */ + public boolean isUsingItem() { + return this.itemInUse != null; + } + + public void stopUsingItem() { + if (this.itemInUse != null) { + this.itemInUse.onPlayerStoppedUsing(this.worldObj, this, this.itemInUseCount); + } + + this.clearItemInUse(); + } + + public void clearItemInUse() { + this.itemInUse = null; + this.itemInUseCount = 0; + + if (!this.worldObj.isRemote) { + this.setEating(false); + } + } + + public boolean isBlocking() { + return this.isUsingItem() + && Item.itemsList[this.itemInUse.itemID].getItemUseAction(this.itemInUse) == EnumAction.block; + } + + /** + * Called to update the entity's position/logic. + */ + public void onUpdate() { + if (this.itemInUse != null) { + ItemStack var1 = this.inventory.getCurrentItem(); + + if (var1 == this.itemInUse) { + if (this.itemInUseCount <= 25 && this.itemInUseCount % 4 == 0) { + this.updateItemUse(var1, 5); + } + + if (--this.itemInUseCount == 0 && !this.worldObj.isRemote) { + this.onItemUseFinish(); + } + } else { + this.clearItemInUse(); + } + } + + if (this.xpCooldown > 0) { + --this.xpCooldown; + } + + if (this.isPlayerSleeping()) { + ++this.sleepTimer; + + if (this.sleepTimer > 100) { + this.sleepTimer = 100; + } + + if (!this.worldObj.isRemote) { + if (!this.isInBed()) { + this.wakeUpPlayer(true, true, false); + } else if (this.worldObj.isDaytime()) { + this.wakeUpPlayer(false, true, true); + } + } + } else if (this.sleepTimer > 0) { + ++this.sleepTimer; + + if (this.sleepTimer >= 110) { + this.sleepTimer = 0; + } + } + + super.onUpdate(); + + if (!this.worldObj.isRemote && this.openContainer != null && !this.openContainer.canInteractWith(this)) { + this.closeScreen(); + this.openContainer = this.inventoryContainer; + } + + if (this.isBurning() && this.capabilities.disableDamage) { + this.extinguish(); + } + + this.field_71091_bM = this.field_71094_bP; + this.field_71096_bN = this.field_71095_bQ; + this.field_71097_bO = this.field_71085_bR; + double var9 = this.posX - this.field_71094_bP; + double var3 = this.posY - this.field_71095_bQ; + double var5 = this.posZ - this.field_71085_bR; + double var7 = 10.0D; + + if (var9 > var7) { + this.field_71091_bM = this.field_71094_bP = this.posX; + } + + if (var5 > var7) { + this.field_71097_bO = this.field_71085_bR = this.posZ; + } + + if (var3 > var7) { + this.field_71096_bN = this.field_71095_bQ = this.posY; + } + + if (var9 < -var7) { + this.field_71091_bM = this.field_71094_bP = this.posX; + } + + if (var5 < -var7) { + this.field_71097_bO = this.field_71085_bR = this.posZ; + } + + if (var3 < -var7) { + this.field_71096_bN = this.field_71095_bQ = this.posY; + } + + this.field_71094_bP += var9 * 0.25D; + this.field_71085_bR += var5 * 0.25D; + this.field_71095_bQ += var3 * 0.25D; + this.addStat(StatList.minutesPlayedStat, 1); + + if (this.ridingEntity == null) { + this.startMinecartRidingCoordinate = null; + } + + if (!this.worldObj.isRemote) { + this.foodStats.onUpdate(this); + } + } + + /** + * Return the amount of time this entity should stay in a portal before being + * transported. + */ + public int getMaxInPortalTime() { + return this.capabilities.disableDamage ? 0 : 80; + } + + /** + * Return the amount of cooldown before this entity can use a portal again. + */ + public int getPortalCooldown() { + return 10; + } + + public void playSound(String par1Str, float par2, float par3) { + this.worldObj.playSoundToNearExcept(this, par1Str, par2, par3); + } + + /** + * Plays sounds and makes particles for item in use state + */ + protected void updateItemUse(ItemStack par1ItemStack, int par2) { + if (par1ItemStack.getItemUseAction() == EnumAction.drink) { + this.playSound("random.drink", 0.5F, this.worldObj.rand.nextFloat() * 0.1F + 0.9F); + } + + if (par1ItemStack.getItemUseAction() == EnumAction.eat) { + for (int var3 = 0; var3 < par2; ++var3) { + Vec3 var4 = this.worldObj.getWorldVec3Pool().getVecFromPool( + ((double) this.rand.nextFloat() - 0.5D) * 0.1D, Math.random() * 0.1D + 0.1D, 0.0D); + var4.rotateAroundX(-this.rotationPitch * (float) Math.PI / 180.0F); + var4.rotateAroundY(-this.rotationYaw * (float) Math.PI / 180.0F); + Vec3 var5 = this.worldObj.getWorldVec3Pool().getVecFromPool( + ((double) this.rand.nextFloat() - 0.5D) * 0.3D, (double) (-this.rand.nextFloat()) * 0.6D - 0.3D, + 0.6D); + var5.rotateAroundX(-this.rotationPitch * (float) Math.PI / 180.0F); + var5.rotateAroundY(-this.rotationYaw * (float) Math.PI / 180.0F); + var5 = var5.addVector(this.posX, this.posY + (double) this.getEyeHeight(), this.posZ); + this.worldObj.spawnParticle("iconcrack_" + par1ItemStack.getItem().itemID, var5.xCoord, var5.yCoord, + var5.zCoord, var4.xCoord, var4.yCoord + 0.05D, var4.zCoord); + } + + this.playSound("random.eat", 0.5F + 0.5F * (float) this.rand.nextInt(2), + (this.rand.nextFloat() - this.rand.nextFloat()) * 0.2F + 1.0F); + } + } + + /** + * Used for when item use count runs out, ie: eating completed + */ + protected void onItemUseFinish() { + if (this.itemInUse != null) { + this.updateItemUse(this.itemInUse, 16); + int var1 = this.itemInUse.stackSize; + ItemStack var2 = this.itemInUse.onFoodEaten(this.worldObj, this); + + if (var2 != this.itemInUse || var2 != null && var2.stackSize != var1) { + this.inventory.mainInventory[this.inventory.currentItem] = var2; + + if (var2.stackSize == 0) { + this.inventory.mainInventory[this.inventory.currentItem] = null; + } + } + + this.clearItemInUse(); + } + } + + /** + * Dead and sleeping entities cannot move + */ + protected boolean isMovementBlocked() { + return this.getHealth() <= 0 || this.isPlayerSleeping(); + } + + /** + * set current crafting inventory back to the 2x2 square + */ + protected void closeScreen() { + this.openContainer = this.inventoryContainer; + } + + /** + * Called when a player mounts an entity. e.g. mounts a pig, mounts a boat. + */ + public void mountEntity(Entity par1Entity) { + if (this.ridingEntity == par1Entity) { + this.unmountEntity(par1Entity); + + if (this.ridingEntity != null) { + this.ridingEntity.riddenByEntity = null; + } + + this.ridingEntity = null; + } else { + super.mountEntity(par1Entity); + } + } + + /** + * Handles updating while being ridden by an entity + */ + public void updateRidden() { + double var1 = this.posX; + double var3 = this.posY; + double var5 = this.posZ; + float var7 = this.rotationYaw; + float var8 = this.rotationPitch; + super.updateRidden(); + this.prevCameraYaw = this.cameraYaw; + this.cameraYaw = 0.0F; + this.addMountedMovementStat(this.posX - var1, this.posY - var3, this.posZ - var5); + + if (this.ridingEntity instanceof EntityPig) { + this.rotationPitch = var8; + this.rotationYaw = var7; + this.renderYawOffset = ((EntityPig) this.ridingEntity).renderYawOffset; + } + } + + protected void updateEntityActionState() { + this.updateArmSwingProgress(); + } + + /** + * Called frequently so the entity can update its state every tick as required. + * For example, zombies and skeletons use this to react to sunlight and start to + * burn. + */ + public void onLivingUpdate() { + if (this.flyToggleTimer > 0) { + --this.flyToggleTimer; + } + + if (this.worldObj.difficultySetting == 0 && this.getHealth() < this.getMaxHealth() + && this.ticksExisted % 20 * 12 == 0) { + this.heal(1); + } + + this.inventory.decrementAnimations(); + this.prevCameraYaw = this.cameraYaw; + super.onLivingUpdate(); + this.landMovementFactor = this.capabilities.getWalkSpeed(); + this.jumpMovementFactor = this.speedInAir; + + if (this.isSprinting()) { + this.landMovementFactor = (float) ((double) this.landMovementFactor + + (double) this.capabilities.getWalkSpeed() * 0.3D); + this.jumpMovementFactor = (float) ((double) this.jumpMovementFactor + (double) this.speedInAir * 0.3D); + } + + float var1 = MathHelper.sqrt_double(this.motionX * this.motionX + this.motionZ * this.motionZ); + float var2 = (float) Math.atan(-this.motionY * 0.20000000298023224D) * 15.0F; + + if (var1 > 0.1F) { + var1 = 0.1F; + } + + if (!this.onGround || this.getHealth() <= 0) { + var1 = 0.0F; + } + + if (this.onGround || this.getHealth() <= 0) { + var2 = 0.0F; + } + + this.cameraYaw += (var1 - this.cameraYaw) * 0.4F; + this.cameraPitch += (var2 - this.cameraPitch) * 0.8F; + + if (this.getHealth() > 0) { + List var3 = this.worldObj.getEntitiesWithinAABBExcludingEntity(this, + this.boundingBox.expand(1.0D, 0.5D, 1.0D)); + + if (var3 != null) { + for (int var4 = 0; var4 < var3.size(); ++var4) { + Entity var5 = (Entity) var3.get(var4); + + if (!var5.isDead) { + this.collideWithPlayer(var5); + } + } + } + } + } + + private void collideWithPlayer(Entity par1Entity) { + par1Entity.onCollideWithPlayer(this); + } + + public int getScore() { + return this.dataWatcher.getWatchableObjectInt(18); + } + + /** + * Set player's score + */ + public void setScore(int par1) { + this.dataWatcher.updateObject(18, Integer.valueOf(par1)); + } + + /** + * Add to player's score + */ + public void addScore(int par1) { + int var2 = this.getScore(); + this.dataWatcher.updateObject(18, Integer.valueOf(var2 + par1)); + } + + /** + * Called when the mob's health reaches 0. + */ + public void onDeath(DamageSource par1DamageSource) { + super.onDeath(par1DamageSource); + this.setSize(0.2F, 0.2F); + this.setPosition(this.posX, this.posY, this.posZ); + this.motionY = 0.10000000149011612D; + + if (this.username.equals("Notch")) { + this.dropPlayerItemWithRandomChoice(new ItemStack(Item.appleRed, 1), true); + } + + if (!this.worldObj.getGameRules().getGameRuleBooleanValue("keepInventory")) { + this.inventory.dropAllItems(); + } + + if (par1DamageSource != null) { + this.motionX = (double) (-MathHelper.cos((this.attackedAtYaw + this.rotationYaw) * (float) Math.PI / 180.0F) + * 0.1F); + this.motionZ = (double) (-MathHelper.sin((this.attackedAtYaw + this.rotationYaw) * (float) Math.PI / 180.0F) + * 0.1F); + } else { + this.motionX = this.motionZ = 0.0D; + } + + this.yOffset = 0.1F; + this.addStat(StatList.deathsStat, 1); + } + + /** + * Adds a value to the player score. Currently not actually used and the entity + * passed in does nothing. Args: entity, scoreToAdd + */ + public void addToPlayerScore(Entity par1Entity, int par2) { + this.addScore(par2); + Collection var3 = this.getWorldScoreboard().func_96520_a(ScoreObjectiveCriteria.field_96640_e); + + if (par1Entity instanceof EntityPlayer) { + this.addStat(StatList.playerKillsStat, 1); + var3.addAll(this.getWorldScoreboard().func_96520_a(ScoreObjectiveCriteria.field_96639_d)); + } else { + this.addStat(StatList.mobKillsStat, 1); + } + + Iterator var4 = var3.iterator(); + + while (var4.hasNext()) { + ScoreObjective var5 = (ScoreObjective) var4.next(); + Score var6 = this.getWorldScoreboard().func_96529_a(this.getEntityName(), var5); + var6.func_96648_a(); + } + } + + /** + * Called when player presses the drop item key + */ + public EntityItem dropOneItem(boolean par1) { + return this.dropPlayerItemWithRandomChoice(this.inventory.decrStackSize(this.inventory.currentItem, + par1 && this.inventory.getCurrentItem() != null ? this.inventory.getCurrentItem().stackSize : 1), + false); + } + + /** + * Args: itemstack - called when player drops an item stack that's not in his + * inventory (like items still placed in a workbench while the workbench'es GUI + * gets closed) + */ + public EntityItem dropPlayerItem(ItemStack par1ItemStack) { + return this.dropPlayerItemWithRandomChoice(par1ItemStack, false); + } + + /** + * Args: itemstack, flag + */ + public EntityItem dropPlayerItemWithRandomChoice(ItemStack par1ItemStack, boolean par2) { + if (par1ItemStack == null) { + return null; + } else { + EntityItem var3 = new EntityItem(this.worldObj, this.posX, + this.posY - 0.30000001192092896D + (double) this.getEyeHeight(), this.posZ, par1ItemStack); + var3.delayBeforeCanPickup = 40; + float var4 = 0.1F; + float var5; + + if (par2) { + var5 = this.rand.nextFloat() * 0.5F; + float var6 = this.rand.nextFloat() * (float) Math.PI * 2.0F; + var3.motionX = (double) (-MathHelper.sin(var6) * var5); + var3.motionZ = (double) (MathHelper.cos(var6) * var5); + var3.motionY = 0.20000000298023224D; + } else { + var4 = 0.3F; + var3.motionX = (double) (-MathHelper.sin(this.rotationYaw / 180.0F * (float) Math.PI) + * MathHelper.cos(this.rotationPitch / 180.0F * (float) Math.PI) * var4); + var3.motionZ = (double) (MathHelper.cos(this.rotationYaw / 180.0F * (float) Math.PI) + * MathHelper.cos(this.rotationPitch / 180.0F * (float) Math.PI) * var4); + var3.motionY = (double) (-MathHelper.sin(this.rotationPitch / 180.0F * (float) Math.PI) * var4 + 0.1F); + var4 = 0.02F; + var5 = this.rand.nextFloat() * (float) Math.PI * 2.0F; + var4 *= this.rand.nextFloat(); + var3.motionX += Math.cos((double) var5) * (double) var4; + var3.motionY += (double) ((this.rand.nextFloat() - this.rand.nextFloat()) * 0.1F); + var3.motionZ += Math.sin((double) var5) * (double) var4; + } + + this.joinEntityItemWithWorld(var3); + this.addStat(StatList.dropStat, 1); + return var3; + } + } + + /** + * Joins the passed in entity item with the world. Args: entityItem + */ + protected void joinEntityItemWithWorld(EntityItem par1EntityItem) { + this.worldObj.spawnEntityInWorld(par1EntityItem); + } + + /** + * Returns how strong the player is against the specified block at this moment + */ + public float getCurrentPlayerStrVsBlock(Block par1Block, boolean par2) { + float var3 = this.inventory.getStrVsBlock(par1Block); + + if (var3 > 1.0F) { + int var4 = EnchantmentHelper.getEfficiencyModifier(this); + ItemStack var5 = this.inventory.getCurrentItem(); + + if (var4 > 0 && var5 != null) { + float var6 = (float) (var4 * var4 + 1); + + if (!var5.canHarvestBlock(par1Block) && var3 <= 1.0F) { + var3 += var6 * 0.08F; + } else { + var3 += var6; + } + } + } + + if (this.isPotionActive(Potion.digSpeed)) { + var3 *= 1.0F + (float) (this.getActivePotionEffect(Potion.digSpeed).getAmplifier() + 1) * 0.2F; + } + + if (this.isPotionActive(Potion.digSlowdown)) { + var3 *= 1.0F - (float) (this.getActivePotionEffect(Potion.digSlowdown).getAmplifier() + 1) * 0.2F; + } + + if (this.isInsideOfMaterial(Material.water) && !EnchantmentHelper.getAquaAffinityModifier(this)) { + var3 /= 5.0F; + } + + if (!this.onGround) { + var3 /= 5.0F; + } + + return var3; + } + + /** + * Checks if the player has the ability to harvest a block (checks current + * inventory item for a tool if necessary) + */ + public boolean canHarvestBlock(Block par1Block) { + return this.inventory.canHarvestBlock(par1Block); + } + + /** + * (abstract) Protected helper method to read subclass entity data from NBT. + */ + public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) { + super.readEntityFromNBT(par1NBTTagCompound); + NBTTagList var2 = par1NBTTagCompound.getTagList("Inventory"); + this.inventory.readFromNBT(var2); + this.inventory.currentItem = par1NBTTagCompound.getInteger("SelectedItemSlot"); + this.sleeping = par1NBTTagCompound.getBoolean("Sleeping"); + this.sleepTimer = par1NBTTagCompound.getShort("SleepTimer"); + this.experience = par1NBTTagCompound.getFloat("XpP"); + this.experienceLevel = par1NBTTagCompound.getInteger("XpLevel"); + this.experienceTotal = par1NBTTagCompound.getInteger("XpTotal"); + this.setScore(par1NBTTagCompound.getInteger("Score")); + + if (this.sleeping) { + this.playerLocation = new ChunkCoordinates(MathHelper.floor_double(this.posX), + MathHelper.floor_double(this.posY), MathHelper.floor_double(this.posZ)); + this.wakeUpPlayer(true, true, false); + } + + if (par1NBTTagCompound.hasKey("SpawnX") && par1NBTTagCompound.hasKey("SpawnY") + && par1NBTTagCompound.hasKey("SpawnZ")) { + this.spawnChunk = new ChunkCoordinates(par1NBTTagCompound.getInteger("SpawnX"), + par1NBTTagCompound.getInteger("SpawnY"), par1NBTTagCompound.getInteger("SpawnZ")); + this.spawnForced = par1NBTTagCompound.getBoolean("SpawnForced"); + } + + this.foodStats.readNBT(par1NBTTagCompound); + this.capabilities.readCapabilitiesFromNBT(par1NBTTagCompound); + + if (par1NBTTagCompound.hasKey("EnderItems")) { + NBTTagList var3 = par1NBTTagCompound.getTagList("EnderItems"); + this.theInventoryEnderChest.loadInventoryFromNBT(var3); + } + } + + /** + * (abstract) Protected helper method to write subclass entity data to NBT. + */ + public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) { + super.writeEntityToNBT(par1NBTTagCompound); + par1NBTTagCompound.setTag("Inventory", this.inventory.writeToNBT(new NBTTagList())); + par1NBTTagCompound.setInteger("SelectedItemSlot", this.inventory.currentItem); + par1NBTTagCompound.setBoolean("Sleeping", this.sleeping); + par1NBTTagCompound.setShort("SleepTimer", (short) this.sleepTimer); + par1NBTTagCompound.setFloat("XpP", this.experience); + par1NBTTagCompound.setInteger("XpLevel", this.experienceLevel); + par1NBTTagCompound.setInteger("XpTotal", this.experienceTotal); + par1NBTTagCompound.setInteger("Score", this.getScore()); + + if (this.spawnChunk != null) { + par1NBTTagCompound.setInteger("SpawnX", this.spawnChunk.posX); + par1NBTTagCompound.setInteger("SpawnY", this.spawnChunk.posY); + par1NBTTagCompound.setInteger("SpawnZ", this.spawnChunk.posZ); + par1NBTTagCompound.setBoolean("SpawnForced", this.spawnForced); + } + + this.foodStats.writeNBT(par1NBTTagCompound); + this.capabilities.writeCapabilitiesToNBT(par1NBTTagCompound); + par1NBTTagCompound.setTag("EnderItems", this.theInventoryEnderChest.saveInventoryToNBT()); + } + + /** + * Displays the GUI for interacting with a chest inventory. Args: chestInventory + */ + public void displayGUIChest(IInventory par1IInventory) { + } + + public void displayGUIHopper(TileEntityHopper par1TileEntityHopper) { + } + + public void displayGUIHopperMinecart(EntityMinecartHopper par1EntityMinecartHopper) { + } + + public void displayGUIEnchantment(int par1, int par2, int par3, String par4Str) { + } + + /** + * Displays the GUI for interacting with an anvil. + */ + public void displayGUIAnvil(int par1, int par2, int par3) { + } + + /** + * Displays the crafting GUI for a workbench. + */ + public void displayGUIWorkbench(int par1, int par2, int par3) { + } + + public float getEyeHeight() { + return 0.12F; + } + + /** + * sets the players height back to normal after doing things like sleeping and + * dieing + */ + protected void resetHeight() { + this.yOffset = 1.62F; + } + + /** + * Called when the entity is attacked. + */ + public boolean attackEntityFrom(DamageSource par1DamageSource, int par2) { + if (this.isEntityInvulnerable()) { + return false; + } else if (this.capabilities.disableDamage && !par1DamageSource.canHarmInCreative()) { + return false; + } else { + this.entityAge = 0; + + if (this.getHealth() <= 0) { + return false; + } else { + if (this.isPlayerSleeping() && !this.worldObj.isRemote) { + this.wakeUpPlayer(true, true, false); + } + + if (par1DamageSource.isDifficultyScaled()) { + if (this.worldObj.difficultySetting == 0) { + par2 = 0; + } + + if (this.worldObj.difficultySetting == 1) { + par2 = par2 / 2 + 1; + } + + if (this.worldObj.difficultySetting == 3) { + par2 = par2 * 3 / 2; + } + } + + if (par2 == 0) { + return false; + } else { + Entity var3 = par1DamageSource.getEntity(); + + if (var3 instanceof EntityArrow && ((EntityArrow) var3).shootingEntity != null) { + var3 = ((EntityArrow) var3).shootingEntity; + } + + if (var3 instanceof EntityLiving) { + this.alertWolves((EntityLiving) var3, false); + } + + this.addStat(StatList.damageTakenStat, par2); + return super.attackEntityFrom(par1DamageSource, par2); + } + } + } + } + + public boolean func_96122_a(EntityPlayer par1EntityPlayer) { + ScorePlayerTeam var2 = this.getTeam(); + ScorePlayerTeam var3 = par1EntityPlayer.getTeam(); + return var2 != var3 ? true : (var2 != null ? var2.func_96665_g() : true); + } + + /** + * Called when the player attack or gets attacked, it's alert all wolves in the + * area that are owned by the player to join the attack or defend the player. + */ + protected void alertWolves(EntityLiving par1EntityLiving, boolean par2) { + if (!(par1EntityLiving instanceof EntityCreeper) && !(par1EntityLiving instanceof EntityGhast)) { + if (par1EntityLiving instanceof EntityWolf) { + EntityWolf var3 = (EntityWolf) par1EntityLiving; + + if (var3.isTamed() && this.username.equals(var3.getOwnerName())) { + return; + } + } + + if (!(par1EntityLiving instanceof EntityPlayer) || this.func_96122_a((EntityPlayer) par1EntityLiving)) { + List var6 = this.worldObj.getEntitiesWithinAABB(EntityWolf.class, AxisAlignedBB.getAABBPool() + .getAABB(this.posX, this.posY, this.posZ, this.posX + 1.0D, this.posY + 1.0D, this.posZ + 1.0D) + .expand(16.0D, 4.0D, 16.0D)); + Iterator var4 = var6.iterator(); + + while (var4.hasNext()) { + EntityWolf var5 = (EntityWolf) var4.next(); + + if (var5.isTamed() && var5.getEntityToAttack() == null && this.username.equals(var5.getOwnerName()) + && (!par2 || !var5.isSitting())) { + var5.setSitting(false); + var5.setTarget(par1EntityLiving); + } + } + } + } + } + + protected void damageArmor(int par1) { + this.inventory.damageArmor(par1); + } + + /** + * Returns the current armor value as determined by a call to + * InventoryPlayer.getTotalArmorValue + */ + public int getTotalArmorValue() { + return this.inventory.getTotalArmorValue(); + } + + public float func_82243_bO() { + int var1 = 0; + ItemStack[] var2 = this.inventory.armorInventory; + int var3 = var2.length; + + for (int var4 = 0; var4 < var3; ++var4) { + ItemStack var5 = var2[var4]; + + if (var5 != null) { + ++var1; + } + } + + return (float) var1 / (float) this.inventory.armorInventory.length; + } + + /** + * Deals damage to the entity. If its a EntityPlayer then will take damage from + * the armor first and then health second with the reduced value. Args: + * damageAmount + */ + protected void damageEntity(DamageSource par1DamageSource, int par2) { + if (!this.isEntityInvulnerable()) { + if (!par1DamageSource.isUnblockable() && this.isBlocking()) { + par2 = 1 + par2 >> 1; + } + + par2 = this.applyArmorCalculations(par1DamageSource, par2); + par2 = this.applyPotionDamageCalculations(par1DamageSource, par2); + this.addExhaustion(par1DamageSource.getHungerDamage()); + int var3 = this.getHealth(); + this.setEntityHealth(this.getHealth() - par2); + this.field_94063_bt.func_94547_a(par1DamageSource, var3, par2); + } + } + + /** + * Displays the furnace GUI for the passed in furnace entity. Args: + * tileEntityFurnace + */ + public void displayGUIFurnace(TileEntityFurnace par1TileEntityFurnace) { + } + + /** + * Displays the dipsenser GUI for the passed in dispenser entity. Args: + * TileEntityDispenser + */ + public void displayGUIDispenser(TileEntityDispenser par1TileEntityDispenser) { + } + + /** + * Displays the GUI for editing a sign. Args: tileEntitySign + */ + public void displayGUIEditSign(TileEntity par1TileEntity) { + } + + /** + * Displays the GUI for interacting with a brewing stand. + */ + public void displayGUIBrewingStand(TileEntityBrewingStand par1TileEntityBrewingStand) { + } + + /** + * Displays the GUI for interacting with a beacon. + */ + public void displayGUIBeacon(TileEntityBeacon par1TileEntityBeacon) { + } + + public void displayGUIMerchant(IMerchant par1IMerchant, String par2Str) { + } + + /** + * Displays the GUI for interacting with a book. + */ + public void displayGUIBook(ItemStack par1ItemStack) { + } + + public boolean interactWith(Entity par1Entity) { + if (par1Entity.interact(this)) { + return true; + } else { + ItemStack var2 = this.getCurrentEquippedItem(); + + if (var2 != null && par1Entity instanceof EntityLiving) { + if (this.capabilities.isCreativeMode) { + var2 = var2.copy(); + } + + if (var2.interactWith((EntityLiving) par1Entity)) { + if (var2.stackSize <= 0 && !this.capabilities.isCreativeMode) { + this.destroyCurrentEquippedItem(); + } + + return true; + } + } + + return false; + } + } + + /** + * Returns the currently being used item by the player. + */ + public ItemStack getCurrentEquippedItem() { + return this.inventory.getCurrentItem(); + } + + /** + * Destroys the currently equipped item from the player's inventory. + */ + public void destroyCurrentEquippedItem() { + this.inventory.setInventorySlotContents(this.inventory.currentItem, (ItemStack) null); + } + + /** + * Returns the Y Offset of this entity. + */ + public double getYOffset() { + return (double) (this.yOffset - 0.5F); + } + + /** + * Attacks for the player the targeted entity with the currently equipped item. + * The equipped item has hitEntity called on it. Args: targetEntity + */ + public void attackTargetEntityWithCurrentItem(Entity par1Entity) { + if (par1Entity.canAttackWithItem()) { + if (!par1Entity.func_85031_j(this)) { + int var2 = this.inventory.getDamageVsEntity(par1Entity); + + if (this.isPotionActive(Potion.damageBoost)) { + var2 += 3 << this.getActivePotionEffect(Potion.damageBoost).getAmplifier(); + } + + if (this.isPotionActive(Potion.weakness)) { + var2 -= 2 << this.getActivePotionEffect(Potion.weakness).getAmplifier(); + } + + int var3 = 0; + int var4 = 0; + + if (par1Entity instanceof EntityLiving) { + var4 = EnchantmentHelper.getEnchantmentModifierLiving(this, (EntityLiving) par1Entity); + var3 += EnchantmentHelper.getKnockbackModifier(this, (EntityLiving) par1Entity); + } + + if (this.isSprinting()) { + ++var3; + } + + if (var2 > 0 || var4 > 0) { + boolean var5 = this.fallDistance > 0.0F && !this.onGround && !this.isOnLadder() && !this.isInWater() + && !this.isPotionActive(Potion.blindness) && this.ridingEntity == null + && par1Entity instanceof EntityLiving; + + if (var5 && var2 > 0) { + var2 += this.rand.nextInt(var2 / 2 + 2); + } + + var2 += var4; + boolean var6 = false; + int var7 = EnchantmentHelper.getFireAspectModifier(this); + + if (par1Entity instanceof EntityLiving && var7 > 0 && !par1Entity.isBurning()) { + var6 = true; + par1Entity.setFire(1); + } + + boolean var8 = par1Entity.attackEntityFrom(DamageSource.causePlayerDamage(this), var2); + + if (var8) { + if (var3 > 0) { + par1Entity.addVelocity( + (double) (-MathHelper.sin(this.rotationYaw * (float) Math.PI / 180.0F) + * (float) var3 * 0.5F), + 0.1D, (double) (MathHelper.cos(this.rotationYaw * (float) Math.PI / 180.0F) + * (float) var3 * 0.5F)); + this.motionX *= 0.6D; + this.motionZ *= 0.6D; + this.setSprinting(false); + } + + if (var5) { + this.onCriticalHit(par1Entity); + } + + if (var4 > 0) { + this.onEnchantmentCritical(par1Entity); + } + + if (var2 >= 18) { + this.triggerAchievement(AchievementList.overkill); + } + + this.setLastAttackingEntity(par1Entity); + + if (par1Entity instanceof EntityLiving) { + EnchantmentThorns.func_92096_a(this, (EntityLiving) par1Entity, this.rand); + } + } + + ItemStack var9 = this.getCurrentEquippedItem(); + Object var10 = par1Entity; + + if (par1Entity instanceof EntityDragonPart) { + IEntityMultiPart var11 = ((EntityDragonPart) par1Entity).entityDragonObj; + + if (var11 != null && var11 instanceof EntityLiving) { + var10 = (EntityLiving) var11; + } + } + + if (var9 != null && var10 instanceof EntityLiving) { + var9.hitEntity((EntityLiving) var10, this); + + if (var9.stackSize <= 0) { + this.destroyCurrentEquippedItem(); + } + } + + if (par1Entity instanceof EntityLiving) { + if (par1Entity.isEntityAlive()) { + this.alertWolves((EntityLiving) par1Entity, true); + } + + this.addStat(StatList.damageDealtStat, var2); + + if (var7 > 0 && var8) { + par1Entity.setFire(var7 * 4); + } else if (var6) { + par1Entity.extinguish(); + } + } + + this.addExhaustion(0.3F); + } + } + } + } + + /** + * Called when the player performs a critical hit on the Entity. Args: entity + * that was hit critically + */ + public void onCriticalHit(Entity par1Entity) { + } + + public void onEnchantmentCritical(Entity par1Entity) { + } + + /** + * Will get destroyed next tick. + */ + public void setDead() { + super.setDead(); + this.inventoryContainer.onCraftGuiClosed(this); + + if (this.openContainer != null) { + this.openContainer.onCraftGuiClosed(this); + } + } + + /** + * Checks if this entity is inside of an opaque block + */ + public boolean isEntityInsideOpaqueBlock() { + return !this.sleeping && super.isEntityInsideOpaqueBlock(); + } + + public boolean func_71066_bF() { + return false; + } + + /** + * puts player to sleep on specified bed if possible + */ + public EnumStatus sleepInBedAt(int par1, int par2, int par3) { + if (!this.worldObj.isRemote) { + if (this.isPlayerSleeping() || !this.isEntityAlive()) { + return EnumStatus.OTHER_PROBLEM; + } + + if (!this.worldObj.provider.isSurfaceWorld()) { + return EnumStatus.NOT_POSSIBLE_HERE; + } + + if (this.worldObj.isDaytime()) { + return EnumStatus.NOT_POSSIBLE_NOW; + } + + if (Math.abs(this.posX - (double) par1) > 3.0D || Math.abs(this.posY - (double) par2) > 2.0D + || Math.abs(this.posZ - (double) par3) > 3.0D) { + return EnumStatus.TOO_FAR_AWAY; + } + + double var4 = 8.0D; + double var6 = 5.0D; + List var8 = this.worldObj.getEntitiesWithinAABB(EntityMob.class, + AxisAlignedBB.getAABBPool().getAABB((double) par1 - var4, (double) par2 - var6, + (double) par3 - var4, (double) par1 + var4, (double) par2 + var6, (double) par3 + var4)); + + if (!var8.isEmpty()) { + return EnumStatus.NOT_SAFE; + } + } + + this.setSize(0.2F, 0.2F); + this.yOffset = 0.2F; + + if (this.worldObj.blockExists(par1, par2, par3)) { + int var9 = this.worldObj.getBlockMetadata(par1, par2, par3); + int var5 = BlockBed.getDirection(var9); + float var10 = 0.5F; + float var7 = 0.5F; + + switch (var5) { + case 0: + var7 = 0.9F; + break; + + case 1: + var10 = 0.1F; + break; + + case 2: + var7 = 0.1F; + break; + + case 3: + var10 = 0.9F; + } + + this.func_71013_b(var5); + this.setPosition((double) ((float) par1 + var10), (double) ((float) par2 + 0.9375F), + (double) ((float) par3 + var7)); + } else { + this.setPosition((double) ((float) par1 + 0.5F), (double) ((float) par2 + 0.9375F), + (double) ((float) par3 + 0.5F)); + } + + this.sleeping = true; + this.sleepTimer = 0; + this.playerLocation = new ChunkCoordinates(par1, par2, par3); + this.motionX = this.motionZ = this.motionY = 0.0D; + + if (!this.worldObj.isRemote) { + this.worldObj.updateAllPlayersSleepingFlag(); + } + + return EnumStatus.OK; + } + + private void func_71013_b(int par1) { + this.field_71079_bU = 0.0F; + this.field_71089_bV = 0.0F; + + switch (par1) { + case 0: + this.field_71089_bV = -1.8F; + break; + + case 1: + this.field_71079_bU = 1.8F; + break; + + case 2: + this.field_71089_bV = 1.8F; + break; + + case 3: + this.field_71079_bU = -1.8F; + } + } + + /** + * Wake up the player if they're sleeping. + */ + public void wakeUpPlayer(boolean par1, boolean par2, boolean par3) { + this.setSize(0.6F, 1.8F); + this.resetHeight(); + ChunkCoordinates var4 = this.playerLocation; + ChunkCoordinates var5 = this.playerLocation; + + if (var4 != null && this.worldObj.getBlockId(var4.posX, var4.posY, var4.posZ) == Block.bed.blockID) { + BlockBed.setBedOccupied(this.worldObj, var4.posX, var4.posY, var4.posZ, false); + var5 = BlockBed.getNearestEmptyChunkCoordinates(this.worldObj, var4.posX, var4.posY, var4.posZ, 0); + + if (var5 == null) { + var5 = new ChunkCoordinates(var4.posX, var4.posY + 1, var4.posZ); + } + + this.setPosition((double) ((float) var5.posX + 0.5F), (double) ((float) var5.posY + this.yOffset + 0.1F), + (double) ((float) var5.posZ + 0.5F)); + } + + this.sleeping = false; + + if (!this.worldObj.isRemote && par2) { + this.worldObj.updateAllPlayersSleepingFlag(); + } + + if (par1) { + this.sleepTimer = 0; + } else { + this.sleepTimer = 100; + } + + if (par3) { + this.setSpawnChunk(this.playerLocation, false); + } + } + + /** + * Checks if the player is currently in a bed + */ + private boolean isInBed() { + return this.worldObj.getBlockId(this.playerLocation.posX, this.playerLocation.posY, + this.playerLocation.posZ) == Block.bed.blockID; + } + + /** + * Ensure that a block enabling respawning exists at the specified coordinates + * and find an empty space nearby to spawn. + */ + public static ChunkCoordinates verifyRespawnCoordinates(World par0World, ChunkCoordinates par1ChunkCoordinates, + boolean par2) { + IChunkProvider var3 = par0World.getChunkProvider(); + var3.loadChunk(par1ChunkCoordinates.posX - 3 >> 4, par1ChunkCoordinates.posZ - 3 >> 4); + var3.loadChunk(par1ChunkCoordinates.posX + 3 >> 4, par1ChunkCoordinates.posZ - 3 >> 4); + var3.loadChunk(par1ChunkCoordinates.posX - 3 >> 4, par1ChunkCoordinates.posZ + 3 >> 4); + var3.loadChunk(par1ChunkCoordinates.posX + 3 >> 4, par1ChunkCoordinates.posZ + 3 >> 4); + + if (par0World.getBlockId(par1ChunkCoordinates.posX, par1ChunkCoordinates.posY, + par1ChunkCoordinates.posZ) == Block.bed.blockID) { + ChunkCoordinates var8 = BlockBed.getNearestEmptyChunkCoordinates(par0World, par1ChunkCoordinates.posX, + par1ChunkCoordinates.posY, par1ChunkCoordinates.posZ, 0); + return var8; + } else { + Material var4 = par0World.getBlockMaterial(par1ChunkCoordinates.posX, par1ChunkCoordinates.posY, + par1ChunkCoordinates.posZ); + Material var5 = par0World.getBlockMaterial(par1ChunkCoordinates.posX, par1ChunkCoordinates.posY + 1, + par1ChunkCoordinates.posZ); + boolean var6 = !var4.isSolid() && !var4.isLiquid(); + boolean var7 = !var5.isSolid() && !var5.isLiquid(); + return par2 && var6 && var7 ? par1ChunkCoordinates : null; + } + } + + /** + * Returns whether player is sleeping or not + */ + public boolean isPlayerSleeping() { + return this.sleeping; + } + + /** + * Returns whether or not the player is asleep and the screen has fully faded. + */ + public boolean isPlayerFullyAsleep() { + return this.sleeping && this.sleepTimer >= 100; + } + + protected void setHideCape(int par1, boolean par2) { + byte var3 = this.dataWatcher.getWatchableObjectByte(16); + + if (par2) { + this.dataWatcher.updateObject(16, Byte.valueOf((byte) (var3 | 1 << par1))); + } else { + this.dataWatcher.updateObject(16, Byte.valueOf((byte) (var3 & ~(1 << par1)))); + } + } + + /** + * Add a chat message to the player + */ + public void addChatMessage(String par1Str) { + } + + /** + * Returns the location of the bed the player will respawn at, or null if the + * player has not slept in a bed. + */ + public ChunkCoordinates getBedLocation() { + return this.spawnChunk; + } + + public boolean isSpawnForced() { + return this.spawnForced; + } + + /** + * Defines a spawn coordinate to player spawn. Used by bed after the player + * sleep on it. + */ + public void setSpawnChunk(ChunkCoordinates par1ChunkCoordinates, boolean par2) { + if (par1ChunkCoordinates != null) { + this.spawnChunk = new ChunkCoordinates(par1ChunkCoordinates); + this.spawnForced = par2; + } else { + this.spawnChunk = null; + this.spawnForced = false; + } + } + + /** + * Will trigger the specified trigger. + */ + public void triggerAchievement(StatBase par1StatBase) { + this.addStat(par1StatBase, 1); + } + + /** + * Adds a value to a statistic field. + */ + public void addStat(StatBase par1StatBase, int par2) { + } + + /** + * Causes this entity to do an upwards motion (jumping). + */ + protected void jump() { + super.jump(); + this.addStat(StatList.jumpStat, 1); + + if (this.isSprinting()) { + this.addExhaustion(0.8F); + } else { + this.addExhaustion(0.2F); + } + } + + /** + * Moves the entity based on the specified heading. Args: strafe, forward + */ + public void moveEntityWithHeading(float par1, float par2) { + double var3 = this.posX; + double var5 = this.posY; + double var7 = this.posZ; + + if (this.capabilities.isFlying && this.ridingEntity == null) { + double var9 = this.motionY; + float var11 = this.jumpMovementFactor; + this.jumpMovementFactor = this.capabilities.getFlySpeed(); + super.moveEntityWithHeading(par1, par2); + this.motionY = var9 * 0.6D; + this.jumpMovementFactor = var11; + } else { + super.moveEntityWithHeading(par1, par2); + } + + this.addMovementStat(this.posX - var3, this.posY - var5, this.posZ - var7); + } + + /** + * Adds a value to a movement statistic field - like run, walk, swin or climb. + */ + public void addMovementStat(double par1, double par3, double par5) { + if (this.ridingEntity == null) { + int var7; + + if (this.isInsideOfMaterial(Material.water)) { + var7 = Math.round(MathHelper.sqrt_double(par1 * par1 + par3 * par3 + par5 * par5) * 100.0F); + + if (var7 > 0) { + this.addStat(StatList.distanceDoveStat, var7); + this.addExhaustion(0.015F * (float) var7 * 0.01F); + } + } else if (this.isInWater()) { + var7 = Math.round(MathHelper.sqrt_double(par1 * par1 + par5 * par5) * 100.0F); + + if (var7 > 0) { + this.addStat(StatList.distanceSwumStat, var7); + this.addExhaustion(0.015F * (float) var7 * 0.01F); + } + } else if (this.isOnLadder()) { + if (par3 > 0.0D) { + this.addStat(StatList.distanceClimbedStat, (int) Math.round(par3 * 100.0D)); + } + } else if (this.onGround) { + var7 = Math.round(MathHelper.sqrt_double(par1 * par1 + par5 * par5) * 100.0F); + + if (var7 > 0) { + this.addStat(StatList.distanceWalkedStat, var7); + + if (this.isSprinting()) { + this.addExhaustion(0.099999994F * (float) var7 * 0.01F); + } else { + this.addExhaustion(0.01F * (float) var7 * 0.01F); + } + } + } else { + var7 = Math.round(MathHelper.sqrt_double(par1 * par1 + par5 * par5) * 100.0F); + + if (var7 > 25) { + this.addStat(StatList.distanceFlownStat, var7); + } + } + } + } + + /** + * Adds a value to a mounted movement statistic field - by minecart, boat, or + * pig. + */ + private void addMountedMovementStat(double par1, double par3, double par5) { + if (this.ridingEntity != null) { + int var7 = Math.round(MathHelper.sqrt_double(par1 * par1 + par3 * par3 + par5 * par5) * 100.0F); + + if (var7 > 0) { + if (this.ridingEntity instanceof EntityMinecart) { + this.addStat(StatList.distanceByMinecartStat, var7); + + if (this.startMinecartRidingCoordinate == null) { + this.startMinecartRidingCoordinate = new ChunkCoordinates(MathHelper.floor_double(this.posX), + MathHelper.floor_double(this.posY), MathHelper.floor_double(this.posZ)); + } else if ((double) this.startMinecartRidingCoordinate.getDistanceSquared( + MathHelper.floor_double(this.posX), MathHelper.floor_double(this.posY), + MathHelper.floor_double(this.posZ)) >= 1000000.0D) { + this.addStat(AchievementList.onARail, 1); + } + } else if (this.ridingEntity instanceof EntityBoat) { + this.addStat(StatList.distanceByBoatStat, var7); + } else if (this.ridingEntity instanceof EntityPig) { + this.addStat(StatList.distanceByPigStat, var7); + } + } + } + } + + /** + * Called when the mob is falling. Calculates and applies fall damage. + */ + protected void fall(float par1) { + if (!this.capabilities.allowFlying) { + if (par1 >= 2.0F) { + this.addStat(StatList.distanceFallenStat, (int) Math.round((double) par1 * 100.0D)); + } + + super.fall(par1); + } + } + + /** + * This method gets called when the entity kills another one. + */ + public void onKillEntity(EntityLiving par1EntityLiving) { + if (par1EntityLiving instanceof IMob) { + this.triggerAchievement(AchievementList.killEnemy); + } + } + + /** + * Sets the Entity inside a web block. + */ + public void setInWeb() { + if (!this.capabilities.isFlying) { + super.setInWeb(); + } + } + + public ItemStack getCurrentArmor(int par1) { + return this.inventory.armorItemInSlot(par1); + } + + /** + * Makes entity wear random armor based on difficulty + */ + protected void addRandomArmor() { + } + + protected void func_82162_bC() { + } + + /** + * Add experience points to player. + */ + public void addExperience(int par1) { + this.addScore(par1); + int var2 = Integer.MAX_VALUE - this.experienceTotal; + + if (par1 > var2) { + par1 = var2; + } + + this.experience += (float) par1 / (float) this.xpBarCap(); + + for (this.experienceTotal += par1; this.experience >= 1.0F; this.experience /= (float) this.xpBarCap()) { + this.experience = (this.experience - 1.0F) * (float) this.xpBarCap(); + this.addExperienceLevel(1); + } + } + + /** + * Add experience levels to this player. + */ + public void addExperienceLevel(int par1) { + this.experienceLevel += par1; + + if (this.experienceLevel < 0) { + this.experienceLevel = 0; + this.experience = 0.0F; + this.experienceTotal = 0; + } + + if (par1 > 0 && this.experienceLevel % 5 == 0 + && (float) this.field_82249_h < (float) this.ticksExisted - 100.0F) { + float var2 = this.experienceLevel > 30 ? 1.0F : (float) this.experienceLevel / 30.0F; + this.worldObj.playSoundAtEntity(this, "random.levelup", var2 * 0.75F, 1.0F); + this.field_82249_h = this.ticksExisted; + } + } + + /** + * This method returns the cap amount of experience that the experience bar can + * hold. With each level, the experience cap on the player's experience bar is + * raised by 10. + */ + public int xpBarCap() { + return this.experienceLevel >= 30 ? 62 + (this.experienceLevel - 30) * 7 + : (this.experienceLevel >= 15 ? 17 + (this.experienceLevel - 15) * 3 : 17); + } + + /** + * increases exhaustion level by supplied amount + */ + public void addExhaustion(float par1) { + if (!this.capabilities.disableDamage) { + if (!this.worldObj.isRemote) { + this.foodStats.addExhaustion(par1); + } + } + } + + /** + * Returns the player's FoodStats object. + */ + public FoodStats getFoodStats() { + return this.foodStats; + } + + public boolean canEat(boolean par1) { + return (par1 || this.foodStats.needFood()) && !this.capabilities.disableDamage; + } + + /** + * Checks if the player's health is not full and not zero. + */ + public boolean shouldHeal() { + return this.getHealth() > 0 && this.getHealth() < this.getMaxHealth(); + } + + /** + * sets the itemInUse when the use item button is clicked. Args: itemstack, int + * maxItemUseDuration + */ + public void setItemInUse(ItemStack par1ItemStack, int par2) { + if (par1ItemStack != this.itemInUse) { + this.itemInUse = par1ItemStack; + this.itemInUseCount = par2; + + if (!this.worldObj.isRemote) { + this.setEating(true); + } + } + } + + /** + * Returns true if the item the player is holding can harvest the block at the + * given coords. Args: x, y, z. + */ + public boolean canCurrentToolHarvestBlock(int par1, int par2, int par3) { + if (this.capabilities.allowEdit) { + return true; + } else { + int var4 = this.worldObj.getBlockId(par1, par2, par3); + + if (var4 > 0) { + Block var5 = Block.blocksList[var4]; + + if (var5.blockMaterial.isAlwaysHarvested()) { + return true; + } + + if (this.getCurrentEquippedItem() != null) { + ItemStack var6 = this.getCurrentEquippedItem(); + + if (var6.canHarvestBlock(var5) || var6.getStrVsBlock(var5) > 1.0F) { + return true; + } + } + } + + return false; + } + } + + public boolean canPlayerEdit(int par1, int par2, int par3, int par4, ItemStack par5ItemStack) { + return this.capabilities.allowEdit ? true : (par5ItemStack != null ? par5ItemStack.func_82835_x() : false); + } + + /** + * Get the experience points the entity currently has. + */ + protected int getExperiencePoints(EntityPlayer par1EntityPlayer) { + if (this.worldObj.getGameRules().getGameRuleBooleanValue("keepInventory")) { + return 0; + } else { + int var2 = this.experienceLevel * 7; + return var2 > 100 ? 100 : var2; + } + } + + /** + * Only use is to identify if class is an instance of player for experience + * dropping + */ + protected boolean isPlayer() { + return true; + } + + /** + * Gets the username of the entity. + */ + public String getEntityName() { + return this.username; + } + + public boolean func_94062_bN() { + return super.func_94062_bN(); + } + + public boolean canPickUpLoot() { + return false; + } + + /** + * Copies the values from the given player into this player if boolean par2 is + * true. Always clones Ender Chest Inventory. + */ + public void clonePlayer(EntityPlayer par1EntityPlayer, boolean par2) { + if (par2) { + this.inventory.copyInventory(par1EntityPlayer.inventory); + this.health = par1EntityPlayer.health; + this.foodStats = par1EntityPlayer.foodStats; + this.experienceLevel = par1EntityPlayer.experienceLevel; + this.experienceTotal = par1EntityPlayer.experienceTotal; + this.experience = par1EntityPlayer.experience; + this.setScore(par1EntityPlayer.getScore()); + this.teleportDirection = par1EntityPlayer.teleportDirection; + } else if (this.worldObj.getGameRules().getGameRuleBooleanValue("keepInventory")) { + this.inventory.copyInventory(par1EntityPlayer.inventory); + this.experienceLevel = par1EntityPlayer.experienceLevel; + this.experienceTotal = par1EntityPlayer.experienceTotal; + this.experience = par1EntityPlayer.experience; + this.setScore(par1EntityPlayer.getScore()); + } + + this.theInventoryEnderChest = par1EntityPlayer.theInventoryEnderChest; + } + + /** + * returns if this entity triggers Block.onEntityWalking on the blocks they walk + * on. used for spiders and wolves to prevent them from trampling crops + */ + protected boolean canTriggerWalking() { + return !this.capabilities.isFlying; + } + + /** + * Sends the player's abilities to the server (if there is one). + */ + public void sendPlayerAbilities() { + } + + /** + * Sets the player's game mode and sends it to them. + */ + public void setGameType(EnumGameType par1EnumGameType) { + } + + /** + * Gets the name of this command sender (usually username, but possibly "Rcon") + */ + public String getCommandSenderName() { + return this.username; + } + + public StringTranslate getTranslator() { + return StringTranslate.getInstance(); + } + + /** + * Translates and formats the given string key with the given arguments. + */ + public String translateString(String par1Str, Object... par2ArrayOfObj) { + return this.getTranslator().translateKeyFormat(par1Str, par2ArrayOfObj); + } + + /** + * Returns the InventoryEnderChest of this player. + */ + public InventoryEnderChest getInventoryEnderChest() { + return this.theInventoryEnderChest; + } + + /** + * 0: Tool in Hand; 1-4: Armor + */ + public ItemStack getEquipmentInSlot(int par1) { + return par1 == 0 ? this.inventory.getCurrentItem() : this.inventory.armorInventory[par1 - 1]; + } + + /** + * Returns the item that this EntityLiving is holding, if any. + */ + public ItemStack getHeldItem() { + return this.inventory.getCurrentItem(); + } + + /** + * Sets the held item, or an armor slot. Slot 0 is held item. Slot 1-4 is armor. + * Params: Item, slot + */ + public void setCurrentItemOrArmor(int par1, ItemStack par2ItemStack) { + this.inventory.armorInventory[par1] = par2ItemStack; + } + + /** + * returns the inventory of this entity (only used in EntityPlayerMP it seems) + */ + public ItemStack[] getInventory() { + return this.inventory.armorInventory; + } + + public boolean func_96092_aw() { + return !this.capabilities.isFlying; + } + + public Scoreboard getWorldScoreboard() { + return this.worldObj.getScoreboard(); + } + + public ScorePlayerTeam getTeam() { + return this.getWorldScoreboard().getPlayersTeam(this.username); + } + + /** + * Returns the translated name of the entity. + */ + public String getTranslatedEntityName() { + return ScorePlayerTeam.func_96667_a(this.getTeam(), this.username); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityPlayerMP.java b/sp-server/src/main/java/net/minecraft/src/EntityPlayerMP.java new file mode 100644 index 0000000..70f141e --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityPlayerMP.java @@ -0,0 +1,854 @@ +package net.minecraft.src; + +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import net.minecraft.server.MinecraftServer; + +public class EntityPlayerMP extends EntityPlayer implements ICrafting { + private StringTranslate translator = new StringTranslate("en_US"); + + /** + * The NetServerHandler assigned to this player by the + * ServerConfigurationManager. + */ + public NetServerHandler playerNetServerHandler; + + /** Reference to the MinecraftServer object. */ + public MinecraftServer mcServer; + + /** The ItemInWorldManager belonging to this player */ + public ItemInWorldManager theItemInWorldManager; + + /** player X position as seen by PlayerManager */ + public double managedPosX; + + /** player Z position as seen by PlayerManager */ + public double managedPosZ; + + /** LinkedList that holds the loaded chunks. */ + public final List loadedChunks = new LinkedList(); + + /** entities added to this list will be packet29'd to the player */ + public final List destroyedItemsNetCache = new LinkedList(); + + /** amount of health the client was last set to */ + private int lastHealth = -99999999; + + /** set to foodStats.GetFoodLevel */ + private int lastFoodLevel = -99999999; + + /** set to foodStats.getSaturationLevel() == 0.0F each tick */ + private boolean wasHungry = true; + + /** Amount of experience the client was last set to */ + private int lastExperience = -99999999; + + /** how many ticks of invulnerability(spawn protection) this player has */ + private int ticksOfInvuln = 60; + + /** must be between 3>x>15 (strictly between) */ + private int renderDistance = 0; + private int chatVisibility = 0; + private boolean chatColours = true; + + /** + * The currently in use window ID. Incremented every time a window is opened. + */ + private int currentWindowId = 0; + + /** + * set to true when player is moving quantity of items from one inventory to + * another(crafting) but item in either slot is not changed + */ + public boolean isChangingQuantityOnly; + public int ping; + + /** + * Set when a player beats the ender dragon, used to respawn the player at the + * spawn point while retaining inventory and XP + */ + public boolean playerConqueredTheEnd = false; + + public EntityPlayerMP(MinecraftServer par1MinecraftServer, World par2World, String par3Str, + ItemInWorldManager par4ItemInWorldManager) { + super(par2World); + par4ItemInWorldManager.thisPlayerMP = this; + this.theItemInWorldManager = par4ItemInWorldManager; + this.renderDistance = par1MinecraftServer.getConfigurationManager().getViewDistance(); + ChunkCoordinates var5 = par2World.getSpawnPoint(); + int var6 = var5.posX; + int var7 = var5.posZ; + int var8 = var5.posY; + + if (!par2World.provider.hasNoSky && par2World.getWorldInfo().getGameType() != EnumGameType.ADVENTURE) { + int var9 = Math.max(5, par1MinecraftServer.getSpawnProtectionSize() - 6); + var6 += this.rand.nextInt(var9 * 2) - var9; + var7 += this.rand.nextInt(var9 * 2) - var9; + var8 = par2World.getTopSolidOrLiquidBlock(var6, var7); + } + + this.mcServer = par1MinecraftServer; + this.stepHeight = 0.0F; + this.username = par3Str; + this.yOffset = 0.0F; + this.setLocationAndAngles((double) var6 + 0.5D, (double) var8, (double) var7 + 0.5D, 0.0F, 0.0F); + + while (!par2World.getCollidingBoundingBoxes(this, this.boundingBox).isEmpty()) { + this.setPosition(this.posX, this.posY + 1.0D, this.posZ); + } + } + + /** + * (abstract) Protected helper method to read subclass entity data from NBT. + */ + public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) { + super.readEntityFromNBT(par1NBTTagCompound); + + if (par1NBTTagCompound.hasKey("playerGameType")) { + if (MinecraftServer.getServer().func_104056_am()) { + this.theItemInWorldManager.setGameType(MinecraftServer.getServer().getGameType()); + } else { + this.theItemInWorldManager + .setGameType(EnumGameType.getByID(par1NBTTagCompound.getInteger("playerGameType"))); + } + } + } + + /** + * (abstract) Protected helper method to write subclass entity data to NBT. + */ + public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) { + super.writeEntityToNBT(par1NBTTagCompound); + par1NBTTagCompound.setInteger("playerGameType", this.theItemInWorldManager.getGameType().getID()); + } + + /** + * Add experience levels to this player. + */ + public void addExperienceLevel(int par1) { + super.addExperienceLevel(par1); + this.lastExperience = -1; + } + + public void addSelfToInternalCraftingInventory() { + this.openContainer.onCraftGuiOpened(this); + } + + /** + * sets the players height back to normal after doing things like sleeping and + * dieing + */ + protected void resetHeight() { + this.yOffset = 0.0F; + } + + public float getEyeHeight() { + return 1.62F; + } + + /** + * Called to update the entity's position/logic. + */ + public void onUpdate() { + this.theItemInWorldManager.updateBlockRemoving(); + --this.ticksOfInvuln; + this.openContainer.detectAndSendChanges(); + + while (!this.destroyedItemsNetCache.isEmpty()) { + int var1 = Math.min(this.destroyedItemsNetCache.size(), 127); + int[] var2 = new int[var1]; + Iterator var3 = this.destroyedItemsNetCache.iterator(); + int var4 = 0; + + while (var3.hasNext() && var4 < var1) { + var2[var4++] = ((Integer) var3.next()).intValue(); + var3.remove(); + } + + this.playerNetServerHandler.sendPacket(new Packet29DestroyEntity(var2)); + } + + if (!this.loadedChunks.isEmpty()) { + ArrayList var6 = new ArrayList(); + Iterator var7 = this.loadedChunks.iterator(); + ArrayList var8 = new ArrayList(); + + while (var7.hasNext() && var6.size() < 5) { + ChunkCoordIntPair var9 = (ChunkCoordIntPair) var7.next(); + var7.remove(); + + if (var9 != null && this.worldObj.blockExists(var9.chunkXPos << 4, 0, var9.chunkZPos << 4)) { + var6.add(this.worldObj.getChunkFromChunkCoords(var9.chunkXPos, var9.chunkZPos)); + var8.addAll(((WorldServer) this.worldObj).getTileEntityList(var9.chunkXPos * 16, 0, + var9.chunkZPos * 16, var9.chunkXPos * 16 + 16, 256, var9.chunkZPos * 16 + 16)); + } + } + + if (!var6.isEmpty()) { + this.playerNetServerHandler.sendPacket(new Packet56MapChunks(var6)); + Iterator var10 = var8.iterator(); + + while (var10.hasNext()) { + TileEntity var5 = (TileEntity) var10.next(); + this.getTileEntityInfo(var5); + } + + var10 = var6.iterator(); + + while (var10.hasNext()) { + Chunk var11 = (Chunk) var10.next(); + this.getServerForPlayer().getEntityTracker().func_85172_a(this, var11); + } + } + } + } + + public void setEntityHealth(int par1) { + super.setEntityHealth(par1); + Collection var2 = this.getWorldScoreboard().func_96520_a(ScoreObjectiveCriteria.field_96638_f); + Iterator var3 = var2.iterator(); + + while (var3.hasNext()) { + ScoreObjective var4 = (ScoreObjective) var3.next(); + this.getWorldScoreboard().func_96529_a(this.getEntityName(), var4) + .func_96651_a(Arrays.asList(new EntityPlayer[] { this })); + } + } + + public void onUpdateEntity() { + try { + super.onUpdate(); + + for (int var1 = 0; var1 < this.inventory.getSizeInventory(); ++var1) { + ItemStack var5 = this.inventory.getStackInSlot(var1); + + if (var5 != null && Item.itemsList[var5.itemID].isMap() + && this.playerNetServerHandler.getNumChunkDataPackets() <= 5) { + Packet var6 = ((ItemMapBase) Item.itemsList[var5.itemID]).getUpdatePacket(var5, this.worldObj, + this); + + if (var6 != null) { + this.playerNetServerHandler.sendPacket(var6); + } + } + } + + if (this.getHealth() != this.lastHealth || this.lastFoodLevel != this.foodStats.getFoodLevel() + || this.foodStats.getSaturationLevel() == 0.0F != this.wasHungry) { + this.playerNetServerHandler.sendPacket(new Packet8UpdateHealth(this.getHealth(), + this.foodStats.getFoodLevel(), this.foodStats.getSaturationLevel())); + this.lastHealth = this.getHealth(); + this.lastFoodLevel = this.foodStats.getFoodLevel(); + this.wasHungry = this.foodStats.getSaturationLevel() == 0.0F; + } + + if (this.experienceTotal != this.lastExperience) { + this.lastExperience = this.experienceTotal; + this.playerNetServerHandler.sendPacket( + new Packet43Experience(this.experience, this.experienceTotal, this.experienceLevel)); + } + } catch (Throwable var4) { + CrashReport var2 = CrashReport.makeCrashReport(var4, "Ticking player"); + CrashReportCategory var3 = var2.makeCategory("Player being ticked"); + this.func_85029_a(var3); + throw new ReportedException(var2); + } + } + + /** + * Called when the mob's health reaches 0. + */ + public void onDeath(DamageSource par1DamageSource) { + this.mcServer.getConfigurationManager().sendChatMsg(this.field_94063_bt.func_94546_b()); + + if (!this.worldObj.getGameRules().getGameRuleBooleanValue("keepInventory")) { + this.inventory.dropAllItems(); + } + + Collection var2 = this.worldObj.getScoreboard().func_96520_a(ScoreObjectiveCriteria.field_96642_c); + Iterator var3 = var2.iterator(); + + while (var3.hasNext()) { + ScoreObjective var4 = (ScoreObjective) var3.next(); + Score var5 = this.getWorldScoreboard().func_96529_a(this.getEntityName(), var4); + var5.func_96648_a(); + } + + EntityLiving var6 = this.func_94060_bK(); + + if (var6 != null) { + var6.addToPlayerScore(this, this.scoreValue); + } + } + + /** + * Called when the entity is attacked. + */ + public boolean attackEntityFrom(DamageSource par1DamageSource, int par2) { + if (this.isEntityInvulnerable()) { + return false; + } else { + boolean var3 = this.mcServer.isDedicatedServer() && this.mcServer.isPVPEnabled() + && "fall".equals(par1DamageSource.damageType); + + if (!var3 && this.ticksOfInvuln > 0 && par1DamageSource != DamageSource.outOfWorld) { + return false; + } else { + if (par1DamageSource instanceof EntityDamageSource) { + Entity var4 = par1DamageSource.getEntity(); + + if (var4 instanceof EntityPlayer && !this.func_96122_a((EntityPlayer) var4)) { + return false; + } + + if (var4 instanceof EntityArrow) { + EntityArrow var5 = (EntityArrow) var4; + + if (var5.shootingEntity instanceof EntityPlayer + && !this.func_96122_a((EntityPlayer) var5.shootingEntity)) { + return false; + } + } + } + + return super.attackEntityFrom(par1DamageSource, par2); + } + } + } + + public boolean func_96122_a(EntityPlayer par1EntityPlayer) { + return !this.mcServer.isPVPEnabled() ? false : super.func_96122_a(par1EntityPlayer); + } + + public void travelToTheEnd(int par1) { + if (this.dimension == 1 && par1 == 1) { + this.triggerAchievement(AchievementList.theEnd2); + this.worldObj.removeEntity(this); + this.playerConqueredTheEnd = true; + this.playerNetServerHandler.sendPacket(new Packet70GameEvent(4, 0)); + } else { + if (this.dimension == 1 && par1 == 0) { + this.triggerAchievement(AchievementList.theEnd); + ChunkCoordinates var2 = this.mcServer.worldServerForDimension(par1).getEntrancePortalLocation(); + + if (var2 != null) { + this.playerNetServerHandler.setPlayerLocation((double) var2.posX, (double) var2.posY, + (double) var2.posZ, 0.0F, 0.0F); + } + + par1 = 1; + } else { + this.triggerAchievement(AchievementList.portal); + } + + this.mcServer.getConfigurationManager().transferPlayerToDimension(this, par1); + this.lastExperience = -1; + this.lastHealth = -1; + this.lastFoodLevel = -1; + } + } + + /** + * gets description packets from all TileEntity's that override func_20070 + */ + private void getTileEntityInfo(TileEntity par1TileEntity) { + if (par1TileEntity != null) { + Packet var2 = par1TileEntity.getDescriptionPacket(); + + if (var2 != null) { + this.playerNetServerHandler.sendPacket(var2); + } + } + } + + /** + * Called whenever an item is picked up from walking over it. Args: + * pickedUpEntity, stackSize + */ + public void onItemPickup(Entity par1Entity, int par2) { + super.onItemPickup(par1Entity, par2); + this.openContainer.detectAndSendChanges(); + } + + /** + * puts player to sleep on specified bed if possible + */ + public EnumStatus sleepInBedAt(int par1, int par2, int par3) { + EnumStatus var4 = super.sleepInBedAt(par1, par2, par3); + + if (var4 == EnumStatus.OK) { + Packet17Sleep var5 = new Packet17Sleep(this, 0, par1, par2, par3); + this.getServerForPlayer().getEntityTracker().sendPacketToTrackedPlayers(this, var5); + this.playerNetServerHandler.setPlayerLocation(this.posX, this.posY, this.posZ, this.rotationYaw, + this.rotationPitch); + this.playerNetServerHandler.sendPacket(var5); + } + + return var4; + } + + /** + * Wake up the player if they're sleeping. + */ + public void wakeUpPlayer(boolean par1, boolean par2, boolean par3) { + if (this.isPlayerSleeping()) { + this.getServerForPlayer().getEntityTracker().sendPacketToTrackedPlayersAndTrackedEntity(this, + new Packet18Animation(this, 3)); + } + + super.wakeUpPlayer(par1, par2, par3); + + if (this.playerNetServerHandler != null) { + this.playerNetServerHandler.setPlayerLocation(this.posX, this.posY, this.posZ, this.rotationYaw, + this.rotationPitch); + } + } + + /** + * Called when a player mounts an entity. e.g. mounts a pig, mounts a boat. + */ + public void mountEntity(Entity par1Entity) { + super.mountEntity(par1Entity); + this.playerNetServerHandler.sendPacket(new Packet39AttachEntity(this, this.ridingEntity)); + this.playerNetServerHandler.setPlayerLocation(this.posX, this.posY, this.posZ, this.rotationYaw, + this.rotationPitch); + } + + /** + * Takes in the distance the entity has fallen this tick and whether its on the + * ground to update the fall distance and deal fall damage if landing on the + * ground. Args: distanceFallenThisTick, onGround + */ + protected void updateFallState(double par1, boolean par3) { + } + + /** + * process player falling based on movement packet + */ + public void handleFalling(double par1, boolean par3) { + super.updateFallState(par1, par3); + } + + /** + * get the next window id to use + */ + private void getNextWindowId() { + this.currentWindowId = this.currentWindowId % 100 + 1; + } + + /** + * Displays the crafting GUI for a workbench. + */ + public void displayGUIWorkbench(int par1, int par2, int par3) { + this.getNextWindowId(); + this.playerNetServerHandler.sendPacket(new Packet100OpenWindow(this.currentWindowId, 1, "Crafting", 9, true)); + this.openContainer = new ContainerWorkbench(this.inventory, this.worldObj, par1, par2, par3); + this.openContainer.windowId = this.currentWindowId; + this.openContainer.onCraftGuiOpened(this); + } + + public void displayGUIEnchantment(int par1, int par2, int par3, String par4Str) { + this.getNextWindowId(); + this.playerNetServerHandler.sendPacket( + new Packet100OpenWindow(this.currentWindowId, 4, par4Str == null ? "" : par4Str, 9, par4Str != null)); + this.openContainer = new ContainerEnchantment(this.inventory, this.worldObj, par1, par2, par3); + this.openContainer.windowId = this.currentWindowId; + this.openContainer.onCraftGuiOpened(this); + } + + /** + * Displays the GUI for interacting with an anvil. + */ + public void displayGUIAnvil(int par1, int par2, int par3) { + this.getNextWindowId(); + this.playerNetServerHandler.sendPacket(new Packet100OpenWindow(this.currentWindowId, 8, "Repairing", 9, true)); + this.openContainer = new ContainerRepair(this.inventory, this.worldObj, par1, par2, par3, this); + this.openContainer.windowId = this.currentWindowId; + this.openContainer.onCraftGuiOpened(this); + } + + /** + * Displays the GUI for interacting with a chest inventory. Args: chestInventory + */ + public void displayGUIChest(IInventory par1IInventory) { + if (this.openContainer != this.inventoryContainer) { + this.closeScreen(); + } + + this.getNextWindowId(); + this.playerNetServerHandler.sendPacket(new Packet100OpenWindow(this.currentWindowId, 0, + par1IInventory.getInvName(), par1IInventory.getSizeInventory(), par1IInventory.isInvNameLocalized())); + this.openContainer = new ContainerChest(this.inventory, par1IInventory); + this.openContainer.windowId = this.currentWindowId; + this.openContainer.onCraftGuiOpened(this); + } + + public void displayGUIHopper(TileEntityHopper par1TileEntityHopper) { + this.getNextWindowId(); + this.playerNetServerHandler + .sendPacket(new Packet100OpenWindow(this.currentWindowId, 9, par1TileEntityHopper.getInvName(), + par1TileEntityHopper.getSizeInventory(), par1TileEntityHopper.isInvNameLocalized())); + this.openContainer = new ContainerHopper(this.inventory, par1TileEntityHopper); + this.openContainer.windowId = this.currentWindowId; + this.openContainer.onCraftGuiOpened(this); + } + + public void displayGUIHopperMinecart(EntityMinecartHopper par1EntityMinecartHopper) { + this.getNextWindowId(); + this.playerNetServerHandler + .sendPacket(new Packet100OpenWindow(this.currentWindowId, 9, par1EntityMinecartHopper.getInvName(), + par1EntityMinecartHopper.getSizeInventory(), par1EntityMinecartHopper.isInvNameLocalized())); + this.openContainer = new ContainerHopper(this.inventory, par1EntityMinecartHopper); + this.openContainer.windowId = this.currentWindowId; + this.openContainer.onCraftGuiOpened(this); + } + + /** + * Displays the furnace GUI for the passed in furnace entity. Args: + * tileEntityFurnace + */ + public void displayGUIFurnace(TileEntityFurnace par1TileEntityFurnace) { + this.getNextWindowId(); + this.playerNetServerHandler + .sendPacket(new Packet100OpenWindow(this.currentWindowId, 2, par1TileEntityFurnace.getInvName(), + par1TileEntityFurnace.getSizeInventory(), par1TileEntityFurnace.isInvNameLocalized())); + this.openContainer = new ContainerFurnace(this.inventory, par1TileEntityFurnace); + this.openContainer.windowId = this.currentWindowId; + this.openContainer.onCraftGuiOpened(this); + } + + /** + * Displays the dipsenser GUI for the passed in dispenser entity. Args: + * TileEntityDispenser + */ + public void displayGUIDispenser(TileEntityDispenser par1TileEntityDispenser) { + this.getNextWindowId(); + this.playerNetServerHandler.sendPacket(new Packet100OpenWindow(this.currentWindowId, + par1TileEntityDispenser instanceof TileEntityDropper ? 10 : 3, par1TileEntityDispenser.getInvName(), + par1TileEntityDispenser.getSizeInventory(), par1TileEntityDispenser.isInvNameLocalized())); + this.openContainer = new ContainerDispenser(this.inventory, par1TileEntityDispenser); + this.openContainer.windowId = this.currentWindowId; + this.openContainer.onCraftGuiOpened(this); + } + + /** + * Displays the GUI for interacting with a brewing stand. + */ + public void displayGUIBrewingStand(TileEntityBrewingStand par1TileEntityBrewingStand) { + this.getNextWindowId(); + this.playerNetServerHandler.sendPacket(new Packet100OpenWindow(this.currentWindowId, 5, + par1TileEntityBrewingStand.getInvName(), par1TileEntityBrewingStand.getSizeInventory(), + par1TileEntityBrewingStand.isInvNameLocalized())); + this.openContainer = new ContainerBrewingStand(this.inventory, par1TileEntityBrewingStand); + this.openContainer.windowId = this.currentWindowId; + this.openContainer.onCraftGuiOpened(this); + } + + /** + * Displays the GUI for interacting with a beacon. + */ + public void displayGUIBeacon(TileEntityBeacon par1TileEntityBeacon) { + this.getNextWindowId(); + this.playerNetServerHandler + .sendPacket(new Packet100OpenWindow(this.currentWindowId, 7, par1TileEntityBeacon.getInvName(), + par1TileEntityBeacon.getSizeInventory(), par1TileEntityBeacon.isInvNameLocalized())); + this.openContainer = new ContainerBeacon(this.inventory, par1TileEntityBeacon); + this.openContainer.windowId = this.currentWindowId; + this.openContainer.onCraftGuiOpened(this); + } + + public void displayGUIMerchant(IMerchant par1IMerchant, String par2Str) { + this.getNextWindowId(); + this.openContainer = new ContainerMerchant(this.inventory, par1IMerchant, this.worldObj); + this.openContainer.windowId = this.currentWindowId; + this.openContainer.onCraftGuiOpened(this); + InventoryMerchant var3 = ((ContainerMerchant) this.openContainer).getMerchantInventory(); + this.playerNetServerHandler.sendPacket(new Packet100OpenWindow(this.currentWindowId, 6, + par2Str == null ? "" : par2Str, var3.getSizeInventory(), par2Str != null)); + MerchantRecipeList var4 = par1IMerchant.getRecipes(this); + + if (var4 != null) { + try { + ByteArrayOutputStream var5 = new ByteArrayOutputStream(); + DataOutputStream var6 = new DataOutputStream(var5); + var6.writeInt(this.currentWindowId); + var4.writeRecipiesToStream(var6); + this.playerNetServerHandler.sendPacket(new Packet250CustomPayload("MC|TrList", var5.toByteArray())); + } catch (IOException var7) { + var7.printStackTrace(); + } + } + } + + /** + * Sends the contents of an inventory slot to the client-side Container. This + * doesn't have to match the actual contents of that slot. Args: Container, slot + * number, slot contents + */ + public void sendSlotContents(Container par1Container, int par2, ItemStack par3ItemStack) { + if (!(par1Container.getSlot(par2) instanceof SlotCrafting)) { + if (!this.isChangingQuantityOnly) { + this.playerNetServerHandler + .sendPacket(new Packet103SetSlot(par1Container.windowId, par2, par3ItemStack)); + } + } + } + + public void sendContainerToPlayer(Container par1Container) { + this.updateCraftingInventory(par1Container, par1Container.getInventory()); + } + + /** + * update the crafting window inventory with the items in the list + */ + public void updateCraftingInventory(Container par1Container, List par2List) { + this.playerNetServerHandler.sendPacket(new Packet104WindowItems(par1Container.windowId, par2List)); + this.playerNetServerHandler.sendPacket(new Packet103SetSlot(-1, -1, this.inventory.getItemStack())); + } + + /** + * Sends two ints to the client-side Container. Used for furnace burning time, + * smelting progress, brewing progress, and enchanting level. Normally the first + * int identifies which variable to update, and the second contains the new + * value. Both are truncated to shorts in non-local SMP. + */ + public void sendProgressBarUpdate(Container par1Container, int par2, int par3) { + this.playerNetServerHandler.sendPacket(new Packet105UpdateProgressbar(par1Container.windowId, par2, par3)); + } + + /** + * set current crafting inventory back to the 2x2 square + */ + public void closeScreen() { + this.playerNetServerHandler.sendPacket(new Packet101CloseWindow(this.openContainer.windowId)); + this.closeCraftingGui(); + } + + /** + * updates item held by mouse + */ + public void updateHeldItem() { + if (!this.isChangingQuantityOnly) { + this.playerNetServerHandler.sendPacket(new Packet103SetSlot(-1, -1, this.inventory.getItemStack())); + } + } + + /** + * close the current crafting gui + */ + public void closeCraftingGui() { + this.openContainer.onCraftGuiClosed(this); + this.openContainer = this.inventoryContainer; + } + + /** + * Adds a value to a statistic field. + */ + public void addStat(StatBase par1StatBase, int par2) { + if (par1StatBase != null) { + if (!par1StatBase.isIndependent) { + while (par2 > 100) { + this.playerNetServerHandler.sendPacket(new Packet200Statistic(par1StatBase.statId, 100)); + par2 -= 100; + } + + this.playerNetServerHandler.sendPacket(new Packet200Statistic(par1StatBase.statId, par2)); + } + } + } + + public void mountEntityAndWakeUp() { + if (this.riddenByEntity != null) { + this.riddenByEntity.mountEntity(this); + } + + if (this.sleeping) { + this.wakeUpPlayer(true, false, false); + } + } + + /** + * this function is called when a players inventory is sent to him, lastHealth + * is updated on any dimension transitions, then reset. + */ + public void setPlayerHealthUpdated() { + this.lastHealth = -99999999; + } + + /** + * Add a chat message to the player + */ + public void addChatMessage(String par1Str) { + StringTranslate var2 = StringTranslate.getInstance(); + String var3 = var2.translateKey(par1Str); + this.playerNetServerHandler.sendPacket(new Packet3Chat(var3)); + } + + /** + * Used for when item use count runs out, ie: eating completed + */ + protected void onItemUseFinish() { + this.playerNetServerHandler.sendPacket(new Packet38EntityStatus(this.entityId, (byte) 9)); + super.onItemUseFinish(); + } + + /** + * sets the itemInUse when the use item button is clicked. Args: itemstack, int + * maxItemUseDuration + */ + public void setItemInUse(ItemStack par1ItemStack, int par2) { + super.setItemInUse(par1ItemStack, par2); + + if (par1ItemStack != null && par1ItemStack.getItem() != null + && par1ItemStack.getItem().getItemUseAction(par1ItemStack) == EnumAction.eat) { + this.getServerForPlayer().getEntityTracker().sendPacketToTrackedPlayersAndTrackedEntity(this, + new Packet18Animation(this, 5)); + } + } + + /** + * Copies the values from the given player into this player if boolean par2 is + * true. Always clones Ender Chest Inventory. + */ + public void clonePlayer(EntityPlayer par1EntityPlayer, boolean par2) { + super.clonePlayer(par1EntityPlayer, par2); + this.lastExperience = -1; + this.lastHealth = -1; + this.lastFoodLevel = -1; + this.destroyedItemsNetCache.addAll(((EntityPlayerMP) par1EntityPlayer).destroyedItemsNetCache); + } + + protected void onNewPotionEffect(PotionEffect par1PotionEffect) { + super.onNewPotionEffect(par1PotionEffect); + this.playerNetServerHandler.sendPacket(new Packet41EntityEffect(this.entityId, par1PotionEffect)); + } + + protected void onChangedPotionEffect(PotionEffect par1PotionEffect) { + super.onChangedPotionEffect(par1PotionEffect); + this.playerNetServerHandler.sendPacket(new Packet41EntityEffect(this.entityId, par1PotionEffect)); + } + + protected void onFinishedPotionEffect(PotionEffect par1PotionEffect) { + super.onFinishedPotionEffect(par1PotionEffect); + this.playerNetServerHandler.sendPacket(new Packet42RemoveEntityEffect(this.entityId, par1PotionEffect)); + } + + /** + * Sets the position of the entity and updates the 'last' variables + */ + public void setPositionAndUpdate(double par1, double par3, double par5) { + this.playerNetServerHandler.setPlayerLocation(par1, par3, par5, this.rotationYaw, this.rotationPitch); + } + + /** + * Called when the player performs a critical hit on the Entity. Args: entity + * that was hit critically + */ + public void onCriticalHit(Entity par1Entity) { + this.getServerForPlayer().getEntityTracker().sendPacketToTrackedPlayersAndTrackedEntity(this, + new Packet18Animation(par1Entity, 6)); + } + + public void onEnchantmentCritical(Entity par1Entity) { + this.getServerForPlayer().getEntityTracker().sendPacketToTrackedPlayersAndTrackedEntity(this, + new Packet18Animation(par1Entity, 7)); + } + + /** + * Sends the player's abilities to the server (if there is one). + */ + public void sendPlayerAbilities() { + if (this.playerNetServerHandler != null) { + this.playerNetServerHandler.sendPacket(new Packet202PlayerAbilities(this.capabilities)); + } + } + + public WorldServer getServerForPlayer() { + return (WorldServer) this.worldObj; + } + + /** + * Sets the player's game mode and sends it to them. + */ + public void setGameType(EnumGameType par1EnumGameType) { + this.theItemInWorldManager.setGameType(par1EnumGameType); + this.playerNetServerHandler.sendPacket(new Packet70GameEvent(3, par1EnumGameType.getID())); + } + + public void sendChatToPlayer(String par1Str) { + this.playerNetServerHandler.sendPacket(new Packet3Chat(par1Str)); + } + + /** + * Returns true if the command sender is allowed to use the given command. + */ + public boolean canCommandSenderUseCommand(int par1, String par2Str) { + return "seed".equals(par2Str) && !this.mcServer.isDedicatedServer() ? true + : (!"tell".equals(par2Str) && !"help".equals(par2Str) && !"me".equals(par2Str) + ? this.mcServer.getConfigurationManager().areCommandsAllowed(this.username) + : true); + } + + /** + * Gets the player's IP address. Used in /banip. + */ + public String getPlayerIP() { + String var1 = this.playerNetServerHandler.netManager.getRemoteAddress().toString(); + var1 = var1.substring(var1.indexOf("/") + 1); + var1 = var1.substring(0, var1.indexOf(":")); + return var1; + } + + public void updateClientInfo(Packet204ClientInfo par1Packet204ClientInfo) { + if (this.translator.getLanguageList().containsKey(par1Packet204ClientInfo.getLanguage())) { + this.translator.setLanguage(par1Packet204ClientInfo.getLanguage(), false); + } + + int var2 = 256 >> par1Packet204ClientInfo.getRenderDistance(); + + if (var2 > 3 && var2 < 15) { + this.renderDistance = var2; + } + + this.chatVisibility = par1Packet204ClientInfo.getChatVisibility(); + this.chatColours = par1Packet204ClientInfo.getChatColours(); + + if (this.mcServer.isSinglePlayer() && this.mcServer.getServerOwner().equals(this.username)) { + this.mcServer.setDifficultyForAllWorlds(par1Packet204ClientInfo.getDifficulty()); + } + + this.setHideCape(1, !par1Packet204ClientInfo.getShowCape()); + } + + public StringTranslate getTranslator() { + return this.translator; + } + + public int getChatVisibility() { + return this.chatVisibility; + } + + /** + * on recieving this message the client (if permission is given) will download + * the requested textures + */ + public void requestTexturePackLoad(String par1Str, int par2) { + String var3 = par1Str + "\u0000" + par2; + this.playerNetServerHandler.sendPacket(new Packet250CustomPayload("MC|TPack", var3.getBytes())); + } + + /** + * Return the position for this command sender. + */ + public ChunkCoordinates getCommandSenderPosition() { + return new ChunkCoordinates(MathHelper.floor_double(this.posX), MathHelper.floor_double(this.posY + 0.5D), + MathHelper.floor_double(this.posZ)); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityPotion.java b/sp-server/src/main/java/net/minecraft/src/EntityPotion.java new file mode 100644 index 0000000..3414232 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityPotion.java @@ -0,0 +1,145 @@ +package net.minecraft.src; + +import java.util.Iterator; +import java.util.List; + +public class EntityPotion extends EntityThrowable { + /** + * The damage value of the thrown potion that this EntityPotion represents. + */ + private ItemStack potionDamage; + + public EntityPotion(World par1World) { + super(par1World); + } + + public EntityPotion(World par1World, EntityLiving par2EntityLiving, int par3) { + this(par1World, par2EntityLiving, new ItemStack(Item.potion, 1, par3)); + } + + public EntityPotion(World par1World, EntityLiving par2EntityLiving, ItemStack par3ItemStack) { + super(par1World, par2EntityLiving); + this.potionDamage = par3ItemStack; + } + + public EntityPotion(World par1World, double par2, double par4, double par6, ItemStack par8ItemStack) { + super(par1World, par2, par4, par6); + this.potionDamage = par8ItemStack; + } + + /** + * Gets the amount of gravity to apply to the thrown entity with each tick. + */ + protected float getGravityVelocity() { + return 0.05F; + } + + protected float func_70182_d() { + return 0.5F; + } + + protected float func_70183_g() { + return -20.0F; + } + + public void setPotionDamage(int par1) { + if (this.potionDamage == null) { + this.potionDamage = new ItemStack(Item.potion, 1, 0); + } + + this.potionDamage.setItemDamage(par1); + } + + /** + * Returns the damage value of the thrown potion that this EntityPotion + * represents. + */ + public int getPotionDamage() { + if (this.potionDamage == null) { + this.potionDamage = new ItemStack(Item.potion, 1, 0); + } + + return this.potionDamage.getItemDamage(); + } + + /** + * Called when this EntityThrowable hits a block or entity. + */ + protected void onImpact(MovingObjectPosition par1MovingObjectPosition) { + if (!this.worldObj.isRemote) { + List var2 = Item.potion.getEffects(this.potionDamage); + + if (var2 != null && !var2.isEmpty()) { + AxisAlignedBB var3 = this.boundingBox.expand(4.0D, 2.0D, 4.0D); + List var4 = this.worldObj.getEntitiesWithinAABB(EntityLiving.class, var3); + + if (var4 != null && !var4.isEmpty()) { + Iterator var5 = var4.iterator(); + + while (var5.hasNext()) { + EntityLiving var6 = (EntityLiving) var5.next(); + double var7 = this.getDistanceSqToEntity(var6); + + if (var7 < 16.0D) { + double var9 = 1.0D - Math.sqrt(var7) / 4.0D; + + if (var6 == par1MovingObjectPosition.entityHit) { + var9 = 1.0D; + } + + Iterator var11 = var2.iterator(); + + while (var11.hasNext()) { + PotionEffect var12 = (PotionEffect) var11.next(); + int var13 = var12.getPotionID(); + + if (Potion.potionTypes[var13].isInstant()) { + Potion.potionTypes[var13].affectEntity(this.getThrower(), var6, + var12.getAmplifier(), var9); + } else { + int var14 = (int) (var9 * (double) var12.getDuration() + 0.5D); + + if (var14 > 20) { + var6.addPotionEffect(new PotionEffect(var13, var14, var12.getAmplifier())); + } + } + } + } + } + } + } + + this.worldObj.playAuxSFX(2002, (int) Math.round(this.posX), (int) Math.round(this.posY), + (int) Math.round(this.posZ), this.getPotionDamage()); + this.setDead(); + } + } + + /** + * (abstract) Protected helper method to read subclass entity data from NBT. + */ + public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) { + super.readEntityFromNBT(par1NBTTagCompound); + + if (par1NBTTagCompound.hasKey("Potion")) { + this.potionDamage = ItemStack.loadItemStackFromNBT(par1NBTTagCompound.getCompoundTag("Potion")); + } else { + this.setPotionDamage(par1NBTTagCompound.getInteger("potionValue")); + } + + if (this.potionDamage == null) { + this.setDead(); + } + } + + /** + * (abstract) Protected helper method to write subclass entity data to NBT. + */ + public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) { + super.writeEntityToNBT(par1NBTTagCompound); + + if (this.potionDamage != null) { + par1NBTTagCompound.setCompoundTag("Potion", this.potionDamage.writeToNBT(new NBTTagCompound())); + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntitySelectorAlive.java b/sp-server/src/main/java/net/minecraft/src/EntitySelectorAlive.java new file mode 100644 index 0000000..29b843f --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntitySelectorAlive.java @@ -0,0 +1,10 @@ +package net.minecraft.src; + +final class EntitySelectorAlive implements IEntitySelector { + /** + * Return whether the specified entity is applicable to this filter. + */ + public boolean isEntityApplicable(Entity par1Entity) { + return par1Entity.isEntityAlive(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntitySelectorArmoredMob.java b/sp-server/src/main/java/net/minecraft/src/EntitySelectorArmoredMob.java new file mode 100644 index 0000000..3c5749d --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntitySelectorArmoredMob.java @@ -0,0 +1,24 @@ +package net.minecraft.src; + +public class EntitySelectorArmoredMob implements IEntitySelector { + private final ItemStack field_96567_c; + + public EntitySelectorArmoredMob(ItemStack par1ItemStack) { + this.field_96567_c = par1ItemStack; + } + + /** + * Return whether the specified entity is applicable to this filter. + */ + public boolean isEntityApplicable(Entity par1Entity) { + if (!par1Entity.isEntityAlive()) { + return false; + } else if (!(par1Entity instanceof EntityLiving)) { + return false; + } else { + EntityLiving var2 = (EntityLiving) par1Entity; + return var2.getEquipmentInSlot(EntityLiving.getArmorPosition(this.field_96567_c)) != null ? false + : var2.canPickUpLoot() || var2 instanceof EntityPlayer; + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntitySelectorInventory.java b/sp-server/src/main/java/net/minecraft/src/EntitySelectorInventory.java new file mode 100644 index 0000000..06eaf87 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntitySelectorInventory.java @@ -0,0 +1,10 @@ +package net.minecraft.src; + +final class EntitySelectorInventory implements IEntitySelector { + /** + * Return whether the specified entity is applicable to this filter. + */ + public boolean isEntityApplicable(Entity par1Entity) { + return par1Entity instanceof IInventory && par1Entity.isEntityAlive(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntitySenses.java b/sp-server/src/main/java/net/minecraft/src/EntitySenses.java new file mode 100644 index 0000000..da16d28 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntitySenses.java @@ -0,0 +1,50 @@ +package net.minecraft.src; + +import java.util.ArrayList; +import java.util.List; + +public class EntitySenses { + EntityLiving entityObj; + + /** Cache of entities which we can see */ + List seenEntities = new ArrayList(); + + /** Cache of entities which we cannot see */ + List unseenEntities = new ArrayList(); + + public EntitySenses(EntityLiving par1EntityLiving) { + this.entityObj = par1EntityLiving; + } + + /** + * Clears canSeeCachePositive and canSeeCacheNegative. + */ + public void clearSensingCache() { + this.seenEntities.clear(); + this.unseenEntities.clear(); + } + + /** + * Checks, whether 'our' entity can see the entity given as argument (true) or + * not (false), caching the result. + */ + public boolean canSee(Entity par1Entity) { + if (this.seenEntities.contains(par1Entity)) { + return true; + } else if (this.unseenEntities.contains(par1Entity)) { + return false; + } else { + this.entityObj.worldObj.theProfiler.startSection("canSee"); + boolean var2 = this.entityObj.canEntityBeSeen(par1Entity); + this.entityObj.worldObj.theProfiler.endSection(); + + if (var2) { + this.seenEntities.add(par1Entity); + } else { + this.unseenEntities.add(par1Entity); + } + + return var2; + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntitySheep.java b/sp-server/src/main/java/net/minecraft/src/EntitySheep.java new file mode 100644 index 0000000..b4476c1 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntitySheep.java @@ -0,0 +1,267 @@ +package net.minecraft.src; + +import java.util.Random; + +public class EntitySheep extends EntityAnimal { + private final InventoryCrafting field_90016_e = new InventoryCrafting(new ContainerSheep(this), 2, 1); + + /** + * Holds the RGB table of the sheep colors - in OpenGL glColor3f values - used + * to render the sheep colored fleece. + */ + public static final float[][] fleeceColorTable = new float[][] { { 1.0F, 1.0F, 1.0F }, { 0.85F, 0.5F, 0.2F }, + { 0.7F, 0.3F, 0.85F }, { 0.4F, 0.6F, 0.85F }, { 0.9F, 0.9F, 0.2F }, { 0.5F, 0.8F, 0.1F }, + { 0.95F, 0.5F, 0.65F }, { 0.3F, 0.3F, 0.3F }, { 0.6F, 0.6F, 0.6F }, { 0.3F, 0.5F, 0.6F }, + { 0.5F, 0.25F, 0.7F }, { 0.2F, 0.3F, 0.7F }, { 0.4F, 0.3F, 0.2F }, { 0.4F, 0.5F, 0.2F }, + { 0.6F, 0.2F, 0.2F }, { 0.1F, 0.1F, 0.1F } }; + + /** + * Used to control movement as well as wool regrowth. Set to 40 on + * handleHealthUpdate and counts down with each tick. + */ + private int sheepTimer; + + /** The eat grass AI task for this mob. */ + private EntityAIEatGrass aiEatGrass = new EntityAIEatGrass(this); + + public EntitySheep(World par1World) { + super(par1World); + this.texture = "/mob/sheep.png"; + this.setSize(0.9F, 1.3F); + float var2 = 0.23F; + this.getNavigator().setAvoidsWater(true); + this.tasks.addTask(0, new EntityAISwimming(this)); + this.tasks.addTask(1, new EntityAIPanic(this, 0.38F)); + this.tasks.addTask(2, new EntityAIMate(this, var2)); + this.tasks.addTask(3, new EntityAITempt(this, 0.25F, Item.wheat.itemID, false)); + this.tasks.addTask(4, new EntityAIFollowParent(this, 0.25F)); + this.tasks.addTask(5, this.aiEatGrass); + this.tasks.addTask(6, new EntityAIWander(this, var2)); + this.tasks.addTask(7, new EntityAIWatchClosest(this, EntityPlayer.class, 6.0F)); + this.tasks.addTask(8, new EntityAILookIdle(this)); + this.field_90016_e.setInventorySlotContents(0, new ItemStack(Item.dyePowder, 1, 0)); + this.field_90016_e.setInventorySlotContents(1, new ItemStack(Item.dyePowder, 1, 0)); + } + + /** + * Returns true if the newer Entity AI code should be run + */ + protected boolean isAIEnabled() { + return true; + } + + protected void updateAITasks() { + this.sheepTimer = this.aiEatGrass.getEatGrassTick(); + super.updateAITasks(); + } + + /** + * Called frequently so the entity can update its state every tick as required. + * For example, zombies and skeletons use this to react to sunlight and start to + * burn. + */ + public void onLivingUpdate() { + if (this.worldObj.isRemote) { + this.sheepTimer = Math.max(0, this.sheepTimer - 1); + } + + super.onLivingUpdate(); + } + + public int getMaxHealth() { + return 8; + } + + protected void entityInit() { + super.entityInit(); + this.dataWatcher.addObject(16, new Byte((byte) 0)); + } + + /** + * Drop 0-2 items of this living's type + */ + protected void dropFewItems(boolean par1, int par2) { + if (!this.getSheared()) { + this.entityDropItem(new ItemStack(Block.cloth.blockID, 1, this.getFleeceColor()), 0.0F); + } + } + + /** + * Returns the item ID for the item the mob drops on death. + */ + protected int getDropItemId() { + return Block.cloth.blockID; + } + + /** + * Called when a player interacts with a mob. e.g. gets milk from a cow, gets + * into the saddle on a pig. + */ + public boolean interact(EntityPlayer par1EntityPlayer) { + ItemStack var2 = par1EntityPlayer.inventory.getCurrentItem(); + + if (var2 != null && var2.itemID == Item.shears.itemID && !this.getSheared() && !this.isChild()) { + if (!this.worldObj.isRemote) { + this.setSheared(true); + int var3 = 1 + this.rand.nextInt(3); + + for (int var4 = 0; var4 < var3; ++var4) { + EntityItem var5 = this.entityDropItem(new ItemStack(Block.cloth.blockID, 1, this.getFleeceColor()), + 1.0F); + var5.motionY += (double) (this.rand.nextFloat() * 0.05F); + var5.motionX += (double) ((this.rand.nextFloat() - this.rand.nextFloat()) * 0.1F); + var5.motionZ += (double) ((this.rand.nextFloat() - this.rand.nextFloat()) * 0.1F); + } + } + + var2.damageItem(1, par1EntityPlayer); + this.playSound("mob.sheep.shear", 1.0F, 1.0F); + } + + return super.interact(par1EntityPlayer); + } + + /** + * (abstract) Protected helper method to write subclass entity data to NBT. + */ + public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) { + super.writeEntityToNBT(par1NBTTagCompound); + par1NBTTagCompound.setBoolean("Sheared", this.getSheared()); + par1NBTTagCompound.setByte("Color", (byte) this.getFleeceColor()); + } + + /** + * (abstract) Protected helper method to read subclass entity data from NBT. + */ + public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) { + super.readEntityFromNBT(par1NBTTagCompound); + this.setSheared(par1NBTTagCompound.getBoolean("Sheared")); + this.setFleeceColor(par1NBTTagCompound.getByte("Color")); + } + + /** + * Returns the sound this mob makes while it's alive. + */ + protected String getLivingSound() { + return "mob.sheep.say"; + } + + /** + * Returns the sound this mob makes when it is hurt. + */ + protected String getHurtSound() { + return "mob.sheep.say"; + } + + /** + * Returns the sound this mob makes on death. + */ + protected String getDeathSound() { + return "mob.sheep.say"; + } + + /** + * Plays step sound at given x, y, z for the entity + */ + protected void playStepSound(int par1, int par2, int par3, int par4) { + this.playSound("mob.sheep.step", 0.15F, 1.0F); + } + + public int getFleeceColor() { + return this.dataWatcher.getWatchableObjectByte(16) & 15; + } + + public void setFleeceColor(int par1) { + byte var2 = this.dataWatcher.getWatchableObjectByte(16); + this.dataWatcher.updateObject(16, Byte.valueOf((byte) (var2 & 240 | par1 & 15))); + } + + /** + * returns true if a sheeps wool has been sheared + */ + public boolean getSheared() { + return (this.dataWatcher.getWatchableObjectByte(16) & 16) != 0; + } + + /** + * make a sheep sheared if set to true + */ + public void setSheared(boolean par1) { + byte var2 = this.dataWatcher.getWatchableObjectByte(16); + + if (par1) { + this.dataWatcher.updateObject(16, Byte.valueOf((byte) (var2 | 16))); + } else { + this.dataWatcher.updateObject(16, Byte.valueOf((byte) (var2 & -17))); + } + } + + /** + * This method is called when a sheep spawns in the world to select the color of + * sheep fleece. + */ + public static int getRandomFleeceColor(Random par0Random) { + int var1 = par0Random.nextInt(100); + return var1 < 5 ? 15 + : (var1 < 10 ? 7 : (var1 < 15 ? 8 : (var1 < 18 ? 12 : (par0Random.nextInt(500) == 0 ? 6 : 0)))); + } + + public EntitySheep func_90015_b(EntityAgeable par1EntityAgeable) { + EntitySheep var2 = (EntitySheep) par1EntityAgeable; + EntitySheep var3 = new EntitySheep(this.worldObj); + int var4 = this.func_90014_a(this, var2); + var3.setFleeceColor(15 - var4); + return var3; + } + + /** + * This function applies the benefits of growing back wool and faster growing up + * to the acting entity. (This function is used in the AIEatGrass) + */ + public void eatGrassBonus() { + this.setSheared(false); + + if (this.isChild()) { + int var1 = this.getGrowingAge() + 1200; + + if (var1 > 0) { + var1 = 0; + } + + this.setGrowingAge(var1); + } + } + + /** + * Initialize this creature. + */ + public void initCreature() { + this.setFleeceColor(getRandomFleeceColor(this.worldObj.rand)); + } + + private int func_90014_a(EntityAnimal par1EntityAnimal, EntityAnimal par2EntityAnimal) { + int var3 = this.func_90013_b(par1EntityAnimal); + int var4 = this.func_90013_b(par2EntityAnimal); + this.field_90016_e.getStackInSlot(0).setItemDamage(var3); + this.field_90016_e.getStackInSlot(1).setItemDamage(var4); + ItemStack var5 = CraftingManager.getInstance().findMatchingRecipe(this.field_90016_e, + ((EntitySheep) par1EntityAnimal).worldObj); + int var6; + + if (var5 != null && var5.getItem().itemID == Item.dyePowder.itemID) { + var6 = var5.getItemDamage(); + } else { + var6 = this.worldObj.rand.nextBoolean() ? var3 : var4; + } + + return var6; + } + + private int func_90013_b(EntityAnimal par1EntityAnimal) { + return 15 - ((EntitySheep) par1EntityAnimal).getFleeceColor(); + } + + public EntityAgeable createChild(EntityAgeable par1EntityAgeable) { + return this.func_90015_b(par1EntityAgeable); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntitySilverfish.java b/sp-server/src/main/java/net/minecraft/src/EntitySilverfish.java new file mode 100644 index 0000000..113579f --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntitySilverfish.java @@ -0,0 +1,214 @@ +package net.minecraft.src; + +public class EntitySilverfish extends EntityMob { + /** + * A cooldown before this entity will search for another Silverfish to join them + * in battle. + */ + private int allySummonCooldown; + + public EntitySilverfish(World par1World) { + super(par1World); + this.texture = "/mob/silverfish.png"; + this.setSize(0.3F, 0.7F); + this.moveSpeed = 0.6F; + } + + public int getMaxHealth() { + return 8; + } + + /** + * returns if this entity triggers Block.onEntityWalking on the blocks they walk + * on. used for spiders and wolves to prevent them from trampling crops + */ + protected boolean canTriggerWalking() { + return false; + } + + /** + * Finds the closest player within 16 blocks to attack, or null if this Entity + * isn't interested in attacking (Animals, Spiders at day, peaceful PigZombies). + */ + protected Entity findPlayerToAttack() { + double var1 = 8.0D; + return this.worldObj.getClosestVulnerablePlayerToEntity(this, var1); + } + + /** + * Returns the sound this mob makes while it's alive. + */ + protected String getLivingSound() { + return "mob.silverfish.say"; + } + + /** + * Returns the sound this mob makes when it is hurt. + */ + protected String getHurtSound() { + return "mob.silverfish.hit"; + } + + /** + * Returns the sound this mob makes on death. + */ + protected String getDeathSound() { + return "mob.silverfish.kill"; + } + + /** + * Called when the entity is attacked. + */ + public boolean attackEntityFrom(DamageSource par1DamageSource, int par2) { + if (this.isEntityInvulnerable()) { + return false; + } else { + if (this.allySummonCooldown <= 0 + && (par1DamageSource instanceof EntityDamageSource || par1DamageSource == DamageSource.magic)) { + this.allySummonCooldown = 20; + } + + return super.attackEntityFrom(par1DamageSource, par2); + } + } + + /** + * Basic mob attack. Default to touch of death in EntityCreature. Overridden by + * each mob to define their attack. + */ + protected void attackEntity(Entity par1Entity, float par2) { + if (this.attackTime <= 0 && par2 < 1.2F && par1Entity.boundingBox.maxY > this.boundingBox.minY + && par1Entity.boundingBox.minY < this.boundingBox.maxY) { + this.attackTime = 20; + this.attackEntityAsMob(par1Entity); + } + } + + /** + * Plays step sound at given x, y, z for the entity + */ + protected void playStepSound(int par1, int par2, int par3, int par4) { + this.playSound("mob.silverfish.step", 0.15F, 1.0F); + } + + /** + * Returns the item ID for the item the mob drops on death. + */ + protected int getDropItemId() { + return 0; + } + + /** + * Called to update the entity's position/logic. + */ + public void onUpdate() { + this.renderYawOffset = this.rotationYaw; + super.onUpdate(); + } + + protected void updateEntityActionState() { + super.updateEntityActionState(); + + if (!this.worldObj.isRemote) { + int var1; + int var2; + int var3; + int var5; + + if (this.allySummonCooldown > 0) { + --this.allySummonCooldown; + + if (this.allySummonCooldown == 0) { + var1 = MathHelper.floor_double(this.posX); + var2 = MathHelper.floor_double(this.posY); + var3 = MathHelper.floor_double(this.posZ); + boolean var4 = false; + + for (var5 = 0; !var4 && var5 <= 5 && var5 >= -5; var5 = var5 <= 0 ? 1 - var5 : 0 - var5) { + for (int var6 = 0; !var4 && var6 <= 10 && var6 >= -10; var6 = var6 <= 0 ? 1 - var6 : 0 - var6) { + for (int var7 = 0; !var4 && var7 <= 10 + && var7 >= -10; var7 = var7 <= 0 ? 1 - var7 : 0 - var7) { + int var8 = this.worldObj.getBlockId(var1 + var6, var2 + var5, var3 + var7); + + if (var8 == Block.silverfish.blockID) { + this.worldObj.destroyBlock(var1 + var6, var2 + var5, var3 + var7, false); + Block.silverfish.onBlockDestroyedByPlayer(this.worldObj, var1 + var6, var2 + var5, + var3 + var7, 0); + + if (this.rand.nextBoolean()) { + var4 = true; + break; + } + } + } + } + } + } + } + + if (this.entityToAttack == null && !this.hasPath()) { + var1 = MathHelper.floor_double(this.posX); + var2 = MathHelper.floor_double(this.posY + 0.5D); + var3 = MathHelper.floor_double(this.posZ); + int var9 = this.rand.nextInt(6); + var5 = this.worldObj.getBlockId(var1 + Facing.offsetsXForSide[var9], + var2 + Facing.offsetsYForSide[var9], var3 + Facing.offsetsZForSide[var9]); + + if (BlockSilverfish.getPosingIdByMetadata(var5)) { + this.worldObj.setBlock(var1 + Facing.offsetsXForSide[var9], var2 + Facing.offsetsYForSide[var9], + var3 + Facing.offsetsZForSide[var9], Block.silverfish.blockID, + BlockSilverfish.getMetadataForBlockType(var5), 3); + this.spawnExplosionParticle(); + this.setDead(); + } else { + this.updateWanderPath(); + } + } else if (this.entityToAttack != null && !this.hasPath()) { + this.entityToAttack = null; + } + } + } + + /** + * Takes a coordinate in and returns a weight to determine how likely this + * creature will try to path to the block. Args: x, y, z + */ + public float getBlockPathWeight(int par1, int par2, int par3) { + return this.worldObj.getBlockId(par1, par2 - 1, par3) == Block.stone.blockID ? 10.0F + : super.getBlockPathWeight(par1, par2, par3); + } + + /** + * Checks to make sure the light is not too bright where the mob is spawning + */ + protected boolean isValidLightLevel() { + return true; + } + + /** + * Checks if the entity's current position is a valid location to spawn this + * entity. + */ + public boolean getCanSpawnHere() { + if (super.getCanSpawnHere()) { + EntityPlayer var1 = this.worldObj.getClosestPlayerToEntity(this, 5.0D); + return var1 == null; + } else { + return false; + } + } + + /** + * Returns the amount of damage a mob should deal. + */ + public int getAttackStrength(Entity par1Entity) { + return 1; + } + + /** + * Get this Entity's EnumCreatureAttribute + */ + public EnumCreatureAttribute getCreatureAttribute() { + return EnumCreatureAttribute.ARTHROPOD; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntitySkeleton.java b/sp-server/src/main/java/net/minecraft/src/EntitySkeleton.java new file mode 100644 index 0000000..d1453e4 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntitySkeleton.java @@ -0,0 +1,341 @@ +package net.minecraft.src; + +import java.util.Calendar; + +public class EntitySkeleton extends EntityMob implements IRangedAttackMob { + private EntityAIArrowAttack aiArrowAttack = new EntityAIArrowAttack(this, 0.25F, 20, 60, 15.0F); + private EntityAIAttackOnCollide aiAttackOnCollide = new EntityAIAttackOnCollide(this, EntityPlayer.class, 0.31F, + false); + + public EntitySkeleton(World par1World) { + super(par1World); + this.texture = "/mob/skeleton.png"; + this.moveSpeed = 0.25F; + this.tasks.addTask(1, new EntityAISwimming(this)); + this.tasks.addTask(2, new EntityAIRestrictSun(this)); + this.tasks.addTask(3, new EntityAIFleeSun(this, this.moveSpeed)); + this.tasks.addTask(5, new EntityAIWander(this, this.moveSpeed)); + this.tasks.addTask(6, new EntityAIWatchClosest(this, EntityPlayer.class, 8.0F)); + this.tasks.addTask(6, new EntityAILookIdle(this)); + this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, false)); + this.targetTasks.addTask(2, new EntityAINearestAttackableTarget(this, EntityPlayer.class, 16.0F, 0, true)); + + if (par1World != null && !par1World.isRemote) { + this.setCombatTask(); + } + } + + protected void entityInit() { + super.entityInit(); + this.dataWatcher.addObject(13, new Byte((byte) 0)); + } + + /** + * Returns true if the newer Entity AI code should be run + */ + public boolean isAIEnabled() { + return true; + } + + public int getMaxHealth() { + return 20; + } + + /** + * Returns the sound this mob makes while it's alive. + */ + protected String getLivingSound() { + return "mob.skeleton.say"; + } + + /** + * Returns the sound this mob makes when it is hurt. + */ + protected String getHurtSound() { + return "mob.skeleton.hurt"; + } + + /** + * Returns the sound this mob makes on death. + */ + protected String getDeathSound() { + return "mob.skeleton.death"; + } + + /** + * Plays step sound at given x, y, z for the entity + */ + protected void playStepSound(int par1, int par2, int par3, int par4) { + this.playSound("mob.skeleton.step", 0.15F, 1.0F); + } + + public boolean attackEntityAsMob(Entity par1Entity) { + if (super.attackEntityAsMob(par1Entity)) { + if (this.getSkeletonType() == 1 && par1Entity instanceof EntityLiving) { + ((EntityLiving) par1Entity).addPotionEffect(new PotionEffect(Potion.wither.id, 200)); + } + + return true; + } else { + return false; + } + } + + /** + * Returns the amount of damage a mob should deal. + */ + public int getAttackStrength(Entity par1Entity) { + if (this.getSkeletonType() == 1) { + ItemStack var2 = this.getHeldItem(); + int var3 = 4; + + if (var2 != null) { + var3 += var2.getDamageVsEntity(this); + } + + return var3; + } else { + return super.getAttackStrength(par1Entity); + } + } + + /** + * Get this Entity's EnumCreatureAttribute + */ + public EnumCreatureAttribute getCreatureAttribute() { + return EnumCreatureAttribute.UNDEAD; + } + + /** + * Called frequently so the entity can update its state every tick as required. + * For example, zombies and skeletons use this to react to sunlight and start to + * burn. + */ + public void onLivingUpdate() { + if (this.worldObj.isDaytime() && !this.worldObj.isRemote) { + float var1 = this.getBrightness(1.0F); + + if (var1 > 0.5F && this.rand.nextFloat() * 30.0F < (var1 - 0.4F) * 2.0F + && this.worldObj.canBlockSeeTheSky(MathHelper.floor_double(this.posX), + MathHelper.floor_double(this.posY), MathHelper.floor_double(this.posZ))) { + boolean var2 = true; + ItemStack var3 = this.getEquipmentInSlot(4); + + if (var3 != null) { + if (var3.isItemStackDamageable()) { + var3.setItemDamage(var3.getItemDamageForDisplay() + this.rand.nextInt(2)); + + if (var3.getItemDamageForDisplay() >= var3.getMaxDamage()) { + this.renderBrokenItemStack(var3); + this.setCurrentItemOrArmor(4, (ItemStack) null); + } + } + + var2 = false; + } + + if (var2) { + this.setFire(8); + } + } + } + + if (this.worldObj.isRemote && this.getSkeletonType() == 1) { + this.setSize(0.72F, 2.34F); + } + + super.onLivingUpdate(); + } + + /** + * Called when the mob's health reaches 0. + */ + public void onDeath(DamageSource par1DamageSource) { + super.onDeath(par1DamageSource); + + if (par1DamageSource.getSourceOfDamage() instanceof EntityArrow + && par1DamageSource.getEntity() instanceof EntityPlayer) { + EntityPlayer var2 = (EntityPlayer) par1DamageSource.getEntity(); + double var3 = var2.posX - this.posX; + double var5 = var2.posZ - this.posZ; + + if (var3 * var3 + var5 * var5 >= 2500.0D) { + var2.triggerAchievement(AchievementList.snipeSkeleton); + } + } + } + + /** + * Returns the item ID for the item the mob drops on death. + */ + protected int getDropItemId() { + return Item.arrow.itemID; + } + + /** + * Drop 0-2 items of this living's type + */ + protected void dropFewItems(boolean par1, int par2) { + int var3; + int var4; + + if (this.getSkeletonType() == 1) { + var3 = this.rand.nextInt(3 + par2) - 1; + + for (var4 = 0; var4 < var3; ++var4) { + this.dropItem(Item.coal.itemID, 1); + } + } else { + var3 = this.rand.nextInt(3 + par2); + + for (var4 = 0; var4 < var3; ++var4) { + this.dropItem(Item.arrow.itemID, 1); + } + } + + var3 = this.rand.nextInt(3 + par2); + + for (var4 = 0; var4 < var3; ++var4) { + this.dropItem(Item.bone.itemID, 1); + } + } + + protected void dropRareDrop(int par1) { + if (this.getSkeletonType() == 1) { + this.entityDropItem(new ItemStack(Item.skull.itemID, 1, 1), 0.0F); + } + } + + /** + * Makes entity wear random armor based on difficulty + */ + protected void addRandomArmor() { + super.addRandomArmor(); + this.setCurrentItemOrArmor(0, new ItemStack(Item.bow)); + } + + /** + * Initialize this creature. + */ + public void initCreature() { + if (this.worldObj.provider instanceof WorldProviderHell && this.getRNG().nextInt(5) > 0) { + this.tasks.addTask(4, this.aiAttackOnCollide); + this.setSkeletonType(1); + this.setCurrentItemOrArmor(0, new ItemStack(Item.swordStone)); + } else { + this.tasks.addTask(4, this.aiArrowAttack); + this.addRandomArmor(); + this.func_82162_bC(); + } + + this.setCanPickUpLoot(this.rand.nextFloat() < pickUpLootProability[this.worldObj.difficultySetting]); + + if (this.getEquipmentInSlot(4) == null) { + Calendar var1 = this.worldObj.getCurrentDate(); + + if (var1.get(2) + 1 == 10 && var1.get(5) == 31 && this.rand.nextFloat() < 0.25F) { + this.setCurrentItemOrArmor(4, + new ItemStack(this.rand.nextFloat() < 0.1F ? Block.pumpkinLantern : Block.pumpkin)); + this.equipmentDropChances[4] = 0.0F; + } + } + } + + /** + * sets this entity's combat AI. + */ + public void setCombatTask() { + this.tasks.removeTask(this.aiAttackOnCollide); + this.tasks.removeTask(this.aiArrowAttack); + ItemStack var1 = this.getHeldItem(); + + if (var1 != null && var1.itemID == Item.bow.itemID) { + this.tasks.addTask(4, this.aiArrowAttack); + } else { + this.tasks.addTask(4, this.aiAttackOnCollide); + } + } + + /** + * Attack the specified entity using a ranged attack. + */ + public void attackEntityWithRangedAttack(EntityLiving par1EntityLiving, float par2) { + EntityArrow var3 = new EntityArrow(this.worldObj, this, par1EntityLiving, 1.6F, + (float) (14 - this.worldObj.difficultySetting * 4)); + int var4 = EnchantmentHelper.getEnchantmentLevel(Enchantment.power.effectId, this.getHeldItem()); + int var5 = EnchantmentHelper.getEnchantmentLevel(Enchantment.punch.effectId, this.getHeldItem()); + var3.setDamage((double) (par2 * 2.0F) + this.rand.nextGaussian() * 0.25D + + (double) ((float) this.worldObj.difficultySetting * 0.11F)); + + if (var4 > 0) { + var3.setDamage(var3.getDamage() + (double) var4 * 0.5D + 0.5D); + } + + if (var5 > 0) { + var3.setKnockbackStrength(var5); + } + + if (EnchantmentHelper.getEnchantmentLevel(Enchantment.flame.effectId, this.getHeldItem()) > 0 + || this.getSkeletonType() == 1) { + var3.setFire(100); + } + + this.playSound("random.bow", 1.0F, 1.0F / (this.getRNG().nextFloat() * 0.4F + 0.8F)); + this.worldObj.spawnEntityInWorld(var3); + } + + /** + * Return this skeleton's type. + */ + public int getSkeletonType() { + return this.dataWatcher.getWatchableObjectByte(13); + } + + /** + * Set this skeleton's type. + */ + public void setSkeletonType(int par1) { + this.dataWatcher.updateObject(13, Byte.valueOf((byte) par1)); + this.isImmuneToFire = par1 == 1; + + if (par1 == 1) { + this.setSize(0.72F, 2.34F); + } else { + this.setSize(0.6F, 1.8F); + } + } + + /** + * (abstract) Protected helper method to read subclass entity data from NBT. + */ + public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) { + super.readEntityFromNBT(par1NBTTagCompound); + + if (par1NBTTagCompound.hasKey("SkeletonType")) { + byte var2 = par1NBTTagCompound.getByte("SkeletonType"); + this.setSkeletonType(var2); + } + + this.setCombatTask(); + } + + /** + * (abstract) Protected helper method to write subclass entity data to NBT. + */ + public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) { + super.writeEntityToNBT(par1NBTTagCompound); + par1NBTTagCompound.setByte("SkeletonType", (byte) this.getSkeletonType()); + } + + /** + * Sets the held item, or an armor slot. Slot 0 is held item. Slot 1-4 is armor. + * Params: Item, slot + */ + public void setCurrentItemOrArmor(int par1, ItemStack par2ItemStack) { + super.setCurrentItemOrArmor(par1, par2ItemStack); + + if (!this.worldObj.isRemote && par1 == 0) { + this.setCombatTask(); + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntitySlime.java b/sp-server/src/main/java/net/minecraft/src/EntitySlime.java new file mode 100644 index 0000000..5eb2c3a --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntitySlime.java @@ -0,0 +1,308 @@ +package net.minecraft.src; + +public class EntitySlime extends EntityLiving implements IMob { + /** Chances for slimes to spawn in swamps for every moon phase. */ + private static final float[] spawnChances = new float[] { 1.0F, 0.75F, 0.5F, 0.25F, 0.0F, 0.25F, 0.5F, 0.75F }; + public float field_70813_a; + public float field_70811_b; + public float field_70812_c; + + /** ticks until this slime jumps again */ + private int slimeJumpDelay = 0; + + public EntitySlime(World par1World) { + super(par1World); + this.texture = "/mob/slime.png"; + int var2 = 1 << this.rand.nextInt(3); + this.yOffset = 0.0F; + this.slimeJumpDelay = this.rand.nextInt(20) + 10; + this.setSlimeSize(var2); + } + + protected void entityInit() { + super.entityInit(); + this.dataWatcher.addObject(16, new Byte((byte) 1)); + } + + protected void setSlimeSize(int par1) { + this.dataWatcher.updateObject(16, new Byte((byte) par1)); + this.setSize(0.6F * (float) par1, 0.6F * (float) par1); + this.setPosition(this.posX, this.posY, this.posZ); + this.setEntityHealth(this.getMaxHealth()); + this.experienceValue = par1; + } + + public int getMaxHealth() { + int var1 = this.getSlimeSize(); + return var1 * var1; + } + + /** + * Returns the size of the slime. + */ + public int getSlimeSize() { + return this.dataWatcher.getWatchableObjectByte(16); + } + + /** + * (abstract) Protected helper method to write subclass entity data to NBT. + */ + public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) { + super.writeEntityToNBT(par1NBTTagCompound); + par1NBTTagCompound.setInteger("Size", this.getSlimeSize() - 1); + } + + /** + * (abstract) Protected helper method to read subclass entity data from NBT. + */ + public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) { + super.readEntityFromNBT(par1NBTTagCompound); + this.setSlimeSize(par1NBTTagCompound.getInteger("Size") + 1); + } + + /** + * Returns the name of a particle effect that may be randomly created by + * EntitySlime.onUpdate() + */ + protected String getSlimeParticle() { + return "slime"; + } + + /** + * Returns the name of the sound played when the slime jumps. + */ + protected String getJumpSound() { + return "mob.slime." + (this.getSlimeSize() > 1 ? "big" : "small"); + } + + /** + * Called to update the entity's position/logic. + */ + public void onUpdate() { + if (!this.worldObj.isRemote && this.worldObj.difficultySetting == 0 && this.getSlimeSize() > 0) { + this.isDead = true; + } + + this.field_70811_b += (this.field_70813_a - this.field_70811_b) * 0.5F; + this.field_70812_c = this.field_70811_b; + boolean var1 = this.onGround; + super.onUpdate(); + int var2; + + if (this.onGround && !var1) { + var2 = this.getSlimeSize(); + + for (int var3 = 0; var3 < var2 * 8; ++var3) { + float var4 = this.rand.nextFloat() * (float) Math.PI * 2.0F; + float var5 = this.rand.nextFloat() * 0.5F + 0.5F; + float var6 = MathHelper.sin(var4) * (float) var2 * 0.5F * var5; + float var7 = MathHelper.cos(var4) * (float) var2 * 0.5F * var5; + this.worldObj.spawnParticle(this.getSlimeParticle(), this.posX + (double) var6, this.boundingBox.minY, + this.posZ + (double) var7, 0.0D, 0.0D, 0.0D); + } + + if (this.makesSoundOnLand()) { + this.playSound(this.getJumpSound(), this.getSoundVolume(), + ((this.rand.nextFloat() - this.rand.nextFloat()) * 0.2F + 1.0F) / 0.8F); + } + + this.field_70813_a = -0.5F; + } else if (!this.onGround && var1) { + this.field_70813_a = 1.0F; + } + + this.func_70808_l(); + + if (this.worldObj.isRemote) { + var2 = this.getSlimeSize(); + this.setSize(0.6F * (float) var2, 0.6F * (float) var2); + } + } + + protected void updateEntityActionState() { + this.despawnEntity(); + EntityPlayer var1 = this.worldObj.getClosestVulnerablePlayerToEntity(this, 16.0D); + + if (var1 != null) { + this.faceEntity(var1, 10.0F, 20.0F); + } + + if (this.onGround && this.slimeJumpDelay-- <= 0) { + this.slimeJumpDelay = this.getJumpDelay(); + + if (var1 != null) { + this.slimeJumpDelay /= 3; + } + + this.isJumping = true; + + if (this.makesSoundOnJump()) { + this.playSound(this.getJumpSound(), this.getSoundVolume(), + ((this.rand.nextFloat() - this.rand.nextFloat()) * 0.2F + 1.0F) * 0.8F); + } + + this.moveStrafing = 1.0F - this.rand.nextFloat() * 2.0F; + this.moveForward = (float) (1 * this.getSlimeSize()); + } else { + this.isJumping = false; + + if (this.onGround) { + this.moveStrafing = this.moveForward = 0.0F; + } + } + } + + protected void func_70808_l() { + this.field_70813_a *= 0.6F; + } + + /** + * Gets the amount of time the slime needs to wait between jumps. + */ + protected int getJumpDelay() { + return this.rand.nextInt(20) + 10; + } + + protected EntitySlime createInstance() { + return new EntitySlime(this.worldObj); + } + + /** + * Will get destroyed next tick. + */ + public void setDead() { + int var1 = this.getSlimeSize(); + + if (!this.worldObj.isRemote && var1 > 1 && this.getHealth() <= 0) { + int var2 = 2 + this.rand.nextInt(3); + + for (int var3 = 0; var3 < var2; ++var3) { + float var4 = ((float) (var3 % 2) - 0.5F) * (float) var1 / 4.0F; + float var5 = ((float) (var3 / 2) - 0.5F) * (float) var1 / 4.0F; + EntitySlime var6 = this.createInstance(); + var6.setSlimeSize(var1 / 2); + var6.setLocationAndAngles(this.posX + (double) var4, this.posY + 0.5D, this.posZ + (double) var5, + this.rand.nextFloat() * 360.0F, 0.0F); + this.worldObj.spawnEntityInWorld(var6); + } + } + + super.setDead(); + } + + /** + * Called by a player entity when they collide with an entity + */ + public void onCollideWithPlayer(EntityPlayer par1EntityPlayer) { + if (this.canDamagePlayer()) { + int var2 = this.getSlimeSize(); + + if (this.canEntityBeSeen(par1EntityPlayer) + && this.getDistanceSqToEntity(par1EntityPlayer) < 0.6D * (double) var2 * 0.6D * (double) var2 + && par1EntityPlayer.attackEntityFrom(DamageSource.causeMobDamage(this), this.getAttackStrength())) { + this.playSound("mob.attack", 1.0F, (this.rand.nextFloat() - this.rand.nextFloat()) * 0.2F + 1.0F); + } + } + } + + /** + * Indicates weather the slime is able to damage the player (based upon the + * slime's size) + */ + protected boolean canDamagePlayer() { + return this.getSlimeSize() > 1; + } + + /** + * Gets the amount of damage dealt to the player when "attacked" by the slime. + */ + protected int getAttackStrength() { + return this.getSlimeSize(); + } + + /** + * Returns the sound this mob makes when it is hurt. + */ + protected String getHurtSound() { + return "mob.slime." + (this.getSlimeSize() > 1 ? "big" : "small"); + } + + /** + * Returns the sound this mob makes on death. + */ + protected String getDeathSound() { + return "mob.slime." + (this.getSlimeSize() > 1 ? "big" : "small"); + } + + /** + * Returns the item ID for the item the mob drops on death. + */ + protected int getDropItemId() { + return this.getSlimeSize() == 1 ? Item.slimeBall.itemID : 0; + } + + /** + * Checks if the entity's current position is a valid location to spawn this + * entity. + */ + public boolean getCanSpawnHere() { + Chunk var1 = this.worldObj.getChunkFromBlockCoords(MathHelper.floor_double(this.posX), + MathHelper.floor_double(this.posZ)); + + if (this.worldObj.getWorldInfo().getTerrainType() == WorldType.FLAT && this.rand.nextInt(4) != 1) { + return false; + } else { + if (this.getSlimeSize() == 1 || this.worldObj.difficultySetting > 0) { + BiomeGenBase var2 = this.worldObj.getBiomeGenForCoords(MathHelper.floor_double(this.posX), + MathHelper.floor_double(this.posZ)); + + if (var2 == BiomeGenBase.swampland && this.posY > 50.0D && this.posY < 70.0D + && this.rand.nextFloat() < 0.5F + && this.rand.nextFloat() < spawnChances[this.worldObj.getMoonPhase()] + && this.worldObj.getBlockLightValue(MathHelper.floor_double(this.posX), + MathHelper.floor_double(this.posY), + MathHelper.floor_double(this.posZ)) <= this.rand.nextInt(8)) { + return super.getCanSpawnHere(); + } + + if (this.rand.nextInt(10) == 0 && var1.getRandomWithSeed(987234911L).nextInt(10) == 0 + && this.posY < 40.0D) { + return super.getCanSpawnHere(); + } + } + + return false; + } + } + + /** + * Returns the volume for the sounds this mob makes. + */ + protected float getSoundVolume() { + return 0.4F * (float) this.getSlimeSize(); + } + + /** + * The speed it takes to move the entityliving's rotationPitch through the + * faceEntity method. This is only currently use in wolves. + */ + public int getVerticalFaceSpeed() { + return 0; + } + + /** + * Returns true if the slime makes a sound when it jumps (based upon the slime's + * size) + */ + protected boolean makesSoundOnJump() { + return this.getSlimeSize() > 0; + } + + /** + * Returns true if the slime makes a sound when it lands after a jump (based + * upon the slime's size) + */ + protected boolean makesSoundOnLand() { + return this.getSlimeSize() > 2; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntitySmallFireball.java b/sp-server/src/main/java/net/minecraft/src/EntitySmallFireball.java new file mode 100644 index 0000000..9672175 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntitySmallFireball.java @@ -0,0 +1,83 @@ +package net.minecraft.src; + +public class EntitySmallFireball extends EntityFireball { + public EntitySmallFireball(World par1World) { + super(par1World); + this.setSize(0.3125F, 0.3125F); + } + + public EntitySmallFireball(World par1World, EntityLiving par2EntityLiving, double par3, double par5, double par7) { + super(par1World, par2EntityLiving, par3, par5, par7); + this.setSize(0.3125F, 0.3125F); + } + + public EntitySmallFireball(World par1World, double par2, double par4, double par6, double par8, double par10, + double par12) { + super(par1World, par2, par4, par6, par8, par10, par12); + this.setSize(0.3125F, 0.3125F); + } + + /** + * Called when this EntityFireball hits a block or entity. + */ + protected void onImpact(MovingObjectPosition par1MovingObjectPosition) { + if (!this.worldObj.isRemote) { + if (par1MovingObjectPosition.entityHit != null) { + if (!par1MovingObjectPosition.entityHit.isImmuneToFire() && par1MovingObjectPosition.entityHit + .attackEntityFrom(DamageSource.causeFireballDamage(this, this.shootingEntity), 5)) { + par1MovingObjectPosition.entityHit.setFire(5); + } + } else { + int var2 = par1MovingObjectPosition.blockX; + int var3 = par1MovingObjectPosition.blockY; + int var4 = par1MovingObjectPosition.blockZ; + + switch (par1MovingObjectPosition.sideHit) { + case 0: + --var3; + break; + + case 1: + ++var3; + break; + + case 2: + --var4; + break; + + case 3: + ++var4; + break; + + case 4: + --var2; + break; + + case 5: + ++var2; + } + + if (this.worldObj.isAirBlock(var2, var3, var4)) { + this.worldObj.setBlock(var2, var3, var4, Block.fire.blockID); + } + } + + this.setDead(); + } + } + + /** + * Returns true if other Entities should be prevented from moving through this + * Entity. + */ + public boolean canBeCollidedWith() { + return false; + } + + /** + * Called when the entity is attacked. + */ + public boolean attackEntityFrom(DamageSource par1DamageSource, int par2) { + return false; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntitySnowball.java b/sp-server/src/main/java/net/minecraft/src/EntitySnowball.java new file mode 100644 index 0000000..2d1eb77 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntitySnowball.java @@ -0,0 +1,39 @@ +package net.minecraft.src; + +public class EntitySnowball extends EntityThrowable { + public EntitySnowball(World par1World) { + super(par1World); + } + + public EntitySnowball(World par1World, EntityLiving par2EntityLiving) { + super(par1World, par2EntityLiving); + } + + public EntitySnowball(World par1World, double par2, double par4, double par6) { + super(par1World, par2, par4, par6); + } + + /** + * Called when this EntityThrowable hits a block or entity. + */ + protected void onImpact(MovingObjectPosition par1MovingObjectPosition) { + if (par1MovingObjectPosition.entityHit != null) { + byte var2 = 0; + + if (par1MovingObjectPosition.entityHit instanceof EntityBlaze) { + var2 = 3; + } + + par1MovingObjectPosition.entityHit.attackEntityFrom(DamageSource.causeThrownDamage(this, this.getThrower()), + var2); + } + + for (int var3 = 0; var3 < 8; ++var3) { + this.worldObj.spawnParticle("snowballpoof", this.posX, this.posY, this.posZ, 0.0D, 0.0D, 0.0D); + } + + if (!this.worldObj.isRemote) { + this.setDead(); + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntitySnowman.java b/sp-server/src/main/java/net/minecraft/src/EntitySnowman.java new file mode 100644 index 0000000..98ab96c --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntitySnowman.java @@ -0,0 +1,91 @@ +package net.minecraft.src; + +public class EntitySnowman extends EntityGolem implements IRangedAttackMob { + public EntitySnowman(World par1World) { + super(par1World); + this.texture = "/mob/snowman.png"; + this.setSize(0.4F, 1.8F); + this.getNavigator().setAvoidsWater(true); + this.tasks.addTask(1, new EntityAIArrowAttack(this, 0.25F, 20, 10.0F)); + this.tasks.addTask(2, new EntityAIWander(this, 0.2F)); + this.tasks.addTask(3, new EntityAIWatchClosest(this, EntityPlayer.class, 6.0F)); + this.tasks.addTask(4, new EntityAILookIdle(this)); + this.targetTasks.addTask(1, + new EntityAINearestAttackableTarget(this, EntityLiving.class, 16.0F, 0, true, false, IMob.mobSelector)); + } + + /** + * Returns true if the newer Entity AI code should be run + */ + public boolean isAIEnabled() { + return true; + } + + public int getMaxHealth() { + return 4; + } + + /** + * Called frequently so the entity can update its state every tick as required. + * For example, zombies and skeletons use this to react to sunlight and start to + * burn. + */ + public void onLivingUpdate() { + super.onLivingUpdate(); + + if (this.isWet()) { + this.attackEntityFrom(DamageSource.drown, 1); + } + + int var1 = MathHelper.floor_double(this.posX); + int var2 = MathHelper.floor_double(this.posZ); + + if (this.worldObj.getBiomeGenForCoords(var1, var2).getFloatTemperature() > 1.0F) { + this.attackEntityFrom(DamageSource.onFire, 1); + } + + for (var1 = 0; var1 < 4; ++var1) { + var2 = MathHelper.floor_double(this.posX + (double) ((float) (var1 % 2 * 2 - 1) * 0.25F)); + int var3 = MathHelper.floor_double(this.posY); + int var4 = MathHelper.floor_double(this.posZ + (double) ((float) (var1 / 2 % 2 * 2 - 1) * 0.25F)); + + if (this.worldObj.getBlockId(var2, var3, var4) == 0 + && this.worldObj.getBiomeGenForCoords(var2, var4).getFloatTemperature() < 0.8F + && Block.snow.canPlaceBlockAt(this.worldObj, var2, var3, var4)) { + this.worldObj.setBlock(var2, var3, var4, Block.snow.blockID); + } + } + } + + /** + * Returns the item ID for the item the mob drops on death. + */ + protected int getDropItemId() { + return Item.snowball.itemID; + } + + /** + * Drop 0-2 items of this living's type + */ + protected void dropFewItems(boolean par1, int par2) { + int var3 = this.rand.nextInt(16); + + for (int var4 = 0; var4 < var3; ++var4) { + this.dropItem(Item.snowball.itemID, 1); + } + } + + /** + * Attack the specified entity using a ranged attack. + */ + public void attackEntityWithRangedAttack(EntityLiving par1EntityLiving, float par2) { + EntitySnowball var3 = new EntitySnowball(this.worldObj, this); + double var4 = par1EntityLiving.posX - this.posX; + double var6 = par1EntityLiving.posY + (double) par1EntityLiving.getEyeHeight() - 1.100000023841858D - var3.posY; + double var8 = par1EntityLiving.posZ - this.posZ; + float var10 = MathHelper.sqrt_double(var4 * var4 + var8 * var8) * 0.2F; + var3.setThrowableHeading(var4, var6 + (double) var10, var8, 1.6F, 12.0F); + this.playSound("random.bow", 1.0F, 1.0F / (this.getRNG().nextFloat() * 0.4F + 0.8F)); + this.worldObj.spawnEntityInWorld(var3); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntitySpider.java b/sp-server/src/main/java/net/minecraft/src/EntitySpider.java new file mode 100644 index 0000000..bd61884 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntitySpider.java @@ -0,0 +1,187 @@ +package net.minecraft.src; + +public class EntitySpider extends EntityMob { + public EntitySpider(World par1World) { + super(par1World); + this.texture = "/mob/spider.png"; + this.setSize(1.4F, 0.9F); + this.moveSpeed = 0.8F; + } + + protected void entityInit() { + super.entityInit(); + this.dataWatcher.addObject(16, new Byte((byte) 0)); + } + + /** + * Called to update the entity's position/logic. + */ + public void onUpdate() { + super.onUpdate(); + + if (!this.worldObj.isRemote) { + this.setBesideClimbableBlock(this.isCollidedHorizontally); + } + } + + public int getMaxHealth() { + return 16; + } + + /** + * Returns the Y offset from the entity's position for any entity riding this + * one. + */ + public double getMountedYOffset() { + return (double) this.height * 0.75D - 0.5D; + } + + /** + * Finds the closest player within 16 blocks to attack, or null if this Entity + * isn't interested in attacking (Animals, Spiders at day, peaceful PigZombies). + */ + protected Entity findPlayerToAttack() { + float var1 = this.getBrightness(1.0F); + + if (var1 < 0.5F) { + double var2 = 16.0D; + return this.worldObj.getClosestVulnerablePlayerToEntity(this, var2); + } else { + return null; + } + } + + /** + * Returns the sound this mob makes while it's alive. + */ + protected String getLivingSound() { + return "mob.spider.say"; + } + + /** + * Returns the sound this mob makes when it is hurt. + */ + protected String getHurtSound() { + return "mob.spider.say"; + } + + /** + * Returns the sound this mob makes on death. + */ + protected String getDeathSound() { + return "mob.spider.death"; + } + + /** + * Plays step sound at given x, y, z for the entity + */ + protected void playStepSound(int par1, int par2, int par3, int par4) { + this.playSound("mob.spider.step", 0.15F, 1.0F); + } + + /** + * Basic mob attack. Default to touch of death in EntityCreature. Overridden by + * each mob to define their attack. + */ + protected void attackEntity(Entity par1Entity, float par2) { + float var3 = this.getBrightness(1.0F); + + if (var3 > 0.5F && this.rand.nextInt(100) == 0) { + this.entityToAttack = null; + } else { + if (par2 > 2.0F && par2 < 6.0F && this.rand.nextInt(10) == 0) { + if (this.onGround) { + double var4 = par1Entity.posX - this.posX; + double var6 = par1Entity.posZ - this.posZ; + float var8 = MathHelper.sqrt_double(var4 * var4 + var6 * var6); + this.motionX = var4 / (double) var8 * 0.5D * 0.800000011920929D + + this.motionX * 0.20000000298023224D; + this.motionZ = var6 / (double) var8 * 0.5D * 0.800000011920929D + + this.motionZ * 0.20000000298023224D; + this.motionY = 0.4000000059604645D; + } + } else { + super.attackEntity(par1Entity, par2); + } + } + } + + /** + * Returns the item ID for the item the mob drops on death. + */ + protected int getDropItemId() { + return Item.silk.itemID; + } + + /** + * Drop 0-2 items of this living's type + */ + protected void dropFewItems(boolean par1, int par2) { + super.dropFewItems(par1, par2); + + if (par1 && (this.rand.nextInt(3) == 0 || this.rand.nextInt(1 + par2) > 0)) { + this.dropItem(Item.spiderEye.itemID, 1); + } + } + + /** + * returns true if this entity is by a ladder, false otherwise + */ + public boolean isOnLadder() { + return this.isBesideClimbableBlock(); + } + + /** + * Sets the Entity inside a web block. + */ + public void setInWeb() { + } + + /** + * Get this Entity's EnumCreatureAttribute + */ + public EnumCreatureAttribute getCreatureAttribute() { + return EnumCreatureAttribute.ARTHROPOD; + } + + public boolean isPotionApplicable(PotionEffect par1PotionEffect) { + return par1PotionEffect.getPotionID() == Potion.poison.id ? false : super.isPotionApplicable(par1PotionEffect); + } + + /** + * Returns true if the WatchableObject (Byte) is 0x01 otherwise returns false. + * The WatchableObject is updated using setBesideClimableBlock. + */ + public boolean isBesideClimbableBlock() { + return (this.dataWatcher.getWatchableObjectByte(16) & 1) != 0; + } + + /** + * Updates the WatchableObject (Byte) created in entityInit(), setting it to + * 0x01 if par1 is true or 0x00 if it is false. + */ + public void setBesideClimbableBlock(boolean par1) { + byte var2 = this.dataWatcher.getWatchableObjectByte(16); + + if (par1) { + var2 = (byte) (var2 | 1); + } else { + var2 &= -2; + } + + this.dataWatcher.updateObject(16, Byte.valueOf(var2)); + } + + /** + * Initialize this creature. + */ + public void initCreature() { + if (this.worldObj.rand.nextInt(100) == 0) { + EntitySkeleton var1 = new EntitySkeleton(this.worldObj); + var1.setLocationAndAngles(this.posX, this.posY, this.posZ, this.rotationYaw, 0.0F); + var1.initCreature(); + this.worldObj.spawnEntityInWorld(var1); + var1.mountEntity(this); + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntitySquid.java b/sp-server/src/main/java/net/minecraft/src/EntitySquid.java new file mode 100644 index 0000000..54e61b9 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntitySquid.java @@ -0,0 +1,186 @@ +package net.minecraft.src; + +public class EntitySquid extends EntityWaterMob { + public float field_70861_d = 0.0F; + public float field_70862_e = 0.0F; + public float field_70859_f = 0.0F; + public float field_70860_g = 0.0F; + public float field_70867_h = 0.0F; + public float field_70868_i = 0.0F; + + /** angle of the tentacles in radians */ + public float tentacleAngle = 0.0F; + + /** the last calculated angle of the tentacles in radians */ + public float lastTentacleAngle = 0.0F; + private float randomMotionSpeed = 0.0F; + private float field_70864_bA = 0.0F; + private float field_70871_bB = 0.0F; + private float randomMotionVecX = 0.0F; + private float randomMotionVecY = 0.0F; + private float randomMotionVecZ = 0.0F; + + public EntitySquid(World par1World) { + super(par1World); + this.texture = "/mob/squid.png"; + this.setSize(0.95F, 0.95F); + this.field_70864_bA = 1.0F / (this.rand.nextFloat() + 1.0F) * 0.2F; + } + + public int getMaxHealth() { + return 10; + } + + /** + * Returns the sound this mob makes while it's alive. + */ + protected String getLivingSound() { + return null; + } + + /** + * Returns the sound this mob makes when it is hurt. + */ + protected String getHurtSound() { + return null; + } + + /** + * Returns the sound this mob makes on death. + */ + protected String getDeathSound() { + return null; + } + + /** + * Returns the volume for the sounds this mob makes. + */ + protected float getSoundVolume() { + return 0.4F; + } + + /** + * Returns the item ID for the item the mob drops on death. + */ + protected int getDropItemId() { + return 0; + } + + /** + * Drop 0-2 items of this living's type + */ + protected void dropFewItems(boolean par1, int par2) { + int var3 = this.rand.nextInt(3 + par2) + 1; + + for (int var4 = 0; var4 < var3; ++var4) { + this.entityDropItem(new ItemStack(Item.dyePowder, 1, 0), 0.0F); + } + } + + /** + * Checks if this entity is inside water (if inWater field is true as a result + * of handleWaterMovement() returning true) + */ + public boolean isInWater() { + return this.worldObj.handleMaterialAcceleration(this.boundingBox.expand(0.0D, -0.6000000238418579D, 0.0D), + Material.water, this); + } + + /** + * Called frequently so the entity can update its state every tick as required. + * For example, zombies and skeletons use this to react to sunlight and start to + * burn. + */ + public void onLivingUpdate() { + super.onLivingUpdate(); + this.field_70862_e = this.field_70861_d; + this.field_70860_g = this.field_70859_f; + this.field_70868_i = this.field_70867_h; + this.lastTentacleAngle = this.tentacleAngle; + this.field_70867_h += this.field_70864_bA; + + if (this.field_70867_h > ((float) Math.PI * 2F)) { + this.field_70867_h -= ((float) Math.PI * 2F); + + if (this.rand.nextInt(10) == 0) { + this.field_70864_bA = 1.0F / (this.rand.nextFloat() + 1.0F) * 0.2F; + } + } + + if (this.isInWater()) { + float var1; + + if (this.field_70867_h < (float) Math.PI) { + var1 = this.field_70867_h / (float) Math.PI; + this.tentacleAngle = MathHelper.sin(var1 * var1 * (float) Math.PI) * (float) Math.PI * 0.25F; + + if ((double) var1 > 0.75D) { + this.randomMotionSpeed = 1.0F; + this.field_70871_bB = 1.0F; + } else { + this.field_70871_bB *= 0.8F; + } + } else { + this.tentacleAngle = 0.0F; + this.randomMotionSpeed *= 0.9F; + this.field_70871_bB *= 0.99F; + } + + if (!this.worldObj.isRemote) { + this.motionX = (double) (this.randomMotionVecX * this.randomMotionSpeed); + this.motionY = (double) (this.randomMotionVecY * this.randomMotionSpeed); + this.motionZ = (double) (this.randomMotionVecZ * this.randomMotionSpeed); + } + + var1 = MathHelper.sqrt_double(this.motionX * this.motionX + this.motionZ * this.motionZ); + this.renderYawOffset += (-((float) Math.atan2(this.motionX, this.motionZ)) * 180.0F / (float) Math.PI + - this.renderYawOffset) * 0.1F; + this.rotationYaw = this.renderYawOffset; + this.field_70859_f += (float) Math.PI * this.field_70871_bB * 1.5F; + this.field_70861_d += (-((float) Math.atan2((double) var1, this.motionY)) * 180.0F / (float) Math.PI + - this.field_70861_d) * 0.1F; + } else { + this.tentacleAngle = MathHelper.abs(MathHelper.sin(this.field_70867_h)) * (float) Math.PI * 0.25F; + + if (!this.worldObj.isRemote) { + this.motionX = 0.0D; + this.motionY -= 0.08D; + this.motionY *= 0.9800000190734863D; + this.motionZ = 0.0D; + } + + this.field_70861_d = (float) ((double) this.field_70861_d + (double) (-90.0F - this.field_70861_d) * 0.02D); + } + } + + /** + * Moves the entity based on the specified heading. Args: strafe, forward + */ + public void moveEntityWithHeading(float par1, float par2) { + this.moveEntity(this.motionX, this.motionY, this.motionZ); + } + + protected void updateEntityActionState() { + ++this.entityAge; + + if (this.entityAge > 100) { + this.randomMotionVecX = this.randomMotionVecY = this.randomMotionVecZ = 0.0F; + } else if (this.rand.nextInt(50) == 0 || !this.inWater + || this.randomMotionVecX == 0.0F && this.randomMotionVecY == 0.0F && this.randomMotionVecZ == 0.0F) { + float var1 = this.rand.nextFloat() * (float) Math.PI * 2.0F; + this.randomMotionVecX = MathHelper.cos(var1) * 0.2F; + this.randomMotionVecY = -0.1F + this.rand.nextFloat() * 0.2F; + this.randomMotionVecZ = MathHelper.sin(var1) * 0.2F; + } + + this.despawnEntity(); + } + + /** + * Checks if the entity's current position is a valid location to spawn this + * entity. + */ + public boolean getCanSpawnHere() { + return this.posY > 45.0D && this.posY < 63.0D && super.getCanSpawnHere(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityTNTPrimed.java b/sp-server/src/main/java/net/minecraft/src/EntityTNTPrimed.java new file mode 100644 index 0000000..89f01a2 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityTNTPrimed.java @@ -0,0 +1,104 @@ +package net.minecraft.src; + +public class EntityTNTPrimed extends Entity { + /** How long the fuse is */ + public int fuse; + private EntityLiving tntPlacedBy; + + public EntityTNTPrimed(World par1World) { + super(par1World); + this.fuse = 0; + this.preventEntitySpawning = true; + this.setSize(0.98F, 0.98F); + this.yOffset = this.height / 2.0F; + } + + public EntityTNTPrimed(World par1World, double par2, double par4, double par6, EntityLiving par8EntityLiving) { + this(par1World); + this.setPosition(par2, par4, par6); + float var9 = (float) (Math.random() * Math.PI * 2.0D); + this.motionX = (double) (-((float) Math.sin((double) var9)) * 0.02F); + this.motionY = 0.20000000298023224D; + this.motionZ = (double) (-((float) Math.cos((double) var9)) * 0.02F); + this.fuse = 80; + this.prevPosX = par2; + this.prevPosY = par4; + this.prevPosZ = par6; + this.tntPlacedBy = par8EntityLiving; + } + + protected void entityInit() { + } + + /** + * returns if this entity triggers Block.onEntityWalking on the blocks they walk + * on. used for spiders and wolves to prevent them from trampling crops + */ + protected boolean canTriggerWalking() { + return false; + } + + /** + * Returns true if other Entities should be prevented from moving through this + * Entity. + */ + public boolean canBeCollidedWith() { + return !this.isDead; + } + + /** + * Called to update the entity's position/logic. + */ + public void onUpdate() { + this.prevPosX = this.posX; + this.prevPosY = this.posY; + this.prevPosZ = this.posZ; + this.motionY -= 0.03999999910593033D; + this.moveEntity(this.motionX, this.motionY, this.motionZ); + this.motionX *= 0.9800000190734863D; + this.motionY *= 0.9800000190734863D; + this.motionZ *= 0.9800000190734863D; + + if (this.onGround) { + this.motionX *= 0.699999988079071D; + this.motionZ *= 0.699999988079071D; + this.motionY *= -0.5D; + } + + if (this.fuse-- <= 0) { + this.setDead(); + + if (!this.worldObj.isRemote) { + this.explode(); + } + } else { + this.worldObj.spawnParticle("smoke", this.posX, this.posY + 0.5D, this.posZ, 0.0D, 0.0D, 0.0D); + } + } + + private void explode() { + float var1 = 4.0F; + this.worldObj.createExplosion(this, this.posX, this.posY, this.posZ, var1, true); + } + + /** + * (abstract) Protected helper method to write subclass entity data to NBT. + */ + protected void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) { + par1NBTTagCompound.setByte("Fuse", (byte) this.fuse); + } + + /** + * (abstract) Protected helper method to read subclass entity data from NBT. + */ + protected void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) { + this.fuse = par1NBTTagCompound.getByte("Fuse"); + } + + /** + * returns null or the entityliving it was placed or ignited by + */ + public EntityLiving getTntPlacedBy() { + return this.tntPlacedBy; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityTameable.java b/sp-server/src/main/java/net/minecraft/src/EntityTameable.java new file mode 100644 index 0000000..7cde1d9 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityTameable.java @@ -0,0 +1,112 @@ +package net.minecraft.src; + +public abstract class EntityTameable extends EntityAnimal { + protected EntityAISit aiSit = new EntityAISit(this); + + public EntityTameable(World par1World) { + super(par1World); + } + + protected void entityInit() { + super.entityInit(); + this.dataWatcher.addObject(16, Byte.valueOf((byte) 0)); + this.dataWatcher.addObject(17, ""); + } + + /** + * (abstract) Protected helper method to write subclass entity data to NBT. + */ + public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) { + super.writeEntityToNBT(par1NBTTagCompound); + + if (this.getOwnerName() == null) { + par1NBTTagCompound.setString("Owner", ""); + } else { + par1NBTTagCompound.setString("Owner", this.getOwnerName()); + } + + par1NBTTagCompound.setBoolean("Sitting", this.isSitting()); + } + + /** + * (abstract) Protected helper method to read subclass entity data from NBT. + */ + public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) { + super.readEntityFromNBT(par1NBTTagCompound); + String var2 = par1NBTTagCompound.getString("Owner"); + + if (var2.length() > 0) { + this.setOwner(var2); + this.setTamed(true); + } + + this.aiSit.setSitting(par1NBTTagCompound.getBoolean("Sitting")); + this.setSitting(par1NBTTagCompound.getBoolean("Sitting")); + } + + /** + * Play the taming effect, will either be hearts or smoke depending on status + */ + protected void playTameEffect(boolean par1) { + String var2 = "heart"; + + if (!par1) { + var2 = "smoke"; + } + + for (int var3 = 0; var3 < 7; ++var3) { + double var4 = this.rand.nextGaussian() * 0.02D; + double var6 = this.rand.nextGaussian() * 0.02D; + double var8 = this.rand.nextGaussian() * 0.02D; + this.worldObj.spawnParticle(var2, + this.posX + (double) (this.rand.nextFloat() * this.width * 2.0F) - (double) this.width, + this.posY + 0.5D + (double) (this.rand.nextFloat() * this.height), + this.posZ + (double) (this.rand.nextFloat() * this.width * 2.0F) - (double) this.width, var4, var6, + var8); + } + } + + public boolean isTamed() { + return (this.dataWatcher.getWatchableObjectByte(16) & 4) != 0; + } + + public void setTamed(boolean par1) { + byte var2 = this.dataWatcher.getWatchableObjectByte(16); + + if (par1) { + this.dataWatcher.updateObject(16, Byte.valueOf((byte) (var2 | 4))); + } else { + this.dataWatcher.updateObject(16, Byte.valueOf((byte) (var2 & -5))); + } + } + + public boolean isSitting() { + return (this.dataWatcher.getWatchableObjectByte(16) & 1) != 0; + } + + public void setSitting(boolean par1) { + byte var2 = this.dataWatcher.getWatchableObjectByte(16); + + if (par1) { + this.dataWatcher.updateObject(16, Byte.valueOf((byte) (var2 | 1))); + } else { + this.dataWatcher.updateObject(16, Byte.valueOf((byte) (var2 & -2))); + } + } + + public String getOwnerName() { + return this.dataWatcher.getWatchableObjectString(17); + } + + public void setOwner(String par1Str) { + this.dataWatcher.updateObject(17, par1Str); + } + + public EntityLiving getOwner() { + return this.worldObj.getPlayerEntityByName(this.getOwnerName()); + } + + public EntityAISit func_70907_r() { + return this.aiSit; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityThrowable.java b/sp-server/src/main/java/net/minecraft/src/EntityThrowable.java new file mode 100644 index 0000000..169ae49 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityThrowable.java @@ -0,0 +1,279 @@ +package net.minecraft.src; + +import java.util.List; + +public abstract class EntityThrowable extends Entity implements IProjectile { + private int xTile = -1; + private int yTile = -1; + private int zTile = -1; + private int inTile = 0; + protected boolean inGround = false; + public int throwableShake = 0; + + /** The entity that threw this throwable item. */ + private EntityLiving thrower; + private String throwerName = null; + private int ticksInGround; + private int ticksInAir = 0; + + public EntityThrowable(World par1World) { + super(par1World); + this.setSize(0.25F, 0.25F); + } + + protected void entityInit() { + } + + public EntityThrowable(World par1World, EntityLiving par2EntityLiving) { + super(par1World); + this.thrower = par2EntityLiving; + this.setSize(0.25F, 0.25F); + this.setLocationAndAngles(par2EntityLiving.posX, + par2EntityLiving.posY + (double) par2EntityLiving.getEyeHeight(), par2EntityLiving.posZ, + par2EntityLiving.rotationYaw, par2EntityLiving.rotationPitch); + this.posX -= (double) (MathHelper.cos(this.rotationYaw / 180.0F * (float) Math.PI) * 0.16F); + this.posY -= 0.10000000149011612D; + this.posZ -= (double) (MathHelper.sin(this.rotationYaw / 180.0F * (float) Math.PI) * 0.16F); + this.setPosition(this.posX, this.posY, this.posZ); + this.yOffset = 0.0F; + float var3 = 0.4F; + this.motionX = (double) (-MathHelper.sin(this.rotationYaw / 180.0F * (float) Math.PI) + * MathHelper.cos(this.rotationPitch / 180.0F * (float) Math.PI) * var3); + this.motionZ = (double) (MathHelper.cos(this.rotationYaw / 180.0F * (float) Math.PI) + * MathHelper.cos(this.rotationPitch / 180.0F * (float) Math.PI) * var3); + this.motionY = (double) (-MathHelper.sin((this.rotationPitch + this.func_70183_g()) / 180.0F * (float) Math.PI) + * var3); + this.setThrowableHeading(this.motionX, this.motionY, this.motionZ, this.func_70182_d(), 1.0F); + } + + public EntityThrowable(World par1World, double par2, double par4, double par6) { + super(par1World); + this.ticksInGround = 0; + this.setSize(0.25F, 0.25F); + this.setPosition(par2, par4, par6); + this.yOffset = 0.0F; + } + + protected float func_70182_d() { + return 1.5F; + } + + protected float func_70183_g() { + return 0.0F; + } + + /** + * Similar to setArrowHeading, it's point the throwable entity to a x, y, z + * direction. + */ + public void setThrowableHeading(double par1, double par3, double par5, float par7, float par8) { + float var9 = MathHelper.sqrt_double(par1 * par1 + par3 * par3 + par5 * par5); + par1 /= (double) var9; + par3 /= (double) var9; + par5 /= (double) var9; + par1 += this.rand.nextGaussian() * 0.007499999832361937D * (double) par8; + par3 += this.rand.nextGaussian() * 0.007499999832361937D * (double) par8; + par5 += this.rand.nextGaussian() * 0.007499999832361937D * (double) par8; + par1 *= (double) par7; + par3 *= (double) par7; + par5 *= (double) par7; + this.motionX = par1; + this.motionY = par3; + this.motionZ = par5; + float var10 = MathHelper.sqrt_double(par1 * par1 + par5 * par5); + this.prevRotationYaw = this.rotationYaw = (float) (Math.atan2(par1, par5) * 180.0D / Math.PI); + this.prevRotationPitch = this.rotationPitch = (float) (Math.atan2(par3, (double) var10) * 180.0D / Math.PI); + this.ticksInGround = 0; + } + + /** + * Called to update the entity's position/logic. + */ + public void onUpdate() { + this.lastTickPosX = this.posX; + this.lastTickPosY = this.posY; + this.lastTickPosZ = this.posZ; + super.onUpdate(); + + if (this.throwableShake > 0) { + --this.throwableShake; + } + + if (this.inGround) { + int var1 = this.worldObj.getBlockId(this.xTile, this.yTile, this.zTile); + + if (var1 == this.inTile) { + ++this.ticksInGround; + + if (this.ticksInGround == 1200) { + this.setDead(); + } + + return; + } + + this.inGround = false; + this.motionX *= (double) (this.rand.nextFloat() * 0.2F); + this.motionY *= (double) (this.rand.nextFloat() * 0.2F); + this.motionZ *= (double) (this.rand.nextFloat() * 0.2F); + this.ticksInGround = 0; + this.ticksInAir = 0; + } else { + ++this.ticksInAir; + } + + Vec3 var16 = this.worldObj.getWorldVec3Pool().getVecFromPool(this.posX, this.posY, this.posZ); + Vec3 var2 = this.worldObj.getWorldVec3Pool().getVecFromPool(this.posX + this.motionX, this.posY + this.motionY, + this.posZ + this.motionZ); + MovingObjectPosition var3 = this.worldObj.rayTraceBlocks(var16, var2); + var16 = this.worldObj.getWorldVec3Pool().getVecFromPool(this.posX, this.posY, this.posZ); + var2 = this.worldObj.getWorldVec3Pool().getVecFromPool(this.posX + this.motionX, this.posY + this.motionY, + this.posZ + this.motionZ); + + if (var3 != null) { + var2 = this.worldObj.getWorldVec3Pool().getVecFromPool(var3.hitVec.xCoord, var3.hitVec.yCoord, + var3.hitVec.zCoord); + } + + if (!this.worldObj.isRemote) { + Entity var4 = null; + List var5 = this.worldObj.getEntitiesWithinAABBExcludingEntity(this, + this.boundingBox.addCoord(this.motionX, this.motionY, this.motionZ).expand(1.0D, 1.0D, 1.0D)); + double var6 = 0.0D; + EntityLiving var8 = this.getThrower(); + + for (int var9 = 0; var9 < var5.size(); ++var9) { + Entity var10 = (Entity) var5.get(var9); + + if (var10.canBeCollidedWith() && (var10 != var8 || this.ticksInAir >= 5)) { + float var11 = 0.3F; + AxisAlignedBB var12 = var10.boundingBox.expand((double) var11, (double) var11, (double) var11); + MovingObjectPosition var13 = var12.calculateIntercept(var16, var2); + + if (var13 != null) { + double var14 = var16.distanceTo(var13.hitVec); + + if (var14 < var6 || var6 == 0.0D) { + var4 = var10; + var6 = var14; + } + } + } + } + + if (var4 != null) { + var3 = new MovingObjectPosition(var4); + } + } + + if (var3 != null) { + if (var3.typeOfHit == EnumMovingObjectType.TILE + && this.worldObj.getBlockId(var3.blockX, var3.blockY, var3.blockZ) == Block.portal.blockID) { + this.setInPortal(); + } else { + this.onImpact(var3); + } + } + + this.posX += this.motionX; + this.posY += this.motionY; + this.posZ += this.motionZ; + float var17 = MathHelper.sqrt_double(this.motionX * this.motionX + this.motionZ * this.motionZ); + this.rotationYaw = (float) (Math.atan2(this.motionX, this.motionZ) * 180.0D / Math.PI); + + for (this.rotationPitch = (float) (Math.atan2(this.motionY, (double) var17) * 180.0D + / Math.PI); this.rotationPitch - this.prevRotationPitch < -180.0F; this.prevRotationPitch -= 360.0F) { + ; + } + + while (this.rotationPitch - this.prevRotationPitch >= 180.0F) { + this.prevRotationPitch += 360.0F; + } + + while (this.rotationYaw - this.prevRotationYaw < -180.0F) { + this.prevRotationYaw -= 360.0F; + } + + while (this.rotationYaw - this.prevRotationYaw >= 180.0F) { + this.prevRotationYaw += 360.0F; + } + + this.rotationPitch = this.prevRotationPitch + (this.rotationPitch - this.prevRotationPitch) * 0.2F; + this.rotationYaw = this.prevRotationYaw + (this.rotationYaw - this.prevRotationYaw) * 0.2F; + float var18 = 0.99F; + float var19 = this.getGravityVelocity(); + + if (this.isInWater()) { + for (int var7 = 0; var7 < 4; ++var7) { + float var20 = 0.25F; + this.worldObj.spawnParticle("bubble", this.posX - this.motionX * (double) var20, + this.posY - this.motionY * (double) var20, this.posZ - this.motionZ * (double) var20, + this.motionX, this.motionY, this.motionZ); + } + + var18 = 0.8F; + } + + this.motionX *= (double) var18; + this.motionY *= (double) var18; + this.motionZ *= (double) var18; + this.motionY -= (double) var19; + this.setPosition(this.posX, this.posY, this.posZ); + } + + /** + * Gets the amount of gravity to apply to the thrown entity with each tick. + */ + protected float getGravityVelocity() { + return 0.03F; + } + + /** + * Called when this EntityThrowable hits a block or entity. + */ + protected abstract void onImpact(MovingObjectPosition var1); + + /** + * (abstract) Protected helper method to write subclass entity data to NBT. + */ + public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) { + par1NBTTagCompound.setShort("xTile", (short) this.xTile); + par1NBTTagCompound.setShort("yTile", (short) this.yTile); + par1NBTTagCompound.setShort("zTile", (short) this.zTile); + par1NBTTagCompound.setByte("inTile", (byte) this.inTile); + par1NBTTagCompound.setByte("shake", (byte) this.throwableShake); + par1NBTTagCompound.setByte("inGround", (byte) (this.inGround ? 1 : 0)); + + if ((this.throwerName == null || this.throwerName.length() == 0) && this.thrower != null + && this.thrower instanceof EntityPlayer) { + this.throwerName = this.thrower.getEntityName(); + } + + par1NBTTagCompound.setString("ownerName", this.throwerName == null ? "" : this.throwerName); + } + + /** + * (abstract) Protected helper method to read subclass entity data from NBT. + */ + public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) { + this.xTile = par1NBTTagCompound.getShort("xTile"); + this.yTile = par1NBTTagCompound.getShort("yTile"); + this.zTile = par1NBTTagCompound.getShort("zTile"); + this.inTile = par1NBTTagCompound.getByte("inTile") & 255; + this.throwableShake = par1NBTTagCompound.getByte("shake") & 255; + this.inGround = par1NBTTagCompound.getByte("inGround") == 1; + this.throwerName = par1NBTTagCompound.getString("ownerName"); + + if (this.throwerName != null && this.throwerName.length() == 0) { + this.throwerName = null; + } + } + + public EntityLiving getThrower() { + if (this.thrower == null && this.throwerName != null && this.throwerName.length() > 0) { + this.thrower = this.worldObj.getPlayerEntityByName(this.throwerName); + } + + return this.thrower; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityTracker.java b/sp-server/src/main/java/net/minecraft/src/EntityTracker.java new file mode 100644 index 0000000..9635074 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityTracker.java @@ -0,0 +1,212 @@ +package net.minecraft.src; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + +public class EntityTracker { + private final WorldServer theWorld; + + /** + * List of tracked entities, used for iteration operations on tracked entities. + */ + private Set trackedEntities = new HashSet(); + + /** Used for identity lookup of tracked entities. */ + private IntHashMap trackedEntityHashTable = new IntHashMap(); + private int maxTrackingDistanceThreshold; + + public EntityTracker(WorldServer par1WorldServer) { + this.theWorld = par1WorldServer; + this.maxTrackingDistanceThreshold = par1WorldServer.getMinecraftServer().getConfigurationManager() + .getEntityViewDistance(); + } + + public void trackEntity(Entity par1Entity) { + if (par1Entity instanceof EntityPlayerMP) { + this.trackEntity(par1Entity, 512, 2); + EntityPlayerMP var2 = (EntityPlayerMP) par1Entity; + Iterator var3 = this.trackedEntities.iterator(); + + while (var3.hasNext()) { + EntityTrackerEntry var4 = (EntityTrackerEntry) var3.next(); + + if (var4.trackedEntity != var2) { + var4.updatePlayerEntity(var2); + } + } + } else if (par1Entity instanceof EntityFishHook) { + this.trackEntity(par1Entity, 64, 5, true); + } else if (par1Entity instanceof EntityArrow) { + this.trackEntity(par1Entity, 64, 20, false); + } else if (par1Entity instanceof EntitySmallFireball) { + this.trackEntity(par1Entity, 64, 10, false); + } else if (par1Entity instanceof EntityFireball) { + this.trackEntity(par1Entity, 64, 10, false); + } else if (par1Entity instanceof EntitySnowball) { + this.trackEntity(par1Entity, 64, 10, true); + } else if (par1Entity instanceof EntityEnderPearl) { + this.trackEntity(par1Entity, 64, 10, true); + } else if (par1Entity instanceof EntityEnderEye) { + this.trackEntity(par1Entity, 64, 4, true); + } else if (par1Entity instanceof EntityEgg) { + this.trackEntity(par1Entity, 64, 10, true); + } else if (par1Entity instanceof EntityPotion) { + this.trackEntity(par1Entity, 64, 10, true); + } else if (par1Entity instanceof EntityExpBottle) { + this.trackEntity(par1Entity, 64, 10, true); + } else if (par1Entity instanceof EntityFireworkRocket) { + this.trackEntity(par1Entity, 64, 10, true); + } else if (par1Entity instanceof EntityItem) { + this.trackEntity(par1Entity, 64, 20, true); + } else if (par1Entity instanceof EntityMinecart) { + this.trackEntity(par1Entity, 80, 3, true); + } else if (par1Entity instanceof EntityBoat) { + this.trackEntity(par1Entity, 80, 3, true); + } else if (par1Entity instanceof EntitySquid) { + this.trackEntity(par1Entity, 64, 3, true); + } else if (par1Entity instanceof EntityWither) { + this.trackEntity(par1Entity, 80, 3, false); + } else if (par1Entity instanceof EntityBat) { + this.trackEntity(par1Entity, 80, 3, false); + } else if (par1Entity instanceof IAnimals) { + this.trackEntity(par1Entity, 80, 3, true); + } else if (par1Entity instanceof EntityDragon) { + this.trackEntity(par1Entity, 160, 3, true); + } else if (par1Entity instanceof EntityTNTPrimed) { + this.trackEntity(par1Entity, 160, 10, true); + } else if (par1Entity instanceof EntityFallingSand) { + this.trackEntity(par1Entity, 160, 20, true); + } else if (par1Entity instanceof EntityPainting) { + this.trackEntity(par1Entity, 160, Integer.MAX_VALUE, false); + } else if (par1Entity instanceof EntityXPOrb) { + this.trackEntity(par1Entity, 160, 20, true); + } else if (par1Entity instanceof EntityEnderCrystal) { + this.trackEntity(par1Entity, 256, Integer.MAX_VALUE, false); + } else if (par1Entity instanceof EntityItemFrame) { + this.trackEntity(par1Entity, 160, Integer.MAX_VALUE, false); + } + } + + public void trackEntity(Entity par1Entity, int par2, int par3) { + this.trackEntity(par1Entity, par2, par3, false); + } + + public void trackEntity(Entity par1Entity, int par2, int par3, boolean par4) { + if (par2 > this.maxTrackingDistanceThreshold) { + par2 = this.maxTrackingDistanceThreshold; + } + + try { + if (this.trackedEntityHashTable.containsItem(par1Entity.entityId)) { + throw new IllegalStateException("Entity is already tracked!"); + } + + EntityTrackerEntry var5 = new EntityTrackerEntry(par1Entity, par2, par3, par4); + this.trackedEntities.add(var5); + this.trackedEntityHashTable.addKey(par1Entity.entityId, var5); + var5.updatePlayerEntities(this.theWorld.playerEntities); + } catch (Throwable var11) { + CrashReport var6 = CrashReport.makeCrashReport(var11, "Adding entity to track"); + CrashReportCategory var7 = var6.makeCategory("Entity To Track"); + var7.addCrashSection("Tracking range", par2 + " blocks"); + var7.addCrashSectionCallable("Update interval", new CallableEntityTracker(this, par3)); + par1Entity.func_85029_a(var7); + CrashReportCategory var8 = var6.makeCategory("Entity That Is Already Tracked"); + ((EntityTrackerEntry) this.trackedEntityHashTable.lookup(par1Entity.entityId)).trackedEntity + .func_85029_a(var8); + + try { + throw new ReportedException(var6); + } catch (ReportedException var10) { + System.err.println("\"Silently\" catching entity tracking error."); + var10.printStackTrace(); + } + } + } + + public void untrackEntity(Entity par1Entity) { + if (par1Entity instanceof EntityPlayerMP) { + EntityPlayerMP var2 = (EntityPlayerMP) par1Entity; + Iterator var3 = this.trackedEntities.iterator(); + + while (var3.hasNext()) { + EntityTrackerEntry var4 = (EntityTrackerEntry) var3.next(); + var4.removeFromTrackedPlayers(var2); + } + } + + EntityTrackerEntry var5 = (EntityTrackerEntry) this.trackedEntityHashTable.removeObject(par1Entity.entityId); + + if (var5 != null) { + this.trackedEntities.remove(var5); + var5.sendDestroyEntityPacketToTrackedPlayers(); + } + } + + public void updateTrackedEntities() { + ArrayList var1 = new ArrayList(); + Iterator var2 = this.trackedEntities.iterator(); + + while (var2.hasNext()) { + EntityTrackerEntry var3 = (EntityTrackerEntry) var2.next(); + var3.updatePlayerList(this.theWorld.playerEntities); + + if (var3.playerEntitiesUpdated && var3.trackedEntity instanceof EntityPlayerMP) { + var1.add((EntityPlayerMP) var3.trackedEntity); + } + } + + for (int var6 = 0; var6 < var1.size(); ++var6) { + EntityPlayerMP var7 = (EntityPlayerMP) var1.get(var6); + Iterator var4 = this.trackedEntities.iterator(); + + while (var4.hasNext()) { + EntityTrackerEntry var5 = (EntityTrackerEntry) var4.next(); + + if (var5.trackedEntity != var7) { + var5.updatePlayerEntity(var7); + } + } + } + } + + public void sendPacketToTrackedPlayers(Entity par1Entity, Packet par2Packet) { + EntityTrackerEntry var3 = (EntityTrackerEntry) this.trackedEntityHashTable.lookup(par1Entity.entityId); + + if (var3 != null) { + var3.sendPacketToTrackedPlayers(par2Packet); + } + } + + public void sendPacketToTrackedPlayersAndTrackedEntity(Entity par1Entity, Packet par2Packet) { + EntityTrackerEntry var3 = (EntityTrackerEntry) this.trackedEntityHashTable.lookup(par1Entity.entityId); + + if (var3 != null) { + var3.sendPacketToTrackedPlayersAndTrackedEntity(par2Packet); + } + } + + public void removePlayerFromTrackers(EntityPlayerMP par1EntityPlayerMP) { + Iterator var2 = this.trackedEntities.iterator(); + + while (var2.hasNext()) { + EntityTrackerEntry var3 = (EntityTrackerEntry) var2.next(); + var3.removeTrackedPlayerSymmetric(par1EntityPlayerMP); + } + } + + public void func_85172_a(EntityPlayerMP par1EntityPlayerMP, Chunk par2Chunk) { + Iterator var3 = this.trackedEntities.iterator(); + + while (var3.hasNext()) { + EntityTrackerEntry var4 = (EntityTrackerEntry) var3.next(); + + if (var4.trackedEntity != par1EntityPlayerMP && var4.trackedEntity.chunkCoordX == par2Chunk.xPosition + && var4.trackedEntity.chunkCoordZ == par2Chunk.zPosition) { + var4.updatePlayerEntity(par1EntityPlayerMP); + } + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityTrackerEntry.java b/sp-server/src/main/java/net/minecraft/src/EntityTrackerEntry.java new file mode 100644 index 0000000..3803588 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityTrackerEntry.java @@ -0,0 +1,472 @@ +package net.minecraft.src; + +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +public class EntityTrackerEntry { + /** The entity that this EntityTrackerEntry tracks. */ + public Entity trackedEntity; + public int trackingDistanceThreshold; + + /** check for sync when ticks % updateFrequency==0 */ + public int updateFrequency; + + /** The encoded entity X position. */ + public int encodedPosX; + + /** The encoded entity Y position. */ + public int encodedPosY; + + /** The encoded entity Z position. */ + public int encodedPosZ; + + /** The encoded entity yaw rotation. */ + public int encodedRotationYaw; + + /** The encoded entity pitch rotation. */ + public int encodedRotationPitch; + public int lastHeadMotion; + public double lastTrackedEntityMotionX; + public double lastTrackedEntityMotionY; + public double motionZ; + public int updateCounter = 0; + private double lastTrackedEntityPosX; + private double lastTrackedEntityPosY; + private double lastTrackedEntityPosZ; + private boolean firstUpdateDone = false; + private boolean sendVelocityUpdates; + + /** + * every 400 ticks a full teleport packet is sent, rather than just a "move me + * +x" command, so that position remains fully synced. + */ + private int ticksSinceLastForcedTeleport = 0; + private Entity field_85178_v; + private boolean ridingEntity = false; + public boolean playerEntitiesUpdated = false; + + /** + * Holds references to all the players that are currently receiving position + * updates for this entity. + */ + public Set trackingPlayers = new HashSet(); + + public EntityTrackerEntry(Entity par1Entity, int par2, int par3, boolean par4) { + this.trackedEntity = par1Entity; + this.trackingDistanceThreshold = par2; + this.updateFrequency = par3; + this.sendVelocityUpdates = par4; + this.encodedPosX = MathHelper.floor_double(par1Entity.posX * 32.0D); + this.encodedPosY = MathHelper.floor_double(par1Entity.posY * 32.0D); + this.encodedPosZ = MathHelper.floor_double(par1Entity.posZ * 32.0D); + this.encodedRotationYaw = MathHelper.floor_float(par1Entity.rotationYaw * 256.0F / 360.0F); + this.encodedRotationPitch = MathHelper.floor_float(par1Entity.rotationPitch * 256.0F / 360.0F); + this.lastHeadMotion = MathHelper.floor_float(par1Entity.getRotationYawHead() * 256.0F / 360.0F); + } + + public boolean equals(Object par1Obj) { + return par1Obj instanceof EntityTrackerEntry + ? ((EntityTrackerEntry) par1Obj).trackedEntity.entityId == this.trackedEntity.entityId + : false; + } + + public int hashCode() { + return this.trackedEntity.entityId; + } + + public void updatePlayerList(List par1List) { + this.playerEntitiesUpdated = false; + + if (!this.firstUpdateDone || this.trackedEntity.getDistanceSq(this.lastTrackedEntityPosX, + this.lastTrackedEntityPosY, this.lastTrackedEntityPosZ) > 16.0D) { + this.lastTrackedEntityPosX = this.trackedEntity.posX; + this.lastTrackedEntityPosY = this.trackedEntity.posY; + this.lastTrackedEntityPosZ = this.trackedEntity.posZ; + this.firstUpdateDone = true; + this.playerEntitiesUpdated = true; + this.updatePlayerEntities(par1List); + } + + if (this.field_85178_v != this.trackedEntity.ridingEntity + || this.trackedEntity.ridingEntity != null && this.updateCounter % 60 == 0) { + this.field_85178_v = this.trackedEntity.ridingEntity; + this.sendPacketToTrackedPlayers( + new Packet39AttachEntity(this.trackedEntity, this.trackedEntity.ridingEntity)); + } + + if (this.trackedEntity instanceof EntityItemFrame && this.updateCounter % 10 == 0) { + EntityItemFrame var23 = (EntityItemFrame) this.trackedEntity; + ItemStack var24 = var23.getDisplayedItem(); + + if (var24 != null && var24.getItem() instanceof ItemMap) { + MapData var26 = Item.map.getMapData(var24, this.trackedEntity.worldObj); + Iterator var29 = par1List.iterator(); + + while (var29.hasNext()) { + EntityPlayer var30 = (EntityPlayer) var29.next(); + EntityPlayerMP var31 = (EntityPlayerMP) var30; + var26.updateVisiblePlayers(var31, var24); + + if (var31.playerNetServerHandler.getNumChunkDataPackets() <= 5) { + Packet var32 = Item.map.getUpdatePacket(var24, this.trackedEntity.worldObj, var31); + + if (var32 != null) { + var31.playerNetServerHandler.sendPacket(var32); + } + } + } + } + + DataWatcher var27 = this.trackedEntity.getDataWatcher(); + + if (var27.hasObjectChanged()) { + this.sendPacketToTrackedPlayersAndTrackedEntity( + new Packet40EntityMetadata(this.trackedEntity.entityId, var27, false)); + } + } else if (this.updateCounter % this.updateFrequency == 0 || this.trackedEntity.isAirBorne + || this.trackedEntity.getDataWatcher().hasObjectChanged()) { + int var2; + int var3; + + if (this.trackedEntity.ridingEntity == null) { + ++this.ticksSinceLastForcedTeleport; + var2 = this.trackedEntity.myEntitySize.multiplyBy32AndRound(this.trackedEntity.posX); + var3 = MathHelper.floor_double(this.trackedEntity.posY * 32.0D); + int var4 = this.trackedEntity.myEntitySize.multiplyBy32AndRound(this.trackedEntity.posZ); + int var5 = MathHelper.floor_float(this.trackedEntity.rotationYaw * 256.0F / 360.0F); + int var6 = MathHelper.floor_float(this.trackedEntity.rotationPitch * 256.0F / 360.0F); + int var7 = var2 - this.encodedPosX; + int var8 = var3 - this.encodedPosY; + int var9 = var4 - this.encodedPosZ; + Object var10 = null; + boolean var11 = Math.abs(var7) >= 4 || Math.abs(var8) >= 4 || Math.abs(var9) >= 4 + || this.updateCounter % 60 == 0; + boolean var12 = Math.abs(var5 - this.encodedRotationYaw) >= 4 + || Math.abs(var6 - this.encodedRotationPitch) >= 4; + + if (this.updateCounter > 0 || this.trackedEntity instanceof EntityArrow) { + if (var7 >= -128 && var7 < 128 && var8 >= -128 && var8 < 128 && var9 >= -128 && var9 < 128 + && this.ticksSinceLastForcedTeleport <= 400 && !this.ridingEntity) { + if (var11 && var12) { + var10 = new Packet33RelEntityMoveLook(this.trackedEntity.entityId, (byte) var7, (byte) var8, + (byte) var9, (byte) var5, (byte) var6); + } else if (var11) { + var10 = new Packet31RelEntityMove(this.trackedEntity.entityId, (byte) var7, (byte) var8, + (byte) var9); + } else if (var12) { + var10 = new Packet32EntityLook(this.trackedEntity.entityId, (byte) var5, (byte) var6); + } + } else { + this.ticksSinceLastForcedTeleport = 0; + var10 = new Packet34EntityTeleport(this.trackedEntity.entityId, var2, var3, var4, (byte) var5, + (byte) var6); + } + } + + if (this.sendVelocityUpdates) { + double var13 = this.trackedEntity.motionX - this.lastTrackedEntityMotionX; + double var15 = this.trackedEntity.motionY - this.lastTrackedEntityMotionY; + double var17 = this.trackedEntity.motionZ - this.motionZ; + double var19 = 0.02D; + double var21 = var13 * var13 + var15 * var15 + var17 * var17; + + if (var21 > var19 * var19 || var21 > 0.0D && this.trackedEntity.motionX == 0.0D + && this.trackedEntity.motionY == 0.0D && this.trackedEntity.motionZ == 0.0D) { + this.lastTrackedEntityMotionX = this.trackedEntity.motionX; + this.lastTrackedEntityMotionY = this.trackedEntity.motionY; + this.motionZ = this.trackedEntity.motionZ; + this.sendPacketToTrackedPlayers(new Packet28EntityVelocity(this.trackedEntity.entityId, + this.lastTrackedEntityMotionX, this.lastTrackedEntityMotionY, this.motionZ)); + } + } + + if (var10 != null) { + this.sendPacketToTrackedPlayers((Packet) var10); + } + + DataWatcher var33 = this.trackedEntity.getDataWatcher(); + + if (var33.hasObjectChanged()) { + this.sendPacketToTrackedPlayersAndTrackedEntity( + new Packet40EntityMetadata(this.trackedEntity.entityId, var33, false)); + } + + if (var11) { + this.encodedPosX = var2; + this.encodedPosY = var3; + this.encodedPosZ = var4; + } + + if (var12) { + this.encodedRotationYaw = var5; + this.encodedRotationPitch = var6; + } + + this.ridingEntity = false; + } else { + var2 = MathHelper.floor_float(this.trackedEntity.rotationYaw * 256.0F / 360.0F); + var3 = MathHelper.floor_float(this.trackedEntity.rotationPitch * 256.0F / 360.0F); + boolean var25 = Math.abs(var2 - this.encodedRotationYaw) >= 4 + || Math.abs(var3 - this.encodedRotationPitch) >= 4; + + if (var25) { + this.sendPacketToTrackedPlayers( + new Packet32EntityLook(this.trackedEntity.entityId, (byte) var2, (byte) var3)); + this.encodedRotationYaw = var2; + this.encodedRotationPitch = var3; + } + + this.encodedPosX = this.trackedEntity.myEntitySize.multiplyBy32AndRound(this.trackedEntity.posX); + this.encodedPosY = MathHelper.floor_double(this.trackedEntity.posY * 32.0D); + this.encodedPosZ = this.trackedEntity.myEntitySize.multiplyBy32AndRound(this.trackedEntity.posZ); + DataWatcher var28 = this.trackedEntity.getDataWatcher(); + + if (var28.hasObjectChanged()) { + this.sendPacketToTrackedPlayersAndTrackedEntity( + new Packet40EntityMetadata(this.trackedEntity.entityId, var28, false)); + } + + this.ridingEntity = true; + } + + var2 = MathHelper.floor_float(this.trackedEntity.getRotationYawHead() * 256.0F / 360.0F); + + if (Math.abs(var2 - this.lastHeadMotion) >= 4) { + this.sendPacketToTrackedPlayers( + new Packet35EntityHeadRotation(this.trackedEntity.entityId, (byte) var2)); + this.lastHeadMotion = var2; + } + + this.trackedEntity.isAirBorne = false; + } + + ++this.updateCounter; + + if (this.trackedEntity.velocityChanged) { + this.sendPacketToTrackedPlayersAndTrackedEntity(new Packet28EntityVelocity(this.trackedEntity)); + this.trackedEntity.velocityChanged = false; + } + } + + public void sendPacketToTrackedPlayers(Packet par1Packet) { + Iterator var2 = this.trackingPlayers.iterator(); + + while (var2.hasNext()) { + EntityPlayerMP var3 = (EntityPlayerMP) var2.next(); + var3.playerNetServerHandler.sendPacket(par1Packet); + } + } + + public void sendPacketToTrackedPlayersAndTrackedEntity(Packet par1Packet) { + this.sendPacketToTrackedPlayers(par1Packet); + + if (this.trackedEntity instanceof EntityPlayerMP) { + ((EntityPlayerMP) this.trackedEntity).playerNetServerHandler.sendPacket(par1Packet); + } + } + + public void sendDestroyEntityPacketToTrackedPlayers() { + Iterator var1 = this.trackingPlayers.iterator(); + + while (var1.hasNext()) { + EntityPlayerMP var2 = (EntityPlayerMP) var1.next(); + var2.destroyedItemsNetCache.add(Integer.valueOf(this.trackedEntity.entityId)); + } + } + + public void removeFromTrackedPlayers(EntityPlayerMP par1EntityPlayerMP) { + if (this.trackingPlayers.contains(par1EntityPlayerMP)) { + par1EntityPlayerMP.destroyedItemsNetCache.add(Integer.valueOf(this.trackedEntity.entityId)); + this.trackingPlayers.remove(par1EntityPlayerMP); + } + } + + public void updatePlayerEntity(EntityPlayerMP par1EntityPlayerMP) { + if (par1EntityPlayerMP != this.trackedEntity) { + double var2 = par1EntityPlayerMP.posX - (double) (this.encodedPosX / 32); + double var4 = par1EntityPlayerMP.posZ - (double) (this.encodedPosZ / 32); + + if (var2 >= (double) (-this.trackingDistanceThreshold) && var2 <= (double) this.trackingDistanceThreshold + && var4 >= (double) (-this.trackingDistanceThreshold) + && var4 <= (double) this.trackingDistanceThreshold) { + if (!this.trackingPlayers.contains(par1EntityPlayerMP) + && (this.isPlayerWatchingThisChunk(par1EntityPlayerMP) || this.trackedEntity.field_98038_p)) { + this.trackingPlayers.add(par1EntityPlayerMP); + Packet var6 = this.getSpawnPacket(); + par1EntityPlayerMP.playerNetServerHandler.sendPacket(var6); + + if (!this.trackedEntity.getDataWatcher().getIsBlank()) { + par1EntityPlayerMP.playerNetServerHandler.sendPacket(new Packet40EntityMetadata( + this.trackedEntity.entityId, this.trackedEntity.getDataWatcher(), true)); + } + + this.lastTrackedEntityMotionX = this.trackedEntity.motionX; + this.lastTrackedEntityMotionY = this.trackedEntity.motionY; + this.motionZ = this.trackedEntity.motionZ; + + if (this.sendVelocityUpdates && !(var6 instanceof Packet24MobSpawn)) { + par1EntityPlayerMP.playerNetServerHandler.sendPacket( + new Packet28EntityVelocity(this.trackedEntity.entityId, this.trackedEntity.motionX, + this.trackedEntity.motionY, this.trackedEntity.motionZ)); + } + + if (this.trackedEntity.ridingEntity != null) { + par1EntityPlayerMP.playerNetServerHandler.sendPacket( + new Packet39AttachEntity(this.trackedEntity, this.trackedEntity.ridingEntity)); + } + + if (this.trackedEntity instanceof EntityLiving) { + for (int var7 = 0; var7 < 5; ++var7) { + ItemStack var8 = ((EntityLiving) this.trackedEntity).getEquipmentInSlot(var7); + + if (var8 != null) { + par1EntityPlayerMP.playerNetServerHandler.sendPacket( + new Packet5PlayerInventory(this.trackedEntity.entityId, var7, var8)); + } + } + } + + if (this.trackedEntity instanceof EntityPlayer) { + EntityPlayer var10 = (EntityPlayer) this.trackedEntity; + + if (var10.isPlayerSleeping()) { + par1EntityPlayerMP.playerNetServerHandler.sendPacket(new Packet17Sleep(this.trackedEntity, + 0, MathHelper.floor_double(this.trackedEntity.posX), + MathHelper.floor_double(this.trackedEntity.posY), + MathHelper.floor_double(this.trackedEntity.posZ))); + } + } + + if (this.trackedEntity instanceof EntityLiving) { + EntityLiving var11 = (EntityLiving) this.trackedEntity; + Iterator var12 = var11.getActivePotionEffects().iterator(); + + while (var12.hasNext()) { + PotionEffect var9 = (PotionEffect) var12.next(); + par1EntityPlayerMP.playerNetServerHandler + .sendPacket(new Packet41EntityEffect(this.trackedEntity.entityId, var9)); + } + } + } + } else if (this.trackingPlayers.contains(par1EntityPlayerMP)) { + this.trackingPlayers.remove(par1EntityPlayerMP); + par1EntityPlayerMP.destroyedItemsNetCache.add(Integer.valueOf(this.trackedEntity.entityId)); + } + } + } + + private boolean isPlayerWatchingThisChunk(EntityPlayerMP par1EntityPlayerMP) { + return par1EntityPlayerMP.getServerForPlayer().getPlayerManager().isPlayerWatchingChunk(par1EntityPlayerMP, + this.trackedEntity.chunkCoordX, this.trackedEntity.chunkCoordZ); + } + + public void updatePlayerEntities(List par1List) { + for (int var2 = 0; var2 < par1List.size(); ++var2) { + this.updatePlayerEntity((EntityPlayerMP) par1List.get(var2)); + } + } + + private Packet getSpawnPacket() { + if (this.trackedEntity.isDead) { + this.trackedEntity.worldObj.getWorldLogAgent().func_98236_b("Fetching addPacket for removed entity"); + } + + if (this.trackedEntity instanceof EntityItem) { + return new Packet23VehicleSpawn(this.trackedEntity, 2, 1); + } else if (this.trackedEntity instanceof EntityPlayerMP) { + return new Packet20NamedEntitySpawn((EntityPlayer) this.trackedEntity); + } else if (this.trackedEntity instanceof EntityMinecart) { + EntityMinecart var8 = (EntityMinecart) this.trackedEntity; + return new Packet23VehicleSpawn(this.trackedEntity, 10, var8.getMinecartType()); + } else if (this.trackedEntity instanceof EntityBoat) { + return new Packet23VehicleSpawn(this.trackedEntity, 1); + } else if (!(this.trackedEntity instanceof IAnimals) && !(this.trackedEntity instanceof EntityDragon)) { + if (this.trackedEntity instanceof EntityFishHook) { + EntityPlayer var7 = ((EntityFishHook) this.trackedEntity).angler; + return new Packet23VehicleSpawn(this.trackedEntity, 90, + var7 != null ? var7.entityId : this.trackedEntity.entityId); + } else if (this.trackedEntity instanceof EntityArrow) { + Entity var6 = ((EntityArrow) this.trackedEntity).shootingEntity; + return new Packet23VehicleSpawn(this.trackedEntity, 60, + var6 != null ? var6.entityId : this.trackedEntity.entityId); + } else if (this.trackedEntity instanceof EntitySnowball) { + return new Packet23VehicleSpawn(this.trackedEntity, 61); + } else if (this.trackedEntity instanceof EntityPotion) { + return new Packet23VehicleSpawn(this.trackedEntity, 73, + ((EntityPotion) this.trackedEntity).getPotionDamage()); + } else if (this.trackedEntity instanceof EntityExpBottle) { + return new Packet23VehicleSpawn(this.trackedEntity, 75); + } else if (this.trackedEntity instanceof EntityEnderPearl) { + return new Packet23VehicleSpawn(this.trackedEntity, 65); + } else if (this.trackedEntity instanceof EntityEnderEye) { + return new Packet23VehicleSpawn(this.trackedEntity, 72); + } else if (this.trackedEntity instanceof EntityFireworkRocket) { + return new Packet23VehicleSpawn(this.trackedEntity, 76); + } else { + Packet23VehicleSpawn var2; + + if (this.trackedEntity instanceof EntityFireball) { + EntityFireball var5 = (EntityFireball) this.trackedEntity; + var2 = null; + byte var3 = 63; + + if (this.trackedEntity instanceof EntitySmallFireball) { + var3 = 64; + } else if (this.trackedEntity instanceof EntityWitherSkull) { + var3 = 66; + } + + if (var5.shootingEntity != null) { + var2 = new Packet23VehicleSpawn(this.trackedEntity, var3, + ((EntityFireball) this.trackedEntity).shootingEntity.entityId); + } else { + var2 = new Packet23VehicleSpawn(this.trackedEntity, var3, 0); + } + + var2.speedX = (int) (var5.accelerationX * 8000.0D); + var2.speedY = (int) (var5.accelerationY * 8000.0D); + var2.speedZ = (int) (var5.accelerationZ * 8000.0D); + return var2; + } else if (this.trackedEntity instanceof EntityEgg) { + return new Packet23VehicleSpawn(this.trackedEntity, 62); + } else if (this.trackedEntity instanceof EntityTNTPrimed) { + return new Packet23VehicleSpawn(this.trackedEntity, 50); + } else if (this.trackedEntity instanceof EntityEnderCrystal) { + return new Packet23VehicleSpawn(this.trackedEntity, 51); + } else if (this.trackedEntity instanceof EntityFallingSand) { + EntityFallingSand var4 = (EntityFallingSand) this.trackedEntity; + return new Packet23VehicleSpawn(this.trackedEntity, 70, var4.blockID | var4.metadata << 16); + } else if (this.trackedEntity instanceof EntityPainting) { + return new Packet25EntityPainting((EntityPainting) this.trackedEntity); + } else if (this.trackedEntity instanceof EntityItemFrame) { + EntityItemFrame var1 = (EntityItemFrame) this.trackedEntity; + var2 = new Packet23VehicleSpawn(this.trackedEntity, 71, var1.hangingDirection); + var2.xPosition = MathHelper.floor_float((float) (var1.xPosition * 32)); + var2.yPosition = MathHelper.floor_float((float) (var1.yPosition * 32)); + var2.zPosition = MathHelper.floor_float((float) (var1.zPosition * 32)); + return var2; + } else if (this.trackedEntity instanceof EntityXPOrb) { + return new Packet26EntityExpOrb((EntityXPOrb) this.trackedEntity); + } else { + throw new IllegalArgumentException("Don\'t know how to add " + this.trackedEntity.getClass() + "!"); + } + } + } else { + this.lastHeadMotion = MathHelper.floor_float(this.trackedEntity.getRotationYawHead() * 256.0F / 360.0F); + return new Packet24MobSpawn((EntityLiving) this.trackedEntity); + } + } + + /** + * Remove a tracked player from our list and tell the tracked player to destroy + * us from their world. + */ + public void removeTrackedPlayerSymmetric(EntityPlayerMP par1EntityPlayerMP) { + if (this.trackingPlayers.contains(par1EntityPlayerMP)) { + this.trackingPlayers.remove(par1EntityPlayerMP); + par1EntityPlayerMP.destroyedItemsNetCache.add(Integer.valueOf(this.trackedEntity.entityId)); + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityVillager.java b/sp-server/src/main/java/net/minecraft/src/EntityVillager.java new file mode 100644 index 0000000..45b21a1 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityVillager.java @@ -0,0 +1,684 @@ +package net.minecraft.src; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Random; + +public class EntityVillager extends EntityAgeable implements INpc, IMerchant { + private int randomTickDivider; + private boolean isMating; + private boolean isPlaying; + Village villageObj; + + /** This villager's current customer. */ + private EntityPlayer buyingPlayer; + + /** Initialises the MerchantRecipeList.java */ + private MerchantRecipeList buyingList; + private int timeUntilReset; + + /** addDefaultEquipmentAndRecipies is called if this is true */ + private boolean needsInitilization; + private int wealth; + + /** Last player to trade with this villager, used for aggressivity. */ + private String lastBuyingPlayer; + private boolean field_82190_bM; + private float field_82191_bN; + + /** Selling list of Villagers items. */ + private static final Map villagersSellingList = new HashMap(); + + /** Selling list of Blacksmith items. */ + private static final Map blacksmithSellingList = new HashMap(); + + public EntityVillager(World par1World) { + this(par1World, 0); + } + + public EntityVillager(World par1World, int par2) { + super(par1World); + this.randomTickDivider = 0; + this.isMating = false; + this.isPlaying = false; + this.villageObj = null; + this.setProfession(par2); + this.texture = "/mob/villager/villager.png"; + this.moveSpeed = 0.5F; + this.setSize(0.6F, 1.8F); + this.getNavigator().setBreakDoors(true); + this.getNavigator().setAvoidsWater(true); + this.tasks.addTask(0, new EntityAISwimming(this)); + this.tasks.addTask(1, new EntityAIAvoidEntity(this, EntityZombie.class, 8.0F, 0.3F, 0.35F)); + this.tasks.addTask(1, new EntityAITradePlayer(this)); + this.tasks.addTask(1, new EntityAILookAtTradePlayer(this)); + this.tasks.addTask(2, new EntityAIMoveIndoors(this)); + this.tasks.addTask(3, new EntityAIRestrictOpenDoor(this)); + this.tasks.addTask(4, new EntityAIOpenDoor(this, true)); + this.tasks.addTask(5, new EntityAIMoveTwardsRestriction(this, 0.3F)); + this.tasks.addTask(6, new EntityAIVillagerMate(this)); + this.tasks.addTask(7, new EntityAIFollowGolem(this)); + this.tasks.addTask(8, new EntityAIPlay(this, 0.32F)); + this.tasks.addTask(9, new EntityAIWatchClosest2(this, EntityPlayer.class, 3.0F, 1.0F)); + this.tasks.addTask(9, new EntityAIWatchClosest2(this, EntityVillager.class, 5.0F, 0.02F)); + this.tasks.addTask(9, new EntityAIWander(this, 0.3F)); + this.tasks.addTask(10, new EntityAIWatchClosest(this, EntityLiving.class, 8.0F)); + } + + /** + * Returns true if the newer Entity AI code should be run + */ + public boolean isAIEnabled() { + return true; + } + + /** + * main AI tick function, replaces updateEntityActionState + */ + protected void updateAITick() { + if (--this.randomTickDivider <= 0) { + this.worldObj.villageCollectionObj.addVillagerPosition(MathHelper.floor_double(this.posX), + MathHelper.floor_double(this.posY), MathHelper.floor_double(this.posZ)); + this.randomTickDivider = 70 + this.rand.nextInt(50); + this.villageObj = this.worldObj.villageCollectionObj.findNearestVillage(MathHelper.floor_double(this.posX), + MathHelper.floor_double(this.posY), MathHelper.floor_double(this.posZ), 32); + + if (this.villageObj == null) { + this.detachHome(); + } else { + ChunkCoordinates var1 = this.villageObj.getCenter(); + this.setHomeArea(var1.posX, var1.posY, var1.posZ, + (int) ((float) this.villageObj.getVillageRadius() * 0.6F)); + + if (this.field_82190_bM) { + this.field_82190_bM = false; + this.villageObj.func_82683_b(5); + } + } + } + + if (!this.isTrading() && this.timeUntilReset > 0) { + --this.timeUntilReset; + + if (this.timeUntilReset <= 0) { + if (this.needsInitilization) { + if (this.buyingList.size() > 1) { + Iterator var3 = this.buyingList.iterator(); + + while (var3.hasNext()) { + MerchantRecipe var2 = (MerchantRecipe) var3.next(); + + if (var2.func_82784_g()) { + var2.func_82783_a(this.rand.nextInt(6) + this.rand.nextInt(6) + 2); + } + } + } + + this.addDefaultEquipmentAndRecipies(1); + this.needsInitilization = false; + + if (this.villageObj != null && this.lastBuyingPlayer != null) { + this.worldObj.setEntityState(this, (byte) 14); + this.villageObj.setReputationForPlayer(this.lastBuyingPlayer, 1); + } + } + + this.addPotionEffect(new PotionEffect(Potion.regeneration.id, 200, 0)); + } + } + + super.updateAITick(); + } + + /** + * Called when a player interacts with a mob. e.g. gets milk from a cow, gets + * into the saddle on a pig. + */ + public boolean interact(EntityPlayer par1EntityPlayer) { + ItemStack var2 = par1EntityPlayer.inventory.getCurrentItem(); + boolean var3 = var2 != null && var2.itemID == Item.monsterPlacer.itemID; + + if (!var3 && this.isEntityAlive() && !this.isTrading() && !this.isChild()) { + if (!this.worldObj.isRemote) { + this.setCustomer(par1EntityPlayer); + par1EntityPlayer.displayGUIMerchant(this, this.func_94057_bL()); + } + + return true; + } else { + return super.interact(par1EntityPlayer); + } + } + + protected void entityInit() { + super.entityInit(); + this.dataWatcher.addObject(16, Integer.valueOf(0)); + } + + public int getMaxHealth() { + return 20; + } + + /** + * (abstract) Protected helper method to write subclass entity data to NBT. + */ + public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) { + super.writeEntityToNBT(par1NBTTagCompound); + par1NBTTagCompound.setInteger("Profession", this.getProfession()); + par1NBTTagCompound.setInteger("Riches", this.wealth); + + if (this.buyingList != null) { + par1NBTTagCompound.setCompoundTag("Offers", this.buyingList.getRecipiesAsTags()); + } + } + + /** + * (abstract) Protected helper method to read subclass entity data from NBT. + */ + public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) { + super.readEntityFromNBT(par1NBTTagCompound); + this.setProfession(par1NBTTagCompound.getInteger("Profession")); + this.wealth = par1NBTTagCompound.getInteger("Riches"); + + if (par1NBTTagCompound.hasKey("Offers")) { + NBTTagCompound var2 = par1NBTTagCompound.getCompoundTag("Offers"); + this.buyingList = new MerchantRecipeList(var2); + } + } + + /** + * Determines if an entity can be despawned, used on idle far away entities + */ + protected boolean canDespawn() { + return false; + } + + /** + * Returns the sound this mob makes while it's alive. + */ + protected String getLivingSound() { + return "mob.villager.default"; + } + + /** + * Returns the sound this mob makes when it is hurt. + */ + protected String getHurtSound() { + return "mob.villager.defaulthurt"; + } + + /** + * Returns the sound this mob makes on death. + */ + protected String getDeathSound() { + return "mob.villager.defaultdeath"; + } + + public void setProfession(int par1) { + this.dataWatcher.updateObject(16, Integer.valueOf(par1)); + } + + public int getProfession() { + return this.dataWatcher.getWatchableObjectInt(16); + } + + public boolean isMating() { + return this.isMating; + } + + public void setMating(boolean par1) { + this.isMating = par1; + } + + public void setPlaying(boolean par1) { + this.isPlaying = par1; + } + + public boolean isPlaying() { + return this.isPlaying; + } + + public void setRevengeTarget(EntityLiving par1EntityLiving) { + super.setRevengeTarget(par1EntityLiving); + + if (this.villageObj != null && par1EntityLiving != null) { + this.villageObj.addOrRenewAgressor(par1EntityLiving); + + if (par1EntityLiving instanceof EntityPlayer) { + byte var2 = -1; + + if (this.isChild()) { + var2 = -3; + } + + this.villageObj.setReputationForPlayer(((EntityPlayer) par1EntityLiving).getCommandSenderName(), var2); + + if (this.isEntityAlive()) { + this.worldObj.setEntityState(this, (byte) 13); + } + } + } + } + + /** + * Called when the mob's health reaches 0. + */ + public void onDeath(DamageSource par1DamageSource) { + if (this.villageObj != null) { + Entity var2 = par1DamageSource.getEntity(); + + if (var2 != null) { + if (var2 instanceof EntityPlayer) { + this.villageObj.setReputationForPlayer(((EntityPlayer) var2).getCommandSenderName(), -2); + } else if (var2 instanceof IMob) { + this.villageObj.endMatingSeason(); + } + } else if (var2 == null) { + EntityPlayer var3 = this.worldObj.getClosestPlayerToEntity(this, 16.0D); + + if (var3 != null) { + this.villageObj.endMatingSeason(); + } + } + } + + super.onDeath(par1DamageSource); + } + + public void setCustomer(EntityPlayer par1EntityPlayer) { + this.buyingPlayer = par1EntityPlayer; + } + + public EntityPlayer getCustomer() { + return this.buyingPlayer; + } + + public boolean isTrading() { + return this.buyingPlayer != null; + } + + public void useRecipe(MerchantRecipe par1MerchantRecipe) { + par1MerchantRecipe.incrementToolUses(); + + if (par1MerchantRecipe.hasSameIDsAs((MerchantRecipe) this.buyingList.get(this.buyingList.size() - 1))) { + this.timeUntilReset = 40; + this.needsInitilization = true; + + if (this.buyingPlayer != null) { + this.lastBuyingPlayer = this.buyingPlayer.getCommandSenderName(); + } else { + this.lastBuyingPlayer = null; + } + } + + if (par1MerchantRecipe.getItemToBuy().itemID == Item.emerald.itemID) { + this.wealth += par1MerchantRecipe.getItemToBuy().stackSize; + } + } + + public MerchantRecipeList getRecipes(EntityPlayer par1EntityPlayer) { + if (this.buyingList == null) { + this.addDefaultEquipmentAndRecipies(1); + } + + return this.buyingList; + } + + private float func_82188_j(float par1) { + float var2 = par1 + this.field_82191_bN; + return var2 > 0.9F ? 0.9F - (var2 - 0.9F) : var2; + } + + /** + * based on the villagers profession add items, equipment, and recipies adds + * par1 random items to the list of things that the villager wants to buy. (at + * most 1 of each wanted type is added) + */ + private void addDefaultEquipmentAndRecipies(int par1) { + if (this.buyingList != null) { + this.field_82191_bN = MathHelper.sqrt_float((float) this.buyingList.size()) * 0.2F; + } else { + this.field_82191_bN = 0.0F; + } + + MerchantRecipeList var2; + var2 = new MerchantRecipeList(); + int var6; + label50: + + switch (this.getProfession()) { + case 0: + addMerchantItem(var2, Item.wheat.itemID, this.rand, this.func_82188_j(0.9F)); + addMerchantItem(var2, Block.cloth.blockID, this.rand, this.func_82188_j(0.5F)); + addMerchantItem(var2, Item.chickenRaw.itemID, this.rand, this.func_82188_j(0.5F)); + addMerchantItem(var2, Item.fishCooked.itemID, this.rand, this.func_82188_j(0.4F)); + addBlacksmithItem(var2, Item.bread.itemID, this.rand, this.func_82188_j(0.9F)); + addBlacksmithItem(var2, Item.melon.itemID, this.rand, this.func_82188_j(0.3F)); + addBlacksmithItem(var2, Item.appleRed.itemID, this.rand, this.func_82188_j(0.3F)); + addBlacksmithItem(var2, Item.cookie.itemID, this.rand, this.func_82188_j(0.3F)); + addBlacksmithItem(var2, Item.shears.itemID, this.rand, this.func_82188_j(0.3F)); + addBlacksmithItem(var2, Item.flintAndSteel.itemID, this.rand, this.func_82188_j(0.3F)); + addBlacksmithItem(var2, Item.chickenCooked.itemID, this.rand, this.func_82188_j(0.3F)); + addBlacksmithItem(var2, Item.arrow.itemID, this.rand, this.func_82188_j(0.5F)); + + if (this.rand.nextFloat() < this.func_82188_j(0.5F)) { + var2.add(new MerchantRecipe(new ItemStack(Block.gravel, 10), new ItemStack(Item.emerald), + new ItemStack(Item.flint.itemID, 4 + this.rand.nextInt(2), 0))); + } + + break; + + case 1: + addMerchantItem(var2, Item.paper.itemID, this.rand, this.func_82188_j(0.8F)); + addMerchantItem(var2, Item.book.itemID, this.rand, this.func_82188_j(0.8F)); + addMerchantItem(var2, Item.writtenBook.itemID, this.rand, this.func_82188_j(0.3F)); + addBlacksmithItem(var2, Block.bookShelf.blockID, this.rand, this.func_82188_j(0.8F)); + addBlacksmithItem(var2, Block.glass.blockID, this.rand, this.func_82188_j(0.2F)); + addBlacksmithItem(var2, Item.compass.itemID, this.rand, this.func_82188_j(0.2F)); + addBlacksmithItem(var2, Item.pocketSundial.itemID, this.rand, this.func_82188_j(0.2F)); + + if (this.rand.nextFloat() < this.func_82188_j(0.07F)) { + Enchantment var8 = Enchantment.field_92090_c[this.rand.nextInt(Enchantment.field_92090_c.length)]; + int var10 = MathHelper.getRandomIntegerInRange(this.rand, var8.getMinLevel(), var8.getMaxLevel()); + ItemStack var11 = Item.enchantedBook.func_92111_a(new EnchantmentData(var8, var10)); + var6 = 2 + this.rand.nextInt(5 + var10 * 10) + 3 * var10; + var2.add(new MerchantRecipe(new ItemStack(Item.book), new ItemStack(Item.emerald, var6), var11)); + } + + break; + + case 2: + addBlacksmithItem(var2, Item.eyeOfEnder.itemID, this.rand, this.func_82188_j(0.3F)); + addBlacksmithItem(var2, Item.expBottle.itemID, this.rand, this.func_82188_j(0.2F)); + addBlacksmithItem(var2, Item.redstone.itemID, this.rand, this.func_82188_j(0.4F)); + addBlacksmithItem(var2, Block.glowStone.blockID, this.rand, this.func_82188_j(0.3F)); + int[] var3 = new int[] { Item.swordIron.itemID, Item.swordDiamond.itemID, Item.plateIron.itemID, + Item.plateDiamond.itemID, Item.axeIron.itemID, Item.axeDiamond.itemID, Item.pickaxeIron.itemID, + Item.pickaxeDiamond.itemID }; + int[] var4 = var3; + int var5 = var3.length; + var6 = 0; + + while (true) { + if (var6 >= var5) { + break label50; + } + + int var7 = var4[var6]; + + if (this.rand.nextFloat() < this.func_82188_j(0.05F)) { + var2.add(new MerchantRecipe(new ItemStack(var7, 1, 0), + new ItemStack(Item.emerald, 2 + this.rand.nextInt(3), 0), + EnchantmentHelper.addRandomEnchantment(this.rand, new ItemStack(var7, 1, 0), + 5 + this.rand.nextInt(15)))); + } + + ++var6; + } + + case 3: + addMerchantItem(var2, Item.coal.itemID, this.rand, this.func_82188_j(0.7F)); + addMerchantItem(var2, Item.ingotIron.itemID, this.rand, this.func_82188_j(0.5F)); + addMerchantItem(var2, Item.ingotGold.itemID, this.rand, this.func_82188_j(0.5F)); + addMerchantItem(var2, Item.diamond.itemID, this.rand, this.func_82188_j(0.5F)); + addBlacksmithItem(var2, Item.swordIron.itemID, this.rand, this.func_82188_j(0.5F)); + addBlacksmithItem(var2, Item.swordDiamond.itemID, this.rand, this.func_82188_j(0.5F)); + addBlacksmithItem(var2, Item.axeIron.itemID, this.rand, this.func_82188_j(0.3F)); + addBlacksmithItem(var2, Item.axeDiamond.itemID, this.rand, this.func_82188_j(0.3F)); + addBlacksmithItem(var2, Item.pickaxeIron.itemID, this.rand, this.func_82188_j(0.5F)); + addBlacksmithItem(var2, Item.pickaxeDiamond.itemID, this.rand, this.func_82188_j(0.5F)); + addBlacksmithItem(var2, Item.shovelIron.itemID, this.rand, this.func_82188_j(0.2F)); + addBlacksmithItem(var2, Item.shovelDiamond.itemID, this.rand, this.func_82188_j(0.2F)); + addBlacksmithItem(var2, Item.hoeIron.itemID, this.rand, this.func_82188_j(0.2F)); + addBlacksmithItem(var2, Item.hoeDiamond.itemID, this.rand, this.func_82188_j(0.2F)); + addBlacksmithItem(var2, Item.bootsIron.itemID, this.rand, this.func_82188_j(0.2F)); + addBlacksmithItem(var2, Item.bootsDiamond.itemID, this.rand, this.func_82188_j(0.2F)); + addBlacksmithItem(var2, Item.helmetIron.itemID, this.rand, this.func_82188_j(0.2F)); + addBlacksmithItem(var2, Item.helmetDiamond.itemID, this.rand, this.func_82188_j(0.2F)); + addBlacksmithItem(var2, Item.plateIron.itemID, this.rand, this.func_82188_j(0.2F)); + addBlacksmithItem(var2, Item.plateDiamond.itemID, this.rand, this.func_82188_j(0.2F)); + addBlacksmithItem(var2, Item.legsIron.itemID, this.rand, this.func_82188_j(0.2F)); + addBlacksmithItem(var2, Item.legsDiamond.itemID, this.rand, this.func_82188_j(0.2F)); + addBlacksmithItem(var2, Item.bootsChain.itemID, this.rand, this.func_82188_j(0.1F)); + addBlacksmithItem(var2, Item.helmetChain.itemID, this.rand, this.func_82188_j(0.1F)); + addBlacksmithItem(var2, Item.plateChain.itemID, this.rand, this.func_82188_j(0.1F)); + addBlacksmithItem(var2, Item.legsChain.itemID, this.rand, this.func_82188_j(0.1F)); + break; + + case 4: + addMerchantItem(var2, Item.coal.itemID, this.rand, this.func_82188_j(0.7F)); + addMerchantItem(var2, Item.porkRaw.itemID, this.rand, this.func_82188_j(0.5F)); + addMerchantItem(var2, Item.beefRaw.itemID, this.rand, this.func_82188_j(0.5F)); + addBlacksmithItem(var2, Item.saddle.itemID, this.rand, this.func_82188_j(0.1F)); + addBlacksmithItem(var2, Item.plateLeather.itemID, this.rand, this.func_82188_j(0.3F)); + addBlacksmithItem(var2, Item.bootsLeather.itemID, this.rand, this.func_82188_j(0.3F)); + addBlacksmithItem(var2, Item.helmetLeather.itemID, this.rand, this.func_82188_j(0.3F)); + addBlacksmithItem(var2, Item.legsLeather.itemID, this.rand, this.func_82188_j(0.3F)); + addBlacksmithItem(var2, Item.porkCooked.itemID, this.rand, this.func_82188_j(0.3F)); + addBlacksmithItem(var2, Item.beefCooked.itemID, this.rand, this.func_82188_j(0.3F)); + } + + if (var2.isEmpty()) { + addMerchantItem(var2, Item.ingotGold.itemID, this.rand, 1.0F); + } + + Collections.shuffle(var2); + + if (this.buyingList == null) { + this.buyingList = new MerchantRecipeList(); + } + + for (int var9 = 0; var9 < par1 && var9 < var2.size(); ++var9) { + this.buyingList.addToListWithCheck((MerchantRecipe) var2.get(var9)); + } + } + + /** + * each recipie takes a random stack from villagerStockList and offers it for 1 + * emerald + */ + private static void addMerchantItem(MerchantRecipeList par0MerchantRecipeList, int par1, Random par2Random, + float par3) { + if (par2Random.nextFloat() < par3) { + par0MerchantRecipeList.add(new MerchantRecipe(getRandomSizedStack(par1, par2Random), Item.emerald)); + } + } + + private static ItemStack getRandomSizedStack(int par0, Random par1Random) { + return new ItemStack(par0, getRandomCountForItem(par0, par1Random), 0); + } + + /** + * default to 1, and villagerStockList contains a min/max amount for each index + */ + private static int getRandomCountForItem(int par0, Random par1Random) { + Tuple var2 = (Tuple) villagersSellingList.get(Integer.valueOf(par0)); + return var2 == null ? 1 + : (((Integer) var2.getFirst()).intValue() >= ((Integer) var2.getSecond()).intValue() + ? ((Integer) var2.getFirst()).intValue() + : ((Integer) var2.getFirst()).intValue() + par1Random.nextInt( + ((Integer) var2.getSecond()).intValue() - ((Integer) var2.getFirst()).intValue())); + } + + private static void addBlacksmithItem(MerchantRecipeList par0MerchantRecipeList, int par1, Random par2Random, + float par3) { + if (par2Random.nextFloat() < par3) { + int var4 = getRandomCountForBlacksmithItem(par1, par2Random); + ItemStack var5; + ItemStack var6; + + if (var4 < 0) { + var5 = new ItemStack(Item.emerald.itemID, 1, 0); + var6 = new ItemStack(par1, -var4, 0); + } else { + var5 = new ItemStack(Item.emerald.itemID, var4, 0); + var6 = new ItemStack(par1, 1, 0); + } + + par0MerchantRecipeList.add(new MerchantRecipe(var5, var6)); + } + } + + private static int getRandomCountForBlacksmithItem(int par0, Random par1Random) { + Tuple var2 = (Tuple) blacksmithSellingList.get(Integer.valueOf(par0)); + return var2 == null ? 1 + : (((Integer) var2.getFirst()).intValue() >= ((Integer) var2.getSecond()).intValue() + ? ((Integer) var2.getFirst()).intValue() + : ((Integer) var2.getFirst()).intValue() + par1Random.nextInt( + ((Integer) var2.getSecond()).intValue() - ((Integer) var2.getFirst()).intValue())); + } + + /** + * Initialize this creature. + */ + public void initCreature() { + this.setProfession(this.worldObj.rand.nextInt(5)); + } + + public void func_82187_q() { + this.field_82190_bM = true; + } + + public EntityVillager func_90012_b(EntityAgeable par1EntityAgeable) { + EntityVillager var2 = new EntityVillager(this.worldObj); + var2.initCreature(); + return var2; + } + + public EntityAgeable createChild(EntityAgeable par1EntityAgeable) { + return this.func_90012_b(par1EntityAgeable); + } + + static { + villagersSellingList.put(Integer.valueOf(Item.coal.itemID), + new Tuple(Integer.valueOf(16), Integer.valueOf(24))); + villagersSellingList.put(Integer.valueOf(Item.ingotIron.itemID), + new Tuple(Integer.valueOf(8), Integer.valueOf(10))); + villagersSellingList.put(Integer.valueOf(Item.ingotGold.itemID), + new Tuple(Integer.valueOf(8), Integer.valueOf(10))); + villagersSellingList.put(Integer.valueOf(Item.diamond.itemID), + new Tuple(Integer.valueOf(4), Integer.valueOf(6))); + villagersSellingList.put(Integer.valueOf(Item.paper.itemID), + new Tuple(Integer.valueOf(24), Integer.valueOf(36))); + villagersSellingList.put(Integer.valueOf(Item.book.itemID), + new Tuple(Integer.valueOf(11), Integer.valueOf(13))); + villagersSellingList.put(Integer.valueOf(Item.writtenBook.itemID), + new Tuple(Integer.valueOf(1), Integer.valueOf(1))); + villagersSellingList.put(Integer.valueOf(Item.enderPearl.itemID), + new Tuple(Integer.valueOf(3), Integer.valueOf(4))); + villagersSellingList.put(Integer.valueOf(Item.eyeOfEnder.itemID), + new Tuple(Integer.valueOf(2), Integer.valueOf(3))); + villagersSellingList.put(Integer.valueOf(Item.porkRaw.itemID), + new Tuple(Integer.valueOf(14), Integer.valueOf(18))); + villagersSellingList.put(Integer.valueOf(Item.beefRaw.itemID), + new Tuple(Integer.valueOf(14), Integer.valueOf(18))); + villagersSellingList.put(Integer.valueOf(Item.chickenRaw.itemID), + new Tuple(Integer.valueOf(14), Integer.valueOf(18))); + villagersSellingList.put(Integer.valueOf(Item.fishCooked.itemID), + new Tuple(Integer.valueOf(9), Integer.valueOf(13))); + villagersSellingList.put(Integer.valueOf(Item.seeds.itemID), + new Tuple(Integer.valueOf(34), Integer.valueOf(48))); + villagersSellingList.put(Integer.valueOf(Item.melonSeeds.itemID), + new Tuple(Integer.valueOf(30), Integer.valueOf(38))); + villagersSellingList.put(Integer.valueOf(Item.pumpkinSeeds.itemID), + new Tuple(Integer.valueOf(30), Integer.valueOf(38))); + villagersSellingList.put(Integer.valueOf(Item.wheat.itemID), + new Tuple(Integer.valueOf(18), Integer.valueOf(22))); + villagersSellingList.put(Integer.valueOf(Block.cloth.blockID), + new Tuple(Integer.valueOf(14), Integer.valueOf(22))); + villagersSellingList.put(Integer.valueOf(Item.rottenFlesh.itemID), + new Tuple(Integer.valueOf(36), Integer.valueOf(64))); + blacksmithSellingList.put(Integer.valueOf(Item.flintAndSteel.itemID), + new Tuple(Integer.valueOf(3), Integer.valueOf(4))); + blacksmithSellingList.put(Integer.valueOf(Item.shears.itemID), + new Tuple(Integer.valueOf(3), Integer.valueOf(4))); + blacksmithSellingList.put(Integer.valueOf(Item.swordIron.itemID), + new Tuple(Integer.valueOf(7), Integer.valueOf(11))); + blacksmithSellingList.put(Integer.valueOf(Item.swordDiamond.itemID), + new Tuple(Integer.valueOf(12), Integer.valueOf(14))); + blacksmithSellingList.put(Integer.valueOf(Item.axeIron.itemID), + new Tuple(Integer.valueOf(6), Integer.valueOf(8))); + blacksmithSellingList.put(Integer.valueOf(Item.axeDiamond.itemID), + new Tuple(Integer.valueOf(9), Integer.valueOf(12))); + blacksmithSellingList.put(Integer.valueOf(Item.pickaxeIron.itemID), + new Tuple(Integer.valueOf(7), Integer.valueOf(9))); + blacksmithSellingList.put(Integer.valueOf(Item.pickaxeDiamond.itemID), + new Tuple(Integer.valueOf(10), Integer.valueOf(12))); + blacksmithSellingList.put(Integer.valueOf(Item.shovelIron.itemID), + new Tuple(Integer.valueOf(4), Integer.valueOf(6))); + blacksmithSellingList.put(Integer.valueOf(Item.shovelDiamond.itemID), + new Tuple(Integer.valueOf(7), Integer.valueOf(8))); + blacksmithSellingList.put(Integer.valueOf(Item.hoeIron.itemID), + new Tuple(Integer.valueOf(4), Integer.valueOf(6))); + blacksmithSellingList.put(Integer.valueOf(Item.hoeDiamond.itemID), + new Tuple(Integer.valueOf(7), Integer.valueOf(8))); + blacksmithSellingList.put(Integer.valueOf(Item.bootsIron.itemID), + new Tuple(Integer.valueOf(4), Integer.valueOf(6))); + blacksmithSellingList.put(Integer.valueOf(Item.bootsDiamond.itemID), + new Tuple(Integer.valueOf(7), Integer.valueOf(8))); + blacksmithSellingList.put(Integer.valueOf(Item.helmetIron.itemID), + new Tuple(Integer.valueOf(4), Integer.valueOf(6))); + blacksmithSellingList.put(Integer.valueOf(Item.helmetDiamond.itemID), + new Tuple(Integer.valueOf(7), Integer.valueOf(8))); + blacksmithSellingList.put(Integer.valueOf(Item.plateIron.itemID), + new Tuple(Integer.valueOf(10), Integer.valueOf(14))); + blacksmithSellingList.put(Integer.valueOf(Item.plateDiamond.itemID), + new Tuple(Integer.valueOf(16), Integer.valueOf(19))); + blacksmithSellingList.put(Integer.valueOf(Item.legsIron.itemID), + new Tuple(Integer.valueOf(8), Integer.valueOf(10))); + blacksmithSellingList.put(Integer.valueOf(Item.legsDiamond.itemID), + new Tuple(Integer.valueOf(11), Integer.valueOf(14))); + blacksmithSellingList.put(Integer.valueOf(Item.bootsChain.itemID), + new Tuple(Integer.valueOf(5), Integer.valueOf(7))); + blacksmithSellingList.put(Integer.valueOf(Item.helmetChain.itemID), + new Tuple(Integer.valueOf(5), Integer.valueOf(7))); + blacksmithSellingList.put(Integer.valueOf(Item.plateChain.itemID), + new Tuple(Integer.valueOf(11), Integer.valueOf(15))); + blacksmithSellingList.put(Integer.valueOf(Item.legsChain.itemID), + new Tuple(Integer.valueOf(9), Integer.valueOf(11))); + blacksmithSellingList.put(Integer.valueOf(Item.bread.itemID), + new Tuple(Integer.valueOf(-4), Integer.valueOf(-2))); + blacksmithSellingList.put(Integer.valueOf(Item.melon.itemID), + new Tuple(Integer.valueOf(-8), Integer.valueOf(-4))); + blacksmithSellingList.put(Integer.valueOf(Item.appleRed.itemID), + new Tuple(Integer.valueOf(-8), Integer.valueOf(-4))); + blacksmithSellingList.put(Integer.valueOf(Item.cookie.itemID), + new Tuple(Integer.valueOf(-10), Integer.valueOf(-7))); + blacksmithSellingList.put(Integer.valueOf(Block.glass.blockID), + new Tuple(Integer.valueOf(-5), Integer.valueOf(-3))); + blacksmithSellingList.put(Integer.valueOf(Block.bookShelf.blockID), + new Tuple(Integer.valueOf(3), Integer.valueOf(4))); + blacksmithSellingList.put(Integer.valueOf(Item.plateLeather.itemID), + new Tuple(Integer.valueOf(4), Integer.valueOf(5))); + blacksmithSellingList.put(Integer.valueOf(Item.bootsLeather.itemID), + new Tuple(Integer.valueOf(2), Integer.valueOf(4))); + blacksmithSellingList.put(Integer.valueOf(Item.helmetLeather.itemID), + new Tuple(Integer.valueOf(2), Integer.valueOf(4))); + blacksmithSellingList.put(Integer.valueOf(Item.legsLeather.itemID), + new Tuple(Integer.valueOf(2), Integer.valueOf(4))); + blacksmithSellingList.put(Integer.valueOf(Item.saddle.itemID), + new Tuple(Integer.valueOf(6), Integer.valueOf(8))); + blacksmithSellingList.put(Integer.valueOf(Item.expBottle.itemID), + new Tuple(Integer.valueOf(-4), Integer.valueOf(-1))); + blacksmithSellingList.put(Integer.valueOf(Item.redstone.itemID), + new Tuple(Integer.valueOf(-4), Integer.valueOf(-1))); + blacksmithSellingList.put(Integer.valueOf(Item.compass.itemID), + new Tuple(Integer.valueOf(10), Integer.valueOf(12))); + blacksmithSellingList.put(Integer.valueOf(Item.pocketSundial.itemID), + new Tuple(Integer.valueOf(10), Integer.valueOf(12))); + blacksmithSellingList.put(Integer.valueOf(Block.glowStone.blockID), + new Tuple(Integer.valueOf(-3), Integer.valueOf(-1))); + blacksmithSellingList.put(Integer.valueOf(Item.porkCooked.itemID), + new Tuple(Integer.valueOf(-7), Integer.valueOf(-5))); + blacksmithSellingList.put(Integer.valueOf(Item.beefCooked.itemID), + new Tuple(Integer.valueOf(-7), Integer.valueOf(-5))); + blacksmithSellingList.put(Integer.valueOf(Item.chickenCooked.itemID), + new Tuple(Integer.valueOf(-8), Integer.valueOf(-6))); + blacksmithSellingList.put(Integer.valueOf(Item.eyeOfEnder.itemID), + new Tuple(Integer.valueOf(7), Integer.valueOf(11))); + blacksmithSellingList.put(Integer.valueOf(Item.arrow.itemID), + new Tuple(Integer.valueOf(-12), Integer.valueOf(-8))); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityWaterMob.java b/sp-server/src/main/java/net/minecraft/src/EntityWaterMob.java new file mode 100644 index 0000000..165df54 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityWaterMob.java @@ -0,0 +1,60 @@ +package net.minecraft.src; + +public abstract class EntityWaterMob extends EntityCreature implements IAnimals { + public EntityWaterMob(World par1World) { + super(par1World); + } + + public boolean canBreatheUnderwater() { + return true; + } + + /** + * Checks if the entity's current position is a valid location to spawn this + * entity. + */ + public boolean getCanSpawnHere() { + return this.worldObj.checkNoEntityCollision(this.boundingBox); + } + + /** + * Get number of ticks, at least during which the living entity will be silent. + */ + public int getTalkInterval() { + return 120; + } + + /** + * Determines if an entity can be despawned, used on idle far away entities + */ + protected boolean canDespawn() { + return true; + } + + /** + * Get the experience points the entity currently has. + */ + protected int getExperiencePoints(EntityPlayer par1EntityPlayer) { + return 1 + this.worldObj.rand.nextInt(3); + } + + /** + * Gets called every tick from main Entity class + */ + public void onEntityUpdate() { + int var1 = this.getAir(); + super.onEntityUpdate(); + + if (this.isEntityAlive() && !this.isInsideOfMaterial(Material.water)) { + --var1; + this.setAir(var1); + + if (this.getAir() == -20) { + this.setAir(0); + this.attackEntityFrom(DamageSource.drown, 2); + } + } else { + this.setAir(300); + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityWeatherEffect.java b/sp-server/src/main/java/net/minecraft/src/EntityWeatherEffect.java new file mode 100644 index 0000000..1d81075 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityWeatherEffect.java @@ -0,0 +1,7 @@ +package net.minecraft.src; + +public abstract class EntityWeatherEffect extends Entity { + public EntityWeatherEffect(World par1World) { + super(par1World); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityWitch.java b/sp-server/src/main/java/net/minecraft/src/EntityWitch.java new file mode 100644 index 0000000..b6debc7 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityWitch.java @@ -0,0 +1,219 @@ +package net.minecraft.src; + +import java.util.Iterator; +import java.util.List; + +public class EntityWitch extends EntityMob implements IRangedAttackMob { + /** List of items a witch should drop on death. */ + private static final int[] witchDrops = new int[] { Item.lightStoneDust.itemID, Item.sugar.itemID, + Item.redstone.itemID, Item.spiderEye.itemID, Item.glassBottle.itemID, Item.gunpowder.itemID, + Item.stick.itemID, Item.stick.itemID }; + + /** + * Timer used as interval for a witch's attack, decremented every tick if + * aggressive and when reaches zero the witch will throw a potion at the target + * entity. + */ + private int witchAttackTimer = 0; + + public EntityWitch(World par1World) { + super(par1World); + this.texture = "/mob/villager/witch.png"; + this.moveSpeed = 0.25F; + this.tasks.addTask(1, new EntityAISwimming(this)); + this.tasks.addTask(2, new EntityAIArrowAttack(this, this.moveSpeed, 60, 10.0F)); + this.tasks.addTask(2, new EntityAIWander(this, this.moveSpeed)); + this.tasks.addTask(3, new EntityAIWatchClosest(this, EntityPlayer.class, 8.0F)); + this.tasks.addTask(3, new EntityAILookIdle(this)); + this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, false)); + this.targetTasks.addTask(2, new EntityAINearestAttackableTarget(this, EntityPlayer.class, 16.0F, 0, true)); + } + + protected void entityInit() { + super.entityInit(); + this.getDataWatcher().addObject(21, Byte.valueOf((byte) 0)); + } + + /** + * Returns the sound this mob makes while it's alive. + */ + protected String getLivingSound() { + return "mob.witch.idle"; + } + + /** + * Returns the sound this mob makes when it is hurt. + */ + protected String getHurtSound() { + return "mob.witch.hurt"; + } + + /** + * Returns the sound this mob makes on death. + */ + protected String getDeathSound() { + return "mob.witch.death"; + } + + /** + * Set whether this witch is aggressive at an entity. + */ + public void setAggressive(boolean par1) { + this.getDataWatcher().updateObject(21, Byte.valueOf((byte) (par1 ? 1 : 0))); + } + + /** + * Return whether this witch is aggressive at an entity. + */ + public boolean getAggressive() { + return this.getDataWatcher().getWatchableObjectByte(21) == 1; + } + + public int getMaxHealth() { + return 26; + } + + /** + * Returns true if the newer Entity AI code should be run + */ + public boolean isAIEnabled() { + return true; + } + + /** + * Called frequently so the entity can update its state every tick as required. + * For example, zombies and skeletons use this to react to sunlight and start to + * burn. + */ + public void onLivingUpdate() { + if (!this.worldObj.isRemote) { + if (this.getAggressive()) { + if (this.witchAttackTimer-- <= 0) { + this.setAggressive(false); + ItemStack var1 = this.getHeldItem(); + this.setCurrentItemOrArmor(0, (ItemStack) null); + + if (var1 != null && var1.itemID == Item.potion.itemID) { + List var2 = Item.potion.getEffects(var1); + + if (var2 != null) { + Iterator var3 = var2.iterator(); + + while (var3.hasNext()) { + PotionEffect var4 = (PotionEffect) var3.next(); + this.addPotionEffect(new PotionEffect(var4)); + } + } + } + } + } else { + short var5 = -1; + + if (this.rand.nextFloat() < 0.15F && this.isBurning() && !this.isPotionActive(Potion.fireResistance)) { + var5 = 16307; + } else if (this.rand.nextFloat() < 0.05F && this.health < this.getMaxHealth()) { + var5 = 16341; + } else if (this.rand.nextFloat() < 0.25F && this.getAttackTarget() != null + && !this.isPotionActive(Potion.moveSpeed) + && this.getAttackTarget().getDistanceSqToEntity(this) > 121.0D) { + var5 = 16274; + } else if (this.rand.nextFloat() < 0.25F && this.getAttackTarget() != null + && !this.isPotionActive(Potion.moveSpeed) + && this.getAttackTarget().getDistanceSqToEntity(this) > 121.0D) { + var5 = 16274; + } + + if (var5 > -1) { + this.setCurrentItemOrArmor(0, new ItemStack(Item.potion, 1, var5)); + this.witchAttackTimer = this.getHeldItem().getMaxItemUseDuration(); + this.setAggressive(true); + } + } + + if (this.rand.nextFloat() < 7.5E-4F) { + this.worldObj.setEntityState(this, (byte) 15); + } + } + + super.onLivingUpdate(); + } + + /** + * Reduces damage, depending on potions + */ + protected int applyPotionDamageCalculations(DamageSource par1DamageSource, int par2) { + par2 = super.applyPotionDamageCalculations(par1DamageSource, par2); + + if (par1DamageSource.getEntity() == this) { + par2 = 0; + } + + if (par1DamageSource.isMagicDamage()) { + par2 = (int) ((double) par2 * 0.15D); + } + + return par2; + } + + /** + * This method returns a value to be applied directly to entity speed, this + * factor is less than 1 when a slowdown potion effect is applied, more than 1 + * when a haste potion effect is applied and 2 for fleeing entities. + */ + public float getSpeedModifier() { + float var1 = super.getSpeedModifier(); + + if (this.getAggressive()) { + var1 *= 0.75F; + } + + return var1; + } + + /** + * Drop 0-2 items of this living's type + */ + protected void dropFewItems(boolean par1, int par2) { + int var3 = this.rand.nextInt(3) + 1; + + for (int var4 = 0; var4 < var3; ++var4) { + int var5 = this.rand.nextInt(3); + int var6 = witchDrops[this.rand.nextInt(witchDrops.length)]; + + if (par2 > 0) { + var5 += this.rand.nextInt(par2 + 1); + } + + for (int var7 = 0; var7 < var5; ++var7) { + this.dropItem(var6, 1); + } + } + } + + /** + * Attack the specified entity using a ranged attack. + */ + public void attackEntityWithRangedAttack(EntityLiving par1EntityLiving, float par2) { + if (!this.getAggressive()) { + EntityPotion var3 = new EntityPotion(this.worldObj, this, 32732); + var3.rotationPitch -= -20.0F; + double var4 = par1EntityLiving.posX + par1EntityLiving.motionX - this.posX; + double var6 = par1EntityLiving.posY + (double) par1EntityLiving.getEyeHeight() - 1.100000023841858D + - this.posY; + double var8 = par1EntityLiving.posZ + par1EntityLiving.motionZ - this.posZ; + float var10 = MathHelper.sqrt_double(var4 * var4 + var8 * var8); + + if (var10 >= 8.0F && !par1EntityLiving.isPotionActive(Potion.moveSlowdown)) { + var3.setPotionDamage(32698); + } else if (par1EntityLiving.getHealth() >= 8 && !par1EntityLiving.isPotionActive(Potion.poison)) { + var3.setPotionDamage(32660); + } else if (var10 <= 3.0F && !par1EntityLiving.isPotionActive(Potion.weakness) + && this.rand.nextFloat() < 0.25F) { + var3.setPotionDamage(32696); + } + + var3.setThrowableHeading(var4, var6 + (double) (var10 * 0.2F), var8, 0.75F, 8.0F); + this.worldObj.spawnEntityInWorld(var3); + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityWither.java b/sp-server/src/main/java/net/minecraft/src/EntityWither.java new file mode 100644 index 0000000..9679983 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityWither.java @@ -0,0 +1,539 @@ +package net.minecraft.src; + +import java.util.List; + +public class EntityWither extends EntityMob implements IRangedAttackMob { + private float[] field_82220_d = new float[2]; + private float[] field_82221_e = new float[2]; + private float[] field_82217_f = new float[2]; + private float[] field_82218_g = new float[2]; + private int[] field_82223_h = new int[2]; + private int[] field_82224_i = new int[2]; + private int field_82222_j; + + /** Selector used to determine the entities a wither boss should attack. */ + private static final IEntitySelector attackEntitySelector = new EntityWitherAttackFilter(); + + public EntityWither(World par1World) { + super(par1World); + this.setEntityHealth(this.getMaxHealth()); + this.texture = "/mob/wither.png"; + this.setSize(0.9F, 4.0F); + this.isImmuneToFire = true; + this.moveSpeed = 0.6F; + this.getNavigator().setCanSwim(true); + this.tasks.addTask(0, new EntityAISwimming(this)); + this.tasks.addTask(2, new EntityAIArrowAttack(this, this.moveSpeed, 40, 20.0F)); + this.tasks.addTask(5, new EntityAIWander(this, this.moveSpeed)); + this.tasks.addTask(6, new EntityAIWatchClosest(this, EntityPlayer.class, 8.0F)); + this.tasks.addTask(7, new EntityAILookIdle(this)); + this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, false)); + this.targetTasks.addTask(2, new EntityAINearestAttackableTarget(this, EntityLiving.class, 30.0F, 0, false, + false, attackEntitySelector)); + this.experienceValue = 50; + } + + protected void entityInit() { + super.entityInit(); + this.dataWatcher.addObject(16, new Integer(100)); + this.dataWatcher.addObject(17, new Integer(0)); + this.dataWatcher.addObject(18, new Integer(0)); + this.dataWatcher.addObject(19, new Integer(0)); + this.dataWatcher.addObject(20, new Integer(0)); + } + + /** + * (abstract) Protected helper method to write subclass entity data to NBT. + */ + public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) { + super.writeEntityToNBT(par1NBTTagCompound); + par1NBTTagCompound.setInteger("Invul", this.func_82212_n()); + } + + /** + * (abstract) Protected helper method to read subclass entity data from NBT. + */ + public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) { + super.readEntityFromNBT(par1NBTTagCompound); + this.func_82215_s(par1NBTTagCompound.getInteger("Invul")); + this.dataWatcher.updateObject(16, Integer.valueOf(this.health)); + } + + /** + * Returns the sound this mob makes while it's alive. + */ + protected String getLivingSound() { + return "mob.wither.idle"; + } + + /** + * Returns the sound this mob makes when it is hurt. + */ + protected String getHurtSound() { + return "mob.wither.hurt"; + } + + /** + * Returns the sound this mob makes on death. + */ + protected String getDeathSound() { + return "mob.wither.death"; + } + + /** + * Called frequently so the entity can update its state every tick as required. + * For example, zombies and skeletons use this to react to sunlight and start to + * burn. + */ + public void onLivingUpdate() { + if (!this.worldObj.isRemote) { + this.dataWatcher.updateObject(16, Integer.valueOf(this.health)); + } + + this.motionY *= 0.6000000238418579D; + double var4; + double var6; + double var8; + + if (!this.worldObj.isRemote && this.getWatchedTargetId(0) > 0) { + Entity var1 = this.worldObj.getEntityByID(this.getWatchedTargetId(0)); + + if (var1 != null) { + if (this.posY < var1.posY || !this.isArmored() && this.posY < var1.posY + 5.0D) { + if (this.motionY < 0.0D) { + this.motionY = 0.0D; + } + + this.motionY += (0.5D - this.motionY) * 0.6000000238418579D; + } + + double var2 = var1.posX - this.posX; + var4 = var1.posZ - this.posZ; + var6 = var2 * var2 + var4 * var4; + + if (var6 > 9.0D) { + var8 = (double) MathHelper.sqrt_double(var6); + this.motionX += (var2 / var8 * 0.5D - this.motionX) * 0.6000000238418579D; + this.motionZ += (var4 / var8 * 0.5D - this.motionZ) * 0.6000000238418579D; + } + } + } + + if (this.motionX * this.motionX + this.motionZ * this.motionZ > 0.05000000074505806D) { + this.rotationYaw = (float) Math.atan2(this.motionZ, this.motionX) * (180F / (float) Math.PI) - 90.0F; + } + + super.onLivingUpdate(); + int var20; + + for (var20 = 0; var20 < 2; ++var20) { + this.field_82218_g[var20] = this.field_82221_e[var20]; + this.field_82217_f[var20] = this.field_82220_d[var20]; + } + + int var21; + + for (var20 = 0; var20 < 2; ++var20) { + var21 = this.getWatchedTargetId(var20 + 1); + Entity var3 = null; + + if (var21 > 0) { + var3 = this.worldObj.getEntityByID(var21); + } + + if (var3 != null) { + var4 = this.func_82214_u(var20 + 1); + var6 = this.func_82208_v(var20 + 1); + var8 = this.func_82213_w(var20 + 1); + double var10 = var3.posX - var4; + double var12 = var3.posY + (double) var3.getEyeHeight() - var6; + double var14 = var3.posZ - var8; + double var16 = (double) MathHelper.sqrt_double(var10 * var10 + var14 * var14); + float var18 = (float) (Math.atan2(var14, var10) * 180.0D / Math.PI) - 90.0F; + float var19 = (float) (-(Math.atan2(var12, var16) * 180.0D / Math.PI)); + this.field_82220_d[var20] = this.func_82204_b(this.field_82220_d[var20], var19, 40.0F); + this.field_82221_e[var20] = this.func_82204_b(this.field_82221_e[var20], var18, 10.0F); + } else { + this.field_82221_e[var20] = this.func_82204_b(this.field_82221_e[var20], this.renderYawOffset, 10.0F); + } + } + + boolean var22 = this.isArmored(); + + for (var21 = 0; var21 < 3; ++var21) { + double var23 = this.func_82214_u(var21); + double var5 = this.func_82208_v(var21); + double var7 = this.func_82213_w(var21); + this.worldObj.spawnParticle("smoke", var23 + this.rand.nextGaussian() * 0.30000001192092896D, + var5 + this.rand.nextGaussian() * 0.30000001192092896D, + var7 + this.rand.nextGaussian() * 0.30000001192092896D, 0.0D, 0.0D, 0.0D); + + if (var22 && this.worldObj.rand.nextInt(4) == 0) { + this.worldObj.spawnParticle("mobSpell", var23 + this.rand.nextGaussian() * 0.30000001192092896D, + var5 + this.rand.nextGaussian() * 0.30000001192092896D, + var7 + this.rand.nextGaussian() * 0.30000001192092896D, 0.699999988079071D, 0.699999988079071D, + 0.5D); + } + } + + if (this.func_82212_n() > 0) { + for (var21 = 0; var21 < 3; ++var21) { + this.worldObj.spawnParticle("mobSpell", this.posX + this.rand.nextGaussian() * 1.0D, + this.posY + (double) (this.rand.nextFloat() * 3.3F), + this.posZ + this.rand.nextGaussian() * 1.0D, 0.699999988079071D, 0.699999988079071D, + 0.8999999761581421D); + } + } + } + + protected void updateAITasks() { + int var1; + + if (this.func_82212_n() > 0) { + var1 = this.func_82212_n() - 1; + + if (var1 <= 0) { + this.worldObj.newExplosion(this, this.posX, this.posY + (double) this.getEyeHeight(), this.posZ, 7.0F, + false, this.worldObj.getGameRules().getGameRuleBooleanValue("mobGriefing")); + this.worldObj.func_82739_e(1013, (int) this.posX, (int) this.posY, (int) this.posZ, 0); + } + + this.func_82215_s(var1); + + if (this.ticksExisted % 10 == 0) { + this.heal(10); + } + } else { + super.updateAITasks(); + int var12; + + for (var1 = 1; var1 < 3; ++var1) { + if (this.ticksExisted >= this.field_82223_h[var1 - 1]) { + this.field_82223_h[var1 - 1] = this.ticksExisted + 10 + this.rand.nextInt(10); + + if (this.worldObj.difficultySetting >= 2) { + int var10001 = var1 - 1; + int var10003 = this.field_82224_i[var1 - 1]; + this.field_82224_i[var10001] = this.field_82224_i[var1 - 1] + 1; + + if (var10003 > 15) { + float var2 = 10.0F; + float var3 = 5.0F; + double var4 = MathHelper.getRandomDoubleInRange(this.rand, this.posX - (double) var2, + this.posX + (double) var2); + double var6 = MathHelper.getRandomDoubleInRange(this.rand, this.posY - (double) var3, + this.posY + (double) var3); + double var8 = MathHelper.getRandomDoubleInRange(this.rand, this.posZ - (double) var2, + this.posZ + (double) var2); + this.func_82209_a(var1 + 1, var4, var6, var8, true); + this.field_82224_i[var1 - 1] = 0; + } + } + + var12 = this.getWatchedTargetId(var1); + + if (var12 > 0) { + Entity var14 = this.worldObj.getEntityByID(var12); + + if (var14 != null && var14.isEntityAlive() && this.getDistanceSqToEntity(var14) <= 900.0D + && this.canEntityBeSeen(var14)) { + this.func_82216_a(var1 + 1, (EntityLiving) var14); + this.field_82223_h[var1 - 1] = this.ticksExisted + 40 + this.rand.nextInt(20); + this.field_82224_i[var1 - 1] = 0; + } else { + this.func_82211_c(var1, 0); + } + } else { + List var13 = this.worldObj.selectEntitiesWithinAABB(EntityLiving.class, + this.boundingBox.expand(20.0D, 8.0D, 20.0D), attackEntitySelector); + + for (int var16 = 0; var16 < 10 && !var13.isEmpty(); ++var16) { + EntityLiving var5 = (EntityLiving) var13.get(this.rand.nextInt(var13.size())); + + if (var5 != this && var5.isEntityAlive() && this.canEntityBeSeen(var5)) { + if (var5 instanceof EntityPlayer) { + if (!((EntityPlayer) var5).capabilities.disableDamage) { + this.func_82211_c(var1, var5.entityId); + } + } else { + this.func_82211_c(var1, var5.entityId); + } + + break; + } + + var13.remove(var5); + } + } + } + } + + if (this.getAttackTarget() != null) { + this.func_82211_c(0, this.getAttackTarget().entityId); + } else { + this.func_82211_c(0, 0); + } + + if (this.field_82222_j > 0) { + --this.field_82222_j; + + if (this.field_82222_j == 0 && this.worldObj.getGameRules().getGameRuleBooleanValue("mobGriefing")) { + var1 = MathHelper.floor_double(this.posY); + var12 = MathHelper.floor_double(this.posX); + int var15 = MathHelper.floor_double(this.posZ); + boolean var17 = false; + + for (int var18 = -1; var18 <= 1; ++var18) { + for (int var19 = -1; var19 <= 1; ++var19) { + for (int var7 = 0; var7 <= 3; ++var7) { + int var20 = var12 + var18; + int var9 = var1 + var7; + int var10 = var15 + var19; + int var11 = this.worldObj.getBlockId(var20, var9, var10); + + if (var11 > 0 && var11 != Block.bedrock.blockID && var11 != Block.endPortal.blockID + && var11 != Block.endPortalFrame.blockID) { + var17 = this.worldObj.destroyBlock(var20, var9, var10, true) || var17; + } + } + } + } + + if (var17) { + this.worldObj.playAuxSFXAtEntity((EntityPlayer) null, 1012, (int) this.posX, (int) this.posY, + (int) this.posZ, 0); + } + } + } + + if (this.ticksExisted % 20 == 0) { + this.heal(1); + } + } + } + + public void func_82206_m() { + this.func_82215_s(220); + this.setEntityHealth(this.getMaxHealth() / 3); + } + + /** + * Sets the Entity inside a web block. + */ + public void setInWeb() { + } + + /** + * Returns the current armor value as determined by a call to + * InventoryPlayer.getTotalArmorValue + */ + public int getTotalArmorValue() { + return 4; + } + + private double func_82214_u(int par1) { + if (par1 <= 0) { + return this.posX; + } else { + float var2 = (this.renderYawOffset + (float) (180 * (par1 - 1))) / 180.0F * (float) Math.PI; + float var3 = MathHelper.cos(var2); + return this.posX + (double) var3 * 1.3D; + } + } + + private double func_82208_v(int par1) { + return par1 <= 0 ? this.posY + 3.0D : this.posY + 2.2D; + } + + private double func_82213_w(int par1) { + if (par1 <= 0) { + return this.posZ; + } else { + float var2 = (this.renderYawOffset + (float) (180 * (par1 - 1))) / 180.0F * (float) Math.PI; + float var3 = MathHelper.sin(var2); + return this.posZ + (double) var3 * 1.3D; + } + } + + private float func_82204_b(float par1, float par2, float par3) { + float var4 = MathHelper.wrapAngleTo180_float(par2 - par1); + + if (var4 > par3) { + var4 = par3; + } + + if (var4 < -par3) { + var4 = -par3; + } + + return par1 + var4; + } + + private void func_82216_a(int par1, EntityLiving par2EntityLiving) { + this.func_82209_a(par1, par2EntityLiving.posX, + par2EntityLiving.posY + (double) par2EntityLiving.getEyeHeight() * 0.5D, par2EntityLiving.posZ, + par1 == 0 && this.rand.nextFloat() < 0.001F); + } + + private void func_82209_a(int par1, double par2, double par4, double par6, boolean par8) { + this.worldObj.playAuxSFXAtEntity((EntityPlayer) null, 1014, (int) this.posX, (int) this.posY, (int) this.posZ, + 0); + double var9 = this.func_82214_u(par1); + double var11 = this.func_82208_v(par1); + double var13 = this.func_82213_w(par1); + double var15 = par2 - var9; + double var17 = par4 - var11; + double var19 = par6 - var13; + EntityWitherSkull var21 = new EntityWitherSkull(this.worldObj, this, var15, var17, var19); + + if (par8) { + var21.setInvulnerable(true); + } + + var21.posY = var11; + var21.posX = var9; + var21.posZ = var13; + this.worldObj.spawnEntityInWorld(var21); + } + + /** + * Attack the specified entity using a ranged attack. + */ + public void attackEntityWithRangedAttack(EntityLiving par1EntityLiving, float par2) { + this.func_82216_a(0, par1EntityLiving); + } + + /** + * Called when the entity is attacked. + */ + public boolean attackEntityFrom(DamageSource par1DamageSource, int par2) { + if (this.isEntityInvulnerable()) { + return false; + } else if (par1DamageSource == DamageSource.drown) { + return false; + } else if (this.func_82212_n() > 0) { + return false; + } else { + Entity var3; + + if (this.isArmored()) { + var3 = par1DamageSource.getSourceOfDamage(); + + if (var3 instanceof EntityArrow) { + return false; + } + } + + var3 = par1DamageSource.getEntity(); + + if (var3 != null && !(var3 instanceof EntityPlayer) && var3 instanceof EntityLiving + && ((EntityLiving) var3).getCreatureAttribute() == this.getCreatureAttribute()) { + return false; + } else { + if (this.field_82222_j <= 0) { + this.field_82222_j = 20; + } + + for (int var4 = 0; var4 < this.field_82224_i.length; ++var4) { + this.field_82224_i[var4] += 3; + } + + return super.attackEntityFrom(par1DamageSource, par2); + } + } + } + + /** + * Drop 0-2 items of this living's type + */ + protected void dropFewItems(boolean par1, int par2) { + this.dropItem(Item.netherStar.itemID, 1); + } + + /** + * Makes the entity despawn if requirements are reached + */ + protected void despawnEntity() { + this.entityAge = 0; + } + + /** + * Returns true if other Entities should be prevented from moving through this + * Entity. + */ + public boolean canBeCollidedWith() { + return !this.isDead; + } + + /** + * Returns the health points of the dragon. + */ + public int getBossHealth() { + return this.dataWatcher.getWatchableObjectInt(16); + } + + /** + * Called when the mob is falling. Calculates and applies fall damage. + */ + protected void fall(float par1) { + } + + /** + * adds a PotionEffect to the entity + */ + public void addPotionEffect(PotionEffect par1PotionEffect) { + } + + /** + * Returns true if the newer Entity AI code should be run + */ + protected boolean isAIEnabled() { + return true; + } + + public int getMaxHealth() { + return 300; + } + + public int func_82212_n() { + return this.dataWatcher.getWatchableObjectInt(20); + } + + public void func_82215_s(int par1) { + this.dataWatcher.updateObject(20, Integer.valueOf(par1)); + } + + /** + * Returns the target entity ID if present, or -1 if not @param par1 The target + * offset, should be from 0-2 + */ + public int getWatchedTargetId(int par1) { + return this.dataWatcher.getWatchableObjectInt(17 + par1); + } + + public void func_82211_c(int par1, int par2) { + this.dataWatcher.updateObject(17 + par1, Integer.valueOf(par2)); + } + + /** + * Returns whether the wither is armored with its boss armor or not by checking + * whether its health is below half of its maximum. + */ + public boolean isArmored() { + return this.getBossHealth() <= this.getMaxHealth() / 2; + } + + /** + * Get this Entity's EnumCreatureAttribute + */ + public EnumCreatureAttribute getCreatureAttribute() { + return EnumCreatureAttribute.UNDEAD; + } + + /** + * Called when a player mounts an entity. e.g. mounts a pig, mounts a boat. + */ + public void mountEntity(Entity par1Entity) { + this.ridingEntity = null; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityWitherAttackFilter.java b/sp-server/src/main/java/net/minecraft/src/EntityWitherAttackFilter.java new file mode 100644 index 0000000..c972dcf --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityWitherAttackFilter.java @@ -0,0 +1,11 @@ +package net.minecraft.src; + +final class EntityWitherAttackFilter implements IEntitySelector { + /** + * Return whether the specified entity is applicable to this filter. + */ + public boolean isEntityApplicable(Entity par1Entity) { + return par1Entity instanceof EntityLiving + && ((EntityLiving) par1Entity).getCreatureAttribute() != EnumCreatureAttribute.UNDEAD; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityWitherSkull.java b/sp-server/src/main/java/net/minecraft/src/EntityWitherSkull.java new file mode 100644 index 0000000..29bad5e --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityWitherSkull.java @@ -0,0 +1,113 @@ +package net.minecraft.src; + +public class EntityWitherSkull extends EntityFireball { + public EntityWitherSkull(World par1World) { + super(par1World); + this.setSize(0.3125F, 0.3125F); + } + + public EntityWitherSkull(World par1World, EntityLiving par2EntityLiving, double par3, double par5, double par7) { + super(par1World, par2EntityLiving, par3, par5, par7); + this.setSize(0.3125F, 0.3125F); + } + + /** + * Return the motion factor for this projectile. The factor is multiplied by the + * original motion. + */ + protected float getMotionFactor() { + return this.isInvulnerable() ? 0.73F : super.getMotionFactor(); + } + + /** + * Returns true if the entity is on fire. Used by render to add the fire effect + * on rendering. + */ + public boolean isBurning() { + return false; + } + + public float func_82146_a(Explosion par1Explosion, World par2World, int par3, int par4, int par5, Block par6Block) { + float var7 = super.func_82146_a(par1Explosion, par2World, par3, par4, par5, par6Block); + + if (this.isInvulnerable() && par6Block != Block.bedrock && par6Block != Block.endPortal + && par6Block != Block.endPortalFrame) { + var7 = Math.min(0.8F, var7); + } + + return var7; + } + + /** + * Called when this EntityFireball hits a block or entity. + */ + protected void onImpact(MovingObjectPosition par1MovingObjectPosition) { + if (!this.worldObj.isRemote) { + if (par1MovingObjectPosition.entityHit != null) { + if (this.shootingEntity != null) { + if (par1MovingObjectPosition.entityHit + .attackEntityFrom(DamageSource.causeMobDamage(this.shootingEntity), 8) + && !par1MovingObjectPosition.entityHit.isEntityAlive()) { + this.shootingEntity.heal(5); + } + } else { + par1MovingObjectPosition.entityHit.attackEntityFrom(DamageSource.magic, 5); + } + + if (par1MovingObjectPosition.entityHit instanceof EntityLiving) { + byte var2 = 0; + + if (this.worldObj.difficultySetting > 1) { + if (this.worldObj.difficultySetting == 2) { + var2 = 10; + } else if (this.worldObj.difficultySetting == 3) { + var2 = 40; + } + } + + if (var2 > 0) { + ((EntityLiving) par1MovingObjectPosition.entityHit) + .addPotionEffect(new PotionEffect(Potion.wither.id, 20 * var2, 1)); + } + } + } + + this.worldObj.newExplosion(this, this.posX, this.posY, this.posZ, 1.0F, false, + this.worldObj.getGameRules().getGameRuleBooleanValue("mobGriefing")); + this.setDead(); + } + } + + /** + * Returns true if other Entities should be prevented from moving through this + * Entity. + */ + public boolean canBeCollidedWith() { + return false; + } + + /** + * Called when the entity is attacked. + */ + public boolean attackEntityFrom(DamageSource par1DamageSource, int par2) { + return false; + } + + protected void entityInit() { + this.dataWatcher.addObject(10, Byte.valueOf((byte) 0)); + } + + /** + * Return whether this skull comes from an invulnerable (aura) wither boss. + */ + public boolean isInvulnerable() { + return this.dataWatcher.getWatchableObjectByte(10) == 1; + } + + /** + * Set whether this skull comes from an invulnerable (aura) wither boss. + */ + public void setInvulnerable(boolean par1) { + this.dataWatcher.updateObject(10, Byte.valueOf((byte) (par1 ? 1 : 0))); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityWolf.java b/sp-server/src/main/java/net/minecraft/src/EntityWolf.java new file mode 100644 index 0000000..5b2b433 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityWolf.java @@ -0,0 +1,434 @@ +package net.minecraft.src; + +public class EntityWolf extends EntityTameable { + private float field_70926_e; + private float field_70924_f; + + /** true is the wolf is wet else false */ + private boolean isShaking; + private boolean field_70928_h; + + /** + * This time increases while wolf is shaking and emitting water particles. + */ + private float timeWolfIsShaking; + private float prevTimeWolfIsShaking; + + public EntityWolf(World par1World) { + super(par1World); + this.texture = "/mob/wolf.png"; + this.setSize(0.6F, 0.8F); + this.moveSpeed = 0.3F; + this.getNavigator().setAvoidsWater(true); + this.tasks.addTask(1, new EntityAISwimming(this)); + this.tasks.addTask(2, this.aiSit); + this.tasks.addTask(3, new EntityAILeapAtTarget(this, 0.4F)); + this.tasks.addTask(4, new EntityAIAttackOnCollide(this, this.moveSpeed, true)); + this.tasks.addTask(5, new EntityAIFollowOwner(this, this.moveSpeed, 10.0F, 2.0F)); + this.tasks.addTask(6, new EntityAIMate(this, this.moveSpeed)); + this.tasks.addTask(7, new EntityAIWander(this, this.moveSpeed)); + this.tasks.addTask(8, new EntityAIBeg(this, 8.0F)); + this.tasks.addTask(9, new EntityAIWatchClosest(this, EntityPlayer.class, 8.0F)); + this.tasks.addTask(9, new EntityAILookIdle(this)); + this.targetTasks.addTask(1, new EntityAIOwnerHurtByTarget(this)); + this.targetTasks.addTask(2, new EntityAIOwnerHurtTarget(this)); + this.targetTasks.addTask(3, new EntityAIHurtByTarget(this, true)); + this.targetTasks.addTask(4, new EntityAITargetNonTamed(this, EntitySheep.class, 16.0F, 200, false)); + } + + /** + * Returns true if the newer Entity AI code should be run + */ + public boolean isAIEnabled() { + return true; + } + + /** + * Sets the active target the Task system uses for tracking + */ + public void setAttackTarget(EntityLiving par1EntityLiving) { + super.setAttackTarget(par1EntityLiving); + + if (par1EntityLiving instanceof EntityPlayer) { + this.setAngry(true); + } + } + + /** + * main AI tick function, replaces updateEntityActionState + */ + protected void updateAITick() { + this.dataWatcher.updateObject(18, Integer.valueOf(this.getHealth())); + } + + public int getMaxHealth() { + return this.isTamed() ? 20 : 8; + } + + protected void entityInit() { + super.entityInit(); + this.dataWatcher.addObject(18, new Integer(this.getHealth())); + this.dataWatcher.addObject(19, new Byte((byte) 0)); + this.dataWatcher.addObject(20, new Byte((byte) BlockCloth.getBlockFromDye(1))); + } + + /** + * Plays step sound at given x, y, z for the entity + */ + protected void playStepSound(int par1, int par2, int par3, int par4) { + this.playSound("mob.wolf.step", 0.15F, 1.0F); + } + + /** + * (abstract) Protected helper method to write subclass entity data to NBT. + */ + public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) { + super.writeEntityToNBT(par1NBTTagCompound); + par1NBTTagCompound.setBoolean("Angry", this.isAngry()); + par1NBTTagCompound.setByte("CollarColor", (byte) this.getCollarColor()); + } + + /** + * (abstract) Protected helper method to read subclass entity data from NBT. + */ + public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) { + super.readEntityFromNBT(par1NBTTagCompound); + this.setAngry(par1NBTTagCompound.getBoolean("Angry")); + + if (par1NBTTagCompound.hasKey("CollarColor")) { + this.setCollarColor(par1NBTTagCompound.getByte("CollarColor")); + } + } + + /** + * Determines if an entity can be despawned, used on idle far away entities + */ + protected boolean canDespawn() { + return this.isAngry() && !this.isTamed(); + } + + /** + * Returns the sound this mob makes while it's alive. + */ + protected String getLivingSound() { + return this + .isAngry() + ? "mob.wolf.growl" + : (this.rand.nextInt(3) == 0 + ? (this.isTamed() && this.dataWatcher.getWatchableObjectInt(18) < 10 ? "mob.wolf.whine" + : "mob.wolf.panting") + : "mob.wolf.bark"); + } + + /** + * Returns the sound this mob makes when it is hurt. + */ + protected String getHurtSound() { + return "mob.wolf.hurt"; + } + + /** + * Returns the sound this mob makes on death. + */ + protected String getDeathSound() { + return "mob.wolf.death"; + } + + /** + * Returns the volume for the sounds this mob makes. + */ + protected float getSoundVolume() { + return 0.4F; + } + + /** + * Returns the item ID for the item the mob drops on death. + */ + protected int getDropItemId() { + return -1; + } + + /** + * Called frequently so the entity can update its state every tick as required. + * For example, zombies and skeletons use this to react to sunlight and start to + * burn. + */ + public void onLivingUpdate() { + super.onLivingUpdate(); + + if (!this.worldObj.isRemote && this.isShaking && !this.field_70928_h && !this.hasPath() && this.onGround) { + this.field_70928_h = true; + this.timeWolfIsShaking = 0.0F; + this.prevTimeWolfIsShaking = 0.0F; + this.worldObj.setEntityState(this, (byte) 8); + } + } + + /** + * Called to update the entity's position/logic. + */ + public void onUpdate() { + super.onUpdate(); + this.field_70924_f = this.field_70926_e; + + if (this.func_70922_bv()) { + this.field_70926_e += (1.0F - this.field_70926_e) * 0.4F; + } else { + this.field_70926_e += (0.0F - this.field_70926_e) * 0.4F; + } + + if (this.func_70922_bv()) { + this.numTicksToChaseTarget = 10; + } + + if (this.isWet()) { + this.isShaking = true; + this.field_70928_h = false; + this.timeWolfIsShaking = 0.0F; + this.prevTimeWolfIsShaking = 0.0F; + } else if ((this.isShaking || this.field_70928_h) && this.field_70928_h) { + if (this.timeWolfIsShaking == 0.0F) { + this.playSound("mob.wolf.shake", this.getSoundVolume(), + (this.rand.nextFloat() - this.rand.nextFloat()) * 0.2F + 1.0F); + } + + this.prevTimeWolfIsShaking = this.timeWolfIsShaking; + this.timeWolfIsShaking += 0.05F; + + if (this.prevTimeWolfIsShaking >= 2.0F) { + this.isShaking = false; + this.field_70928_h = false; + this.prevTimeWolfIsShaking = 0.0F; + this.timeWolfIsShaking = 0.0F; + } + + if (this.timeWolfIsShaking > 0.4F) { + float var1 = (float) this.boundingBox.minY; + int var2 = (int) (MathHelper.sin((this.timeWolfIsShaking - 0.4F) * (float) Math.PI) * 7.0F); + + for (int var3 = 0; var3 < var2; ++var3) { + float var4 = (this.rand.nextFloat() * 2.0F - 1.0F) * this.width * 0.5F; + float var5 = (this.rand.nextFloat() * 2.0F - 1.0F) * this.width * 0.5F; + this.worldObj.spawnParticle("splash", this.posX + (double) var4, (double) (var1 + 0.8F), + this.posZ + (double) var5, this.motionX, this.motionY, this.motionZ); + } + } + } + } + + public float getEyeHeight() { + return this.height * 0.8F; + } + + /** + * The speed it takes to move the entityliving's rotationPitch through the + * faceEntity method. This is only currently use in wolves. + */ + public int getVerticalFaceSpeed() { + return this.isSitting() ? 20 : super.getVerticalFaceSpeed(); + } + + /** + * Called when the entity is attacked. + */ + public boolean attackEntityFrom(DamageSource par1DamageSource, int par2) { + if (this.isEntityInvulnerable()) { + return false; + } else { + Entity var3 = par1DamageSource.getEntity(); + this.aiSit.setSitting(false); + + if (var3 != null && !(var3 instanceof EntityPlayer) && !(var3 instanceof EntityArrow)) { + par2 = (par2 + 1) / 2; + } + + return super.attackEntityFrom(par1DamageSource, par2); + } + } + + public boolean attackEntityAsMob(Entity par1Entity) { + int var2 = this.isTamed() ? 4 : 2; + return par1Entity.attackEntityFrom(DamageSource.causeMobDamage(this), var2); + } + + /** + * Called when a player interacts with a mob. e.g. gets milk from a cow, gets + * into the saddle on a pig. + */ + public boolean interact(EntityPlayer par1EntityPlayer) { + ItemStack var2 = par1EntityPlayer.inventory.getCurrentItem(); + + if (this.isTamed()) { + if (var2 != null) { + if (Item.itemsList[var2.itemID] instanceof ItemFood) { + ItemFood var3 = (ItemFood) Item.itemsList[var2.itemID]; + + if (var3.isWolfsFavoriteMeat() && this.dataWatcher.getWatchableObjectInt(18) < 20) { + if (!par1EntityPlayer.capabilities.isCreativeMode) { + --var2.stackSize; + } + + this.heal(var3.getHealAmount()); + + if (var2.stackSize <= 0) { + par1EntityPlayer.inventory.setInventorySlotContents(par1EntityPlayer.inventory.currentItem, + (ItemStack) null); + } + + return true; + } + } else if (var2.itemID == Item.dyePowder.itemID) { + int var4 = BlockCloth.getBlockFromDye(var2.getItemDamage()); + + if (var4 != this.getCollarColor()) { + this.setCollarColor(var4); + + if (!par1EntityPlayer.capabilities.isCreativeMode && --var2.stackSize <= 0) { + par1EntityPlayer.inventory.setInventorySlotContents(par1EntityPlayer.inventory.currentItem, + (ItemStack) null); + } + + return true; + } + } + } + + if (par1EntityPlayer.username.equalsIgnoreCase(this.getOwnerName()) && !this.worldObj.isRemote + && !this.isBreedingItem(var2)) { + this.aiSit.setSitting(!this.isSitting()); + this.isJumping = false; + this.setPathToEntity((PathEntity) null); + } + } else if (var2 != null && var2.itemID == Item.bone.itemID && !this.isAngry()) { + if (!par1EntityPlayer.capabilities.isCreativeMode) { + --var2.stackSize; + } + + if (var2.stackSize <= 0) { + par1EntityPlayer.inventory.setInventorySlotContents(par1EntityPlayer.inventory.currentItem, + (ItemStack) null); + } + + if (!this.worldObj.isRemote) { + if (this.rand.nextInt(3) == 0) { + this.setTamed(true); + this.setPathToEntity((PathEntity) null); + this.setAttackTarget((EntityLiving) null); + this.aiSit.setSitting(true); + this.setEntityHealth(20); + this.setOwner(par1EntityPlayer.username); + this.playTameEffect(true); + this.worldObj.setEntityState(this, (byte) 7); + } else { + this.playTameEffect(false); + this.worldObj.setEntityState(this, (byte) 6); + } + } + + return true; + } + + return super.interact(par1EntityPlayer); + } + + /** + * Checks if the parameter is an item which this animal can be fed to breed it + * (wheat, carrots or seeds depending on the animal type) + */ + public boolean isBreedingItem(ItemStack par1ItemStack) { + return par1ItemStack == null ? false + : (!(Item.itemsList[par1ItemStack.itemID] instanceof ItemFood) ? false + : ((ItemFood) Item.itemsList[par1ItemStack.itemID]).isWolfsFavoriteMeat()); + } + + /** + * Will return how many at most can spawn in a chunk at once. + */ + public int getMaxSpawnedInChunk() { + return 8; + } + + /** + * Determines whether this wolf is angry or not. + */ + public boolean isAngry() { + return (this.dataWatcher.getWatchableObjectByte(16) & 2) != 0; + } + + /** + * Sets whether this wolf is angry or not. + */ + public void setAngry(boolean par1) { + byte var2 = this.dataWatcher.getWatchableObjectByte(16); + + if (par1) { + this.dataWatcher.updateObject(16, Byte.valueOf((byte) (var2 | 2))); + } else { + this.dataWatcher.updateObject(16, Byte.valueOf((byte) (var2 & -3))); + } + } + + /** + * Return this wolf's collar color. + */ + public int getCollarColor() { + return this.dataWatcher.getWatchableObjectByte(20) & 15; + } + + /** + * Set this wolf's collar color. + */ + public void setCollarColor(int par1) { + this.dataWatcher.updateObject(20, Byte.valueOf((byte) (par1 & 15))); + } + + /** + * This function is used when two same-species animals in 'love mode' breed to + * generate the new baby animal. + */ + public EntityWolf spawnBabyAnimal(EntityAgeable par1EntityAgeable) { + EntityWolf var2 = new EntityWolf(this.worldObj); + String var3 = this.getOwnerName(); + + if (var3 != null && var3.trim().length() > 0) { + var2.setOwner(var3); + var2.setTamed(true); + } + + return var2; + } + + public void func_70918_i(boolean par1) { + byte var2 = this.dataWatcher.getWatchableObjectByte(19); + + if (par1) { + this.dataWatcher.updateObject(19, Byte.valueOf((byte) 1)); + } else { + this.dataWatcher.updateObject(19, Byte.valueOf((byte) 0)); + } + } + + /** + * Returns true if the mob is currently able to mate with the specified mob. + */ + public boolean canMateWith(EntityAnimal par1EntityAnimal) { + if (par1EntityAnimal == this) { + return false; + } else if (!this.isTamed()) { + return false; + } else if (!(par1EntityAnimal instanceof EntityWolf)) { + return false; + } else { + EntityWolf var2 = (EntityWolf) par1EntityAnimal; + return !var2.isTamed() ? false : (var2.isSitting() ? false : this.isInLove() && var2.isInLove()); + } + } + + public boolean func_70922_bv() { + return this.dataWatcher.getWatchableObjectByte(19) == 1; + } + + public EntityAgeable createChild(EntityAgeable par1EntityAgeable) { + return this.spawnBabyAnimal(par1EntityAgeable); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityXPOrb.java b/sp-server/src/main/java/net/minecraft/src/EntityXPOrb.java new file mode 100644 index 0000000..3469682 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityXPOrb.java @@ -0,0 +1,230 @@ +package net.minecraft.src; + +public class EntityXPOrb extends Entity { + /** + * A constantly increasing value that RenderXPOrb uses to control the colour + * shifting (Green / yellow) + */ + public int xpColor; + + /** The age of the XP orb in ticks. */ + public int xpOrbAge = 0; + public int field_70532_c; + + /** The health of this XP orb. */ + private int xpOrbHealth = 5; + + /** This is how much XP this orb has. */ + private int xpValue; + + /** The closest EntityPlayer to this orb. */ + private EntityPlayer closestPlayer; + + /** Threshold color for tracking players */ + private int xpTargetColor; + + public EntityXPOrb(World par1World, double par2, double par4, double par6, int par8) { + super(par1World); + this.setSize(0.5F, 0.5F); + this.yOffset = this.height / 2.0F; + this.setPosition(par2, par4, par6); + this.rotationYaw = (float) (Math.random() * 360.0D); + this.motionX = (double) ((float) (Math.random() * 0.20000000298023224D - 0.10000000149011612D) * 2.0F); + this.motionY = (double) ((float) (Math.random() * 0.2D) * 2.0F); + this.motionZ = (double) ((float) (Math.random() * 0.20000000298023224D - 0.10000000149011612D) * 2.0F); + this.xpValue = par8; + } + + /** + * returns if this entity triggers Block.onEntityWalking on the blocks they walk + * on. used for spiders and wolves to prevent them from trampling crops + */ + protected boolean canTriggerWalking() { + return false; + } + + public EntityXPOrb(World par1World) { + super(par1World); + this.setSize(0.25F, 0.25F); + this.yOffset = this.height / 2.0F; + } + + protected void entityInit() { + } + + /** + * Called to update the entity's position/logic. + */ + public void onUpdate() { + super.onUpdate(); + + if (this.field_70532_c > 0) { + --this.field_70532_c; + } + + this.prevPosX = this.posX; + this.prevPosY = this.posY; + this.prevPosZ = this.posZ; + this.motionY -= 0.029999999329447746D; + + if (this.worldObj.getBlockMaterial(MathHelper.floor_double(this.posX), MathHelper.floor_double(this.posY), + MathHelper.floor_double(this.posZ)) == Material.lava) { + this.motionY = 0.20000000298023224D; + this.motionX = (double) ((this.rand.nextFloat() - this.rand.nextFloat()) * 0.2F); + this.motionZ = (double) ((this.rand.nextFloat() - this.rand.nextFloat()) * 0.2F); + this.playSound("random.fizz", 0.4F, 2.0F + this.rand.nextFloat() * 0.4F); + } + + this.pushOutOfBlocks(this.posX, (this.boundingBox.minY + this.boundingBox.maxY) / 2.0D, this.posZ); + double var1 = 8.0D; + + if (this.xpTargetColor < this.xpColor - 20 + this.entityId % 100) { + if (this.closestPlayer == null || this.closestPlayer.getDistanceSqToEntity(this) > var1 * var1) { + this.closestPlayer = this.worldObj.getClosestPlayerToEntity(this, var1); + } + + this.xpTargetColor = this.xpColor; + } + + if (this.closestPlayer != null) { + double var3 = (this.closestPlayer.posX - this.posX) / var1; + double var5 = (this.closestPlayer.posY + (double) this.closestPlayer.getEyeHeight() - this.posY) / var1; + double var7 = (this.closestPlayer.posZ - this.posZ) / var1; + double var9 = Math.sqrt(var3 * var3 + var5 * var5 + var7 * var7); + double var11 = 1.0D - var9; + + if (var11 > 0.0D) { + var11 *= var11; + this.motionX += var3 / var9 * var11 * 0.1D; + this.motionY += var5 / var9 * var11 * 0.1D; + this.motionZ += var7 / var9 * var11 * 0.1D; + } + } + + this.moveEntity(this.motionX, this.motionY, this.motionZ); + float var13 = 0.98F; + + if (this.onGround) { + var13 = 0.58800006F; + int var4 = this.worldObj.getBlockId(MathHelper.floor_double(this.posX), + MathHelper.floor_double(this.boundingBox.minY) - 1, MathHelper.floor_double(this.posZ)); + + if (var4 > 0) { + var13 = Block.blocksList[var4].slipperiness * 0.98F; + } + } + + this.motionX *= (double) var13; + this.motionY *= 0.9800000190734863D; + this.motionZ *= (double) var13; + + if (this.onGround) { + this.motionY *= -0.8999999761581421D; + } + + ++this.xpColor; + ++this.xpOrbAge; + + if (this.xpOrbAge >= 6000) { + this.setDead(); + } + } + + /** + * Returns if this entity is in water and will end up adding the waters velocity + * to the entity + */ + public boolean handleWaterMovement() { + return this.worldObj.handleMaterialAcceleration(this.boundingBox, Material.water, this); + } + + /** + * Will deal the specified amount of damage to the entity if the entity isn't + * immune to fire damage. Args: amountDamage + */ + protected void dealFireDamage(int par1) { + this.attackEntityFrom(DamageSource.inFire, par1); + } + + /** + * Called when the entity is attacked. + */ + public boolean attackEntityFrom(DamageSource par1DamageSource, int par2) { + if (this.isEntityInvulnerable()) { + return false; + } else { + this.setBeenAttacked(); + this.xpOrbHealth -= par2; + + if (this.xpOrbHealth <= 0) { + this.setDead(); + } + + return false; + } + } + + /** + * (abstract) Protected helper method to write subclass entity data to NBT. + */ + public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) { + par1NBTTagCompound.setShort("Health", (short) ((byte) this.xpOrbHealth)); + par1NBTTagCompound.setShort("Age", (short) this.xpOrbAge); + par1NBTTagCompound.setShort("Value", (short) this.xpValue); + } + + /** + * (abstract) Protected helper method to read subclass entity data from NBT. + */ + public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) { + this.xpOrbHealth = par1NBTTagCompound.getShort("Health") & 255; + this.xpOrbAge = par1NBTTagCompound.getShort("Age"); + this.xpValue = par1NBTTagCompound.getShort("Value"); + } + + /** + * Called by a player entity when they collide with an entity + */ + public void onCollideWithPlayer(EntityPlayer par1EntityPlayer) { + if (!this.worldObj.isRemote) { + if (this.field_70532_c == 0 && par1EntityPlayer.xpCooldown == 0) { + par1EntityPlayer.xpCooldown = 2; + this.playSound("random.orb", 0.1F, + 0.5F * ((this.rand.nextFloat() - this.rand.nextFloat()) * 0.7F + 1.8F)); + par1EntityPlayer.onItemPickup(this, 1); + par1EntityPlayer.addExperience(this.xpValue); + this.setDead(); + } + } + } + + /** + * Returns the XP value of this XP orb. + */ + public int getXpValue() { + return this.xpValue; + } + + /** + * Get a fragment of the maximum experience points value for the supplied value + * of experience points value. + */ + public static int getXPSplit(int par0) { + return par0 >= 2477 ? 2477 + : (par0 >= 1237 ? 1237 + : (par0 >= 617 ? 617 + : (par0 >= 307 ? 307 + : (par0 >= 149 ? 149 + : (par0 >= 73 ? 73 + : (par0 >= 37 ? 37 + : (par0 >= 17 ? 17 + : (par0 >= 7 ? 7 : (par0 >= 3 ? 3 : 1))))))))); + } + + /** + * If returns false, the item will not inflict any damage against entities. + */ + public boolean canAttackWithItem() { + return false; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EntityZombie.java b/sp-server/src/main/java/net/minecraft/src/EntityZombie.java new file mode 100644 index 0000000..c1b3597 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EntityZombie.java @@ -0,0 +1,440 @@ +package net.minecraft.src; + +import java.util.Calendar; + +public class EntityZombie extends EntityMob { + /** + * Ticker used to determine the time remaining for this zombie to convert into a + * villager when cured. + */ + private int conversionTime = 0; + + public EntityZombie(World par1World) { + super(par1World); + this.texture = "/mob/zombie.png"; + this.moveSpeed = 0.23F; + this.getNavigator().setBreakDoors(true); + this.tasks.addTask(0, new EntityAISwimming(this)); + this.tasks.addTask(1, new EntityAIBreakDoor(this)); + this.tasks.addTask(2, new EntityAIAttackOnCollide(this, EntityPlayer.class, this.moveSpeed, false)); + this.tasks.addTask(3, new EntityAIAttackOnCollide(this, EntityVillager.class, this.moveSpeed, true)); + this.tasks.addTask(4, new EntityAIMoveTwardsRestriction(this, this.moveSpeed)); + this.tasks.addTask(5, new EntityAIMoveThroughVillage(this, this.moveSpeed, false)); + this.tasks.addTask(6, new EntityAIWander(this, this.moveSpeed)); + this.tasks.addTask(7, new EntityAIWatchClosest(this, EntityPlayer.class, 8.0F)); + this.tasks.addTask(7, new EntityAILookIdle(this)); + this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, true)); + this.targetTasks.addTask(2, new EntityAINearestAttackableTarget(this, EntityPlayer.class, 16.0F, 0, true)); + this.targetTasks.addTask(2, new EntityAINearestAttackableTarget(this, EntityVillager.class, 16.0F, 0, false)); + } + + protected int func_96121_ay() { + return 40; + } + + /** + * This method returns a value to be applied directly to entity speed, this + * factor is less than 1 when a slowdown potion effect is applied, more than 1 + * when a haste potion effect is applied and 2 for fleeing entities. + */ + public float getSpeedModifier() { + return super.getSpeedModifier() * (this.isChild() ? 1.5F : 1.0F); + } + + protected void entityInit() { + super.entityInit(); + this.getDataWatcher().addObject(12, Byte.valueOf((byte) 0)); + this.getDataWatcher().addObject(13, Byte.valueOf((byte) 0)); + this.getDataWatcher().addObject(14, Byte.valueOf((byte) 0)); + } + + public int getMaxHealth() { + return 20; + } + + /** + * Returns the current armor value as determined by a call to + * InventoryPlayer.getTotalArmorValue + */ + public int getTotalArmorValue() { + int var1 = super.getTotalArmorValue() + 2; + + if (var1 > 20) { + var1 = 20; + } + + return var1; + } + + /** + * Returns true if the newer Entity AI code should be run + */ + protected boolean isAIEnabled() { + return true; + } + + /** + * If Animal, checks if the age timer is negative + */ + public boolean isChild() { + return this.getDataWatcher().getWatchableObjectByte(12) == 1; + } + + /** + * Set whether this zombie is a child. + */ + public void setChild(boolean par1) { + this.getDataWatcher().updateObject(12, Byte.valueOf((byte) 1)); + } + + /** + * Return whether this zombie is a villager. + */ + public boolean isVillager() { + return this.getDataWatcher().getWatchableObjectByte(13) == 1; + } + + /** + * Set whether this zombie is a villager. + */ + public void setVillager(boolean par1) { + this.getDataWatcher().updateObject(13, Byte.valueOf((byte) (par1 ? 1 : 0))); + } + + /** + * Called frequently so the entity can update its state every tick as required. + * For example, zombies and skeletons use this to react to sunlight and start to + * burn. + */ + public void onLivingUpdate() { + if (this.worldObj.isDaytime() && !this.worldObj.isRemote && !this.isChild()) { + float var1 = this.getBrightness(1.0F); + + if (var1 > 0.5F && this.rand.nextFloat() * 30.0F < (var1 - 0.4F) * 2.0F + && this.worldObj.canBlockSeeTheSky(MathHelper.floor_double(this.posX), + MathHelper.floor_double(this.posY), MathHelper.floor_double(this.posZ))) { + boolean var2 = true; + ItemStack var3 = this.getEquipmentInSlot(4); + + if (var3 != null) { + if (var3.isItemStackDamageable()) { + var3.setItemDamage(var3.getItemDamageForDisplay() + this.rand.nextInt(2)); + + if (var3.getItemDamageForDisplay() >= var3.getMaxDamage()) { + this.renderBrokenItemStack(var3); + this.setCurrentItemOrArmor(4, (ItemStack) null); + } + } + + var2 = false; + } + + if (var2) { + this.setFire(8); + } + } + } + + super.onLivingUpdate(); + } + + /** + * Called to update the entity's position/logic. + */ + public void onUpdate() { + if (!this.worldObj.isRemote && this.isConverting()) { + int var1 = this.getConversionTimeBoost(); + this.conversionTime -= var1; + + if (this.conversionTime <= 0) { + this.convertToVillager(); + } + } + + super.onUpdate(); + } + + public boolean attackEntityAsMob(Entity par1Entity) { + boolean var2 = super.attackEntityAsMob(par1Entity); + + if (var2 && this.getHeldItem() == null && this.isBurning() + && this.rand.nextFloat() < (float) this.worldObj.difficultySetting * 0.3F) { + par1Entity.setFire(2 * this.worldObj.difficultySetting); + } + + return var2; + } + + /** + * Returns the amount of damage a mob should deal. + */ + public int getAttackStrength(Entity par1Entity) { + ItemStack var2 = this.getHeldItem(); + float var3 = (float) (this.getMaxHealth() - this.getHealth()) / (float) this.getMaxHealth(); + int var4 = 3 + MathHelper.floor_float(var3 * 4.0F); + + if (var2 != null) { + var4 += var2.getDamageVsEntity(this); + } + + return var4; + } + + /** + * Returns the sound this mob makes while it's alive. + */ + protected String getLivingSound() { + return "mob.zombie.say"; + } + + /** + * Returns the sound this mob makes when it is hurt. + */ + protected String getHurtSound() { + return "mob.zombie.hurt"; + } + + /** + * Returns the sound this mob makes on death. + */ + protected String getDeathSound() { + return "mob.zombie.death"; + } + + /** + * Plays step sound at given x, y, z for the entity + */ + protected void playStepSound(int par1, int par2, int par3, int par4) { + this.playSound("mob.zombie.step", 0.15F, 1.0F); + } + + /** + * Returns the item ID for the item the mob drops on death. + */ + protected int getDropItemId() { + return Item.rottenFlesh.itemID; + } + + /** + * Get this Entity's EnumCreatureAttribute + */ + public EnumCreatureAttribute getCreatureAttribute() { + return EnumCreatureAttribute.UNDEAD; + } + + protected void dropRareDrop(int par1) { + switch (this.rand.nextInt(3)) { + case 0: + this.dropItem(Item.ingotIron.itemID, 1); + break; + + case 1: + this.dropItem(Item.carrot.itemID, 1); + break; + + case 2: + this.dropItem(Item.potato.itemID, 1); + } + } + + /** + * Makes entity wear random armor based on difficulty + */ + protected void addRandomArmor() { + super.addRandomArmor(); + + if (this.rand.nextFloat() < (this.worldObj.difficultySetting == 3 ? 0.05F : 0.01F)) { + int var1 = this.rand.nextInt(3); + + if (var1 == 0) { + this.setCurrentItemOrArmor(0, new ItemStack(Item.swordIron)); + } else { + this.setCurrentItemOrArmor(0, new ItemStack(Item.shovelIron)); + } + } + } + + /** + * (abstract) Protected helper method to write subclass entity data to NBT. + */ + public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) { + super.writeEntityToNBT(par1NBTTagCompound); + + if (this.isChild()) { + par1NBTTagCompound.setBoolean("IsBaby", true); + } + + if (this.isVillager()) { + par1NBTTagCompound.setBoolean("IsVillager", true); + } + + par1NBTTagCompound.setInteger("ConversionTime", this.isConverting() ? this.conversionTime : -1); + } + + /** + * (abstract) Protected helper method to read subclass entity data from NBT. + */ + public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) { + super.readEntityFromNBT(par1NBTTagCompound); + + if (par1NBTTagCompound.getBoolean("IsBaby")) { + this.setChild(true); + } + + if (par1NBTTagCompound.getBoolean("IsVillager")) { + this.setVillager(true); + } + + if (par1NBTTagCompound.hasKey("ConversionTime") && par1NBTTagCompound.getInteger("ConversionTime") > -1) { + this.startConversion(par1NBTTagCompound.getInteger("ConversionTime")); + } + } + + /** + * This method gets called when the entity kills another one. + */ + public void onKillEntity(EntityLiving par1EntityLiving) { + super.onKillEntity(par1EntityLiving); + + if (this.worldObj.difficultySetting >= 2 && par1EntityLiving instanceof EntityVillager) { + if (this.worldObj.difficultySetting == 2 && this.rand.nextBoolean()) { + return; + } + + EntityZombie var2 = new EntityZombie(this.worldObj); + var2.func_82149_j(par1EntityLiving); + this.worldObj.removeEntity(par1EntityLiving); + var2.initCreature(); + var2.setVillager(true); + + if (par1EntityLiving.isChild()) { + var2.setChild(true); + } + + this.worldObj.spawnEntityInWorld(var2); + this.worldObj.playAuxSFXAtEntity((EntityPlayer) null, 1016, (int) this.posX, (int) this.posY, + (int) this.posZ, 0); + } + } + + /** + * Initialize this creature. + */ + public void initCreature() { + this.setCanPickUpLoot(this.rand.nextFloat() < pickUpLootProability[this.worldObj.difficultySetting]); + + if (this.worldObj.rand.nextFloat() < 0.05F) { + this.setVillager(true); + } + + this.addRandomArmor(); + this.func_82162_bC(); + + if (this.getEquipmentInSlot(4) == null) { + Calendar var1 = this.worldObj.getCurrentDate(); + + if (var1.get(2) + 1 == 10 && var1.get(5) == 31 && this.rand.nextFloat() < 0.25F) { + this.setCurrentItemOrArmor(4, + new ItemStack(this.rand.nextFloat() < 0.1F ? Block.pumpkinLantern : Block.pumpkin)); + this.equipmentDropChances[4] = 0.0F; + } + } + } + + /** + * Called when a player interacts with a mob. e.g. gets milk from a cow, gets + * into the saddle on a pig. + */ + public boolean interact(EntityPlayer par1EntityPlayer) { + ItemStack var2 = par1EntityPlayer.getCurrentEquippedItem(); + + if (var2 != null && var2.getItem() == Item.appleGold && var2.getItemDamage() == 0 && this.isVillager() + && this.isPotionActive(Potion.weakness)) { + if (!par1EntityPlayer.capabilities.isCreativeMode) { + --var2.stackSize; + } + + if (var2.stackSize <= 0) { + par1EntityPlayer.inventory.setInventorySlotContents(par1EntityPlayer.inventory.currentItem, + (ItemStack) null); + } + + if (!this.worldObj.isRemote) { + this.startConversion(this.rand.nextInt(2401) + 3600); + } + + return true; + } else { + return false; + } + } + + /** + * Starts converting this zombie into a villager. The zombie converts into a + * villager after the specified time in ticks. + */ + protected void startConversion(int par1) { + this.conversionTime = par1; + this.getDataWatcher().updateObject(14, Byte.valueOf((byte) 1)); + this.removePotionEffect(Potion.weakness.id); + this.addPotionEffect( + new PotionEffect(Potion.damageBoost.id, par1, Math.min(this.worldObj.difficultySetting - 1, 0))); + this.worldObj.setEntityState(this, (byte) 16); + } + + /** + * Returns whether this zombie is in the process of converting to a villager + */ + public boolean isConverting() { + return this.getDataWatcher().getWatchableObjectByte(14) == 1; + } + + /** + * Convert this zombie into a villager. + */ + protected void convertToVillager() { + EntityVillager var1 = new EntityVillager(this.worldObj); + var1.func_82149_j(this); + var1.initCreature(); + var1.func_82187_q(); + + if (this.isChild()) { + var1.setGrowingAge(-24000); + } + + this.worldObj.removeEntity(this); + this.worldObj.spawnEntityInWorld(var1); + var1.addPotionEffect(new PotionEffect(Potion.confusion.id, 200, 0)); + this.worldObj.playAuxSFXAtEntity((EntityPlayer) null, 1017, (int) this.posX, (int) this.posY, (int) this.posZ, + 0); + } + + /** + * Return the amount of time decremented from conversionTime every tick. + */ + protected int getConversionTimeBoost() { + int var1 = 1; + + if (this.rand.nextFloat() < 0.01F) { + int var2 = 0; + + for (int var3 = (int) this.posX - 4; var3 < (int) this.posX + 4 && var2 < 14; ++var3) { + for (int var4 = (int) this.posY - 4; var4 < (int) this.posY + 4 && var2 < 14; ++var4) { + for (int var5 = (int) this.posZ - 4; var5 < (int) this.posZ + 4 && var2 < 14; ++var5) { + int var6 = this.worldObj.getBlockId(var3, var4, var5); + + if (var6 == Block.fenceIron.blockID || var6 == Block.bed.blockID) { + if (this.rand.nextFloat() < 0.3F) { + ++var1; + } + + ++var2; + } + } + } + } + } + + return var1; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EnumAction.java b/sp-server/src/main/java/net/minecraft/src/EnumAction.java new file mode 100644 index 0000000..20076ba --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EnumAction.java @@ -0,0 +1,5 @@ +package net.minecraft.src; + +public enum EnumAction { + none, eat, drink, block, bow; +} diff --git a/sp-server/src/main/java/net/minecraft/src/EnumArmorMaterial.java b/sp-server/src/main/java/net/minecraft/src/EnumArmorMaterial.java new file mode 100644 index 0000000..6354d80 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EnumArmorMaterial.java @@ -0,0 +1,62 @@ +package net.minecraft.src; + +public enum EnumArmorMaterial { + CLOTH(5, new int[] { 1, 3, 2, 1 }, 15), CHAIN(15, new int[] { 2, 5, 4, 1 }, 12), + IRON(15, new int[] { 2, 6, 5, 2 }, 9), GOLD(7, new int[] { 2, 5, 3, 1 }, 25), + DIAMOND(33, new int[] { 3, 8, 6, 3 }, 10); + + /** + * Holds the maximum damage factor (each piece multiply this by it's own value) + * of the material, this is the item damage (how much can absorb before breaks) + */ + private int maxDamageFactor; + + /** + * Holds the damage reduction (each 1 points is half a shield on gui) of each + * piece of armor (helmet, plate, legs and boots) + */ + private int[] damageReductionAmountArray; + + /** Return the enchantability factor of the material */ + private int enchantability; + + private EnumArmorMaterial(int par3, int[] par4ArrayOfInteger, int par5) { + this.maxDamageFactor = par3; + this.damageReductionAmountArray = par4ArrayOfInteger; + this.enchantability = par5; + } + + /** + * Returns the durability for a armor slot of for this type. + */ + public int getDurability(int par1) { + return ItemArmor.getMaxDamageArray()[par1] * this.maxDamageFactor; + } + + /** + * Return the damage reduction (each 1 point is a half a shield on gui) of the + * piece index passed (0 = helmet, 1 = plate, 2 = legs and 3 = boots) + */ + public int getDamageReductionAmount(int par1) { + return this.damageReductionAmountArray[par1]; + } + + /** + * Return the enchantability factor of the material. + */ + public int getEnchantability() { + return this.enchantability; + } + + /** + * Return the crafting material for this armor material, used to determine the + * item that can be used to repair an armor piece with an anvil + */ + public int getArmorCraftingMaterial() { + return this == CLOTH ? Item.leather.itemID + : (this == CHAIN ? Item.ingotIron.itemID + : (this == GOLD ? Item.ingotGold.itemID + : (this == IRON ? Item.ingotIron.itemID + : (this == DIAMOND ? Item.diamond.itemID : 0)))); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EnumArt.java b/sp-server/src/main/java/net/minecraft/src/EnumArt.java new file mode 100644 index 0000000..7c74df5 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EnumArt.java @@ -0,0 +1,32 @@ +package net.minecraft.src; + +public enum EnumArt { + Kebab("Kebab", 16, 16, 0, 0), Aztec("Aztec", 16, 16, 16, 0), Alban("Alban", 16, 16, 32, 0), + Aztec2("Aztec2", 16, 16, 48, 0), Bomb("Bomb", 16, 16, 64, 0), Plant("Plant", 16, 16, 80, 0), + Wasteland("Wasteland", 16, 16, 96, 0), Pool("Pool", 32, 16, 0, 32), Courbet("Courbet", 32, 16, 32, 32), + Sea("Sea", 32, 16, 64, 32), Sunset("Sunset", 32, 16, 96, 32), Creebet("Creebet", 32, 16, 128, 32), + Wanderer("Wanderer", 16, 32, 0, 64), Graham("Graham", 16, 32, 16, 64), Match("Match", 32, 32, 0, 128), + Bust("Bust", 32, 32, 32, 128), Stage("Stage", 32, 32, 64, 128), Void("Void", 32, 32, 96, 128), + SkullAndRoses("SkullAndRoses", 32, 32, 128, 128), Wither("Wither", 32, 32, 160, 128), + Fighters("Fighters", 64, 32, 0, 96), Pointer("Pointer", 64, 64, 0, 192), Pigscene("Pigscene", 64, 64, 64, 192), + BurningSkull("BurningSkull", 64, 64, 128, 192), Skeleton("Skeleton", 64, 48, 192, 64), + DonkeyKong("DonkeyKong", 64, 48, 192, 112); + + /** Holds the maximum length of paintings art title. */ + public static final int maxArtTitleLength = "SkullAndRoses".length(); + + /** Painting Title. */ + public final String title; + public final int sizeX; + public final int sizeY; + public final int offsetX; + public final int offsetY; + + private EnumArt(String par3Str, int par4, int par5, int par6, int par7) { + this.title = par3Str; + this.sizeX = par4; + this.sizeY = par5; + this.offsetX = par6; + this.offsetY = par7; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EnumChatFormatting.java b/sp-server/src/main/java/net/minecraft/src/EnumChatFormatting.java new file mode 100644 index 0000000..60ed6cd --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EnumChatFormatting.java @@ -0,0 +1,82 @@ +package net.minecraft.src; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; +import java.util.regex.Pattern; + +public enum EnumChatFormatting { + BLACK('0'), DARK_BLUE('1'), DARK_GREEN('2'), DARK_AQUA('3'), DARK_RED('4'), DARK_PURPLE('5'), GOLD('6'), GRAY('7'), + DARK_GRAY('8'), BLUE('9'), GREEN('a'), AQUA('b'), RED('c'), LIGHT_PURPLE('d'), YELLOW('e'), WHITE('f'), + OBFUSCATED('k', true), BOLD('l', true), STRIKETHROUGH('m', true), UNDERLINE('n', true), ITALIC('o', true), + RESET('r'); + + private static final Map field_96321_w = new HashMap(); + private static final Map field_96331_x = new HashMap(); + private static final Pattern field_96330_y = Pattern.compile("(?i)" + String.valueOf('\u00a7') + "[0-9A-FK-OR]"); + private final char field_96329_z; + private final boolean field_96303_A; + private final String field_96304_B; + + private EnumChatFormatting(char par3) { + this(par3, false); + } + + private EnumChatFormatting(char par3, boolean par4) { + this.field_96329_z = par3; + this.field_96303_A = par4; + this.field_96304_B = "\u00a7" + par3; + } + + public char func_96298_a() { + return this.field_96329_z; + } + + public boolean func_96301_b() { + return this.field_96303_A; + } + + public boolean func_96302_c() { + return !this.field_96303_A && this != RESET; + } + + public String func_96297_d() { + return this.name().toLowerCase(); + } + + public String toString() { + return this.field_96304_B; + } + + public static EnumChatFormatting func_96300_b(String par0Str) { + return par0Str == null ? null : (EnumChatFormatting) field_96331_x.get(par0Str.toLowerCase()); + } + + public static Collection func_96296_a(boolean par0, boolean par1) { + ArrayList var2 = new ArrayList(); + EnumChatFormatting[] var3 = values(); + int var4 = var3.length; + + for (int var5 = 0; var5 < var4; ++var5) { + EnumChatFormatting var6 = var3[var5]; + + if ((!var6.func_96302_c() || par0) && (!var6.func_96301_b() || par1)) { + var2.add(var6.func_96297_d()); + } + } + + return var2; + } + + static { + EnumChatFormatting[] var0 = values(); + int var1 = var0.length; + + for (int var2 = 0; var2 < var1; ++var2) { + EnumChatFormatting var3 = var0[var2]; + field_96321_w.put(Character.valueOf(var3.func_96298_a()), var3); + field_96331_x.put(var3.func_96297_d(), var3); + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EnumCreatureAttribute.java b/sp-server/src/main/java/net/minecraft/src/EnumCreatureAttribute.java new file mode 100644 index 0000000..0bceccb --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EnumCreatureAttribute.java @@ -0,0 +1,5 @@ +package net.minecraft.src; + +public enum EnumCreatureAttribute { + UNDEFINED, UNDEAD, ARTHROPOD; +} diff --git a/sp-server/src/main/java/net/minecraft/src/EnumCreatureType.java b/sp-server/src/main/java/net/minecraft/src/EnumCreatureType.java new file mode 100644 index 0000000..fb50b7f --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EnumCreatureType.java @@ -0,0 +1,55 @@ +package net.minecraft.src; + +public enum EnumCreatureType { + monster(IMob.class, 70, Material.air, false, false), creature(EntityAnimal.class, 10, Material.air, true, true), + ambient(EntityAmbientCreature.class, 15, Material.air, true, false), + waterCreature(EntityWaterMob.class, 5, Material.water, true, false); + + /** + * The root class of creatures associated with this EnumCreatureType (IMobs for + * aggressive creatures, EntityAnimals for friendly ones) + */ + private final Class creatureClass; + private final int maxNumberOfCreature; + private final Material creatureMaterial; + + /** A flag indicating whether this creature type is peaceful. */ + private final boolean isPeacefulCreature; + + /** Whether this creature type is an animal. */ + private final boolean isAnimal; + + private EnumCreatureType(Class par3Class, int par4, Material par5Material, boolean par6, boolean par7) { + this.creatureClass = par3Class; + this.maxNumberOfCreature = par4; + this.creatureMaterial = par5Material; + this.isPeacefulCreature = par6; + this.isAnimal = par7; + } + + public Class getCreatureClass() { + return this.creatureClass; + } + + public int getMaxNumberOfCreature() { + return this.maxNumberOfCreature; + } + + public Material getCreatureMaterial() { + return this.creatureMaterial; + } + + /** + * Gets whether or not this creature type is peaceful. + */ + public boolean getPeacefulCreature() { + return this.isPeacefulCreature; + } + + /** + * Return whether this creature type is an animal. + */ + public boolean getAnimal() { + return this.isAnimal; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EnumDoor.java b/sp-server/src/main/java/net/minecraft/src/EnumDoor.java new file mode 100644 index 0000000..4b90a8b --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EnumDoor.java @@ -0,0 +1,5 @@ +package net.minecraft.src; + +public enum EnumDoor { + OPENING, WOOD_DOOR, GRATES, IRON_DOOR; +} diff --git a/sp-server/src/main/java/net/minecraft/src/EnumDoorHelper.java b/sp-server/src/main/java/net/minecraft/src/EnumDoorHelper.java new file mode 100644 index 0000000..04e543e --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EnumDoorHelper.java @@ -0,0 +1,31 @@ +package net.minecraft.src; + +class EnumDoorHelper { + static final int[] doorEnum = new int[EnumDoor.values().length]; + + static { + try { + doorEnum[EnumDoor.OPENING.ordinal()] = 1; + } catch (NoSuchFieldError var4) { + ; + } + + try { + doorEnum[EnumDoor.WOOD_DOOR.ordinal()] = 2; + } catch (NoSuchFieldError var3) { + ; + } + + try { + doorEnum[EnumDoor.GRATES.ordinal()] = 3; + } catch (NoSuchFieldError var2) { + ; + } + + try { + doorEnum[EnumDoor.IRON_DOOR.ordinal()] = 4; + } catch (NoSuchFieldError var1) { + ; + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EnumEnchantmentType.java b/sp-server/src/main/java/net/minecraft/src/EnumEnchantmentType.java new file mode 100644 index 0000000..c854746 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EnumEnchantmentType.java @@ -0,0 +1,29 @@ +package net.minecraft.src; + +public enum EnumEnchantmentType { + all, armor, armor_feet, armor_legs, armor_torso, armor_head, weapon, digger, bow; + + /** + * Return true if the item passed can be enchanted by a enchantment of this + * type. + */ + public boolean canEnchantItem(Item par1Item) { + if (this == all) { + return true; + } else if (par1Item instanceof ItemArmor) { + if (this == armor) { + return true; + } else { + ItemArmor var2 = (ItemArmor) par1Item; + return var2.armorType == 0 ? this == armor_head + : (var2.armorType == 2 ? this == armor_legs + : (var2.armorType == 1 ? this == armor_torso + : (var2.armorType == 3 ? this == armor_feet : false))); + } + } else { + return par1Item instanceof ItemSword ? this == weapon + : (par1Item instanceof ItemTool ? this == digger + : (par1Item instanceof ItemBow ? this == bow : false)); + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EnumEntitySize.java b/sp-server/src/main/java/net/minecraft/src/EnumEntitySize.java new file mode 100644 index 0000000..e84cb60 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EnumEntitySize.java @@ -0,0 +1,70 @@ +package net.minecraft.src; + +public enum EnumEntitySize { + SIZE_1, SIZE_2, SIZE_3, SIZE_4, SIZE_5, SIZE_6; + + public int multiplyBy32AndRound(double par1) { + double var3 = par1 - ((double) MathHelper.floor_double(par1) + 0.5D); + + switch (EnumEntitySizeHelper.field_96565_a[this.ordinal()]) { + case 1: + if (var3 < 0.0D) { + if (var3 < -0.3125D) { + return MathHelper.ceiling_double_int(par1 * 32.0D); + } + } else if (var3 < 0.3125D) { + return MathHelper.ceiling_double_int(par1 * 32.0D); + } + + return MathHelper.floor_double(par1 * 32.0D); + + case 2: + if (var3 < 0.0D) { + if (var3 < -0.3125D) { + return MathHelper.floor_double(par1 * 32.0D); + } + } else if (var3 < 0.3125D) { + return MathHelper.floor_double(par1 * 32.0D); + } + + return MathHelper.ceiling_double_int(par1 * 32.0D); + + case 3: + if (var3 > 0.0D) { + return MathHelper.floor_double(par1 * 32.0D); + } + + return MathHelper.ceiling_double_int(par1 * 32.0D); + + case 4: + if (var3 < 0.0D) { + if (var3 < -0.1875D) { + return MathHelper.ceiling_double_int(par1 * 32.0D); + } + } else if (var3 < 0.1875D) { + return MathHelper.ceiling_double_int(par1 * 32.0D); + } + + return MathHelper.floor_double(par1 * 32.0D); + + case 5: + if (var3 < 0.0D) { + if (var3 < -0.1875D) { + return MathHelper.floor_double(par1 * 32.0D); + } + } else if (var3 < 0.1875D) { + return MathHelper.floor_double(par1 * 32.0D); + } + + return MathHelper.ceiling_double_int(par1 * 32.0D); + + case 6: + default: + if (var3 > 0.0D) { + return MathHelper.ceiling_double_int(par1 * 32.0D); + } else { + return MathHelper.floor_double(par1 * 32.0D); + } + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EnumEntitySizeHelper.java b/sp-server/src/main/java/net/minecraft/src/EnumEntitySizeHelper.java new file mode 100644 index 0000000..428c06c --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EnumEntitySizeHelper.java @@ -0,0 +1,43 @@ +package net.minecraft.src; + +class EnumEntitySizeHelper { + static final int[] field_96565_a = new int[EnumEntitySize.values().length]; + + static { + try { + field_96565_a[EnumEntitySize.SIZE_1.ordinal()] = 1; + } catch (NoSuchFieldError var6) { + ; + } + + try { + field_96565_a[EnumEntitySize.SIZE_2.ordinal()] = 2; + } catch (NoSuchFieldError var5) { + ; + } + + try { + field_96565_a[EnumEntitySize.SIZE_3.ordinal()] = 3; + } catch (NoSuchFieldError var4) { + ; + } + + try { + field_96565_a[EnumEntitySize.SIZE_4.ordinal()] = 4; + } catch (NoSuchFieldError var3) { + ; + } + + try { + field_96565_a[EnumEntitySize.SIZE_5.ordinal()] = 5; + } catch (NoSuchFieldError var2) { + ; + } + + try { + field_96565_a[EnumEntitySize.SIZE_6.ordinal()] = 6; + } catch (NoSuchFieldError var1) { + ; + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EnumFacing.java b/sp-server/src/main/java/net/minecraft/src/EnumFacing.java new file mode 100644 index 0000000..fe4065e --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EnumFacing.java @@ -0,0 +1,61 @@ +package net.minecraft.src; + +public enum EnumFacing { + DOWN(0, 1, 0, -1, 0), UP(1, 0, 0, 1, 0), NORTH(2, 3, 0, 0, -1), SOUTH(3, 2, 0, 0, 1), EAST(4, 5, -1, 0, 0), + WEST(5, 4, 1, 0, 0); + + /** Face order for D-U-N-S-E-W. */ + private final int order_a; + + /** Face order for U-D-S-N-W-E. */ + private final int order_b; + private final int frontOffsetX; + private final int frontOffsetY; + private final int frontOffsetZ; + + /** List of all values in EnumFacing. Order is D-U-N-S-E-W. */ + private static final EnumFacing[] faceList = new EnumFacing[6]; + + private EnumFacing(int par3, int par4, int par5, int par6, int par7) { + this.order_a = par3; + this.order_b = par4; + this.frontOffsetX = par5; + this.frontOffsetY = par6; + this.frontOffsetZ = par7; + } + + /** + * Returns a offset that addresses the block in front of this facing. + */ + public int getFrontOffsetX() { + return this.frontOffsetX; + } + + public int getFrontOffsetY() { + return this.frontOffsetY; + } + + /** + * Returns a offset that addresses the block in front of this facing. + */ + public int getFrontOffsetZ() { + return this.frontOffsetZ; + } + + /** + * Returns the facing that represents the block in front of it. + */ + public static EnumFacing getFront(int par0) { + return faceList[par0 % faceList.length]; + } + + static { + EnumFacing[] var0 = values(); + int var1 = var0.length; + + for (int var2 = 0; var2 < var1; ++var2) { + EnumFacing var3 = var0[var2]; + faceList[var3.order_a] = var3; + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EnumGameType.java b/sp-server/src/main/java/net/minecraft/src/EnumGameType.java new file mode 100644 index 0000000..6d00253 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EnumGameType.java @@ -0,0 +1,78 @@ +package net.minecraft.src; + +public enum EnumGameType { + NOT_SET(-1, ""), SURVIVAL(0, "survival"), CREATIVE(1, "creative"), ADVENTURE(2, "adventure"); + + int id; + String name; + + private EnumGameType(int par3, String par4Str) { + this.id = par3; + this.name = par4Str; + } + + /** + * Returns the ID of this game type + */ + public int getID() { + return this.id; + } + + /** + * Returns the name of this game type + */ + public String getName() { + return this.name; + } + + /** + * Configures the player capabilities based on the game type + */ + public void configurePlayerCapabilities(PlayerCapabilities par1PlayerCapabilities) { + if (this == CREATIVE) { + par1PlayerCapabilities.allowFlying = true; + par1PlayerCapabilities.isCreativeMode = true; + par1PlayerCapabilities.disableDamage = true; + } else { + par1PlayerCapabilities.allowFlying = false; + par1PlayerCapabilities.isCreativeMode = false; + par1PlayerCapabilities.disableDamage = false; + par1PlayerCapabilities.isFlying = false; + } + + par1PlayerCapabilities.allowEdit = !this.isAdventure(); + } + + /** + * Returns true if this is the ADVENTURE game type + */ + public boolean isAdventure() { + return this == ADVENTURE; + } + + /** + * Returns true if this is the CREATIVE game type + */ + public boolean isCreative() { + return this == CREATIVE; + } + + /** + * Returns the game type with the specified ID, or SURVIVAL if none found. Args: + * id + */ + public static EnumGameType getByID(int par0) { + EnumGameType[] var1 = values(); + int var2 = var1.length; + + for (int var3 = 0; var3 < var2; ++var3) { + EnumGameType var4 = var1[var3]; + + if (var4.id == par0) { + return var4; + } + } + + return SURVIVAL; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EnumMobType.java b/sp-server/src/main/java/net/minecraft/src/EnumMobType.java new file mode 100644 index 0000000..cc82f4e --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EnumMobType.java @@ -0,0 +1,5 @@ +package net.minecraft.src; + +public enum EnumMobType { + everything, mobs, players; +} diff --git a/sp-server/src/main/java/net/minecraft/src/EnumMovingObjectType.java b/sp-server/src/main/java/net/minecraft/src/EnumMovingObjectType.java new file mode 100644 index 0000000..bdda685 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EnumMovingObjectType.java @@ -0,0 +1,5 @@ +package net.minecraft.src; + +public enum EnumMovingObjectType { + TILE, ENTITY; +} diff --git a/sp-server/src/main/java/net/minecraft/src/EnumSkyBlock.java b/sp-server/src/main/java/net/minecraft/src/EnumSkyBlock.java new file mode 100644 index 0000000..881fc7b --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EnumSkyBlock.java @@ -0,0 +1,11 @@ +package net.minecraft.src; + +public enum EnumSkyBlock { + Sky(15), Block(0); + + public final int defaultLightValue; + + private EnumSkyBlock(int par3) { + this.defaultLightValue = par3; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/EnumStatus.java b/sp-server/src/main/java/net/minecraft/src/EnumStatus.java new file mode 100644 index 0000000..d999efa --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EnumStatus.java @@ -0,0 +1,5 @@ +package net.minecraft.src; + +public enum EnumStatus { + OK, NOT_POSSIBLE_HERE, NOT_POSSIBLE_NOW, TOO_FAR_AWAY, OTHER_PROBLEM, NOT_SAFE; +} diff --git a/sp-server/src/main/java/net/minecraft/src/EnumToolMaterial.java b/sp-server/src/main/java/net/minecraft/src/EnumToolMaterial.java new file mode 100644 index 0000000..9f06754 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/EnumToolMaterial.java @@ -0,0 +1,88 @@ +package net.minecraft.src; + +public enum EnumToolMaterial { + WOOD(0, 59, 2.0F, 0, 15), STONE(1, 131, 4.0F, 1, 5), IRON(2, 250, 6.0F, 2, 14), EMERALD(3, 1561, 8.0F, 3, 10), + GOLD(0, 32, 12.0F, 0, 22); + + /** + * The level of material this tool can harvest (3 = DIAMOND, 2 = IRON, 1 = + * STONE, 0 = IRON/GOLD) + */ + private final int harvestLevel; + + /** + * The number of uses this material allows. (wood = 59, stone = 131, iron = 250, + * diamond = 1561, gold = 32) + */ + private final int maxUses; + + /** + * The strength of this tool material against blocks which it is effective + * against. + */ + private final float efficiencyOnProperMaterial; + + /** Damage versus entities. */ + private final int damageVsEntity; + + /** Defines the natural enchantability factor of the material. */ + private final int enchantability; + + private EnumToolMaterial(int par3, int par4, float par5, int par6, int par7) { + this.harvestLevel = par3; + this.maxUses = par4; + this.efficiencyOnProperMaterial = par5; + this.damageVsEntity = par6; + this.enchantability = par7; + } + + /** + * The number of uses this material allows. (wood = 59, stone = 131, iron = 250, + * diamond = 1561, gold = 32) + */ + public int getMaxUses() { + return this.maxUses; + } + + /** + * The strength of this tool material against blocks which it is effective + * against. + */ + public float getEfficiencyOnProperMaterial() { + return this.efficiencyOnProperMaterial; + } + + /** + * Returns the damage against a given entity. + */ + public int getDamageVsEntity() { + return this.damageVsEntity; + } + + /** + * The level of material this tool can harvest (3 = DIAMOND, 2 = IRON, 1 = + * STONE, 0 = IRON/GOLD) + */ + public int getHarvestLevel() { + return this.harvestLevel; + } + + /** + * Return the natural enchantability factor of the material. + */ + public int getEnchantability() { + return this.enchantability; + } + + /** + * Return the crafting material for this tool material, used to determine the + * item that can be used to repair a tool with an anvil + */ + public int getToolCraftingMaterial() { + return this == WOOD ? Block.planks.blockID + : (this == STONE ? Block.cobblestone.blockID + : (this == GOLD ? Item.ingotGold.itemID + : (this == IRON ? Item.ingotIron.itemID + : (this == EMERALD ? Item.diamond.itemID : 0)))); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/Explosion.java b/sp-server/src/main/java/net/minecraft/src/Explosion.java new file mode 100644 index 0000000..bcd26cb --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/Explosion.java @@ -0,0 +1,239 @@ +package net.minecraft.src; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Random; + +public class Explosion { + /** whether or not the explosion sets fire to blocks around it */ + public boolean isFlaming = false; + + /** whether or not this explosion spawns smoke particles */ + public boolean isSmoking = true; + private int field_77289_h = 16; + private Random explosionRNG = new Random(); + private World worldObj; + public double explosionX; + public double explosionY; + public double explosionZ; + public Entity exploder; + public float explosionSize; + + /** A list of ChunkPositions of blocks affected by this explosion */ + public List affectedBlockPositions = new ArrayList(); + private Map field_77288_k = new HashMap(); + + public Explosion(World par1World, Entity par2Entity, double par3, double par5, double par7, float par9) { + this.worldObj = par1World; + this.exploder = par2Entity; + this.explosionSize = par9; + this.explosionX = par3; + this.explosionY = par5; + this.explosionZ = par7; + } + + /** + * Does the first part of the explosion (destroy blocks) + */ + public void doExplosionA() { + float var1 = this.explosionSize; + HashSet var2 = new HashSet(); + int var3; + int var4; + int var5; + double var15; + double var17; + double var19; + + for (var3 = 0; var3 < this.field_77289_h; ++var3) { + for (var4 = 0; var4 < this.field_77289_h; ++var4) { + for (var5 = 0; var5 < this.field_77289_h; ++var5) { + if (var3 == 0 || var3 == this.field_77289_h - 1 || var4 == 0 || var4 == this.field_77289_h - 1 + || var5 == 0 || var5 == this.field_77289_h - 1) { + double var6 = (double) ((float) var3 / ((float) this.field_77289_h - 1.0F) * 2.0F - 1.0F); + double var8 = (double) ((float) var4 / ((float) this.field_77289_h - 1.0F) * 2.0F - 1.0F); + double var10 = (double) ((float) var5 / ((float) this.field_77289_h - 1.0F) * 2.0F - 1.0F); + double var12 = Math.sqrt(var6 * var6 + var8 * var8 + var10 * var10); + var6 /= var12; + var8 /= var12; + var10 /= var12; + float var14 = this.explosionSize * (0.7F + this.worldObj.rand.nextFloat() * 0.6F); + var15 = this.explosionX; + var17 = this.explosionY; + var19 = this.explosionZ; + + for (float var21 = 0.3F; var14 > 0.0F; var14 -= var21 * 0.75F) { + int var22 = MathHelper.floor_double(var15); + int var23 = MathHelper.floor_double(var17); + int var24 = MathHelper.floor_double(var19); + int var25 = this.worldObj.getBlockId(var22, var23, var24); + + if (var25 > 0) { + Block var26 = Block.blocksList[var25]; + float var27 = this.exploder != null + ? this.exploder.func_82146_a(this, this.worldObj, var22, var23, var24, var26) + : var26.getExplosionResistance(this.exploder); + var14 -= (var27 + 0.3F) * var21; + } + + if (var14 > 0.0F && (this.exploder == null || this.exploder.func_96091_a(this, + this.worldObj, var22, var23, var24, var25, var14))) { + var2.add(new ChunkPosition(var22, var23, var24)); + } + + var15 += var6 * (double) var21; + var17 += var8 * (double) var21; + var19 += var10 * (double) var21; + } + } + } + } + } + + this.affectedBlockPositions.addAll(var2); + this.explosionSize *= 2.0F; + var3 = MathHelper.floor_double(this.explosionX - (double) this.explosionSize - 1.0D); + var4 = MathHelper.floor_double(this.explosionX + (double) this.explosionSize + 1.0D); + var5 = MathHelper.floor_double(this.explosionY - (double) this.explosionSize - 1.0D); + int var29 = MathHelper.floor_double(this.explosionY + (double) this.explosionSize + 1.0D); + int var7 = MathHelper.floor_double(this.explosionZ - (double) this.explosionSize - 1.0D); + int var30 = MathHelper.floor_double(this.explosionZ + (double) this.explosionSize + 1.0D); + List var9 = this.worldObj.getEntitiesWithinAABBExcludingEntity(this.exploder, AxisAlignedBB.getAABBPool() + .getAABB((double) var3, (double) var5, (double) var7, (double) var4, (double) var29, (double) var30)); + Vec3 var31 = this.worldObj.getWorldVec3Pool().getVecFromPool(this.explosionX, this.explosionY, this.explosionZ); + + for (int var11 = 0; var11 < var9.size(); ++var11) { + Entity var32 = (Entity) var9.get(var11); + double var13 = var32.getDistance(this.explosionX, this.explosionY, this.explosionZ) + / (double) this.explosionSize; + + if (var13 <= 1.0D) { + var15 = var32.posX - this.explosionX; + var17 = var32.posY + (double) var32.getEyeHeight() - this.explosionY; + var19 = var32.posZ - this.explosionZ; + double var33 = (double) MathHelper.sqrt_double(var15 * var15 + var17 * var17 + var19 * var19); + + if (var33 != 0.0D) { + var15 /= var33; + var17 /= var33; + var19 /= var33; + double var34 = (double) this.worldObj.getBlockDensity(var31, var32.boundingBox); + double var35 = (1.0D - var13) * var34; + var32.attackEntityFrom(DamageSource.setExplosionSource(this), + (int) ((var35 * var35 + var35) / 2.0D * 8.0D * (double) this.explosionSize + 1.0D)); + double var36 = EnchantmentProtection.func_92092_a(var32, var35); + var32.motionX += var15 * var36; + var32.motionY += var17 * var36; + var32.motionZ += var19 * var36; + + if (var32 instanceof EntityPlayer) { + this.field_77288_k.put((EntityPlayer) var32, this.worldObj.getWorldVec3Pool() + .getVecFromPool(var15 * var35, var17 * var35, var19 * var35)); + } + } + } + } + + this.explosionSize = var1; + } + + /** + * Does the second part of the explosion (sound, particles, drop spawn) + */ + public void doExplosionB(boolean par1) { + this.worldObj.playSoundEffect(this.explosionX, this.explosionY, this.explosionZ, "random.explode", 4.0F, + (1.0F + (this.worldObj.rand.nextFloat() - this.worldObj.rand.nextFloat()) * 0.2F) * 0.7F); + + if (this.explosionSize >= 2.0F && this.isSmoking) { + this.worldObj.spawnParticle("hugeexplosion", this.explosionX, this.explosionY, this.explosionZ, 1.0D, 0.0D, + 0.0D); + } else { + this.worldObj.spawnParticle("largeexplode", this.explosionX, this.explosionY, this.explosionZ, 1.0D, 0.0D, + 0.0D); + } + + Iterator var2; + ChunkPosition var3; + int var4; + int var5; + int var6; + int var7; + + if (this.isSmoking) { + var2 = this.affectedBlockPositions.iterator(); + + while (var2.hasNext()) { + var3 = (ChunkPosition) var2.next(); + var4 = var3.x; + var5 = var3.y; + var6 = var3.z; + var7 = this.worldObj.getBlockId(var4, var5, var6); + + if (par1) { + double var8 = (double) ((float) var4 + this.worldObj.rand.nextFloat()); + double var10 = (double) ((float) var5 + this.worldObj.rand.nextFloat()); + double var12 = (double) ((float) var6 + this.worldObj.rand.nextFloat()); + double var14 = var8 - this.explosionX; + double var16 = var10 - this.explosionY; + double var18 = var12 - this.explosionZ; + double var20 = (double) MathHelper.sqrt_double(var14 * var14 + var16 * var16 + var18 * var18); + var14 /= var20; + var16 /= var20; + var18 /= var20; + double var22 = 0.5D / (var20 / (double) this.explosionSize + 0.1D); + var22 *= (double) (this.worldObj.rand.nextFloat() * this.worldObj.rand.nextFloat() + 0.3F); + var14 *= var22; + var16 *= var22; + var18 *= var22; + this.worldObj.spawnParticle("explode", (var8 + this.explosionX * 1.0D) / 2.0D, + (var10 + this.explosionY * 1.0D) / 2.0D, (var12 + this.explosionZ * 1.0D) / 2.0D, var14, + var16, var18); + this.worldObj.spawnParticle("smoke", var8, var10, var12, var14, var16, var18); + } + + if (var7 > 0) { + Block var24 = Block.blocksList[var7]; + + if (var24.canDropFromExplosion(this)) { + var24.dropBlockAsItemWithChance(this.worldObj, var4, var5, var6, + this.worldObj.getBlockMetadata(var4, var5, var6), 1.0F / this.explosionSize, 0); + } + + this.worldObj.setBlock(var4, var5, var6, 0, 0, 3); + var24.onBlockDestroyedByExplosion(this.worldObj, var4, var5, var6, this); + } + } + } + + if (this.isFlaming) { + var2 = this.affectedBlockPositions.iterator(); + + while (var2.hasNext()) { + var3 = (ChunkPosition) var2.next(); + var4 = var3.x; + var5 = var3.y; + var6 = var3.z; + var7 = this.worldObj.getBlockId(var4, var5, var6); + int var25 = this.worldObj.getBlockId(var4, var5 - 1, var6); + + if (var7 == 0 && Block.opaqueCubeLookup[var25] && this.explosionRNG.nextInt(3) == 0) { + this.worldObj.setBlock(var4, var5, var6, Block.fire.blockID); + } + } + } + } + + public Map func_77277_b() { + return this.field_77288_k; + } + + public EntityLiving func_94613_c() { + return this.exploder == null ? null + : (this.exploder instanceof EntityTNTPrimed ? ((EntityTNTPrimed) this.exploder).getTntPlacedBy() + : (this.exploder instanceof EntityLiving ? (EntityLiving) this.exploder : null)); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ExtendedBlockStorage.java b/sp-server/src/main/java/net/minecraft/src/ExtendedBlockStorage.java new file mode 100644 index 0000000..ba9e3ac --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ExtendedBlockStorage.java @@ -0,0 +1,276 @@ +package net.minecraft.src; + +public class ExtendedBlockStorage { + /** + * Contains the bottom-most Y block represented by this ExtendedBlockStorage. + * Typically a multiple of 16. + */ + private int yBase; + + /** + * A total count of the number of non-air blocks in this block storage's Chunk. + */ + private int blockRefCount; + + /** + * Contains the number of blocks in this block storage's parent chunk that + * require random ticking. Used to cull the Chunk from random tick updates for + * performance reasons. + */ + private int tickRefCount; + + /** + * Contains the least significant 8 bits of each block ID belonging to this + * block storage's parent Chunk. + */ + private byte[] blockLSBArray; + + /** + * Contains the most significant 4 bits of each block ID belonging to this block + * storage's parent Chunk. + */ + private NibbleArray blockMSBArray; + + /** + * Stores the metadata associated with blocks in this ExtendedBlockStorage. + */ + private NibbleArray blockMetadataArray; + + /** The NibbleArray containing a block of Block-light data. */ + private NibbleArray blocklightArray; + + /** The NibbleArray containing a block of Sky-light data. */ + private NibbleArray skylightArray; + + public ExtendedBlockStorage(int par1, boolean par2) { + this.yBase = par1; + this.blockLSBArray = new byte[4096]; + this.blockMetadataArray = new NibbleArray(this.blockLSBArray.length, 4); + this.blocklightArray = new NibbleArray(this.blockLSBArray.length, 4); + + if (par2) { + this.skylightArray = new NibbleArray(this.blockLSBArray.length, 4); + } + } + + /** + * Returns the extended block ID for a location in a chunk, merged from a byte + * array and a NibbleArray to form a full 12-bit block ID. + */ + public int getExtBlockID(int par1, int par2, int par3) { + int var4 = this.blockLSBArray[par2 << 8 | par3 << 4 | par1] & 255; + return this.blockMSBArray != null ? this.blockMSBArray.get(par1, par2, par3) << 8 | var4 : var4; + } + + /** + * Sets the extended block ID for a location in a chunk, splitting bits 11..8 + * into a NibbleArray and bits 7..0 into a byte array. Also performs reference + * counting to determine whether or not to broadly cull this Chunk from the + * random-update tick list. + */ + public void setExtBlockID(int par1, int par2, int par3, int par4) { + int var5 = this.blockLSBArray[par2 << 8 | par3 << 4 | par1] & 255; + + if (this.blockMSBArray != null) { + var5 |= this.blockMSBArray.get(par1, par2, par3) << 8; + } + + if (var5 == 0 && par4 != 0) { + ++this.blockRefCount; + + if (Block.blocksList[par4] != null && Block.blocksList[par4].getTickRandomly()) { + ++this.tickRefCount; + } + } else if (var5 != 0 && par4 == 0) { + --this.blockRefCount; + + if (Block.blocksList[var5] != null && Block.blocksList[var5].getTickRandomly()) { + --this.tickRefCount; + } + } else if (Block.blocksList[var5] != null && Block.blocksList[var5].getTickRandomly() + && (Block.blocksList[par4] == null || !Block.blocksList[par4].getTickRandomly())) { + --this.tickRefCount; + } else if ((Block.blocksList[var5] == null || !Block.blocksList[var5].getTickRandomly()) + && Block.blocksList[par4] != null && Block.blocksList[par4].getTickRandomly()) { + ++this.tickRefCount; + } + + this.blockLSBArray[par2 << 8 | par3 << 4 | par1] = (byte) (par4 & 255); + + if (par4 > 255) { + if (this.blockMSBArray == null) { + this.blockMSBArray = new NibbleArray(this.blockLSBArray.length, 4); + } + + this.blockMSBArray.set(par1, par2, par3, (par4 & 3840) >> 8); + } else if (this.blockMSBArray != null) { + this.blockMSBArray.set(par1, par2, par3, 0); + } + } + + /** + * Returns the metadata associated with the block at the given coordinates in + * this ExtendedBlockStorage. + */ + public int getExtBlockMetadata(int par1, int par2, int par3) { + return this.blockMetadataArray.get(par1, par2, par3); + } + + /** + * Sets the metadata of the Block at the given coordinates in this + * ExtendedBlockStorage to the given metadata. + */ + public void setExtBlockMetadata(int par1, int par2, int par3, int par4) { + this.blockMetadataArray.set(par1, par2, par3, par4); + } + + /** + * Returns whether or not this block storage's Chunk is fully empty, based on + * its internal reference count. + */ + public boolean isEmpty() { + return this.blockRefCount == 0; + } + + /** + * Returns whether or not this block storage's Chunk will require random + * ticking, used to avoid looping through random block ticks when there are no + * blocks that would randomly tick. + */ + public boolean getNeedsRandomTick() { + return this.tickRefCount > 0; + } + + /** + * Returns the Y location of this ExtendedBlockStorage. + */ + public int getYLocation() { + return this.yBase; + } + + /** + * Sets the saved Sky-light value in the extended block storage structure. + */ + public void setExtSkylightValue(int par1, int par2, int par3, int par4) { + this.skylightArray.set(par1, par2, par3, par4); + } + + /** + * Gets the saved Sky-light value in the extended block storage structure. + */ + public int getExtSkylightValue(int par1, int par2, int par3) { + return this.skylightArray.get(par1, par2, par3); + } + + /** + * Sets the saved Block-light value in the extended block storage structure. + */ + public void setExtBlocklightValue(int par1, int par2, int par3, int par4) { + this.blocklightArray.set(par1, par2, par3, par4); + } + + /** + * Gets the saved Block-light value in the extended block storage structure. + */ + public int getExtBlocklightValue(int par1, int par2, int par3) { + return this.blocklightArray.get(par1, par2, par3); + } + + public void removeInvalidBlocks() { + this.blockRefCount = 0; + this.tickRefCount = 0; + + for (int var1 = 0; var1 < 16; ++var1) { + for (int var2 = 0; var2 < 16; ++var2) { + for (int var3 = 0; var3 < 16; ++var3) { + int var4 = this.getExtBlockID(var1, var2, var3); + + if (var4 > 0) { + if (Block.blocksList[var4] == null) { + this.blockLSBArray[var2 << 8 | var3 << 4 | var1] = 0; + + if (this.blockMSBArray != null) { + this.blockMSBArray.set(var1, var2, var3, 0); + } + } else { + ++this.blockRefCount; + + if (Block.blocksList[var4].getTickRandomly()) { + ++this.tickRefCount; + } + } + } + } + } + } + } + + public byte[] getBlockLSBArray() { + return this.blockLSBArray; + } + + /** + * Returns the block ID MSB (bits 11..8) array for this storage array's Chunk. + */ + public NibbleArray getBlockMSBArray() { + return this.blockMSBArray; + } + + public NibbleArray getMetadataArray() { + return this.blockMetadataArray; + } + + /** + * Returns the NibbleArray instance containing Block-light data. + */ + public NibbleArray getBlocklightArray() { + return this.blocklightArray; + } + + /** + * Returns the NibbleArray instance containing Sky-light data. + */ + public NibbleArray getSkylightArray() { + return this.skylightArray; + } + + /** + * Sets the array of block ID least significant bits for this + * ExtendedBlockStorage. + */ + public void setBlockLSBArray(byte[] par1ArrayOfByte) { + this.blockLSBArray = par1ArrayOfByte; + } + + /** + * Sets the array of blockID most significant bits (blockMSBArray) for this + * ExtendedBlockStorage. + */ + public void setBlockMSBArray(NibbleArray par1NibbleArray) { + this.blockMSBArray = par1NibbleArray; + } + + /** + * Sets the NibbleArray of block metadata (blockMetadataArray) for this + * ExtendedBlockStorage. + */ + public void setBlockMetadataArray(NibbleArray par1NibbleArray) { + this.blockMetadataArray = par1NibbleArray; + } + + /** + * Sets the NibbleArray instance used for Block-light values in this particular + * storage block. + */ + public void setBlocklightArray(NibbleArray par1NibbleArray) { + this.blocklightArray = par1NibbleArray; + } + + /** + * Sets the NibbleArray instance used for Sky-light values in this particular + * storage block. + */ + public void setSkylightArray(NibbleArray par1NibbleArray) { + this.skylightArray = par1NibbleArray; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/Facing.java b/sp-server/src/main/java/net/minecraft/src/Facing.java new file mode 100644 index 0000000..7db4e10 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/Facing.java @@ -0,0 +1,24 @@ +package net.minecraft.src; + +public class Facing { + /** + * Converts a side to the opposite side. This is the same as XOR'ing it with 1. + */ + public static final int[] oppositeSide = new int[] { 1, 0, 3, 2, 5, 4 }; + + /** + * gives the offset required for this axis to get the block at that side. + */ + public static final int[] offsetsXForSide = new int[] { 0, 0, 0, 0, -1, 1 }; + + /** + * gives the offset required for this axis to get the block at that side. + */ + public static final int[] offsetsYForSide = new int[] { -1, 1, 0, 0, 0, 0 }; + + /** + * gives the offset required for this axis to get the block at that side. + */ + public static final int[] offsetsZForSide = new int[] { 0, 0, -1, 1, 0, 0 }; + public static final String[] facings = new String[] { "DOWN", "UP", "NORTH", "SOUTH", "WEST", "EAST" }; +} diff --git a/sp-server/src/main/java/net/minecraft/src/FilterIMob.java b/sp-server/src/main/java/net/minecraft/src/FilterIMob.java new file mode 100644 index 0000000..2ed6500 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/FilterIMob.java @@ -0,0 +1,10 @@ +package net.minecraft.src; + +final class FilterIMob implements IEntitySelector { + /** + * Return whether the specified entity is applicable to this filter. + */ + public boolean isEntityApplicable(Entity par1Entity) { + return par1Entity instanceof IMob; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/FlatGeneratorInfo.java b/sp-server/src/main/java/net/minecraft/src/FlatGeneratorInfo.java new file mode 100644 index 0000000..5671eed --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/FlatGeneratorInfo.java @@ -0,0 +1,263 @@ +package net.minecraft.src; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +public class FlatGeneratorInfo { + /** List of layers on this preset. */ + private final List flatLayers = new ArrayList(); + + /** List of world features enabled on this preset. */ + private final Map worldFeatures = new HashMap(); + private int biomeToUse = 0; + + /** + * Return the biome used on this preset. + */ + public int getBiome() { + return this.biomeToUse; + } + + /** + * Set the biome used on this preset. + */ + public void setBiome(int par1) { + this.biomeToUse = par1; + } + + /** + * Return the list of world features enabled on this preset. + */ + public Map getWorldFeatures() { + return this.worldFeatures; + } + + /** + * Return the list of layers on this preset. + */ + public List getFlatLayers() { + return this.flatLayers; + } + + public void func_82645_d() { + int var1 = 0; + FlatLayerInfo var3; + + for (Iterator var2 = this.flatLayers.iterator(); var2.hasNext(); var1 += var3.getLayerCount()) { + var3 = (FlatLayerInfo) var2.next(); + var3.setMinY(var1); + } + } + + public String toString() { + StringBuilder var1 = new StringBuilder(); + var1.append(2); + var1.append(";"); + int var2; + + for (var2 = 0; var2 < this.flatLayers.size(); ++var2) { + if (var2 > 0) { + var1.append(","); + } + + var1.append(((FlatLayerInfo) this.flatLayers.get(var2)).toString()); + } + + var1.append(";"); + var1.append(this.biomeToUse); + + if (!this.worldFeatures.isEmpty()) { + var1.append(";"); + var2 = 0; + Iterator var3 = this.worldFeatures.entrySet().iterator(); + + while (var3.hasNext()) { + Entry var4 = (Entry) var3.next(); + + if (var2++ > 0) { + var1.append(","); + } + + var1.append(((String) var4.getKey()).toLowerCase()); + Map var5 = (Map) var4.getValue(); + + if (!var5.isEmpty()) { + var1.append("("); + int var6 = 0; + Iterator var7 = var5.entrySet().iterator(); + + while (var7.hasNext()) { + Entry var8 = (Entry) var7.next(); + + if (var6++ > 0) { + var1.append(" "); + } + + var1.append((String) var8.getKey()); + var1.append("="); + var1.append((String) var8.getValue()); + } + + var1.append(")"); + } + } + } else { + var1.append(";"); + } + + return var1.toString(); + } + + private static FlatLayerInfo func_82646_a(String par0Str, int par1) { + String[] var2 = par0Str.split("x", 2); + int var3 = 1; + int var5 = 0; + + if (var2.length == 2) { + try { + var3 = Integer.parseInt(var2[0]); + + if (par1 + var3 >= 256) { + var3 = 256 - par1; + } + + if (var3 < 0) { + var3 = 0; + } + } catch (Throwable var7) { + return null; + } + } + + int var4; + + try { + String var6 = var2[var2.length - 1]; + var2 = var6.split(":", 2); + var4 = Integer.parseInt(var2[0]); + + if (var2.length > 1) { + var5 = Integer.parseInt(var2[1]); + } + + if (Block.blocksList[var4] == null) { + var4 = 0; + var5 = 0; + } + + if (var5 < 0 || var5 > 15) { + var5 = 0; + } + } catch (Throwable var8) { + return null; + } + + FlatLayerInfo var9 = new FlatLayerInfo(var3, var4, var5); + var9.setMinY(par1); + return var9; + } + + private static List func_82652_b(String par0Str) { + if (par0Str != null && par0Str.length() >= 1) { + ArrayList var1 = new ArrayList(); + String[] var2 = par0Str.split(","); + int var3 = 0; + String[] var4 = var2; + int var5 = var2.length; + + for (int var6 = 0; var6 < var5; ++var6) { + String var7 = var4[var6]; + FlatLayerInfo var8 = func_82646_a(var7, var3); + + if (var8 == null) { + return null; + } + + var1.add(var8); + var3 += var8.getLayerCount(); + } + + return var1; + } else { + return null; + } + } + + public static FlatGeneratorInfo createFlatGeneratorFromString(String par0Str) { + if (par0Str == null) { + return getDefaultFlatGenerator(); + } else { + String[] var1 = par0Str.split(";", -1); + int var2 = var1.length == 1 ? 0 : MathHelper.parseIntWithDefault(var1[0], 0); + + if (var2 >= 0 && var2 <= 2) { + FlatGeneratorInfo var3 = new FlatGeneratorInfo(); + int var4 = var1.length == 1 ? 0 : 1; + List var5 = func_82652_b(var1[var4++]); + + if (var5 != null && !var5.isEmpty()) { + var3.getFlatLayers().addAll(var5); + var3.func_82645_d(); + int var6 = BiomeGenBase.plains.biomeID; + + if (var2 > 0 && var1.length > var4) { + var6 = MathHelper.parseIntWithDefault(var1[var4++], var6); + } + + var3.setBiome(var6); + + if (var2 > 0 && var1.length > var4) { + String[] var7 = var1[var4++].toLowerCase().split(","); + String[] var8 = var7; + int var9 = var7.length; + + for (int var10 = 0; var10 < var9; ++var10) { + String var11 = var8[var10]; + String[] var12 = var11.split("\\(", 2); + HashMap var13 = new HashMap(); + + if (var12[0].length() > 0) { + var3.getWorldFeatures().put(var12[0], var13); + + if (var12.length > 1 && var12[1].endsWith(")") && var12[1].length() > 1) { + String[] var14 = var12[1].substring(0, var12[1].length() - 1).split(" "); + + for (int var15 = 0; var15 < var14.length; ++var15) { + String[] var16 = var14[var15].split("=", 2); + + if (var16.length == 2) { + var13.put(var16[0], var16[1]); + } + } + } + } + } + } else { + var3.getWorldFeatures().put("village", new HashMap()); + } + + return var3; + } else { + return getDefaultFlatGenerator(); + } + } else { + return getDefaultFlatGenerator(); + } + } + } + + public static FlatGeneratorInfo getDefaultFlatGenerator() { + FlatGeneratorInfo var0 = new FlatGeneratorInfo(); + var0.setBiome(BiomeGenBase.plains.biomeID); + var0.getFlatLayers().add(new FlatLayerInfo(1, Block.bedrock.blockID)); + var0.getFlatLayers().add(new FlatLayerInfo(2, Block.dirt.blockID)); + var0.getFlatLayers().add(new FlatLayerInfo(1, Block.grass.blockID)); + var0.func_82645_d(); + var0.getWorldFeatures().put("village", new HashMap()); + return var0; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/FlatLayerInfo.java b/sp-server/src/main/java/net/minecraft/src/FlatLayerInfo.java new file mode 100644 index 0000000..545e183 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/FlatLayerInfo.java @@ -0,0 +1,76 @@ +package net.minecraft.src; + +public class FlatLayerInfo { + /** Amount of layers for this set of layers. */ + private int layerCount; + + /** Block type used on this set of layers. */ + private int layerFillBlock; + + /** Block metadata used on this set of laeyrs. */ + private int layerFillBlockMeta; + private int layerMinimumY; + + public FlatLayerInfo(int par1, int par2) { + this.layerCount = 1; + this.layerFillBlock = 0; + this.layerFillBlockMeta = 0; + this.layerMinimumY = 0; + this.layerCount = par1; + this.layerFillBlock = par2; + } + + public FlatLayerInfo(int par1, int par2, int par3) { + this(par1, par2); + this.layerFillBlockMeta = par3; + } + + /** + * Return the amount of layers for this set of layers. + */ + public int getLayerCount() { + return this.layerCount; + } + + /** + * Return the block type used on this set of layers. + */ + public int getFillBlock() { + return this.layerFillBlock; + } + + /** + * Return the block metadata used on this set of layers. + */ + public int getFillBlockMeta() { + return this.layerFillBlockMeta; + } + + /** + * Return the minimum Y coordinate for this layer, set during generation. + */ + public int getMinY() { + return this.layerMinimumY; + } + + /** + * Set the minimum Y coordinate for this layer. + */ + public void setMinY(int par1) { + this.layerMinimumY = par1; + } + + public String toString() { + String var1 = Integer.toString(this.layerFillBlock); + + if (this.layerCount > 1) { + var1 = this.layerCount + "x" + var1; + } + + if (this.layerFillBlockMeta > 0) { + var1 = var1 + ":" + this.layerFillBlockMeta; + } + + return var1; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/FoodStats.java b/sp-server/src/main/java/net/minecraft/src/FoodStats.java new file mode 100644 index 0000000..c70979f --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/FoodStats.java @@ -0,0 +1,121 @@ +package net.minecraft.src; + +public class FoodStats { + /** The player's food level. */ + private int foodLevel = 20; + + /** The player's food saturation. */ + private float foodSaturationLevel = 5.0F; + + /** The player's food exhaustion. */ + private float foodExhaustionLevel; + + /** The player's food timer value. */ + private int foodTimer = 0; + private int prevFoodLevel = 20; + + /** + * Args: int foodLevel, float foodSaturationModifier + */ + public void addStats(int par1, float par2) { + this.foodLevel = Math.min(par1 + this.foodLevel, 20); + this.foodSaturationLevel = Math.min(this.foodSaturationLevel + (float) par1 * par2 * 2.0F, + (float) this.foodLevel); + } + + /** + * Eat some food. + */ + public void addStats(ItemFood par1ItemFood) { + this.addStats(par1ItemFood.getHealAmount(), par1ItemFood.getSaturationModifier()); + } + + /** + * Handles the food game logic. + */ + public void onUpdate(EntityPlayer par1EntityPlayer) { + int var2 = par1EntityPlayer.worldObj.difficultySetting; + this.prevFoodLevel = this.foodLevel; + + if (this.foodExhaustionLevel > 4.0F) { + this.foodExhaustionLevel -= 4.0F; + + if (this.foodSaturationLevel > 0.0F) { + this.foodSaturationLevel = Math.max(this.foodSaturationLevel - 1.0F, 0.0F); + } else if (var2 > 0) { + this.foodLevel = Math.max(this.foodLevel - 1, 0); + } + } + + if (this.foodLevel >= 18 && par1EntityPlayer.shouldHeal()) { + ++this.foodTimer; + + if (this.foodTimer >= 80) { + par1EntityPlayer.heal(1); + this.foodTimer = 0; + } + } else if (this.foodLevel <= 0) { + ++this.foodTimer; + + if (this.foodTimer >= 80) { + if (par1EntityPlayer.getHealth() > 10 || var2 >= 3 || par1EntityPlayer.getHealth() > 1 && var2 >= 2) { + par1EntityPlayer.attackEntityFrom(DamageSource.starve, 1); + } + + this.foodTimer = 0; + } + } else { + this.foodTimer = 0; + } + } + + /** + * Reads the food data for the player. + */ + public void readNBT(NBTTagCompound par1NBTTagCompound) { + if (par1NBTTagCompound.hasKey("foodLevel")) { + this.foodLevel = par1NBTTagCompound.getInteger("foodLevel"); + this.foodTimer = par1NBTTagCompound.getInteger("foodTickTimer"); + this.foodSaturationLevel = par1NBTTagCompound.getFloat("foodSaturationLevel"); + this.foodExhaustionLevel = par1NBTTagCompound.getFloat("foodExhaustionLevel"); + } + } + + /** + * Writes the food data for the player. + */ + public void writeNBT(NBTTagCompound par1NBTTagCompound) { + par1NBTTagCompound.setInteger("foodLevel", this.foodLevel); + par1NBTTagCompound.setInteger("foodTickTimer", this.foodTimer); + par1NBTTagCompound.setFloat("foodSaturationLevel", this.foodSaturationLevel); + par1NBTTagCompound.setFloat("foodExhaustionLevel", this.foodExhaustionLevel); + } + + /** + * Get the player's food level. + */ + public int getFoodLevel() { + return this.foodLevel; + } + + /** + * Get whether the player must eat food. + */ + public boolean needFood() { + return this.foodLevel < 20; + } + + /** + * adds input to foodExhaustionLevel to a max of 40 + */ + public void addExhaustion(float par1) { + this.foodExhaustionLevel = Math.min(this.foodExhaustionLevel + par1, 40.0F); + } + + /** + * Get the player's food saturation level. + */ + public float getSaturationLevel() { + return this.foodSaturationLevel; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/FurnaceRecipes.java b/sp-server/src/main/java/net/minecraft/src/FurnaceRecipes.java new file mode 100644 index 0000000..2cdfa4e --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/FurnaceRecipes.java @@ -0,0 +1,66 @@ +package net.minecraft.src; + +import java.util.HashMap; +import java.util.Map; + +public class FurnaceRecipes { + private static final FurnaceRecipes smeltingBase = new FurnaceRecipes(); + + /** The list of smelting results. */ + private Map smeltingList = new HashMap(); + private Map experienceList = new HashMap(); + + /** + * Used to call methods addSmelting and getSmeltingResult. + */ + public static final FurnaceRecipes smelting() { + return smeltingBase; + } + + private FurnaceRecipes() { + this.addSmelting(Block.oreIron.blockID, new ItemStack(Item.ingotIron), 0.7F); + this.addSmelting(Block.oreGold.blockID, new ItemStack(Item.ingotGold), 1.0F); + this.addSmelting(Block.oreDiamond.blockID, new ItemStack(Item.diamond), 1.0F); + this.addSmelting(Block.sand.blockID, new ItemStack(Block.glass), 0.1F); + this.addSmelting(Item.porkRaw.itemID, new ItemStack(Item.porkCooked), 0.35F); + this.addSmelting(Item.beefRaw.itemID, new ItemStack(Item.beefCooked), 0.35F); + this.addSmelting(Item.chickenRaw.itemID, new ItemStack(Item.chickenCooked), 0.35F); + this.addSmelting(Item.fishRaw.itemID, new ItemStack(Item.fishCooked), 0.35F); + this.addSmelting(Block.cobblestone.blockID, new ItemStack(Block.stone), 0.1F); + this.addSmelting(Item.clay.itemID, new ItemStack(Item.brick), 0.3F); + this.addSmelting(Block.cactus.blockID, new ItemStack(Item.dyePowder, 1, 2), 0.2F); + this.addSmelting(Block.wood.blockID, new ItemStack(Item.coal, 1, 1), 0.15F); + this.addSmelting(Block.oreEmerald.blockID, new ItemStack(Item.emerald), 1.0F); + this.addSmelting(Item.potato.itemID, new ItemStack(Item.bakedPotato), 0.35F); + this.addSmelting(Block.netherrack.blockID, new ItemStack(Item.netherrackBrick), 0.1F); + this.addSmelting(Block.oreCoal.blockID, new ItemStack(Item.coal), 0.1F); + this.addSmelting(Block.oreRedstone.blockID, new ItemStack(Item.redstone), 0.7F); + this.addSmelting(Block.oreLapis.blockID, new ItemStack(Item.dyePowder, 1, 4), 0.2F); + this.addSmelting(Block.oreNetherQuartz.blockID, new ItemStack(Item.netherQuartz), 0.2F); + } + + /** + * Adds a smelting recipe. + */ + public void addSmelting(int par1, ItemStack par2ItemStack, float par3) { + this.smeltingList.put(Integer.valueOf(par1), par2ItemStack); + this.experienceList.put(Integer.valueOf(par2ItemStack.itemID), Float.valueOf(par3)); + } + + /** + * Returns the smelting result of an item. + */ + public ItemStack getSmeltingResult(int par1) { + return (ItemStack) this.smeltingList.get(Integer.valueOf(par1)); + } + + public Map getSmeltingList() { + return this.smeltingList; + } + + public float getExperience(int par1) { + return this.experienceList.containsKey(Integer.valueOf(par1)) + ? ((Float) this.experienceList.get(Integer.valueOf(par1))).floatValue() + : 0.0F; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/GameRuleValue.java b/sp-server/src/main/java/net/minecraft/src/GameRuleValue.java new file mode 100644 index 0000000..2b8f4e5 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/GameRuleValue.java @@ -0,0 +1,46 @@ +package net.minecraft.src; + +class GameRuleValue { + private String valueString; + private boolean valueBoolean; + private int valueInteger; + private double valueDouble; + + public GameRuleValue(String par1Str) { + this.setValue(par1Str); + } + + /** + * Set this game rule value. + */ + public void setValue(String par1Str) { + this.valueString = par1Str; + this.valueBoolean = Boolean.parseBoolean(par1Str); + + try { + this.valueInteger = Integer.parseInt(par1Str); + } catch (NumberFormatException var4) { + ; + } + + try { + this.valueDouble = Double.parseDouble(par1Str); + } catch (NumberFormatException var3) { + ; + } + } + + /** + * Gets the GameRule's value as String. + */ + public String getGameRuleStringValue() { + return this.valueString; + } + + /** + * Gets the GameRule's value as boolean. + */ + public boolean getGameRuleBooleanValue() { + return this.valueBoolean; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/GameRules.java b/sp-server/src/main/java/net/minecraft/src/GameRules.java new file mode 100644 index 0000000..40b09d8 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/GameRules.java @@ -0,0 +1,97 @@ +package net.minecraft.src; + +import java.util.Collection; +import java.util.Iterator; +import java.util.TreeMap; + +public class GameRules { + private TreeMap theGameRules = new TreeMap(); + + public GameRules() { + this.addGameRule("doFireTick", "true"); + this.addGameRule("mobGriefing", "true"); + this.addGameRule("keepInventory", "false"); + this.addGameRule("doMobSpawning", "true"); + this.addGameRule("doMobLoot", "true"); + this.addGameRule("doTileDrops", "true"); + this.addGameRule("commandBlockOutput", "true"); + } + + /** + * Define a game rule and its default value. + */ + public void addGameRule(String par1Str, String par2Str) { + this.theGameRules.put(par1Str, new GameRuleValue(par2Str)); + } + + public void setOrCreateGameRule(String par1Str, String par2Str) { + GameRuleValue var3 = (GameRuleValue) this.theGameRules.get(par1Str); + + if (var3 != null) { + var3.setValue(par2Str); + } else { + this.addGameRule(par1Str, par2Str); + } + } + + /** + * Gets the string Game Rule value. + */ + public String getGameRuleStringValue(String par1Str) { + GameRuleValue var2 = (GameRuleValue) this.theGameRules.get(par1Str); + return var2 != null ? var2.getGameRuleStringValue() : ""; + } + + /** + * Gets the boolean Game Rule value. + */ + public boolean getGameRuleBooleanValue(String par1Str) { + GameRuleValue var2 = (GameRuleValue) this.theGameRules.get(par1Str); + return var2 != null ? var2.getGameRuleBooleanValue() : false; + } + + /** + * Return the defined game rules as NBT. + */ + public NBTTagCompound writeGameRulesToNBT() { + NBTTagCompound var1 = new NBTTagCompound("GameRules"); + Iterator var2 = this.theGameRules.keySet().iterator(); + + while (var2.hasNext()) { + String var3 = (String) var2.next(); + GameRuleValue var4 = (GameRuleValue) this.theGameRules.get(var3); + var1.setString(var3, var4.getGameRuleStringValue()); + } + + return var1; + } + + /** + * Set defined game rules from NBT. + */ + public void readGameRulesFromNBT(NBTTagCompound par1NBTTagCompound) { + Collection var2 = par1NBTTagCompound.getTags(); + Iterator var3 = var2.iterator(); + + while (var3.hasNext()) { + NBTBase var4 = (NBTBase) var3.next(); + String var5 = var4.getName(); + String var6 = par1NBTTagCompound.getString(var4.getName()); + this.setOrCreateGameRule(var5, var6); + } + } + + /** + * Return the defined game rules. + */ + public String[] getRules() { + return (String[]) this.theGameRules.keySet().toArray(new String[0]); + } + + /** + * Return whether the specified game rule is defined. + */ + public boolean hasRule(String par1Str) { + return this.theGameRules.containsKey(par1Str); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/GenLayer.java b/sp-server/src/main/java/net/minecraft/src/GenLayer.java new file mode 100644 index 0000000..0162de9 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/GenLayer.java @@ -0,0 +1,141 @@ +package net.minecraft.src; + +public abstract class GenLayer { + /** seed from World#getWorldSeed that is used in the LCG prng */ + private long worldGenSeed; + + /** parent GenLayer that was provided via the constructor */ + protected GenLayer parent; + + /** + * final part of the LCG prng that uses the chunk X, Z coords along with the + * other two seeds to generate pseudorandom numbers + */ + private long chunkSeed; + + /** base seed to the LCG prng provided via the constructor */ + private long baseSeed; + + /** + * the first array item is a linked list of the bioms, the second is the zoom + * function, the third is the same as the first. + */ + public static GenLayer[] initializeAllBiomeGenerators(long par0, WorldType par2WorldType) { + GenLayerIsland var3 = new GenLayerIsland(1L); + GenLayerFuzzyZoom var9 = new GenLayerFuzzyZoom(2000L, var3); + GenLayerAddIsland var10 = new GenLayerAddIsland(1L, var9); + GenLayerZoom var11 = new GenLayerZoom(2001L, var10); + var10 = new GenLayerAddIsland(2L, var11); + GenLayerAddSnow var12 = new GenLayerAddSnow(2L, var10); + var11 = new GenLayerZoom(2002L, var12); + var10 = new GenLayerAddIsland(3L, var11); + var11 = new GenLayerZoom(2003L, var10); + var10 = new GenLayerAddIsland(4L, var11); + GenLayerAddMushroomIsland var15 = new GenLayerAddMushroomIsland(5L, var10); + byte var4 = 4; + + if (par2WorldType == WorldType.LARGE_BIOMES) { + var4 = 6; + } + + GenLayer var5 = GenLayerZoom.magnify(1000L, var15, 0); + GenLayerRiverInit var13 = new GenLayerRiverInit(100L, var5); + var5 = GenLayerZoom.magnify(1000L, var13, var4 + 2); + GenLayerRiver var14 = new GenLayerRiver(1L, var5); + GenLayerSmooth var16 = new GenLayerSmooth(1000L, var14); + GenLayer var6 = GenLayerZoom.magnify(1000L, var15, 0); + GenLayerBiome var17 = new GenLayerBiome(200L, var6, par2WorldType); + var6 = GenLayerZoom.magnify(1000L, var17, 2); + Object var18 = new GenLayerHills(1000L, var6); + + for (int var7 = 0; var7 < var4; ++var7) { + var18 = new GenLayerZoom((long) (1000 + var7), (GenLayer) var18); + + if (var7 == 0) { + var18 = new GenLayerAddIsland(3L, (GenLayer) var18); + } + + if (var7 == 1) { + var18 = new GenLayerShore(1000L, (GenLayer) var18); + } + + if (var7 == 1) { + var18 = new GenLayerSwampRivers(1000L, (GenLayer) var18); + } + } + + GenLayerSmooth var19 = new GenLayerSmooth(1000L, (GenLayer) var18); + GenLayerRiverMix var20 = new GenLayerRiverMix(100L, var19, var16); + GenLayerVoronoiZoom var8 = new GenLayerVoronoiZoom(10L, var20); + var20.initWorldGenSeed(par0); + var8.initWorldGenSeed(par0); + return new GenLayer[] { var20, var8, var20 }; + } + + public GenLayer(long par1) { + this.baseSeed = par1; + this.baseSeed *= this.baseSeed * 6364136223846793005L + 1442695040888963407L; + this.baseSeed += par1; + this.baseSeed *= this.baseSeed * 6364136223846793005L + 1442695040888963407L; + this.baseSeed += par1; + this.baseSeed *= this.baseSeed * 6364136223846793005L + 1442695040888963407L; + this.baseSeed += par1; + } + + /** + * Initialize layer's local worldGenSeed based on its own baseSeed and the + * world's global seed (passed in as an argument). + */ + public void initWorldGenSeed(long par1) { + this.worldGenSeed = par1; + + if (this.parent != null) { + this.parent.initWorldGenSeed(par1); + } + + this.worldGenSeed *= this.worldGenSeed * 6364136223846793005L + 1442695040888963407L; + this.worldGenSeed += this.baseSeed; + this.worldGenSeed *= this.worldGenSeed * 6364136223846793005L + 1442695040888963407L; + this.worldGenSeed += this.baseSeed; + this.worldGenSeed *= this.worldGenSeed * 6364136223846793005L + 1442695040888963407L; + this.worldGenSeed += this.baseSeed; + } + + /** + * Initialize layer's current chunkSeed based on the local worldGenSeed and the + * (x,z) chunk coordinates. + */ + public void initChunkSeed(long par1, long par3) { + this.chunkSeed = this.worldGenSeed; + this.chunkSeed *= this.chunkSeed * 6364136223846793005L + 1442695040888963407L; + this.chunkSeed += par1; + this.chunkSeed *= this.chunkSeed * 6364136223846793005L + 1442695040888963407L; + this.chunkSeed += par3; + this.chunkSeed *= this.chunkSeed * 6364136223846793005L + 1442695040888963407L; + this.chunkSeed += par1; + this.chunkSeed *= this.chunkSeed * 6364136223846793005L + 1442695040888963407L; + this.chunkSeed += par3; + } + + /** + * returns a LCG pseudo random number from [0, x). Args: int x + */ + protected int nextInt(int par1) { + int var2 = (int) ((this.chunkSeed >> 24) % (long) par1); + + if (var2 < 0) { + var2 += par1; + } + + this.chunkSeed *= this.chunkSeed * 6364136223846793005L + 1442695040888963407L; + this.chunkSeed += this.worldGenSeed; + return var2; + } + + /** + * Returns a list of integer values generated by this layer. These may be + * interpreted as temperatures, rainfall amounts, or biomeList[] indices based + * on the particular GenLayer subclass. + */ + public abstract int[] getInts(int var1, int var2, int var3, int var4); +} diff --git a/sp-server/src/main/java/net/minecraft/src/GenLayerAddIsland.java b/sp-server/src/main/java/net/minecraft/src/GenLayerAddIsland.java new file mode 100644 index 0000000..021f47b --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/GenLayerAddIsland.java @@ -0,0 +1,76 @@ +package net.minecraft.src; + +public class GenLayerAddIsland extends GenLayer { + public GenLayerAddIsland(long par1, GenLayer par3GenLayer) { + super(par1); + this.parent = par3GenLayer; + } + + /** + * Returns a list of integer values generated by this layer. These may be + * interpreted as temperatures, rainfall amounts, or biomeList[] indices based + * on the particular GenLayer subclass. + */ + public int[] getInts(int par1, int par2, int par3, int par4) { + int var5 = par1 - 1; + int var6 = par2 - 1; + int var7 = par3 + 2; + int var8 = par4 + 2; + int[] var9 = this.parent.getInts(var5, var6, var7, var8); + int[] var10 = IntCache.getIntCache(par3 * par4); + + for (int var11 = 0; var11 < par4; ++var11) { + for (int var12 = 0; var12 < par3; ++var12) { + int var13 = var9[var12 + 0 + (var11 + 0) * var7]; + int var14 = var9[var12 + 2 + (var11 + 0) * var7]; + int var15 = var9[var12 + 0 + (var11 + 2) * var7]; + int var16 = var9[var12 + 2 + (var11 + 2) * var7]; + int var17 = var9[var12 + 1 + (var11 + 1) * var7]; + this.initChunkSeed((long) (var12 + par1), (long) (var11 + par2)); + + if (var17 == 0 && (var13 != 0 || var14 != 0 || var15 != 0 || var16 != 0)) { + int var18 = 1; + int var19 = 1; + + if (var13 != 0 && this.nextInt(var18++) == 0) { + var19 = var13; + } + + if (var14 != 0 && this.nextInt(var18++) == 0) { + var19 = var14; + } + + if (var15 != 0 && this.nextInt(var18++) == 0) { + var19 = var15; + } + + if (var16 != 0 && this.nextInt(var18++) == 0) { + var19 = var16; + } + + if (this.nextInt(3) == 0) { + var10[var12 + var11 * par3] = var19; + } else if (var19 == BiomeGenBase.icePlains.biomeID) { + var10[var12 + var11 * par3] = BiomeGenBase.frozenOcean.biomeID; + } else { + var10[var12 + var11 * par3] = 0; + } + } else if (var17 > 0 && (var13 == 0 || var14 == 0 || var15 == 0 || var16 == 0)) { + if (this.nextInt(5) == 0) { + if (var17 == BiomeGenBase.icePlains.biomeID) { + var10[var12 + var11 * par3] = BiomeGenBase.frozenOcean.biomeID; + } else { + var10[var12 + var11 * par3] = 0; + } + } else { + var10[var12 + var11 * par3] = var17; + } + } else { + var10[var12 + var11 * par3] = var17; + } + } + } + + return var10; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/GenLayerAddMushroomIsland.java b/sp-server/src/main/java/net/minecraft/src/GenLayerAddMushroomIsland.java new file mode 100644 index 0000000..549db3b --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/GenLayerAddMushroomIsland.java @@ -0,0 +1,41 @@ +package net.minecraft.src; + +public class GenLayerAddMushroomIsland extends GenLayer { + public GenLayerAddMushroomIsland(long par1, GenLayer par3GenLayer) { + super(par1); + this.parent = par3GenLayer; + } + + /** + * Returns a list of integer values generated by this layer. These may be + * interpreted as temperatures, rainfall amounts, or biomeList[] indices based + * on the particular GenLayer subclass. + */ + public int[] getInts(int par1, int par2, int par3, int par4) { + int var5 = par1 - 1; + int var6 = par2 - 1; + int var7 = par3 + 2; + int var8 = par4 + 2; + int[] var9 = this.parent.getInts(var5, var6, var7, var8); + int[] var10 = IntCache.getIntCache(par3 * par4); + + for (int var11 = 0; var11 < par4; ++var11) { + for (int var12 = 0; var12 < par3; ++var12) { + int var13 = var9[var12 + 0 + (var11 + 0) * var7]; + int var14 = var9[var12 + 2 + (var11 + 0) * var7]; + int var15 = var9[var12 + 0 + (var11 + 2) * var7]; + int var16 = var9[var12 + 2 + (var11 + 2) * var7]; + int var17 = var9[var12 + 1 + (var11 + 1) * var7]; + this.initChunkSeed((long) (var12 + par1), (long) (var11 + par2)); + + if (var17 == 0 && var13 == 0 && var14 == 0 && var15 == 0 && var16 == 0 && this.nextInt(100) == 0) { + var10[var12 + var11 * par3] = BiomeGenBase.mushroomIsland.biomeID; + } else { + var10[var12 + var11 * par3] = var17; + } + } + } + + return var10; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/GenLayerAddSnow.java b/sp-server/src/main/java/net/minecraft/src/GenLayerAddSnow.java new file mode 100644 index 0000000..902ee11 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/GenLayerAddSnow.java @@ -0,0 +1,45 @@ +package net.minecraft.src; + +public class GenLayerAddSnow extends GenLayer { + public GenLayerAddSnow(long par1, GenLayer par3GenLayer) { + super(par1); + this.parent = par3GenLayer; + } + + /** + * Returns a list of integer values generated by this layer. These may be + * interpreted as temperatures, rainfall amounts, or biomeList[] indices based + * on the particular GenLayer subclass. + */ + public int[] getInts(int par1, int par2, int par3, int par4) { + int var5 = par1 - 1; + int var6 = par2 - 1; + int var7 = par3 + 2; + int var8 = par4 + 2; + int[] var9 = this.parent.getInts(var5, var6, var7, var8); + int[] var10 = IntCache.getIntCache(par3 * par4); + + for (int var11 = 0; var11 < par4; ++var11) { + for (int var12 = 0; var12 < par3; ++var12) { + int var13 = var9[var12 + 1 + (var11 + 1) * var7]; + this.initChunkSeed((long) (var12 + par1), (long) (var11 + par2)); + + if (var13 == 0) { + var10[var12 + var11 * par3] = 0; + } else { + int var14 = this.nextInt(5); + + if (var14 == 0) { + var14 = BiomeGenBase.icePlains.biomeID; + } else { + var14 = 1; + } + + var10[var12 + var11 * par3] = var14; + } + } + } + + return var10; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/GenLayerBiome.java b/sp-server/src/main/java/net/minecraft/src/GenLayerBiome.java new file mode 100644 index 0000000..8cc27be --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/GenLayerBiome.java @@ -0,0 +1,53 @@ +package net.minecraft.src; + +public class GenLayerBiome extends GenLayer { + /** this sets all the biomes that are allowed to appear in the overworld */ + private BiomeGenBase[] allowedBiomes; + + public GenLayerBiome(long par1, GenLayer par3GenLayer, WorldType par4WorldType) { + super(par1); + this.allowedBiomes = new BiomeGenBase[] { BiomeGenBase.desert, BiomeGenBase.forest, BiomeGenBase.extremeHills, + BiomeGenBase.swampland, BiomeGenBase.plains, BiomeGenBase.taiga, BiomeGenBase.jungle }; + this.parent = par3GenLayer; + + if (par4WorldType == WorldType.DEFAULT_1_1) { + this.allowedBiomes = new BiomeGenBase[] { BiomeGenBase.desert, BiomeGenBase.forest, + BiomeGenBase.extremeHills, BiomeGenBase.swampland, BiomeGenBase.plains, BiomeGenBase.taiga }; + } + } + + /** + * Returns a list of integer values generated by this layer. These may be + * interpreted as temperatures, rainfall amounts, or biomeList[] indices based + * on the particular GenLayer subclass. + */ + public int[] getInts(int par1, int par2, int par3, int par4) { + int[] var5 = this.parent.getInts(par1, par2, par3, par4); + int[] var6 = IntCache.getIntCache(par3 * par4); + + for (int var7 = 0; var7 < par4; ++var7) { + for (int var8 = 0; var8 < par3; ++var8) { + this.initChunkSeed((long) (var8 + par1), (long) (var7 + par2)); + int var9 = var5[var8 + var7 * par3]; + + if (var9 == 0) { + var6[var8 + var7 * par3] = 0; + } else if (var9 == BiomeGenBase.mushroomIsland.biomeID) { + var6[var8 + var7 * par3] = var9; + } else if (var9 == 1) { + var6[var8 + var7 * par3] = this.allowedBiomes[this.nextInt(this.allowedBiomes.length)].biomeID; + } else { + int var10 = this.allowedBiomes[this.nextInt(this.allowedBiomes.length)].biomeID; + + if (var10 == BiomeGenBase.taiga.biomeID) { + var6[var8 + var7 * par3] = var10; + } else { + var6[var8 + var7 * par3] = BiomeGenBase.icePlains.biomeID; + } + } + } + } + + return var6; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/GenLayerFuzzyZoom.java b/sp-server/src/main/java/net/minecraft/src/GenLayerFuzzyZoom.java new file mode 100644 index 0000000..7b3bb56 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/GenLayerFuzzyZoom.java @@ -0,0 +1,66 @@ +package net.minecraft.src; + +public class GenLayerFuzzyZoom extends GenLayer { + public GenLayerFuzzyZoom(long par1, GenLayer par3GenLayer) { + super(par1); + super.parent = par3GenLayer; + } + + /** + * Returns a list of integer values generated by this layer. These may be + * interpreted as temperatures, rainfall amounts, or biomeList[] indices based + * on the particular GenLayer subclass. + */ + public int[] getInts(int par1, int par2, int par3, int par4) { + int var5 = par1 >> 1; + int var6 = par2 >> 1; + int var7 = (par3 >> 1) + 3; + int var8 = (par4 >> 1) + 3; + int[] var9 = this.parent.getInts(var5, var6, var7, var8); + int[] var10 = IntCache.getIntCache(var7 * 2 * var8 * 2); + int var11 = var7 << 1; + int var13; + + for (int var12 = 0; var12 < var8 - 1; ++var12) { + var13 = var12 << 1; + int var14 = var13 * var11; + int var15 = var9[0 + (var12 + 0) * var7]; + int var16 = var9[0 + (var12 + 1) * var7]; + + for (int var17 = 0; var17 < var7 - 1; ++var17) { + this.initChunkSeed((long) (var17 + var5 << 1), (long) (var12 + var6 << 1)); + int var18 = var9[var17 + 1 + (var12 + 0) * var7]; + int var19 = var9[var17 + 1 + (var12 + 1) * var7]; + var10[var14] = var15; + var10[var14++ + var11] = this.choose(var15, var16); + var10[var14] = this.choose(var15, var18); + var10[var14++ + var11] = this.choose(var15, var18, var16, var19); + var15 = var18; + var16 = var19; + } + } + + int[] var20 = IntCache.getIntCache(par3 * par4); + + for (var13 = 0; var13 < par4; ++var13) { + System.arraycopy(var10, (var13 + (par2 & 1)) * (var7 << 1) + (par1 & 1), var20, var13 * par3, par3); + } + + return var20; + } + + /** + * randomly choose between the two args + */ + protected int choose(int par1, int par2) { + return this.nextInt(2) == 0 ? par1 : par2; + } + + /** + * randomly choose between the four args + */ + protected int choose(int par1, int par2, int par3, int par4) { + int var5 = this.nextInt(4); + return var5 == 0 ? par1 : (var5 == 1 ? par2 : (var5 == 2 ? par3 : par4)); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/GenLayerHills.java b/sp-server/src/main/java/net/minecraft/src/GenLayerHills.java new file mode 100644 index 0000000..bfa0c74 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/GenLayerHills.java @@ -0,0 +1,62 @@ +package net.minecraft.src; + +public class GenLayerHills extends GenLayer { + public GenLayerHills(long par1, GenLayer par3GenLayer) { + super(par1); + this.parent = par3GenLayer; + } + + /** + * Returns a list of integer values generated by this layer. These may be + * interpreted as temperatures, rainfall amounts, or biomeList[] indices based + * on the particular GenLayer subclass. + */ + public int[] getInts(int par1, int par2, int par3, int par4) { + int[] var5 = this.parent.getInts(par1 - 1, par2 - 1, par3 + 2, par4 + 2); + int[] var6 = IntCache.getIntCache(par3 * par4); + + for (int var7 = 0; var7 < par4; ++var7) { + for (int var8 = 0; var8 < par3; ++var8) { + this.initChunkSeed((long) (var8 + par1), (long) (var7 + par2)); + int var9 = var5[var8 + 1 + (var7 + 1) * (par3 + 2)]; + + if (this.nextInt(3) == 0) { + int var10 = var9; + + if (var9 == BiomeGenBase.desert.biomeID) { + var10 = BiomeGenBase.desertHills.biomeID; + } else if (var9 == BiomeGenBase.forest.biomeID) { + var10 = BiomeGenBase.forestHills.biomeID; + } else if (var9 == BiomeGenBase.taiga.biomeID) { + var10 = BiomeGenBase.taigaHills.biomeID; + } else if (var9 == BiomeGenBase.plains.biomeID) { + var10 = BiomeGenBase.forest.biomeID; + } else if (var9 == BiomeGenBase.icePlains.biomeID) { + var10 = BiomeGenBase.iceMountains.biomeID; + } else if (var9 == BiomeGenBase.jungle.biomeID) { + var10 = BiomeGenBase.jungleHills.biomeID; + } + + if (var10 == var9) { + var6[var8 + var7 * par3] = var9; + } else { + int var11 = var5[var8 + 1 + (var7 + 1 - 1) * (par3 + 2)]; + int var12 = var5[var8 + 1 + 1 + (var7 + 1) * (par3 + 2)]; + int var13 = var5[var8 + 1 - 1 + (var7 + 1) * (par3 + 2)]; + int var14 = var5[var8 + 1 + (var7 + 1 + 1) * (par3 + 2)]; + + if (var11 == var9 && var12 == var9 && var13 == var9 && var14 == var9) { + var6[var8 + var7 * par3] = var10; + } else { + var6[var8 + var7 * par3] = var9; + } + } + } else { + var6[var8 + var7 * par3] = var9; + } + } + } + + return var6; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/GenLayerIsland.java b/sp-server/src/main/java/net/minecraft/src/GenLayerIsland.java new file mode 100644 index 0000000..40e815a --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/GenLayerIsland.java @@ -0,0 +1,29 @@ +package net.minecraft.src; + +public class GenLayerIsland extends GenLayer { + public GenLayerIsland(long par1) { + super(par1); + } + + /** + * Returns a list of integer values generated by this layer. These may be + * interpreted as temperatures, rainfall amounts, or biomeList[] indices based + * on the particular GenLayer subclass. + */ + public int[] getInts(int par1, int par2, int par3, int par4) { + int[] var5 = IntCache.getIntCache(par3 * par4); + + for (int var6 = 0; var6 < par4; ++var6) { + for (int var7 = 0; var7 < par3; ++var7) { + this.initChunkSeed((long) (par1 + var7), (long) (par2 + var6)); + var5[var7 + var6 * par3] = this.nextInt(10) == 0 ? 1 : 0; + } + } + + if (par1 > -par3 && par1 <= 0 && par2 > -par4 && par2 <= 0) { + var5[-par1 + -par2 * par3] = 1; + } + + return var5; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/GenLayerRiver.java b/sp-server/src/main/java/net/minecraft/src/GenLayerRiver.java new file mode 100644 index 0000000..56b8081 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/GenLayerRiver.java @@ -0,0 +1,41 @@ +package net.minecraft.src; + +public class GenLayerRiver extends GenLayer { + public GenLayerRiver(long par1, GenLayer par3GenLayer) { + super(par1); + super.parent = par3GenLayer; + } + + /** + * Returns a list of integer values generated by this layer. These may be + * interpreted as temperatures, rainfall amounts, or biomeList[] indices based + * on the particular GenLayer subclass. + */ + public int[] getInts(int par1, int par2, int par3, int par4) { + int var5 = par1 - 1; + int var6 = par2 - 1; + int var7 = par3 + 2; + int var8 = par4 + 2; + int[] var9 = this.parent.getInts(var5, var6, var7, var8); + int[] var10 = IntCache.getIntCache(par3 * par4); + + for (int var11 = 0; var11 < par4; ++var11) { + for (int var12 = 0; var12 < par3; ++var12) { + int var13 = var9[var12 + 0 + (var11 + 1) * var7]; + int var14 = var9[var12 + 2 + (var11 + 1) * var7]; + int var15 = var9[var12 + 1 + (var11 + 0) * var7]; + int var16 = var9[var12 + 1 + (var11 + 2) * var7]; + int var17 = var9[var12 + 1 + (var11 + 1) * var7]; + + if (var17 != 0 && var13 != 0 && var14 != 0 && var15 != 0 && var16 != 0 && var17 == var13 + && var17 == var15 && var17 == var14 && var17 == var16) { + var10[var12 + var11 * par3] = -1; + } else { + var10[var12 + var11 * par3] = BiomeGenBase.river.biomeID; + } + } + } + + return var10; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/GenLayerRiverInit.java b/sp-server/src/main/java/net/minecraft/src/GenLayerRiverInit.java new file mode 100644 index 0000000..fa994a4 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/GenLayerRiverInit.java @@ -0,0 +1,27 @@ +package net.minecraft.src; + +public class GenLayerRiverInit extends GenLayer { + public GenLayerRiverInit(long par1, GenLayer par3GenLayer) { + super(par1); + this.parent = par3GenLayer; + } + + /** + * Returns a list of integer values generated by this layer. These may be + * interpreted as temperatures, rainfall amounts, or biomeList[] indices based + * on the particular GenLayer subclass. + */ + public int[] getInts(int par1, int par2, int par3, int par4) { + int[] var5 = this.parent.getInts(par1, par2, par3, par4); + int[] var6 = IntCache.getIntCache(par3 * par4); + + for (int var7 = 0; var7 < par4; ++var7) { + for (int var8 = 0; var8 < par3; ++var8) { + this.initChunkSeed((long) (var8 + par1), (long) (var7 + par2)); + var6[var8 + var7 * par3] = var5[var8 + var7 * par3] > 0 ? this.nextInt(2) + 2 : 0; + } + } + + return var6; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/GenLayerRiverMix.java b/sp-server/src/main/java/net/minecraft/src/GenLayerRiverMix.java new file mode 100644 index 0000000..14c51d3 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/GenLayerRiverMix.java @@ -0,0 +1,52 @@ +package net.minecraft.src; + +public class GenLayerRiverMix extends GenLayer { + private GenLayer biomePatternGeneratorChain; + private GenLayer riverPatternGeneratorChain; + + public GenLayerRiverMix(long par1, GenLayer par3GenLayer, GenLayer par4GenLayer) { + super(par1); + this.biomePatternGeneratorChain = par3GenLayer; + this.riverPatternGeneratorChain = par4GenLayer; + } + + /** + * Initialize layer's local worldGenSeed based on its own baseSeed and the + * world's global seed (passed in as an argument). + */ + public void initWorldGenSeed(long par1) { + this.biomePatternGeneratorChain.initWorldGenSeed(par1); + this.riverPatternGeneratorChain.initWorldGenSeed(par1); + super.initWorldGenSeed(par1); + } + + /** + * Returns a list of integer values generated by this layer. These may be + * interpreted as temperatures, rainfall amounts, or biomeList[] indices based + * on the particular GenLayer subclass. + */ + public int[] getInts(int par1, int par2, int par3, int par4) { + int[] var5 = this.biomePatternGeneratorChain.getInts(par1, par2, par3, par4); + int[] var6 = this.riverPatternGeneratorChain.getInts(par1, par2, par3, par4); + int[] var7 = IntCache.getIntCache(par3 * par4); + + for (int var8 = 0; var8 < par3 * par4; ++var8) { + if (var5[var8] == BiomeGenBase.ocean.biomeID) { + var7[var8] = var5[var8]; + } else if (var6[var8] >= 0) { + if (var5[var8] == BiomeGenBase.icePlains.biomeID) { + var7[var8] = BiomeGenBase.frozenRiver.biomeID; + } else if (var5[var8] != BiomeGenBase.mushroomIsland.biomeID + && var5[var8] != BiomeGenBase.mushroomIslandShore.biomeID) { + var7[var8] = var6[var8]; + } else { + var7[var8] = BiomeGenBase.mushroomIslandShore.biomeID; + } + } else { + var7[var8] = var5[var8]; + } + } + + return var7; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/GenLayerShore.java b/sp-server/src/main/java/net/minecraft/src/GenLayerShore.java new file mode 100644 index 0000000..6e5f4fe --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/GenLayerShore.java @@ -0,0 +1,73 @@ +package net.minecraft.src; + +public class GenLayerShore extends GenLayer { + public GenLayerShore(long par1, GenLayer par3GenLayer) { + super(par1); + this.parent = par3GenLayer; + } + + /** + * Returns a list of integer values generated by this layer. These may be + * interpreted as temperatures, rainfall amounts, or biomeList[] indices based + * on the particular GenLayer subclass. + */ + public int[] getInts(int par1, int par2, int par3, int par4) { + int[] var5 = this.parent.getInts(par1 - 1, par2 - 1, par3 + 2, par4 + 2); + int[] var6 = IntCache.getIntCache(par3 * par4); + + for (int var7 = 0; var7 < par4; ++var7) { + for (int var8 = 0; var8 < par3; ++var8) { + this.initChunkSeed((long) (var8 + par1), (long) (var7 + par2)); + int var9 = var5[var8 + 1 + (var7 + 1) * (par3 + 2)]; + int var10; + int var11; + int var12; + int var13; + + if (var9 == BiomeGenBase.mushroomIsland.biomeID) { + var10 = var5[var8 + 1 + (var7 + 1 - 1) * (par3 + 2)]; + var11 = var5[var8 + 1 + 1 + (var7 + 1) * (par3 + 2)]; + var12 = var5[var8 + 1 - 1 + (var7 + 1) * (par3 + 2)]; + var13 = var5[var8 + 1 + (var7 + 1 + 1) * (par3 + 2)]; + + if (var10 != BiomeGenBase.ocean.biomeID && var11 != BiomeGenBase.ocean.biomeID + && var12 != BiomeGenBase.ocean.biomeID && var13 != BiomeGenBase.ocean.biomeID) { + var6[var8 + var7 * par3] = var9; + } else { + var6[var8 + var7 * par3] = BiomeGenBase.mushroomIslandShore.biomeID; + } + } else if (var9 != BiomeGenBase.ocean.biomeID && var9 != BiomeGenBase.river.biomeID + && var9 != BiomeGenBase.swampland.biomeID && var9 != BiomeGenBase.extremeHills.biomeID) { + var10 = var5[var8 + 1 + (var7 + 1 - 1) * (par3 + 2)]; + var11 = var5[var8 + 1 + 1 + (var7 + 1) * (par3 + 2)]; + var12 = var5[var8 + 1 - 1 + (var7 + 1) * (par3 + 2)]; + var13 = var5[var8 + 1 + (var7 + 1 + 1) * (par3 + 2)]; + + if (var10 != BiomeGenBase.ocean.biomeID && var11 != BiomeGenBase.ocean.biomeID + && var12 != BiomeGenBase.ocean.biomeID && var13 != BiomeGenBase.ocean.biomeID) { + var6[var8 + var7 * par3] = var9; + } else { + var6[var8 + var7 * par3] = BiomeGenBase.beach.biomeID; + } + } else if (var9 == BiomeGenBase.extremeHills.biomeID) { + var10 = var5[var8 + 1 + (var7 + 1 - 1) * (par3 + 2)]; + var11 = var5[var8 + 1 + 1 + (var7 + 1) * (par3 + 2)]; + var12 = var5[var8 + 1 - 1 + (var7 + 1) * (par3 + 2)]; + var13 = var5[var8 + 1 + (var7 + 1 + 1) * (par3 + 2)]; + + if (var10 == BiomeGenBase.extremeHills.biomeID && var11 == BiomeGenBase.extremeHills.biomeID + && var12 == BiomeGenBase.extremeHills.biomeID + && var13 == BiomeGenBase.extremeHills.biomeID) { + var6[var8 + var7 * par3] = var9; + } else { + var6[var8 + var7 * par3] = BiomeGenBase.extremeHillsEdge.biomeID; + } + } else { + var6[var8 + var7 * par3] = var9; + } + } + } + + return var6; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/GenLayerSmooth.java b/sp-server/src/main/java/net/minecraft/src/GenLayerSmooth.java new file mode 100644 index 0000000..9008d28 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/GenLayerSmooth.java @@ -0,0 +1,54 @@ +package net.minecraft.src; + +public class GenLayerSmooth extends GenLayer { + public GenLayerSmooth(long par1, GenLayer par3GenLayer) { + super(par1); + super.parent = par3GenLayer; + } + + /** + * Returns a list of integer values generated by this layer. These may be + * interpreted as temperatures, rainfall amounts, or biomeList[] indices based + * on the particular GenLayer subclass. + */ + public int[] getInts(int par1, int par2, int par3, int par4) { + int var5 = par1 - 1; + int var6 = par2 - 1; + int var7 = par3 + 2; + int var8 = par4 + 2; + int[] var9 = this.parent.getInts(var5, var6, var7, var8); + int[] var10 = IntCache.getIntCache(par3 * par4); + + for (int var11 = 0; var11 < par4; ++var11) { + for (int var12 = 0; var12 < par3; ++var12) { + int var13 = var9[var12 + 0 + (var11 + 1) * var7]; + int var14 = var9[var12 + 2 + (var11 + 1) * var7]; + int var15 = var9[var12 + 1 + (var11 + 0) * var7]; + int var16 = var9[var12 + 1 + (var11 + 2) * var7]; + int var17 = var9[var12 + 1 + (var11 + 1) * var7]; + + if (var13 == var14 && var15 == var16) { + this.initChunkSeed((long) (var12 + par1), (long) (var11 + par2)); + + if (this.nextInt(2) == 0) { + var17 = var13; + } else { + var17 = var15; + } + } else { + if (var13 == var14) { + var17 = var13; + } + + if (var15 == var16) { + var17 = var15; + } + } + + var10[var12 + var11 * par3] = var17; + } + } + + return var10; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/GenLayerSwampRivers.java b/sp-server/src/main/java/net/minecraft/src/GenLayerSwampRivers.java new file mode 100644 index 0000000..eef78c6 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/GenLayerSwampRivers.java @@ -0,0 +1,35 @@ +package net.minecraft.src; + +public class GenLayerSwampRivers extends GenLayer { + public GenLayerSwampRivers(long par1, GenLayer par3GenLayer) { + super(par1); + this.parent = par3GenLayer; + } + + /** + * Returns a list of integer values generated by this layer. These may be + * interpreted as temperatures, rainfall amounts, or biomeList[] indices based + * on the particular GenLayer subclass. + */ + public int[] getInts(int par1, int par2, int par3, int par4) { + int[] var5 = this.parent.getInts(par1 - 1, par2 - 1, par3 + 2, par4 + 2); + int[] var6 = IntCache.getIntCache(par3 * par4); + + for (int var7 = 0; var7 < par4; ++var7) { + for (int var8 = 0; var8 < par3; ++var8) { + this.initChunkSeed((long) (var8 + par1), (long) (var7 + par2)); + int var9 = var5[var8 + 1 + (var7 + 1) * (par3 + 2)]; + + if ((var9 != BiomeGenBase.swampland.biomeID || this.nextInt(6) != 0) + && (var9 != BiomeGenBase.jungle.biomeID && var9 != BiomeGenBase.jungleHills.biomeID + || this.nextInt(8) != 0)) { + var6[var8 + var7 * par3] = var9; + } else { + var6[var8 + var7 * par3] = BiomeGenBase.river.biomeID; + } + } + } + + return var6; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/GenLayerVoronoiZoom.java b/sp-server/src/main/java/net/minecraft/src/GenLayerVoronoiZoom.java new file mode 100644 index 0000000..4fd5fe6 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/GenLayerVoronoiZoom.java @@ -0,0 +1,89 @@ +package net.minecraft.src; + +public class GenLayerVoronoiZoom extends GenLayer { + public GenLayerVoronoiZoom(long par1, GenLayer par3GenLayer) { + super(par1); + super.parent = par3GenLayer; + } + + /** + * Returns a list of integer values generated by this layer. These may be + * interpreted as temperatures, rainfall amounts, or biomeList[] indices based + * on the particular GenLayer subclass. + */ + public int[] getInts(int par1, int par2, int par3, int par4) { + par1 -= 2; + par2 -= 2; + byte var5 = 2; + int var6 = 1 << var5; + int var7 = par1 >> var5; + int var8 = par2 >> var5; + int var9 = (par3 >> var5) + 3; + int var10 = (par4 >> var5) + 3; + int[] var11 = this.parent.getInts(var7, var8, var9, var10); + int var12 = var9 << var5; + int var13 = var10 << var5; + int[] var14 = IntCache.getIntCache(var12 * var13); + int var16; + + for (int var15 = 0; var15 < var10 - 1; ++var15) { + var16 = var11[0 + (var15 + 0) * var9]; + int var17 = var11[0 + (var15 + 1) * var9]; + + for (int var18 = 0; var18 < var9 - 1; ++var18) { + double var19 = (double) var6 * 0.9D; + this.initChunkSeed((long) (var18 + var7 << var5), (long) (var15 + var8 << var5)); + double var21 = ((double) this.nextInt(1024) / 1024.0D - 0.5D) * var19; + double var23 = ((double) this.nextInt(1024) / 1024.0D - 0.5D) * var19; + this.initChunkSeed((long) (var18 + var7 + 1 << var5), (long) (var15 + var8 << var5)); + double var25 = ((double) this.nextInt(1024) / 1024.0D - 0.5D) * var19 + (double) var6; + double var27 = ((double) this.nextInt(1024) / 1024.0D - 0.5D) * var19; + this.initChunkSeed((long) (var18 + var7 << var5), (long) (var15 + var8 + 1 << var5)); + double var29 = ((double) this.nextInt(1024) / 1024.0D - 0.5D) * var19; + double var31 = ((double) this.nextInt(1024) / 1024.0D - 0.5D) * var19 + (double) var6; + this.initChunkSeed((long) (var18 + var7 + 1 << var5), (long) (var15 + var8 + 1 << var5)); + double var33 = ((double) this.nextInt(1024) / 1024.0D - 0.5D) * var19 + (double) var6; + double var35 = ((double) this.nextInt(1024) / 1024.0D - 0.5D) * var19 + (double) var6; + int var37 = var11[var18 + 1 + (var15 + 0) * var9]; + int var38 = var11[var18 + 1 + (var15 + 1) * var9]; + + for (int var39 = 0; var39 < var6; ++var39) { + int var40 = ((var15 << var5) + var39) * var12 + (var18 << var5); + + for (int var41 = 0; var41 < var6; ++var41) { + double var42 = ((double) var39 - var23) * ((double) var39 - var23) + + ((double) var41 - var21) * ((double) var41 - var21); + double var44 = ((double) var39 - var27) * ((double) var39 - var27) + + ((double) var41 - var25) * ((double) var41 - var25); + double var46 = ((double) var39 - var31) * ((double) var39 - var31) + + ((double) var41 - var29) * ((double) var41 - var29); + double var48 = ((double) var39 - var35) * ((double) var39 - var35) + + ((double) var41 - var33) * ((double) var41 - var33); + + if (var42 < var44 && var42 < var46 && var42 < var48) { + var14[var40++] = var16; + } else if (var44 < var42 && var44 < var46 && var44 < var48) { + var14[var40++] = var37; + } else if (var46 < var42 && var46 < var44 && var46 < var48) { + var14[var40++] = var17; + } else { + var14[var40++] = var38; + } + } + } + + var16 = var37; + var17 = var38; + } + } + + int[] var50 = IntCache.getIntCache(par3 * par4); + + for (var16 = 0; var16 < par4; ++var16) { + System.arraycopy(var14, (var16 + (par2 & var6 - 1)) * (var9 << var5) + (par1 & var6 - 1), var50, + var16 * par3, par3); + } + + return var50; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/GenLayerZoom.java b/sp-server/src/main/java/net/minecraft/src/GenLayerZoom.java new file mode 100644 index 0000000..bac728e --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/GenLayerZoom.java @@ -0,0 +1,114 @@ +package net.minecraft.src; + +public class GenLayerZoom extends GenLayer { + public GenLayerZoom(long par1, GenLayer par3GenLayer) { + super(par1); + super.parent = par3GenLayer; + } + + /** + * Returns a list of integer values generated by this layer. These may be + * interpreted as temperatures, rainfall amounts, or biomeList[] indices based + * on the particular GenLayer subclass. + */ + public int[] getInts(int par1, int par2, int par3, int par4) { + int var5 = par1 >> 1; + int var6 = par2 >> 1; + int var7 = (par3 >> 1) + 3; + int var8 = (par4 >> 1) + 3; + int[] var9 = this.parent.getInts(var5, var6, var7, var8); + int[] var10 = IntCache.getIntCache(var7 * 2 * var8 * 2); + int var11 = var7 << 1; + int var13; + + for (int var12 = 0; var12 < var8 - 1; ++var12) { + var13 = var12 << 1; + int var14 = var13 * var11; + int var15 = var9[0 + (var12 + 0) * var7]; + int var16 = var9[0 + (var12 + 1) * var7]; + + for (int var17 = 0; var17 < var7 - 1; ++var17) { + this.initChunkSeed((long) (var17 + var5 << 1), (long) (var12 + var6 << 1)); + int var18 = var9[var17 + 1 + (var12 + 0) * var7]; + int var19 = var9[var17 + 1 + (var12 + 1) * var7]; + var10[var14] = var15; + var10[var14++ + var11] = this.choose(var15, var16); + var10[var14] = this.choose(var15, var18); + var10[var14++ + var11] = this.modeOrRandom(var15, var18, var16, var19); + var15 = var18; + var16 = var19; + } + } + + int[] var20 = IntCache.getIntCache(par3 * par4); + + for (var13 = 0; var13 < par4; ++var13) { + System.arraycopy(var10, (var13 + (par2 & 1)) * (var7 << 1) + (par1 & 1), var20, var13 * par3, par3); + } + + return var20; + } + + /** + * Chooses one of the two inputs randomly. + */ + protected int choose(int par1, int par2) { + return this.nextInt(2) == 0 ? par1 : par2; + } + + /** + * returns the mode (most frequently occuring number) or a random number from + * the 4 integers provided + */ + protected int modeOrRandom(int par1, int par2, int par3, int par4) { + if (par2 == par3 && par3 == par4) { + return par2; + } else if (par1 == par2 && par1 == par3) { + return par1; + } else if (par1 == par2 && par1 == par4) { + return par1; + } else if (par1 == par3 && par1 == par4) { + return par1; + } else if (par1 == par2 && par3 != par4) { + return par1; + } else if (par1 == par3 && par2 != par4) { + return par1; + } else if (par1 == par4 && par2 != par3) { + return par1; + } else if (par2 == par1 && par3 != par4) { + return par2; + } else if (par2 == par3 && par1 != par4) { + return par2; + } else if (par2 == par4 && par1 != par3) { + return par2; + } else if (par3 == par1 && par2 != par4) { + return par3; + } else if (par3 == par2 && par1 != par4) { + return par3; + } else if (par3 == par4 && par1 != par2) { + return par3; + } else if (par4 == par1 && par2 != par3) { + return par3; + } else if (par4 == par2 && par1 != par3) { + return par3; + } else if (par4 == par3 && par1 != par2) { + return par3; + } else { + int var5 = this.nextInt(4); + return var5 == 0 ? par1 : (var5 == 1 ? par2 : (var5 == 2 ? par3 : par4)); + } + } + + /** + * Magnify a layer. Parms are seed adjustment, layer, number of times to magnify + */ + public static GenLayer magnify(long par0, GenLayer par2GenLayer, int par3) { + Object var4 = par2GenLayer; + + for (int var5 = 0; var5 < par3; ++var5) { + var4 = new GenLayerZoom(par0 + (long) var5, (GenLayer) var4); + } + + return (GenLayer) var4; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/GuiLogFormatter.java b/sp-server/src/main/java/net/minecraft/src/GuiLogFormatter.java new file mode 100644 index 0000000..f88021d --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/GuiLogFormatter.java @@ -0,0 +1,31 @@ +package net.minecraft.src; + +import java.io.PrintWriter; +import java.io.StringWriter; +import java.util.logging.Formatter; +import java.util.logging.LogRecord; + +class GuiLogFormatter extends Formatter { + /** Reference to the GuiLogOutputHandler. */ + final GuiLogOutputHandler outputHandler; + + GuiLogFormatter(GuiLogOutputHandler par1GuiLogOutputHandler) { + this.outputHandler = par1GuiLogOutputHandler; + } + + public String format(LogRecord par1LogRecord) { + StringBuilder var2 = new StringBuilder(); + var2.append(" [").append(par1LogRecord.getLevel().getName()).append("] "); + var2.append(this.formatMessage(par1LogRecord)); + var2.append('\n'); + Throwable var3 = par1LogRecord.getThrown(); + + if (var3 != null) { + StringWriter var4 = new StringWriter(); + var3.printStackTrace(new PrintWriter(var4)); + var2.append(var4.toString()); + } + + return var2.toString(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/GuiLogOutputHandler.java b/sp-server/src/main/java/net/minecraft/src/GuiLogOutputHandler.java new file mode 100644 index 0000000..8909cd3 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/GuiLogOutputHandler.java @@ -0,0 +1,38 @@ +package net.minecraft.src; + +import java.util.logging.Formatter; +import java.util.logging.Handler; +import java.util.logging.LogRecord; +import javax.swing.JTextArea; + +public class GuiLogOutputHandler extends Handler { + private int[] field_79023_b = new int[1024]; + private int field_79024_c = 0; + Formatter field_79025_a = new GuiLogFormatter(this); + private JTextArea field_79022_d; + + public GuiLogOutputHandler(JTextArea par1JTextArea) { + this.setFormatter(this.field_79025_a); + this.field_79022_d = par1JTextArea; + } + + public void close() { + } + + public void flush() { + } + + public void publish(LogRecord par1LogRecord) { + int var2 = this.field_79022_d.getDocument().getLength(); + this.field_79022_d.append(this.field_79025_a.format(par1LogRecord)); + this.field_79022_d.setCaretPosition(this.field_79022_d.getDocument().getLength()); + int var3 = this.field_79022_d.getDocument().getLength() - var2; + + if (this.field_79023_b[this.field_79024_c] != 0) { + this.field_79022_d.replaceRange("", 0, this.field_79023_b[this.field_79024_c]); + } + + this.field_79023_b[this.field_79024_c] = var3; + this.field_79024_c = (this.field_79024_c + 1) % 1024; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/GuiStatsComponent.java b/sp-server/src/main/java/net/minecraft/src/GuiStatsComponent.java new file mode 100644 index 0000000..35364c1 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/GuiStatsComponent.java @@ -0,0 +1,117 @@ +package net.minecraft.src; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics; +import java.text.DecimalFormat; +import javax.swing.JComponent; +import javax.swing.Timer; +import net.minecraft.server.MinecraftServer; + +public class GuiStatsComponent extends JComponent { + private static final DecimalFormat field_79020_a = new DecimalFormat("########0.000"); + + /** An array containing the columns that make up the memory use graph. */ + private int[] memoryUse = new int[256]; + + /** + * Counts the number of updates. Used as the index into the memoryUse array to + * display the latest value. + */ + private int updateCounter = 0; + + /** An array containing the strings displayed in this stats component. */ + private String[] displayStrings = new String[11]; + private final MinecraftServer field_79017_e; + + public GuiStatsComponent(MinecraftServer par1MinecraftServer) { + this.field_79017_e = par1MinecraftServer; + this.setPreferredSize(new Dimension(456, 246)); + this.setMinimumSize(new Dimension(456, 246)); + this.setMaximumSize(new Dimension(456, 246)); + (new Timer(500, new GuiStatsListener(this))).start(); + this.setBackground(Color.BLACK); + } + + /** + * Updates the stat values and calls paint to redraw the component. + */ + private void updateStats() { + long var1 = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory(); + System.gc(); + this.displayStrings[0] = "Memory use: " + var1 / 1024L / 1024L + " mb (" + + Runtime.getRuntime().freeMemory() * 100L / Runtime.getRuntime().maxMemory() + "% free)"; + this.displayStrings[1] = "Threads: " + TcpConnection.field_74471_a.get() + " + " + + TcpConnection.field_74469_b.get(); + this.displayStrings[2] = "Avg tick: " + + field_79020_a.format(this.calcArrayAverage(this.field_79017_e.tickTimeArray) * 1.0E-6D) + " ms"; + this.displayStrings[3] = "Avg sent: " + (int) this.calcArrayAverage(this.field_79017_e.sentPacketCountArray) + + ", Avg size: " + (int) this.calcArrayAverage(this.field_79017_e.sentPacketSizeArray); + this.displayStrings[4] = "Avg rec: " + (int) this.calcArrayAverage(this.field_79017_e.receivedPacketCountArray) + + ", Avg size: " + (int) this.calcArrayAverage(this.field_79017_e.receivedPacketSizeArray); + + if (this.field_79017_e.worldServers != null) { + for (int var3 = 0; var3 < this.field_79017_e.worldServers.length; ++var3) { + this.displayStrings[5 + var3] = "Lvl " + var3 + " tick: " + + field_79020_a.format( + this.calcArrayAverage(this.field_79017_e.timeOfLastDimensionTick[var3]) * 1.0E-6D) + + " ms"; + + if (this.field_79017_e.worldServers[var3] != null + && this.field_79017_e.worldServers[var3].theChunkProviderServer != null) { + this.displayStrings[5 + var3] = this.displayStrings[5 + var3] + ", " + + this.field_79017_e.worldServers[var3].theChunkProviderServer.makeString(); + this.displayStrings[5 + var3] = this.displayStrings[5 + var3] + ", Vec3: " + + this.field_79017_e.worldServers[var3].getWorldVec3Pool().func_82590_d() + " / " + + this.field_79017_e.worldServers[var3].getWorldVec3Pool().getPoolSize(); + } + } + } + + this.memoryUse[this.updateCounter++ + & 255] = (int) (this.calcArrayAverage(this.field_79017_e.sentPacketSizeArray) * 100.0D / 12500.0D); + this.repaint(); + } + + /** + * Calculates the avarage value of the given long array. + */ + private double calcArrayAverage(long[] par1ArrayOfLong) { + long var2 = 0L; + + for (int var4 = 0; var4 < par1ArrayOfLong.length; ++var4) { + var2 += par1ArrayOfLong[var4]; + } + + return (double) var2 / (double) par1ArrayOfLong.length; + } + + public void paint(Graphics par1Graphics) { + par1Graphics.setColor(new Color(16777215)); + par1Graphics.fillRect(0, 0, 456, 246); + int var2; + + for (var2 = 0; var2 < 256; ++var2) { + int var3 = this.memoryUse[var2 + this.updateCounter & 255]; + par1Graphics.setColor(new Color(var3 + 28 << 16)); + par1Graphics.fillRect(var2, 100 - var3, 1, var3); + } + + par1Graphics.setColor(Color.BLACK); + + for (var2 = 0; var2 < this.displayStrings.length; ++var2) { + String var4 = this.displayStrings[var2]; + + if (var4 != null) { + par1Graphics.drawString(var4, 32, 116 + var2 * 16); + } + } + } + + /** + * Public static accessor to call updateStats. + */ + static void update(GuiStatsComponent par0GuiStatsComponent) { + par0GuiStatsComponent.updateStats(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/GuiStatsListener.java b/sp-server/src/main/java/net/minecraft/src/GuiStatsListener.java new file mode 100644 index 0000000..ed322d9 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/GuiStatsListener.java @@ -0,0 +1,16 @@ +package net.minecraft.src; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +class GuiStatsListener implements ActionListener { + final GuiStatsComponent statsComponent; + + GuiStatsListener(GuiStatsComponent par1GuiStatsComponent) { + this.statsComponent = par1GuiStatsComponent; + } + + public void actionPerformed(ActionEvent par1ActionEvent) { + GuiStatsComponent.update(this.statsComponent); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/Hopper.java b/sp-server/src/main/java/net/minecraft/src/Hopper.java new file mode 100644 index 0000000..c4ac379 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/Hopper.java @@ -0,0 +1,23 @@ +package net.minecraft.src; + +public interface Hopper extends IInventory { + /** + * Returns the worldObj for this tileEntity. + */ + World getWorldObj(); + + /** + * Gets the world X position for this hopper entity. + */ + double getXPos(); + + /** + * Gets the world Y position for this hopper entity. + */ + double getYPos(); + + /** + * Gets the world Z position for this hopper entity. + */ + double getZPos(); +} diff --git a/sp-server/src/main/java/net/minecraft/src/HttpUtil.java b/sp-server/src/main/java/net/minecraft/src/HttpUtil.java new file mode 100644 index 0000000..c4e2dbe --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/HttpUtil.java @@ -0,0 +1,98 @@ +package net.minecraft.src; + +import java.io.BufferedReader; +import java.io.DataOutputStream; +import java.io.InputStreamReader; +import java.io.UnsupportedEncodingException; +import java.net.HttpURLConnection; +import java.net.URL; +import java.net.URLEncoder; +import java.util.Iterator; +import java.util.Map; +import java.util.Map.Entry; +import java.util.logging.Level; +import java.util.logging.Logger; + +public class HttpUtil { + /** + * Builds an encoded HTTP POST content string from a string map + */ + public static String buildPostString(Map par0Map) { + StringBuilder var1 = new StringBuilder(); + Iterator var2 = par0Map.entrySet().iterator(); + + while (var2.hasNext()) { + Entry var3 = (Entry) var2.next(); + + if (var1.length() > 0) { + var1.append('&'); + } + + try { + var1.append(URLEncoder.encode((String) var3.getKey(), "UTF-8")); + } catch (UnsupportedEncodingException var6) { + var6.printStackTrace(); + } + + if (var3.getValue() != null) { + var1.append('='); + + try { + var1.append(URLEncoder.encode(var3.getValue().toString(), "UTF-8")); + } catch (UnsupportedEncodingException var5) { + var5.printStackTrace(); + } + } + } + + return var1.toString(); + } + + /** + * Sends a HTTP POST request to the given URL with data from a map + */ + public static String sendPost(ILogAgent par0ILogAgent, URL par1URL, Map par2Map, boolean par3) { + return sendPost(par0ILogAgent, par1URL, buildPostString(par2Map), par3); + } + + /** + * Sends a HTTP POST request to the given URL with data from a string + */ + public static String sendPost(ILogAgent par0ILogAgent, URL par1URL, String par2Str, boolean par3) { + try { + HttpURLConnection var4 = (HttpURLConnection) par1URL.openConnection(); + var4.setRequestMethod("POST"); + var4.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); + var4.setRequestProperty("Content-Length", "" + par2Str.getBytes().length); + var4.setRequestProperty("Content-Language", "en-US"); + var4.setUseCaches(false); + var4.setDoInput(true); + var4.setDoOutput(true); + DataOutputStream var5 = new DataOutputStream(var4.getOutputStream()); + var5.writeBytes(par2Str); + var5.flush(); + var5.close(); + BufferedReader var6 = new BufferedReader(new InputStreamReader(var4.getInputStream())); + StringBuffer var8 = new StringBuffer(); + String var7; + + while ((var7 = var6.readLine()) != null) { + var8.append(var7); + var8.append('\r'); + } + + var6.close(); + return var8.toString(); + } catch (Exception var9) { + if (!par3) { + if (par0ILogAgent != null) { + par0ILogAgent.logSevereException("Could not post to " + par1URL, var9); + } else { + Logger.getAnonymousLogger().log(Level.SEVERE, "Could not post to " + par1URL, var9); + } + } + + return ""; + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/IAdminCommand.java b/sp-server/src/main/java/net/minecraft/src/IAdminCommand.java new file mode 100644 index 0000000..94465e5 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/IAdminCommand.java @@ -0,0 +1,10 @@ +package net.minecraft.src; + +public interface IAdminCommand { + /** + * Sends a message to the admins of the server from a given CommandSender with + * the given resource string and given extra srings. If the int par2 is even or + * zero, the original sender is also notified. + */ + void notifyAdmins(ICommandSender var1, int var2, String var3, Object... var4); +} diff --git a/sp-server/src/main/java/net/minecraft/src/IAnimals.java b/sp-server/src/main/java/net/minecraft/src/IAnimals.java new file mode 100644 index 0000000..61de5b0 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/IAnimals.java @@ -0,0 +1,4 @@ +package net.minecraft.src; + +public interface IAnimals { +} diff --git a/sp-server/src/main/java/net/minecraft/src/IBehaviorDispenseItem.java b/sp-server/src/main/java/net/minecraft/src/IBehaviorDispenseItem.java new file mode 100644 index 0000000..fe66e91 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/IBehaviorDispenseItem.java @@ -0,0 +1,10 @@ +package net.minecraft.src; + +public interface IBehaviorDispenseItem { + IBehaviorDispenseItem itemDispenseBehaviorProvider = new BehaviorDispenseItemProvider(); + + /** + * Dispenses the specified ItemStack from a dispenser. + */ + ItemStack dispense(IBlockSource var1, ItemStack var2); +} diff --git a/sp-server/src/main/java/net/minecraft/src/IBlockAccess.java b/sp-server/src/main/java/net/minecraft/src/IBlockAccess.java new file mode 100644 index 0000000..72a764b --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/IBlockAccess.java @@ -0,0 +1,40 @@ +package net.minecraft.src; + +public interface IBlockAccess { + /** + * Returns the block ID at coords x,y,z + */ + int getBlockId(int var1, int var2, int var3); + + /** + * Returns the TileEntity associated with a given block in X,Y,Z coordinates, or + * null if no TileEntity exists + */ + TileEntity getBlockTileEntity(int var1, int var2, int var3); + + /** + * Returns the block metadata at coords x,y,z + */ + int getBlockMetadata(int var1, int var2, int var3); + + /** + * Returns the block's material. + */ + Material getBlockMaterial(int var1, int var2, int var3); + + /** + * Returns true if the block at the specified coordinates is an opaque cube. + * Args: x, y, z + */ + boolean isBlockNormalCube(int var1, int var2, int var3); + + /** + * Return the Vec3Pool object for this world. + */ + Vec3Pool getWorldVec3Pool(); + + /** + * Is this block powering in the specified direction Args: x, y, z, direction + */ + int isBlockProvidingPowerTo(int var1, int var2, int var3, int var4); +} diff --git a/sp-server/src/main/java/net/minecraft/src/IBlockSource.java b/sp-server/src/main/java/net/minecraft/src/IBlockSource.java new file mode 100644 index 0000000..40e788d --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/IBlockSource.java @@ -0,0 +1,19 @@ +package net.minecraft.src; + +public interface IBlockSource extends ILocatableSource { + double getX(); + + double getY(); + + double getZ(); + + int getXInt(); + + int getYInt(); + + int getZInt(); + + int getBlockMetadata(); + + TileEntity getBlockTileEntity(); +} diff --git a/sp-server/src/main/java/net/minecraft/src/IChunkLoader.java b/sp-server/src/main/java/net/minecraft/src/IChunkLoader.java new file mode 100644 index 0000000..b788f32 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/IChunkLoader.java @@ -0,0 +1,29 @@ +package net.minecraft.src; + +import java.io.IOException; + +public interface IChunkLoader { + /** + * Loads the specified(XZ) chunk into the specified world. + */ + Chunk loadChunk(World var1, int var2, int var3) throws IOException; + + void saveChunk(World var1, Chunk var2) throws MinecraftException, IOException; + + /** + * Save extra data associated with this Chunk not normally saved during + * autosave, only during chunk unload. Currently unused. + */ + void saveExtraChunkData(World var1, Chunk var2); + + /** + * Called every World.tick() + */ + void chunkTick(); + + /** + * Save extra data not associated with any Chunk. Not saved during autosave, + * only during world unload. Currently unused. + */ + void saveExtraData(); +} diff --git a/sp-server/src/main/java/net/minecraft/src/IChunkProvider.java b/sp-server/src/main/java/net/minecraft/src/IChunkProvider.java new file mode 100644 index 0000000..2c8746a --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/IChunkProvider.java @@ -0,0 +1,67 @@ +package net.minecraft.src; + +import java.util.List; + +public interface IChunkProvider { + /** + * Checks to see if a chunk exists at x, y + */ + boolean chunkExists(int var1, int var2); + + /** + * Will return back a chunk, if it doesn't exist and its not a MP client it will + * generates all the blocks for the specified chunk from the map seed and chunk + * seed + */ + Chunk provideChunk(int var1, int var2); + + /** + * loads or generates the chunk at the chunk location specified + */ + Chunk loadChunk(int var1, int var2); + + /** + * Populates chunk with ores etc etc + */ + void populate(IChunkProvider var1, int var2, int var3); + + /** + * Two modes of operation: if passed true, save all Chunks in one go. If passed + * false, save up to two chunks. Return true if all chunks have been saved. + */ + boolean saveChunks(boolean var1, IProgressUpdate var2); + + /** + * Unloads chunks that are marked to be unloaded. This is not guaranteed to + * unload every such chunk. + */ + boolean unloadQueuedChunks(); + + /** + * Returns if the IChunkProvider supports saving. + */ + boolean canSave(); + + /** + * Converts the instance data to a readable string. + */ + String makeString(); + + /** + * Returns a list of creatures of the specified type that can spawn at the given + * location. + */ + List getPossibleCreatures(EnumCreatureType var1, int var2, int var3, int var4); + + /** + * Returns the location of the closest structure of the specified type. If not + * found returns null. + */ + ChunkPosition findClosestStructure(World var1, String var2, int var3, int var4, int var5); + + int getLoadedChunkCount(); + + void recreateStructures(int var1, int var2); + + void func_104112_b(); +} diff --git a/sp-server/src/main/java/net/minecraft/src/ICommand.java b/sp-server/src/main/java/net/minecraft/src/ICommand.java new file mode 100644 index 0000000..c990bb2 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ICommand.java @@ -0,0 +1,29 @@ +package net.minecraft.src; + +import java.util.List; + +public interface ICommand extends Comparable { + String getCommandName(); + + String getCommandUsage(ICommandSender var1); + + List getCommandAliases(); + + void processCommand(ICommandSender var1, String[] var2); + + /** + * Returns true if the given command sender is allowed to use this command. + */ + boolean canCommandSenderUseCommand(ICommandSender var1); + + /** + * Adds the strings available in this command to the given list of tab + * completion options. + */ + List addTabCompletionOptions(ICommandSender var1, String[] var2); + + /** + * Return whether the specified command parameter index is a username parameter. + */ + boolean isUsernameIndex(String[] var1, int var2); +} diff --git a/sp-server/src/main/java/net/minecraft/src/ICommandManager.java b/sp-server/src/main/java/net/minecraft/src/ICommandManager.java new file mode 100644 index 0000000..1b3bf92 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ICommandManager.java @@ -0,0 +1,25 @@ +package net.minecraft.src; + +import java.util.List; +import java.util.Map; + +public interface ICommandManager { + int executeCommand(ICommandSender var1, String var2); + + /** + * Performs a "begins with" string match on each token in par2. Only returns + * commands that par1 can use. + */ + List getPossibleCommands(ICommandSender var1, String var2); + + /** + * returns all commands that the commandSender can use + */ + List getPossibleCommands(ICommandSender var1); + + /** + * returns a map of string to commads. All commands are returned, not just ones + * which someone has permission to use. + */ + Map getCommands(); +} diff --git a/sp-server/src/main/java/net/minecraft/src/ICommandSender.java b/sp-server/src/main/java/net/minecraft/src/ICommandSender.java new file mode 100644 index 0000000..b5c3162 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ICommandSender.java @@ -0,0 +1,25 @@ +package net.minecraft.src; + +public interface ICommandSender { + /** + * Gets the name of this command sender (usually username, but possibly "Rcon") + */ + String getCommandSenderName(); + + void sendChatToPlayer(String var1); + + /** + * Returns true if the command sender is allowed to use the given command. + */ + boolean canCommandSenderUseCommand(int var1, String var2); + + /** + * Translates and formats the given string key with the given arguments. + */ + String translateString(String var1, Object... var2); + + /** + * Return the position for this command sender. + */ + ChunkCoordinates getCommandSenderPosition(); +} diff --git a/sp-server/src/main/java/net/minecraft/src/ICrafting.java b/sp-server/src/main/java/net/minecraft/src/ICrafting.java new file mode 100644 index 0000000..3b8e760 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ICrafting.java @@ -0,0 +1,25 @@ +package net.minecraft.src; + +import java.util.List; + +public interface ICrafting { + /** + * update the crafting window inventory with the items in the list + */ + void updateCraftingInventory(Container var1, List var2); + + /** + * Sends the contents of an inventory slot to the client-side Container. This + * doesn't have to match the actual contents of that slot. Args: Container, slot + * number, slot contents + */ + void sendSlotContents(Container var1, int var2, ItemStack var3); + + /** + * Sends two ints to the client-side Container. Used for furnace burning time, + * smelting progress, brewing progress, and enchanting level. Normally the first + * int identifies which variable to update, and the second contains the new + * value. Both are truncated to shorts in non-local SMP. + */ + void sendProgressBarUpdate(Container var1, int var2, int var3); +} diff --git a/sp-server/src/main/java/net/minecraft/src/IEnchantmentModifier.java b/sp-server/src/main/java/net/minecraft/src/IEnchantmentModifier.java new file mode 100644 index 0000000..7c55e8e --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/IEnchantmentModifier.java @@ -0,0 +1,9 @@ +package net.minecraft.src; + +interface IEnchantmentModifier { + /** + * Generic method use to calculate modifiers of offensive or defensive + * enchantment values. + */ + void calculateModifier(Enchantment var1, int var2); +} diff --git a/sp-server/src/main/java/net/minecraft/src/IEntityMultiPart.java b/sp-server/src/main/java/net/minecraft/src/IEntityMultiPart.java new file mode 100644 index 0000000..236f19f --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/IEntityMultiPart.java @@ -0,0 +1,7 @@ +package net.minecraft.src; + +public interface IEntityMultiPart { + World func_82194_d(); + + boolean attackEntityFromPart(EntityDragonPart var1, DamageSource var2, int var3); +} diff --git a/sp-server/src/main/java/net/minecraft/src/IEntitySelector.java b/sp-server/src/main/java/net/minecraft/src/IEntitySelector.java new file mode 100644 index 0000000..1811cc6 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/IEntitySelector.java @@ -0,0 +1,11 @@ +package net.minecraft.src; + +public interface IEntitySelector { + IEntitySelector selectAnything = new EntitySelectorAlive(); + IEntitySelector selectInventories = new EntitySelectorInventory(); + + /** + * Return whether the specified entity is applicable to this filter. + */ + boolean isEntityApplicable(Entity var1); +} diff --git a/sp-server/src/main/java/net/minecraft/src/IInvBasic.java b/sp-server/src/main/java/net/minecraft/src/IInvBasic.java new file mode 100644 index 0000000..7453ddd --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/IInvBasic.java @@ -0,0 +1,9 @@ +package net.minecraft.src; + +public interface IInvBasic { + /** + * Called by InventoryBasic.onInventoryChanged() on a array that is never + * filled. + */ + void onInventoryChanged(InventoryBasic var1); +} diff --git a/sp-server/src/main/java/net/minecraft/src/IInventory.java b/sp-server/src/main/java/net/minecraft/src/IInventory.java new file mode 100644 index 0000000..a044af9 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/IInventory.java @@ -0,0 +1,70 @@ +package net.minecraft.src; + +public interface IInventory { + /** + * Returns the number of slots in the inventory. + */ + int getSizeInventory(); + + /** + * Returns the stack in slot i + */ + ItemStack getStackInSlot(int var1); + + /** + * Removes from an inventory slot (first arg) up to a specified number (second + * arg) of items and returns them in a new stack. + */ + ItemStack decrStackSize(int var1, int var2); + + /** + * When some containers are closed they call this on each slot, then drop + * whatever it returns as an EntityItem - like when you close a workbench GUI. + */ + ItemStack getStackInSlotOnClosing(int var1); + + /** + * Sets the given item stack to the specified slot in the inventory (can be + * crafting or armor sections). + */ + void setInventorySlotContents(int var1, ItemStack var2); + + /** + * Returns the name of the inventory. + */ + String getInvName(); + + /** + * If this returns false, the inventory name will be used as an unlocalized + * name, and translated into the player's language. Otherwise it will be used + * directly. + */ + boolean isInvNameLocalized(); + + /** + * Returns the maximum stack size for a inventory slot. Seems to always be 64, + * possibly will be extended. *Isn't this more of a set than a get?* + */ + int getInventoryStackLimit(); + + /** + * Called when an the contents of an Inventory change, usually + */ + void onInventoryChanged(); + + /** + * Do not make give this method the name canInteractWith because it clashes with + * Container + */ + boolean isUseableByPlayer(EntityPlayer var1); + + void openChest(); + + void closeChest(); + + /** + * Returns true if automation is allowed to insert the given stack (ignoring + * stack size) into the given slot. + */ + boolean isStackValidForSlot(int var1, ItemStack var2); +} diff --git a/sp-server/src/main/java/net/minecraft/src/ILocatableSource.java b/sp-server/src/main/java/net/minecraft/src/ILocatableSource.java new file mode 100644 index 0000000..2f081b1 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ILocatableSource.java @@ -0,0 +1,4 @@ +package net.minecraft.src; + +public interface ILocatableSource extends ILocation { +} diff --git a/sp-server/src/main/java/net/minecraft/src/ILocation.java b/sp-server/src/main/java/net/minecraft/src/ILocation.java new file mode 100644 index 0000000..fba832c --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ILocation.java @@ -0,0 +1,5 @@ +package net.minecraft.src; + +public interface ILocation extends IPosition { + World getWorld(); +} diff --git a/sp-server/src/main/java/net/minecraft/src/ILogAgent.java b/sp-server/src/main/java/net/minecraft/src/ILogAgent.java new file mode 100644 index 0000000..00dc39f --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ILogAgent.java @@ -0,0 +1,19 @@ +package net.minecraft.src; + +import java.util.logging.Logger; + +public interface ILogAgent { + Logger getServerLogger(); + + void func_98233_a(String var1); + + void func_98236_b(String var1); + + void logWarningFormatted(String var1, Object... var2); + + void logWarningException(String var1, Throwable var2); + + void logSevere(String var1); + + void logSevereException(String var1, Throwable var2); +} diff --git a/sp-server/src/main/java/net/minecraft/src/IMerchant.java b/sp-server/src/main/java/net/minecraft/src/IMerchant.java new file mode 100644 index 0000000..efa4512 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/IMerchant.java @@ -0,0 +1,11 @@ +package net.minecraft.src; + +public interface IMerchant { + void setCustomer(EntityPlayer var1); + + EntityPlayer getCustomer(); + + MerchantRecipeList getRecipes(EntityPlayer var1); + + void useRecipe(MerchantRecipe var1); +} diff --git a/sp-server/src/main/java/net/minecraft/src/IMob.java b/sp-server/src/main/java/net/minecraft/src/IMob.java new file mode 100644 index 0000000..db2bc52 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/IMob.java @@ -0,0 +1,6 @@ +package net.minecraft.src; + +public interface IMob extends IAnimals { + /** Entity selector for IMob types. */ + IEntitySelector mobSelector = new FilterIMob(); +} diff --git a/sp-server/src/main/java/net/minecraft/src/INetworkManager.java b/sp-server/src/main/java/net/minecraft/src/INetworkManager.java new file mode 100644 index 0000000..cb53423 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/INetworkManager.java @@ -0,0 +1,47 @@ +package net.minecraft.src; + +import java.net.SocketAddress; + +public interface INetworkManager { + /** + * Sets the NetHandler for this NetworkManager. Server-only. + */ + void setNetHandler(NetHandler var1); + + /** + * Adds the packet to the correct send queue (chunk data packets go to a + * separate queue). + */ + void addToSendQueue(Packet var1); + + /** + * Wakes reader and writer threads + */ + void wakeThreads(); + + /** + * Checks timeouts and processes all pending read packets. + */ + void processReadPackets(); + + /** + * Returns the socket address of the remote side. Server-only. + */ + SocketAddress getRemoteAddress(); + + /** + * Shuts down the server. (Only actually used on the server) + */ + void serverShutdown(); + + /** + * Returns the number of chunk data packets waiting to be sent. + */ + int getNumChunkDataPackets(); + + /** + * Shuts down the network with the specified reason. Closes all streams and + * sockets, spawns NetworkMasterThread to stop reading and writing threads. + */ + void networkShutdown(String var1, Object... var2); +} diff --git a/sp-server/src/main/java/net/minecraft/src/INpc.java b/sp-server/src/main/java/net/minecraft/src/INpc.java new file mode 100644 index 0000000..224d1c1 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/INpc.java @@ -0,0 +1,4 @@ +package net.minecraft.src; + +public interface INpc extends IAnimals { +} diff --git a/sp-server/src/main/java/net/minecraft/src/IPlayerFileData.java b/sp-server/src/main/java/net/minecraft/src/IPlayerFileData.java new file mode 100644 index 0000000..251e310 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/IPlayerFileData.java @@ -0,0 +1,18 @@ +package net.minecraft.src; + +public interface IPlayerFileData { + /** + * Writes the player data to disk from the specified PlayerEntityMP. + */ + void writePlayerData(EntityPlayer var1); + + /** + * Reads the player data from disk into the specified PlayerEntityMP. + */ + NBTTagCompound readPlayerData(EntityPlayer var1); + + /** + * Returns an array of usernames for which player.dat exists for. + */ + String[] getAvailablePlayerDat(); +} diff --git a/sp-server/src/main/java/net/minecraft/src/IPlayerUsage.java b/sp-server/src/main/java/net/minecraft/src/IPlayerUsage.java new file mode 100644 index 0000000..112a788 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/IPlayerUsage.java @@ -0,0 +1,14 @@ +package net.minecraft.src; + +public interface IPlayerUsage { + void addServerStatsToSnooper(PlayerUsageSnooper var1); + + void addServerTypeToSnooper(PlayerUsageSnooper var1); + + /** + * Returns whether snooping is enabled or not. + */ + boolean isSnooperEnabled(); + + ILogAgent getLogAgent(); +} diff --git a/sp-server/src/main/java/net/minecraft/src/IPosition.java b/sp-server/src/main/java/net/minecraft/src/IPosition.java new file mode 100644 index 0000000..3da626c --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/IPosition.java @@ -0,0 +1,9 @@ +package net.minecraft.src; + +public interface IPosition { + double getX(); + + double getY(); + + double getZ(); +} diff --git a/sp-server/src/main/java/net/minecraft/src/IProgressUpdate.java b/sp-server/src/main/java/net/minecraft/src/IProgressUpdate.java new file mode 100644 index 0000000..9965a24 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/IProgressUpdate.java @@ -0,0 +1,20 @@ +package net.minecraft.src; + +public interface IProgressUpdate { + /** + * Shows the 'Saving level' string. + */ + void displaySavingString(String var1); + + /** + * Displays a string on the loading screen supposed to indicate what is being + * done currently. + */ + void displayLoadingString(String var1); + + /** + * Updates the progress bar on the loading screen to the specified amount. Args: + * loadProgress + */ + void setLoadingProgress(int var1); +} diff --git a/sp-server/src/main/java/net/minecraft/src/IProjectile.java b/sp-server/src/main/java/net/minecraft/src/IProjectile.java new file mode 100644 index 0000000..9084d7b --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/IProjectile.java @@ -0,0 +1,9 @@ +package net.minecraft.src; + +public interface IProjectile { + /** + * Similar to setArrowHeading, it's point the throwable entity to a x, y, z + * direction. + */ + void setThrowableHeading(double var1, double var3, double var5, float var7, float var8); +} diff --git a/sp-server/src/main/java/net/minecraft/src/IRangedAttackMob.java b/sp-server/src/main/java/net/minecraft/src/IRangedAttackMob.java new file mode 100644 index 0000000..728aa14 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/IRangedAttackMob.java @@ -0,0 +1,8 @@ +package net.minecraft.src; + +public interface IRangedAttackMob { + /** + * Attack the specified entity using a ranged attack. + */ + void attackEntityWithRangedAttack(EntityLiving var1, float var2); +} diff --git a/sp-server/src/main/java/net/minecraft/src/IRecipe.java b/sp-server/src/main/java/net/minecraft/src/IRecipe.java new file mode 100644 index 0000000..8f13dc9 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/IRecipe.java @@ -0,0 +1,20 @@ +package net.minecraft.src; + +public interface IRecipe { + /** + * Used to check if a recipe matches current crafting inventory + */ + boolean matches(InventoryCrafting var1, World var2); + + /** + * Returns an Item that is the result of this recipe + */ + ItemStack getCraftingResult(InventoryCrafting var1); + + /** + * Returns the size of the recipe area + */ + int getRecipeSize(); + + ItemStack getRecipeOutput(); +} diff --git a/sp-server/src/main/java/net/minecraft/src/IRegistry.java b/sp-server/src/main/java/net/minecraft/src/IRegistry.java new file mode 100644 index 0000000..da89eb8 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/IRegistry.java @@ -0,0 +1,10 @@ +package net.minecraft.src; + +public interface IRegistry { + Object func_82594_a(Object var1); + + /** + * Register an object on this registry. + */ + void putObject(Object var1, Object var2); +} diff --git a/sp-server/src/main/java/net/minecraft/src/ISaveFormat.java b/sp-server/src/main/java/net/minecraft/src/ISaveFormat.java new file mode 100644 index 0000000..daba497 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ISaveFormat.java @@ -0,0 +1,27 @@ +package net.minecraft.src; + +public interface ISaveFormat { + /** + * Returns back a loader for the specified save directory + */ + ISaveHandler getSaveLoader(String var1, boolean var2); + + void flushCache(); + + /** + * @args: Takes one argument - the name of the directory of the world to + * delete. @desc: Delete the world by deleting the associated directory + * recursively. + */ + boolean deleteWorldDirectory(String var1); + + /** + * gets if the map is old chunk saving (true) or McRegion (false) + */ + boolean isOldMapFormat(String var1); + + /** + * converts the map to mcRegion + */ + boolean convertMapFormat(String var1, IProgressUpdate var2); +} diff --git a/sp-server/src/main/java/net/minecraft/src/ISaveHandler.java b/sp-server/src/main/java/net/minecraft/src/ISaveHandler.java new file mode 100644 index 0000000..1e62d7d --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ISaveHandler.java @@ -0,0 +1,47 @@ +package net.minecraft.src; + +import java.io.File; + +public interface ISaveHandler { + /** + * Loads and returns the world info + */ + WorldInfo loadWorldInfo(); + + /** + * Checks the session lock to prevent save collisions + */ + void checkSessionLock() throws MinecraftException; + + /** + * initializes and returns the chunk loader for the specified world provider + */ + IChunkLoader getChunkLoader(WorldProvider var1); + + /** + * Saves the given World Info with the given NBTTagCompound as the Player. + */ + void saveWorldInfoWithPlayer(WorldInfo var1, NBTTagCompound var2); + + /** + * used to update level.dat from old format to MCRegion format + */ + void saveWorldInfo(WorldInfo var1); + + IPlayerFileData getPlayerNBTManager(); + + /** + * Called to flush all changes to disk, waiting for them to complete. + */ + void flush(); + + /** + * Gets the file location of the given map + */ + File getMapFileFromName(String var1); + + /** + * Returns the name of the directory where world information is saved. + */ + String getWorldDirectoryName(); +} diff --git a/sp-server/src/main/java/net/minecraft/src/IServer.java b/sp-server/src/main/java/net/minecraft/src/IServer.java new file mode 100644 index 0000000..6b9ffef --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/IServer.java @@ -0,0 +1,102 @@ +package net.minecraft.src; + +public interface IServer { + /** + * Gets an integer property. If it does not exist, set it to the specified + * value. + */ + int getIntProperty(String var1, int var2); + + /** + * Gets a string property. If it does not exist, set it to the specified value. + */ + String getStringProperty(String var1, String var2); + + /** + * Saves an Object with the given property name. + */ + void setProperty(String var1, Object var2); + + /** + * Saves all of the server properties to the properties file. + */ + void saveProperties(); + + /** + * Returns the filename where server properties are stored + */ + String getSettingsFilename(); + + /** + * Returns the server's hostname. + */ + String getHostname(); + + /** + * Never used, but "getServerPort" is already taken. + */ + int getPort(); + + /** + * Returns the server message of the day + */ + String getMotd(); + + /** + * Returns the server's Minecraft version as string. + */ + String getMinecraftVersion(); + + /** + * Returns the number of players currently on the server. + */ + int getCurrentPlayerCount(); + + /** + * Returns the maximum number of players allowed on the server. + */ + int getMaxPlayers(); + + /** + * Returns an array of the usernames of all the connected players. + */ + String[] getAllUsernames(); + + String getFolderName(); + + /** + * Used by RCon's Query in the form of "MajorServerMod 1.2.3: MyPlugin 1.3; + * AnotherPlugin 2.1; AndSoForth 1.0". + */ + String getPlugins(); + + /** + * Handle a command received by an RCon instance + */ + String handleRConCommand(String var1); + + /** + * Returns true if debugging is enabled, false otherwise. + */ + boolean isDebuggingEnabled(); + + /** + * Logs the message with a level of INFO. + */ + void logInfo(String var1); + + /** + * Logs the message with a level of WARN. + */ + void logWarning(String var1); + + /** + * Logs the error message with a level of SEVERE. + */ + void logSevere(String var1); + + /** + * If isDebuggingEnabled(), logs the message with a level of INFO. + */ + void logDebug(String var1); +} diff --git a/sp-server/src/main/java/net/minecraft/src/ISidedInventory.java b/sp-server/src/main/java/net/minecraft/src/ISidedInventory.java new file mode 100644 index 0000000..9cee748 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ISidedInventory.java @@ -0,0 +1,20 @@ +package net.minecraft.src; + +public interface ISidedInventory extends IInventory { + /** + * param side + */ + int[] getSlotsForFace(int var1); + + /** + * Returns true if automation can insert the given item in the given slot from + * the given side. Args: Slot, item, side + */ + boolean canInsertItem(int var1, ItemStack var2, int var3); + + /** + * Returns true if automation can extract the given item in the given slot from + * the given side. Args: Slot, item, side + */ + boolean canExtractItem(int var1, ItemStack var2, int var3); +} diff --git a/sp-server/src/main/java/net/minecraft/src/IStatType.java b/sp-server/src/main/java/net/minecraft/src/IStatType.java new file mode 100644 index 0000000..c2c292f --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/IStatType.java @@ -0,0 +1,4 @@ +package net.minecraft.src; + +public interface IStatType { +} diff --git a/sp-server/src/main/java/net/minecraft/src/IThreadedFileIO.java b/sp-server/src/main/java/net/minecraft/src/IThreadedFileIO.java new file mode 100644 index 0000000..c9583cb --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/IThreadedFileIO.java @@ -0,0 +1,8 @@ +package net.minecraft.src; + +public interface IThreadedFileIO { + /** + * Returns a boolean stating if the write was unsuccessful. + */ + boolean writeNextIO(); +} diff --git a/sp-server/src/main/java/net/minecraft/src/ITileEntityProvider.java b/sp-server/src/main/java/net/minecraft/src/ITileEntityProvider.java new file mode 100644 index 0000000..7d3aba7 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ITileEntityProvider.java @@ -0,0 +1,9 @@ +package net.minecraft.src; + +public interface ITileEntityProvider { + /** + * Returns a new instance of a block's tile entity class. Called on placing the + * block. + */ + TileEntity createNewTileEntity(World var1); +} diff --git a/sp-server/src/main/java/net/minecraft/src/IUpdatePlayerListBox.java b/sp-server/src/main/java/net/minecraft/src/IUpdatePlayerListBox.java new file mode 100644 index 0000000..5075676 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/IUpdatePlayerListBox.java @@ -0,0 +1,8 @@ +package net.minecraft.src; + +public interface IUpdatePlayerListBox { + /** + * Updates the JList with a new model. + */ + void update(); +} diff --git a/sp-server/src/main/java/net/minecraft/src/IWorldAccess.java b/sp-server/src/main/java/net/minecraft/src/IWorldAccess.java new file mode 100644 index 0000000..76c5a91 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/IWorldAccess.java @@ -0,0 +1,71 @@ +package net.minecraft.src; + +public interface IWorldAccess { + /** + * On the client, re-renders the block. On the server, sends the block to the + * client (which will re-render it), including the tile entity description + * packet if applicable. Args: x, y, z + */ + void markBlockForUpdate(int var1, int var2, int var3); + + /** + * On the client, re-renders this block. On the server, does nothing. Used for + * lighting updates. + */ + void markBlockForRenderUpdate(int var1, int var2, int var3); + + /** + * On the client, re-renders all blocks in this range, inclusive. On the server, + * does nothing. Args: min x, min y, min z, max x, max y, max z + */ + void markBlockRangeForRenderUpdate(int var1, int var2, int var3, int var4, int var5, int var6); + + /** + * Plays the specified sound. Arg: soundName, x, y, z, volume, pitch + */ + void playSound(String var1, double var2, double var4, double var6, float var8, float var9); + + /** + * Plays sound to all near players except the player reference given + */ + void playSoundToNearExcept(EntityPlayer var1, String var2, double var3, double var5, double var7, float var9, + float var10); + + /** + * Spawns a particle. Arg: particleType, x, y, z, velX, velY, velZ + */ + void spawnParticle(String var1, double var2, double var4, double var6, double var8, double var10, double var12); + + /** + * Called on all IWorldAccesses when an entity is created or loaded. On client + * worlds, starts downloading any necessary textures. On server worlds, adds the + * entity to the entity tracker. + */ + void onEntityCreate(Entity var1); + + /** + * Called on all IWorldAccesses when an entity is unloaded or destroyed. On + * client worlds, releases any downloaded textures. On server worlds, removes + * the entity from the entity tracker. + */ + void onEntityDestroy(Entity var1); + + /** + * Plays the specified record. Arg: recordName, x, y, z + */ + void playRecord(String var1, int var2, int var3, int var4); + + void broadcastSound(int var1, int var2, int var3, int var4, int var5); + + /** + * Plays a pre-canned sound effect along with potentially auxiliary data-driven + * one-shot behaviour (particles, etc). + */ + void playAuxSFX(EntityPlayer var1, int var2, int var3, int var4, int var5, int var6); + + /** + * Starts (or continues) destroying a block with given ID at the given + * coordinates for the given partially destroyed value + */ + void destroyBlockPartially(int var1, int var2, int var3, int var4, int var5); +} diff --git a/sp-server/src/main/java/net/minecraft/src/Icon.java b/sp-server/src/main/java/net/minecraft/src/Icon.java new file mode 100644 index 0000000..df811e5 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/Icon.java @@ -0,0 +1,4 @@ +package net.minecraft.src; + +public interface Icon { +} diff --git a/sp-server/src/main/java/net/minecraft/src/IntCache.java b/sp-server/src/main/java/net/minecraft/src/IntCache.java new file mode 100644 index 0000000..7cde578 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/IntCache.java @@ -0,0 +1,89 @@ +package net.minecraft.src; + +import java.util.ArrayList; +import java.util.List; + +public class IntCache { + private static int intCacheSize = 256; + + /** + * A list of pre-allocated int[256] arrays that are currently unused and can be + * returned by getIntCache() + */ + private static List freeSmallArrays = new ArrayList(); + + /** + * A list of pre-allocated int[256] arrays that were previously returned by + * getIntCache() and which will not be re- used again until resetIntCache() is + * called. + */ + private static List inUseSmallArrays = new ArrayList(); + + /** + * A list of pre-allocated int[cacheSize] arrays that are currently unused and + * can be returned by getIntCache() + */ + private static List freeLargeArrays = new ArrayList(); + + /** + * A list of pre-allocated int[cacheSize] arrays that were previously returned + * by getIntCache() and which will not be re-used again until resetIntCache() is + * called. + */ + private static List inUseLargeArrays = new ArrayList(); + + public static synchronized int[] getIntCache(int par0) { + int[] var1; + + if (par0 <= 256) { + if (freeSmallArrays.isEmpty()) { + var1 = new int[256]; + inUseSmallArrays.add(var1); + return var1; + } else { + var1 = (int[]) freeSmallArrays.remove(freeSmallArrays.size() - 1); + inUseSmallArrays.add(var1); + return var1; + } + } else if (par0 > intCacheSize) { + intCacheSize = par0; + freeLargeArrays.clear(); + inUseLargeArrays.clear(); + var1 = new int[intCacheSize]; + inUseLargeArrays.add(var1); + return var1; + } else if (freeLargeArrays.isEmpty()) { + var1 = new int[intCacheSize]; + inUseLargeArrays.add(var1); + return var1; + } else { + var1 = (int[]) freeLargeArrays.remove(freeLargeArrays.size() - 1); + inUseLargeArrays.add(var1); + return var1; + } + } + + /** + * Mark all pre-allocated arrays as available for re-use by moving them to the + * appropriate free lists. + */ + public static synchronized void resetIntCache() { + if (!freeLargeArrays.isEmpty()) { + freeLargeArrays.remove(freeLargeArrays.size() - 1); + } + + if (!freeSmallArrays.isEmpty()) { + freeSmallArrays.remove(freeSmallArrays.size() - 1); + } + + freeLargeArrays.addAll(inUseLargeArrays); + freeSmallArrays.addAll(inUseSmallArrays); + inUseLargeArrays.clear(); + inUseSmallArrays.clear(); + } + + public static synchronized String func_85144_b() { + return "cache: " + freeLargeArrays.size() + ", tcache: " + freeSmallArrays.size() + ", allocated: " + + inUseLargeArrays.size() + ", tallocated: " + inUseSmallArrays.size(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/IntHashMap.java b/sp-server/src/main/java/net/minecraft/src/IntHashMap.java new file mode 100644 index 0000000..29bc21c --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/IntHashMap.java @@ -0,0 +1,213 @@ +package net.minecraft.src; + +import java.util.HashSet; +import java.util.Set; + +public class IntHashMap { + /** An array of HashEntries representing the heads of hash slot lists */ + private transient IntHashMapEntry[] slots = new IntHashMapEntry[16]; + + /** The number of items stored in this map */ + private transient int count; + + /** The grow threshold */ + private int threshold = 12; + + /** The scale factor used to determine when to grow the table */ + private final float growFactor = 0.75F; + + /** A serial stamp used to mark changes */ + private transient volatile int versionStamp; + + /** The set of all the keys stored in this MCHash object */ + private Set keySet = new HashSet(); + + /** + * Makes the passed in integer suitable for hashing by a number of shifts + */ + private static int computeHash(int par0) { + par0 ^= par0 >>> 20 ^ par0 >>> 12; + return par0 ^ par0 >>> 7 ^ par0 >>> 4; + } + + /** + * Computes the index of the slot for the hash and slot count passed in. + */ + private static int getSlotIndex(int par0, int par1) { + return par0 & par1 - 1; + } + + /** + * Returns the object associated to a key + */ + public Object lookup(int par1) { + int var2 = computeHash(par1); + + for (IntHashMapEntry var3 = this.slots[getSlotIndex(var2, + this.slots.length)]; var3 != null; var3 = var3.nextEntry) { + if (var3.hashEntry == par1) { + return var3.valueEntry; + } + } + + return null; + } + + /** + * Returns true if this hash table contains the specified item. + */ + public boolean containsItem(int par1) { + return this.lookupEntry(par1) != null; + } + + /** + * Returns the internal entry for a key + */ + final IntHashMapEntry lookupEntry(int par1) { + int var2 = computeHash(par1); + + for (IntHashMapEntry var3 = this.slots[getSlotIndex(var2, + this.slots.length)]; var3 != null; var3 = var3.nextEntry) { + if (var3.hashEntry == par1) { + return var3; + } + } + + return null; + } + + /** + * Adds a key and associated value to this map + */ + public void addKey(int par1, Object par2Obj) { + this.keySet.add(Integer.valueOf(par1)); + int var3 = computeHash(par1); + int var4 = getSlotIndex(var3, this.slots.length); + + for (IntHashMapEntry var5 = this.slots[var4]; var5 != null; var5 = var5.nextEntry) { + if (var5.hashEntry == par1) { + var5.valueEntry = par2Obj; + return; + } + } + + ++this.versionStamp; + this.insert(var3, par1, par2Obj, var4); + } + + /** + * Increases the number of hash slots + */ + private void grow(int par1) { + IntHashMapEntry[] var2 = this.slots; + int var3 = var2.length; + + if (var3 == 1073741824) { + this.threshold = Integer.MAX_VALUE; + } else { + IntHashMapEntry[] var4 = new IntHashMapEntry[par1]; + this.copyTo(var4); + this.slots = var4; + this.threshold = (int) ((float) par1 * this.growFactor); + } + } + + /** + * Copies the hash slots to a new array + */ + private void copyTo(IntHashMapEntry[] par1ArrayOfIntHashMapEntry) { + IntHashMapEntry[] var2 = this.slots; + int var3 = par1ArrayOfIntHashMapEntry.length; + + for (int var4 = 0; var4 < var2.length; ++var4) { + IntHashMapEntry var5 = var2[var4]; + + if (var5 != null) { + var2[var4] = null; + IntHashMapEntry var6; + + do { + var6 = var5.nextEntry; + int var7 = getSlotIndex(var5.slotHash, var3); + var5.nextEntry = par1ArrayOfIntHashMapEntry[var7]; + par1ArrayOfIntHashMapEntry[var7] = var5; + var5 = var6; + } while (var6 != null); + } + } + } + + /** + * Removes the specified object from the map and returns it + */ + public Object removeObject(int par1) { + this.keySet.remove(Integer.valueOf(par1)); + IntHashMapEntry var2 = this.removeEntry(par1); + return var2 == null ? null : var2.valueEntry; + } + + /** + * Removes the specified entry from the map and returns it + */ + final IntHashMapEntry removeEntry(int par1) { + int var2 = computeHash(par1); + int var3 = getSlotIndex(var2, this.slots.length); + IntHashMapEntry var4 = this.slots[var3]; + IntHashMapEntry var5; + IntHashMapEntry var6; + + for (var5 = var4; var5 != null; var5 = var6) { + var6 = var5.nextEntry; + + if (var5.hashEntry == par1) { + ++this.versionStamp; + --this.count; + + if (var4 == var5) { + this.slots[var3] = var6; + } else { + var4.nextEntry = var6; + } + + return var5; + } + + var4 = var5; + } + + return var5; + } + + /** + * Removes all entries from the map + */ + public void clearMap() { + ++this.versionStamp; + IntHashMapEntry[] var1 = this.slots; + + for (int var2 = 0; var2 < var1.length; ++var2) { + var1[var2] = null; + } + + this.count = 0; + } + + /** + * Adds an object to a slot + */ + private void insert(int par1, int par2, Object par3Obj, int par4) { + IntHashMapEntry var5 = this.slots[par4]; + this.slots[par4] = new IntHashMapEntry(par1, par2, par3Obj, var5); + + if (this.count++ >= this.threshold) { + this.grow(2 * this.slots.length); + } + } + + /** + * Returns the hash code for a key + */ + static int getHash(int par0) { + return computeHash(par0); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/IntHashMapEntry.java b/sp-server/src/main/java/net/minecraft/src/IntHashMapEntry.java new file mode 100644 index 0000000..d9129e4 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/IntHashMapEntry.java @@ -0,0 +1,65 @@ +package net.minecraft.src; + +class IntHashMapEntry { + /** The hash code of this entry */ + final int hashEntry; + + /** The object stored in this entry */ + Object valueEntry; + + /** The next entry in this slot */ + IntHashMapEntry nextEntry; + + /** The id of the hash slot computed from the hash */ + final int slotHash; + + IntHashMapEntry(int par1, int par2, Object par3Obj, IntHashMapEntry par4IntHashMapEntry) { + this.valueEntry = par3Obj; + this.nextEntry = par4IntHashMapEntry; + this.hashEntry = par2; + this.slotHash = par1; + } + + /** + * Returns the hash code for this entry + */ + public final int getHash() { + return this.hashEntry; + } + + /** + * Returns the object stored in this entry + */ + public final Object getValue() { + return this.valueEntry; + } + + public final boolean equals(Object par1Obj) { + if (!(par1Obj instanceof IntHashMapEntry)) { + return false; + } else { + IntHashMapEntry var2 = (IntHashMapEntry) par1Obj; + Integer var3 = Integer.valueOf(this.getHash()); + Integer var4 = Integer.valueOf(var2.getHash()); + + if (var3 == var4 || var3 != null && var3.equals(var4)) { + Object var5 = this.getValue(); + Object var6 = var2.getValue(); + + if (var5 == var6 || var5 != null && var5.equals(var6)) { + return true; + } + } + + return false; + } + } + + public final int hashCode() { + return IntHashMap.getHash(this.hashEntry); + } + + public final String toString() { + return this.getHash() + "=" + this.getValue(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/InventoryBasic.java b/sp-server/src/main/java/net/minecraft/src/InventoryBasic.java new file mode 100644 index 0000000..a5cc5e3 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/InventoryBasic.java @@ -0,0 +1,145 @@ +package net.minecraft.src; + +import java.util.List; + +public class InventoryBasic implements IInventory { + private String inventoryTitle; + private int slotsCount; + private ItemStack[] inventoryContents; + private List field_70480_d; + private boolean field_94051_e; + + public InventoryBasic(String par1Str, boolean par2, int par3) { + this.inventoryTitle = par1Str; + this.field_94051_e = par2; + this.slotsCount = par3; + this.inventoryContents = new ItemStack[par3]; + } + + /** + * Returns the stack in slot i + */ + public ItemStack getStackInSlot(int par1) { + return this.inventoryContents[par1]; + } + + /** + * Removes from an inventory slot (first arg) up to a specified number (second + * arg) of items and returns them in a new stack. + */ + public ItemStack decrStackSize(int par1, int par2) { + if (this.inventoryContents[par1] != null) { + ItemStack var3; + + if (this.inventoryContents[par1].stackSize <= par2) { + var3 = this.inventoryContents[par1]; + this.inventoryContents[par1] = null; + this.onInventoryChanged(); + return var3; + } else { + var3 = this.inventoryContents[par1].splitStack(par2); + + if (this.inventoryContents[par1].stackSize == 0) { + this.inventoryContents[par1] = null; + } + + this.onInventoryChanged(); + return var3; + } + } else { + return null; + } + } + + /** + * When some containers are closed they call this on each slot, then drop + * whatever it returns as an EntityItem - like when you close a workbench GUI. + */ + public ItemStack getStackInSlotOnClosing(int par1) { + if (this.inventoryContents[par1] != null) { + ItemStack var2 = this.inventoryContents[par1]; + this.inventoryContents[par1] = null; + return var2; + } else { + return null; + } + } + + /** + * Sets the given item stack to the specified slot in the inventory (can be + * crafting or armor sections). + */ + public void setInventorySlotContents(int par1, ItemStack par2ItemStack) { + this.inventoryContents[par1] = par2ItemStack; + + if (par2ItemStack != null && par2ItemStack.stackSize > this.getInventoryStackLimit()) { + par2ItemStack.stackSize = this.getInventoryStackLimit(); + } + + this.onInventoryChanged(); + } + + /** + * Returns the number of slots in the inventory. + */ + public int getSizeInventory() { + return this.slotsCount; + } + + /** + * Returns the name of the inventory. + */ + public String getInvName() { + return this.inventoryTitle; + } + + /** + * If this returns false, the inventory name will be used as an unlocalized + * name, and translated into the player's language. Otherwise it will be used + * directly. + */ + public boolean isInvNameLocalized() { + return this.field_94051_e; + } + + /** + * Returns the maximum stack size for a inventory slot. Seems to always be 64, + * possibly will be extended. *Isn't this more of a set than a get?* + */ + public int getInventoryStackLimit() { + return 64; + } + + /** + * Called when an the contents of an Inventory change, usually + */ + public void onInventoryChanged() { + if (this.field_70480_d != null) { + for (int var1 = 0; var1 < this.field_70480_d.size(); ++var1) { + ((IInvBasic) this.field_70480_d.get(var1)).onInventoryChanged(this); + } + } + } + + /** + * Do not make give this method the name canInteractWith because it clashes with + * Container + */ + public boolean isUseableByPlayer(EntityPlayer par1EntityPlayer) { + return true; + } + + public void openChest() { + } + + public void closeChest() { + } + + /** + * Returns true if automation is allowed to insert the given stack (ignoring + * stack size) into the given slot. + */ + public boolean isStackValidForSlot(int par1, ItemStack par2ItemStack) { + return true; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/InventoryCraftResult.java b/sp-server/src/main/java/net/minecraft/src/InventoryCraftResult.java new file mode 100644 index 0000000..1943a4d --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/InventoryCraftResult.java @@ -0,0 +1,108 @@ +package net.minecraft.src; + +public class InventoryCraftResult implements IInventory { + /** A list of one item containing the result of the crafting formula */ + private ItemStack[] stackResult = new ItemStack[1]; + + /** + * Returns the number of slots in the inventory. + */ + public int getSizeInventory() { + return 1; + } + + /** + * Returns the stack in slot i + */ + public ItemStack getStackInSlot(int par1) { + return this.stackResult[0]; + } + + /** + * Returns the name of the inventory. + */ + public String getInvName() { + return "Result"; + } + + /** + * If this returns false, the inventory name will be used as an unlocalized + * name, and translated into the player's language. Otherwise it will be used + * directly. + */ + public boolean isInvNameLocalized() { + return false; + } + + /** + * Removes from an inventory slot (first arg) up to a specified number (second + * arg) of items and returns them in a new stack. + */ + public ItemStack decrStackSize(int par1, int par2) { + if (this.stackResult[0] != null) { + ItemStack var3 = this.stackResult[0]; + this.stackResult[0] = null; + return var3; + } else { + return null; + } + } + + /** + * When some containers are closed they call this on each slot, then drop + * whatever it returns as an EntityItem - like when you close a workbench GUI. + */ + public ItemStack getStackInSlotOnClosing(int par1) { + if (this.stackResult[0] != null) { + ItemStack var2 = this.stackResult[0]; + this.stackResult[0] = null; + return var2; + } else { + return null; + } + } + + /** + * Sets the given item stack to the specified slot in the inventory (can be + * crafting or armor sections). + */ + public void setInventorySlotContents(int par1, ItemStack par2ItemStack) { + this.stackResult[0] = par2ItemStack; + } + + /** + * Returns the maximum stack size for a inventory slot. Seems to always be 64, + * possibly will be extended. *Isn't this more of a set than a get?* + */ + public int getInventoryStackLimit() { + return 64; + } + + /** + * Called when an the contents of an Inventory change, usually + */ + public void onInventoryChanged() { + } + + /** + * Do not make give this method the name canInteractWith because it clashes with + * Container + */ + public boolean isUseableByPlayer(EntityPlayer par1EntityPlayer) { + return true; + } + + public void openChest() { + } + + public void closeChest() { + } + + /** + * Returns true if automation is allowed to insert the given stack (ignoring + * stack size) into the given slot. + */ + public boolean isStackValidForSlot(int par1, ItemStack par2ItemStack) { + return true; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/InventoryCrafting.java b/sp-server/src/main/java/net/minecraft/src/InventoryCrafting.java new file mode 100644 index 0000000..bf788ea --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/InventoryCrafting.java @@ -0,0 +1,152 @@ +package net.minecraft.src; + +public class InventoryCrafting implements IInventory { + /** List of the stacks in the crafting matrix. */ + private ItemStack[] stackList; + + /** the width of the crafting inventory */ + private int inventoryWidth; + + /** + * Class containing the callbacks for the events on_GUIClosed and + * on_CraftMaxtrixChanged. + */ + private Container eventHandler; + + public InventoryCrafting(Container par1Container, int par2, int par3) { + int var4 = par2 * par3; + this.stackList = new ItemStack[var4]; + this.eventHandler = par1Container; + this.inventoryWidth = par2; + } + + /** + * Returns the number of slots in the inventory. + */ + public int getSizeInventory() { + return this.stackList.length; + } + + /** + * Returns the stack in slot i + */ + public ItemStack getStackInSlot(int par1) { + return par1 >= this.getSizeInventory() ? null : this.stackList[par1]; + } + + /** + * Returns the itemstack in the slot specified (Top left is 0, 0). Args: row, + * column + */ + public ItemStack getStackInRowAndColumn(int par1, int par2) { + if (par1 >= 0 && par1 < this.inventoryWidth) { + int var3 = par1 + par2 * this.inventoryWidth; + return this.getStackInSlot(var3); + } else { + return null; + } + } + + /** + * Returns the name of the inventory. + */ + public String getInvName() { + return "container.crafting"; + } + + /** + * If this returns false, the inventory name will be used as an unlocalized + * name, and translated into the player's language. Otherwise it will be used + * directly. + */ + public boolean isInvNameLocalized() { + return false; + } + + /** + * When some containers are closed they call this on each slot, then drop + * whatever it returns as an EntityItem - like when you close a workbench GUI. + */ + public ItemStack getStackInSlotOnClosing(int par1) { + if (this.stackList[par1] != null) { + ItemStack var2 = this.stackList[par1]; + this.stackList[par1] = null; + return var2; + } else { + return null; + } + } + + /** + * Removes from an inventory slot (first arg) up to a specified number (second + * arg) of items and returns them in a new stack. + */ + public ItemStack decrStackSize(int par1, int par2) { + if (this.stackList[par1] != null) { + ItemStack var3; + + if (this.stackList[par1].stackSize <= par2) { + var3 = this.stackList[par1]; + this.stackList[par1] = null; + this.eventHandler.onCraftMatrixChanged(this); + return var3; + } else { + var3 = this.stackList[par1].splitStack(par2); + + if (this.stackList[par1].stackSize == 0) { + this.stackList[par1] = null; + } + + this.eventHandler.onCraftMatrixChanged(this); + return var3; + } + } else { + return null; + } + } + + /** + * Sets the given item stack to the specified slot in the inventory (can be + * crafting or armor sections). + */ + public void setInventorySlotContents(int par1, ItemStack par2ItemStack) { + this.stackList[par1] = par2ItemStack; + this.eventHandler.onCraftMatrixChanged(this); + } + + /** + * Returns the maximum stack size for a inventory slot. Seems to always be 64, + * possibly will be extended. *Isn't this more of a set than a get?* + */ + public int getInventoryStackLimit() { + return 64; + } + + /** + * Called when an the contents of an Inventory change, usually + */ + public void onInventoryChanged() { + } + + /** + * Do not make give this method the name canInteractWith because it clashes with + * Container + */ + public boolean isUseableByPlayer(EntityPlayer par1EntityPlayer) { + return true; + } + + public void openChest() { + } + + public void closeChest() { + } + + /** + * Returns true if automation is allowed to insert the given stack (ignoring + * stack size) into the given slot. + */ + public boolean isStackValidForSlot(int par1, ItemStack par2ItemStack) { + return true; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/InventoryEnderChest.java b/sp-server/src/main/java/net/minecraft/src/InventoryEnderChest.java new file mode 100644 index 0000000..c3d293d --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/InventoryEnderChest.java @@ -0,0 +1,81 @@ +package net.minecraft.src; + +public class InventoryEnderChest extends InventoryBasic { + private TileEntityEnderChest associatedChest; + + public InventoryEnderChest() { + super("container.enderchest", false, 27); + } + + public void setAssociatedChest(TileEntityEnderChest par1TileEntityEnderChest) { + this.associatedChest = par1TileEntityEnderChest; + } + + public void loadInventoryFromNBT(NBTTagList par1NBTTagList) { + int var2; + + for (var2 = 0; var2 < this.getSizeInventory(); ++var2) { + this.setInventorySlotContents(var2, (ItemStack) null); + } + + for (var2 = 0; var2 < par1NBTTagList.tagCount(); ++var2) { + NBTTagCompound var3 = (NBTTagCompound) par1NBTTagList.tagAt(var2); + int var4 = var3.getByte("Slot") & 255; + + if (var4 >= 0 && var4 < this.getSizeInventory()) { + this.setInventorySlotContents(var4, ItemStack.loadItemStackFromNBT(var3)); + } + } + } + + public NBTTagList saveInventoryToNBT() { + NBTTagList var1 = new NBTTagList("EnderItems"); + + for (int var2 = 0; var2 < this.getSizeInventory(); ++var2) { + ItemStack var3 = this.getStackInSlot(var2); + + if (var3 != null) { + NBTTagCompound var4 = new NBTTagCompound(); + var4.setByte("Slot", (byte) var2); + var3.writeToNBT(var4); + var1.appendTag(var4); + } + } + + return var1; + } + + /** + * Do not make give this method the name canInteractWith because it clashes with + * Container + */ + public boolean isUseableByPlayer(EntityPlayer par1EntityPlayer) { + return this.associatedChest != null && !this.associatedChest.isUseableByPlayer(par1EntityPlayer) ? false + : super.isUseableByPlayer(par1EntityPlayer); + } + + public void openChest() { + if (this.associatedChest != null) { + this.associatedChest.openChest(); + } + + super.openChest(); + } + + public void closeChest() { + if (this.associatedChest != null) { + this.associatedChest.closeChest(); + } + + super.closeChest(); + this.associatedChest = null; + } + + /** + * Returns true if automation is allowed to insert the given stack (ignoring + * stack size) into the given slot. + */ + public boolean isStackValidForSlot(int par1, ItemStack par2ItemStack) { + return true; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/InventoryLargeChest.java b/sp-server/src/main/java/net/minecraft/src/InventoryLargeChest.java new file mode 100644 index 0000000..1e5353c --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/InventoryLargeChest.java @@ -0,0 +1,142 @@ +package net.minecraft.src; + +public class InventoryLargeChest implements IInventory { + /** Name of the chest. */ + private String name; + + /** Inventory object corresponding to double chest upper part */ + private IInventory upperChest; + + /** Inventory object corresponding to double chest lower part */ + private IInventory lowerChest; + + public InventoryLargeChest(String par1Str, IInventory par2IInventory, IInventory par3IInventory) { + this.name = par1Str; + + if (par2IInventory == null) { + par2IInventory = par3IInventory; + } + + if (par3IInventory == null) { + par3IInventory = par2IInventory; + } + + this.upperChest = par2IInventory; + this.lowerChest = par3IInventory; + } + + /** + * Returns the number of slots in the inventory. + */ + public int getSizeInventory() { + return this.upperChest.getSizeInventory() + this.lowerChest.getSizeInventory(); + } + + /** + * Return whether the given inventory is part of this large chest. + */ + public boolean isPartOfLargeChest(IInventory par1IInventory) { + return this.upperChest == par1IInventory || this.lowerChest == par1IInventory; + } + + /** + * Returns the name of the inventory. + */ + public String getInvName() { + return this.upperChest.isInvNameLocalized() ? this.upperChest.getInvName() + : (this.lowerChest.isInvNameLocalized() ? this.lowerChest.getInvName() : this.name); + } + + /** + * If this returns false, the inventory name will be used as an unlocalized + * name, and translated into the player's language. Otherwise it will be used + * directly. + */ + public boolean isInvNameLocalized() { + return this.upperChest.isInvNameLocalized() || this.lowerChest.isInvNameLocalized(); + } + + /** + * Returns the stack in slot i + */ + public ItemStack getStackInSlot(int par1) { + return par1 >= this.upperChest.getSizeInventory() + ? this.lowerChest.getStackInSlot(par1 - this.upperChest.getSizeInventory()) + : this.upperChest.getStackInSlot(par1); + } + + /** + * Removes from an inventory slot (first arg) up to a specified number (second + * arg) of items and returns them in a new stack. + */ + public ItemStack decrStackSize(int par1, int par2) { + return par1 >= this.upperChest.getSizeInventory() + ? this.lowerChest.decrStackSize(par1 - this.upperChest.getSizeInventory(), par2) + : this.upperChest.decrStackSize(par1, par2); + } + + /** + * When some containers are closed they call this on each slot, then drop + * whatever it returns as an EntityItem - like when you close a workbench GUI. + */ + public ItemStack getStackInSlotOnClosing(int par1) { + return par1 >= this.upperChest.getSizeInventory() + ? this.lowerChest.getStackInSlotOnClosing(par1 - this.upperChest.getSizeInventory()) + : this.upperChest.getStackInSlotOnClosing(par1); + } + + /** + * Sets the given item stack to the specified slot in the inventory (can be + * crafting or armor sections). + */ + public void setInventorySlotContents(int par1, ItemStack par2ItemStack) { + if (par1 >= this.upperChest.getSizeInventory()) { + this.lowerChest.setInventorySlotContents(par1 - this.upperChest.getSizeInventory(), par2ItemStack); + } else { + this.upperChest.setInventorySlotContents(par1, par2ItemStack); + } + } + + /** + * Returns the maximum stack size for a inventory slot. Seems to always be 64, + * possibly will be extended. *Isn't this more of a set than a get?* + */ + public int getInventoryStackLimit() { + return this.upperChest.getInventoryStackLimit(); + } + + /** + * Called when an the contents of an Inventory change, usually + */ + public void onInventoryChanged() { + this.upperChest.onInventoryChanged(); + this.lowerChest.onInventoryChanged(); + } + + /** + * Do not make give this method the name canInteractWith because it clashes with + * Container + */ + public boolean isUseableByPlayer(EntityPlayer par1EntityPlayer) { + return this.upperChest.isUseableByPlayer(par1EntityPlayer) + && this.lowerChest.isUseableByPlayer(par1EntityPlayer); + } + + public void openChest() { + this.upperChest.openChest(); + this.lowerChest.openChest(); + } + + public void closeChest() { + this.upperChest.closeChest(); + this.lowerChest.closeChest(); + } + + /** + * Returns true if automation is allowed to insert the given stack (ignoring + * stack size) into the given slot. + */ + public boolean isStackValidForSlot(int par1, ItemStack par2ItemStack) { + return true; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/InventoryMerchant.java b/sp-server/src/main/java/net/minecraft/src/InventoryMerchant.java new file mode 100644 index 0000000..107054d --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/InventoryMerchant.java @@ -0,0 +1,203 @@ +package net.minecraft.src; + +public class InventoryMerchant implements IInventory { + private final IMerchant theMerchant; + private ItemStack[] theInventory = new ItemStack[3]; + private final EntityPlayer thePlayer; + private MerchantRecipe currentRecipe; + private int currentRecipeIndex; + + public InventoryMerchant(EntityPlayer par1EntityPlayer, IMerchant par2IMerchant) { + this.thePlayer = par1EntityPlayer; + this.theMerchant = par2IMerchant; + } + + /** + * Returns the number of slots in the inventory. + */ + public int getSizeInventory() { + return this.theInventory.length; + } + + /** + * Returns the stack in slot i + */ + public ItemStack getStackInSlot(int par1) { + return this.theInventory[par1]; + } + + /** + * Removes from an inventory slot (first arg) up to a specified number (second + * arg) of items and returns them in a new stack. + */ + public ItemStack decrStackSize(int par1, int par2) { + if (this.theInventory[par1] != null) { + ItemStack var3; + + if (par1 == 2) { + var3 = this.theInventory[par1]; + this.theInventory[par1] = null; + return var3; + } else if (this.theInventory[par1].stackSize <= par2) { + var3 = this.theInventory[par1]; + this.theInventory[par1] = null; + + if (this.inventoryResetNeededOnSlotChange(par1)) { + this.resetRecipeAndSlots(); + } + + return var3; + } else { + var3 = this.theInventory[par1].splitStack(par2); + + if (this.theInventory[par1].stackSize == 0) { + this.theInventory[par1] = null; + } + + if (this.inventoryResetNeededOnSlotChange(par1)) { + this.resetRecipeAndSlots(); + } + + return var3; + } + } else { + return null; + } + } + + /** + * if par1 slot has changed, does resetRecipeAndSlots need to be called? + */ + private boolean inventoryResetNeededOnSlotChange(int par1) { + return par1 == 0 || par1 == 1; + } + + /** + * When some containers are closed they call this on each slot, then drop + * whatever it returns as an EntityItem - like when you close a workbench GUI. + */ + public ItemStack getStackInSlotOnClosing(int par1) { + if (this.theInventory[par1] != null) { + ItemStack var2 = this.theInventory[par1]; + this.theInventory[par1] = null; + return var2; + } else { + return null; + } + } + + /** + * Sets the given item stack to the specified slot in the inventory (can be + * crafting or armor sections). + */ + public void setInventorySlotContents(int par1, ItemStack par2ItemStack) { + this.theInventory[par1] = par2ItemStack; + + if (par2ItemStack != null && par2ItemStack.stackSize > this.getInventoryStackLimit()) { + par2ItemStack.stackSize = this.getInventoryStackLimit(); + } + + if (this.inventoryResetNeededOnSlotChange(par1)) { + this.resetRecipeAndSlots(); + } + } + + /** + * Returns the name of the inventory. + */ + public String getInvName() { + return "mob.villager"; + } + + /** + * If this returns false, the inventory name will be used as an unlocalized + * name, and translated into the player's language. Otherwise it will be used + * directly. + */ + public boolean isInvNameLocalized() { + return false; + } + + /** + * Returns the maximum stack size for a inventory slot. Seems to always be 64, + * possibly will be extended. *Isn't this more of a set than a get?* + */ + public int getInventoryStackLimit() { + return 64; + } + + /** + * Do not make give this method the name canInteractWith because it clashes with + * Container + */ + public boolean isUseableByPlayer(EntityPlayer par1EntityPlayer) { + return this.theMerchant.getCustomer() == par1EntityPlayer; + } + + public void openChest() { + } + + public void closeChest() { + } + + /** + * Returns true if automation is allowed to insert the given stack (ignoring + * stack size) into the given slot. + */ + public boolean isStackValidForSlot(int par1, ItemStack par2ItemStack) { + return true; + } + + /** + * Called when an the contents of an Inventory change, usually + */ + public void onInventoryChanged() { + this.resetRecipeAndSlots(); + } + + public void resetRecipeAndSlots() { + this.currentRecipe = null; + ItemStack var1 = this.theInventory[0]; + ItemStack var2 = this.theInventory[1]; + + if (var1 == null) { + var1 = var2; + var2 = null; + } + + if (var1 == null) { + this.setInventorySlotContents(2, (ItemStack) null); + } else { + MerchantRecipeList var3 = this.theMerchant.getRecipes(this.thePlayer); + + if (var3 != null) { + MerchantRecipe var4 = var3.canRecipeBeUsed(var1, var2, this.currentRecipeIndex); + + if (var4 != null && !var4.func_82784_g()) { + this.currentRecipe = var4; + this.setInventorySlotContents(2, var4.getItemToSell().copy()); + } else if (var2 != null) { + var4 = var3.canRecipeBeUsed(var2, var1, this.currentRecipeIndex); + + if (var4 != null && !var4.func_82784_g()) { + this.currentRecipe = var4; + this.setInventorySlotContents(2, var4.getItemToSell().copy()); + } else { + this.setInventorySlotContents(2, (ItemStack) null); + } + } else { + this.setInventorySlotContents(2, (ItemStack) null); + } + } + } + } + + public MerchantRecipe getCurrentRecipe() { + return this.currentRecipe; + } + + public void setCurrentRecipeIndex(int par1) { + this.currentRecipeIndex = par1; + this.resetRecipeAndSlots(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/InventoryPlayer.java b/sp-server/src/main/java/net/minecraft/src/InventoryPlayer.java new file mode 100644 index 0000000..d4dc76a --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/InventoryPlayer.java @@ -0,0 +1,611 @@ +package net.minecraft.src; + +public class InventoryPlayer implements IInventory { + /** + * An array of 36 item stacks indicating the main player inventory (including + * the visible bar). + */ + public ItemStack[] mainInventory = new ItemStack[36]; + + /** An array of 4 item stacks containing the currently worn armor pieces. */ + public ItemStack[] armorInventory = new ItemStack[4]; + + /** The index of the currently held item (0-8). */ + public int currentItem = 0; + + /** The player whose inventory this is. */ + public EntityPlayer player; + private ItemStack itemStack; + + /** + * Set true whenever the inventory changes. Nothing sets it false so you will + * have to write your own code to check it and reset the value. + */ + public boolean inventoryChanged = false; + + public InventoryPlayer(EntityPlayer par1EntityPlayer) { + this.player = par1EntityPlayer; + } + + /** + * Returns the item stack currently held by the player. + */ + public ItemStack getCurrentItem() { + return this.currentItem < 9 && this.currentItem >= 0 ? this.mainInventory[this.currentItem] : null; + } + + /** + * Get the size of the player hotbar inventory + */ + public static int getHotbarSize() { + return 9; + } + + /** + * Returns a slot index in main inventory containing a specific itemID + */ + private int getInventorySlotContainItem(int par1) { + for (int var2 = 0; var2 < this.mainInventory.length; ++var2) { + if (this.mainInventory[var2] != null && this.mainInventory[var2].itemID == par1) { + return var2; + } + } + + return -1; + } + + /** + * stores an itemstack in the users inventory + */ + private int storeItemStack(ItemStack par1ItemStack) { + for (int var2 = 0; var2 < this.mainInventory.length; ++var2) { + if (this.mainInventory[var2] != null && this.mainInventory[var2].itemID == par1ItemStack.itemID + && this.mainInventory[var2].isStackable() + && this.mainInventory[var2].stackSize < this.mainInventory[var2].getMaxStackSize() + && this.mainInventory[var2].stackSize < this.getInventoryStackLimit() + && (!this.mainInventory[var2].getHasSubtypes() + || this.mainInventory[var2].getItemDamage() == par1ItemStack.getItemDamage()) + && ItemStack.areItemStackTagsEqual(this.mainInventory[var2], par1ItemStack)) { + return var2; + } + } + + return -1; + } + + /** + * Returns the first item stack that is empty. + */ + public int getFirstEmptyStack() { + for (int var1 = 0; var1 < this.mainInventory.length; ++var1) { + if (this.mainInventory[var1] == null) { + return var1; + } + } + + return -1; + } + + /** + * Clear this player's inventory, using the specified ID and metadata as filters + * or -1 for no filter. + */ + public int clearInventory(int par1, int par2) { + int var3 = 0; + int var4; + ItemStack var5; + + for (var4 = 0; var4 < this.mainInventory.length; ++var4) { + var5 = this.mainInventory[var4]; + + if (var5 != null && (par1 <= -1 || var5.itemID == par1) && (par2 <= -1 || var5.getItemDamage() == par2)) { + var3 += var5.stackSize; + this.mainInventory[var4] = null; + } + } + + for (var4 = 0; var4 < this.armorInventory.length; ++var4) { + var5 = this.armorInventory[var4]; + + if (var5 != null && (par1 <= -1 || var5.itemID == par1) && (par2 <= -1 || var5.getItemDamage() == par2)) { + var3 += var5.stackSize; + this.armorInventory[var4] = null; + } + } + + return var3; + } + + /** + * This function stores as many items of an ItemStack as possible in a matching + * slot and returns the quantity of left over items. + */ + private int storePartialItemStack(ItemStack par1ItemStack) { + int var2 = par1ItemStack.itemID; + int var3 = par1ItemStack.stackSize; + int var4; + + if (par1ItemStack.getMaxStackSize() == 1) { + var4 = this.getFirstEmptyStack(); + + if (var4 < 0) { + return var3; + } else { + if (this.mainInventory[var4] == null) { + this.mainInventory[var4] = ItemStack.copyItemStack(par1ItemStack); + } + + return 0; + } + } else { + var4 = this.storeItemStack(par1ItemStack); + + if (var4 < 0) { + var4 = this.getFirstEmptyStack(); + } + + if (var4 < 0) { + return var3; + } else { + if (this.mainInventory[var4] == null) { + this.mainInventory[var4] = new ItemStack(var2, 0, par1ItemStack.getItemDamage()); + + if (par1ItemStack.hasTagCompound()) { + this.mainInventory[var4].setTagCompound((NBTTagCompound) par1ItemStack.getTagCompound().copy()); + } + } + + int var5 = var3; + + if (var3 > this.mainInventory[var4].getMaxStackSize() - this.mainInventory[var4].stackSize) { + var5 = this.mainInventory[var4].getMaxStackSize() - this.mainInventory[var4].stackSize; + } + + if (var5 > this.getInventoryStackLimit() - this.mainInventory[var4].stackSize) { + var5 = this.getInventoryStackLimit() - this.mainInventory[var4].stackSize; + } + + if (var5 == 0) { + return var3; + } else { + var3 -= var5; + this.mainInventory[var4].stackSize += var5; + this.mainInventory[var4].animationsToGo = 5; + return var3; + } + } + } + } + + /** + * Decrement the number of animations remaining. Only called on client side. + * This is used to handle the animation of receiving a block. + */ + public void decrementAnimations() { + for (int var1 = 0; var1 < this.mainInventory.length; ++var1) { + if (this.mainInventory[var1] != null) { + this.mainInventory[var1].updateAnimation(this.player.worldObj, this.player, var1, + this.currentItem == var1); + } + } + } + + /** + * removed one item of specified itemID from inventory (if it is in a stack, the + * stack size will reduce with 1) + */ + public boolean consumeInventoryItem(int par1) { + int var2 = this.getInventorySlotContainItem(par1); + + if (var2 < 0) { + return false; + } else { + if (--this.mainInventory[var2].stackSize <= 0) { + this.mainInventory[var2] = null; + } + + return true; + } + } + + /** + * Get if a specifiied item id is inside the inventory. + */ + public boolean hasItem(int par1) { + int var2 = this.getInventorySlotContainItem(par1); + return var2 >= 0; + } + + /** + * Adds the item stack to the inventory, returns false if it is impossible. + */ + public boolean addItemStackToInventory(ItemStack par1ItemStack) { + if (par1ItemStack == null) { + return false; + } else { + try { + int var2; + + if (par1ItemStack.isItemDamaged()) { + var2 = this.getFirstEmptyStack(); + + if (var2 >= 0) { + this.mainInventory[var2] = ItemStack.copyItemStack(par1ItemStack); + this.mainInventory[var2].animationsToGo = 5; + par1ItemStack.stackSize = 0; + return true; + } else if (this.player.capabilities.isCreativeMode) { + par1ItemStack.stackSize = 0; + return true; + } else { + return false; + } + } else { + do { + var2 = par1ItemStack.stackSize; + par1ItemStack.stackSize = this.storePartialItemStack(par1ItemStack); + } while (par1ItemStack.stackSize > 0 && par1ItemStack.stackSize < var2); + + if (par1ItemStack.stackSize == var2 && this.player.capabilities.isCreativeMode) { + par1ItemStack.stackSize = 0; + return true; + } else { + return par1ItemStack.stackSize < var2; + } + } + } catch (Throwable var5) { + CrashReport var3 = CrashReport.makeCrashReport(var5, "Adding item to inventory"); + CrashReportCategory var4 = var3.makeCategory("Item being added"); + var4.addCrashSection("Item ID", Integer.valueOf(par1ItemStack.itemID)); + var4.addCrashSection("Item data", Integer.valueOf(par1ItemStack.getItemDamage())); + var4.addCrashSectionCallable("Item name", new CallableItemName(this, par1ItemStack)); + throw new ReportedException(var3); + } + } + } + + /** + * Removes from an inventory slot (first arg) up to a specified number (second + * arg) of items and returns them in a new stack. + */ + public ItemStack decrStackSize(int par1, int par2) { + ItemStack[] var3 = this.mainInventory; + + if (par1 >= this.mainInventory.length) { + var3 = this.armorInventory; + par1 -= this.mainInventory.length; + } + + if (var3[par1] != null) { + ItemStack var4; + + if (var3[par1].stackSize <= par2) { + var4 = var3[par1]; + var3[par1] = null; + return var4; + } else { + var4 = var3[par1].splitStack(par2); + + if (var3[par1].stackSize == 0) { + var3[par1] = null; + } + + return var4; + } + } else { + return null; + } + } + + /** + * When some containers are closed they call this on each slot, then drop + * whatever it returns as an EntityItem - like when you close a workbench GUI. + */ + public ItemStack getStackInSlotOnClosing(int par1) { + ItemStack[] var2 = this.mainInventory; + + if (par1 >= this.mainInventory.length) { + var2 = this.armorInventory; + par1 -= this.mainInventory.length; + } + + if (var2[par1] != null) { + ItemStack var3 = var2[par1]; + var2[par1] = null; + return var3; + } else { + return null; + } + } + + /** + * Sets the given item stack to the specified slot in the inventory (can be + * crafting or armor sections). + */ + public void setInventorySlotContents(int par1, ItemStack par2ItemStack) { + ItemStack[] var3 = this.mainInventory; + + if (par1 >= var3.length) { + par1 -= var3.length; + var3 = this.armorInventory; + } + + var3[par1] = par2ItemStack; + } + + /** + * Gets the strength of the current item (tool) against the specified block, + * 1.0f if not holding anything. + */ + public float getStrVsBlock(Block par1Block) { + float var2 = 1.0F; + + if (this.mainInventory[this.currentItem] != null) { + var2 *= this.mainInventory[this.currentItem].getStrVsBlock(par1Block); + } + + return var2; + } + + /** + * Writes the inventory out as a list of compound tags. This is where the slot + * indices are used (+100 for armor, +80 for crafting). + */ + public NBTTagList writeToNBT(NBTTagList par1NBTTagList) { + int var2; + NBTTagCompound var3; + + for (var2 = 0; var2 < this.mainInventory.length; ++var2) { + if (this.mainInventory[var2] != null) { + var3 = new NBTTagCompound(); + var3.setByte("Slot", (byte) var2); + this.mainInventory[var2].writeToNBT(var3); + par1NBTTagList.appendTag(var3); + } + } + + for (var2 = 0; var2 < this.armorInventory.length; ++var2) { + if (this.armorInventory[var2] != null) { + var3 = new NBTTagCompound(); + var3.setByte("Slot", (byte) (var2 + 100)); + this.armorInventory[var2].writeToNBT(var3); + par1NBTTagList.appendTag(var3); + } + } + + return par1NBTTagList; + } + + /** + * Reads from the given tag list and fills the slots in the inventory with the + * correct items. + */ + public void readFromNBT(NBTTagList par1NBTTagList) { + this.mainInventory = new ItemStack[36]; + this.armorInventory = new ItemStack[4]; + + for (int var2 = 0; var2 < par1NBTTagList.tagCount(); ++var2) { + NBTTagCompound var3 = (NBTTagCompound) par1NBTTagList.tagAt(var2); + int var4 = var3.getByte("Slot") & 255; + ItemStack var5 = ItemStack.loadItemStackFromNBT(var3); + + if (var5 != null) { + if (var4 >= 0 && var4 < this.mainInventory.length) { + this.mainInventory[var4] = var5; + } + + if (var4 >= 100 && var4 < this.armorInventory.length + 100) { + this.armorInventory[var4 - 100] = var5; + } + } + } + } + + /** + * Returns the number of slots in the inventory. + */ + public int getSizeInventory() { + return this.mainInventory.length + 4; + } + + /** + * Returns the stack in slot i + */ + public ItemStack getStackInSlot(int par1) { + ItemStack[] var2 = this.mainInventory; + + if (par1 >= var2.length) { + par1 -= var2.length; + var2 = this.armorInventory; + } + + return var2[par1]; + } + + /** + * Returns the name of the inventory. + */ + public String getInvName() { + return "container.inventory"; + } + + /** + * If this returns false, the inventory name will be used as an unlocalized + * name, and translated into the player's language. Otherwise it will be used + * directly. + */ + public boolean isInvNameLocalized() { + return false; + } + + /** + * Returns the maximum stack size for a inventory slot. Seems to always be 64, + * possibly will be extended. *Isn't this more of a set than a get?* + */ + public int getInventoryStackLimit() { + return 64; + } + + /** + * Return damage vs an entity done by the current held weapon, or 1 if nothing + * is held + */ + public int getDamageVsEntity(Entity par1Entity) { + ItemStack var2 = this.getStackInSlot(this.currentItem); + return var2 != null ? var2.getDamageVsEntity(par1Entity) : 1; + } + + /** + * Returns whether the current item (tool) can harvest from the specified block + * (actually get a result). + */ + public boolean canHarvestBlock(Block par1Block) { + if (par1Block.blockMaterial.isToolNotRequired()) { + return true; + } else { + ItemStack var2 = this.getStackInSlot(this.currentItem); + return var2 != null ? var2.canHarvestBlock(par1Block) : false; + } + } + + /** + * returns a player armor item (as itemstack) contained in specified armor slot. + */ + public ItemStack armorItemInSlot(int par1) { + return this.armorInventory[par1]; + } + + /** + * Based on the damage values and maximum damage values of each armor item, + * returns the current armor value. + */ + public int getTotalArmorValue() { + int var1 = 0; + + for (int var2 = 0; var2 < this.armorInventory.length; ++var2) { + if (this.armorInventory[var2] != null && this.armorInventory[var2].getItem() instanceof ItemArmor) { + int var3 = ((ItemArmor) this.armorInventory[var2].getItem()).damageReduceAmount; + var1 += var3; + } + } + + return var1; + } + + /** + * Damages armor in each slot by the specified amount. + */ + public void damageArmor(int par1) { + par1 /= 4; + + if (par1 < 1) { + par1 = 1; + } + + for (int var2 = 0; var2 < this.armorInventory.length; ++var2) { + if (this.armorInventory[var2] != null && this.armorInventory[var2].getItem() instanceof ItemArmor) { + this.armorInventory[var2].damageItem(par1, this.player); + + if (this.armorInventory[var2].stackSize == 0) { + this.armorInventory[var2] = null; + } + } + } + } + + /** + * Drop all armor and main inventory items. + */ + public void dropAllItems() { + int var1; + + for (var1 = 0; var1 < this.mainInventory.length; ++var1) { + if (this.mainInventory[var1] != null) { + this.player.dropPlayerItemWithRandomChoice(this.mainInventory[var1], true); + this.mainInventory[var1] = null; + } + } + + for (var1 = 0; var1 < this.armorInventory.length; ++var1) { + if (this.armorInventory[var1] != null) { + this.player.dropPlayerItemWithRandomChoice(this.armorInventory[var1], true); + this.armorInventory[var1] = null; + } + } + } + + /** + * Called when an the contents of an Inventory change, usually + */ + public void onInventoryChanged() { + this.inventoryChanged = true; + } + + public void setItemStack(ItemStack par1ItemStack) { + this.itemStack = par1ItemStack; + } + + public ItemStack getItemStack() { + return this.itemStack; + } + + /** + * Do not make give this method the name canInteractWith because it clashes with + * Container + */ + public boolean isUseableByPlayer(EntityPlayer par1EntityPlayer) { + return this.player.isDead ? false : par1EntityPlayer.getDistanceSqToEntity(this.player) <= 64.0D; + } + + /** + * Returns true if the specified ItemStack exists in the inventory. + */ + public boolean hasItemStack(ItemStack par1ItemStack) { + int var2; + + for (var2 = 0; var2 < this.armorInventory.length; ++var2) { + if (this.armorInventory[var2] != null && this.armorInventory[var2].isItemEqual(par1ItemStack)) { + return true; + } + } + + for (var2 = 0; var2 < this.mainInventory.length; ++var2) { + if (this.mainInventory[var2] != null && this.mainInventory[var2].isItemEqual(par1ItemStack)) { + return true; + } + } + + return false; + } + + public void openChest() { + } + + public void closeChest() { + } + + /** + * Returns true if automation is allowed to insert the given stack (ignoring + * stack size) into the given slot. + */ + public boolean isStackValidForSlot(int par1, ItemStack par2ItemStack) { + return true; + } + + /** + * Copy the ItemStack contents from another InventoryPlayer instance + */ + public void copyInventory(InventoryPlayer par1InventoryPlayer) { + int var2; + + for (var2 = 0; var2 < this.mainInventory.length; ++var2) { + this.mainInventory[var2] = ItemStack.copyItemStack(par1InventoryPlayer.mainInventory[var2]); + } + + for (var2 = 0; var2 < this.armorInventory.length; ++var2) { + this.armorInventory[var2] = ItemStack.copyItemStack(par1InventoryPlayer.armorInventory[var2]); + } + + this.currentItem = par1InventoryPlayer.currentItem; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/InventoryRepair.java b/sp-server/src/main/java/net/minecraft/src/InventoryRepair.java new file mode 100644 index 0000000..cb54cf2 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/InventoryRepair.java @@ -0,0 +1,27 @@ +package net.minecraft.src; + +class InventoryRepair extends InventoryBasic { + /** Container of this anvil's block. */ + final ContainerRepair theContainer; + + InventoryRepair(ContainerRepair par1ContainerRepair, String par2Str, boolean par3, int par4) { + super(par2Str, par3, par4); + this.theContainer = par1ContainerRepair; + } + + /** + * Called when an the contents of an Inventory change, usually + */ + public void onInventoryChanged() { + super.onInventoryChanged(); + this.theContainer.onCraftMatrixChanged(this); + } + + /** + * Returns true if automation is allowed to insert the given stack (ignoring + * stack size) into the given slot. + */ + public boolean isStackValidForSlot(int par1, ItemStack par2ItemStack) { + return true; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/Item.java b/sp-server/src/main/java/net/minecraft/src/Item.java new file mode 100644 index 0000000..e15d7a3 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/Item.java @@ -0,0 +1,623 @@ +package net.minecraft.src; + +import java.util.Random; + +public class Item { + private CreativeTabs tabToDisplayOn = null; + + /** The RNG used by the Item subclasses. */ + protected static Random itemRand = new Random(); + + /** A 32000 elements Item array. */ + public static Item[] itemsList = new Item[32000]; + public static Item shovelIron = (new ItemSpade(0, EnumToolMaterial.IRON)).setUnlocalizedName("shovelIron"); + public static Item pickaxeIron = (new ItemPickaxe(1, EnumToolMaterial.IRON)).setUnlocalizedName("pickaxeIron"); + public static Item axeIron = (new ItemAxe(2, EnumToolMaterial.IRON)).setUnlocalizedName("hatchetIron"); + public static Item flintAndSteel = (new ItemFlintAndSteel(3)).setUnlocalizedName("flintAndSteel"); + public static Item appleRed = (new ItemFood(4, 4, 0.3F, false)).setUnlocalizedName("apple"); + public static ItemBow bow = (ItemBow) (new ItemBow(5)).setUnlocalizedName("bow"); + public static Item arrow = (new Item(6)).setUnlocalizedName("arrow").setCreativeTab(CreativeTabs.tabCombat); + public static Item coal = (new ItemCoal(7)).setUnlocalizedName("coal"); + public static Item diamond = (new Item(8)).setUnlocalizedName("diamond").setCreativeTab(CreativeTabs.tabMaterials); + public static Item ingotIron = (new Item(9)).setUnlocalizedName("ingotIron") + .setCreativeTab(CreativeTabs.tabMaterials); + public static Item ingotGold = (new Item(10)).setUnlocalizedName("ingotGold") + .setCreativeTab(CreativeTabs.tabMaterials); + public static Item swordIron = (new ItemSword(11, EnumToolMaterial.IRON)).setUnlocalizedName("swordIron"); + public static Item swordWood = (new ItemSword(12, EnumToolMaterial.WOOD)).setUnlocalizedName("swordWood"); + public static Item shovelWood = (new ItemSpade(13, EnumToolMaterial.WOOD)).setUnlocalizedName("shovelWood"); + public static Item pickaxeWood = (new ItemPickaxe(14, EnumToolMaterial.WOOD)).setUnlocalizedName("pickaxeWood"); + public static Item axeWood = (new ItemAxe(15, EnumToolMaterial.WOOD)).setUnlocalizedName("hatchetWood"); + public static Item swordStone = (new ItemSword(16, EnumToolMaterial.STONE)).setUnlocalizedName("swordStone"); + public static Item shovelStone = (new ItemSpade(17, EnumToolMaterial.STONE)).setUnlocalizedName("shovelStone"); + public static Item pickaxeStone = (new ItemPickaxe(18, EnumToolMaterial.STONE)).setUnlocalizedName("pickaxeStone"); + public static Item axeStone = (new ItemAxe(19, EnumToolMaterial.STONE)).setUnlocalizedName("hatchetStone"); + public static Item swordDiamond = (new ItemSword(20, EnumToolMaterial.EMERALD)).setUnlocalizedName("swordDiamond"); + public static Item shovelDiamond = (new ItemSpade(21, EnumToolMaterial.EMERALD)) + .setUnlocalizedName("shovelDiamond"); + public static Item pickaxeDiamond = (new ItemPickaxe(22, EnumToolMaterial.EMERALD)) + .setUnlocalizedName("pickaxeDiamond"); + public static Item axeDiamond = (new ItemAxe(23, EnumToolMaterial.EMERALD)).setUnlocalizedName("hatchetDiamond"); + public static Item stick = (new Item(24)).setFull3D().setUnlocalizedName("stick") + .setCreativeTab(CreativeTabs.tabMaterials); + public static Item bowlEmpty = (new Item(25)).setUnlocalizedName("bowl").setCreativeTab(CreativeTabs.tabMaterials); + public static Item bowlSoup = (new ItemSoup(26, 6)).setUnlocalizedName("mushroomStew"); + public static Item swordGold = (new ItemSword(27, EnumToolMaterial.GOLD)).setUnlocalizedName("swordGold"); + public static Item shovelGold = (new ItemSpade(28, EnumToolMaterial.GOLD)).setUnlocalizedName("shovelGold"); + public static Item pickaxeGold = (new ItemPickaxe(29, EnumToolMaterial.GOLD)).setUnlocalizedName("pickaxeGold"); + public static Item axeGold = (new ItemAxe(30, EnumToolMaterial.GOLD)).setUnlocalizedName("hatchetGold"); + public static Item silk = (new ItemReed(31, Block.tripWire)).setUnlocalizedName("string") + .setCreativeTab(CreativeTabs.tabMaterials); + public static Item feather = (new Item(32)).setUnlocalizedName("feather").setCreativeTab(CreativeTabs.tabMaterials); + public static Item gunpowder = (new Item(33)).setUnlocalizedName("sulphur") + .setPotionEffect(PotionHelper.gunpowderEffect).setCreativeTab(CreativeTabs.tabMaterials); + public static Item hoeWood = (new ItemHoe(34, EnumToolMaterial.WOOD)).setUnlocalizedName("hoeWood"); + public static Item hoeStone = (new ItemHoe(35, EnumToolMaterial.STONE)).setUnlocalizedName("hoeStone"); + public static Item hoeIron = (new ItemHoe(36, EnumToolMaterial.IRON)).setUnlocalizedName("hoeIron"); + public static Item hoeDiamond = (new ItemHoe(37, EnumToolMaterial.EMERALD)).setUnlocalizedName("hoeDiamond"); + public static Item hoeGold = (new ItemHoe(38, EnumToolMaterial.GOLD)).setUnlocalizedName("hoeGold"); + public static Item seeds = (new ItemSeeds(39, Block.crops.blockID, Block.tilledField.blockID)) + .setUnlocalizedName("seeds"); + public static Item wheat = (new Item(40)).setUnlocalizedName("wheat").setCreativeTab(CreativeTabs.tabMaterials); + public static Item bread = (new ItemFood(41, 5, 0.6F, false)).setUnlocalizedName("bread"); + public static ItemArmor helmetLeather = (ItemArmor) (new ItemArmor(42, EnumArmorMaterial.CLOTH, 0, 0)) + .setUnlocalizedName("helmetCloth"); + public static ItemArmor plateLeather = (ItemArmor) (new ItemArmor(43, EnumArmorMaterial.CLOTH, 0, 1)) + .setUnlocalizedName("chestplateCloth"); + public static ItemArmor legsLeather = (ItemArmor) (new ItemArmor(44, EnumArmorMaterial.CLOTH, 0, 2)) + .setUnlocalizedName("leggingsCloth"); + public static ItemArmor bootsLeather = (ItemArmor) (new ItemArmor(45, EnumArmorMaterial.CLOTH, 0, 3)) + .setUnlocalizedName("bootsCloth"); + public static ItemArmor helmetChain = (ItemArmor) (new ItemArmor(46, EnumArmorMaterial.CHAIN, 1, 0)) + .setUnlocalizedName("helmetChain"); + public static ItemArmor plateChain = (ItemArmor) (new ItemArmor(47, EnumArmorMaterial.CHAIN, 1, 1)) + .setUnlocalizedName("chestplateChain"); + public static ItemArmor legsChain = (ItemArmor) (new ItemArmor(48, EnumArmorMaterial.CHAIN, 1, 2)) + .setUnlocalizedName("leggingsChain"); + public static ItemArmor bootsChain = (ItemArmor) (new ItemArmor(49, EnumArmorMaterial.CHAIN, 1, 3)) + .setUnlocalizedName("bootsChain"); + public static ItemArmor helmetIron = (ItemArmor) (new ItemArmor(50, EnumArmorMaterial.IRON, 2, 0)) + .setUnlocalizedName("helmetIron"); + public static ItemArmor plateIron = (ItemArmor) (new ItemArmor(51, EnumArmorMaterial.IRON, 2, 1)) + .setUnlocalizedName("chestplateIron"); + public static ItemArmor legsIron = (ItemArmor) (new ItemArmor(52, EnumArmorMaterial.IRON, 2, 2)) + .setUnlocalizedName("leggingsIron"); + public static ItemArmor bootsIron = (ItemArmor) (new ItemArmor(53, EnumArmorMaterial.IRON, 2, 3)) + .setUnlocalizedName("bootsIron"); + public static ItemArmor helmetDiamond = (ItemArmor) (new ItemArmor(54, EnumArmorMaterial.DIAMOND, 3, 0)) + .setUnlocalizedName("helmetDiamond"); + public static ItemArmor plateDiamond = (ItemArmor) (new ItemArmor(55, EnumArmorMaterial.DIAMOND, 3, 1)) + .setUnlocalizedName("chestplateDiamond"); + public static ItemArmor legsDiamond = (ItemArmor) (new ItemArmor(56, EnumArmorMaterial.DIAMOND, 3, 2)) + .setUnlocalizedName("leggingsDiamond"); + public static ItemArmor bootsDiamond = (ItemArmor) (new ItemArmor(57, EnumArmorMaterial.DIAMOND, 3, 3)) + .setUnlocalizedName("bootsDiamond"); + public static ItemArmor helmetGold = (ItemArmor) (new ItemArmor(58, EnumArmorMaterial.GOLD, 4, 0)) + .setUnlocalizedName("helmetGold"); + public static ItemArmor plateGold = (ItemArmor) (new ItemArmor(59, EnumArmorMaterial.GOLD, 4, 1)) + .setUnlocalizedName("chestplateGold"); + public static ItemArmor legsGold = (ItemArmor) (new ItemArmor(60, EnumArmorMaterial.GOLD, 4, 2)) + .setUnlocalizedName("leggingsGold"); + public static ItemArmor bootsGold = (ItemArmor) (new ItemArmor(61, EnumArmorMaterial.GOLD, 4, 3)) + .setUnlocalizedName("bootsGold"); + public static Item flint = (new Item(62)).setUnlocalizedName("flint").setCreativeTab(CreativeTabs.tabMaterials); + public static Item porkRaw = (new ItemFood(63, 3, 0.3F, true)).setUnlocalizedName("porkchopRaw"); + public static Item porkCooked = (new ItemFood(64, 8, 0.8F, true)).setUnlocalizedName("porkchopCooked"); + public static Item painting = (new ItemHangingEntity(65, EntityPainting.class)).setUnlocalizedName("painting"); + public static Item appleGold = (new ItemAppleGold(66, 4, 1.2F, false)).setAlwaysEdible() + .setPotionEffect(Potion.regeneration.id, 5, 0, 1.0F).setUnlocalizedName("appleGold"); + public static Item sign = (new ItemSign(67)).setUnlocalizedName("sign"); + public static Item doorWood = (new ItemDoor(68, Material.wood)).setUnlocalizedName("doorWood"); + public static Item bucketEmpty = (new ItemBucket(69, 0)).setUnlocalizedName("bucket").setMaxStackSize(16); + public static Item bucketWater = (new ItemBucket(70, Block.waterMoving.blockID)).setUnlocalizedName("bucketWater") + .setContainerItem(bucketEmpty); + public static Item bucketLava = (new ItemBucket(71, Block.lavaMoving.blockID)).setUnlocalizedName("bucketLava") + .setContainerItem(bucketEmpty); + public static Item minecartEmpty = (new ItemMinecart(72, 0)).setUnlocalizedName("minecart"); + public static Item saddle = (new ItemSaddle(73)).setUnlocalizedName("saddle"); + public static Item doorIron = (new ItemDoor(74, Material.iron)).setUnlocalizedName("doorIron"); + public static Item redstone = (new ItemRedstone(75)).setUnlocalizedName("redstone") + .setPotionEffect(PotionHelper.redstoneEffect); + public static Item snowball = (new ItemSnowball(76)).setUnlocalizedName("snowball"); + public static Item boat = (new ItemBoat(77)).setUnlocalizedName("boat"); + public static Item leather = (new Item(78)).setUnlocalizedName("leather").setCreativeTab(CreativeTabs.tabMaterials); + public static Item bucketMilk = (new ItemBucketMilk(79)).setUnlocalizedName("milk").setContainerItem(bucketEmpty); + public static Item brick = (new Item(80)).setUnlocalizedName("brick").setCreativeTab(CreativeTabs.tabMaterials); + public static Item clay = (new Item(81)).setUnlocalizedName("clay").setCreativeTab(CreativeTabs.tabMaterials); + public static Item reed = (new ItemReed(82, Block.reed)).setUnlocalizedName("reeds") + .setCreativeTab(CreativeTabs.tabMaterials); + public static Item paper = (new Item(83)).setUnlocalizedName("paper").setCreativeTab(CreativeTabs.tabMisc); + public static Item book = (new ItemBook(84)).setUnlocalizedName("book").setCreativeTab(CreativeTabs.tabMisc); + public static Item slimeBall = (new Item(85)).setUnlocalizedName("slimeball").setCreativeTab(CreativeTabs.tabMisc); + public static Item minecartCrate = (new ItemMinecart(86, 1)).setUnlocalizedName("minecartChest"); + public static Item minecartPowered = (new ItemMinecart(87, 2)).setUnlocalizedName("minecartFurnace"); + public static Item egg = (new ItemEgg(88)).setUnlocalizedName("egg"); + public static Item compass = (new Item(89)).setUnlocalizedName("compass").setCreativeTab(CreativeTabs.tabTools); + public static ItemFishingRod fishingRod = (ItemFishingRod) (new ItemFishingRod(90)) + .setUnlocalizedName("fishingRod"); + public static Item pocketSundial = (new Item(91)).setUnlocalizedName("clock").setCreativeTab(CreativeTabs.tabTools); + public static Item lightStoneDust = (new Item(92)).setUnlocalizedName("yellowDust") + .setPotionEffect(PotionHelper.glowstoneEffect).setCreativeTab(CreativeTabs.tabMaterials); + public static Item fishRaw = (new ItemFood(93, 2, 0.3F, false)).setUnlocalizedName("fishRaw"); + public static Item fishCooked = (new ItemFood(94, 5, 0.6F, false)).setUnlocalizedName("fishCooked"); + public static Item dyePowder = (new ItemDye(95)).setUnlocalizedName("dyePowder"); + public static Item bone = (new Item(96)).setUnlocalizedName("bone").setFull3D() + .setCreativeTab(CreativeTabs.tabMisc); + public static Item sugar = (new Item(97)).setUnlocalizedName("sugar").setPotionEffect(PotionHelper.sugarEffect) + .setCreativeTab(CreativeTabs.tabMaterials); + public static Item cake = (new ItemReed(98, Block.cake)).setMaxStackSize(1).setUnlocalizedName("cake") + .setCreativeTab(CreativeTabs.tabFood); + public static Item bed = (new ItemBed(99)).setMaxStackSize(1).setUnlocalizedName("bed"); + public static Item redstoneRepeater = (new ItemReed(100, Block.redstoneRepeaterIdle)).setUnlocalizedName("diode") + .setCreativeTab(CreativeTabs.tabRedstone); + public static Item cookie = (new ItemFood(101, 2, 0.1F, false)).setUnlocalizedName("cookie"); + public static ItemMap map = (ItemMap) (new ItemMap(102)).setUnlocalizedName("map"); + + /** + * Item introduced on 1.7 version, is a shear to cut leaves (you can keep the + * block) or get wool from sheeps. + */ + public static ItemShears shears = (ItemShears) (new ItemShears(103)).setUnlocalizedName("shears"); + public static Item melon = (new ItemFood(104, 2, 0.3F, false)).setUnlocalizedName("melon"); + public static Item pumpkinSeeds = (new ItemSeeds(105, Block.pumpkinStem.blockID, Block.tilledField.blockID)) + .setUnlocalizedName("seeds_pumpkin"); + public static Item melonSeeds = (new ItemSeeds(106, Block.melonStem.blockID, Block.tilledField.blockID)) + .setUnlocalizedName("seeds_melon"); + public static Item beefRaw = (new ItemFood(107, 3, 0.3F, true)).setUnlocalizedName("beefRaw"); + public static Item beefCooked = (new ItemFood(108, 8, 0.8F, true)).setUnlocalizedName("beefCooked"); + public static Item chickenRaw = (new ItemFood(109, 2, 0.3F, true)).setPotionEffect(Potion.hunger.id, 30, 0, 0.3F) + .setUnlocalizedName("chickenRaw"); + public static Item chickenCooked = (new ItemFood(110, 6, 0.6F, true)).setUnlocalizedName("chickenCooked"); + public static Item rottenFlesh = (new ItemFood(111, 4, 0.1F, true)).setPotionEffect(Potion.hunger.id, 30, 0, 0.8F) + .setUnlocalizedName("rottenFlesh"); + public static Item enderPearl = (new ItemEnderPearl(112)).setUnlocalizedName("enderPearl"); + public static Item blazeRod = (new Item(113)).setUnlocalizedName("blazeRod") + .setCreativeTab(CreativeTabs.tabMaterials); + public static Item ghastTear = (new Item(114)).setUnlocalizedName("ghastTear") + .setPotionEffect(PotionHelper.ghastTearEffect).setCreativeTab(CreativeTabs.tabBrewing); + public static Item goldNugget = (new Item(115)).setUnlocalizedName("goldNugget") + .setCreativeTab(CreativeTabs.tabMaterials); + public static Item netherStalkSeeds = (new ItemSeeds(116, Block.netherStalk.blockID, Block.slowSand.blockID)) + .setUnlocalizedName("netherStalkSeeds").setPotionEffect("+4"); + public static ItemPotion potion = (ItemPotion) (new ItemPotion(117)).setUnlocalizedName("potion"); + public static Item glassBottle = (new ItemGlassBottle(118)).setUnlocalizedName("glassBottle"); + public static Item spiderEye = (new ItemFood(119, 2, 0.8F, false)).setPotionEffect(Potion.poison.id, 5, 0, 1.0F) + .setUnlocalizedName("spiderEye").setPotionEffect(PotionHelper.spiderEyeEffect); + public static Item fermentedSpiderEye = (new Item(120)).setUnlocalizedName("fermentedSpiderEye") + .setPotionEffect(PotionHelper.fermentedSpiderEyeEffect).setCreativeTab(CreativeTabs.tabBrewing); + public static Item blazePowder = (new Item(121)).setUnlocalizedName("blazePowder") + .setPotionEffect(PotionHelper.blazePowderEffect).setCreativeTab(CreativeTabs.tabBrewing); + public static Item magmaCream = (new Item(122)).setUnlocalizedName("magmaCream") + .setPotionEffect(PotionHelper.magmaCreamEffect).setCreativeTab(CreativeTabs.tabBrewing); + public static Item brewingStand = (new ItemReed(123, Block.brewingStand)).setUnlocalizedName("brewingStand") + .setCreativeTab(CreativeTabs.tabBrewing); + public static Item cauldron = (new ItemReed(124, Block.cauldron)).setUnlocalizedName("cauldron") + .setCreativeTab(CreativeTabs.tabBrewing); + public static Item eyeOfEnder = (new ItemEnderEye(125)).setUnlocalizedName("eyeOfEnder"); + public static Item speckledMelon = (new Item(126)).setUnlocalizedName("speckledMelon") + .setPotionEffect(PotionHelper.speckledMelonEffect).setCreativeTab(CreativeTabs.tabBrewing); + public static Item monsterPlacer = (new ItemMonsterPlacer(127)).setUnlocalizedName("monsterPlacer"); + + /** + * Bottle o' Enchanting. Drops between 1 and 3 experience orbs when thrown. + */ + public static Item expBottle = (new ItemExpBottle(128)).setUnlocalizedName("expBottle"); + + /** + * Fire Charge. When used in a dispenser it fires a fireball similiar to a + * Ghast's. + */ + public static Item fireballCharge = (new ItemFireball(129)).setUnlocalizedName("fireball"); + public static Item writableBook = (new ItemWritableBook(130)).setUnlocalizedName("writingBook") + .setCreativeTab(CreativeTabs.tabMisc); + public static Item writtenBook = (new ItemEditableBook(131)).setUnlocalizedName("writtenBook"); + public static Item emerald = (new Item(132)).setUnlocalizedName("emerald") + .setCreativeTab(CreativeTabs.tabMaterials); + public static Item itemFrame = (new ItemHangingEntity(133, EntityItemFrame.class)).setUnlocalizedName("frame"); + public static Item flowerPot = (new ItemReed(134, Block.flowerPot)).setUnlocalizedName("flowerPot") + .setCreativeTab(CreativeTabs.tabDecorations); + public static Item carrot = (new ItemSeedFood(135, 4, 0.6F, Block.carrot.blockID, Block.tilledField.blockID)) + .setUnlocalizedName("carrots"); + public static Item potato = (new ItemSeedFood(136, 1, 0.3F, Block.potato.blockID, Block.tilledField.blockID)) + .setUnlocalizedName("potato"); + public static Item bakedPotato = (new ItemFood(137, 6, 0.6F, false)).setUnlocalizedName("potatoBaked"); + public static Item poisonousPotato = (new ItemFood(138, 2, 0.3F, false)) + .setPotionEffect(Potion.poison.id, 5, 0, 0.6F).setUnlocalizedName("potatoPoisonous"); + public static ItemEmptyMap emptyMap = (ItemEmptyMap) (new ItemEmptyMap(139)).setUnlocalizedName("emptyMap"); + public static Item goldenCarrot = (new ItemFood(140, 6, 1.2F, false)).setUnlocalizedName("carrotGolden") + .setPotionEffect(PotionHelper.goldenCarrotEffect); + public static Item skull = (new ItemSkull(141)).setUnlocalizedName("skull"); + public static Item carrotOnAStick = (new ItemCarrotOnAStick(142)).setUnlocalizedName("carrotOnAStick"); + public static Item netherStar = (new ItemSimpleFoiled(143)).setUnlocalizedName("netherStar") + .setCreativeTab(CreativeTabs.tabMaterials); + public static Item pumpkinPie = (new ItemFood(144, 8, 0.3F, false)).setUnlocalizedName("pumpkinPie") + .setCreativeTab(CreativeTabs.tabFood); + public static Item firework = (new ItemFirework(145)).setUnlocalizedName("fireworks"); + public static Item fireworkCharge = (new ItemFireworkCharge(146)).setUnlocalizedName("fireworksCharge") + .setCreativeTab(CreativeTabs.tabMisc); + public static ItemEnchantedBook enchantedBook = (ItemEnchantedBook) (new ItemEnchantedBook(147)).setMaxStackSize(1) + .setUnlocalizedName("enchantedBook"); + public static Item comparator = (new ItemReed(148, Block.redstoneComparatorIdle)).setUnlocalizedName("comparator") + .setCreativeTab(CreativeTabs.tabRedstone); + public static Item netherrackBrick = (new Item(149)).setUnlocalizedName("netherbrick") + .setCreativeTab(CreativeTabs.tabMaterials); + public static Item netherQuartz = (new Item(150)).setUnlocalizedName("netherquartz") + .setCreativeTab(CreativeTabs.tabMaterials); + public static Item tntMinecart = (new ItemMinecart(151, 3)).setUnlocalizedName("minecartTnt"); + public static Item hopperMinecart = (new ItemMinecart(152, 5)).setUnlocalizedName("minecartHopper"); + public static Item record13 = (new ItemRecord(2000, "13")).setUnlocalizedName("record"); + public static Item recordCat = (new ItemRecord(2001, "cat")).setUnlocalizedName("record"); + public static Item recordBlocks = (new ItemRecord(2002, "blocks")).setUnlocalizedName("record"); + public static Item recordChirp = (new ItemRecord(2003, "chirp")).setUnlocalizedName("record"); + public static Item recordFar = (new ItemRecord(2004, "far")).setUnlocalizedName("record"); + public static Item recordMall = (new ItemRecord(2005, "mall")).setUnlocalizedName("record"); + public static Item recordMellohi = (new ItemRecord(2006, "mellohi")).setUnlocalizedName("record"); + public static Item recordStal = (new ItemRecord(2007, "stal")).setUnlocalizedName("record"); + public static Item recordStrad = (new ItemRecord(2008, "strad")).setUnlocalizedName("record"); + public static Item recordWard = (new ItemRecord(2009, "ward")).setUnlocalizedName("record"); + public static Item record11 = (new ItemRecord(2010, "11")).setUnlocalizedName("record"); + public static Item recordWait = (new ItemRecord(2011, "wait")).setUnlocalizedName("record"); + + /** The ID of this item. */ + public final int itemID; + + /** Maximum size of the stack. */ + protected int maxStackSize = 64; + + /** Maximum damage an item can handle. */ + private int maxDamage = 0; + + /** If true, render the object in full 3D, like weapons and tools. */ + protected boolean bFull3D = false; + + /** + * Some items (like dyes) have multiple subtypes on same item, this is field + * define this behavior + */ + protected boolean hasSubtypes = false; + private Item containerItem = null; + + /** + * The string representing this item's effect on a potion when used as an + * ingredient. + */ + private String potionEffect = null; + + /** The unlocalized name of this item. */ + private String unlocalizedName; + + protected Item(int par1) { + this.itemID = 256 + par1; + + if (itemsList[256 + par1] != null) { + System.out.println("CONFLICT @ " + par1); + } + + itemsList[256 + par1] = this; + } + + public Item setMaxStackSize(int par1) { + this.maxStackSize = par1; + return this; + } + + /** + * Callback for item usage. If the item does something special on right + * clicking, he will have one of those. Return True if something happen and + * false if it don't. This is for ITEMS, not BLOCKS + */ + public boolean onItemUse(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, World par3World, int par4, + int par5, int par6, int par7, float par8, float par9, float par10) { + return false; + } + + /** + * Returns the strength of the stack against a given block. 1.0F base, + * (Quality+1)*2 if correct blocktype, 1.5F if sword + */ + public float getStrVsBlock(ItemStack par1ItemStack, Block par2Block) { + return 1.0F; + } + + /** + * Called whenever this item is equipped and the right mouse button is pressed. + * Args: itemStack, world, entityPlayer + */ + public ItemStack onItemRightClick(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer) { + return par1ItemStack; + } + + public ItemStack onEaten(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer) { + return par1ItemStack; + } + + /** + * Returns the maximum size of the stack for a specific item. *Isn't this more a + * Set than a Get?* + */ + public int getItemStackLimit() { + return this.maxStackSize; + } + + /** + * Returns the metadata of the block which this Item (ItemBlock) can place + */ + public int getMetadata(int par1) { + return 0; + } + + public boolean getHasSubtypes() { + return this.hasSubtypes; + } + + protected Item setHasSubtypes(boolean par1) { + this.hasSubtypes = par1; + return this; + } + + /** + * Returns the maximum damage an item can take. + */ + public int getMaxDamage() { + return this.maxDamage; + } + + /** + * set max damage of an Item + */ + protected Item setMaxDamage(int par1) { + this.maxDamage = par1; + return this; + } + + public boolean isDamageable() { + return this.maxDamage > 0 && !this.hasSubtypes; + } + + /** + * Current implementations of this method in child classes do not use the entry + * argument beside ev. They just raise the damage on the stack. + */ + public boolean hitEntity(ItemStack par1ItemStack, EntityLiving par2EntityLiving, EntityLiving par3EntityLiving) { + return false; + } + + public boolean onBlockDestroyed(ItemStack par1ItemStack, World par2World, int par3, int par4, int par5, int par6, + EntityLiving par7EntityLiving) { + return false; + } + + /** + * Returns the damage against a given entity. + */ + public int getDamageVsEntity(Entity par1Entity) { + return 1; + } + + /** + * Returns if the item (tool) can harvest results from the block type. + */ + public boolean canHarvestBlock(Block par1Block) { + return false; + } + + /** + * Called when a player right clicks an entity with an item. + */ + public boolean useItemOnEntity(ItemStack par1ItemStack, EntityLiving par2EntityLiving) { + return false; + } + + /** + * Sets bFull3D to True and return the object. + */ + public Item setFull3D() { + this.bFull3D = true; + return this; + } + + /** + * Sets the unlocalized name of this item to the string passed as the parameter, + * prefixed by "item." + */ + public Item setUnlocalizedName(String par1Str) { + this.unlocalizedName = par1Str; + return this; + } + + /** + * Gets the localized name of the given item stack. + */ + public String getLocalizedName(ItemStack par1ItemStack) { + String var2 = this.getUnlocalizedName(par1ItemStack); + return var2 == null ? "" : StatCollector.translateToLocal(var2); + } + + /** + * Returns the unlocalized name of this item. + */ + public String getUnlocalizedName() { + return "item." + this.unlocalizedName; + } + + /** + * Returns the unlocalized name of this item. This version accepts an ItemStack + * so different stacks can have different names based on their damage or NBT. + */ + public String getUnlocalizedName(ItemStack par1ItemStack) { + return "item." + this.unlocalizedName; + } + + public Item setContainerItem(Item par1Item) { + this.containerItem = par1Item; + return this; + } + + /** + * If this returns true, after a recipe involving this item is crafted the + * container item will be added to the player's inventory instead of remaining + * in the crafting grid. + */ + public boolean doesContainerItemLeaveCraftingGrid(ItemStack par1ItemStack) { + return true; + } + + /** + * If this function returns true (or the item is damageable), the ItemStack's + * NBT tag will be sent to the client. + */ + public boolean getShareTag() { + return true; + } + + public Item getContainerItem() { + return this.containerItem; + } + + /** + * True if this Item has a container item (a.k.a. crafting result) + */ + public boolean hasContainerItem() { + return this.containerItem != null; + } + + public String getStatName() { + return StatCollector.translateToLocal(this.getUnlocalizedName() + ".name"); + } + + public String func_77653_i(ItemStack par1ItemStack) { + return StatCollector.translateToLocal(this.getUnlocalizedName(par1ItemStack) + ".name"); + } + + /** + * Called each tick as long the item is on a player inventory. Uses by maps to + * check if is on a player hand and update it's contents. + */ + public void onUpdate(ItemStack par1ItemStack, World par2World, Entity par3Entity, int par4, boolean par5) { + } + + /** + * Called when item is crafted/smelted. Used only by maps so far. + */ + public void onCreated(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer) { + } + + /** + * false for all Items except sub-classes of ItemMapBase + */ + public boolean isMap() { + return false; + } + + /** + * returns the action that specifies what animation to play when the items is + * being used + */ + public EnumAction getItemUseAction(ItemStack par1ItemStack) { + return EnumAction.none; + } + + /** + * How long it takes to use or consume an item + */ + public int getMaxItemUseDuration(ItemStack par1ItemStack) { + return 0; + } + + /** + * called when the player releases the use item button. Args: itemstack, world, + * entityplayer, itemInUseCount + */ + public void onPlayerStoppedUsing(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer, + int par4) { + } + + /** + * Sets the string representing this item's effect on a potion when used as an + * ingredient. + */ + protected Item setPotionEffect(String par1Str) { + this.potionEffect = par1Str; + return this; + } + + /** + * Returns a string representing what this item does to a potion. + */ + public String getPotionEffect() { + return this.potionEffect; + } + + /** + * Returns true if this item serves as a potion ingredient (its ingredient + * information is not null). + */ + public boolean isPotionIngredient() { + return this.potionEffect != null; + } + + public String getItemDisplayName(ItemStack par1ItemStack) { + return ("" + StringTranslate.getInstance().translateNamedKey(this.getLocalizedName(par1ItemStack))).trim(); + } + + /** + * Checks isDamagable and if it cannot be stacked + */ + public boolean isItemTool(ItemStack par1ItemStack) { + return this.getItemStackLimit() == 1 && this.isDamageable(); + } + + protected MovingObjectPosition getMovingObjectPositionFromPlayer(World par1World, EntityPlayer par2EntityPlayer, + boolean par3) { + float var4 = 1.0F; + float var5 = par2EntityPlayer.prevRotationPitch + + (par2EntityPlayer.rotationPitch - par2EntityPlayer.prevRotationPitch) * var4; + float var6 = par2EntityPlayer.prevRotationYaw + + (par2EntityPlayer.rotationYaw - par2EntityPlayer.prevRotationYaw) * var4; + double var7 = par2EntityPlayer.prevPosX + (par2EntityPlayer.posX - par2EntityPlayer.prevPosX) * (double) var4; + double var9 = par2EntityPlayer.prevPosY + (par2EntityPlayer.posY - par2EntityPlayer.prevPosY) * (double) var4 + + 1.62D - (double) par2EntityPlayer.yOffset; + double var11 = par2EntityPlayer.prevPosZ + (par2EntityPlayer.posZ - par2EntityPlayer.prevPosZ) * (double) var4; + Vec3 var13 = par1World.getWorldVec3Pool().getVecFromPool(var7, var9, var11); + float var14 = MathHelper.cos(-var6 * 0.017453292F - (float) Math.PI); + float var15 = MathHelper.sin(-var6 * 0.017453292F - (float) Math.PI); + float var16 = -MathHelper.cos(-var5 * 0.017453292F); + float var17 = MathHelper.sin(-var5 * 0.017453292F); + float var18 = var15 * var16; + float var20 = var14 * var16; + double var21 = 5.0D; + Vec3 var23 = var13.addVector((double) var18 * var21, (double) var17 * var21, (double) var20 * var21); + return par1World.rayTraceBlocks_do_do(var13, var23, par3, !par3); + } + + /** + * Return the enchantability factor of the item, most of the time is based on + * material. + */ + public int getItemEnchantability() { + return 0; + } + + /** + * returns this; + */ + public Item setCreativeTab(CreativeTabs par1CreativeTabs) { + this.tabToDisplayOn = par1CreativeTabs; + return this; + } + + public boolean func_82788_x() { + return true; + } + + /** + * Return whether this item is repairable in an anvil. + */ + public boolean getIsRepairable(ItemStack par1ItemStack, ItemStack par2ItemStack) { + return false; + } + + static { + StatList.initStats(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ItemAnvilBlock.java b/sp-server/src/main/java/net/minecraft/src/ItemAnvilBlock.java new file mode 100644 index 0000000..899c285 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ItemAnvilBlock.java @@ -0,0 +1,14 @@ +package net.minecraft.src; + +public class ItemAnvilBlock extends ItemMultiTextureTile { + public ItemAnvilBlock(Block par1Block) { + super(par1Block.blockID - 256, par1Block, BlockAnvil.statuses); + } + + /** + * Returns the metadata of the block which this Item (ItemBlock) can place + */ + public int getMetadata(int par1) { + return par1 << 2; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ItemAppleGold.java b/sp-server/src/main/java/net/minecraft/src/ItemAppleGold.java new file mode 100644 index 0000000..31124f9 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ItemAppleGold.java @@ -0,0 +1,20 @@ +package net.minecraft.src; + +public class ItemAppleGold extends ItemFood { + public ItemAppleGold(int par1, int par2, float par3, boolean par4) { + super(par1, par2, par3, par4); + this.setHasSubtypes(true); + } + + protected void onFoodEaten(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer) { + if (par1ItemStack.getItemDamage() > 0) { + if (!par2World.isRemote) { + par3EntityPlayer.addPotionEffect(new PotionEffect(Potion.regeneration.id, 600, 3)); + par3EntityPlayer.addPotionEffect(new PotionEffect(Potion.resistance.id, 6000, 0)); + par3EntityPlayer.addPotionEffect(new PotionEffect(Potion.fireResistance.id, 6000, 0)); + } + } else { + super.onFoodEaten(par1ItemStack, par2World, par3EntityPlayer); + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ItemArmor.java b/sp-server/src/main/java/net/minecraft/src/ItemArmor.java new file mode 100644 index 0000000..2c50fa0 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ItemArmor.java @@ -0,0 +1,153 @@ +package net.minecraft.src; + +public class ItemArmor extends Item { + /** Holds the 'base' maxDamage that each armorType have. */ + private static final int[] maxDamageArray = new int[] { 11, 16, 15, 13 }; + private static final String[] field_94606_cu = new String[] { "helmetCloth_overlay", "chestplateCloth_overlay", + "leggingsCloth_overlay", "bootsCloth_overlay" }; + public static final String[] field_94603_a = new String[] { "slot_empty_helmet", "slot_empty_chestplate", + "slot_empty_leggings", "slot_empty_boots" }; + private static final IBehaviorDispenseItem field_96605_cw = new BehaviorDispenseArmor(); + + /** + * Stores the armor type: 0 is helmet, 1 is plate, 2 is legs and 3 is boots + */ + public final int armorType; + + /** Holds the amount of damage that the armor reduces at full durability. */ + public final int damageReduceAmount; + + /** + * Used on RenderPlayer to select the correspondent armor to be rendered on the + * player: 0 is cloth, 1 is chain, 2 is iron, 3 is diamond and 4 is gold. + */ + public final int renderIndex; + + /** The EnumArmorMaterial used for this ItemArmor */ + private final EnumArmorMaterial material; + + public ItemArmor(int par1, EnumArmorMaterial par2EnumArmorMaterial, int par3, int par4) { + super(par1); + this.material = par2EnumArmorMaterial; + this.armorType = par4; + this.renderIndex = par3; + this.damageReduceAmount = par2EnumArmorMaterial.getDamageReductionAmount(par4); + this.setMaxDamage(par2EnumArmorMaterial.getDurability(par4)); + this.maxStackSize = 1; + this.setCreativeTab(CreativeTabs.tabCombat); + BlockDispenser.dispenseBehaviorRegistry.putObject(this, field_96605_cw); + } + + /** + * Return the enchantability factor of the item, most of the time is based on + * material. + */ + public int getItemEnchantability() { + return this.material.getEnchantability(); + } + + /** + * Return the armor material for this armor item. + */ + public EnumArmorMaterial getArmorMaterial() { + return this.material; + } + + /** + * Return whether the specified armor ItemStack has a color. + */ + public boolean hasColor(ItemStack par1ItemStack) { + return this.material != EnumArmorMaterial.CLOTH ? false + : (!par1ItemStack.hasTagCompound() ? false + : (!par1ItemStack.getTagCompound().hasKey("display") ? false + : par1ItemStack.getTagCompound().getCompoundTag("display").hasKey("color"))); + } + + /** + * Return the color for the specified armor ItemStack. + */ + public int getColor(ItemStack par1ItemStack) { + if (this.material != EnumArmorMaterial.CLOTH) { + return -1; + } else { + NBTTagCompound var2 = par1ItemStack.getTagCompound(); + + if (var2 == null) { + return 10511680; + } else { + NBTTagCompound var3 = var2.getCompoundTag("display"); + return var3 == null ? 10511680 : (var3.hasKey("color") ? var3.getInteger("color") : 10511680); + } + } + } + + /** + * Remove the color from the specified armor ItemStack. + */ + public void removeColor(ItemStack par1ItemStack) { + if (this.material == EnumArmorMaterial.CLOTH) { + NBTTagCompound var2 = par1ItemStack.getTagCompound(); + + if (var2 != null) { + NBTTagCompound var3 = var2.getCompoundTag("display"); + + if (var3.hasKey("color")) { + var3.removeTag("color"); + } + } + } + } + + public void func_82813_b(ItemStack par1ItemStack, int par2) { + if (this.material != EnumArmorMaterial.CLOTH) { + throw new UnsupportedOperationException("Can\'t dye non-leather!"); + } else { + NBTTagCompound var3 = par1ItemStack.getTagCompound(); + + if (var3 == null) { + var3 = new NBTTagCompound(); + par1ItemStack.setTagCompound(var3); + } + + NBTTagCompound var4 = var3.getCompoundTag("display"); + + if (!var3.hasKey("display")) { + var3.setCompoundTag("display", var4); + } + + var4.setInteger("color", par2); + } + } + + /** + * Return whether this item is repairable in an anvil. + */ + public boolean getIsRepairable(ItemStack par1ItemStack, ItemStack par2ItemStack) { + return this.material.getArmorCraftingMaterial() == par2ItemStack.itemID ? true + : super.getIsRepairable(par1ItemStack, par2ItemStack); + } + + /** + * Called whenever this item is equipped and the right mouse button is pressed. + * Args: itemStack, world, entityPlayer + */ + public ItemStack onItemRightClick(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer) { + int var4 = EntityLiving.getArmorPosition(par1ItemStack) - 1; + ItemStack var5 = par3EntityPlayer.getCurrentArmor(var4); + + if (var5 == null) { + par3EntityPlayer.setCurrentItemOrArmor(var4, par1ItemStack.copy()); + par1ItemStack.stackSize = 0; + } + + return par1ItemStack; + } + + /** + * Returns the 'max damage' factor array for the armor, each piece of armor have + * a durability factor (that gets multiplied by armor material factor) + */ + static int[] getMaxDamageArray() { + return maxDamageArray; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ItemAxe.java b/sp-server/src/main/java/net/minecraft/src/ItemAxe.java new file mode 100644 index 0000000..c63ff39 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ItemAxe.java @@ -0,0 +1,22 @@ +package net.minecraft.src; + +public class ItemAxe extends ItemTool { + /** an array of the blocks this axe is effective against */ + private static Block[] blocksEffectiveAgainst = new Block[] { Block.planks, Block.bookShelf, Block.wood, + Block.chest, Block.stoneDoubleSlab, Block.stoneSingleSlab, Block.pumpkin, Block.pumpkinLantern }; + + protected ItemAxe(int par1, EnumToolMaterial par2EnumToolMaterial) { + super(par1, 3, par2EnumToolMaterial, blocksEffectiveAgainst); + } + + /** + * Returns the strength of the stack against a given block. 1.0F base, + * (Quality+1)*2 if correct blocktype, 1.5F if sword + */ + public float getStrVsBlock(ItemStack par1ItemStack, Block par2Block) { + return par2Block != null && (par2Block.blockMaterial == Material.wood + || par2Block.blockMaterial == Material.plants || par2Block.blockMaterial == Material.vine) + ? this.efficiencyOnProperMaterial + : super.getStrVsBlock(par1ItemStack, par2Block); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ItemBed.java b/sp-server/src/main/java/net/minecraft/src/ItemBed.java new file mode 100644 index 0000000..8937720 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ItemBed.java @@ -0,0 +1,64 @@ +package net.minecraft.src; + +public class ItemBed extends Item { + public ItemBed(int par1) { + super(par1); + this.setCreativeTab(CreativeTabs.tabDecorations); + } + + /** + * Callback for item usage. If the item does something special on right + * clicking, he will have one of those. Return True if something happen and + * false if it don't. This is for ITEMS, not BLOCKS + */ + public boolean onItemUse(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, World par3World, int par4, + int par5, int par6, int par7, float par8, float par9, float par10) { + if (par3World.isRemote) { + return true; + } else if (par7 != 1) { + return false; + } else { + ++par5; + BlockBed var11 = (BlockBed) Block.bed; + int var12 = MathHelper.floor_double((double) (par2EntityPlayer.rotationYaw * 4.0F / 360.0F) + 0.5D) & 3; + byte var13 = 0; + byte var14 = 0; + + if (var12 == 0) { + var14 = 1; + } + + if (var12 == 1) { + var13 = -1; + } + + if (var12 == 2) { + var14 = -1; + } + + if (var12 == 3) { + var13 = 1; + } + + if (par2EntityPlayer.canPlayerEdit(par4, par5, par6, par7, par1ItemStack) + && par2EntityPlayer.canPlayerEdit(par4 + var13, par5, par6 + var14, par7, par1ItemStack)) { + if (par3World.isAirBlock(par4, par5, par6) && par3World.isAirBlock(par4 + var13, par5, par6 + var14) + && par3World.doesBlockHaveSolidTopSurface(par4, par5 - 1, par6) + && par3World.doesBlockHaveSolidTopSurface(par4 + var13, par5 - 1, par6 + var14)) { + par3World.setBlock(par4, par5, par6, var11.blockID, var12, 3); + + if (par3World.getBlockId(par4, par5, par6) == var11.blockID) { + par3World.setBlock(par4 + var13, par5, par6 + var14, var11.blockID, var12 + 8, 3); + } + + --par1ItemStack.stackSize; + return true; + } else { + return false; + } + } else { + return false; + } + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ItemBlock.java b/sp-server/src/main/java/net/minecraft/src/ItemBlock.java new file mode 100644 index 0000000..b969af6 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ItemBlock.java @@ -0,0 +1,102 @@ +package net.minecraft.src; + +public class ItemBlock extends Item { + /** The block ID of the Block associated with this ItemBlock */ + private int blockID; + + public ItemBlock(int par1) { + super(par1); + this.blockID = par1 + 256; + } + + /** + * Returns the blockID for this Item + */ + public int getBlockID() { + return this.blockID; + } + + /** + * Callback for item usage. If the item does something special on right + * clicking, he will have one of those. Return True if something happen and + * false if it don't. This is for ITEMS, not BLOCKS + */ + public boolean onItemUse(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, World par3World, int par4, + int par5, int par6, int par7, float par8, float par9, float par10) { + int var11 = par3World.getBlockId(par4, par5, par6); + + if (var11 == Block.snow.blockID && (par3World.getBlockMetadata(par4, par5, par6) & 7) < 1) { + par7 = 1; + } else if (var11 != Block.vine.blockID && var11 != Block.tallGrass.blockID && var11 != Block.deadBush.blockID) { + if (par7 == 0) { + --par5; + } + + if (par7 == 1) { + ++par5; + } + + if (par7 == 2) { + --par6; + } + + if (par7 == 3) { + ++par6; + } + + if (par7 == 4) { + --par4; + } + + if (par7 == 5) { + ++par4; + } + } + + if (par1ItemStack.stackSize == 0) { + return false; + } else if (!par2EntityPlayer.canPlayerEdit(par4, par5, par6, par7, par1ItemStack)) { + return false; + } else if (par5 == 255 && Block.blocksList[this.blockID].blockMaterial.isSolid()) { + return false; + } else if (par3World.canPlaceEntityOnSide(this.blockID, par4, par5, par6, false, par7, par2EntityPlayer, + par1ItemStack)) { + Block var12 = Block.blocksList[this.blockID]; + int var13 = this.getMetadata(par1ItemStack.getItemDamage()); + int var14 = Block.blocksList[this.blockID].onBlockPlaced(par3World, par4, par5, par6, par7, par8, par9, + par10, var13); + + if (par3World.setBlock(par4, par5, par6, this.blockID, var14, 3)) { + if (par3World.getBlockId(par4, par5, par6) == this.blockID) { + Block.blocksList[this.blockID].onBlockPlacedBy(par3World, par4, par5, par6, par2EntityPlayer, + par1ItemStack); + Block.blocksList[this.blockID].onPostBlockPlaced(par3World, par4, par5, par6, var14); + } + + par3World.playSoundEffect((double) ((float) par4 + 0.5F), (double) ((float) par5 + 0.5F), + (double) ((float) par6 + 0.5F), var12.stepSound.getPlaceSound(), + (var12.stepSound.getVolume() + 1.0F) / 2.0F, var12.stepSound.getPitch() * 0.8F); + --par1ItemStack.stackSize; + } + + return true; + } else { + return false; + } + } + + /** + * Returns the unlocalized name of this item. This version accepts an ItemStack + * so different stacks can have different names based on their damage or NBT. + */ + public String getUnlocalizedName(ItemStack par1ItemStack) { + return Block.blocksList[this.blockID].getUnlocalizedName(); + } + + /** + * Returns the unlocalized name of this item. + */ + public String getUnlocalizedName() { + return Block.blocksList[this.blockID].getUnlocalizedName(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ItemBlockWithMetadata.java b/sp-server/src/main/java/net/minecraft/src/ItemBlockWithMetadata.java new file mode 100644 index 0000000..a826060 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ItemBlockWithMetadata.java @@ -0,0 +1,19 @@ +package net.minecraft.src; + +public class ItemBlockWithMetadata extends ItemBlock { + private Block theBlock; + + public ItemBlockWithMetadata(int par1, Block par2Block) { + super(par1); + this.theBlock = par2Block; + this.setMaxDamage(0); + this.setHasSubtypes(true); + } + + /** + * Returns the metadata of the block which this Item (ItemBlock) can place + */ + public int getMetadata(int par1) { + return par1; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ItemBoat.java b/sp-server/src/main/java/net/minecraft/src/ItemBoat.java new file mode 100644 index 0000000..a8d6462 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ItemBoat.java @@ -0,0 +1,98 @@ +package net.minecraft.src; + +import java.util.List; + +public class ItemBoat extends Item { + public ItemBoat(int par1) { + super(par1); + this.maxStackSize = 1; + this.setCreativeTab(CreativeTabs.tabTransport); + } + + /** + * Called whenever this item is equipped and the right mouse button is pressed. + * Args: itemStack, world, entityPlayer + */ + public ItemStack onItemRightClick(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer) { + float var4 = 1.0F; + float var5 = par3EntityPlayer.prevRotationPitch + + (par3EntityPlayer.rotationPitch - par3EntityPlayer.prevRotationPitch) * var4; + float var6 = par3EntityPlayer.prevRotationYaw + + (par3EntityPlayer.rotationYaw - par3EntityPlayer.prevRotationYaw) * var4; + double var7 = par3EntityPlayer.prevPosX + (par3EntityPlayer.posX - par3EntityPlayer.prevPosX) * (double) var4; + double var9 = par3EntityPlayer.prevPosY + (par3EntityPlayer.posY - par3EntityPlayer.prevPosY) * (double) var4 + + 1.62D - (double) par3EntityPlayer.yOffset; + double var11 = par3EntityPlayer.prevPosZ + (par3EntityPlayer.posZ - par3EntityPlayer.prevPosZ) * (double) var4; + Vec3 var13 = par2World.getWorldVec3Pool().getVecFromPool(var7, var9, var11); + float var14 = MathHelper.cos(-var6 * 0.017453292F - (float) Math.PI); + float var15 = MathHelper.sin(-var6 * 0.017453292F - (float) Math.PI); + float var16 = -MathHelper.cos(-var5 * 0.017453292F); + float var17 = MathHelper.sin(-var5 * 0.017453292F); + float var18 = var15 * var16; + float var20 = var14 * var16; + double var21 = 5.0D; + Vec3 var23 = var13.addVector((double) var18 * var21, (double) var17 * var21, (double) var20 * var21); + MovingObjectPosition var24 = par2World.rayTraceBlocks_do(var13, var23, true); + + if (var24 == null) { + return par1ItemStack; + } else { + Vec3 var25 = par3EntityPlayer.getLook(var4); + boolean var26 = false; + float var27 = 1.0F; + List var28 = par2World.getEntitiesWithinAABBExcludingEntity(par3EntityPlayer, + par3EntityPlayer.boundingBox + .addCoord(var25.xCoord * var21, var25.yCoord * var21, var25.zCoord * var21) + .expand((double) var27, (double) var27, (double) var27)); + int var29; + + for (var29 = 0; var29 < var28.size(); ++var29) { + Entity var30 = (Entity) var28.get(var29); + + if (var30.canBeCollidedWith()) { + float var31 = var30.getCollisionBorderSize(); + AxisAlignedBB var32 = var30.boundingBox.expand((double) var31, (double) var31, (double) var31); + + if (var32.isVecInside(var13)) { + var26 = true; + } + } + } + + if (var26) { + return par1ItemStack; + } else { + if (var24.typeOfHit == EnumMovingObjectType.TILE) { + var29 = var24.blockX; + int var33 = var24.blockY; + int var34 = var24.blockZ; + + if (par2World.getBlockId(var29, var33, var34) == Block.snow.blockID) { + --var33; + } + + EntityBoat var35 = new EntityBoat(par2World, (double) ((float) var29 + 0.5F), + (double) ((float) var33 + 1.0F), (double) ((float) var34 + 0.5F)); + var35.rotationYaw = (float) (((MathHelper + .floor_double((double) (par3EntityPlayer.rotationYaw * 4.0F / 360.0F) + 0.5D) & 3) - 1) + * 90); + + if (!par2World.getCollidingBoundingBoxes(var35, var35.boundingBox.expand(-0.1D, -0.1D, -0.1D)) + .isEmpty()) { + return par1ItemStack; + } + + if (!par2World.isRemote) { + par2World.spawnEntityInWorld(var35); + } + + if (!par3EntityPlayer.capabilities.isCreativeMode) { + --par1ItemStack.stackSize; + } + } + + return par1ItemStack; + } + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ItemBook.java b/sp-server/src/main/java/net/minecraft/src/ItemBook.java new file mode 100644 index 0000000..91dbd88 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ItemBook.java @@ -0,0 +1,22 @@ +package net.minecraft.src; + +public class ItemBook extends Item { + public ItemBook(int par1) { + super(par1); + } + + /** + * Checks isDamagable and if it cannot be stacked + */ + public boolean isItemTool(ItemStack par1ItemStack) { + return par1ItemStack.stackSize == 1; + } + + /** + * Return the enchantability factor of the item, most of the time is based on + * material. + */ + public int getItemEnchantability() { + return 1; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ItemBow.java b/sp-server/src/main/java/net/minecraft/src/ItemBow.java new file mode 100644 index 0000000..ac870d4 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ItemBow.java @@ -0,0 +1,111 @@ +package net.minecraft.src; + +public class ItemBow extends Item { + public static final String[] bowPullIconNameArray = new String[] { "bow_pull_0", "bow_pull_1", "bow_pull_2" }; + + public ItemBow(int par1) { + super(par1); + this.maxStackSize = 1; + this.setMaxDamage(384); + this.setCreativeTab(CreativeTabs.tabCombat); + } + + /** + * called when the player releases the use item button. Args: itemstack, world, + * entityplayer, itemInUseCount + */ + public void onPlayerStoppedUsing(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer, + int par4) { + boolean var5 = par3EntityPlayer.capabilities.isCreativeMode + || EnchantmentHelper.getEnchantmentLevel(Enchantment.infinity.effectId, par1ItemStack) > 0; + + if (var5 || par3EntityPlayer.inventory.hasItem(Item.arrow.itemID)) { + int var6 = this.getMaxItemUseDuration(par1ItemStack) - par4; + float var7 = (float) var6 / 20.0F; + var7 = (var7 * var7 + var7 * 2.0F) / 3.0F; + + if ((double) var7 < 0.1D) { + return; + } + + if (var7 > 1.0F) { + var7 = 1.0F; + } + + EntityArrow var8 = new EntityArrow(par2World, par3EntityPlayer, var7 * 2.0F); + + if (var7 == 1.0F) { + var8.setIsCritical(true); + } + + int var9 = EnchantmentHelper.getEnchantmentLevel(Enchantment.power.effectId, par1ItemStack); + + if (var9 > 0) { + var8.setDamage(var8.getDamage() + (double) var9 * 0.5D + 0.5D); + } + + int var10 = EnchantmentHelper.getEnchantmentLevel(Enchantment.punch.effectId, par1ItemStack); + + if (var10 > 0) { + var8.setKnockbackStrength(var10); + } + + if (EnchantmentHelper.getEnchantmentLevel(Enchantment.flame.effectId, par1ItemStack) > 0) { + var8.setFire(100); + } + + par1ItemStack.damageItem(1, par3EntityPlayer); + par2World.playSoundAtEntity(par3EntityPlayer, "random.bow", 1.0F, + 1.0F / (itemRand.nextFloat() * 0.4F + 1.2F) + var7 * 0.5F); + + if (var5) { + var8.canBePickedUp = 2; + } else { + par3EntityPlayer.inventory.consumeInventoryItem(Item.arrow.itemID); + } + + if (!par2World.isRemote) { + par2World.spawnEntityInWorld(var8); + } + } + } + + public ItemStack onEaten(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer) { + return par1ItemStack; + } + + /** + * How long it takes to use or consume an item + */ + public int getMaxItemUseDuration(ItemStack par1ItemStack) { + return 72000; + } + + /** + * returns the action that specifies what animation to play when the items is + * being used + */ + public EnumAction getItemUseAction(ItemStack par1ItemStack) { + return EnumAction.bow; + } + + /** + * Called whenever this item is equipped and the right mouse button is pressed. + * Args: itemStack, world, entityPlayer + */ + public ItemStack onItemRightClick(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer) { + if (par3EntityPlayer.capabilities.isCreativeMode || par3EntityPlayer.inventory.hasItem(Item.arrow.itemID)) { + par3EntityPlayer.setItemInUse(par1ItemStack, this.getMaxItemUseDuration(par1ItemStack)); + } + + return par1ItemStack; + } + + /** + * Return the enchantability factor of the item, most of the time is based on + * material. + */ + public int getItemEnchantability() { + return 1; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ItemBucket.java b/sp-server/src/main/java/net/minecraft/src/ItemBucket.java new file mode 100644 index 0000000..2adee92 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ItemBucket.java @@ -0,0 +1,153 @@ +package net.minecraft.src; + +public class ItemBucket extends Item { + /** field for checking if the bucket has been filled. */ + private int isFull; + + public ItemBucket(int par1, int par2) { + super(par1); + this.maxStackSize = 1; + this.isFull = par2; + this.setCreativeTab(CreativeTabs.tabMisc); + } + + /** + * Called whenever this item is equipped and the right mouse button is pressed. + * Args: itemStack, world, entityPlayer + */ + public ItemStack onItemRightClick(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer) { + float var4 = 1.0F; + double var5 = par3EntityPlayer.prevPosX + (par3EntityPlayer.posX - par3EntityPlayer.prevPosX) * (double) var4; + double var7 = par3EntityPlayer.prevPosY + (par3EntityPlayer.posY - par3EntityPlayer.prevPosY) * (double) var4 + + 1.62D - (double) par3EntityPlayer.yOffset; + double var9 = par3EntityPlayer.prevPosZ + (par3EntityPlayer.posZ - par3EntityPlayer.prevPosZ) * (double) var4; + boolean var11 = this.isFull == 0; + MovingObjectPosition var12 = this.getMovingObjectPositionFromPlayer(par2World, par3EntityPlayer, var11); + + if (var12 == null) { + return par1ItemStack; + } else { + if (var12.typeOfHit == EnumMovingObjectType.TILE) { + int var13 = var12.blockX; + int var14 = var12.blockY; + int var15 = var12.blockZ; + + if (!par2World.canMineBlock(par3EntityPlayer, var13, var14, var15)) { + return par1ItemStack; + } + + if (this.isFull == 0) { + if (!par3EntityPlayer.canPlayerEdit(var13, var14, var15, var12.sideHit, par1ItemStack)) { + return par1ItemStack; + } + + if (par2World.getBlockMaterial(var13, var14, var15) == Material.water + && par2World.getBlockMetadata(var13, var14, var15) == 0) { + par2World.setBlockToAir(var13, var14, var15); + + if (par3EntityPlayer.capabilities.isCreativeMode) { + return par1ItemStack; + } + + if (--par1ItemStack.stackSize <= 0) { + return new ItemStack(Item.bucketWater); + } + + if (!par3EntityPlayer.inventory.addItemStackToInventory(new ItemStack(Item.bucketWater))) { + par3EntityPlayer.dropPlayerItem(new ItemStack(Item.bucketWater.itemID, 1, 0)); + } + + return par1ItemStack; + } + + if (par2World.getBlockMaterial(var13, var14, var15) == Material.lava + && par2World.getBlockMetadata(var13, var14, var15) == 0) { + par2World.setBlockToAir(var13, var14, var15); + + if (par3EntityPlayer.capabilities.isCreativeMode) { + return par1ItemStack; + } + + if (--par1ItemStack.stackSize <= 0) { + return new ItemStack(Item.bucketLava); + } + + if (!par3EntityPlayer.inventory.addItemStackToInventory(new ItemStack(Item.bucketLava))) { + par3EntityPlayer.dropPlayerItem(new ItemStack(Item.bucketLava.itemID, 1, 0)); + } + + return par1ItemStack; + } + } else { + if (this.isFull < 0) { + return new ItemStack(Item.bucketEmpty); + } + + if (var12.sideHit == 0) { + --var14; + } + + if (var12.sideHit == 1) { + ++var14; + } + + if (var12.sideHit == 2) { + --var15; + } + + if (var12.sideHit == 3) { + ++var15; + } + + if (var12.sideHit == 4) { + --var13; + } + + if (var12.sideHit == 5) { + ++var13; + } + + if (!par3EntityPlayer.canPlayerEdit(var13, var14, var15, var12.sideHit, par1ItemStack)) { + return par1ItemStack; + } + + if (this.tryPlaceContainedLiquid(par2World, var5, var7, var9, var13, var14, var15) + && !par3EntityPlayer.capabilities.isCreativeMode) { + return new ItemStack(Item.bucketEmpty); + } + } + } else if (this.isFull == 0 && var12.entityHit instanceof EntityCow) { + return new ItemStack(Item.bucketMilk); + } + + return par1ItemStack; + } + } + + /** + * Attempts to place the liquid contained inside the bucket. + */ + public boolean tryPlaceContainedLiquid(World par1World, double par2, double par4, double par6, int par8, int par9, + int par10) { + if (this.isFull <= 0) { + return false; + } else if (!par1World.isAirBlock(par8, par9, par10) + && par1World.getBlockMaterial(par8, par9, par10).isSolid()) { + return false; + } else { + if (par1World.provider.isHellWorld && this.isFull == Block.waterMoving.blockID) { + par1World.playSoundEffect(par2 + 0.5D, par4 + 0.5D, par6 + 0.5D, "random.fizz", 0.5F, + 2.6F + (par1World.rand.nextFloat() - par1World.rand.nextFloat()) * 0.8F); + + for (int var11 = 0; var11 < 8; ++var11) { + par1World.spawnParticle("largesmoke", (double) par8 + Math.random(), (double) par9 + Math.random(), + (double) par10 + Math.random(), 0.0D, 0.0D, 0.0D); + } + } else { + par1World.setBlock(par8, par9, par10, this.isFull, 0, 3); + } + + return true; + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ItemBucketMilk.java b/sp-server/src/main/java/net/minecraft/src/ItemBucketMilk.java new file mode 100644 index 0000000..7393491 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ItemBucketMilk.java @@ -0,0 +1,45 @@ +package net.minecraft.src; + +public class ItemBucketMilk extends Item { + public ItemBucketMilk(int par1) { + super(par1); + this.setMaxStackSize(1); + this.setCreativeTab(CreativeTabs.tabMisc); + } + + public ItemStack onEaten(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer) { + if (!par3EntityPlayer.capabilities.isCreativeMode) { + --par1ItemStack.stackSize; + } + + if (!par2World.isRemote) { + par3EntityPlayer.clearActivePotions(); + } + + return par1ItemStack.stackSize <= 0 ? new ItemStack(Item.bucketEmpty) : par1ItemStack; + } + + /** + * How long it takes to use or consume an item + */ + public int getMaxItemUseDuration(ItemStack par1ItemStack) { + return 32; + } + + /** + * returns the action that specifies what animation to play when the items is + * being used + */ + public EnumAction getItemUseAction(ItemStack par1ItemStack) { + return EnumAction.drink; + } + + /** + * Called whenever this item is equipped and the right mouse button is pressed. + * Args: itemStack, world, entityPlayer + */ + public ItemStack onItemRightClick(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer) { + par3EntityPlayer.setItemInUse(par1ItemStack, this.getMaxItemUseDuration(par1ItemStack)); + return par1ItemStack; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ItemCarrotOnAStick.java b/sp-server/src/main/java/net/minecraft/src/ItemCarrotOnAStick.java new file mode 100644 index 0000000..f8dcde2 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ItemCarrotOnAStick.java @@ -0,0 +1,34 @@ +package net.minecraft.src; + +public class ItemCarrotOnAStick extends Item { + public ItemCarrotOnAStick(int par1) { + super(par1); + this.setCreativeTab(CreativeTabs.tabTransport); + this.setMaxStackSize(1); + this.setMaxDamage(25); + } + + /** + * Called whenever this item is equipped and the right mouse button is pressed. + * Args: itemStack, world, entityPlayer + */ + public ItemStack onItemRightClick(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer) { + if (par3EntityPlayer.isRiding() && par3EntityPlayer.ridingEntity instanceof EntityPig) { + EntityPig var4 = (EntityPig) par3EntityPlayer.ridingEntity; + + if (var4.getAIControlledByPlayer().isControlledByPlayer() + && par1ItemStack.getMaxDamage() - par1ItemStack.getItemDamage() >= 7) { + var4.getAIControlledByPlayer().boostSpeed(); + par1ItemStack.damageItem(7, par3EntityPlayer); + + if (par1ItemStack.stackSize == 0) { + ItemStack var5 = new ItemStack(Item.fishingRod); + var5.setTagCompound(par1ItemStack.stackTagCompound); + return var5; + } + } + } + + return par1ItemStack; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ItemCloth.java b/sp-server/src/main/java/net/minecraft/src/ItemCloth.java new file mode 100644 index 0000000..71366bb --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ItemCloth.java @@ -0,0 +1,25 @@ +package net.minecraft.src; + +public class ItemCloth extends ItemBlock { + public ItemCloth(int par1) { + super(par1); + this.setMaxDamage(0); + this.setHasSubtypes(true); + } + + /** + * Returns the metadata of the block which this Item (ItemBlock) can place + */ + public int getMetadata(int par1) { + return par1; + } + + /** + * Returns the unlocalized name of this item. This version accepts an ItemStack + * so different stacks can have different names based on their damage or NBT. + */ + public String getUnlocalizedName(ItemStack par1ItemStack) { + return super.getUnlocalizedName() + "." + + ItemDye.dyeColorNames[BlockCloth.getBlockFromDye(par1ItemStack.getItemDamage())]; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ItemCoal.java b/sp-server/src/main/java/net/minecraft/src/ItemCoal.java new file mode 100644 index 0000000..f934f1f --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ItemCoal.java @@ -0,0 +1,18 @@ +package net.minecraft.src; + +public class ItemCoal extends Item { + public ItemCoal(int par1) { + super(par1); + this.setHasSubtypes(true); + this.setMaxDamage(0); + this.setCreativeTab(CreativeTabs.tabMaterials); + } + + /** + * Returns the unlocalized name of this item. This version accepts an ItemStack + * so different stacks can have different names based on their damage or NBT. + */ + public String getUnlocalizedName(ItemStack par1ItemStack) { + return par1ItemStack.getItemDamage() == 1 ? "item.charcoal" : "item.coal"; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ItemColored.java b/sp-server/src/main/java/net/minecraft/src/ItemColored.java new file mode 100644 index 0000000..8aed141 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ItemColored.java @@ -0,0 +1,47 @@ +package net.minecraft.src; + +public class ItemColored extends ItemBlock { + private final Block blockRef; + private String[] blockNames; + + public ItemColored(int par1, boolean par2) { + super(par1); + this.blockRef = Block.blocksList[this.getBlockID()]; + + if (par2) { + this.setMaxDamage(0); + this.setHasSubtypes(true); + } + } + + /** + * Returns the metadata of the block which this Item (ItemBlock) can place + */ + public int getMetadata(int par1) { + return par1; + } + + /** + * Sets the array of strings to be used for name lookups from item damage to + * metadata + */ + public ItemColored setBlockNames(String[] par1ArrayOfStr) { + this.blockNames = par1ArrayOfStr; + return this; + } + + /** + * Returns the unlocalized name of this item. This version accepts an ItemStack + * so different stacks can have different names based on their damage or NBT. + */ + public String getUnlocalizedName(ItemStack par1ItemStack) { + if (this.blockNames == null) { + return super.getUnlocalizedName(par1ItemStack); + } else { + int var2 = par1ItemStack.getItemDamage(); + return var2 >= 0 && var2 < this.blockNames.length + ? super.getUnlocalizedName(par1ItemStack) + "." + this.blockNames[var2] + : super.getUnlocalizedName(par1ItemStack); + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ItemDoor.java b/sp-server/src/main/java/net/minecraft/src/ItemDoor.java new file mode 100644 index 0000000..b10b4f2 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ItemDoor.java @@ -0,0 +1,90 @@ +package net.minecraft.src; + +public class ItemDoor extends Item { + private Material doorMaterial; + + public ItemDoor(int par1, Material par2Material) { + super(par1); + this.doorMaterial = par2Material; + this.maxStackSize = 1; + this.setCreativeTab(CreativeTabs.tabRedstone); + } + + /** + * Callback for item usage. If the item does something special on right + * clicking, he will have one of those. Return True if something happen and + * false if it don't. This is for ITEMS, not BLOCKS + */ + public boolean onItemUse(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, World par3World, int par4, + int par5, int par6, int par7, float par8, float par9, float par10) { + if (par7 != 1) { + return false; + } else { + ++par5; + Block var11; + + if (this.doorMaterial == Material.wood) { + var11 = Block.doorWood; + } else { + var11 = Block.doorIron; + } + + if (par2EntityPlayer.canPlayerEdit(par4, par5, par6, par7, par1ItemStack) + && par2EntityPlayer.canPlayerEdit(par4, par5 + 1, par6, par7, par1ItemStack)) { + if (!var11.canPlaceBlockAt(par3World, par4, par5, par6)) { + return false; + } else { + int var12 = MathHelper.floor_double( + (double) ((par2EntityPlayer.rotationYaw + 180.0F) * 4.0F / 360.0F) - 0.5D) & 3; + placeDoorBlock(par3World, par4, par5, par6, var12, var11); + --par1ItemStack.stackSize; + return true; + } + } else { + return false; + } + } + } + + public static void placeDoorBlock(World par0World, int par1, int par2, int par3, int par4, Block par5Block) { + byte var6 = 0; + byte var7 = 0; + + if (par4 == 0) { + var7 = 1; + } + + if (par4 == 1) { + var6 = -1; + } + + if (par4 == 2) { + var7 = -1; + } + + if (par4 == 3) { + var6 = 1; + } + + int var8 = (par0World.isBlockNormalCube(par1 - var6, par2, par3 - var7) ? 1 : 0) + + (par0World.isBlockNormalCube(par1 - var6, par2 + 1, par3 - var7) ? 1 : 0); + int var9 = (par0World.isBlockNormalCube(par1 + var6, par2, par3 + var7) ? 1 : 0) + + (par0World.isBlockNormalCube(par1 + var6, par2 + 1, par3 + var7) ? 1 : 0); + boolean var10 = par0World.getBlockId(par1 - var6, par2, par3 - var7) == par5Block.blockID + || par0World.getBlockId(par1 - var6, par2 + 1, par3 - var7) == par5Block.blockID; + boolean var11 = par0World.getBlockId(par1 + var6, par2, par3 + var7) == par5Block.blockID + || par0World.getBlockId(par1 + var6, par2 + 1, par3 + var7) == par5Block.blockID; + boolean var12 = false; + + if (var10 && !var11) { + var12 = true; + } else if (var9 > var8) { + var12 = true; + } + + par0World.setBlock(par1, par2, par3, par5Block.blockID, par4, 2); + par0World.setBlock(par1, par2 + 1, par3, par5Block.blockID, 8 | (var12 ? 1 : 0), 2); + par0World.notifyBlocksOfNeighborChange(par1, par2, par3, par5Block.blockID); + par0World.notifyBlocksOfNeighborChange(par1, par2 + 1, par3, par5Block.blockID); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ItemDye.java b/sp-server/src/main/java/net/minecraft/src/ItemDye.java new file mode 100644 index 0000000..2318706 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ItemDye.java @@ -0,0 +1,226 @@ +package net.minecraft.src; + +public class ItemDye extends Item { + /** List of dye color names */ + public static final String[] dyeColorNames = new String[] { "black", "red", "green", "brown", "blue", "purple", + "cyan", "silver", "gray", "pink", "lime", "yellow", "lightBlue", "magenta", "orange", "white" }; + public static final String[] field_94595_b = new String[] { "dyePowder_black", "dyePowder_red", "dyePowder_green", + "dyePowder_brown", "dyePowder_blue", "dyePowder_purple", "dyePowder_cyan", "dyePowder_silver", + "dyePowder_gray", "dyePowder_pink", "dyePowder_lime", "dyePowder_yellow", "dyePowder_lightBlue", + "dyePowder_magenta", "dyePowder_orange", "dyePowder_white" }; + public static final int[] dyeColors = new int[] { 1973019, 11743532, 3887386, 5320730, 2437522, 8073150, 2651799, + 11250603, 4408131, 14188952, 4312372, 14602026, 6719955, 12801229, 15435844, 15790320 }; + + public ItemDye(int par1) { + super(par1); + this.setHasSubtypes(true); + this.setMaxDamage(0); + this.setCreativeTab(CreativeTabs.tabMaterials); + } + + /** + * Returns the unlocalized name of this item. This version accepts an ItemStack + * so different stacks can have different names based on their damage or NBT. + */ + public String getUnlocalizedName(ItemStack par1ItemStack) { + int var2 = MathHelper.clamp_int(par1ItemStack.getItemDamage(), 0, 15); + return super.getUnlocalizedName() + "." + dyeColorNames[var2]; + } + + /** + * Callback for item usage. If the item does something special on right + * clicking, he will have one of those. Return True if something happen and + * false if it don't. This is for ITEMS, not BLOCKS + */ + public boolean onItemUse(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, World par3World, int par4, + int par5, int par6, int par7, float par8, float par9, float par10) { + if (!par2EntityPlayer.canPlayerEdit(par4, par5, par6, par7, par1ItemStack)) { + return false; + } else { + if (par1ItemStack.getItemDamage() == 15) { + if (func_96604_a(par1ItemStack, par3World, par4, par5, par6)) { + if (!par3World.isRemote) { + par3World.playAuxSFX(2005, par4, par5, par6, 0); + } + + return true; + } + } else if (par1ItemStack.getItemDamage() == 3) { + int var11 = par3World.getBlockId(par4, par5, par6); + int var12 = par3World.getBlockMetadata(par4, par5, par6); + + if (var11 == Block.wood.blockID && BlockLog.limitToValidMetadata(var12) == 3) { + if (par7 == 0) { + return false; + } + + if (par7 == 1) { + return false; + } + + if (par7 == 2) { + --par6; + } + + if (par7 == 3) { + ++par6; + } + + if (par7 == 4) { + --par4; + } + + if (par7 == 5) { + ++par4; + } + + if (par3World.isAirBlock(par4, par5, par6)) { + int var13 = Block.blocksList[Block.cocoaPlant.blockID].onBlockPlaced(par3World, par4, par5, + par6, par7, par8, par9, par10, 0); + par3World.setBlock(par4, par5, par6, Block.cocoaPlant.blockID, var13, 2); + + if (!par2EntityPlayer.capabilities.isCreativeMode) { + --par1ItemStack.stackSize; + } + } + + return true; + } + } + + return false; + } + } + + public static boolean func_96604_a(ItemStack par0ItemStack, World par1World, int par2, int par3, int par4) { + int var5 = par1World.getBlockId(par2, par3, par4); + + if (var5 == Block.sapling.blockID) { + if (!par1World.isRemote) { + if ((double) par1World.rand.nextFloat() < 0.45D) { + ((BlockSapling) Block.sapling).markOrGrowMarked(par1World, par2, par3, par4, par1World.rand); + } + + --par0ItemStack.stackSize; + } + + return true; + } else if (var5 != Block.mushroomBrown.blockID && var5 != Block.mushroomRed.blockID) { + if (var5 != Block.melonStem.blockID && var5 != Block.pumpkinStem.blockID) { + if (var5 > 0 && Block.blocksList[var5] instanceof BlockCrops) { + if (par1World.getBlockMetadata(par2, par3, par4) == 7) { + return false; + } else { + if (!par1World.isRemote) { + ((BlockCrops) Block.blocksList[var5]).fertilize(par1World, par2, par3, par4); + --par0ItemStack.stackSize; + } + + return true; + } + } else { + int var6; + int var7; + int var8; + + if (var5 == Block.cocoaPlant.blockID) { + var6 = par1World.getBlockMetadata(par2, par3, par4); + var7 = BlockDirectional.getDirection(var6); + var8 = BlockCocoa.func_72219_c(var6); + + if (var8 >= 2) { + return false; + } else { + if (!par1World.isRemote) { + ++var8; + par1World.setBlockMetadata(par2, par3, par4, var8 << 2 | var7, 2); + --par0ItemStack.stackSize; + } + + return true; + } + } else if (var5 != Block.grass.blockID) { + return false; + } else { + if (!par1World.isRemote) { + --par0ItemStack.stackSize; + label102: + + for (var6 = 0; var6 < 128; ++var6) { + var7 = par2; + var8 = par3 + 1; + int var9 = par4; + + for (int var10 = 0; var10 < var6 / 16; ++var10) { + var7 += itemRand.nextInt(3) - 1; + var8 += (itemRand.nextInt(3) - 1) * itemRand.nextInt(3) / 2; + var9 += itemRand.nextInt(3) - 1; + + if (par1World.getBlockId(var7, var8 - 1, var9) != Block.grass.blockID + || par1World.isBlockNormalCube(var7, var8, var9)) { + continue label102; + } + } + + if (par1World.getBlockId(var7, var8, var9) == 0) { + if (itemRand.nextInt(10) != 0) { + if (Block.tallGrass.canBlockStay(par1World, var7, var8, var9)) { + par1World.setBlock(var7, var8, var9, Block.tallGrass.blockID, 1, 3); + } + } else if (itemRand.nextInt(3) != 0) { + if (Block.plantYellow.canBlockStay(par1World, var7, var8, var9)) { + par1World.setBlock(var7, var8, var9, Block.plantYellow.blockID); + } + } else if (Block.plantRed.canBlockStay(par1World, var7, var8, var9)) { + par1World.setBlock(var7, var8, var9, Block.plantRed.blockID); + } + } + } + } + + return true; + } + } + } else if (par1World.getBlockMetadata(par2, par3, par4) == 7) { + return false; + } else { + if (!par1World.isRemote) { + ((BlockStem) Block.blocksList[var5]).fertilizeStem(par1World, par2, par3, par4); + --par0ItemStack.stackSize; + } + + return true; + } + } else { + if (!par1World.isRemote) { + if ((double) par1World.rand.nextFloat() < 0.4D) { + ((BlockMushroom) Block.blocksList[var5]).fertilizeMushroom(par1World, par2, par3, par4, + par1World.rand); + } + + --par0ItemStack.stackSize; + } + + return true; + } + } + + /** + * Called when a player right clicks an entity with an item. + */ + public boolean useItemOnEntity(ItemStack par1ItemStack, EntityLiving par2EntityLiving) { + if (par2EntityLiving instanceof EntitySheep) { + EntitySheep var3 = (EntitySheep) par2EntityLiving; + int var4 = BlockCloth.getBlockFromDye(par1ItemStack.getItemDamage()); + + if (!var3.getSheared() && var3.getFleeceColor() != var4) { + var3.setFleeceColor(var4); + --par1ItemStack.stackSize; + } + + return true; + } else { + return false; + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ItemEditableBook.java b/sp-server/src/main/java/net/minecraft/src/ItemEditableBook.java new file mode 100644 index 0000000..725d352 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ItemEditableBook.java @@ -0,0 +1,49 @@ +package net.minecraft.src; + +public class ItemEditableBook extends Item { + public ItemEditableBook(int par1) { + super(par1); + this.setMaxStackSize(1); + } + + public static boolean validBookTagContents(NBTTagCompound par0NBTTagCompound) { + if (!ItemWritableBook.validBookTagPages(par0NBTTagCompound)) { + return false; + } else if (!par0NBTTagCompound.hasKey("title")) { + return false; + } else { + String var1 = par0NBTTagCompound.getString("title"); + return var1 != null && var1.length() <= 16 ? par0NBTTagCompound.hasKey("author") : false; + } + } + + public String getItemDisplayName(ItemStack par1ItemStack) { + if (par1ItemStack.hasTagCompound()) { + NBTTagCompound var2 = par1ItemStack.getTagCompound(); + NBTTagString var3 = (NBTTagString) var2.getTag("title"); + + if (var3 != null) { + return var3.toString(); + } + } + + return super.getItemDisplayName(par1ItemStack); + } + + /** + * Called whenever this item is equipped and the right mouse button is pressed. + * Args: itemStack, world, entityPlayer + */ + public ItemStack onItemRightClick(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer) { + par3EntityPlayer.displayGUIBook(par1ItemStack); + return par1ItemStack; + } + + /** + * If this function returns true (or the item is damageable), the ItemStack's + * NBT tag will be sent to the client. + */ + public boolean getShareTag() { + return true; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ItemEgg.java b/sp-server/src/main/java/net/minecraft/src/ItemEgg.java new file mode 100644 index 0000000..d4e9546 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ItemEgg.java @@ -0,0 +1,27 @@ +package net.minecraft.src; + +public class ItemEgg extends Item { + public ItemEgg(int par1) { + super(par1); + this.maxStackSize = 16; + this.setCreativeTab(CreativeTabs.tabMaterials); + } + + /** + * Called whenever this item is equipped and the right mouse button is pressed. + * Args: itemStack, world, entityPlayer + */ + public ItemStack onItemRightClick(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer) { + if (!par3EntityPlayer.capabilities.isCreativeMode) { + --par1ItemStack.stackSize; + } + + par2World.playSoundAtEntity(par3EntityPlayer, "random.bow", 0.5F, 0.4F / (itemRand.nextFloat() * 0.4F + 0.8F)); + + if (!par2World.isRemote) { + par2World.spawnEntityInWorld(new EntityEgg(par2World, par3EntityPlayer)); + } + + return par1ItemStack; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ItemEmptyMap.java b/sp-server/src/main/java/net/minecraft/src/ItemEmptyMap.java new file mode 100644 index 0000000..f79d8e8 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ItemEmptyMap.java @@ -0,0 +1,36 @@ +package net.minecraft.src; + +public class ItemEmptyMap extends ItemMapBase { + protected ItemEmptyMap(int par1) { + super(par1); + this.setCreativeTab(CreativeTabs.tabMisc); + } + + /** + * Called whenever this item is equipped and the right mouse button is pressed. + * Args: itemStack, world, entityPlayer + */ + public ItemStack onItemRightClick(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer) { + ItemStack var4 = new ItemStack(Item.map, 1, par2World.getUniqueDataId("map")); + String var5 = "map_" + var4.getItemDamage(); + MapData var6 = new MapData(var5); + par2World.setItemData(var5, var6); + var6.scale = 0; + int var7 = 128 * (1 << var6.scale); + var6.xCenter = (int) (Math.round(par3EntityPlayer.posX / (double) var7) * (long) var7); + var6.zCenter = (int) (Math.round(par3EntityPlayer.posZ / (double) var7) * (long) var7); + var6.dimension = (byte) par2World.provider.dimensionId; + var6.markDirty(); + --par1ItemStack.stackSize; + + if (par1ItemStack.stackSize <= 0) { + return var4; + } else { + if (!par3EntityPlayer.inventory.addItemStackToInventory(var4.copy())) { + par3EntityPlayer.dropPlayerItem(var4); + } + + return par1ItemStack; + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ItemEnchantedBook.java b/sp-server/src/main/java/net/minecraft/src/ItemEnchantedBook.java new file mode 100644 index 0000000..7098cd8 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ItemEnchantedBook.java @@ -0,0 +1,79 @@ +package net.minecraft.src; + +import java.util.Random; + +public class ItemEnchantedBook extends Item { + public ItemEnchantedBook(int par1) { + super(par1); + } + + /** + * Checks isDamagable and if it cannot be stacked + */ + public boolean isItemTool(ItemStack par1ItemStack) { + return false; + } + + public NBTTagList func_92110_g(ItemStack par1ItemStack) { + return par1ItemStack.stackTagCompound != null && par1ItemStack.stackTagCompound.hasKey("StoredEnchantments") + ? (NBTTagList) par1ItemStack.stackTagCompound.getTag("StoredEnchantments") + : new NBTTagList(); + } + + public void func_92115_a(ItemStack par1ItemStack, EnchantmentData par2EnchantmentData) { + NBTTagList var3 = this.func_92110_g(par1ItemStack); + boolean var4 = true; + + for (int var5 = 0; var5 < var3.tagCount(); ++var5) { + NBTTagCompound var6 = (NBTTagCompound) var3.tagAt(var5); + + if (var6.getShort("id") == par2EnchantmentData.enchantmentobj.effectId) { + if (var6.getShort("lvl") < par2EnchantmentData.enchantmentLevel) { + var6.setShort("lvl", (short) par2EnchantmentData.enchantmentLevel); + } + + var4 = false; + break; + } + } + + if (var4) { + NBTTagCompound var7 = new NBTTagCompound(); + var7.setShort("id", (short) par2EnchantmentData.enchantmentobj.effectId); + var7.setShort("lvl", (short) par2EnchantmentData.enchantmentLevel); + var3.appendTag(var7); + } + + if (!par1ItemStack.hasTagCompound()) { + par1ItemStack.setTagCompound(new NBTTagCompound()); + } + + par1ItemStack.getTagCompound().setTag("StoredEnchantments", var3); + } + + public ItemStack func_92111_a(EnchantmentData par1EnchantmentData) { + ItemStack var2 = new ItemStack(this); + this.func_92115_a(var2, par1EnchantmentData); + return var2; + } + + public ItemStack func_92109_a(Random par1Random) { + Enchantment var2 = Enchantment.field_92090_c[par1Random.nextInt(Enchantment.field_92090_c.length)]; + ItemStack var3 = new ItemStack(this.itemID, 1, 0); + int var4 = MathHelper.getRandomIntegerInRange(par1Random, var2.getMinLevel(), var2.getMaxLevel()); + this.func_92115_a(var3, new EnchantmentData(var2, var4)); + return var3; + } + + public WeightedRandomChestContent func_92114_b(Random par1Random) { + return this.func_92112_a(par1Random, 1, 1, 1); + } + + public WeightedRandomChestContent func_92112_a(Random par1Random, int par2, int par3, int par4) { + Enchantment var5 = Enchantment.field_92090_c[par1Random.nextInt(Enchantment.field_92090_c.length)]; + ItemStack var6 = new ItemStack(this.itemID, 1, 0); + int var7 = MathHelper.getRandomIntegerInRange(par1Random, var5.getMinLevel(), var5.getMaxLevel()); + this.func_92115_a(var6, new EnchantmentData(var5, var7)); + return new WeightedRandomChestContent(var6, par2, par3, par4); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ItemEnderEye.java b/sp-server/src/main/java/net/minecraft/src/ItemEnderEye.java new file mode 100644 index 0000000..dc3b9b6 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ItemEnderEye.java @@ -0,0 +1,161 @@ +package net.minecraft.src; + +public class ItemEnderEye extends Item { + public ItemEnderEye(int par1) { + super(par1); + this.setCreativeTab(CreativeTabs.tabMisc); + } + + /** + * Callback for item usage. If the item does something special on right + * clicking, he will have one of those. Return True if something happen and + * false if it don't. This is for ITEMS, not BLOCKS + */ + public boolean onItemUse(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, World par3World, int par4, + int par5, int par6, int par7, float par8, float par9, float par10) { + int var11 = par3World.getBlockId(par4, par5, par6); + int var12 = par3World.getBlockMetadata(par4, par5, par6); + + if (par2EntityPlayer.canPlayerEdit(par4, par5, par6, par7, par1ItemStack) + && var11 == Block.endPortalFrame.blockID && !BlockEndPortalFrame.isEnderEyeInserted(var12)) { + if (par3World.isRemote) { + return true; + } else { + par3World.setBlockMetadata(par4, par5, par6, var12 + 4, 2); + --par1ItemStack.stackSize; + int var13; + + for (var13 = 0; var13 < 16; ++var13) { + double var14 = (double) ((float) par4 + (5.0F + itemRand.nextFloat() * 6.0F) / 16.0F); + double var16 = (double) ((float) par5 + 0.8125F); + double var18 = (double) ((float) par6 + (5.0F + itemRand.nextFloat() * 6.0F) / 16.0F); + double var20 = 0.0D; + double var22 = 0.0D; + double var24 = 0.0D; + par3World.spawnParticle("smoke", var14, var16, var18, var20, var22, var24); + } + + var13 = var12 & 3; + int var26 = 0; + int var15 = 0; + boolean var27 = false; + boolean var17 = true; + int var28 = Direction.enderEyeMetaToDirection[var13]; + int var19; + int var21; + int var23; + int var29; + int var30; + + for (var19 = -2; var19 <= 2; ++var19) { + var29 = par4 + Direction.offsetX[var28] * var19; + var21 = par6 + Direction.offsetZ[var28] * var19; + var30 = par3World.getBlockId(var29, par5, var21); + + if (var30 == Block.endPortalFrame.blockID) { + var23 = par3World.getBlockMetadata(var29, par5, var21); + + if (!BlockEndPortalFrame.isEnderEyeInserted(var23)) { + var17 = false; + break; + } + + var15 = var19; + + if (!var27) { + var26 = var19; + var27 = true; + } + } + } + + if (var17 && var15 == var26 + 2) { + for (var19 = var26; var19 <= var15; ++var19) { + var29 = par4 + Direction.offsetX[var28] * var19; + var21 = par6 + Direction.offsetZ[var28] * var19; + var29 += Direction.offsetX[var13] * 4; + var21 += Direction.offsetZ[var13] * 4; + var30 = par3World.getBlockId(var29, par5, var21); + var23 = par3World.getBlockMetadata(var29, par5, var21); + + if (var30 != Block.endPortalFrame.blockID || !BlockEndPortalFrame.isEnderEyeInserted(var23)) { + var17 = false; + break; + } + } + + for (var19 = var26 - 1; var19 <= var15 + 1; var19 += 4) { + for (var29 = 1; var29 <= 3; ++var29) { + var21 = par4 + Direction.offsetX[var28] * var19; + var30 = par6 + Direction.offsetZ[var28] * var19; + var21 += Direction.offsetX[var13] * var29; + var30 += Direction.offsetZ[var13] * var29; + var23 = par3World.getBlockId(var21, par5, var30); + int var31 = par3World.getBlockMetadata(var21, par5, var30); + + if (var23 != Block.endPortalFrame.blockID + || !BlockEndPortalFrame.isEnderEyeInserted(var31)) { + var17 = false; + break; + } + } + } + + if (var17) { + for (var19 = var26; var19 <= var15; ++var19) { + for (var29 = 1; var29 <= 3; ++var29) { + var21 = par4 + Direction.offsetX[var28] * var19; + var30 = par6 + Direction.offsetZ[var28] * var19; + var21 += Direction.offsetX[var13] * var29; + var30 += Direction.offsetZ[var13] * var29; + par3World.setBlock(var21, par5, var30, Block.endPortal.blockID, 0, 2); + } + } + } + } + + return true; + } + } else { + return false; + } + } + + /** + * Called whenever this item is equipped and the right mouse button is pressed. + * Args: itemStack, world, entityPlayer + */ + public ItemStack onItemRightClick(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer) { + MovingObjectPosition var4 = this.getMovingObjectPositionFromPlayer(par2World, par3EntityPlayer, false); + + if (var4 != null && var4.typeOfHit == EnumMovingObjectType.TILE) { + int var5 = par2World.getBlockId(var4.blockX, var4.blockY, var4.blockZ); + + if (var5 == Block.endPortalFrame.blockID) { + return par1ItemStack; + } + } + + if (!par2World.isRemote) { + ChunkPosition var7 = par2World.findClosestStructure("Stronghold", (int) par3EntityPlayer.posX, + (int) par3EntityPlayer.posY, (int) par3EntityPlayer.posZ); + + if (var7 != null) { + EntityEnderEye var6 = new EntityEnderEye(par2World, par3EntityPlayer.posX, + par3EntityPlayer.posY + 1.62D - (double) par3EntityPlayer.yOffset, par3EntityPlayer.posZ); + var6.moveTowards((double) var7.x, var7.y, (double) var7.z); + par2World.spawnEntityInWorld(var6); + par2World.playSoundAtEntity(par3EntityPlayer, "random.bow", 0.5F, + 0.4F / (itemRand.nextFloat() * 0.4F + 0.8F)); + par2World.playAuxSFXAtEntity((EntityPlayer) null, 1002, (int) par3EntityPlayer.posX, + (int) par3EntityPlayer.posY, (int) par3EntityPlayer.posZ, 0); + + if (!par3EntityPlayer.capabilities.isCreativeMode) { + --par1ItemStack.stackSize; + } + } + } + + return par1ItemStack; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ItemEnderPearl.java b/sp-server/src/main/java/net/minecraft/src/ItemEnderPearl.java new file mode 100644 index 0000000..fd5b465 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ItemEnderPearl.java @@ -0,0 +1,31 @@ +package net.minecraft.src; + +public class ItemEnderPearl extends Item { + public ItemEnderPearl(int par1) { + super(par1); + this.maxStackSize = 16; + this.setCreativeTab(CreativeTabs.tabMisc); + } + + /** + * Called whenever this item is equipped and the right mouse button is pressed. + * Args: itemStack, world, entityPlayer + */ + public ItemStack onItemRightClick(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer) { + if (par3EntityPlayer.capabilities.isCreativeMode) { + return par1ItemStack; + } else if (par3EntityPlayer.ridingEntity != null) { + return par1ItemStack; + } else { + --par1ItemStack.stackSize; + par2World.playSoundAtEntity(par3EntityPlayer, "random.bow", 0.5F, + 0.4F / (itemRand.nextFloat() * 0.4F + 0.8F)); + + if (!par2World.isRemote) { + par2World.spawnEntityInWorld(new EntityEnderPearl(par2World, par3EntityPlayer)); + } + + return par1ItemStack; + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ItemExpBottle.java b/sp-server/src/main/java/net/minecraft/src/ItemExpBottle.java new file mode 100644 index 0000000..236fd45 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ItemExpBottle.java @@ -0,0 +1,26 @@ +package net.minecraft.src; + +public class ItemExpBottle extends Item { + public ItemExpBottle(int par1) { + super(par1); + this.setCreativeTab(CreativeTabs.tabMisc); + } + + /** + * Called whenever this item is equipped and the right mouse button is pressed. + * Args: itemStack, world, entityPlayer + */ + public ItemStack onItemRightClick(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer) { + if (!par3EntityPlayer.capabilities.isCreativeMode) { + --par1ItemStack.stackSize; + } + + par2World.playSoundAtEntity(par3EntityPlayer, "random.bow", 0.5F, 0.4F / (itemRand.nextFloat() * 0.4F + 0.8F)); + + if (!par2World.isRemote) { + par2World.spawnEntityInWorld(new EntityExpBottle(par2World, par3EntityPlayer)); + } + + return par1ItemStack; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ItemFireball.java b/sp-server/src/main/java/net/minecraft/src/ItemFireball.java new file mode 100644 index 0000000..65e537d --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ItemFireball.java @@ -0,0 +1,62 @@ +package net.minecraft.src; + +public class ItemFireball extends Item { + public ItemFireball(int par1) { + super(par1); + this.setCreativeTab(CreativeTabs.tabMisc); + } + + /** + * Callback for item usage. If the item does something special on right + * clicking, he will have one of those. Return True if something happen and + * false if it don't. This is for ITEMS, not BLOCKS + */ + public boolean onItemUse(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, World par3World, int par4, + int par5, int par6, int par7, float par8, float par9, float par10) { + if (par3World.isRemote) { + return true; + } else { + if (par7 == 0) { + --par5; + } + + if (par7 == 1) { + ++par5; + } + + if (par7 == 2) { + --par6; + } + + if (par7 == 3) { + ++par6; + } + + if (par7 == 4) { + --par4; + } + + if (par7 == 5) { + ++par4; + } + + if (!par2EntityPlayer.canPlayerEdit(par4, par5, par6, par7, par1ItemStack)) { + return false; + } else { + int var11 = par3World.getBlockId(par4, par5, par6); + + if (var11 == 0) { + par3World.playSoundEffect((double) par4 + 0.5D, (double) par5 + 0.5D, (double) par6 + 0.5D, + "fire.ignite", 1.0F, itemRand.nextFloat() * 0.4F + 0.8F); + par3World.setBlock(par4, par5, par6, Block.fire.blockID); + } + + if (!par2EntityPlayer.capabilities.isCreativeMode) { + --par1ItemStack.stackSize; + } + + return true; + } + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ItemFirework.java b/sp-server/src/main/java/net/minecraft/src/ItemFirework.java new file mode 100644 index 0000000..cf1ad20 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ItemFirework.java @@ -0,0 +1,29 @@ +package net.minecraft.src; + +public class ItemFirework extends Item { + public ItemFirework(int par1) { + super(par1); + } + + /** + * Callback for item usage. If the item does something special on right + * clicking, he will have one of those. Return True if something happen and + * false if it don't. This is for ITEMS, not BLOCKS + */ + public boolean onItemUse(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, World par3World, int par4, + int par5, int par6, int par7, float par8, float par9, float par10) { + if (!par3World.isRemote) { + EntityFireworkRocket var11 = new EntityFireworkRocket(par3World, (double) ((float) par4 + par8), + (double) ((float) par5 + par9), (double) ((float) par6 + par10), par1ItemStack); + par3World.spawnEntityInWorld(var11); + + if (!par2EntityPlayer.capabilities.isCreativeMode) { + --par1ItemStack.stackSize; + } + + return true; + } else { + return false; + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ItemFireworkCharge.java b/sp-server/src/main/java/net/minecraft/src/ItemFireworkCharge.java new file mode 100644 index 0000000..0cbd393 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ItemFireworkCharge.java @@ -0,0 +1,7 @@ +package net.minecraft.src; + +public class ItemFireworkCharge extends Item { + public ItemFireworkCharge(int par1) { + super(par1); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ItemFishingRod.java b/sp-server/src/main/java/net/minecraft/src/ItemFishingRod.java new file mode 100644 index 0000000..be8070c --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ItemFishingRod.java @@ -0,0 +1,33 @@ +package net.minecraft.src; + +public class ItemFishingRod extends Item { + public ItemFishingRod(int par1) { + super(par1); + this.setMaxDamage(64); + this.setMaxStackSize(1); + this.setCreativeTab(CreativeTabs.tabTools); + } + + /** + * Called whenever this item is equipped and the right mouse button is pressed. + * Args: itemStack, world, entityPlayer + */ + public ItemStack onItemRightClick(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer) { + if (par3EntityPlayer.fishEntity != null) { + int var4 = par3EntityPlayer.fishEntity.catchFish(); + par1ItemStack.damageItem(var4, par3EntityPlayer); + par3EntityPlayer.swingItem(); + } else { + par2World.playSoundAtEntity(par3EntityPlayer, "random.bow", 0.5F, + 0.4F / (itemRand.nextFloat() * 0.4F + 0.8F)); + + if (!par2World.isRemote) { + par2World.spawnEntityInWorld(new EntityFishHook(par2World, par3EntityPlayer)); + } + + par3EntityPlayer.swingItem(); + } + + return par1ItemStack; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ItemFlintAndSteel.java b/sp-server/src/main/java/net/minecraft/src/ItemFlintAndSteel.java new file mode 100644 index 0000000..f5a9b8d --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ItemFlintAndSteel.java @@ -0,0 +1,57 @@ +package net.minecraft.src; + +public class ItemFlintAndSteel extends Item { + public ItemFlintAndSteel(int par1) { + super(par1); + this.maxStackSize = 1; + this.setMaxDamage(64); + this.setCreativeTab(CreativeTabs.tabTools); + } + + /** + * Callback for item usage. If the item does something special on right + * clicking, he will have one of those. Return True if something happen and + * false if it don't. This is for ITEMS, not BLOCKS + */ + public boolean onItemUse(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, World par3World, int par4, + int par5, int par6, int par7, float par8, float par9, float par10) { + if (par7 == 0) { + --par5; + } + + if (par7 == 1) { + ++par5; + } + + if (par7 == 2) { + --par6; + } + + if (par7 == 3) { + ++par6; + } + + if (par7 == 4) { + --par4; + } + + if (par7 == 5) { + ++par4; + } + + if (!par2EntityPlayer.canPlayerEdit(par4, par5, par6, par7, par1ItemStack)) { + return false; + } else { + int var11 = par3World.getBlockId(par4, par5, par6); + + if (var11 == 0) { + par3World.playSoundEffect((double) par4 + 0.5D, (double) par5 + 0.5D, (double) par6 + 0.5D, + "fire.ignite", 1.0F, itemRand.nextFloat() * 0.4F + 0.8F); + par3World.setBlock(par4, par5, par6, Block.fire.blockID); + } + + par1ItemStack.damageItem(1, par2EntityPlayer); + return true; + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ItemFood.java b/sp-server/src/main/java/net/minecraft/src/ItemFood.java new file mode 100644 index 0000000..e79c8cb --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ItemFood.java @@ -0,0 +1,128 @@ +package net.minecraft.src; + +public class ItemFood extends Item { + /** Number of ticks to run while 'EnumAction'ing until result. */ + public final int itemUseDuration; + + /** The amount this food item heals the player. */ + private final int healAmount; + private final float saturationModifier; + + /** Whether wolves like this food (true for raw and cooked porkchop). */ + private final boolean isWolfsFavoriteMeat; + + /** + * If this field is true, the food can be consumed even if the player don't need + * to eat. + */ + private boolean alwaysEdible; + + /** + * represents the potion effect that will occurr upon eating this food. Set by + * setPotionEffect + */ + private int potionId; + + /** set by setPotionEffect */ + private int potionDuration; + + /** set by setPotionEffect */ + private int potionAmplifier; + + /** probably of the set potion effect occurring */ + private float potionEffectProbability; + + public ItemFood(int par1, int par2, float par3, boolean par4) { + super(par1); + this.itemUseDuration = 32; + this.healAmount = par2; + this.isWolfsFavoriteMeat = par4; + this.saturationModifier = par3; + this.setCreativeTab(CreativeTabs.tabFood); + } + + public ItemFood(int par1, int par2, boolean par3) { + this(par1, par2, 0.6F, par3); + } + + public ItemStack onEaten(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer) { + --par1ItemStack.stackSize; + par3EntityPlayer.getFoodStats().addStats(this); + par2World.playSoundAtEntity(par3EntityPlayer, "random.burp", 0.5F, par2World.rand.nextFloat() * 0.1F + 0.9F); + this.onFoodEaten(par1ItemStack, par2World, par3EntityPlayer); + return par1ItemStack; + } + + protected void onFoodEaten(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer) { + if (!par2World.isRemote && this.potionId > 0 && par2World.rand.nextFloat() < this.potionEffectProbability) { + par3EntityPlayer + .addPotionEffect(new PotionEffect(this.potionId, this.potionDuration * 20, this.potionAmplifier)); + } + } + + /** + * How long it takes to use or consume an item + */ + public int getMaxItemUseDuration(ItemStack par1ItemStack) { + return 32; + } + + /** + * returns the action that specifies what animation to play when the items is + * being used + */ + public EnumAction getItemUseAction(ItemStack par1ItemStack) { + return EnumAction.eat; + } + + /** + * Called whenever this item is equipped and the right mouse button is pressed. + * Args: itemStack, world, entityPlayer + */ + public ItemStack onItemRightClick(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer) { + if (par3EntityPlayer.canEat(this.alwaysEdible)) { + par3EntityPlayer.setItemInUse(par1ItemStack, this.getMaxItemUseDuration(par1ItemStack)); + } + + return par1ItemStack; + } + + public int getHealAmount() { + return this.healAmount; + } + + /** + * gets the saturationModifier of the ItemFood + */ + public float getSaturationModifier() { + return this.saturationModifier; + } + + /** + * Whether wolves like this food (true for raw and cooked porkchop). + */ + public boolean isWolfsFavoriteMeat() { + return this.isWolfsFavoriteMeat; + } + + /** + * sets a potion effect on the item. Args: int potionId, int duration (will be + * multiplied by 20), int amplifier, float probability of effect happening + */ + public ItemFood setPotionEffect(int par1, int par2, int par3, float par4) { + this.potionId = par1; + this.potionDuration = par2; + this.potionAmplifier = par3; + this.potionEffectProbability = par4; + return this; + } + + /** + * Set the field 'alwaysEdible' to true, and make the food edible even if the + * player don't need to eat. + */ + public ItemFood setAlwaysEdible() { + this.alwaysEdible = true; + return this; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ItemGlassBottle.java b/sp-server/src/main/java/net/minecraft/src/ItemGlassBottle.java new file mode 100644 index 0000000..b8e4015 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ItemGlassBottle.java @@ -0,0 +1,48 @@ +package net.minecraft.src; + +public class ItemGlassBottle extends Item { + public ItemGlassBottle(int par1) { + super(par1); + this.setCreativeTab(CreativeTabs.tabBrewing); + } + + /** + * Called whenever this item is equipped and the right mouse button is pressed. + * Args: itemStack, world, entityPlayer + */ + public ItemStack onItemRightClick(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer) { + MovingObjectPosition var4 = this.getMovingObjectPositionFromPlayer(par2World, par3EntityPlayer, true); + + if (var4 == null) { + return par1ItemStack; + } else { + if (var4.typeOfHit == EnumMovingObjectType.TILE) { + int var5 = var4.blockX; + int var6 = var4.blockY; + int var7 = var4.blockZ; + + if (!par2World.canMineBlock(par3EntityPlayer, var5, var6, var7)) { + return par1ItemStack; + } + + if (!par3EntityPlayer.canPlayerEdit(var5, var6, var7, var4.sideHit, par1ItemStack)) { + return par1ItemStack; + } + + if (par2World.getBlockMaterial(var5, var6, var7) == Material.water) { + --par1ItemStack.stackSize; + + if (par1ItemStack.stackSize <= 0) { + return new ItemStack(Item.potion); + } + + if (!par3EntityPlayer.inventory.addItemStackToInventory(new ItemStack(Item.potion))) { + par3EntityPlayer.dropPlayerItem(new ItemStack(Item.potion.itemID, 1, 0)); + } + } + } + + return par1ItemStack; + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ItemHangingEntity.java b/sp-server/src/main/java/net/minecraft/src/ItemHangingEntity.java new file mode 100644 index 0000000..836ea5c --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ItemHangingEntity.java @@ -0,0 +1,53 @@ +package net.minecraft.src; + +public class ItemHangingEntity extends Item { + private final Class hangingEntityClass; + + public ItemHangingEntity(int par1, Class par2Class) { + super(par1); + this.hangingEntityClass = par2Class; + this.setCreativeTab(CreativeTabs.tabDecorations); + } + + /** + * Callback for item usage. If the item does something special on right + * clicking, he will have one of those. Return True if something happen and + * false if it don't. This is for ITEMS, not BLOCKS + */ + public boolean onItemUse(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, World par3World, int par4, + int par5, int par6, int par7, float par8, float par9, float par10) { + if (par7 == 0) { + return false; + } else if (par7 == 1) { + return false; + } else { + int var11 = Direction.facingToDirection[par7]; + EntityHanging var12 = this.createHangingEntity(par3World, par4, par5, par6, var11); + + if (!par2EntityPlayer.canPlayerEdit(par4, par5, par6, par7, par1ItemStack)) { + return false; + } else { + if (var12 != null && var12.onValidSurface()) { + if (!par3World.isRemote) { + par3World.spawnEntityInWorld(var12); + } + + --par1ItemStack.stackSize; + } + + return true; + } + } + } + + /** + * Create the hanging entity associated to this item. + */ + private EntityHanging createHangingEntity(World par1World, int par2, int par3, int par4, int par5) { + return (EntityHanging) (this.hangingEntityClass == EntityPainting.class + ? new EntityPainting(par1World, par2, par3, par4, par5) + : (this.hangingEntityClass == EntityItemFrame.class + ? new EntityItemFrame(par1World, par2, par3, par4, par5) + : null)); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ItemHoe.java b/sp-server/src/main/java/net/minecraft/src/ItemHoe.java new file mode 100644 index 0000000..cb35f34 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ItemHoe.java @@ -0,0 +1,53 @@ +package net.minecraft.src; + +public class ItemHoe extends Item { + protected EnumToolMaterial theToolMaterial; + + public ItemHoe(int par1, EnumToolMaterial par2EnumToolMaterial) { + super(par1); + this.theToolMaterial = par2EnumToolMaterial; + this.maxStackSize = 1; + this.setMaxDamage(par2EnumToolMaterial.getMaxUses()); + this.setCreativeTab(CreativeTabs.tabTools); + } + + /** + * Callback for item usage. If the item does something special on right + * clicking, he will have one of those. Return True if something happen and + * false if it don't. This is for ITEMS, not BLOCKS + */ + public boolean onItemUse(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, World par3World, int par4, + int par5, int par6, int par7, float par8, float par9, float par10) { + if (!par2EntityPlayer.canPlayerEdit(par4, par5, par6, par7, par1ItemStack)) { + return false; + } else { + int var11 = par3World.getBlockId(par4, par5, par6); + int var12 = par3World.getBlockId(par4, par5 + 1, par6); + + if ((par7 == 0 || var12 != 0 || var11 != Block.grass.blockID) && var11 != Block.dirt.blockID) { + return false; + } else { + Block var13 = Block.tilledField; + par3World.playSoundEffect((double) ((float) par4 + 0.5F), (double) ((float) par5 + 0.5F), + (double) ((float) par6 + 0.5F), var13.stepSound.getStepSound(), + (var13.stepSound.getVolume() + 1.0F) / 2.0F, var13.stepSound.getPitch() * 0.8F); + + if (par3World.isRemote) { + return true; + } else { + par3World.setBlock(par4, par5, par6, var13.blockID); + par1ItemStack.damageItem(1, par2EntityPlayer); + return true; + } + } + } + } + + /** + * Returns the name of the material this tool is made from as it is declared in + * EnumToolMaterial (meaning diamond would return "EMERALD") + */ + public String getMaterialName() { + return this.theToolMaterial.toString(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ItemInWorldManager.java b/sp-server/src/main/java/net/minecraft/src/ItemInWorldManager.java new file mode 100644 index 0000000..3de549c --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ItemInWorldManager.java @@ -0,0 +1,323 @@ +package net.minecraft.src; + +public class ItemInWorldManager { + /** The world object that this object is connected to. */ + public World theWorld; + + /** The EntityPlayerMP object that this object is connected to. */ + public EntityPlayerMP thisPlayerMP; + private EnumGameType gameType; + + /** True if the player is destroying a block */ + private boolean isDestroyingBlock; + private int initialDamage; + private int curBlockX; + private int curBlockY; + private int curBlockZ; + private int curblockDamage; + + /** + * Set to true when the "finished destroying block" packet is received but the + * block wasn't fully damaged yet. The block will not be destroyed while this is + * false. + */ + private boolean receivedFinishDiggingPacket; + private int posX; + private int posY; + private int posZ; + private int field_73093_n; + private int durabilityRemainingOnBlock; + + public ItemInWorldManager(World par1World) { + this.gameType = EnumGameType.NOT_SET; + this.durabilityRemainingOnBlock = -1; + this.theWorld = par1World; + } + + public void setGameType(EnumGameType par1EnumGameType) { + this.gameType = par1EnumGameType; + par1EnumGameType.configurePlayerCapabilities(this.thisPlayerMP.capabilities); + this.thisPlayerMP.sendPlayerAbilities(); + } + + public EnumGameType getGameType() { + return this.gameType; + } + + /** + * Get if we are in creative game mode. + */ + public boolean isCreative() { + return this.gameType.isCreative(); + } + + /** + * if the gameType is currently NOT_SET then change it to par1 + */ + public void initializeGameType(EnumGameType par1EnumGameType) { + if (this.gameType == EnumGameType.NOT_SET) { + this.gameType = par1EnumGameType; + } + + this.setGameType(this.gameType); + } + + public void updateBlockRemoving() { + ++this.curblockDamage; + int var1; + float var4; + int var5; + + if (this.receivedFinishDiggingPacket) { + var1 = this.curblockDamage - this.field_73093_n; + int var2 = this.theWorld.getBlockId(this.posX, this.posY, this.posZ); + + if (var2 == 0) { + this.receivedFinishDiggingPacket = false; + } else { + Block var3 = Block.blocksList[var2]; + var4 = var3.getPlayerRelativeBlockHardness(this.thisPlayerMP, this.thisPlayerMP.worldObj, this.posX, + this.posY, this.posZ) * (float) (var1 + 1); + var5 = (int) (var4 * 10.0F); + + if (var5 != this.durabilityRemainingOnBlock) { + this.theWorld.destroyBlockInWorldPartially(this.thisPlayerMP.entityId, this.posX, this.posY, + this.posZ, var5); + this.durabilityRemainingOnBlock = var5; + } + + if (var4 >= 1.0F) { + this.receivedFinishDiggingPacket = false; + this.tryHarvestBlock(this.posX, this.posY, this.posZ); + } + } + } else if (this.isDestroyingBlock) { + var1 = this.theWorld.getBlockId(this.curBlockX, this.curBlockY, this.curBlockZ); + Block var6 = Block.blocksList[var1]; + + if (var6 == null) { + this.theWorld.destroyBlockInWorldPartially(this.thisPlayerMP.entityId, this.curBlockX, this.curBlockY, + this.curBlockZ, -1); + this.durabilityRemainingOnBlock = -1; + this.isDestroyingBlock = false; + } else { + int var7 = this.curblockDamage - this.initialDamage; + var4 = var6.getPlayerRelativeBlockHardness(this.thisPlayerMP, this.thisPlayerMP.worldObj, + this.curBlockX, this.curBlockY, this.curBlockZ) * (float) (var7 + 1); + var5 = (int) (var4 * 10.0F); + + if (var5 != this.durabilityRemainingOnBlock) { + this.theWorld.destroyBlockInWorldPartially(this.thisPlayerMP.entityId, this.curBlockX, + this.curBlockY, this.curBlockZ, var5); + this.durabilityRemainingOnBlock = var5; + } + } + } + } + + /** + * if not creative, it calls destroyBlockInWorldPartially untill the block is + * broken first. par4 is the specific side. tryHarvestBlock can also be the + * result of this call + */ + public void onBlockClicked(int par1, int par2, int par3, int par4) { + if (!this.gameType.isAdventure() || this.thisPlayerMP.canCurrentToolHarvestBlock(par1, par2, par3)) { + if (this.isCreative()) { + if (!this.theWorld.extinguishFire((EntityPlayer) null, par1, par2, par3, par4)) { + this.tryHarvestBlock(par1, par2, par3); + } + } else { + this.theWorld.extinguishFire((EntityPlayer) null, par1, par2, par3, par4); + this.initialDamage = this.curblockDamage; + float var5 = 1.0F; + int var6 = this.theWorld.getBlockId(par1, par2, par3); + + if (var6 > 0) { + Block.blocksList[var6].onBlockClicked(this.theWorld, par1, par2, par3, this.thisPlayerMP); + var5 = Block.blocksList[var6].getPlayerRelativeBlockHardness(this.thisPlayerMP, + this.thisPlayerMP.worldObj, par1, par2, par3); + } + + if (var6 > 0 && var5 >= 1.0F) { + this.tryHarvestBlock(par1, par2, par3); + } else { + this.isDestroyingBlock = true; + this.curBlockX = par1; + this.curBlockY = par2; + this.curBlockZ = par3; + int var7 = (int) (var5 * 10.0F); + this.theWorld.destroyBlockInWorldPartially(this.thisPlayerMP.entityId, par1, par2, par3, var7); + this.durabilityRemainingOnBlock = var7; + } + } + } + } + + public void blockRemoving(int par1, int par2, int par3) { + if (par1 == this.curBlockX && par2 == this.curBlockY && par3 == this.curBlockZ) { + int var4 = this.curblockDamage - this.initialDamage; + int var5 = this.theWorld.getBlockId(par1, par2, par3); + + if (var5 != 0) { + Block var6 = Block.blocksList[var5]; + float var7 = var6.getPlayerRelativeBlockHardness(this.thisPlayerMP, this.thisPlayerMP.worldObj, par1, + par2, par3) * (float) (var4 + 1); + + if (var7 >= 0.7F) { + this.isDestroyingBlock = false; + this.theWorld.destroyBlockInWorldPartially(this.thisPlayerMP.entityId, par1, par2, par3, -1); + this.tryHarvestBlock(par1, par2, par3); + } else if (!this.receivedFinishDiggingPacket) { + this.isDestroyingBlock = false; + this.receivedFinishDiggingPacket = true; + this.posX = par1; + this.posY = par2; + this.posZ = par3; + this.field_73093_n = this.initialDamage; + } + } + } + } + + /** + * note: this ignores the pars passed in and continues to destroy the + * onClickedBlock + */ + public void cancelDestroyingBlock(int par1, int par2, int par3) { + this.isDestroyingBlock = false; + this.theWorld.destroyBlockInWorldPartially(this.thisPlayerMP.entityId, this.curBlockX, this.curBlockY, + this.curBlockZ, -1); + } + + /** + * Removes a block and triggers the appropriate events + */ + private boolean removeBlock(int par1, int par2, int par3) { + Block var4 = Block.blocksList[this.theWorld.getBlockId(par1, par2, par3)]; + int var5 = this.theWorld.getBlockMetadata(par1, par2, par3); + + if (var4 != null) { + var4.onBlockHarvested(this.theWorld, par1, par2, par3, var5, this.thisPlayerMP); + } + + boolean var6 = this.theWorld.setBlockToAir(par1, par2, par3); + + if (var4 != null && var6) { + var4.onBlockDestroyedByPlayer(this.theWorld, par1, par2, par3, var5); + } + + return var6; + } + + /** + * Attempts to harvest a block at the given coordinate + */ + public boolean tryHarvestBlock(int par1, int par2, int par3) { + if (this.gameType.isAdventure() && !this.thisPlayerMP.canCurrentToolHarvestBlock(par1, par2, par3)) { + return false; + } else { + int var4 = this.theWorld.getBlockId(par1, par2, par3); + int var5 = this.theWorld.getBlockMetadata(par1, par2, par3); + this.theWorld.playAuxSFXAtEntity(this.thisPlayerMP, 2001, par1, par2, par3, + var4 + (this.theWorld.getBlockMetadata(par1, par2, par3) << 12)); + boolean var6 = this.removeBlock(par1, par2, par3); + + if (this.isCreative()) { + this.thisPlayerMP.playerNetServerHandler + .sendPacket(new Packet53BlockChange(par1, par2, par3, this.theWorld)); + } else { + ItemStack var7 = this.thisPlayerMP.getCurrentEquippedItem(); + boolean var8 = this.thisPlayerMP.canHarvestBlock(Block.blocksList[var4]); + + if (var7 != null) { + var7.onBlockDestroyed(this.theWorld, var4, par1, par2, par3, this.thisPlayerMP); + + if (var7.stackSize == 0) { + this.thisPlayerMP.destroyCurrentEquippedItem(); + } + } + + if (var6 && var8) { + Block.blocksList[var4].harvestBlock(this.theWorld, this.thisPlayerMP, par1, par2, par3, var5); + } + } + + return var6; + } + } + + /** + * Attempts to right-click use an item by the given EntityPlayer in the given + * World + */ + public boolean tryUseItem(EntityPlayer par1EntityPlayer, World par2World, ItemStack par3ItemStack) { + int var4 = par3ItemStack.stackSize; + int var5 = par3ItemStack.getItemDamage(); + ItemStack var6 = par3ItemStack.useItemRightClick(par2World, par1EntityPlayer); + + if (var6 == par3ItemStack && (var6 == null + || var6.stackSize == var4 && var6.getMaxItemUseDuration() <= 0 && var6.getItemDamage() == var5)) { + return false; + } else { + par1EntityPlayer.inventory.mainInventory[par1EntityPlayer.inventory.currentItem] = var6; + + if (this.isCreative()) { + var6.stackSize = var4; + + if (var6.isItemStackDamageable()) { + var6.setItemDamage(var5); + } + } + + if (var6.stackSize == 0) { + par1EntityPlayer.inventory.mainInventory[par1EntityPlayer.inventory.currentItem] = null; + } + + if (!par1EntityPlayer.isUsingItem()) { + ((EntityPlayerMP) par1EntityPlayer).sendContainerToPlayer(par1EntityPlayer.inventoryContainer); + } + + return true; + } + } + + /** + * Activate the clicked on block, otherwise use the held item. Args: player, + * world, itemStack, x, y, z, side, xOffset, yOffset, zOffset + */ + public boolean activateBlockOrUseItem(EntityPlayer par1EntityPlayer, World par2World, ItemStack par3ItemStack, + int par4, int par5, int par6, int par7, float par8, float par9, float par10) { + int var11; + + if (!par1EntityPlayer.isSneaking() || par1EntityPlayer.getHeldItem() == null) { + var11 = par2World.getBlockId(par4, par5, par6); + + if (var11 > 0 && Block.blocksList[var11].onBlockActivated(par2World, par4, par5, par6, par1EntityPlayer, + par7, par8, par9, par10)) { + return true; + } + } + + if (par3ItemStack == null) { + return false; + } else if (this.isCreative()) { + var11 = par3ItemStack.getItemDamage(); + int var12 = par3ItemStack.stackSize; + boolean var13 = par3ItemStack.tryPlaceItemIntoWorld(par1EntityPlayer, par2World, par4, par5, par6, par7, + par8, par9, par10); + par3ItemStack.setItemDamage(var11); + par3ItemStack.stackSize = var12; + return var13; + } else { + return par3ItemStack.tryPlaceItemIntoWorld(par1EntityPlayer, par2World, par4, par5, par6, par7, par8, par9, + par10); + } + } + + /** + * Sets the world instance. + */ + public void setWorld(WorldServer par1WorldServer) { + this.theWorld = par1WorldServer; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ItemLeaves.java b/sp-server/src/main/java/net/minecraft/src/ItemLeaves.java new file mode 100644 index 0000000..171a148 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ItemLeaves.java @@ -0,0 +1,30 @@ +package net.minecraft.src; + +public class ItemLeaves extends ItemBlock { + public ItemLeaves(int par1) { + super(par1); + this.setMaxDamage(0); + this.setHasSubtypes(true); + } + + /** + * Returns the metadata of the block which this Item (ItemBlock) can place + */ + public int getMetadata(int par1) { + return par1 | 4; + } + + /** + * Returns the unlocalized name of this item. This version accepts an ItemStack + * so different stacks can have different names based on their damage or NBT. + */ + public String getUnlocalizedName(ItemStack par1ItemStack) { + int var2 = par1ItemStack.getItemDamage(); + + if (var2 < 0 || var2 >= BlockLeaves.LEAF_TYPES.length) { + var2 = 0; + } + + return super.getUnlocalizedName() + "." + BlockLeaves.LEAF_TYPES[var2]; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ItemLilyPad.java b/sp-server/src/main/java/net/minecraft/src/ItemLilyPad.java new file mode 100644 index 0000000..12c1d80 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ItemLilyPad.java @@ -0,0 +1,45 @@ +package net.minecraft.src; + +public class ItemLilyPad extends ItemColored { + public ItemLilyPad(int par1) { + super(par1, false); + } + + /** + * Called whenever this item is equipped and the right mouse button is pressed. + * Args: itemStack, world, entityPlayer + */ + public ItemStack onItemRightClick(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer) { + MovingObjectPosition var4 = this.getMovingObjectPositionFromPlayer(par2World, par3EntityPlayer, true); + + if (var4 == null) { + return par1ItemStack; + } else { + if (var4.typeOfHit == EnumMovingObjectType.TILE) { + int var5 = var4.blockX; + int var6 = var4.blockY; + int var7 = var4.blockZ; + + if (!par2World.canMineBlock(par3EntityPlayer, var5, var6, var7)) { + return par1ItemStack; + } + + if (!par3EntityPlayer.canPlayerEdit(var5, var6, var7, var4.sideHit, par1ItemStack)) { + return par1ItemStack; + } + + if (par2World.getBlockMaterial(var5, var6, var7) == Material.water + && par2World.getBlockMetadata(var5, var6, var7) == 0 + && par2World.isAirBlock(var5, var6 + 1, var7)) { + par2World.setBlock(var5, var6 + 1, var7, Block.waterlily.blockID); + + if (!par3EntityPlayer.capabilities.isCreativeMode) { + --par1ItemStack.stackSize; + } + } + } + + return par1ItemStack; + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ItemMap.java b/sp-server/src/main/java/net/minecraft/src/ItemMap.java new file mode 100644 index 0000000..2c264de --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ItemMap.java @@ -0,0 +1,258 @@ +package net.minecraft.src; + +public class ItemMap extends ItemMapBase { + protected ItemMap(int par1) { + super(par1); + this.setHasSubtypes(true); + } + + public MapData getMapData(ItemStack par1ItemStack, World par2World) { + String var3 = "map_" + par1ItemStack.getItemDamage(); + MapData var4 = (MapData) par2World.loadItemData(MapData.class, var3); + + if (var4 == null && !par2World.isRemote) { + par1ItemStack.setItemDamage(par2World.getUniqueDataId("map")); + var3 = "map_" + par1ItemStack.getItemDamage(); + var4 = new MapData(var3); + var4.scale = 3; + int var5 = 128 * (1 << var4.scale); + var4.xCenter = Math.round((float) par2World.getWorldInfo().getSpawnX() / (float) var5) * var5; + var4.zCenter = Math.round((float) (par2World.getWorldInfo().getSpawnZ() / var5)) * var5; + var4.dimension = (byte) par2World.provider.dimensionId; + var4.markDirty(); + par2World.setItemData(var3, var4); + } + + return var4; + } + + public void updateMapData(World par1World, Entity par2Entity, MapData par3MapData) { + if (par1World.provider.dimensionId == par3MapData.dimension && par2Entity instanceof EntityPlayer) { + short var4 = 128; + short var5 = 128; + int var6 = 1 << par3MapData.scale; + int var7 = par3MapData.xCenter; + int var8 = par3MapData.zCenter; + int var9 = MathHelper.floor_double(par2Entity.posX - (double) var7) / var6 + var4 / 2; + int var10 = MathHelper.floor_double(par2Entity.posZ - (double) var8) / var6 + var5 / 2; + int var11 = 128 / var6; + + if (par1World.provider.hasNoSky) { + var11 /= 2; + } + + MapInfo var12 = par3MapData.func_82568_a((EntityPlayer) par2Entity); + ++var12.field_82569_d; + + for (int var13 = var9 - var11 + 1; var13 < var9 + var11; ++var13) { + if ((var13 & 15) == (var12.field_82569_d & 15)) { + int var14 = 255; + int var15 = 0; + double var16 = 0.0D; + + for (int var18 = var10 - var11 - 1; var18 < var10 + var11; ++var18) { + if (var13 >= 0 && var18 >= -1 && var13 < var4 && var18 < var5) { + int var19 = var13 - var9; + int var20 = var18 - var10; + boolean var21 = var19 * var19 + var20 * var20 > (var11 - 2) * (var11 - 2); + int var22 = (var7 / var6 + var13 - var4 / 2) * var6; + int var23 = (var8 / var6 + var18 - var5 / 2) * var6; + int[] var24 = new int[256]; + Chunk var25 = par1World.getChunkFromBlockCoords(var22, var23); + + if (!var25.isEmpty()) { + int var26 = var22 & 15; + int var27 = var23 & 15; + int var28 = 0; + double var29 = 0.0D; + int var31; + int var32; + int var33; + int var36; + + if (par1World.provider.hasNoSky) { + var31 = var22 + var23 * 231871; + var31 = var31 * var31 * 31287121 + var31 * 11; + + if ((var31 >> 20 & 1) == 0) { + var24[Block.dirt.blockID] += 10; + } else { + var24[Block.stone.blockID] += 10; + } + + var29 = 100.0D; + } else { + for (var31 = 0; var31 < var6; ++var31) { + for (var32 = 0; var32 < var6; ++var32) { + var33 = var25.getHeightValue(var31 + var26, var32 + var27) + 1; + int var34 = 0; + + if (var33 > 1) { + boolean var35; + + do { + var35 = true; + var34 = var25.getBlockID(var31 + var26, var33 - 1, var32 + var27); + + if (var34 == 0) { + var35 = false; + } else if (var33 > 0 && var34 > 0 + && Block.blocksList[var34].blockMaterial.materialMapColor == MapColor.airColor) { + var35 = false; + } + + if (!var35) { + --var33; + + if (var33 <= 0) { + break; + } + + var34 = var25.getBlockID(var31 + var26, var33 - 1, + var32 + var27); + } + } while (var33 > 0 && !var35); + + if (var33 > 0 && var34 != 0 + && Block.blocksList[var34].blockMaterial.isLiquid()) { + var36 = var33 - 1; + boolean var37 = false; + int var41; + + do { + var41 = var25.getBlockID(var31 + var26, var36--, var32 + var27); + ++var28; + } while (var36 > 0 && var41 != 0 + && Block.blocksList[var41].blockMaterial.isLiquid()); + } + } + + var29 += (double) var33 / (double) (var6 * var6); + ++var24[var34]; + } + } + } + + var28 /= var6 * var6; + var31 = 0; + var32 = 0; + + for (var33 = 0; var33 < 256; ++var33) { + if (var24[var33] > var31) { + var32 = var33; + var31 = var24[var33]; + } + } + + double var39 = (var29 - var16) * 4.0D / (double) (var6 + 4) + + ((double) (var13 + var18 & 1) - 0.5D) * 0.4D; + byte var40 = 1; + + if (var39 > 0.6D) { + var40 = 2; + } + + if (var39 < -0.6D) { + var40 = 0; + } + + var36 = 0; + + if (var32 > 0) { + MapColor var42 = Block.blocksList[var32].blockMaterial.materialMapColor; + + if (var42 == MapColor.waterColor) { + var39 = (double) var28 * 0.1D + (double) (var13 + var18 & 1) * 0.2D; + var40 = 1; + + if (var39 < 0.5D) { + var40 = 2; + } + + if (var39 > 0.9D) { + var40 = 0; + } + } + + var36 = var42.colorIndex; + } + + var16 = var29; + + if (var18 >= 0 && var19 * var19 + var20 * var20 < var11 * var11 + && (!var21 || (var13 + var18 & 1) != 0)) { + byte var43 = par3MapData.colors[var13 + var18 * var4]; + byte var38 = (byte) (var36 * 4 + var40); + + if (var43 != var38) { + if (var14 > var18) { + var14 = var18; + } + + if (var15 < var18) { + var15 = var18; + } + + par3MapData.colors[var13 + var18 * var4] = var38; + } + } + } + } + } + + if (var14 <= var15) { + par3MapData.setColumnDirty(var13, var14, var15); + } + } + } + } + } + + /** + * Called each tick as long the item is on a player inventory. Uses by maps to + * check if is on a player hand and update it's contents. + */ + public void onUpdate(ItemStack par1ItemStack, World par2World, Entity par3Entity, int par4, boolean par5) { + if (!par2World.isRemote) { + MapData var6 = this.getMapData(par1ItemStack, par2World); + + if (par3Entity instanceof EntityPlayer) { + EntityPlayer var7 = (EntityPlayer) par3Entity; + var6.updateVisiblePlayers(var7, par1ItemStack); + } + + if (par5) { + this.updateMapData(par2World, par3Entity, var6); + } + } + } + + public Packet getUpdatePacket(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer) { + byte[] var4 = this.getMapData(par1ItemStack, par2World).getUpdatePacketData(par1ItemStack, par2World, + par3EntityPlayer); + return var4 == null ? null + : new Packet131MapData((short) Item.map.itemID, (short) par1ItemStack.getItemDamage(), var4); + } + + /** + * Called when item is crafted/smelted. Used only by maps so far. + */ + public void onCreated(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer) { + if (par1ItemStack.hasTagCompound() && par1ItemStack.getTagCompound().getBoolean("map_is_scaling")) { + MapData var4 = Item.map.getMapData(par1ItemStack, par2World); + par1ItemStack.setItemDamage(par2World.getUniqueDataId("map")); + MapData var5 = new MapData("map_" + par1ItemStack.getItemDamage()); + var5.scale = (byte) (var4.scale + 1); + + if (var5.scale > 4) { + var5.scale = 4; + } + + var5.xCenter = var4.xCenter; + var5.zCenter = var4.zCenter; + var5.dimension = var4.dimension; + var5.markDirty(); + par2World.setItemData("map_" + par1ItemStack.getItemDamage(), var5); + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ItemMapBase.java b/sp-server/src/main/java/net/minecraft/src/ItemMapBase.java new file mode 100644 index 0000000..96aa888 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ItemMapBase.java @@ -0,0 +1,18 @@ +package net.minecraft.src; + +public class ItemMapBase extends Item { + protected ItemMapBase(int par1) { + super(par1); + } + + /** + * false for all Items except sub-classes of ItemMapBase + */ + public boolean isMap() { + return true; + } + + public Packet getUpdatePacket(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer) { + return null; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ItemMinecart.java b/sp-server/src/main/java/net/minecraft/src/ItemMinecart.java new file mode 100644 index 0000000..c3ae29b --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ItemMinecart.java @@ -0,0 +1,42 @@ +package net.minecraft.src; + +public class ItemMinecart extends Item { + private static final IBehaviorDispenseItem dispenserMinecartBehavior = new BehaviorDispenseMinecart(); + public int minecartType; + + public ItemMinecart(int par1, int par2) { + super(par1); + this.maxStackSize = 1; + this.minecartType = par2; + this.setCreativeTab(CreativeTabs.tabTransport); + BlockDispenser.dispenseBehaviorRegistry.putObject(this, dispenserMinecartBehavior); + } + + /** + * Callback for item usage. If the item does something special on right + * clicking, he will have one of those. Return True if something happen and + * false if it don't. This is for ITEMS, not BLOCKS + */ + public boolean onItemUse(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, World par3World, int par4, + int par5, int par6, int par7, float par8, float par9, float par10) { + int var11 = par3World.getBlockId(par4, par5, par6); + + if (BlockRailBase.isRailBlock(var11)) { + if (!par3World.isRemote) { + EntityMinecart var12 = EntityMinecart.createMinecart(par3World, (double) ((float) par4 + 0.5F), + (double) ((float) par5 + 0.5F), (double) ((float) par6 + 0.5F), this.minecartType); + + if (par1ItemStack.hasDisplayName()) { + var12.func_96094_a(par1ItemStack.getDisplayName()); + } + + par3World.spawnEntityInWorld(var12); + } + + --par1ItemStack.stackSize; + return true; + } else { + return false; + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ItemMonsterPlacer.java b/sp-server/src/main/java/net/minecraft/src/ItemMonsterPlacer.java new file mode 100644 index 0000000..1103880 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ItemMonsterPlacer.java @@ -0,0 +1,86 @@ +package net.minecraft.src; + +public class ItemMonsterPlacer extends Item { + public ItemMonsterPlacer(int par1) { + super(par1); + this.setHasSubtypes(true); + this.setCreativeTab(CreativeTabs.tabMisc); + } + + public String getItemDisplayName(ItemStack par1ItemStack) { + String var2 = ("" + StatCollector.translateToLocal(this.getUnlocalizedName() + ".name")).trim(); + String var3 = EntityList.getStringFromID(par1ItemStack.getItemDamage()); + + if (var3 != null) { + var2 = var2 + " " + StatCollector.translateToLocal("entity." + var3 + ".name"); + } + + return var2; + } + + /** + * Callback for item usage. If the item does something special on right + * clicking, he will have one of those. Return True if something happen and + * false if it don't. This is for ITEMS, not BLOCKS + */ + public boolean onItemUse(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, World par3World, int par4, + int par5, int par6, int par7, float par8, float par9, float par10) { + if (par3World.isRemote) { + return true; + } else { + int var11 = par3World.getBlockId(par4, par5, par6); + par4 += Facing.offsetsXForSide[par7]; + par5 += Facing.offsetsYForSide[par7]; + par6 += Facing.offsetsZForSide[par7]; + double var12 = 0.0D; + + if (par7 == 1 && Block.blocksList[var11] != null && Block.blocksList[var11].getRenderType() == 11) { + var12 = 0.5D; + } + + Entity var14 = spawnCreature(par3World, par1ItemStack.getItemDamage(), (double) par4 + 0.5D, + (double) par5 + var12, (double) par6 + 0.5D); + + if (var14 != null) { + if (var14 instanceof EntityLiving && par1ItemStack.hasDisplayName()) { + ((EntityLiving) var14).func_94058_c(par1ItemStack.getDisplayName()); + } + + if (!par2EntityPlayer.capabilities.isCreativeMode) { + --par1ItemStack.stackSize; + } + } + + return true; + } + } + + /** + * Spawns the creature specified by the egg's type in the location specified by + * the last three parameters. Parameters: world, entityID, x, y, z. + */ + public static Entity spawnCreature(World par0World, int par1, double par2, double par4, double par6) { + if (!EntityList.entityEggs.containsKey(Integer.valueOf(par1))) { + return null; + } else { + Entity var8 = null; + + for (int var9 = 0; var9 < 1; ++var9) { + var8 = EntityList.createEntityByID(par1, par0World); + + if (var8 != null && var8 instanceof EntityLiving) { + EntityLiving var10 = (EntityLiving) var8; + var8.setLocationAndAngles(par2, par4, par6, + MathHelper.wrapAngleTo180_float(par0World.rand.nextFloat() * 360.0F), 0.0F); + var10.rotationYawHead = var10.rotationYaw; + var10.renderYawOffset = var10.rotationYaw; + var10.initCreature(); + par0World.spawnEntityInWorld(var8); + var10.playLivingSound(); + } + } + + return var8; + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ItemMultiTextureTile.java b/sp-server/src/main/java/net/minecraft/src/ItemMultiTextureTile.java new file mode 100644 index 0000000..0f63e4c --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ItemMultiTextureTile.java @@ -0,0 +1,35 @@ +package net.minecraft.src; + +public class ItemMultiTextureTile extends ItemBlock { + private final Block theBlock; + private final String[] field_82804_b; + + public ItemMultiTextureTile(int par1, Block par2Block, String[] par3ArrayOfStr) { + super(par1); + this.theBlock = par2Block; + this.field_82804_b = par3ArrayOfStr; + this.setMaxDamage(0); + this.setHasSubtypes(true); + } + + /** + * Returns the metadata of the block which this Item (ItemBlock) can place + */ + public int getMetadata(int par1) { + return par1; + } + + /** + * Returns the unlocalized name of this item. This version accepts an ItemStack + * so different stacks can have different names based on their damage or NBT. + */ + public String getUnlocalizedName(ItemStack par1ItemStack) { + int var2 = par1ItemStack.getItemDamage(); + + if (var2 < 0 || var2 >= this.field_82804_b.length) { + var2 = 0; + } + + return super.getUnlocalizedName() + "." + this.field_82804_b[var2]; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ItemPickaxe.java b/sp-server/src/main/java/net/minecraft/src/ItemPickaxe.java new file mode 100644 index 0000000..2f6fdd3 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ItemPickaxe.java @@ -0,0 +1,50 @@ +package net.minecraft.src; + +public class ItemPickaxe extends ItemTool { + /** an array of the blocks this pickaxe is effective against */ + private static Block[] blocksEffectiveAgainst = new Block[] { Block.cobblestone, Block.stoneDoubleSlab, + Block.stoneSingleSlab, Block.stone, Block.sandStone, Block.cobblestoneMossy, Block.oreIron, Block.blockIron, + Block.oreCoal, Block.blockGold, Block.oreGold, Block.oreDiamond, Block.blockDiamond, Block.ice, + Block.netherrack, Block.oreLapis, Block.blockLapis, Block.oreRedstone, Block.oreRedstoneGlowing, Block.rail, + Block.railDetector, Block.railPowered, Block.railActivator }; + + protected ItemPickaxe(int par1, EnumToolMaterial par2EnumToolMaterial) { + super(par1, 2, par2EnumToolMaterial, blocksEffectiveAgainst); + } + + /** + * Returns if the item (tool) can harvest results from the block type. + */ + public boolean canHarvestBlock(Block par1Block) { + return par1Block == Block.obsidian ? this.toolMaterial.getHarvestLevel() == 3 + : (par1Block != Block.blockDiamond && par1Block != Block.oreDiamond + ? (par1Block != Block.oreEmerald && par1Block != Block.blockEmerald + ? (par1Block != Block.blockGold && par1Block != Block.oreGold + ? (par1Block != Block.blockIron && par1Block != Block.oreIron + ? (par1Block != Block.blockLapis && par1Block != Block.oreLapis + ? (par1Block != Block.oreRedstone + && par1Block != Block.oreRedstoneGlowing + ? (par1Block.blockMaterial == Material.rock + ? true + : (par1Block.blockMaterial == Material.iron + ? true + : par1Block.blockMaterial == Material.anvil)) + : this.toolMaterial.getHarvestLevel() >= 2) + : this.toolMaterial.getHarvestLevel() >= 1) + : this.toolMaterial.getHarvestLevel() >= 1) + : this.toolMaterial.getHarvestLevel() >= 2) + : this.toolMaterial.getHarvestLevel() >= 2) + : this.toolMaterial.getHarvestLevel() >= 2); + } + + /** + * Returns the strength of the stack against a given block. 1.0F base, + * (Quality+1)*2 if correct blocktype, 1.5F if sword + */ + public float getStrVsBlock(ItemStack par1ItemStack, Block par2Block) { + return par2Block != null && (par2Block.blockMaterial == Material.iron + || par2Block.blockMaterial == Material.anvil || par2Block.blockMaterial == Material.rock) + ? this.efficiencyOnProperMaterial + : super.getStrVsBlock(par1ItemStack, par2Block); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ItemPiston.java b/sp-server/src/main/java/net/minecraft/src/ItemPiston.java new file mode 100644 index 0000000..90cb239 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ItemPiston.java @@ -0,0 +1,14 @@ +package net.minecraft.src; + +public class ItemPiston extends ItemBlock { + public ItemPiston(int par1) { + super(par1); + } + + /** + * Returns the metadata of the block which this Item (ItemBlock) can place + */ + public int getMetadata(int par1) { + return 7; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ItemPotion.java b/sp-server/src/main/java/net/minecraft/src/ItemPotion.java new file mode 100644 index 0000000..8b9a7a2 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ItemPotion.java @@ -0,0 +1,175 @@ +package net.minecraft.src; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +public class ItemPotion extends Item { + /** + * Contains a map from integers to the list of potion effects that potions with + * that damage value confer (to prevent recalculating it). + */ + private HashMap effectCache = new HashMap(); + private static final Map field_77835_b = new LinkedHashMap(); + + public ItemPotion(int par1) { + super(par1); + this.setMaxStackSize(1); + this.setHasSubtypes(true); + this.setMaxDamage(0); + this.setCreativeTab(CreativeTabs.tabBrewing); + } + + /** + * Returns a list of potion effects for the specified itemstack. + */ + public List getEffects(ItemStack par1ItemStack) { + if (par1ItemStack.hasTagCompound() && par1ItemStack.getTagCompound().hasKey("CustomPotionEffects")) { + ArrayList var6 = new ArrayList(); + NBTTagList var3 = par1ItemStack.getTagCompound().getTagList("CustomPotionEffects"); + + for (int var4 = 0; var4 < var3.tagCount(); ++var4) { + NBTTagCompound var5 = (NBTTagCompound) var3.tagAt(var4); + var6.add(PotionEffect.readCustomPotionEffectFromNBT(var5)); + } + + return var6; + } else { + List var2 = (List) this.effectCache.get(Integer.valueOf(par1ItemStack.getItemDamage())); + + if (var2 == null) { + var2 = PotionHelper.getPotionEffects(par1ItemStack.getItemDamage(), false); + this.effectCache.put(Integer.valueOf(par1ItemStack.getItemDamage()), var2); + } + + return var2; + } + } + + /** + * Returns a list of effects for the specified potion damage value. + */ + public List getEffects(int par1) { + List var2 = (List) this.effectCache.get(Integer.valueOf(par1)); + + if (var2 == null) { + var2 = PotionHelper.getPotionEffects(par1, false); + this.effectCache.put(Integer.valueOf(par1), var2); + } + + return var2; + } + + public ItemStack onEaten(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer) { + if (!par3EntityPlayer.capabilities.isCreativeMode) { + --par1ItemStack.stackSize; + } + + if (!par2World.isRemote) { + List var4 = this.getEffects(par1ItemStack); + + if (var4 != null) { + Iterator var5 = var4.iterator(); + + while (var5.hasNext()) { + PotionEffect var6 = (PotionEffect) var5.next(); + par3EntityPlayer.addPotionEffect(new PotionEffect(var6)); + } + } + } + + if (!par3EntityPlayer.capabilities.isCreativeMode) { + if (par1ItemStack.stackSize <= 0) { + return new ItemStack(Item.glassBottle); + } + + par3EntityPlayer.inventory.addItemStackToInventory(new ItemStack(Item.glassBottle)); + } + + return par1ItemStack; + } + + /** + * How long it takes to use or consume an item + */ + public int getMaxItemUseDuration(ItemStack par1ItemStack) { + return 32; + } + + /** + * returns the action that specifies what animation to play when the items is + * being used + */ + public EnumAction getItemUseAction(ItemStack par1ItemStack) { + return EnumAction.drink; + } + + /** + * Called whenever this item is equipped and the right mouse button is pressed. + * Args: itemStack, world, entityPlayer + */ + public ItemStack onItemRightClick(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer) { + if (isSplash(par1ItemStack.getItemDamage())) { + if (!par3EntityPlayer.capabilities.isCreativeMode) { + --par1ItemStack.stackSize; + } + + par2World.playSoundAtEntity(par3EntityPlayer, "random.bow", 0.5F, + 0.4F / (itemRand.nextFloat() * 0.4F + 0.8F)); + + if (!par2World.isRemote) { + par2World.spawnEntityInWorld(new EntityPotion(par2World, par3EntityPlayer, par1ItemStack)); + } + + return par1ItemStack; + } else { + par3EntityPlayer.setItemInUse(par1ItemStack, this.getMaxItemUseDuration(par1ItemStack)); + return par1ItemStack; + } + } + + /** + * Callback for item usage. If the item does something special on right + * clicking, he will have one of those. Return True if something happen and + * false if it don't. This is for ITEMS, not BLOCKS + */ + public boolean onItemUse(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, World par3World, int par4, + int par5, int par6, int par7, float par8, float par9, float par10) { + return false; + } + + /** + * returns wether or not a potion is a throwable splash potion based on damage + * value + */ + public static boolean isSplash(int par0) { + return (par0 & 16384) != 0; + } + + public String getItemDisplayName(ItemStack par1ItemStack) { + if (par1ItemStack.getItemDamage() == 0) { + return StatCollector.translateToLocal("item.emptyPotion.name").trim(); + } else { + String var2 = ""; + + if (isSplash(par1ItemStack.getItemDamage())) { + var2 = StatCollector.translateToLocal("potion.prefix.grenade").trim() + " "; + } + + List var3 = Item.potion.getEffects(par1ItemStack); + String var4; + + if (var3 != null && !var3.isEmpty()) { + var4 = ((PotionEffect) var3.get(0)).getEffectName(); + var4 = var4 + ".postfix"; + return var2 + StatCollector.translateToLocal(var4).trim(); + } else { + var4 = PotionHelper.func_77905_c(par1ItemStack.getItemDamage()); + return StatCollector.translateToLocal(var4).trim() + " " + super.getItemDisplayName(par1ItemStack); + } + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ItemRecord.java b/sp-server/src/main/java/net/minecraft/src/ItemRecord.java new file mode 100644 index 0000000..d298b4c --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ItemRecord.java @@ -0,0 +1,42 @@ +package net.minecraft.src; + +import java.util.HashMap; +import java.util.Map; + +public class ItemRecord extends Item { + /** List of all record items and their names. */ + private static final Map records = new HashMap(); + + /** The name of the record. */ + public final String recordName; + + protected ItemRecord(int par1, String par2Str) { + super(par1); + this.recordName = par2Str; + this.maxStackSize = 1; + this.setCreativeTab(CreativeTabs.tabMisc); + records.put(par2Str, this); + } + + /** + * Callback for item usage. If the item does something special on right + * clicking, he will have one of those. Return True if something happen and + * false if it don't. This is for ITEMS, not BLOCKS + */ + public boolean onItemUse(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, World par3World, int par4, + int par5, int par6, int par7, float par8, float par9, float par10) { + if (par3World.getBlockId(par4, par5, par6) == Block.jukebox.blockID + && par3World.getBlockMetadata(par4, par5, par6) == 0) { + if (par3World.isRemote) { + return true; + } else { + ((BlockJukeBox) Block.jukebox).insertRecord(par3World, par4, par5, par6, par1ItemStack); + par3World.playAuxSFXAtEntity((EntityPlayer) null, 1005, par4, par5, par6, this.itemID); + --par1ItemStack.stackSize; + return true; + } + } else { + return false; + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ItemRedstone.java b/sp-server/src/main/java/net/minecraft/src/ItemRedstone.java new file mode 100644 index 0000000..7021b00 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ItemRedstone.java @@ -0,0 +1,57 @@ +package net.minecraft.src; + +public class ItemRedstone extends Item { + public ItemRedstone(int par1) { + super(par1); + this.setCreativeTab(CreativeTabs.tabRedstone); + } + + /** + * Callback for item usage. If the item does something special on right + * clicking, he will have one of those. Return True if something happen and + * false if it don't. This is for ITEMS, not BLOCKS + */ + public boolean onItemUse(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, World par3World, int par4, + int par5, int par6, int par7, float par8, float par9, float par10) { + if (par3World.getBlockId(par4, par5, par6) != Block.snow.blockID) { + if (par7 == 0) { + --par5; + } + + if (par7 == 1) { + ++par5; + } + + if (par7 == 2) { + --par6; + } + + if (par7 == 3) { + ++par6; + } + + if (par7 == 4) { + --par4; + } + + if (par7 == 5) { + ++par4; + } + + if (!par3World.isAirBlock(par4, par5, par6)) { + return false; + } + } + + if (!par2EntityPlayer.canPlayerEdit(par4, par5, par6, par7, par1ItemStack)) { + return false; + } else { + if (Block.redstoneWire.canPlaceBlockAt(par3World, par4, par5, par6)) { + --par1ItemStack.stackSize; + par3World.setBlock(par4, par5, par6, Block.redstoneWire.blockID); + } + + return true; + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ItemReed.java b/sp-server/src/main/java/net/minecraft/src/ItemReed.java new file mode 100644 index 0000000..0480f67 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ItemReed.java @@ -0,0 +1,76 @@ +package net.minecraft.src; + +public class ItemReed extends Item { + /** The ID of the block the reed will spawn when used from inventory bar. */ + private int spawnID; + + public ItemReed(int par1, Block par2Block) { + super(par1); + this.spawnID = par2Block.blockID; + } + + /** + * Callback for item usage. If the item does something special on right + * clicking, he will have one of those. Return True if something happen and + * false if it don't. This is for ITEMS, not BLOCKS + */ + public boolean onItemUse(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, World par3World, int par4, + int par5, int par6, int par7, float par8, float par9, float par10) { + int var11 = par3World.getBlockId(par4, par5, par6); + + if (var11 == Block.snow.blockID && (par3World.getBlockMetadata(par4, par5, par6) & 7) < 1) { + par7 = 1; + } else if (var11 != Block.vine.blockID && var11 != Block.tallGrass.blockID && var11 != Block.deadBush.blockID) { + if (par7 == 0) { + --par5; + } + + if (par7 == 1) { + ++par5; + } + + if (par7 == 2) { + --par6; + } + + if (par7 == 3) { + ++par6; + } + + if (par7 == 4) { + --par4; + } + + if (par7 == 5) { + ++par4; + } + } + + if (!par2EntityPlayer.canPlayerEdit(par4, par5, par6, par7, par1ItemStack)) { + return false; + } else if (par1ItemStack.stackSize == 0) { + return false; + } else { + if (par3World.canPlaceEntityOnSide(this.spawnID, par4, par5, par6, false, par7, (Entity) null, + par1ItemStack)) { + Block var12 = Block.blocksList[this.spawnID]; + int var13 = var12.onBlockPlaced(par3World, par4, par5, par6, par7, par8, par9, par10, 0); + + if (par3World.setBlock(par4, par5, par6, this.spawnID, var13, 3)) { + if (par3World.getBlockId(par4, par5, par6) == this.spawnID) { + Block.blocksList[this.spawnID].onBlockPlacedBy(par3World, par4, par5, par6, par2EntityPlayer, + par1ItemStack); + Block.blocksList[this.spawnID].onPostBlockPlaced(par3World, par4, par5, par6, var13); + } + + par3World.playSoundEffect((double) ((float) par4 + 0.5F), (double) ((float) par5 + 0.5F), + (double) ((float) par6 + 0.5F), var12.stepSound.getPlaceSound(), + (var12.stepSound.getVolume() + 1.0F) / 2.0F, var12.stepSound.getPitch() * 0.8F); + --par1ItemStack.stackSize; + } + } + + return true; + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ItemSaddle.java b/sp-server/src/main/java/net/minecraft/src/ItemSaddle.java new file mode 100644 index 0000000..f8d1ec9 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ItemSaddle.java @@ -0,0 +1,36 @@ +package net.minecraft.src; + +public class ItemSaddle extends Item { + public ItemSaddle(int par1) { + super(par1); + this.maxStackSize = 1; + this.setCreativeTab(CreativeTabs.tabTransport); + } + + /** + * Called when a player right clicks an entity with an item. + */ + public boolean useItemOnEntity(ItemStack par1ItemStack, EntityLiving par2EntityLiving) { + if (par2EntityLiving instanceof EntityPig) { + EntityPig var3 = (EntityPig) par2EntityLiving; + + if (!var3.getSaddled() && !var3.isChild()) { + var3.setSaddled(true); + --par1ItemStack.stackSize; + } + + return true; + } else { + return false; + } + } + + /** + * Current implementations of this method in child classes do not use the entry + * argument beside ev. They just raise the damage on the stack. + */ + public boolean hitEntity(ItemStack par1ItemStack, EntityLiving par2EntityLiving, EntityLiving par3EntityLiving) { + this.useItemOnEntity(par1ItemStack, par2EntityLiving); + return true; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ItemSeedFood.java b/sp-server/src/main/java/net/minecraft/src/ItemSeedFood.java new file mode 100644 index 0000000..98410e0 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ItemSeedFood.java @@ -0,0 +1,40 @@ +package net.minecraft.src; + +public class ItemSeedFood extends ItemFood { + /** Block ID of the crop this seed food should place. */ + private int cropId; + + /** Block ID of the soil this seed food should be planted on. */ + private int soilId; + + public ItemSeedFood(int par1, int par2, float par3, int par4, int par5) { + super(par1, par2, par3, false); + this.cropId = par4; + this.soilId = par5; + } + + /** + * Callback for item usage. If the item does something special on right + * clicking, he will have one of those. Return True if something happen and + * false if it don't. This is for ITEMS, not BLOCKS + */ + public boolean onItemUse(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, World par3World, int par4, + int par5, int par6, int par7, float par8, float par9, float par10) { + if (par7 != 1) { + return false; + } else if (par2EntityPlayer.canPlayerEdit(par4, par5, par6, par7, par1ItemStack) + && par2EntityPlayer.canPlayerEdit(par4, par5 + 1, par6, par7, par1ItemStack)) { + int var11 = par3World.getBlockId(par4, par5, par6); + + if (var11 == this.soilId && par3World.isAirBlock(par4, par5 + 1, par6)) { + par3World.setBlock(par4, par5 + 1, par6, this.cropId); + --par1ItemStack.stackSize; + return true; + } else { + return false; + } + } else { + return false; + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ItemSeeds.java b/sp-server/src/main/java/net/minecraft/src/ItemSeeds.java new file mode 100644 index 0000000..3011e3c --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ItemSeeds.java @@ -0,0 +1,43 @@ +package net.minecraft.src; + +public class ItemSeeds extends Item { + /** + * The type of block this seed turns into (wheat or pumpkin stems for instance) + */ + private int blockType; + + /** BlockID of the block the seeds can be planted on. */ + private int soilBlockID; + + public ItemSeeds(int par1, int par2, int par3) { + super(par1); + this.blockType = par2; + this.soilBlockID = par3; + this.setCreativeTab(CreativeTabs.tabMaterials); + } + + /** + * Callback for item usage. If the item does something special on right + * clicking, he will have one of those. Return True if something happen and + * false if it don't. This is for ITEMS, not BLOCKS + */ + public boolean onItemUse(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, World par3World, int par4, + int par5, int par6, int par7, float par8, float par9, float par10) { + if (par7 != 1) { + return false; + } else if (par2EntityPlayer.canPlayerEdit(par4, par5, par6, par7, par1ItemStack) + && par2EntityPlayer.canPlayerEdit(par4, par5 + 1, par6, par7, par1ItemStack)) { + int var11 = par3World.getBlockId(par4, par5, par6); + + if (var11 == this.soilBlockID && par3World.isAirBlock(par4, par5 + 1, par6)) { + par3World.setBlock(par4, par5 + 1, par6, this.blockType); + --par1ItemStack.stackSize; + return true; + } else { + return false; + } + } else { + return false; + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ItemShears.java b/sp-server/src/main/java/net/minecraft/src/ItemShears.java new file mode 100644 index 0000000..ef60930 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ItemShears.java @@ -0,0 +1,39 @@ +package net.minecraft.src; + +public class ItemShears extends Item { + public ItemShears(int par1) { + super(par1); + this.setMaxStackSize(1); + this.setMaxDamage(238); + this.setCreativeTab(CreativeTabs.tabTools); + } + + public boolean onBlockDestroyed(ItemStack par1ItemStack, World par2World, int par3, int par4, int par5, int par6, + EntityLiving par7EntityLiving) { + if (par3 != Block.leaves.blockID && par3 != Block.web.blockID && par3 != Block.tallGrass.blockID + && par3 != Block.vine.blockID && par3 != Block.tripWire.blockID) { + return super.onBlockDestroyed(par1ItemStack, par2World, par3, par4, par5, par6, par7EntityLiving); + } else { + par1ItemStack.damageItem(1, par7EntityLiving); + return true; + } + } + + /** + * Returns if the item (tool) can harvest results from the block type. + */ + public boolean canHarvestBlock(Block par1Block) { + return par1Block.blockID == Block.web.blockID || par1Block.blockID == Block.redstoneWire.blockID + || par1Block.blockID == Block.tripWire.blockID; + } + + /** + * Returns the strength of the stack against a given block. 1.0F base, + * (Quality+1)*2 if correct blocktype, 1.5F if sword + */ + public float getStrVsBlock(ItemStack par1ItemStack, Block par2Block) { + return par2Block.blockID != Block.web.blockID && par2Block.blockID != Block.leaves.blockID + ? (par2Block.blockID == Block.cloth.blockID ? 5.0F : super.getStrVsBlock(par1ItemStack, par2Block)) + : 15.0F; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ItemSign.java b/sp-server/src/main/java/net/minecraft/src/ItemSign.java new file mode 100644 index 0000000..003835c --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ItemSign.java @@ -0,0 +1,66 @@ +package net.minecraft.src; + +public class ItemSign extends Item { + public ItemSign(int par1) { + super(par1); + this.maxStackSize = 16; + this.setCreativeTab(CreativeTabs.tabDecorations); + } + + /** + * Callback for item usage. If the item does something special on right + * clicking, he will have one of those. Return True if something happen and + * false if it don't. This is for ITEMS, not BLOCKS + */ + public boolean onItemUse(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, World par3World, int par4, + int par5, int par6, int par7, float par8, float par9, float par10) { + if (par7 == 0) { + return false; + } else if (!par3World.getBlockMaterial(par4, par5, par6).isSolid()) { + return false; + } else { + if (par7 == 1) { + ++par5; + } + + if (par7 == 2) { + --par6; + } + + if (par7 == 3) { + ++par6; + } + + if (par7 == 4) { + --par4; + } + + if (par7 == 5) { + ++par4; + } + + if (!par2EntityPlayer.canPlayerEdit(par4, par5, par6, par7, par1ItemStack)) { + return false; + } else if (!Block.signPost.canPlaceBlockAt(par3World, par4, par5, par6)) { + return false; + } else { + if (par7 == 1) { + int var11 = MathHelper.floor_double( + (double) ((par2EntityPlayer.rotationYaw + 180.0F) * 16.0F / 360.0F) + 0.5D) & 15; + par3World.setBlock(par4, par5, par6, Block.signPost.blockID, var11, 2); + } else { + par3World.setBlock(par4, par5, par6, Block.signWall.blockID, par7, 2); + } + + --par1ItemStack.stackSize; + TileEntitySign var12 = (TileEntitySign) par3World.getBlockTileEntity(par4, par5, par6); + + if (var12 != null) { + par2EntityPlayer.displayGUIEditSign(var12); + } + + return true; + } + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ItemSimpleFoiled.java b/sp-server/src/main/java/net/minecraft/src/ItemSimpleFoiled.java new file mode 100644 index 0000000..7036df0 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ItemSimpleFoiled.java @@ -0,0 +1,7 @@ +package net.minecraft.src; + +public class ItemSimpleFoiled extends Item { + public ItemSimpleFoiled(int par1) { + super(par1); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ItemSkull.java b/sp-server/src/main/java/net/minecraft/src/ItemSkull.java new file mode 100644 index 0000000..6a8cc4e --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ItemSkull.java @@ -0,0 +1,108 @@ +package net.minecraft.src; + +public class ItemSkull extends Item { + private static final String[] skullTypes = new String[] { "skeleton", "wither", "zombie", "char", "creeper" }; + public static final String[] field_94587_a = new String[] { "skull_skeleton", "skull_wither", "skull_zombie", + "skull_char", "skull_creeper" }; + + public ItemSkull(int par1) { + super(par1); + this.setCreativeTab(CreativeTabs.tabDecorations); + this.setMaxDamage(0); + this.setHasSubtypes(true); + } + + /** + * Callback for item usage. If the item does something special on right + * clicking, he will have one of those. Return True if something happen and + * false if it don't. This is for ITEMS, not BLOCKS + */ + public boolean onItemUse(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, World par3World, int par4, + int par5, int par6, int par7, float par8, float par9, float par10) { + if (par7 == 0) { + return false; + } else if (!par3World.getBlockMaterial(par4, par5, par6).isSolid()) { + return false; + } else { + if (par7 == 1) { + ++par5; + } + + if (par7 == 2) { + --par6; + } + + if (par7 == 3) { + ++par6; + } + + if (par7 == 4) { + --par4; + } + + if (par7 == 5) { + ++par4; + } + + if (!par2EntityPlayer.canPlayerEdit(par4, par5, par6, par7, par1ItemStack)) { + return false; + } else if (!Block.skull.canPlaceBlockAt(par3World, par4, par5, par6)) { + return false; + } else { + par3World.setBlock(par4, par5, par6, Block.skull.blockID, par7, 2); + int var11 = 0; + + if (par7 == 1) { + var11 = MathHelper.floor_double((double) (par2EntityPlayer.rotationYaw * 16.0F / 360.0F) + 0.5D) + & 15; + } + + TileEntity var12 = par3World.getBlockTileEntity(par4, par5, par6); + + if (var12 != null && var12 instanceof TileEntitySkull) { + String var13 = ""; + + if (par1ItemStack.hasTagCompound() && par1ItemStack.getTagCompound().hasKey("SkullOwner")) { + var13 = par1ItemStack.getTagCompound().getString("SkullOwner"); + } + + ((TileEntitySkull) var12).setSkullType(par1ItemStack.getItemDamage(), var13); + ((TileEntitySkull) var12).setSkullRotation(var11); + ((BlockSkull) Block.skull).makeWither(par3World, par4, par5, par6, (TileEntitySkull) var12); + } + + --par1ItemStack.stackSize; + return true; + } + } + } + + /** + * Returns the metadata of the block which this Item (ItemBlock) can place + */ + public int getMetadata(int par1) { + return par1; + } + + /** + * Returns the unlocalized name of this item. This version accepts an ItemStack + * so different stacks can have different names based on their damage or NBT. + */ + public String getUnlocalizedName(ItemStack par1ItemStack) { + int var2 = par1ItemStack.getItemDamage(); + + if (var2 < 0 || var2 >= skullTypes.length) { + var2 = 0; + } + + return super.getUnlocalizedName() + "." + skullTypes[var2]; + } + + public String getItemDisplayName(ItemStack par1ItemStack) { + return par1ItemStack.getItemDamage() == 3 && par1ItemStack.hasTagCompound() + && par1ItemStack.getTagCompound().hasKey("SkullOwner") + ? StatCollector.translateToLocalFormatted("item.skull.player.name", + new Object[] { par1ItemStack.getTagCompound().getString("SkullOwner") }) + : super.getItemDisplayName(par1ItemStack); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ItemSlab.java b/sp-server/src/main/java/net/minecraft/src/ItemSlab.java new file mode 100644 index 0000000..2897d2e --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ItemSlab.java @@ -0,0 +1,123 @@ +package net.minecraft.src; + +public class ItemSlab extends ItemBlock { + private final boolean isFullBlock; + + /** Instance of BlockHalfSlab. */ + private final BlockHalfSlab theHalfSlab; + + /** The double-slab block corresponding to this item. */ + private final BlockHalfSlab doubleSlab; + + public ItemSlab(int par1, BlockHalfSlab par2BlockHalfSlab, BlockHalfSlab par3BlockHalfSlab, boolean par4) { + super(par1); + this.theHalfSlab = par2BlockHalfSlab; + this.doubleSlab = par3BlockHalfSlab; + this.isFullBlock = par4; + this.setMaxDamage(0); + this.setHasSubtypes(true); + } + + /** + * Returns the metadata of the block which this Item (ItemBlock) can place + */ + public int getMetadata(int par1) { + return par1; + } + + /** + * Returns the unlocalized name of this item. This version accepts an ItemStack + * so different stacks can have different names based on their damage or NBT. + */ + public String getUnlocalizedName(ItemStack par1ItemStack) { + return this.theHalfSlab.getFullSlabName(par1ItemStack.getItemDamage()); + } + + /** + * Callback for item usage. If the item does something special on right + * clicking, he will have one of those. Return True if something happen and + * false if it don't. This is for ITEMS, not BLOCKS + */ + public boolean onItemUse(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, World par3World, int par4, + int par5, int par6, int par7, float par8, float par9, float par10) { + if (this.isFullBlock) { + return super.onItemUse(par1ItemStack, par2EntityPlayer, par3World, par4, par5, par6, par7, par8, par9, + par10); + } else if (par1ItemStack.stackSize == 0) { + return false; + } else if (!par2EntityPlayer.canPlayerEdit(par4, par5, par6, par7, par1ItemStack)) { + return false; + } else { + int var11 = par3World.getBlockId(par4, par5, par6); + int var12 = par3World.getBlockMetadata(par4, par5, par6); + int var13 = var12 & 7; + boolean var14 = (var12 & 8) != 0; + + if ((par7 == 1 && !var14 || par7 == 0 && var14) && var11 == this.theHalfSlab.blockID + && var13 == par1ItemStack.getItemDamage()) { + if (par3World.checkNoEntityCollision( + this.doubleSlab.getCollisionBoundingBoxFromPool(par3World, par4, par5, par6)) + && par3World.setBlock(par4, par5, par6, this.doubleSlab.blockID, var13, 3)) { + par3World.playSoundEffect((double) ((float) par4 + 0.5F), (double) ((float) par5 + 0.5F), + (double) ((float) par6 + 0.5F), this.doubleSlab.stepSound.getPlaceSound(), + (this.doubleSlab.stepSound.getVolume() + 1.0F) / 2.0F, + this.doubleSlab.stepSound.getPitch() * 0.8F); + --par1ItemStack.stackSize; + } + + return true; + } else { + return this.func_77888_a(par1ItemStack, par2EntityPlayer, par3World, par4, par5, par6, par7) ? true + : super.onItemUse(par1ItemStack, par2EntityPlayer, par3World, par4, par5, par6, par7, par8, + par9, par10); + } + } + } + + private boolean func_77888_a(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, World par3World, int par4, + int par5, int par6, int par7) { + if (par7 == 0) { + --par5; + } + + if (par7 == 1) { + ++par5; + } + + if (par7 == 2) { + --par6; + } + + if (par7 == 3) { + ++par6; + } + + if (par7 == 4) { + --par4; + } + + if (par7 == 5) { + ++par4; + } + + int var8 = par3World.getBlockId(par4, par5, par6); + int var9 = par3World.getBlockMetadata(par4, par5, par6); + int var10 = var9 & 7; + + if (var8 == this.theHalfSlab.blockID && var10 == par1ItemStack.getItemDamage()) { + if (par3World.checkNoEntityCollision( + this.doubleSlab.getCollisionBoundingBoxFromPool(par3World, par4, par5, par6)) + && par3World.setBlock(par4, par5, par6, this.doubleSlab.blockID, var10, 3)) { + par3World.playSoundEffect((double) ((float) par4 + 0.5F), (double) ((float) par5 + 0.5F), + (double) ((float) par6 + 0.5F), this.doubleSlab.stepSound.getPlaceSound(), + (this.doubleSlab.stepSound.getVolume() + 1.0F) / 2.0F, + this.doubleSlab.stepSound.getPitch() * 0.8F); + --par1ItemStack.stackSize; + } + + return true; + } else { + return false; + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ItemSnow.java b/sp-server/src/main/java/net/minecraft/src/ItemSnow.java new file mode 100644 index 0000000..a1b5fc9 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ItemSnow.java @@ -0,0 +1,43 @@ +package net.minecraft.src; + +public class ItemSnow extends ItemBlockWithMetadata { + public ItemSnow(int par1, Block par2Block) { + super(par1, par2Block); + } + + /** + * Callback for item usage. If the item does something special on right + * clicking, he will have one of those. Return True if something happen and + * false if it don't. This is for ITEMS, not BLOCKS + */ + public boolean onItemUse(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, World par3World, int par4, + int par5, int par6, int par7, float par8, float par9, float par10) { + if (par1ItemStack.stackSize == 0) { + return false; + } else if (!par2EntityPlayer.canPlayerEdit(par4, par5, par6, par7, par1ItemStack)) { + return false; + } else { + int var11 = par3World.getBlockId(par4, par5, par6); + + if (var11 == Block.snow.blockID) { + Block var12 = Block.blocksList[this.getBlockID()]; + int var13 = par3World.getBlockMetadata(par4, par5, par6); + int var14 = var13 & 7; + + if (var14 <= 6 + && par3World.checkNoEntityCollision( + var12.getCollisionBoundingBoxFromPool(par3World, par4, par5, par6)) + && par3World.setBlockMetadata(par4, par5, par6, var14 + 1 | var13 & -8, 2)) { + par3World.playSoundEffect((double) ((float) par4 + 0.5F), (double) ((float) par5 + 0.5F), + (double) ((float) par6 + 0.5F), var12.stepSound.getPlaceSound(), + (var12.stepSound.getVolume() + 1.0F) / 2.0F, var12.stepSound.getPitch() * 0.8F); + --par1ItemStack.stackSize; + return true; + } + } + + return super.onItemUse(par1ItemStack, par2EntityPlayer, par3World, par4, par5, par6, par7, par8, par9, + par10); + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ItemSnowball.java b/sp-server/src/main/java/net/minecraft/src/ItemSnowball.java new file mode 100644 index 0000000..66757b2 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ItemSnowball.java @@ -0,0 +1,27 @@ +package net.minecraft.src; + +public class ItemSnowball extends Item { + public ItemSnowball(int par1) { + super(par1); + this.maxStackSize = 16; + this.setCreativeTab(CreativeTabs.tabMisc); + } + + /** + * Called whenever this item is equipped and the right mouse button is pressed. + * Args: itemStack, world, entityPlayer + */ + public ItemStack onItemRightClick(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer) { + if (!par3EntityPlayer.capabilities.isCreativeMode) { + --par1ItemStack.stackSize; + } + + par2World.playSoundAtEntity(par3EntityPlayer, "random.bow", 0.5F, 0.4F / (itemRand.nextFloat() * 0.4F + 0.8F)); + + if (!par2World.isRemote) { + par2World.spawnEntityInWorld(new EntitySnowball(par2World, par3EntityPlayer)); + } + + return par1ItemStack; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ItemSoup.java b/sp-server/src/main/java/net/minecraft/src/ItemSoup.java new file mode 100644 index 0000000..60dc9b4 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ItemSoup.java @@ -0,0 +1,13 @@ +package net.minecraft.src; + +public class ItemSoup extends ItemFood { + public ItemSoup(int par1, int par2) { + super(par1, par2, false); + this.setMaxStackSize(1); + } + + public ItemStack onEaten(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer) { + super.onEaten(par1ItemStack, par2World, par3EntityPlayer); + return new ItemStack(Item.bowlEmpty); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ItemSpade.java b/sp-server/src/main/java/net/minecraft/src/ItemSpade.java new file mode 100644 index 0000000..2eb0067 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ItemSpade.java @@ -0,0 +1,18 @@ +package net.minecraft.src; + +public class ItemSpade extends ItemTool { + /** an array of the blocks this spade is effective against */ + private static Block[] blocksEffectiveAgainst = new Block[] { Block.grass, Block.dirt, Block.sand, Block.gravel, + Block.snow, Block.blockSnow, Block.blockClay, Block.tilledField, Block.slowSand, Block.mycelium }; + + public ItemSpade(int par1, EnumToolMaterial par2EnumToolMaterial) { + super(par1, 1, par2EnumToolMaterial, blocksEffectiveAgainst); + } + + /** + * Returns if the item (tool) can harvest results from the block type. + */ + public boolean canHarvestBlock(Block par1Block) { + return par1Block == Block.snow ? true : par1Block == Block.blockSnow; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ItemStack.java b/sp-server/src/main/java/net/minecraft/src/ItemStack.java new file mode 100644 index 0000000..3e0651b --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ItemStack.java @@ -0,0 +1,574 @@ +package net.minecraft.src; + +import java.util.Random; + +public final class ItemStack { + /** Size of the stack. */ + public int stackSize; + + /** + * Number of animation frames to go when receiving an item (by walking into it, + * for example). + */ + public int animationsToGo; + + /** ID of the item. */ + public int itemID; + + /** + * A NBTTagMap containing data about an ItemStack. Can only be used for non + * stackable items + */ + public NBTTagCompound stackTagCompound; + + /** Damage dealt to the item or number of use. Raise when using items. */ + private int itemDamage; + + /** Item frame this stack is on, or null if not on an item frame. */ + private EntityItemFrame itemFrame; + + public ItemStack(Block par1Block) { + this(par1Block, 1); + } + + public ItemStack(Block par1Block, int par2) { + this(par1Block.blockID, par2, 0); + } + + public ItemStack(Block par1Block, int par2, int par3) { + this(par1Block.blockID, par2, par3); + } + + public ItemStack(Item par1Item) { + this(par1Item.itemID, 1, 0); + } + + public ItemStack(Item par1Item, int par2) { + this(par1Item.itemID, par2, 0); + } + + public ItemStack(Item par1Item, int par2, int par3) { + this(par1Item.itemID, par2, par3); + } + + public ItemStack(int par1, int par2, int par3) { + this.stackSize = 0; + this.itemFrame = null; + this.itemID = par1; + this.stackSize = par2; + this.itemDamage = par3; + + if (this.itemDamage < 0) { + this.itemDamage = 0; + } + } + + public static ItemStack loadItemStackFromNBT(NBTTagCompound par0NBTTagCompound) { + ItemStack var1 = new ItemStack(); + var1.readFromNBT(par0NBTTagCompound); + return var1.getItem() != null ? var1 : null; + } + + private ItemStack() { + this.stackSize = 0; + this.itemFrame = null; + } + + /** + * Remove the argument from the stack size. Return a new stack object with + * argument size. + */ + public ItemStack splitStack(int par1) { + ItemStack var2 = new ItemStack(this.itemID, par1, this.itemDamage); + + if (this.stackTagCompound != null) { + var2.stackTagCompound = (NBTTagCompound) this.stackTagCompound.copy(); + } + + this.stackSize -= par1; + return var2; + } + + /** + * Returns the object corresponding to the stack. + */ + public Item getItem() { + return Item.itemsList[this.itemID]; + } + + public boolean tryPlaceItemIntoWorld(EntityPlayer par1EntityPlayer, World par2World, int par3, int par4, int par5, + int par6, float par7, float par8, float par9) { + boolean var10 = this.getItem().onItemUse(this, par1EntityPlayer, par2World, par3, par4, par5, par6, par7, par8, + par9); + + if (var10) { + par1EntityPlayer.addStat(StatList.objectUseStats[this.itemID], 1); + } + + return var10; + } + + /** + * Returns the strength of the stack against a given block. + */ + public float getStrVsBlock(Block par1Block) { + return this.getItem().getStrVsBlock(this, par1Block); + } + + /** + * Called whenever this item stack is equipped and right clicked. Returns the + * new item stack to put in the position where this item is. Args: world, player + */ + public ItemStack useItemRightClick(World par1World, EntityPlayer par2EntityPlayer) { + return this.getItem().onItemRightClick(this, par1World, par2EntityPlayer); + } + + public ItemStack onFoodEaten(World par1World, EntityPlayer par2EntityPlayer) { + return this.getItem().onEaten(this, par1World, par2EntityPlayer); + } + + /** + * Write the stack fields to a NBT object. Return the new NBT object. + */ + public NBTTagCompound writeToNBT(NBTTagCompound par1NBTTagCompound) { + par1NBTTagCompound.setShort("id", (short) this.itemID); + par1NBTTagCompound.setByte("Count", (byte) this.stackSize); + par1NBTTagCompound.setShort("Damage", (short) this.itemDamage); + + if (this.stackTagCompound != null) { + par1NBTTagCompound.setTag("tag", this.stackTagCompound); + } + + return par1NBTTagCompound; + } + + /** + * Read the stack fields from a NBT object. + */ + public void readFromNBT(NBTTagCompound par1NBTTagCompound) { + this.itemID = par1NBTTagCompound.getShort("id"); + this.stackSize = par1NBTTagCompound.getByte("Count"); + this.itemDamage = par1NBTTagCompound.getShort("Damage"); + + if (this.itemDamage < 0) { + this.itemDamage = 0; + } + + if (par1NBTTagCompound.hasKey("tag")) { + this.stackTagCompound = par1NBTTagCompound.getCompoundTag("tag"); + } + } + + /** + * Returns maximum size of the stack. + */ + public int getMaxStackSize() { + return this.getItem().getItemStackLimit(); + } + + /** + * Returns true if the ItemStack can hold 2 or more units of the item. + */ + public boolean isStackable() { + return this.getMaxStackSize() > 1 && (!this.isItemStackDamageable() || !this.isItemDamaged()); + } + + /** + * true if this itemStack is damageable + */ + public boolean isItemStackDamageable() { + return Item.itemsList[this.itemID].getMaxDamage() > 0; + } + + public boolean getHasSubtypes() { + return Item.itemsList[this.itemID].getHasSubtypes(); + } + + /** + * returns true when a damageable item is damaged + */ + public boolean isItemDamaged() { + return this.isItemStackDamageable() && this.itemDamage > 0; + } + + /** + * gets the damage of an itemstack, for displaying purposes + */ + public int getItemDamageForDisplay() { + return this.itemDamage; + } + + /** + * gets the damage of an itemstack + */ + public int getItemDamage() { + return this.itemDamage; + } + + /** + * Sets the item damage of the ItemStack. + */ + public void setItemDamage(int par1) { + this.itemDamage = par1; + + if (this.itemDamage < 0) { + this.itemDamage = 0; + } + } + + /** + * Returns the max damage an item in the stack can take. + */ + public int getMaxDamage() { + return Item.itemsList[this.itemID].getMaxDamage(); + } + + public boolean func_96631_a(int par1, Random par2Random) { + if (!this.isItemStackDamageable()) { + return false; + } else { + if (par1 > 0) { + int var3 = EnchantmentHelper.getEnchantmentLevel(Enchantment.unbreaking.effectId, this); + int var4 = 0; + + for (int var5 = 0; var3 > 0 && var5 < par1; ++var5) { + if (EnchantmentDurability.func_92097_a(this, var3, par2Random)) { + ++var4; + } + } + + par1 -= var4; + + if (par1 <= 0) { + return false; + } + } + + this.itemDamage += par1; + return this.itemDamage > this.getMaxDamage(); + } + } + + /** + * Damages the item in the ItemStack + */ + public void damageItem(int par1, EntityLiving par2EntityLiving) { + if (!(par2EntityLiving instanceof EntityPlayer) + || !((EntityPlayer) par2EntityLiving).capabilities.isCreativeMode) { + if (this.isItemStackDamageable()) { + if (this.func_96631_a(par1, par2EntityLiving.getRNG())) { + par2EntityLiving.renderBrokenItemStack(this); + + if (par2EntityLiving instanceof EntityPlayer) { + ((EntityPlayer) par2EntityLiving).addStat(StatList.objectBreakStats[this.itemID], 1); + } + + --this.stackSize; + + if (this.stackSize < 0) { + this.stackSize = 0; + } + + this.itemDamage = 0; + } + } + } + } + + /** + * Calls the corresponding fct in di + */ + public void hitEntity(EntityLiving par1EntityLiving, EntityPlayer par2EntityPlayer) { + boolean var3 = Item.itemsList[this.itemID].hitEntity(this, par1EntityLiving, par2EntityPlayer); + + if (var3) { + par2EntityPlayer.addStat(StatList.objectUseStats[this.itemID], 1); + } + } + + public void onBlockDestroyed(World par1World, int par2, int par3, int par4, int par5, + EntityPlayer par6EntityPlayer) { + boolean var7 = Item.itemsList[this.itemID].onBlockDestroyed(this, par1World, par2, par3, par4, par5, + par6EntityPlayer); + + if (var7) { + par6EntityPlayer.addStat(StatList.objectUseStats[this.itemID], 1); + } + } + + /** + * Returns the damage against a given entity. + */ + public int getDamageVsEntity(Entity par1Entity) { + return Item.itemsList[this.itemID].getDamageVsEntity(par1Entity); + } + + /** + * Checks if the itemStack object can harvest a specified block + */ + public boolean canHarvestBlock(Block par1Block) { + return Item.itemsList[this.itemID].canHarvestBlock(par1Block); + } + + public boolean interactWith(EntityLiving par1EntityLiving) { + return Item.itemsList[this.itemID].useItemOnEntity(this, par1EntityLiving); + } + + /** + * Returns a new stack with the same properties. + */ + public ItemStack copy() { + ItemStack var1 = new ItemStack(this.itemID, this.stackSize, this.itemDamage); + + if (this.stackTagCompound != null) { + var1.stackTagCompound = (NBTTagCompound) this.stackTagCompound.copy(); + } + + return var1; + } + + public static boolean areItemStackTagsEqual(ItemStack par0ItemStack, ItemStack par1ItemStack) { + return par0ItemStack == null + && par1ItemStack == null + ? true + : (par0ItemStack != null && par1ItemStack != null + ? (par0ItemStack.stackTagCompound == null && par1ItemStack.stackTagCompound != null + ? false + : par0ItemStack.stackTagCompound == null || par0ItemStack.stackTagCompound + .equals(par1ItemStack.stackTagCompound)) + : false); + } + + /** + * compares ItemStack argument1 with ItemStack argument2; returns true if both + * ItemStacks are equal + */ + public static boolean areItemStacksEqual(ItemStack par0ItemStack, ItemStack par1ItemStack) { + return par0ItemStack == null && par1ItemStack == null ? true + : (par0ItemStack != null && par1ItemStack != null ? par0ItemStack.isItemStackEqual(par1ItemStack) + : false); + } + + /** + * compares ItemStack argument to the instance ItemStack; returns true if both + * ItemStacks are equal + */ + private boolean isItemStackEqual(ItemStack par1ItemStack) { + return this.stackSize != par1ItemStack.stackSize ? false + : (this.itemID != par1ItemStack.itemID ? false + : (this.itemDamage != par1ItemStack.itemDamage ? false + : (this.stackTagCompound == null && par1ItemStack.stackTagCompound != null ? false + : this.stackTagCompound == null + || this.stackTagCompound.equals(par1ItemStack.stackTagCompound)))); + } + + /** + * compares ItemStack argument to the instance ItemStack; returns true if the + * Items contained in both ItemStacks are equal + */ + public boolean isItemEqual(ItemStack par1ItemStack) { + return this.itemID == par1ItemStack.itemID && this.itemDamage == par1ItemStack.itemDamage; + } + + public String getItemName() { + return Item.itemsList[this.itemID].getUnlocalizedName(this); + } + + /** + * Creates a copy of a ItemStack, a null parameters will return a null. + */ + public static ItemStack copyItemStack(ItemStack par0ItemStack) { + return par0ItemStack == null ? null : par0ItemStack.copy(); + } + + public String toString() { + return this.stackSize + "x" + Item.itemsList[this.itemID].getUnlocalizedName() + "@" + this.itemDamage; + } + + /** + * Called each tick as long the ItemStack in on player inventory. Used to + * progress the pickup animation and update maps. + */ + public void updateAnimation(World par1World, Entity par2Entity, int par3, boolean par4) { + if (this.animationsToGo > 0) { + --this.animationsToGo; + } + + Item.itemsList[this.itemID].onUpdate(this, par1World, par2Entity, par3, par4); + } + + public void onCrafting(World par1World, EntityPlayer par2EntityPlayer, int par3) { + par2EntityPlayer.addStat(StatList.objectCraftStats[this.itemID], par3); + Item.itemsList[this.itemID].onCreated(this, par1World, par2EntityPlayer); + } + + public int getMaxItemUseDuration() { + return this.getItem().getMaxItemUseDuration(this); + } + + public EnumAction getItemUseAction() { + return this.getItem().getItemUseAction(this); + } + + /** + * Called when the player releases the use item button. Args: world, + * entityplayer, itemInUseCount + */ + public void onPlayerStoppedUsing(World par1World, EntityPlayer par2EntityPlayer, int par3) { + this.getItem().onPlayerStoppedUsing(this, par1World, par2EntityPlayer, par3); + } + + /** + * Returns true if the ItemStack has an NBTTagCompound. Currently used to store + * enchantments. + */ + public boolean hasTagCompound() { + return this.stackTagCompound != null; + } + + /** + * Returns the NBTTagCompound of the ItemStack. + */ + public NBTTagCompound getTagCompound() { + return this.stackTagCompound; + } + + public NBTTagList getEnchantmentTagList() { + return this.stackTagCompound == null ? null : (NBTTagList) this.stackTagCompound.getTag("ench"); + } + + /** + * Assigns a NBTTagCompound to the ItemStack, minecraft validates that only + * non-stackable items can have it. + */ + public void setTagCompound(NBTTagCompound par1NBTTagCompound) { + this.stackTagCompound = par1NBTTagCompound; + } + + /** + * returns the display name of the itemstack + */ + public String getDisplayName() { + String var1 = this.getItem().getItemDisplayName(this); + + if (this.stackTagCompound != null && this.stackTagCompound.hasKey("display")) { + NBTTagCompound var2 = this.stackTagCompound.getCompoundTag("display"); + + if (var2.hasKey("Name")) { + var1 = var2.getString("Name"); + } + } + + return var1; + } + + /** + * Sets the item's name (used by anvil to rename the items). + */ + public void setItemName(String par1Str) { + if (this.stackTagCompound == null) { + this.stackTagCompound = new NBTTagCompound("tag"); + } + + if (!this.stackTagCompound.hasKey("display")) { + this.stackTagCompound.setCompoundTag("display", new NBTTagCompound()); + } + + this.stackTagCompound.getCompoundTag("display").setString("Name", par1Str); + } + + /** + * Returns true if the itemstack has a display name + */ + public boolean hasDisplayName() { + return this.stackTagCompound == null ? false + : (!this.stackTagCompound.hasKey("display") ? false + : this.stackTagCompound.getCompoundTag("display").hasKey("Name")); + } + + /** + * True if it is a tool and has no enchantments to begin with + */ + public boolean isItemEnchantable() { + return !this.getItem().isItemTool(this) ? false : !this.isItemEnchanted(); + } + + /** + * Adds an enchantment with a desired level on the ItemStack. + */ + public void addEnchantment(Enchantment par1Enchantment, int par2) { + if (this.stackTagCompound == null) { + this.setTagCompound(new NBTTagCompound()); + } + + if (!this.stackTagCompound.hasKey("ench")) { + this.stackTagCompound.setTag("ench", new NBTTagList("ench")); + } + + NBTTagList var3 = (NBTTagList) this.stackTagCompound.getTag("ench"); + NBTTagCompound var4 = new NBTTagCompound(); + var4.setShort("id", (short) par1Enchantment.effectId); + var4.setShort("lvl", (short) ((byte) par2)); + var3.appendTag(var4); + } + + /** + * True if the item has enchantment data + */ + public boolean isItemEnchanted() { + return this.stackTagCompound != null && this.stackTagCompound.hasKey("ench"); + } + + public void setTagInfo(String par1Str, NBTBase par2NBTBase) { + if (this.stackTagCompound == null) { + this.setTagCompound(new NBTTagCompound()); + } + + this.stackTagCompound.setTag(par1Str, par2NBTBase); + } + + public boolean func_82835_x() { + return this.getItem().func_82788_x(); + } + + /** + * Return whether this stack is on an item frame. + */ + public boolean isOnItemFrame() { + return this.itemFrame != null; + } + + /** + * Set the item frame this stack is on. + */ + public void setItemFrame(EntityItemFrame par1EntityItemFrame) { + this.itemFrame = par1EntityItemFrame; + } + + /** + * Return the item frame this stack is on. Returns null if not on an item frame. + */ + public EntityItemFrame getItemFrame() { + return this.itemFrame; + } + + /** + * Get this stack's repair cost, or 0 if no repair cost is defined. + */ + public int getRepairCost() { + return this.hasTagCompound() && this.stackTagCompound.hasKey("RepairCost") + ? this.stackTagCompound.getInteger("RepairCost") + : 0; + } + + /** + * Set this stack's repair cost. + */ + public void setRepairCost(int par1) { + if (!this.hasTagCompound()) { + this.stackTagCompound = new NBTTagCompound("tag"); + } + + this.stackTagCompound.setInteger("RepairCost", par1); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ItemSword.java b/sp-server/src/main/java/net/minecraft/src/ItemSword.java new file mode 100644 index 0000000..af983ae --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ItemSword.java @@ -0,0 +1,112 @@ +package net.minecraft.src; + +public class ItemSword extends Item { + private int weaponDamage; + private final EnumToolMaterial toolMaterial; + + public ItemSword(int par1, EnumToolMaterial par2EnumToolMaterial) { + super(par1); + this.toolMaterial = par2EnumToolMaterial; + this.maxStackSize = 1; + this.setMaxDamage(par2EnumToolMaterial.getMaxUses()); + this.setCreativeTab(CreativeTabs.tabCombat); + this.weaponDamage = 4 + par2EnumToolMaterial.getDamageVsEntity(); + } + + public int func_82803_g() { + return this.toolMaterial.getDamageVsEntity(); + } + + /** + * Returns the strength of the stack against a given block. 1.0F base, + * (Quality+1)*2 if correct blocktype, 1.5F if sword + */ + public float getStrVsBlock(ItemStack par1ItemStack, Block par2Block) { + if (par2Block.blockID == Block.web.blockID) { + return 15.0F; + } else { + Material var3 = par2Block.blockMaterial; + return var3 != Material.plants && var3 != Material.vine && var3 != Material.coral && var3 != Material.leaves + && var3 != Material.pumpkin ? 1.0F : 1.5F; + } + } + + /** + * Current implementations of this method in child classes do not use the entry + * argument beside ev. They just raise the damage on the stack. + */ + public boolean hitEntity(ItemStack par1ItemStack, EntityLiving par2EntityLiving, EntityLiving par3EntityLiving) { + par1ItemStack.damageItem(1, par3EntityLiving); + return true; + } + + public boolean onBlockDestroyed(ItemStack par1ItemStack, World par2World, int par3, int par4, int par5, int par6, + EntityLiving par7EntityLiving) { + if ((double) Block.blocksList[par3].getBlockHardness(par2World, par4, par5, par6) != 0.0D) { + par1ItemStack.damageItem(2, par7EntityLiving); + } + + return true; + } + + /** + * Returns the damage against a given entity. + */ + public int getDamageVsEntity(Entity par1Entity) { + return this.weaponDamage; + } + + /** + * returns the action that specifies what animation to play when the items is + * being used + */ + public EnumAction getItemUseAction(ItemStack par1ItemStack) { + return EnumAction.block; + } + + /** + * How long it takes to use or consume an item + */ + public int getMaxItemUseDuration(ItemStack par1ItemStack) { + return 72000; + } + + /** + * Called whenever this item is equipped and the right mouse button is pressed. + * Args: itemStack, world, entityPlayer + */ + public ItemStack onItemRightClick(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer) { + par3EntityPlayer.setItemInUse(par1ItemStack, this.getMaxItemUseDuration(par1ItemStack)); + return par1ItemStack; + } + + /** + * Returns if the item (tool) can harvest results from the block type. + */ + public boolean canHarvestBlock(Block par1Block) { + return par1Block.blockID == Block.web.blockID; + } + + /** + * Return the enchantability factor of the item, most of the time is based on + * material. + */ + public int getItemEnchantability() { + return this.toolMaterial.getEnchantability(); + } + + /** + * Return the name for this tool's material. + */ + public String getToolMaterialName() { + return this.toolMaterial.toString(); + } + + /** + * Return whether this item is repairable in an anvil. + */ + public boolean getIsRepairable(ItemStack par1ItemStack, ItemStack par2ItemStack) { + return this.toolMaterial.getToolCraftingMaterial() == par2ItemStack.itemID ? true + : super.getIsRepairable(par1ItemStack, par2ItemStack); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ItemTool.java b/sp-server/src/main/java/net/minecraft/src/ItemTool.java new file mode 100644 index 0000000..c9276e4 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ItemTool.java @@ -0,0 +1,86 @@ +package net.minecraft.src; + +public class ItemTool extends Item { + /** Array of blocks the tool has extra effect against. */ + private Block[] blocksEffectiveAgainst; + protected float efficiencyOnProperMaterial = 4.0F; + + /** Damage versus entities. */ + private int damageVsEntity; + + /** The material this tool is made from. */ + protected EnumToolMaterial toolMaterial; + + protected ItemTool(int par1, int par2, EnumToolMaterial par3EnumToolMaterial, Block[] par4ArrayOfBlock) { + super(par1); + this.toolMaterial = par3EnumToolMaterial; + this.blocksEffectiveAgainst = par4ArrayOfBlock; + this.maxStackSize = 1; + this.setMaxDamage(par3EnumToolMaterial.getMaxUses()); + this.efficiencyOnProperMaterial = par3EnumToolMaterial.getEfficiencyOnProperMaterial(); + this.damageVsEntity = par2 + par3EnumToolMaterial.getDamageVsEntity(); + this.setCreativeTab(CreativeTabs.tabTools); + } + + /** + * Returns the strength of the stack against a given block. 1.0F base, + * (Quality+1)*2 if correct blocktype, 1.5F if sword + */ + public float getStrVsBlock(ItemStack par1ItemStack, Block par2Block) { + for (int var3 = 0; var3 < this.blocksEffectiveAgainst.length; ++var3) { + if (this.blocksEffectiveAgainst[var3] == par2Block) { + return this.efficiencyOnProperMaterial; + } + } + + return 1.0F; + } + + /** + * Current implementations of this method in child classes do not use the entry + * argument beside ev. They just raise the damage on the stack. + */ + public boolean hitEntity(ItemStack par1ItemStack, EntityLiving par2EntityLiving, EntityLiving par3EntityLiving) { + par1ItemStack.damageItem(2, par3EntityLiving); + return true; + } + + public boolean onBlockDestroyed(ItemStack par1ItemStack, World par2World, int par3, int par4, int par5, int par6, + EntityLiving par7EntityLiving) { + if ((double) Block.blocksList[par3].getBlockHardness(par2World, par4, par5, par6) != 0.0D) { + par1ItemStack.damageItem(1, par7EntityLiving); + } + + return true; + } + + /** + * Returns the damage against a given entity. + */ + public int getDamageVsEntity(Entity par1Entity) { + return this.damageVsEntity; + } + + /** + * Return the enchantability factor of the item, most of the time is based on + * material. + */ + public int getItemEnchantability() { + return this.toolMaterial.getEnchantability(); + } + + /** + * Return the name for this tool's material. + */ + public String getToolMaterialName() { + return this.toolMaterial.toString(); + } + + /** + * Return whether this item is repairable in an anvil. + */ + public boolean getIsRepairable(ItemStack par1ItemStack, ItemStack par2ItemStack) { + return this.toolMaterial.getToolCraftingMaterial() == par2ItemStack.itemID ? true + : super.getIsRepairable(par1ItemStack, par2ItemStack); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ItemWritableBook.java b/sp-server/src/main/java/net/minecraft/src/ItemWritableBook.java new file mode 100644 index 0000000..6380cc8 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ItemWritableBook.java @@ -0,0 +1,49 @@ +package net.minecraft.src; + +public class ItemWritableBook extends Item { + public ItemWritableBook(int par1) { + super(par1); + this.setMaxStackSize(1); + } + + /** + * Called whenever this item is equipped and the right mouse button is pressed. + * Args: itemStack, world, entityPlayer + */ + public ItemStack onItemRightClick(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer) { + par3EntityPlayer.displayGUIBook(par1ItemStack); + return par1ItemStack; + } + + /** + * If this function returns true (or the item is damageable), the ItemStack's + * NBT tag will be sent to the client. + */ + public boolean getShareTag() { + return true; + } + + public static boolean validBookTagPages(NBTTagCompound par0NBTTagCompound) { + if (par0NBTTagCompound == null) { + return false; + } else if (!par0NBTTagCompound.hasKey("pages")) { + return false; + } else { + NBTTagList var1 = (NBTTagList) par0NBTTagCompound.getTag("pages"); + + for (int var2 = 0; var2 < var1.tagCount(); ++var2) { + NBTTagString var3 = (NBTTagString) var1.tagAt(var2); + + if (var3.data == null) { + return false; + } + + if (var3.data.length() > 256) { + return false; + } + } + + return true; + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/LogAgent.java b/sp-server/src/main/java/net/minecraft/src/LogAgent.java new file mode 100644 index 0000000..5073fe1 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/LogAgent.java @@ -0,0 +1,81 @@ +package net.minecraft.src; + +import java.util.logging.ConsoleHandler; +import java.util.logging.FileHandler; +import java.util.logging.Handler; +import java.util.logging.Level; +import java.util.logging.Logger; + +public class LogAgent implements ILogAgent { + private final Logger serverLogger; + private final String logFile; + private final String loggerName; + private final String loggerPrefix; + + public LogAgent(String par1Str, String par2Str, String par3Str) { + this.serverLogger = Logger.getLogger(par1Str); + this.loggerName = par1Str; + this.loggerPrefix = par2Str; + this.logFile = par3Str; + this.setupLogger(); + } + + /** + * Sets up the logger for usage. + */ + private void setupLogger() { + this.serverLogger.setUseParentHandlers(false); + Handler[] var1 = this.serverLogger.getHandlers(); + int var2 = var1.length; + + for (int var3 = 0; var3 < var2; ++var3) { + Handler var4 = var1[var3]; + this.serverLogger.removeHandler(var4); + } + + LogFormatter var6 = new LogFormatter(this, (LogAgentINNER1) null); + ConsoleHandler var7 = new ConsoleHandler(); + var7.setFormatter(var6); + this.serverLogger.addHandler(var7); + + try { + FileHandler var8 = new FileHandler(this.logFile, true); + var8.setFormatter(var6); + this.serverLogger.addHandler(var8); + } catch (Exception var5) { + this.serverLogger.log(Level.WARNING, "Failed to log " + this.loggerName + " to " + this.logFile, var5); + } + } + + public Logger getServerLogger() { + return this.serverLogger; + } + + public void func_98233_a(String par1Str) { + this.serverLogger.log(Level.INFO, par1Str); + } + + public void func_98236_b(String par1Str) { + this.serverLogger.log(Level.WARNING, par1Str); + } + + public void logWarningFormatted(String par1Str, Object... par2ArrayOfObj) { + this.serverLogger.log(Level.WARNING, par1Str, par2ArrayOfObj); + } + + public void logWarningException(String par1Str, Throwable par2Throwable) { + this.serverLogger.log(Level.WARNING, par1Str, par2Throwable); + } + + public void logSevere(String par1Str) { + this.serverLogger.log(Level.SEVERE, par1Str); + } + + public void logSevereException(String par1Str, Throwable par2Throwable) { + this.serverLogger.log(Level.SEVERE, par1Str, par2Throwable); + } + + static String func_98237_a(LogAgent par0LogAgent) { + return par0LogAgent.loggerPrefix; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/LogAgentINNER1.java b/sp-server/src/main/java/net/minecraft/src/LogAgentINNER1.java new file mode 100644 index 0000000..9e23536 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/LogAgentINNER1.java @@ -0,0 +1,4 @@ +package net.minecraft.src; + +class LogAgentINNER1 { +} diff --git a/sp-server/src/main/java/net/minecraft/src/LogFormatter.java b/sp-server/src/main/java/net/minecraft/src/LogFormatter.java new file mode 100644 index 0000000..daeeb5a --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/LogFormatter.java @@ -0,0 +1,44 @@ +package net.minecraft.src; + +import java.io.PrintWriter; +import java.io.StringWriter; +import java.text.SimpleDateFormat; +import java.util.logging.Formatter; +import java.util.logging.LogRecord; + +class LogFormatter extends Formatter { + private SimpleDateFormat field_98228_b; + + final LogAgent field_98229_a; + + private LogFormatter(LogAgent par1LogAgent) { + this.field_98229_a = par1LogAgent; + this.field_98228_b = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + } + + public String format(LogRecord par1LogRecord) { + StringBuilder var2 = new StringBuilder(); + var2.append(this.field_98228_b.format(Long.valueOf(par1LogRecord.getMillis()))); + + if (LogAgent.func_98237_a(this.field_98229_a) != null) { + var2.append(LogAgent.func_98237_a(this.field_98229_a)); + } + + var2.append(" [").append(par1LogRecord.getLevel().getName()).append("] "); + var2.append(this.formatMessage(par1LogRecord)); + var2.append('\n'); + Throwable var3 = par1LogRecord.getThrown(); + + if (var3 != null) { + StringWriter var4 = new StringWriter(); + var3.printStackTrace(new PrintWriter(var4)); + var2.append(var4.toString()); + } + + return var2.toString(); + } + + LogFormatter(LogAgent par1LogAgent, LogAgentINNER1 par2LogAgentINNER1) { + this(par1LogAgent); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/LongHashMap.java b/sp-server/src/main/java/net/minecraft/src/LongHashMap.java new file mode 100644 index 0000000..1cce9e8 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/LongHashMap.java @@ -0,0 +1,201 @@ +package net.minecraft.src; + +public class LongHashMap { + /** the array of all elements in the hash */ + private transient LongHashMapEntry[] hashArray = new LongHashMapEntry[16]; + + /** the number of elements in the hash array */ + private transient int numHashElements; + + /** + * the maximum amount of elements in the hash (probably 3/4 the size due to meh + * hashing function) + */ + private int capacity = 12; + + /** + * percent of the hasharray that can be used without hash colliding probably + */ + private final float percentUseable = 0.75F; + + /** count of times elements have been added/removed */ + private transient volatile int modCount; + + /** + * returns the hashed key given the original key + */ + private static int getHashedKey(long par0) { + return hash((int) (par0 ^ par0 >>> 32)); + } + + /** + * the hash function + */ + private static int hash(int par0) { + par0 ^= par0 >>> 20 ^ par0 >>> 12; + return par0 ^ par0 >>> 7 ^ par0 >>> 4; + } + + /** + * gets the index in the hash given the array length and the hashed key + */ + private static int getHashIndex(int par0, int par1) { + return par0 & par1 - 1; + } + + public int getNumHashElements() { + return this.numHashElements; + } + + /** + * get the value from the map given the key + */ + public Object getValueByKey(long par1) { + int var3 = getHashedKey(par1); + + for (LongHashMapEntry var4 = this.hashArray[getHashIndex(var3, + this.hashArray.length)]; var4 != null; var4 = var4.nextEntry) { + if (var4.key == par1) { + return var4.value; + } + } + + return null; + } + + public boolean containsItem(long par1) { + return this.getEntry(par1) != null; + } + + final LongHashMapEntry getEntry(long par1) { + int var3 = getHashedKey(par1); + + for (LongHashMapEntry var4 = this.hashArray[getHashIndex(var3, + this.hashArray.length)]; var4 != null; var4 = var4.nextEntry) { + if (var4.key == par1) { + return var4; + } + } + + return null; + } + + /** + * Add a key-value pair. + */ + public void add(long par1, Object par3Obj) { + int var4 = getHashedKey(par1); + int var5 = getHashIndex(var4, this.hashArray.length); + + for (LongHashMapEntry var6 = this.hashArray[var5]; var6 != null; var6 = var6.nextEntry) { + if (var6.key == par1) { + var6.value = par3Obj; + return; + } + } + + ++this.modCount; + this.createKey(var4, par1, par3Obj, var5); + } + + /** + * resizes the table + */ + private void resizeTable(int par1) { + LongHashMapEntry[] var2 = this.hashArray; + int var3 = var2.length; + + if (var3 == 1073741824) { + this.capacity = Integer.MAX_VALUE; + } else { + LongHashMapEntry[] var4 = new LongHashMapEntry[par1]; + this.copyHashTableTo(var4); + this.hashArray = var4; + this.capacity = (int) ((float) par1 * this.percentUseable); + } + } + + /** + * copies the hash table to the specified array + */ + private void copyHashTableTo(LongHashMapEntry[] par1ArrayOfLongHashMapEntry) { + LongHashMapEntry[] var2 = this.hashArray; + int var3 = par1ArrayOfLongHashMapEntry.length; + + for (int var4 = 0; var4 < var2.length; ++var4) { + LongHashMapEntry var5 = var2[var4]; + + if (var5 != null) { + var2[var4] = null; + LongHashMapEntry var6; + + do { + var6 = var5.nextEntry; + int var7 = getHashIndex(var5.hash, var3); + var5.nextEntry = par1ArrayOfLongHashMapEntry[var7]; + par1ArrayOfLongHashMapEntry[var7] = var5; + var5 = var6; + } while (var6 != null); + } + } + } + + /** + * calls the removeKey method and returns removed object + */ + public Object remove(long par1) { + LongHashMapEntry var3 = this.removeKey(par1); + return var3 == null ? null : var3.value; + } + + /** + * removes the key from the hash linked list + */ + final LongHashMapEntry removeKey(long par1) { + int var3 = getHashedKey(par1); + int var4 = getHashIndex(var3, this.hashArray.length); + LongHashMapEntry var5 = this.hashArray[var4]; + LongHashMapEntry var6; + LongHashMapEntry var7; + + for (var6 = var5; var6 != null; var6 = var7) { + var7 = var6.nextEntry; + + if (var6.key == par1) { + ++this.modCount; + --this.numHashElements; + + if (var5 == var6) { + this.hashArray[var4] = var7; + } else { + var5.nextEntry = var7; + } + + return var6; + } + + var5 = var6; + } + + return var6; + } + + /** + * creates the key in the hash table + */ + private void createKey(int par1, long par2, Object par4Obj, int par5) { + LongHashMapEntry var6 = this.hashArray[par5]; + this.hashArray[par5] = new LongHashMapEntry(par1, par2, par4Obj, var6); + + if (this.numHashElements++ >= this.capacity) { + this.resizeTable(2 * this.hashArray.length); + } + } + + /** + * public method to get the hashed key(hashCode) + */ + static int getHashCode(long par0) { + return getHashedKey(par0); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/LongHashMapEntry.java b/sp-server/src/main/java/net/minecraft/src/LongHashMapEntry.java new file mode 100644 index 0000000..83e40f2 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/LongHashMapEntry.java @@ -0,0 +1,60 @@ +package net.minecraft.src; + +class LongHashMapEntry { + /** + * the key as a long (for playerInstances it is the x in the most significant 32 + * bits and then y) + */ + final long key; + + /** the value held by the hash at the specified key */ + Object value; + + /** the next hashentry in the table */ + LongHashMapEntry nextEntry; + final int hash; + + LongHashMapEntry(int par1, long par2, Object par4Obj, LongHashMapEntry par5LongHashMapEntry) { + this.value = par4Obj; + this.nextEntry = par5LongHashMapEntry; + this.key = par2; + this.hash = par1; + } + + public final long getKey() { + return this.key; + } + + public final Object getValue() { + return this.value; + } + + public final boolean equals(Object par1Obj) { + if (!(par1Obj instanceof LongHashMapEntry)) { + return false; + } else { + LongHashMapEntry var2 = (LongHashMapEntry) par1Obj; + Long var3 = Long.valueOf(this.getKey()); + Long var4 = Long.valueOf(var2.getKey()); + + if (var3 == var4 || var3 != null && var3.equals(var4)) { + Object var5 = this.getValue(); + Object var6 = var2.getValue(); + + if (var5 == var6 || var5 != null && var5.equals(var6)) { + return true; + } + } + + return false; + } + } + + public final int hashCode() { + return LongHashMap.getHashCode(this.key); + } + + public final String toString() { + return this.getKey() + "=" + this.getValue(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/LowerStringMap.java b/sp-server/src/main/java/net/minecraft/src/LowerStringMap.java new file mode 100644 index 0000000..420c390 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/LowerStringMap.java @@ -0,0 +1,72 @@ +package net.minecraft.src; + +import java.util.Collection; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Set; +import java.util.Map.Entry; + +public class LowerStringMap implements Map { + private final Map internalMap = new LinkedHashMap(); + + public int size() { + return this.internalMap.size(); + } + + public boolean isEmpty() { + return this.internalMap.isEmpty(); + } + + public boolean containsKey(Object par1Obj) { + return this.internalMap.containsKey(par1Obj.toString().toLowerCase()); + } + + public boolean containsValue(Object par1Obj) { + return this.internalMap.containsKey(par1Obj); + } + + public Object get(Object par1Obj) { + return this.internalMap.get(par1Obj.toString().toLowerCase()); + } + + /** + * a map already defines a general put + */ + public Object putLower(String par1Str, Object par2Obj) { + return this.internalMap.put(par1Str.toLowerCase(), par2Obj); + } + + public Object remove(Object par1Obj) { + return this.internalMap.remove(par1Obj.toString().toLowerCase()); + } + + public void putAll(Map par1Map) { + Iterator var2 = par1Map.entrySet().iterator(); + + while (var2.hasNext()) { + Entry var3 = (Entry) var2.next(); + this.putLower((String) var3.getKey(), var3.getValue()); + } + } + + public void clear() { + this.internalMap.clear(); + } + + public Set keySet() { + return this.internalMap.keySet(); + } + + public Collection values() { + return this.internalMap.values(); + } + + public Set entrySet() { + return this.internalMap.entrySet(); + } + + public Object put(Object par1Obj, Object par2Obj) { + return this.putLower((String) par1Obj, par2Obj); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/MapColor.java b/sp-server/src/main/java/net/minecraft/src/MapColor.java new file mode 100644 index 0000000..298a128 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/MapColor.java @@ -0,0 +1,62 @@ +package net.minecraft.src; + +public class MapColor { + /** + * Holds all the 16 colors used on maps, very similar of a pallete system. + */ + public static final MapColor[] mapColorArray = new MapColor[16]; + + /** The map color for Air blocks */ + public static final MapColor airColor = new MapColor(0, 0); + + /** this is the grass color in html format */ + public static final MapColor grassColor = new MapColor(1, 8368696); + + /** This is the color of the sand */ + public static final MapColor sandColor = new MapColor(2, 16247203); + + /** The map color for Cloth and Sponge blocks */ + public static final MapColor clothColor = new MapColor(3, 10987431); + + /** The map color for TNT blocks */ + public static final MapColor tntColor = new MapColor(4, 16711680); + + /** The map color for Ice blocks */ + public static final MapColor iceColor = new MapColor(5, 10526975); + + /** The map color for Iron blocks */ + public static final MapColor ironColor = new MapColor(6, 10987431); + + /** The map color for Leaf, Plant, Cactus, and Pumpkin blocks. */ + public static final MapColor foliageColor = new MapColor(7, 31744); + + /** The map color for Snow Cover and Snow blocks */ + public static final MapColor snowColor = new MapColor(8, 16777215); + + /** The map color for Clay blocks */ + public static final MapColor clayColor = new MapColor(9, 10791096); + + /** The map color for Dirt blocks */ + public static final MapColor dirtColor = new MapColor(10, 12020271); + + /** The map color for Stone blocks */ + public static final MapColor stoneColor = new MapColor(11, 7368816); + + /** The map color for Water blocks */ + public static final MapColor waterColor = new MapColor(12, 4210943); + + /** The map color for Wood blocks */ + public static final MapColor woodColor = new MapColor(13, 6837042); + + /** Holds the color in RGB value that will be rendered on maps. */ + public final int colorValue; + + /** Holds the index of the color used on map. */ + public final int colorIndex; + + private MapColor(int par1, int par2) { + this.colorIndex = par1; + this.colorValue = par2; + mapColorArray[par1] = this; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/MapCoord.java b/sp-server/src/main/java/net/minecraft/src/MapCoord.java new file mode 100644 index 0000000..32f2a91 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/MapCoord.java @@ -0,0 +1,18 @@ +package net.minecraft.src; + +public class MapCoord { + public byte iconSize; + public byte centerX; + public byte centerZ; + public byte iconRotation; + + final MapData data; + + public MapCoord(MapData par1MapData, byte par2, byte par3, byte par4, byte par5) { + this.data = par1MapData; + this.iconSize = par2; + this.centerX = par3; + this.centerZ = par4; + this.iconRotation = par5; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/MapData.java b/sp-server/src/main/java/net/minecraft/src/MapData.java new file mode 100644 index 0000000..e6f6c9b --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/MapData.java @@ -0,0 +1,216 @@ +package net.minecraft.src; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +public class MapData extends WorldSavedData { + public int xCenter; + public int zCenter; + public byte dimension; + public byte scale; + + /** colours */ + public byte[] colors = new byte[16384]; + + /** + * Holds a reference to the MapInfo of the players who own a copy of the map + */ + public List playersArrayList = new ArrayList(); + + /** + * Holds a reference to the players who own a copy of the map and a reference to + * their MapInfo + */ + private Map playersHashMap = new HashMap(); + public Map playersVisibleOnMap = new LinkedHashMap(); + + public MapData(String par1Str) { + super(par1Str); + } + + /** + * reads in data from the NBTTagCompound into this MapDataBase + */ + public void readFromNBT(NBTTagCompound par1NBTTagCompound) { + this.dimension = par1NBTTagCompound.getByte("dimension"); + this.xCenter = par1NBTTagCompound.getInteger("xCenter"); + this.zCenter = par1NBTTagCompound.getInteger("zCenter"); + this.scale = par1NBTTagCompound.getByte("scale"); + + if (this.scale < 0) { + this.scale = 0; + } + + if (this.scale > 4) { + this.scale = 4; + } + + short var2 = par1NBTTagCompound.getShort("width"); + short var3 = par1NBTTagCompound.getShort("height"); + + if (var2 == 128 && var3 == 128) { + this.colors = par1NBTTagCompound.getByteArray("colors"); + } else { + byte[] var4 = par1NBTTagCompound.getByteArray("colors"); + this.colors = new byte[16384]; + int var5 = (128 - var2) / 2; + int var6 = (128 - var3) / 2; + + for (int var7 = 0; var7 < var3; ++var7) { + int var8 = var7 + var6; + + if (var8 >= 0 || var8 < 128) { + for (int var9 = 0; var9 < var2; ++var9) { + int var10 = var9 + var5; + + if (var10 >= 0 || var10 < 128) { + this.colors[var10 + var8 * 128] = var4[var9 + var7 * var2]; + } + } + } + } + } + } + + /** + * write data to NBTTagCompound from this MapDataBase, similar to Entities and + * TileEntities + */ + public void writeToNBT(NBTTagCompound par1NBTTagCompound) { + par1NBTTagCompound.setByte("dimension", this.dimension); + par1NBTTagCompound.setInteger("xCenter", this.xCenter); + par1NBTTagCompound.setInteger("zCenter", this.zCenter); + par1NBTTagCompound.setByte("scale", this.scale); + par1NBTTagCompound.setShort("width", (short) 128); + par1NBTTagCompound.setShort("height", (short) 128); + par1NBTTagCompound.setByteArray("colors", this.colors); + } + + /** + * Adds the player passed to the list of visible players and checks to see which + * players are visible + */ + public void updateVisiblePlayers(EntityPlayer par1EntityPlayer, ItemStack par2ItemStack) { + if (!this.playersHashMap.containsKey(par1EntityPlayer)) { + MapInfo var3 = new MapInfo(this, par1EntityPlayer); + this.playersHashMap.put(par1EntityPlayer, var3); + this.playersArrayList.add(var3); + } + + if (!par1EntityPlayer.inventory.hasItemStack(par2ItemStack)) { + this.playersVisibleOnMap.remove(par1EntityPlayer.getCommandSenderName()); + } + + for (int var5 = 0; var5 < this.playersArrayList.size(); ++var5) { + MapInfo var4 = (MapInfo) this.playersArrayList.get(var5); + + if (!var4.entityplayerObj.isDead + && (var4.entityplayerObj.inventory.hasItemStack(par2ItemStack) || par2ItemStack.isOnItemFrame())) { + if (!par2ItemStack.isOnItemFrame() && var4.entityplayerObj.dimension == this.dimension) { + this.func_82567_a(0, var4.entityplayerObj.worldObj, var4.entityplayerObj.getCommandSenderName(), + var4.entityplayerObj.posX, var4.entityplayerObj.posZ, + (double) var4.entityplayerObj.rotationYaw); + } + } else { + this.playersHashMap.remove(var4.entityplayerObj); + this.playersArrayList.remove(var4); + } + } + + if (par2ItemStack.isOnItemFrame()) { + this.func_82567_a(1, par1EntityPlayer.worldObj, "frame-" + par2ItemStack.getItemFrame().entityId, + (double) par2ItemStack.getItemFrame().xPosition, (double) par2ItemStack.getItemFrame().zPosition, + (double) (par2ItemStack.getItemFrame().hangingDirection * 90)); + } + } + + private void func_82567_a(int par1, World par2World, String par3Str, double par4, double par6, double par8) { + int var10 = 1 << this.scale; + float var11 = (float) (par4 - (double) this.xCenter) / (float) var10; + float var12 = (float) (par6 - (double) this.zCenter) / (float) var10; + byte var13 = (byte) ((int) ((double) (var11 * 2.0F) + 0.5D)); + byte var14 = (byte) ((int) ((double) (var12 * 2.0F) + 0.5D)); + byte var16 = 63; + byte var15; + + if (var11 >= (float) (-var16) && var12 >= (float) (-var16) && var11 <= (float) var16 + && var12 <= (float) var16) { + par8 += par8 < 0.0D ? -8.0D : 8.0D; + var15 = (byte) ((int) (par8 * 16.0D / 360.0D)); + + if (this.dimension < 0) { + int var17 = (int) (par2World.getWorldInfo().getWorldTime() / 10L); + var15 = (byte) (var17 * var17 * 34187121 + var17 * 121 >> 15 & 15); + } + } else { + if (Math.abs(var11) >= 320.0F || Math.abs(var12) >= 320.0F) { + this.playersVisibleOnMap.remove(par3Str); + return; + } + + par1 = 6; + var15 = 0; + + if (var11 <= (float) (-var16)) { + var13 = (byte) ((int) ((double) (var16 * 2) + 2.5D)); + } + + if (var12 <= (float) (-var16)) { + var14 = (byte) ((int) ((double) (var16 * 2) + 2.5D)); + } + + if (var11 >= (float) var16) { + var13 = (byte) (var16 * 2 + 1); + } + + if (var12 >= (float) var16) { + var14 = (byte) (var16 * 2 + 1); + } + } + + this.playersVisibleOnMap.put(par3Str, new MapCoord(this, (byte) par1, var13, var14, var15)); + } + + /** + * Get byte array of packet data to send to players on map for updating map data + */ + public byte[] getUpdatePacketData(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer) { + MapInfo var4 = (MapInfo) this.playersHashMap.get(par3EntityPlayer); + return var4 == null ? null : var4.getPlayersOnMap(par1ItemStack); + } + + /** + * Marks a vertical range of pixels as being modified so they will be resent to + * clients. Parameters: X, lowest Y, highest Y + */ + public void setColumnDirty(int par1, int par2, int par3) { + super.markDirty(); + + for (int var4 = 0; var4 < this.playersArrayList.size(); ++var4) { + MapInfo var5 = (MapInfo) this.playersArrayList.get(var4); + + if (var5.field_76209_b[par1] < 0 || var5.field_76209_b[par1] > par2) { + var5.field_76209_b[par1] = par2; + } + + if (var5.field_76210_c[par1] < 0 || var5.field_76210_c[par1] < par3) { + var5.field_76210_c[par1] = par3; + } + } + } + + public MapInfo func_82568_a(EntityPlayer par1EntityPlayer) { + MapInfo var2 = (MapInfo) this.playersHashMap.get(par1EntityPlayer); + + if (var2 == null) { + var2 = new MapInfo(this, par1EntityPlayer); + this.playersHashMap.put(par1EntityPlayer, var2); + this.playersArrayList.add(var2); + } + + return var2; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/MapGenBase.java b/sp-server/src/main/java/net/minecraft/src/MapGenBase.java new file mode 100644 index 0000000..71ecd00 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/MapGenBase.java @@ -0,0 +1,38 @@ +package net.minecraft.src; + +import java.util.Random; + +public class MapGenBase { + /** The number of Chunks to gen-check in any given direction. */ + protected int range = 8; + + /** The RNG used by the MapGen classes. */ + protected Random rand = new Random(); + + /** This world object. */ + protected World worldObj; + + public void generate(IChunkProvider par1IChunkProvider, World par2World, int par3, int par4, + byte[] par5ArrayOfByte) { + int var6 = this.range; + this.worldObj = par2World; + this.rand.setSeed(par2World.getSeed()); + long var7 = this.rand.nextLong(); + long var9 = this.rand.nextLong(); + + for (int var11 = par3 - var6; var11 <= par3 + var6; ++var11) { + for (int var12 = par4 - var6; var12 <= par4 + var6; ++var12) { + long var13 = (long) var11 * var7; + long var15 = (long) var12 * var9; + this.rand.setSeed(var13 ^ var15 ^ par2World.getSeed()); + this.recursiveGenerate(par2World, var11, var12, par3, par4, par5ArrayOfByte); + } + } + } + + /** + * Recursively called by generate() (generate) and optionally by itself. + */ + protected void recursiveGenerate(World par1World, int par2, int par3, int par4, int par5, byte[] par6ArrayOfByte) { + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/MapGenCaves.java b/sp-server/src/main/java/net/minecraft/src/MapGenCaves.java new file mode 100644 index 0000000..6be8209 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/MapGenCaves.java @@ -0,0 +1,225 @@ +package net.minecraft.src; + +import java.util.Random; + +public class MapGenCaves extends MapGenBase { + /** + * Generates a larger initial cave node than usual. Called 25% of the time. + */ + protected void generateLargeCaveNode(long par1, int par3, int par4, byte[] par5ArrayOfByte, double par6, + double par8, double par10) { + this.generateCaveNode(par1, par3, par4, par5ArrayOfByte, par6, par8, par10, 1.0F + this.rand.nextFloat() * 6.0F, + 0.0F, 0.0F, -1, -1, 0.5D); + } + + /** + * Generates a node in the current cave system recursion tree. + */ + protected void generateCaveNode(long par1, int par3, int par4, byte[] par5ArrayOfByte, double par6, double par8, + double par10, float par12, float par13, float par14, int par15, int par16, double par17) { + double var19 = (double) (par3 * 16 + 8); + double var21 = (double) (par4 * 16 + 8); + float var23 = 0.0F; + float var24 = 0.0F; + Random var25 = new Random(par1); + + if (par16 <= 0) { + int var26 = this.range * 16 - 16; + par16 = var26 - var25.nextInt(var26 / 4); + } + + boolean var54 = false; + + if (par15 == -1) { + par15 = par16 / 2; + var54 = true; + } + + int var27 = var25.nextInt(par16 / 2) + par16 / 4; + + for (boolean var28 = var25.nextInt(6) == 0; par15 < par16; ++par15) { + double var29 = 1.5D + + (double) (MathHelper.sin((float) par15 * (float) Math.PI / (float) par16) * par12 * 1.0F); + double var31 = var29 * par17; + float var33 = MathHelper.cos(par14); + float var34 = MathHelper.sin(par14); + par6 += (double) (MathHelper.cos(par13) * var33); + par8 += (double) var34; + par10 += (double) (MathHelper.sin(par13) * var33); + + if (var28) { + par14 *= 0.92F; + } else { + par14 *= 0.7F; + } + + par14 += var24 * 0.1F; + par13 += var23 * 0.1F; + var24 *= 0.9F; + var23 *= 0.75F; + var24 += (var25.nextFloat() - var25.nextFloat()) * var25.nextFloat() * 2.0F; + var23 += (var25.nextFloat() - var25.nextFloat()) * var25.nextFloat() * 4.0F; + + if (!var54 && par15 == var27 && par12 > 1.0F && par16 > 0) { + this.generateCaveNode(var25.nextLong(), par3, par4, par5ArrayOfByte, par6, par8, par10, + var25.nextFloat() * 0.5F + 0.5F, par13 - ((float) Math.PI / 2F), par14 / 3.0F, par15, par16, + 1.0D); + this.generateCaveNode(var25.nextLong(), par3, par4, par5ArrayOfByte, par6, par8, par10, + var25.nextFloat() * 0.5F + 0.5F, par13 + ((float) Math.PI / 2F), par14 / 3.0F, par15, par16, + 1.0D); + return; + } + + if (var54 || var25.nextInt(4) != 0) { + double var35 = par6 - var19; + double var37 = par10 - var21; + double var39 = (double) (par16 - par15); + double var41 = (double) (par12 + 2.0F + 16.0F); + + if (var35 * var35 + var37 * var37 - var39 * var39 > var41 * var41) { + return; + } + + if (par6 >= var19 - 16.0D - var29 * 2.0D && par10 >= var21 - 16.0D - var29 * 2.0D + && par6 <= var19 + 16.0D + var29 * 2.0D && par10 <= var21 + 16.0D + var29 * 2.0D) { + int var55 = MathHelper.floor_double(par6 - var29) - par3 * 16 - 1; + int var36 = MathHelper.floor_double(par6 + var29) - par3 * 16 + 1; + int var56 = MathHelper.floor_double(par8 - var31) - 1; + int var38 = MathHelper.floor_double(par8 + var31) + 1; + int var57 = MathHelper.floor_double(par10 - var29) - par4 * 16 - 1; + int var40 = MathHelper.floor_double(par10 + var29) - par4 * 16 + 1; + + if (var55 < 0) { + var55 = 0; + } + + if (var36 > 16) { + var36 = 16; + } + + if (var56 < 1) { + var56 = 1; + } + + if (var38 > 120) { + var38 = 120; + } + + if (var57 < 0) { + var57 = 0; + } + + if (var40 > 16) { + var40 = 16; + } + + boolean var58 = false; + int var42; + int var45; + + for (var42 = var55; !var58 && var42 < var36; ++var42) { + for (int var43 = var57; !var58 && var43 < var40; ++var43) { + for (int var44 = var38 + 1; !var58 && var44 >= var56 - 1; --var44) { + var45 = (var42 * 16 + var43) * 128 + var44; + + if (var44 >= 0 && var44 < 128) { + if (par5ArrayOfByte[var45] == Block.waterMoving.blockID + || par5ArrayOfByte[var45] == Block.waterStill.blockID) { + var58 = true; + } + + if (var44 != var56 - 1 && var42 != var55 && var42 != var36 - 1 && var43 != var57 + && var43 != var40 - 1) { + var44 = var56; + } + } + } + } + } + + if (!var58) { + for (var42 = var55; var42 < var36; ++var42) { + double var59 = ((double) (var42 + par3 * 16) + 0.5D - par6) / var29; + + for (var45 = var57; var45 < var40; ++var45) { + double var46 = ((double) (var45 + par4 * 16) + 0.5D - par10) / var29; + int var48 = (var42 * 16 + var45) * 128 + var38; + boolean var49 = false; + + if (var59 * var59 + var46 * var46 < 1.0D) { + for (int var50 = var38 - 1; var50 >= var56; --var50) { + double var51 = ((double) var50 + 0.5D - par8) / var31; + + if (var51 > -0.7D && var59 * var59 + var51 * var51 + var46 * var46 < 1.0D) { + byte var53 = par5ArrayOfByte[var48]; + + if (var53 == Block.grass.blockID) { + var49 = true; + } + + if (var53 == Block.stone.blockID || var53 == Block.dirt.blockID + || var53 == Block.grass.blockID) { + if (var50 < 10) { + par5ArrayOfByte[var48] = (byte) Block.lavaMoving.blockID; + } else { + par5ArrayOfByte[var48] = 0; + + if (var49 && par5ArrayOfByte[var48 - 1] == Block.dirt.blockID) { + par5ArrayOfByte[var48 - 1] = this.worldObj.getBiomeGenForCoords( + var42 + par3 * 16, var45 + par4 * 16).topBlock; + } + } + } + } + + --var48; + } + } + } + } + + if (var54) { + break; + } + } + } + } + } + } + + /** + * Recursively called by generate() (generate) and optionally by itself. + */ + protected void recursiveGenerate(World par1World, int par2, int par3, int par4, int par5, byte[] par6ArrayOfByte) { + int var7 = this.rand.nextInt(this.rand.nextInt(this.rand.nextInt(40) + 1) + 1); + + if (this.rand.nextInt(15) != 0) { + var7 = 0; + } + + for (int var8 = 0; var8 < var7; ++var8) { + double var9 = (double) (par2 * 16 + this.rand.nextInt(16)); + double var11 = (double) this.rand.nextInt(this.rand.nextInt(120) + 8); + double var13 = (double) (par3 * 16 + this.rand.nextInt(16)); + int var15 = 1; + + if (this.rand.nextInt(4) == 0) { + this.generateLargeCaveNode(this.rand.nextLong(), par4, par5, par6ArrayOfByte, var9, var11, var13); + var15 += this.rand.nextInt(4); + } + + for (int var16 = 0; var16 < var15; ++var16) { + float var17 = this.rand.nextFloat() * (float) Math.PI * 2.0F; + float var18 = (this.rand.nextFloat() - 0.5F) * 2.0F / 8.0F; + float var19 = this.rand.nextFloat() * 2.0F + this.rand.nextFloat(); + + if (this.rand.nextInt(10) == 0) { + var19 *= this.rand.nextFloat() * this.rand.nextFloat() * 3.0F + 1.0F; + } + + this.generateCaveNode(this.rand.nextLong(), par4, par5, par6ArrayOfByte, var9, var11, var13, var19, + var17, var18, 0, 0, 1.0D); + } + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/MapGenCavesHell.java b/sp-server/src/main/java/net/minecraft/src/MapGenCavesHell.java new file mode 100644 index 0000000..91c69a0 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/MapGenCavesHell.java @@ -0,0 +1,204 @@ +package net.minecraft.src; + +import java.util.Random; + +public class MapGenCavesHell extends MapGenBase { + /** + * Generates a larger initial cave node than usual. Called 25% of the time. + */ + protected void generateLargeCaveNode(long par1, int par3, int par4, byte[] par5ArrayOfByte, double par6, + double par8, double par10) { + this.generateCaveNode(par1, par3, par4, par5ArrayOfByte, par6, par8, par10, 1.0F + this.rand.nextFloat() * 6.0F, + 0.0F, 0.0F, -1, -1, 0.5D); + } + + /** + * Generates a node in the current cave system recursion tree. + */ + protected void generateCaveNode(long par1, int par3, int par4, byte[] par5ArrayOfByte, double par6, double par8, + double par10, float par12, float par13, float par14, int par15, int par16, double par17) { + double var19 = (double) (par3 * 16 + 8); + double var21 = (double) (par4 * 16 + 8); + float var23 = 0.0F; + float var24 = 0.0F; + Random var25 = new Random(par1); + + if (par16 <= 0) { + int var26 = this.range * 16 - 16; + par16 = var26 - var25.nextInt(var26 / 4); + } + + boolean var53 = false; + + if (par15 == -1) { + par15 = par16 / 2; + var53 = true; + } + + int var27 = var25.nextInt(par16 / 2) + par16 / 4; + + for (boolean var28 = var25.nextInt(6) == 0; par15 < par16; ++par15) { + double var29 = 1.5D + + (double) (MathHelper.sin((float) par15 * (float) Math.PI / (float) par16) * par12 * 1.0F); + double var31 = var29 * par17; + float var33 = MathHelper.cos(par14); + float var34 = MathHelper.sin(par14); + par6 += (double) (MathHelper.cos(par13) * var33); + par8 += (double) var34; + par10 += (double) (MathHelper.sin(par13) * var33); + + if (var28) { + par14 *= 0.92F; + } else { + par14 *= 0.7F; + } + + par14 += var24 * 0.1F; + par13 += var23 * 0.1F; + var24 *= 0.9F; + var23 *= 0.75F; + var24 += (var25.nextFloat() - var25.nextFloat()) * var25.nextFloat() * 2.0F; + var23 += (var25.nextFloat() - var25.nextFloat()) * var25.nextFloat() * 4.0F; + + if (!var53 && par15 == var27 && par12 > 1.0F) { + this.generateCaveNode(var25.nextLong(), par3, par4, par5ArrayOfByte, par6, par8, par10, + var25.nextFloat() * 0.5F + 0.5F, par13 - ((float) Math.PI / 2F), par14 / 3.0F, par15, par16, + 1.0D); + this.generateCaveNode(var25.nextLong(), par3, par4, par5ArrayOfByte, par6, par8, par10, + var25.nextFloat() * 0.5F + 0.5F, par13 + ((float) Math.PI / 2F), par14 / 3.0F, par15, par16, + 1.0D); + return; + } + + if (var53 || var25.nextInt(4) != 0) { + double var35 = par6 - var19; + double var37 = par10 - var21; + double var39 = (double) (par16 - par15); + double var41 = (double) (par12 + 2.0F + 16.0F); + + if (var35 * var35 + var37 * var37 - var39 * var39 > var41 * var41) { + return; + } + + if (par6 >= var19 - 16.0D - var29 * 2.0D && par10 >= var21 - 16.0D - var29 * 2.0D + && par6 <= var19 + 16.0D + var29 * 2.0D && par10 <= var21 + 16.0D + var29 * 2.0D) { + int var54 = MathHelper.floor_double(par6 - var29) - par3 * 16 - 1; + int var36 = MathHelper.floor_double(par6 + var29) - par3 * 16 + 1; + int var55 = MathHelper.floor_double(par8 - var31) - 1; + int var38 = MathHelper.floor_double(par8 + var31) + 1; + int var56 = MathHelper.floor_double(par10 - var29) - par4 * 16 - 1; + int var40 = MathHelper.floor_double(par10 + var29) - par4 * 16 + 1; + + if (var54 < 0) { + var54 = 0; + } + + if (var36 > 16) { + var36 = 16; + } + + if (var55 < 1) { + var55 = 1; + } + + if (var38 > 120) { + var38 = 120; + } + + if (var56 < 0) { + var56 = 0; + } + + if (var40 > 16) { + var40 = 16; + } + + boolean var57 = false; + int var42; + int var45; + + for (var42 = var54; !var57 && var42 < var36; ++var42) { + for (int var43 = var56; !var57 && var43 < var40; ++var43) { + for (int var44 = var38 + 1; !var57 && var44 >= var55 - 1; --var44) { + var45 = (var42 * 16 + var43) * 128 + var44; + + if (var44 >= 0 && var44 < 128) { + if (par5ArrayOfByte[var45] == Block.lavaMoving.blockID + || par5ArrayOfByte[var45] == Block.lavaStill.blockID) { + var57 = true; + } + + if (var44 != var55 - 1 && var42 != var54 && var42 != var36 - 1 && var43 != var56 + && var43 != var40 - 1) { + var44 = var55; + } + } + } + } + } + + if (!var57) { + for (var42 = var54; var42 < var36; ++var42) { + double var58 = ((double) (var42 + par3 * 16) + 0.5D - par6) / var29; + + for (var45 = var56; var45 < var40; ++var45) { + double var46 = ((double) (var45 + par4 * 16) + 0.5D - par10) / var29; + int var48 = (var42 * 16 + var45) * 128 + var38; + + for (int var49 = var38 - 1; var49 >= var55; --var49) { + double var50 = ((double) var49 + 0.5D - par8) / var31; + + if (var50 > -0.7D && var58 * var58 + var50 * var50 + var46 * var46 < 1.0D) { + byte var52 = par5ArrayOfByte[var48]; + + if (var52 == Block.netherrack.blockID || var52 == Block.dirt.blockID + || var52 == Block.grass.blockID) { + par5ArrayOfByte[var48] = 0; + } + } + + --var48; + } + } + } + + if (var53) { + break; + } + } + } + } + } + } + + /** + * Recursively called by generate() (generate) and optionally by itself. + */ + protected void recursiveGenerate(World par1World, int par2, int par3, int par4, int par5, byte[] par6ArrayOfByte) { + int var7 = this.rand.nextInt(this.rand.nextInt(this.rand.nextInt(10) + 1) + 1); + + if (this.rand.nextInt(5) != 0) { + var7 = 0; + } + + for (int var8 = 0; var8 < var7; ++var8) { + double var9 = (double) (par2 * 16 + this.rand.nextInt(16)); + double var11 = (double) this.rand.nextInt(128); + double var13 = (double) (par3 * 16 + this.rand.nextInt(16)); + int var15 = 1; + + if (this.rand.nextInt(4) == 0) { + this.generateLargeCaveNode(this.rand.nextLong(), par4, par5, par6ArrayOfByte, var9, var11, var13); + var15 += this.rand.nextInt(4); + } + + for (int var16 = 0; var16 < var15; ++var16) { + float var17 = this.rand.nextFloat() * (float) Math.PI * 2.0F; + float var18 = (this.rand.nextFloat() - 0.5F) * 2.0F / 8.0F; + float var19 = this.rand.nextFloat() * 2.0F + this.rand.nextFloat(); + this.generateCaveNode(this.rand.nextLong(), par4, par5, par6ArrayOfByte, var9, var11, var13, + var19 * 2.0F, var17, var18, 0, 0, 0.5D); + } + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/MapGenMineshaft.java b/sp-server/src/main/java/net/minecraft/src/MapGenMineshaft.java new file mode 100644 index 0000000..76239bc --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/MapGenMineshaft.java @@ -0,0 +1,33 @@ +package net.minecraft.src; + +import java.util.Iterator; +import java.util.Map; +import java.util.Map.Entry; + +public class MapGenMineshaft extends MapGenStructure { + private double field_82673_e = 0.01D; + + public MapGenMineshaft() { + } + + public MapGenMineshaft(Map par1Map) { + Iterator var2 = par1Map.entrySet().iterator(); + + while (var2.hasNext()) { + Entry var3 = (Entry) var2.next(); + + if (((String) var3.getKey()).equals("chance")) { + this.field_82673_e = MathHelper.parseDoubleWithDefault((String) var3.getValue(), this.field_82673_e); + } + } + } + + protected boolean canSpawnStructureAtCoords(int par1, int par2) { + return this.rand.nextDouble() < this.field_82673_e + && this.rand.nextInt(80) < Math.max(Math.abs(par1), Math.abs(par2)); + } + + protected StructureStart getStructureStart(int par1, int par2) { + return new StructureMineshaftStart(this.worldObj, this.rand, par1, par2); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/MapGenNetherBridge.java b/sp-server/src/main/java/net/minecraft/src/MapGenNetherBridge.java new file mode 100644 index 0000000..50029a1 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/MapGenNetherBridge.java @@ -0,0 +1,33 @@ +package net.minecraft.src; + +import java.util.ArrayList; +import java.util.List; + +public class MapGenNetherBridge extends MapGenStructure { + private List spawnList = new ArrayList(); + + public MapGenNetherBridge() { + this.spawnList.add(new SpawnListEntry(EntityBlaze.class, 10, 2, 3)); + this.spawnList.add(new SpawnListEntry(EntityPigZombie.class, 5, 4, 4)); + this.spawnList.add(new SpawnListEntry(EntitySkeleton.class, 10, 4, 4)); + this.spawnList.add(new SpawnListEntry(EntityMagmaCube.class, 3, 4, 4)); + } + + public List getSpawnList() { + return this.spawnList; + } + + protected boolean canSpawnStructureAtCoords(int par1, int par2) { + int var3 = par1 >> 4; + int var4 = par2 >> 4; + this.rand.setSeed((long) (var3 ^ var4 << 4) ^ this.worldObj.getSeed()); + this.rand.nextInt(); + return this.rand.nextInt(3) != 0 ? false + : (par1 != (var3 << 4) + 4 + this.rand.nextInt(8) ? false + : par2 == (var4 << 4) + 4 + this.rand.nextInt(8)); + } + + protected StructureStart getStructureStart(int par1, int par2) { + return new StructureNetherBridgeStart(this.worldObj, this.rand, par1, par2); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/MapGenRavine.java b/sp-server/src/main/java/net/minecraft/src/MapGenRavine.java new file mode 100644 index 0000000..8716cc0 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/MapGenRavine.java @@ -0,0 +1,194 @@ +package net.minecraft.src; + +import java.util.Random; + +public class MapGenRavine extends MapGenBase { + private float[] field_75046_d = new float[1024]; + + protected void generateRavine(long par1, int par3, int par4, byte[] par5ArrayOfByte, double par6, double par8, + double par10, float par12, float par13, float par14, int par15, int par16, double par17) { + Random var19 = new Random(par1); + double var20 = (double) (par3 * 16 + 8); + double var22 = (double) (par4 * 16 + 8); + float var24 = 0.0F; + float var25 = 0.0F; + + if (par16 <= 0) { + int var26 = this.range * 16 - 16; + par16 = var26 - var19.nextInt(var26 / 4); + } + + boolean var53 = false; + + if (par15 == -1) { + par15 = par16 / 2; + var53 = true; + } + + float var27 = 1.0F; + + for (int var28 = 0; var28 < 128; ++var28) { + if (var28 == 0 || var19.nextInt(3) == 0) { + var27 = 1.0F + var19.nextFloat() * var19.nextFloat() * 1.0F; + } + + this.field_75046_d[var28] = var27 * var27; + } + + for (; par15 < par16; ++par15) { + double var54 = 1.5D + + (double) (MathHelper.sin((float) par15 * (float) Math.PI / (float) par16) * par12 * 1.0F); + double var30 = var54 * par17; + var54 *= (double) var19.nextFloat() * 0.25D + 0.75D; + var30 *= (double) var19.nextFloat() * 0.25D + 0.75D; + float var32 = MathHelper.cos(par14); + float var33 = MathHelper.sin(par14); + par6 += (double) (MathHelper.cos(par13) * var32); + par8 += (double) var33; + par10 += (double) (MathHelper.sin(par13) * var32); + par14 *= 0.7F; + par14 += var25 * 0.05F; + par13 += var24 * 0.05F; + var25 *= 0.8F; + var24 *= 0.5F; + var25 += (var19.nextFloat() - var19.nextFloat()) * var19.nextFloat() * 2.0F; + var24 += (var19.nextFloat() - var19.nextFloat()) * var19.nextFloat() * 4.0F; + + if (var53 || var19.nextInt(4) != 0) { + double var34 = par6 - var20; + double var36 = par10 - var22; + double var38 = (double) (par16 - par15); + double var40 = (double) (par12 + 2.0F + 16.0F); + + if (var34 * var34 + var36 * var36 - var38 * var38 > var40 * var40) { + return; + } + + if (par6 >= var20 - 16.0D - var54 * 2.0D && par10 >= var22 - 16.0D - var54 * 2.0D + && par6 <= var20 + 16.0D + var54 * 2.0D && par10 <= var22 + 16.0D + var54 * 2.0D) { + int var55 = MathHelper.floor_double(par6 - var54) - par3 * 16 - 1; + int var35 = MathHelper.floor_double(par6 + var54) - par3 * 16 + 1; + int var56 = MathHelper.floor_double(par8 - var30) - 1; + int var37 = MathHelper.floor_double(par8 + var30) + 1; + int var57 = MathHelper.floor_double(par10 - var54) - par4 * 16 - 1; + int var39 = MathHelper.floor_double(par10 + var54) - par4 * 16 + 1; + + if (var55 < 0) { + var55 = 0; + } + + if (var35 > 16) { + var35 = 16; + } + + if (var56 < 1) { + var56 = 1; + } + + if (var37 > 120) { + var37 = 120; + } + + if (var57 < 0) { + var57 = 0; + } + + if (var39 > 16) { + var39 = 16; + } + + boolean var58 = false; + int var41; + int var44; + + for (var41 = var55; !var58 && var41 < var35; ++var41) { + for (int var42 = var57; !var58 && var42 < var39; ++var42) { + for (int var43 = var37 + 1; !var58 && var43 >= var56 - 1; --var43) { + var44 = (var41 * 16 + var42) * 128 + var43; + + if (var43 >= 0 && var43 < 128) { + if (par5ArrayOfByte[var44] == Block.waterMoving.blockID + || par5ArrayOfByte[var44] == Block.waterStill.blockID) { + var58 = true; + } + + if (var43 != var56 - 1 && var41 != var55 && var41 != var35 - 1 && var42 != var57 + && var42 != var39 - 1) { + var43 = var56; + } + } + } + } + } + + if (!var58) { + for (var41 = var55; var41 < var35; ++var41) { + double var59 = ((double) (var41 + par3 * 16) + 0.5D - par6) / var54; + + for (var44 = var57; var44 < var39; ++var44) { + double var45 = ((double) (var44 + par4 * 16) + 0.5D - par10) / var54; + int var47 = (var41 * 16 + var44) * 128 + var37; + boolean var48 = false; + + if (var59 * var59 + var45 * var45 < 1.0D) { + for (int var49 = var37 - 1; var49 >= var56; --var49) { + double var50 = ((double) var49 + 0.5D - par8) / var30; + + if ((var59 * var59 + var45 * var45) * (double) this.field_75046_d[var49] + + var50 * var50 / 6.0D < 1.0D) { + byte var52 = par5ArrayOfByte[var47]; + + if (var52 == Block.grass.blockID) { + var48 = true; + } + + if (var52 == Block.stone.blockID || var52 == Block.dirt.blockID + || var52 == Block.grass.blockID) { + if (var49 < 10) { + par5ArrayOfByte[var47] = (byte) Block.lavaMoving.blockID; + } else { + par5ArrayOfByte[var47] = 0; + + if (var48 && par5ArrayOfByte[var47 - 1] == Block.dirt.blockID) { + par5ArrayOfByte[var47 - 1] = this.worldObj.getBiomeGenForCoords( + var41 + par3 * 16, var44 + par4 * 16).topBlock; + } + } + } + } + + --var47; + } + } + } + } + + if (var53) { + break; + } + } + } + } + } + } + + /** + * Recursively called by generate() (generate) and optionally by itself. + */ + protected void recursiveGenerate(World par1World, int par2, int par3, int par4, int par5, byte[] par6ArrayOfByte) { + if (this.rand.nextInt(50) == 0) { + double var7 = (double) (par2 * 16 + this.rand.nextInt(16)); + double var9 = (double) (this.rand.nextInt(this.rand.nextInt(40) + 8) + 20); + double var11 = (double) (par3 * 16 + this.rand.nextInt(16)); + byte var13 = 1; + + for (int var14 = 0; var14 < var13; ++var14) { + float var15 = this.rand.nextFloat() * (float) Math.PI * 2.0F; + float var16 = (this.rand.nextFloat() - 0.5F) * 2.0F / 8.0F; + float var17 = (this.rand.nextFloat() * 2.0F + this.rand.nextFloat()) * 2.0F; + this.generateRavine(this.rand.nextLong(), par4, par5, par6ArrayOfByte, var7, var9, var11, var17, var15, + var16, 0, 0, 3.0D); + } + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/MapGenScatteredFeature.java b/sp-server/src/main/java/net/minecraft/src/MapGenScatteredFeature.java new file mode 100644 index 0000000..1f41bb4 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/MapGenScatteredFeature.java @@ -0,0 +1,92 @@ +package net.minecraft.src; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Random; +import java.util.Map.Entry; + +public class MapGenScatteredFeature extends MapGenStructure { + private static List biomelist = Arrays.asList(new BiomeGenBase[] { BiomeGenBase.desert, BiomeGenBase.desertHills, + BiomeGenBase.jungle, BiomeGenBase.jungleHills, BiomeGenBase.swampland }); + + /** contains possible spawns for scattered features */ + private List scatteredFeatureSpawnList; + + /** the maximum distance between scattered features */ + private int maxDistanceBetweenScatteredFeatures; + + /** the minimum distance between scattered features */ + private int minDistanceBetweenScatteredFeatures; + + public MapGenScatteredFeature() { + this.scatteredFeatureSpawnList = new ArrayList(); + this.maxDistanceBetweenScatteredFeatures = 32; + this.minDistanceBetweenScatteredFeatures = 8; + this.scatteredFeatureSpawnList.add(new SpawnListEntry(EntityWitch.class, 1, 1, 1)); + } + + public MapGenScatteredFeature(Map par1Map) { + this(); + Iterator var2 = par1Map.entrySet().iterator(); + + while (var2.hasNext()) { + Entry var3 = (Entry) var2.next(); + + if (((String) var3.getKey()).equals("distance")) { + this.maxDistanceBetweenScatteredFeatures = MathHelper.parseIntWithDefaultAndMax( + (String) var3.getValue(), this.maxDistanceBetweenScatteredFeatures, + this.minDistanceBetweenScatteredFeatures + 1); + } + } + } + + protected boolean canSpawnStructureAtCoords(int par1, int par2) { + int var3 = par1; + int var4 = par2; + + if (par1 < 0) { + par1 -= this.maxDistanceBetweenScatteredFeatures - 1; + } + + if (par2 < 0) { + par2 -= this.maxDistanceBetweenScatteredFeatures - 1; + } + + int var5 = par1 / this.maxDistanceBetweenScatteredFeatures; + int var6 = par2 / this.maxDistanceBetweenScatteredFeatures; + Random var7 = this.worldObj.setRandomSeed(var5, var6, 14357617); + var5 *= this.maxDistanceBetweenScatteredFeatures; + var6 *= this.maxDistanceBetweenScatteredFeatures; + var5 += var7.nextInt(this.maxDistanceBetweenScatteredFeatures - this.minDistanceBetweenScatteredFeatures); + var6 += var7.nextInt(this.maxDistanceBetweenScatteredFeatures - this.minDistanceBetweenScatteredFeatures); + + if (var3 == var5 && var4 == var6) { + BiomeGenBase var8 = this.worldObj.getWorldChunkManager().getBiomeGenAt(var3 * 16 + 8, var4 * 16 + 8); + Iterator var9 = biomelist.iterator(); + + while (var9.hasNext()) { + BiomeGenBase var10 = (BiomeGenBase) var9.next(); + + if (var8 == var10) { + return true; + } + } + } + + return false; + } + + protected StructureStart getStructureStart(int par1, int par2) { + return new StructureScatteredFeatureStart(this.worldObj, this.rand, par1, par2); + } + + /** + * returns possible spawns for scattered features + */ + public List getScatteredFeatureSpawnList() { + return this.scatteredFeatureSpawnList; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/MapGenStronghold.java b/sp-server/src/main/java/net/minecraft/src/MapGenStronghold.java new file mode 100644 index 0000000..585d0b6 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/MapGenStronghold.java @@ -0,0 +1,137 @@ +package net.minecraft.src; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Random; +import java.util.Map.Entry; + +public class MapGenStronghold extends MapGenStructure { + private BiomeGenBase[] allowedBiomeGenBases; + + /** + * is spawned false and set true once the defined BiomeGenBases were compared + * with the present ones + */ + private boolean ranBiomeCheck; + private ChunkCoordIntPair[] structureCoords; + private double field_82671_h; + private int field_82672_i; + + public MapGenStronghold() { + this.allowedBiomeGenBases = new BiomeGenBase[] { BiomeGenBase.desert, BiomeGenBase.forest, + BiomeGenBase.extremeHills, BiomeGenBase.swampland, BiomeGenBase.taiga, BiomeGenBase.icePlains, + BiomeGenBase.iceMountains, BiomeGenBase.desertHills, BiomeGenBase.forestHills, + BiomeGenBase.extremeHillsEdge, BiomeGenBase.jungle, BiomeGenBase.jungleHills }; + this.structureCoords = new ChunkCoordIntPair[3]; + this.field_82671_h = 32.0D; + this.field_82672_i = 3; + } + + public MapGenStronghold(Map par1Map) { + this.allowedBiomeGenBases = new BiomeGenBase[] { BiomeGenBase.desert, BiomeGenBase.forest, + BiomeGenBase.extremeHills, BiomeGenBase.swampland, BiomeGenBase.taiga, BiomeGenBase.icePlains, + BiomeGenBase.iceMountains, BiomeGenBase.desertHills, BiomeGenBase.forestHills, + BiomeGenBase.extremeHillsEdge, BiomeGenBase.jungle, BiomeGenBase.jungleHills }; + this.structureCoords = new ChunkCoordIntPair[3]; + this.field_82671_h = 32.0D; + this.field_82672_i = 3; + Iterator var2 = par1Map.entrySet().iterator(); + + while (var2.hasNext()) { + Entry var3 = (Entry) var2.next(); + + if (((String) var3.getKey()).equals("distance")) { + this.field_82671_h = MathHelper.func_82713_a((String) var3.getValue(), this.field_82671_h, 1.0D); + } else if (((String) var3.getKey()).equals("count")) { + this.structureCoords = new ChunkCoordIntPair[MathHelper + .parseIntWithDefaultAndMax((String) var3.getValue(), this.structureCoords.length, 1)]; + } else if (((String) var3.getKey()).equals("spread")) { + this.field_82672_i = MathHelper.parseIntWithDefaultAndMax((String) var3.getValue(), this.field_82672_i, + 1); + } + } + } + + protected boolean canSpawnStructureAtCoords(int par1, int par2) { + if (!this.ranBiomeCheck) { + Random var3 = new Random(); + var3.setSeed(this.worldObj.getSeed()); + double var4 = var3.nextDouble() * Math.PI * 2.0D; + int var6 = 1; + + for (int var7 = 0; var7 < this.structureCoords.length; ++var7) { + double var8 = (1.25D * (double) var6 + var3.nextDouble()) * this.field_82671_h * (double) var6; + int var10 = (int) Math.round(Math.cos(var4) * var8); + int var11 = (int) Math.round(Math.sin(var4) * var8); + ArrayList var12 = new ArrayList(); + Collections.addAll(var12, this.allowedBiomeGenBases); + ChunkPosition var13 = this.worldObj.getWorldChunkManager().findBiomePosition((var10 << 4) + 8, + (var11 << 4) + 8, 112, var12, var3); + + if (var13 != null) { + var10 = var13.x >> 4; + var11 = var13.z >> 4; + } + + this.structureCoords[var7] = new ChunkCoordIntPair(var10, var11); + var4 += (Math.PI * 2D) * (double) var6 / (double) this.field_82672_i; + + if (var7 == this.field_82672_i) { + var6 += 2 + var3.nextInt(5); + this.field_82672_i += 1 + var3.nextInt(2); + } + } + + this.ranBiomeCheck = true; + } + + ChunkCoordIntPair[] var14 = this.structureCoords; + int var15 = var14.length; + + for (int var5 = 0; var5 < var15; ++var5) { + ChunkCoordIntPair var16 = var14[var5]; + + if (par1 == var16.chunkXPos && par2 == var16.chunkZPos) { + return true; + } + } + + return false; + } + + /** + * Returns a list of other locations at which the structure generation has been + * run, or null if not relevant to this structure generator. + */ + protected List getCoordList() { + ArrayList var1 = new ArrayList(); + ChunkCoordIntPair[] var2 = this.structureCoords; + int var3 = var2.length; + + for (int var4 = 0; var4 < var3; ++var4) { + ChunkCoordIntPair var5 = var2[var4]; + + if (var5 != null) { + var1.add(var5.getChunkPosition(64)); + } + } + + return var1; + } + + protected StructureStart getStructureStart(int par1, int par2) { + StructureStrongholdStart var3; + + for (var3 = new StructureStrongholdStart(this.worldObj, this.rand, par1, par2); var3.getComponents().isEmpty() + || ((ComponentStrongholdStairs2) var3.getComponents() + .get(0)).strongholdPortalRoom == null; var3 = new StructureStrongholdStart(this.worldObj, + this.rand, par1, par2)) { + ; + } + + return var3; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/MapGenStructure.java b/sp-server/src/main/java/net/minecraft/src/MapGenStructure.java new file mode 100644 index 0000000..901bfdf --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/MapGenStructure.java @@ -0,0 +1,167 @@ +package net.minecraft.src; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Random; + +public abstract class MapGenStructure extends MapGenBase { + /** + * Used to store a list of all structures that have been recursively generated. + * Used so that during recursive generation, the structure generator can avoid + * generating structures that intersect ones that have already been placed. + */ + protected Map structureMap = new HashMap(); + + /** + * Recursively called by generate() (generate) and optionally by itself. + */ + protected void recursiveGenerate(World par1World, int par2, int par3, int par4, int par5, byte[] par6ArrayOfByte) { + if (!this.structureMap.containsKey(Long.valueOf(ChunkCoordIntPair.chunkXZ2Int(par2, par3)))) { + this.rand.nextInt(); + + try { + if (this.canSpawnStructureAtCoords(par2, par3)) { + StructureStart var7 = this.getStructureStart(par2, par3); + this.structureMap.put(Long.valueOf(ChunkCoordIntPair.chunkXZ2Int(par2, par3)), var7); + } + } catch (Throwable var10) { + CrashReport var8 = CrashReport.makeCrashReport(var10, "Exception preparing structure feature"); + CrashReportCategory var9 = var8.makeCategory("Feature being prepared"); + var9.addCrashSectionCallable("Is feature chunk", new CallableIsFeatureChunk(this, par2, par3)); + var9.addCrashSection("Chunk location", + String.format("%d,%d", new Object[] { Integer.valueOf(par2), Integer.valueOf(par3) })); + var9.addCrashSectionCallable("Chunk pos hash", new CallableChunkPosHash(this, par2, par3)); + var9.addCrashSectionCallable("Structure type", new CallableStructureType(this)); + throw new ReportedException(var8); + } + } + } + + /** + * Generates structures in specified chunk next to existing structures. Does + * *not* generate StructureStarts. + */ + public boolean generateStructuresInChunk(World par1World, Random par2Random, int par3, int par4) { + int var5 = (par3 << 4) + 8; + int var6 = (par4 << 4) + 8; + boolean var7 = false; + Iterator var8 = this.structureMap.values().iterator(); + + while (var8.hasNext()) { + StructureStart var9 = (StructureStart) var8.next(); + + if (var9.isSizeableStructure() && var9.getBoundingBox().intersectsWith(var5, var6, var5 + 15, var6 + 15)) { + var9.generateStructure(par1World, par2Random, + new StructureBoundingBox(var5, var6, var5 + 15, var6 + 15)); + var7 = true; + } + } + + return var7; + } + + /** + * Returns true if the structure generator has generated a structure located at + * the given position tuple. + */ + public boolean hasStructureAt(int par1, int par2, int par3) { + Iterator var4 = this.structureMap.values().iterator(); + + while (var4.hasNext()) { + StructureStart var5 = (StructureStart) var4.next(); + + if (var5.isSizeableStructure() && var5.getBoundingBox().intersectsWith(par1, par3, par1, par3)) { + Iterator var6 = var5.getComponents().iterator(); + + while (var6.hasNext()) { + StructureComponent var7 = (StructureComponent) var6.next(); + + if (var7.getBoundingBox().isVecInside(par1, par2, par3)) { + return true; + } + } + } + } + + return false; + } + + public ChunkPosition getNearestInstance(World par1World, int par2, int par3, int par4) { + this.worldObj = par1World; + this.rand.setSeed(par1World.getSeed()); + long var5 = this.rand.nextLong(); + long var7 = this.rand.nextLong(); + long var9 = (long) (par2 >> 4) * var5; + long var11 = (long) (par4 >> 4) * var7; + this.rand.setSeed(var9 ^ var11 ^ par1World.getSeed()); + this.recursiveGenerate(par1World, par2 >> 4, par4 >> 4, 0, 0, (byte[]) null); + double var13 = Double.MAX_VALUE; + ChunkPosition var15 = null; + Iterator var16 = this.structureMap.values().iterator(); + ChunkPosition var19; + int var20; + int var21; + int var22; + double var23; + + while (var16.hasNext()) { + StructureStart var17 = (StructureStart) var16.next(); + + if (var17.isSizeableStructure()) { + StructureComponent var18 = (StructureComponent) var17.getComponents().get(0); + var19 = var18.getCenter(); + var20 = var19.x - par2; + var21 = var19.y - par3; + var22 = var19.z - par4; + var23 = (double) (var20 + var20 * var21 * var21 + var22 * var22); + + if (var23 < var13) { + var13 = var23; + var15 = var19; + } + } + } + + if (var15 != null) { + return var15; + } else { + List var25 = this.getCoordList(); + + if (var25 != null) { + ChunkPosition var26 = null; + Iterator var27 = var25.iterator(); + + while (var27.hasNext()) { + var19 = (ChunkPosition) var27.next(); + var20 = var19.x - par2; + var21 = var19.y - par3; + var22 = var19.z - par4; + var23 = (double) (var20 + var20 * var21 * var21 + var22 * var22); + + if (var23 < var13) { + var13 = var23; + var26 = var19; + } + } + + return var26; + } else { + return null; + } + } + } + + /** + * Returns a list of other locations at which the structure generation has been + * run, or null if not relevant to this structure generator. + */ + protected List getCoordList() { + return null; + } + + protected abstract boolean canSpawnStructureAtCoords(int var1, int var2); + + protected abstract StructureStart getStructureStart(int var1, int var2); +} diff --git a/sp-server/src/main/java/net/minecraft/src/MapGenVillage.java b/sp-server/src/main/java/net/minecraft/src/MapGenVillage.java new file mode 100644 index 0000000..ea568c0 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/MapGenVillage.java @@ -0,0 +1,77 @@ +package net.minecraft.src; + +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Random; +import java.util.Map.Entry; + +public class MapGenVillage extends MapGenStructure { + /** A list of all the biomes villages can spawn in. */ + public static final List villageSpawnBiomes = Arrays + .asList(new BiomeGenBase[] { BiomeGenBase.plains, BiomeGenBase.desert }); + + /** World terrain type, 0 for normal, 1 for flat map */ + private int terrainType; + private int field_82665_g; + private int field_82666_h; + + public MapGenVillage() { + this.terrainType = 0; + this.field_82665_g = 32; + this.field_82666_h = 8; + } + + public MapGenVillage(Map par1Map) { + this(); + Iterator var2 = par1Map.entrySet().iterator(); + + while (var2.hasNext()) { + Entry var3 = (Entry) var2.next(); + + if (((String) var3.getKey()).equals("size")) { + this.terrainType = MathHelper.parseIntWithDefaultAndMax((String) var3.getValue(), this.terrainType, 0); + } else if (((String) var3.getKey()).equals("distance")) { + this.field_82665_g = MathHelper.parseIntWithDefaultAndMax((String) var3.getValue(), this.field_82665_g, + this.field_82666_h + 1); + } + } + } + + protected boolean canSpawnStructureAtCoords(int par1, int par2) { + int var3 = par1; + int var4 = par2; + + if (par1 < 0) { + par1 -= this.field_82665_g - 1; + } + + if (par2 < 0) { + par2 -= this.field_82665_g - 1; + } + + int var5 = par1 / this.field_82665_g; + int var6 = par2 / this.field_82665_g; + Random var7 = this.worldObj.setRandomSeed(var5, var6, 10387312); + var5 *= this.field_82665_g; + var6 *= this.field_82665_g; + var5 += var7.nextInt(this.field_82665_g - this.field_82666_h); + var6 += var7.nextInt(this.field_82665_g - this.field_82666_h); + + if (var3 == var5 && var4 == var6) { + boolean var8 = this.worldObj.getWorldChunkManager().areBiomesViable(var3 * 16 + 8, var4 * 16 + 8, 0, + villageSpawnBiomes); + + if (var8) { + return true; + } + } + + return false; + } + + protected StructureStart getStructureStart(int par1, int par2) { + return new StructureVillageStart(this.worldObj, this.rand, par1, par2, this.terrainType); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/MapInfo.java b/sp-server/src/main/java/net/minecraft/src/MapInfo.java new file mode 100644 index 0000000..b58d21f --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/MapInfo.java @@ -0,0 +1,115 @@ +package net.minecraft.src; + +import java.util.Iterator; + +public class MapInfo { + /** Reference for EntityPlayer object in MapInfo */ + public final EntityPlayer entityplayerObj; + public int[] field_76209_b; + public int[] field_76210_c; + + /** + * updated by x = mod(x*11,128) +1 x-1 is used to index field_76209_b and + * field_76210_c + */ + private int currentRandomNumber; + private int ticksUntilPlayerLocationMapUpdate; + + /** + * a cache of the result from getPlayersOnMap so that it is not resent when + * nothing changes + */ + private byte[] lastPlayerLocationOnMap; + public int field_82569_d; + private boolean field_82570_i; + + /** reference in MapInfo to MapData object */ + final MapData mapDataObj; + + public MapInfo(MapData par1MapData, EntityPlayer par2EntityPlayer) { + this.mapDataObj = par1MapData; + this.field_76209_b = new int[128]; + this.field_76210_c = new int[128]; + this.currentRandomNumber = 0; + this.ticksUntilPlayerLocationMapUpdate = 0; + this.field_82570_i = false; + this.entityplayerObj = par2EntityPlayer; + + for (int var3 = 0; var3 < this.field_76209_b.length; ++var3) { + this.field_76209_b[var3] = 0; + this.field_76210_c[var3] = 127; + } + } + + /** + * returns a 1+players*3 array, of x,y, and color . the name of this function + * may be partially wrong, as there is a second branch to the code here + */ + public byte[] getPlayersOnMap(ItemStack par1ItemStack) { + byte[] var2; + + if (!this.field_82570_i) { + var2 = new byte[] { (byte) 2, this.mapDataObj.scale }; + this.field_82570_i = true; + return var2; + } else { + int var3; + int var10; + + if (--this.ticksUntilPlayerLocationMapUpdate < 0) { + this.ticksUntilPlayerLocationMapUpdate = 4; + var2 = new byte[this.mapDataObj.playersVisibleOnMap.size() * 3 + 1]; + var2[0] = 1; + var3 = 0; + + for (Iterator var4 = this.mapDataObj.playersVisibleOnMap.values().iterator(); var4.hasNext(); ++var3) { + MapCoord var5 = (MapCoord) var4.next(); + var2[var3 * 3 + 1] = (byte) (var5.iconSize << 4 | var5.iconRotation & 15); + var2[var3 * 3 + 2] = var5.centerX; + var2[var3 * 3 + 3] = var5.centerZ; + } + + boolean var9 = !par1ItemStack.isOnItemFrame(); + + if (this.lastPlayerLocationOnMap != null && this.lastPlayerLocationOnMap.length == var2.length) { + for (var10 = 0; var10 < var2.length; ++var10) { + if (var2[var10] != this.lastPlayerLocationOnMap[var10]) { + var9 = false; + break; + } + } + } else { + var9 = false; + } + + if (!var9) { + this.lastPlayerLocationOnMap = var2; + return var2; + } + } + + for (int var8 = 0; var8 < 1; ++var8) { + var3 = this.currentRandomNumber++ * 11 % 128; + + if (this.field_76209_b[var3] >= 0) { + int var11 = this.field_76210_c[var3] - this.field_76209_b[var3] + 1; + var10 = this.field_76209_b[var3]; + byte[] var6 = new byte[var11 + 3]; + var6[0] = 0; + var6[1] = (byte) var3; + var6[2] = (byte) var10; + + for (int var7 = 0; var7 < var6.length - 3; ++var7) { + var6[var7 + 3] = this.mapDataObj.colors[(var7 + var10) * 128 + var3]; + } + + this.field_76210_c[var3] = -1; + this.field_76209_b[var3] = -1; + return var6; + } + } + + return null; + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/MapStorage.java b/sp-server/src/main/java/net/minecraft/src/MapStorage.java new file mode 100644 index 0000000..d20e0eb --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/MapStorage.java @@ -0,0 +1,207 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +public class MapStorage { + private ISaveHandler saveHandler; + + /** Map of item data String id to loaded MapDataBases */ + private Map loadedDataMap = new HashMap(); + + /** List of loaded MapDataBases. */ + private List loadedDataList = new ArrayList(); + + /** + * Map of MapDataBase id String prefixes ('map' etc) to max known unique Short + * id (the 0 part etc) for that prefix + */ + private Map idCounts = new HashMap(); + + public MapStorage(ISaveHandler par1ISaveHandler) { + this.saveHandler = par1ISaveHandler; + this.loadIdCounts(); + } + + /** + * Loads an existing MapDataBase corresponding to the given String id from disk, + * instantiating the given Class, or returns null if none such file exists. + * args: Class to instantiate, String dataid + */ + public WorldSavedData loadData(Class par1Class, String par2Str) { + WorldSavedData var3 = (WorldSavedData) this.loadedDataMap.get(par2Str); + + if (var3 != null) { + return var3; + } else { + if (this.saveHandler != null) { + try { + File var4 = this.saveHandler.getMapFileFromName(par2Str); + + if (var4 != null && var4.exists()) { + try { + var3 = (WorldSavedData) par1Class.getConstructor(new Class[] { String.class }) + .newInstance(new Object[] { par2Str }); + } catch (Exception var7) { + throw new RuntimeException("Failed to instantiate " + par1Class.toString(), var7); + } + + FileInputStream var5 = new FileInputStream(var4); + NBTTagCompound var6 = CompressedStreamTools.readCompressed(var5); + var5.close(); + var3.readFromNBT(var6.getCompoundTag("data")); + } + } catch (Exception var8) { + var8.printStackTrace(); + } + } + + if (var3 != null) { + this.loadedDataMap.put(par2Str, var3); + this.loadedDataList.add(var3); + } + + return var3; + } + } + + /** + * Assigns the given String id to the given MapDataBase, removing any existing + * ones of the same id. + */ + public void setData(String par1Str, WorldSavedData par2WorldSavedData) { + if (par2WorldSavedData == null) { + throw new RuntimeException("Can\'t set null data"); + } else { + if (this.loadedDataMap.containsKey(par1Str)) { + this.loadedDataList.remove(this.loadedDataMap.remove(par1Str)); + } + + this.loadedDataMap.put(par1Str, par2WorldSavedData); + this.loadedDataList.add(par2WorldSavedData); + } + } + + /** + * Saves all dirty loaded MapDataBases to disk. + */ + public void saveAllData() { + for (int var1 = 0; var1 < this.loadedDataList.size(); ++var1) { + WorldSavedData var2 = (WorldSavedData) this.loadedDataList.get(var1); + + if (var2.isDirty()) { + this.saveData(var2); + var2.setDirty(false); + } + } + } + + /** + * Saves the given MapDataBase to disk. + */ + private void saveData(WorldSavedData par1WorldSavedData) { + if (this.saveHandler != null) { + try { + File var2 = this.saveHandler.getMapFileFromName(par1WorldSavedData.mapName); + + if (var2 != null) { + NBTTagCompound var3 = new NBTTagCompound(); + par1WorldSavedData.writeToNBT(var3); + NBTTagCompound var4 = new NBTTagCompound(); + var4.setCompoundTag("data", var3); + FileOutputStream var5 = new FileOutputStream(var2); + CompressedStreamTools.writeCompressed(var4, var5); + var5.close(); + } + } catch (Exception var6) { + var6.printStackTrace(); + } + } + } + + /** + * Loads the idCounts Map from the 'idcounts' file. + */ + private void loadIdCounts() { + try { + this.idCounts.clear(); + + if (this.saveHandler == null) { + return; + } + + File var1 = this.saveHandler.getMapFileFromName("idcounts"); + + if (var1 != null && var1.exists()) { + DataInputStream var2 = new DataInputStream(new FileInputStream(var1)); + NBTTagCompound var3 = CompressedStreamTools.read(var2); + var2.close(); + Iterator var4 = var3.getTags().iterator(); + + while (var4.hasNext()) { + NBTBase var5 = (NBTBase) var4.next(); + + if (var5 instanceof NBTTagShort) { + NBTTagShort var6 = (NBTTagShort) var5; + String var7 = var6.getName(); + short var8 = var6.data; + this.idCounts.put(var7, Short.valueOf(var8)); + } + } + } + } catch (Exception var9) { + var9.printStackTrace(); + } + } + + /** + * Returns an unique new data id for the given prefix and saves the idCounts map + * to the 'idcounts' file. + */ + public int getUniqueDataId(String par1Str) { + Short var2 = (Short) this.idCounts.get(par1Str); + + if (var2 == null) { + var2 = Short.valueOf((short) 0); + } else { + var2 = Short.valueOf((short) (var2.shortValue() + 1)); + } + + this.idCounts.put(par1Str, var2); + + if (this.saveHandler == null) { + return var2.shortValue(); + } else { + try { + File var3 = this.saveHandler.getMapFileFromName("idcounts"); + + if (var3 != null) { + NBTTagCompound var4 = new NBTTagCompound(); + Iterator var5 = this.idCounts.keySet().iterator(); + + while (var5.hasNext()) { + String var6 = (String) var5.next(); + short var7 = ((Short) this.idCounts.get(var6)).shortValue(); + var4.setShort(var6, var7); + } + + DataOutputStream var9 = new DataOutputStream(new FileOutputStream(var3)); + CompressedStreamTools.write(var4, var9); + var9.close(); + } + } catch (Exception var8) { + var8.printStackTrace(); + } + + return var2.shortValue(); + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/Material.java b/sp-server/src/main/java/net/minecraft/src/Material.java new file mode 100644 index 0000000..65b938c --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/Material.java @@ -0,0 +1,212 @@ +package net.minecraft.src; + +public class Material { + public static final Material air = new MaterialTransparent(MapColor.airColor); + + /** The material used by BlockGrass. */ + public static final Material grass = new Material(MapColor.grassColor); + public static final Material ground = new Material(MapColor.dirtColor); + public static final Material wood = (new Material(MapColor.woodColor)).setBurning(); + public static final Material rock = (new Material(MapColor.stoneColor)).setRequiresTool(); + public static final Material iron = (new Material(MapColor.ironColor)).setRequiresTool(); + public static final Material anvil = (new Material(MapColor.ironColor)).setRequiresTool().setImmovableMobility(); + public static final Material water = (new MaterialLiquid(MapColor.waterColor)).setNoPushMobility(); + public static final Material lava = (new MaterialLiquid(MapColor.tntColor)).setNoPushMobility(); + public static final Material leaves = (new Material(MapColor.foliageColor)).setBurning().setTranslucent() + .setNoPushMobility(); + public static final Material plants = (new MaterialLogic(MapColor.foliageColor)).setNoPushMobility(); + public static final Material vine = (new MaterialLogic(MapColor.foliageColor)).setBurning().setNoPushMobility() + .setReplaceable(); + public static final Material sponge = new Material(MapColor.clothColor); + public static final Material cloth = (new Material(MapColor.clothColor)).setBurning(); + public static final Material fire = (new MaterialTransparent(MapColor.airColor)).setNoPushMobility(); + public static final Material sand = new Material(MapColor.sandColor); + public static final Material circuits = (new MaterialLogic(MapColor.airColor)).setNoPushMobility(); + public static final Material glass = (new Material(MapColor.airColor)).setTranslucent().setAlwaysHarvested(); + public static final Material redstoneLight = (new Material(MapColor.airColor)).setAlwaysHarvested(); + public static final Material tnt = (new Material(MapColor.tntColor)).setBurning().setTranslucent(); + public static final Material coral = (new Material(MapColor.foliageColor)).setNoPushMobility(); + public static final Material ice = (new Material(MapColor.iceColor)).setTranslucent().setAlwaysHarvested(); + public static final Material snow = (new MaterialLogic(MapColor.snowColor)).setReplaceable().setTranslucent() + .setRequiresTool().setNoPushMobility(); + + /** The material for crafted snow. */ + public static final Material craftedSnow = (new Material(MapColor.snowColor)).setRequiresTool(); + public static final Material cactus = (new Material(MapColor.foliageColor)).setTranslucent().setNoPushMobility(); + public static final Material clay = new Material(MapColor.clayColor); + + /** pumpkin */ + public static final Material pumpkin = (new Material(MapColor.foliageColor)).setNoPushMobility(); + public static final Material dragonEgg = (new Material(MapColor.foliageColor)).setNoPushMobility(); + + /** Material used for portals */ + public static final Material portal = (new MaterialPortal(MapColor.airColor)).setImmovableMobility(); + + /** Cake's material, see BlockCake */ + public static final Material cake = (new Material(MapColor.airColor)).setNoPushMobility(); + + /** Web's material. */ + public static final Material web = (new MaterialWeb(MapColor.clothColor)).setRequiresTool().setNoPushMobility(); + + /** Pistons' material. */ + public static final Material piston = (new Material(MapColor.stoneColor)).setImmovableMobility(); + + /** Bool defining if the block can burn or not. */ + private boolean canBurn; + + /** + * Determines whether blocks with this material can be "overwritten" by other + * blocks when placed - eg snow, vines and tall grass. + */ + private boolean replaceable; + + /** Indicates if the material is translucent */ + private boolean isTranslucent; + + /** The color index used to draw the blocks of this material on maps. */ + public final MapColor materialMapColor; + + /** + * Determines if the material can be harvested without a tool (or with the wrong + * tool) + */ + private boolean requiresNoTool = true; + + /** + * Mobility information flag. 0 indicates that this block is normal, 1 indicates + * that it can't push other blocks, 2 indicates that it can't be pushed. + */ + private int mobilityFlag; + private boolean field_85159_M; + + public Material(MapColor par1MapColor) { + this.materialMapColor = par1MapColor; + } + + /** + * Returns if blocks of these materials are liquids. + */ + public boolean isLiquid() { + return false; + } + + public boolean isSolid() { + return true; + } + + /** + * Will prevent grass from growing on dirt underneath and kill any grass below + * it if it returns true + */ + public boolean getCanBlockGrass() { + return true; + } + + /** + * Returns if this material is considered solid or not + */ + public boolean blocksMovement() { + return true; + } + + /** + * Marks the material as translucent + */ + private Material setTranslucent() { + this.isTranslucent = true; + return this; + } + + /** + * Makes blocks with this material require the correct tool to be harvested. + */ + protected Material setRequiresTool() { + this.requiresNoTool = false; + return this; + } + + /** + * Set the canBurn bool to True and return the current object. + */ + protected Material setBurning() { + this.canBurn = true; + return this; + } + + /** + * Returns if the block can burn or not. + */ + public boolean getCanBurn() { + return this.canBurn; + } + + /** + * Sets {@link #replaceable} to true. + */ + public Material setReplaceable() { + this.replaceable = true; + return this; + } + + /** + * Returns whether the material can be replaced by other blocks when placed - eg + * snow, vines and tall grass. + */ + public boolean isReplaceable() { + return this.replaceable; + } + + /** + * Indicate if the material is opaque + */ + public boolean isOpaque() { + return this.isTranslucent ? false : this.blocksMovement(); + } + + /** + * Returns true if the material can be harvested without a tool (or with the + * wrong tool) + */ + public boolean isToolNotRequired() { + return this.requiresNoTool; + } + + /** + * Returns the mobility information of the material, 0 = free, 1 = can't push + * but can move over, 2 = total immobility and stop pistons. + */ + public int getMaterialMobility() { + return this.mobilityFlag; + } + + /** + * This type of material can't be pushed, but pistons can move over it. + */ + protected Material setNoPushMobility() { + this.mobilityFlag = 1; + return this; + } + + /** + * This type of material can't be pushed, and pistons are blocked to move. + */ + protected Material setImmovableMobility() { + this.mobilityFlag = 2; + return this; + } + + /** + * Set as harvestable in any case. + */ + protected Material setAlwaysHarvested() { + this.field_85159_M = true; + return this; + } + + /** + * Check to see if we can harvest it in any case. + */ + public boolean isAlwaysHarvested() { + return this.field_85159_M; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/MaterialLiquid.java b/sp-server/src/main/java/net/minecraft/src/MaterialLiquid.java new file mode 100644 index 0000000..5d2fbd3 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/MaterialLiquid.java @@ -0,0 +1,27 @@ +package net.minecraft.src; + +public class MaterialLiquid extends Material { + public MaterialLiquid(MapColor par1MapColor) { + super(par1MapColor); + this.setReplaceable(); + this.setNoPushMobility(); + } + + /** + * Returns if blocks of these materials are liquids. + */ + public boolean isLiquid() { + return true; + } + + /** + * Returns if this material is considered solid or not + */ + public boolean blocksMovement() { + return false; + } + + public boolean isSolid() { + return false; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/MaterialLogic.java b/sp-server/src/main/java/net/minecraft/src/MaterialLogic.java new file mode 100644 index 0000000..eb91420 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/MaterialLogic.java @@ -0,0 +1,27 @@ +package net.minecraft.src; + +public class MaterialLogic extends Material { + public MaterialLogic(MapColor par1MapColor) { + super(par1MapColor); + this.setAlwaysHarvested(); + } + + public boolean isSolid() { + return false; + } + + /** + * Will prevent grass from growing on dirt underneath and kill any grass below + * it if it returns true + */ + public boolean getCanBlockGrass() { + return false; + } + + /** + * Returns if this material is considered solid or not + */ + public boolean blocksMovement() { + return false; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/MaterialPortal.java b/sp-server/src/main/java/net/minecraft/src/MaterialPortal.java new file mode 100644 index 0000000..38e335c --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/MaterialPortal.java @@ -0,0 +1,26 @@ +package net.minecraft.src; + +public class MaterialPortal extends Material { + public MaterialPortal(MapColor par1MapColor) { + super(par1MapColor); + } + + public boolean isSolid() { + return false; + } + + /** + * Will prevent grass from growing on dirt underneath and kill any grass below + * it if it returns true + */ + public boolean getCanBlockGrass() { + return false; + } + + /** + * Returns if this material is considered solid or not + */ + public boolean blocksMovement() { + return false; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/MaterialTransparent.java b/sp-server/src/main/java/net/minecraft/src/MaterialTransparent.java new file mode 100644 index 0000000..8ff5995 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/MaterialTransparent.java @@ -0,0 +1,27 @@ +package net.minecraft.src; + +public class MaterialTransparent extends Material { + public MaterialTransparent(MapColor par1MapColor) { + super(par1MapColor); + this.setReplaceable(); + } + + public boolean isSolid() { + return false; + } + + /** + * Will prevent grass from growing on dirt underneath and kill any grass below + * it if it returns true + */ + public boolean getCanBlockGrass() { + return false; + } + + /** + * Returns if this material is considered solid or not + */ + public boolean blocksMovement() { + return false; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/MaterialWeb.java b/sp-server/src/main/java/net/minecraft/src/MaterialWeb.java new file mode 100644 index 0000000..4b1b6d0 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/MaterialWeb.java @@ -0,0 +1,14 @@ +package net.minecraft.src; + +final class MaterialWeb extends Material { + MaterialWeb(MapColor par1MapColor) { + super(par1MapColor); + } + + /** + * Returns if this material is considered solid or not + */ + public boolean blocksMovement() { + return false; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/MathHelper.java b/sp-server/src/main/java/net/minecraft/src/MathHelper.java new file mode 100644 index 0000000..2cf2873 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/MathHelper.java @@ -0,0 +1,230 @@ +package net.minecraft.src; + +import java.util.Random; + +public class MathHelper { + /** + * A table of sin values computed from 0 (inclusive) to 2*pi (exclusive), with + * steps of 2*PI / 65536. + */ + private static float[] SIN_TABLE = new float[65536]; + + /** + * sin looked up in a table + */ + public static final float sin(float par0) { + return SIN_TABLE[(int) (par0 * 10430.378F) & 65535]; + } + + /** + * cos looked up in the sin table with the appropriate offset + */ + public static final float cos(float par0) { + return SIN_TABLE[(int) (par0 * 10430.378F + 16384.0F) & 65535]; + } + + public static final float sqrt_float(float par0) { + return (float) Math.sqrt((double) par0); + } + + public static final float sqrt_double(double par0) { + return (float) Math.sqrt(par0); + } + + /** + * Returns the greatest integer less than or equal to the float argument + */ + public static int floor_float(float par0) { + int var1 = (int) par0; + return par0 < (float) var1 ? var1 - 1 : var1; + } + + /** + * Returns the greatest integer less than or equal to the double argument + */ + public static int floor_double(double par0) { + int var2 = (int) par0; + return par0 < (double) var2 ? var2 - 1 : var2; + } + + /** + * Long version of floor_double + */ + public static long floor_double_long(double par0) { + long var2 = (long) par0; + return par0 < (double) var2 ? var2 - 1L : var2; + } + + public static float abs(float par0) { + return par0 >= 0.0F ? par0 : -par0; + } + + /** + * Returns the unsigned value of an int. + */ + public static int abs_int(int par0) { + return par0 >= 0 ? par0 : -par0; + } + + public static int ceiling_float_int(float par0) { + int var1 = (int) par0; + return par0 > (float) var1 ? var1 + 1 : var1; + } + + public static int ceiling_double_int(double par0) { + int var2 = (int) par0; + return par0 > (double) var2 ? var2 + 1 : var2; + } + + /** + * Returns the value of the first parameter, clamped to be within the lower and + * upper limits given by the second and third parameters. + */ + public static int clamp_int(int par0, int par1, int par2) { + return par0 < par1 ? par1 : (par0 > par2 ? par2 : par0); + } + + /** + * Maximum of the absolute value of two numbers. + */ + public static double abs_max(double par0, double par2) { + if (par0 < 0.0D) { + par0 = -par0; + } + + if (par2 < 0.0D) { + par2 = -par2; + } + + return par0 > par2 ? par0 : par2; + } + + public static int getRandomIntegerInRange(Random par0Random, int par1, int par2) { + return par1 >= par2 ? par1 : par0Random.nextInt(par2 - par1 + 1) + par1; + } + + public static double getRandomDoubleInRange(Random par0Random, double par1, double par3) { + return par1 >= par3 ? par1 : par0Random.nextDouble() * (par3 - par1) + par1; + } + + public static double average(long[] par0ArrayOfLong) { + long var1 = 0L; + long[] var3 = par0ArrayOfLong; + int var4 = par0ArrayOfLong.length; + + for (int var5 = 0; var5 < var4; ++var5) { + long var6 = var3[var5]; + var1 += var6; + } + + return (double) var1 / (double) par0ArrayOfLong.length; + } + + /** + * the angle is reduced to an angle between -180 and +180 by mod, and a 360 + * check + */ + public static float wrapAngleTo180_float(float par0) { + par0 %= 360.0F; + + if (par0 >= 180.0F) { + par0 -= 360.0F; + } + + if (par0 < -180.0F) { + par0 += 360.0F; + } + + return par0; + } + + /** + * the angle is reduced to an angle between -180 and +180 by mod, and a 360 + * check + */ + public static double wrapAngleTo180_double(double par0) { + par0 %= 360.0D; + + if (par0 >= 180.0D) { + par0 -= 360.0D; + } + + if (par0 < -180.0D) { + par0 += 360.0D; + } + + return par0; + } + + /** + * parses the string as integer or returns the second parameter if it fails + */ + public static int parseIntWithDefault(String par0Str, int par1) { + int var2 = par1; + + try { + var2 = Integer.parseInt(par0Str); + } catch (Throwable var4) { + ; + } + + return var2; + } + + /** + * parses the string as integer or returns the second parameter if it fails. + * this value is capped to par2 + */ + public static int parseIntWithDefaultAndMax(String par0Str, int par1, int par2) { + int var3 = par1; + + try { + var3 = Integer.parseInt(par0Str); + } catch (Throwable var5) { + ; + } + + if (var3 < par2) { + var3 = par2; + } + + return var3; + } + + /** + * parses the string as double or returns the second parameter if it fails. + */ + public static double parseDoubleWithDefault(String par0Str, double par1) { + double var3 = par1; + + try { + var3 = Double.parseDouble(par0Str); + } catch (Throwable var6) { + ; + } + + return var3; + } + + public static double func_82713_a(String par0Str, double par1, double par3) { + double var5 = par1; + + try { + var5 = Double.parseDouble(par0Str); + } catch (Throwable var8) { + ; + } + + if (var5 < par3) { + var5 = par3; + } + + return var5; + } + + static { + for (int var0 = 0; var0 < 65536; ++var0) { + SIN_TABLE[var0] = (float) Math.sin((double) var0 * Math.PI * 2.0D / 65536.0D); + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/MemoryConnection.java b/sp-server/src/main/java/net/minecraft/src/MemoryConnection.java new file mode 100644 index 0000000..b26ed18 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/MemoryConnection.java @@ -0,0 +1,113 @@ +package net.minecraft.src; + +import java.net.InetSocketAddress; +import java.net.SocketAddress; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class MemoryConnection implements INetworkManager { + private static final SocketAddress mySocketAddress = new InetSocketAddress("127.0.0.1", 0); + private final List readPacketCache = Collections.synchronizedList(new ArrayList()); + private final ILogAgent field_98214_c; + private MemoryConnection pairedConnection; + private NetHandler myNetHandler; + + /** set to true by {server,network}Shutdown */ + private boolean shuttingDown; + private String shutdownReason; + private Object[] field_74439_g; + + public MemoryConnection(ILogAgent par1ILogAgent, NetHandler par2NetHandler) { + this.myNetHandler = par2NetHandler; + this.field_98214_c = par1ILogAgent; + } + + /** + * Sets the NetHandler for this NetworkManager. Server-only. + */ + public void setNetHandler(NetHandler par1NetHandler) { + this.myNetHandler = par1NetHandler; + } + + /** + * Adds the packet to the correct send queue (chunk data packets go to a + * separate queue). + */ + public void addToSendQueue(Packet par1Packet) { + if (!this.shuttingDown) { + this.pairedConnection.processOrCachePacket(par1Packet); + } + } + + /** + * Wakes reader and writer threads + */ + public void wakeThreads() { + } + + /** + * Checks timeouts and processes all pending read packets. + */ + public void processReadPackets() { + int var1 = 2500; + + while (var1-- >= 0 && !this.readPacketCache.isEmpty()) { + Packet var2 = (Packet) this.readPacketCache.remove(0); + var2.processPacket(this.myNetHandler); + } + + if (this.readPacketCache.size() > var1) { + this.field_98214_c + .func_98236_b("Memory connection overburdened; after processing 2500 packets, we still have " + + this.readPacketCache.size() + " to go!"); + } + + if (this.shuttingDown && this.readPacketCache.isEmpty()) { + this.myNetHandler.handleErrorMessage(this.shutdownReason, this.field_74439_g); + } + } + + /** + * Returns the socket address of the remote side. Server-only. + */ + public SocketAddress getRemoteAddress() { + return mySocketAddress; + } + + /** + * Shuts down the server. (Only actually used on the server) + */ + public void serverShutdown() { + this.shuttingDown = true; + } + + /** + * Shuts down the network with the specified reason. Closes all streams and + * sockets, spawns NetworkMasterThread to stop reading and writing threads. + */ + public void networkShutdown(String par1Str, Object... par2ArrayOfObj) { + this.shuttingDown = true; + this.shutdownReason = par1Str; + this.field_74439_g = par2ArrayOfObj; + } + + /** + * Returns the number of chunk data packets waiting to be sent. + */ + public int getNumChunkDataPackets() { + return 0; + } + + /** + * acts immiditally if isWritePacket, otherwise adds it to the readCache to be + * processed next tick + */ + public void processOrCachePacket(Packet par1Packet) { + if (par1Packet.canProcessAsync() && this.myNetHandler.canProcessPacketsAsync()) { + par1Packet.processPacket(this.myNetHandler); + } else { + this.readPacketCache.add(par1Packet); + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/MerchantRecipe.java b/sp-server/src/main/java/net/minecraft/src/MerchantRecipe.java new file mode 100644 index 0000000..998e985 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/MerchantRecipe.java @@ -0,0 +1,135 @@ +package net.minecraft.src; + +public class MerchantRecipe { + /** Item the Villager buys. */ + private ItemStack itemToBuy; + + /** Second Item the Villager buys. */ + private ItemStack secondItemToBuy; + + /** Item the Villager sells. */ + private ItemStack itemToSell; + + /** + * Saves how much has been tool used when put into to slot to be enchanted. + */ + private int toolUses; + + /** Maximum times this trade can be used. */ + private int maxTradeUses; + + public MerchantRecipe(NBTTagCompound par1NBTTagCompound) { + this.readFromTags(par1NBTTagCompound); + } + + public MerchantRecipe(ItemStack par1ItemStack, ItemStack par2ItemStack, ItemStack par3ItemStack) { + this.itemToBuy = par1ItemStack; + this.secondItemToBuy = par2ItemStack; + this.itemToSell = par3ItemStack; + this.maxTradeUses = 7; + } + + public MerchantRecipe(ItemStack par1ItemStack, ItemStack par2ItemStack) { + this(par1ItemStack, (ItemStack) null, par2ItemStack); + } + + public MerchantRecipe(ItemStack par1ItemStack, Item par2Item) { + this(par1ItemStack, new ItemStack(par2Item)); + } + + /** + * Gets the itemToBuy. + */ + public ItemStack getItemToBuy() { + return this.itemToBuy; + } + + /** + * Gets secondItemToBuy. + */ + public ItemStack getSecondItemToBuy() { + return this.secondItemToBuy; + } + + /** + * Gets if Villager has secondItemToBuy. + */ + public boolean hasSecondItemToBuy() { + return this.secondItemToBuy != null; + } + + /** + * Gets itemToSell. + */ + public ItemStack getItemToSell() { + return this.itemToSell; + } + + /** + * checks if both the first and second ItemToBuy IDs are the same + */ + public boolean hasSameIDsAs(MerchantRecipe par1MerchantRecipe) { + return this.itemToBuy.itemID == par1MerchantRecipe.itemToBuy.itemID + && this.itemToSell.itemID == par1MerchantRecipe.itemToSell.itemID + ? this.secondItemToBuy == null && par1MerchantRecipe.secondItemToBuy == null + || this.secondItemToBuy != null && par1MerchantRecipe.secondItemToBuy != null + && this.secondItemToBuy.itemID == par1MerchantRecipe.secondItemToBuy.itemID + : false; + } + + /** + * checks first and second ItemToBuy ID's and count. Calls hasSameIDs + */ + public boolean hasSameItemsAs(MerchantRecipe par1MerchantRecipe) { + return this.hasSameIDsAs(par1MerchantRecipe) + && (this.itemToBuy.stackSize < par1MerchantRecipe.itemToBuy.stackSize || this.secondItemToBuy != null + && this.secondItemToBuy.stackSize < par1MerchantRecipe.secondItemToBuy.stackSize); + } + + public void incrementToolUses() { + ++this.toolUses; + } + + public void func_82783_a(int par1) { + this.maxTradeUses += par1; + } + + public boolean func_82784_g() { + return this.toolUses >= this.maxTradeUses; + } + + public void readFromTags(NBTTagCompound par1NBTTagCompound) { + NBTTagCompound var2 = par1NBTTagCompound.getCompoundTag("buy"); + this.itemToBuy = ItemStack.loadItemStackFromNBT(var2); + NBTTagCompound var3 = par1NBTTagCompound.getCompoundTag("sell"); + this.itemToSell = ItemStack.loadItemStackFromNBT(var3); + + if (par1NBTTagCompound.hasKey("buyB")) { + this.secondItemToBuy = ItemStack.loadItemStackFromNBT(par1NBTTagCompound.getCompoundTag("buyB")); + } + + if (par1NBTTagCompound.hasKey("uses")) { + this.toolUses = par1NBTTagCompound.getInteger("uses"); + } + + if (par1NBTTagCompound.hasKey("maxUses")) { + this.maxTradeUses = par1NBTTagCompound.getInteger("maxUses"); + } else { + this.maxTradeUses = 7; + } + } + + public NBTTagCompound writeToTags() { + NBTTagCompound var1 = new NBTTagCompound(); + var1.setCompoundTag("buy", this.itemToBuy.writeToNBT(new NBTTagCompound("buy"))); + var1.setCompoundTag("sell", this.itemToSell.writeToNBT(new NBTTagCompound("sell"))); + + if (this.secondItemToBuy != null) { + var1.setCompoundTag("buyB", this.secondItemToBuy.writeToNBT(new NBTTagCompound("buyB"))); + } + + var1.setInteger("uses", this.toolUses); + var1.setInteger("maxUses", this.maxTradeUses); + return var1; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/MerchantRecipeList.java b/sp-server/src/main/java/net/minecraft/src/MerchantRecipeList.java new file mode 100644 index 0000000..a48e8aa --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/MerchantRecipeList.java @@ -0,0 +1,104 @@ +package net.minecraft.src; + +import java.io.DataOutputStream; +import java.io.IOException; +import java.util.ArrayList; + +public class MerchantRecipeList extends ArrayList { + public MerchantRecipeList() { + } + + public MerchantRecipeList(NBTTagCompound par1NBTTagCompound) { + this.readRecipiesFromTags(par1NBTTagCompound); + } + + /** + * can par1,par2 be used to in crafting recipe par3 + */ + public MerchantRecipe canRecipeBeUsed(ItemStack par1ItemStack, ItemStack par2ItemStack, int par3) { + if (par3 > 0 && par3 < this.size()) { + MerchantRecipe var6 = (MerchantRecipe) this.get(par3); + return par1ItemStack.itemID == var6.getItemToBuy().itemID + && (par2ItemStack == null && !var6.hasSecondItemToBuy() || var6.hasSecondItemToBuy() + && par2ItemStack != null && var6.getSecondItemToBuy().itemID == par2ItemStack.itemID) + && par1ItemStack.stackSize >= var6.getItemToBuy().stackSize + && (!var6.hasSecondItemToBuy() || par2ItemStack.stackSize >= var6.getSecondItemToBuy().stackSize) + ? var6 + : null; + } else { + for (int var4 = 0; var4 < this.size(); ++var4) { + MerchantRecipe var5 = (MerchantRecipe) this.get(var4); + + if (par1ItemStack.itemID == var5.getItemToBuy().itemID + && par1ItemStack.stackSize >= var5.getItemToBuy().stackSize + && (!var5.hasSecondItemToBuy() && par2ItemStack == null || var5.hasSecondItemToBuy() + && par2ItemStack != null && var5.getSecondItemToBuy().itemID == par2ItemStack.itemID + && par2ItemStack.stackSize >= var5.getSecondItemToBuy().stackSize)) { + return var5; + } + } + + return null; + } + } + + /** + * checks if there is a recipie for the same ingredients already on the list, + * and replaces it. otherwise, adds it + */ + public void addToListWithCheck(MerchantRecipe par1MerchantRecipe) { + for (int var2 = 0; var2 < this.size(); ++var2) { + MerchantRecipe var3 = (MerchantRecipe) this.get(var2); + + if (par1MerchantRecipe.hasSameIDsAs(var3)) { + if (par1MerchantRecipe.hasSameItemsAs(var3)) { + this.set(var2, par1MerchantRecipe); + } + + return; + } + } + + this.add(par1MerchantRecipe); + } + + public void writeRecipiesToStream(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeByte((byte) (this.size() & 255)); + + for (int var2 = 0; var2 < this.size(); ++var2) { + MerchantRecipe var3 = (MerchantRecipe) this.get(var2); + Packet.writeItemStack(var3.getItemToBuy(), par1DataOutputStream); + Packet.writeItemStack(var3.getItemToSell(), par1DataOutputStream); + ItemStack var4 = var3.getSecondItemToBuy(); + par1DataOutputStream.writeBoolean(var4 != null); + + if (var4 != null) { + Packet.writeItemStack(var4, par1DataOutputStream); + } + + par1DataOutputStream.writeBoolean(var3.func_82784_g()); + } + } + + public void readRecipiesFromTags(NBTTagCompound par1NBTTagCompound) { + NBTTagList var2 = par1NBTTagCompound.getTagList("Recipes"); + + for (int var3 = 0; var3 < var2.tagCount(); ++var3) { + NBTTagCompound var4 = (NBTTagCompound) var2.tagAt(var3); + this.add(new MerchantRecipe(var4)); + } + } + + public NBTTagCompound getRecipiesAsTags() { + NBTTagCompound var1 = new NBTTagCompound(); + NBTTagList var2 = new NBTTagList("Recipes"); + + for (int var3 = 0; var3 < this.size(); ++var3) { + MerchantRecipe var4 = (MerchantRecipe) this.get(var3); + var2.appendTag(var4.writeToTags()); + } + + var1.setTag("Recipes", var2); + return var1; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/MinecraftException.java b/sp-server/src/main/java/net/minecraft/src/MinecraftException.java new file mode 100644 index 0000000..ca9e1f3 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/MinecraftException.java @@ -0,0 +1,7 @@ +package net.minecraft.src; + +public class MinecraftException extends Exception { + public MinecraftException(String par1Str) { + super(par1Str); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/MobSpawnerBaseLogic.java b/sp-server/src/main/java/net/minecraft/src/MobSpawnerBaseLogic.java new file mode 100644 index 0000000..1a9c5a8 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/MobSpawnerBaseLogic.java @@ -0,0 +1,308 @@ +package net.minecraft.src; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +public abstract class MobSpawnerBaseLogic { + /** The delay to spawn. */ + public int spawnDelay = 20; + private String mobID = "Pig"; + + /** List of minecart to spawn. */ + private List minecartToSpawn = null; + private WeightedRandomMinecart randomMinecart = null; + public double field_98287_c; + public double field_98284_d = 0.0D; + private int minSpawnDelay = 200; + private int maxSpawnDelay = 800; + private int spawnCount = 4; + private Entity field_98291_j; + private int maxNearbyEntities = 6; + + /** The distance from which a player activates the spawner. */ + private int activatingRangeFromPlayer = 16; + + /** The range coefficient for spawning entities around. */ + private int spawnRange = 4; + + /** + * Gets the entity name that should be spawned. + */ + public String getEntityNameToSpawn() { + if (this.getRandomMinecart() == null) { + if (this.mobID.equals("Minecart")) { + this.mobID = "MinecartRideable"; + } + + return this.mobID; + } else { + return this.getRandomMinecart().minecartName; + } + } + + public void setMobID(String par1Str) { + this.mobID = par1Str; + } + + /** + * Returns true if there's a player close enough to this mob spawner to activate + * it. + */ + public boolean canRun() { + return this.getSpawnerWorld().getClosestPlayer((double) this.getSpawnerX() + 0.5D, + (double) this.getSpawnerY() + 0.5D, (double) this.getSpawnerZ() + 0.5D, + (double) this.activatingRangeFromPlayer) != null; + } + + public void updateSpawner() { + if (this.canRun()) { + double var5; + + if (this.getSpawnerWorld().isRemote) { + double var1 = (double) ((float) this.getSpawnerX() + this.getSpawnerWorld().rand.nextFloat()); + double var3 = (double) ((float) this.getSpawnerY() + this.getSpawnerWorld().rand.nextFloat()); + var5 = (double) ((float) this.getSpawnerZ() + this.getSpawnerWorld().rand.nextFloat()); + this.getSpawnerWorld().spawnParticle("smoke", var1, var3, var5, 0.0D, 0.0D, 0.0D); + this.getSpawnerWorld().spawnParticle("flame", var1, var3, var5, 0.0D, 0.0D, 0.0D); + + if (this.spawnDelay > 0) { + --this.spawnDelay; + } + + this.field_98284_d = this.field_98287_c; + this.field_98287_c = (this.field_98287_c + (double) (1000.0F / ((float) this.spawnDelay + 200.0F))) + % 360.0D; + } else { + if (this.spawnDelay == -1) { + this.func_98273_j(); + } + + if (this.spawnDelay > 0) { + --this.spawnDelay; + return; + } + + boolean var12 = false; + + for (int var2 = 0; var2 < this.spawnCount; ++var2) { + Entity var13 = EntityList.createEntityByName(this.getEntityNameToSpawn(), this.getSpawnerWorld()); + + if (var13 == null) { + return; + } + + int var4 = this.getSpawnerWorld() + .getEntitiesWithinAABB(var13.getClass(), AxisAlignedBB.getAABBPool() + .getAABB((double) this.getSpawnerX(), (double) this.getSpawnerY(), + (double) this.getSpawnerZ(), (double) (this.getSpawnerX() + 1), + (double) (this.getSpawnerY() + 1), (double) (this.getSpawnerZ() + 1)) + .expand((double) (this.spawnRange * 2), 4.0D, (double) (this.spawnRange * 2))) + .size(); + + if (var4 >= this.maxNearbyEntities) { + this.func_98273_j(); + return; + } + + var5 = (double) this.getSpawnerX() + + (this.getSpawnerWorld().rand.nextDouble() - this.getSpawnerWorld().rand.nextDouble()) + * (double) this.spawnRange; + double var7 = (double) (this.getSpawnerY() + this.getSpawnerWorld().rand.nextInt(3) - 1); + double var9 = (double) this.getSpawnerZ() + + (this.getSpawnerWorld().rand.nextDouble() - this.getSpawnerWorld().rand.nextDouble()) + * (double) this.spawnRange; + EntityLiving var11 = var13 instanceof EntityLiving ? (EntityLiving) var13 : null; + var13.setLocationAndAngles(var5, var7, var9, this.getSpawnerWorld().rand.nextFloat() * 360.0F, + 0.0F); + + if (var11 == null || var11.getCanSpawnHere()) { + this.func_98265_a(var13); + this.getSpawnerWorld().playAuxSFX(2004, this.getSpawnerX(), this.getSpawnerY(), + this.getSpawnerZ(), 0); + + if (var11 != null) { + var11.spawnExplosionParticle(); + } + + var12 = true; + } + } + + if (var12) { + this.func_98273_j(); + } + } + } + } + + public Entity func_98265_a(Entity par1Entity) { + if (this.getRandomMinecart() != null) { + NBTTagCompound var2 = new NBTTagCompound(); + par1Entity.addEntityID(var2); + Iterator var3 = this.getRandomMinecart().field_98222_b.getTags().iterator(); + + while (var3.hasNext()) { + NBTBase var4 = (NBTBase) var3.next(); + var2.setTag(var4.getName(), var4.copy()); + } + + par1Entity.readFromNBT(var2); + + if (par1Entity.worldObj != null) { + par1Entity.worldObj.spawnEntityInWorld(par1Entity); + } + + NBTTagCompound var10; + + for (Entity var9 = par1Entity; var2.hasKey("Riding"); var2 = var10) { + var10 = var2.getCompoundTag("Riding"); + Entity var5 = EntityList.createEntityByName(var10.getString("id"), this.getSpawnerWorld()); + + if (var5 != null) { + NBTTagCompound var6 = new NBTTagCompound(); + var5.addEntityID(var6); + Iterator var7 = var10.getTags().iterator(); + + while (var7.hasNext()) { + NBTBase var8 = (NBTBase) var7.next(); + var6.setTag(var8.getName(), var8.copy()); + } + + var5.readFromNBT(var6); + var5.setLocationAndAngles(var9.posX, var9.posY, var9.posZ, var9.rotationYaw, var9.rotationPitch); + this.getSpawnerWorld().spawnEntityInWorld(var5); + var9.mountEntity(var5); + } + + var9 = var5; + } + } else if (par1Entity instanceof EntityLiving && par1Entity.worldObj != null) { + ((EntityLiving) par1Entity).initCreature(); + this.getSpawnerWorld().spawnEntityInWorld(par1Entity); + } + + return par1Entity; + } + + private void func_98273_j() { + if (this.maxSpawnDelay <= this.minSpawnDelay) { + this.spawnDelay = this.minSpawnDelay; + } else { + int var10003 = this.maxSpawnDelay - this.minSpawnDelay; + this.spawnDelay = this.minSpawnDelay + this.getSpawnerWorld().rand.nextInt(var10003); + } + + if (this.minecartToSpawn != null && this.minecartToSpawn.size() > 0) { + this.setRandomMinecart((WeightedRandomMinecart) WeightedRandom.getRandomItem(this.getSpawnerWorld().rand, + this.minecartToSpawn)); + } + + this.func_98267_a(1); + } + + public void readFromNBT(NBTTagCompound par1NBTTagCompound) { + this.mobID = par1NBTTagCompound.getString("EntityId"); + this.spawnDelay = par1NBTTagCompound.getShort("Delay"); + + if (par1NBTTagCompound.hasKey("SpawnPotentials")) { + this.minecartToSpawn = new ArrayList(); + NBTTagList var2 = par1NBTTagCompound.getTagList("SpawnPotentials"); + + for (int var3 = 0; var3 < var2.tagCount(); ++var3) { + this.minecartToSpawn.add(new WeightedRandomMinecart(this, (NBTTagCompound) var2.tagAt(var3))); + } + } else { + this.minecartToSpawn = null; + } + + if (par1NBTTagCompound.hasKey("SpawnData")) { + this.setRandomMinecart( + new WeightedRandomMinecart(this, par1NBTTagCompound.getCompoundTag("SpawnData"), this.mobID)); + } else { + this.setRandomMinecart((WeightedRandomMinecart) null); + } + + if (par1NBTTagCompound.hasKey("MinSpawnDelay")) { + this.minSpawnDelay = par1NBTTagCompound.getShort("MinSpawnDelay"); + this.maxSpawnDelay = par1NBTTagCompound.getShort("MaxSpawnDelay"); + this.spawnCount = par1NBTTagCompound.getShort("SpawnCount"); + } + + if (par1NBTTagCompound.hasKey("MaxNearbyEntities")) { + this.maxNearbyEntities = par1NBTTagCompound.getShort("MaxNearbyEntities"); + this.activatingRangeFromPlayer = par1NBTTagCompound.getShort("RequiredPlayerRange"); + } + + if (par1NBTTagCompound.hasKey("SpawnRange")) { + this.spawnRange = par1NBTTagCompound.getShort("SpawnRange"); + } + + if (this.getSpawnerWorld() != null && this.getSpawnerWorld().isRemote) { + this.field_98291_j = null; + } + } + + public void writeToNBT(NBTTagCompound par1NBTTagCompound) { + par1NBTTagCompound.setString("EntityId", this.getEntityNameToSpawn()); + par1NBTTagCompound.setShort("Delay", (short) this.spawnDelay); + par1NBTTagCompound.setShort("MinSpawnDelay", (short) this.minSpawnDelay); + par1NBTTagCompound.setShort("MaxSpawnDelay", (short) this.maxSpawnDelay); + par1NBTTagCompound.setShort("SpawnCount", (short) this.spawnCount); + par1NBTTagCompound.setShort("MaxNearbyEntities", (short) this.maxNearbyEntities); + par1NBTTagCompound.setShort("RequiredPlayerRange", (short) this.activatingRangeFromPlayer); + par1NBTTagCompound.setShort("SpawnRange", (short) this.spawnRange); + + if (this.getRandomMinecart() != null) { + par1NBTTagCompound.setCompoundTag("SpawnData", + (NBTTagCompound) this.getRandomMinecart().field_98222_b.copy()); + } + + if (this.getRandomMinecart() != null || this.minecartToSpawn != null && this.minecartToSpawn.size() > 0) { + NBTTagList var2 = new NBTTagList(); + + if (this.minecartToSpawn != null && this.minecartToSpawn.size() > 0) { + Iterator var3 = this.minecartToSpawn.iterator(); + + while (var3.hasNext()) { + WeightedRandomMinecart var4 = (WeightedRandomMinecart) var3.next(); + var2.appendTag(var4.func_98220_a()); + } + } else { + var2.appendTag(this.getRandomMinecart().func_98220_a()); + } + + par1NBTTagCompound.setTag("SpawnPotentials", var2); + } + } + + /** + * Sets the delay to minDelay if parameter given is 1, else return false. + */ + public boolean setDelayToMin(int par1) { + if (par1 == 1 && this.getSpawnerWorld().isRemote) { + this.spawnDelay = this.minSpawnDelay; + return true; + } else { + return false; + } + } + + public WeightedRandomMinecart getRandomMinecart() { + return this.randomMinecart; + } + + public void setRandomMinecart(WeightedRandomMinecart par1WeightedRandomMinecart) { + this.randomMinecart = par1WeightedRandomMinecart; + } + + public abstract void func_98267_a(int var1); + + public abstract World getSpawnerWorld(); + + public abstract int getSpawnerX(); + + public abstract int getSpawnerY(); + + public abstract int getSpawnerZ(); +} diff --git a/sp-server/src/main/java/net/minecraft/src/MovingObjectPosition.java b/sp-server/src/main/java/net/minecraft/src/MovingObjectPosition.java new file mode 100644 index 0000000..9f48dfc --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/MovingObjectPosition.java @@ -0,0 +1,43 @@ +package net.minecraft.src; + +public class MovingObjectPosition { + /** What type of ray trace hit was this? 0 = block, 1 = entity */ + public EnumMovingObjectType typeOfHit; + + /** x coordinate of the block ray traced against */ + public int blockX; + + /** y coordinate of the block ray traced against */ + public int blockY; + + /** z coordinate of the block ray traced against */ + public int blockZ; + + /** + * Which side was hit. If its -1 then it went the full length of the ray trace. + * Bottom = 0, Top = 1, East = 2, West = 3, North = 4, South = 5. + */ + public int sideHit; + + /** The vector position of the hit */ + public Vec3 hitVec; + + /** The hit entity */ + public Entity entityHit; + + public MovingObjectPosition(int par1, int par2, int par3, int par4, Vec3 par5Vec3) { + this.typeOfHit = EnumMovingObjectType.TILE; + this.blockX = par1; + this.blockY = par2; + this.blockZ = par3; + this.sideHit = par4; + this.hitVec = par5Vec3.myVec3LocalPool.getVecFromPool(par5Vec3.xCoord, par5Vec3.yCoord, par5Vec3.zCoord); + } + + public MovingObjectPosition(Entity par1Entity) { + this.typeOfHit = EnumMovingObjectType.ENTITY; + this.entityHit = par1Entity; + this.hitVec = par1Entity.worldObj.getWorldVec3Pool().getVecFromPool(par1Entity.posX, par1Entity.posY, + par1Entity.posZ); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/NBTBase.java b/sp-server/src/main/java/net/minecraft/src/NBTBase.java new file mode 100644 index 0000000..70c20d5 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/NBTBase.java @@ -0,0 +1,211 @@ +package net.minecraft.src; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; + +public abstract class NBTBase { + public static final String[] NBTTypes = new String[] { "END", "BYTE", "SHORT", "INT", "LONG", "FLOAT", "DOUBLE", + "BYTE[]", "STRING", "LIST", "COMPOUND", "INT[]" }; + + /** The UTF string key used to lookup values. */ + private String name; + + /** + * Write the actual data contents of the tag, implemented in NBT extension + * classes + */ + abstract void write(DataOutput var1) throws IOException; + + /** + * Read the actual data contents of the tag, implemented in NBT extension + * classes + */ + abstract void load(DataInput var1) throws IOException; + + /** + * Gets the type byte for the tag. + */ + public abstract byte getId(); + + protected NBTBase(String par1Str) { + if (par1Str == null) { + this.name = ""; + } else { + this.name = par1Str; + } + } + + /** + * Sets the name for this tag and returns this for convenience. + */ + public NBTBase setName(String par1Str) { + if (par1Str == null) { + this.name = ""; + } else { + this.name = par1Str; + } + + return this; + } + + /** + * Gets the name corresponding to the tag, or an empty string if none set. + */ + public String getName() { + return this.name == null ? "" : this.name; + } + + /** + * Reads and returns a tag from the given DataInput, or the End tag if no tag + * could be read. + */ + public static NBTBase readNamedTag(DataInput par0DataInput) throws IOException { + byte var1 = par0DataInput.readByte(); + + if (var1 == 0) { + return new NBTTagEnd(); + } else { + String var2 = par0DataInput.readUTF(); + NBTBase var3 = newTag(var1, var2); + + try { + var3.load(par0DataInput); + return var3; + } catch (IOException var7) { + CrashReport var5 = CrashReport.makeCrashReport(var7, "Loading NBT data"); + CrashReportCategory var6 = var5.makeCategory("NBT Tag"); + var6.addCrashSection("Tag name", var2); + var6.addCrashSection("Tag type", Byte.valueOf(var1)); + throw new ReportedException(var5); + } + } + } + + /** + * Writes the specified tag to the given DataOutput, writing the type byte, the + * UTF string key and then calling the tag to write its data. + */ + public static void writeNamedTag(NBTBase par0NBTBase, DataOutput par1DataOutput) throws IOException { + par1DataOutput.writeByte(par0NBTBase.getId()); + + if (par0NBTBase.getId() != 0) { + par1DataOutput.writeUTF(par0NBTBase.getName()); + par0NBTBase.write(par1DataOutput); + } + } + + /** + * Creates and returns a new tag of the specified type, or null if invalid. + */ + public static NBTBase newTag(byte par0, String par1Str) { + switch (par0) { + case 0: + return new NBTTagEnd(); + + case 1: + return new NBTTagByte(par1Str); + + case 2: + return new NBTTagShort(par1Str); + + case 3: + return new NBTTagInt(par1Str); + + case 4: + return new NBTTagLong(par1Str); + + case 5: + return new NBTTagFloat(par1Str); + + case 6: + return new NBTTagDouble(par1Str); + + case 7: + return new NBTTagByteArray(par1Str); + + case 8: + return new NBTTagString(par1Str); + + case 9: + return new NBTTagList(par1Str); + + case 10: + return new NBTTagCompound(par1Str); + + case 11: + return new NBTTagIntArray(par1Str); + + default: + return null; + } + } + + /** + * Returns the string name of a tag with the specified type, or 'UNKNOWN' if + * invalid. + */ + public static String getTagName(byte par0) { + switch (par0) { + case 0: + return "TAG_End"; + + case 1: + return "TAG_Byte"; + + case 2: + return "TAG_Short"; + + case 3: + return "TAG_Int"; + + case 4: + return "TAG_Long"; + + case 5: + return "TAG_Float"; + + case 6: + return "TAG_Double"; + + case 7: + return "TAG_Byte_Array"; + + case 8: + return "TAG_String"; + + case 9: + return "TAG_List"; + + case 10: + return "TAG_Compound"; + + case 11: + return "TAG_Int_Array"; + + default: + return "UNKNOWN"; + } + } + + /** + * Creates a clone of the tag. + */ + public abstract NBTBase copy(); + + public boolean equals(Object par1Obj) { + if (!(par1Obj instanceof NBTBase)) { + return false; + } else { + NBTBase var2 = (NBTBase) par1Obj; + return this.getId() != var2.getId() ? false + : ((this.name != null || var2.name == null) && (this.name == null || var2.name != null) + ? this.name == null || this.name.equals(var2.name) + : false); + } + } + + public int hashCode() { + return this.name.hashCode() ^ this.getId(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/NBTTagByte.java b/sp-server/src/main/java/net/minecraft/src/NBTTagByte.java new file mode 100644 index 0000000..35dc311 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/NBTTagByte.java @@ -0,0 +1,66 @@ +package net.minecraft.src; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; + +public class NBTTagByte extends NBTBase { + /** The byte value for the tag. */ + public byte data; + + public NBTTagByte(String par1Str) { + super(par1Str); + } + + public NBTTagByte(String par1Str, byte par2) { + super(par1Str); + this.data = par2; + } + + /** + * Write the actual data contents of the tag, implemented in NBT extension + * classes + */ + void write(DataOutput par1DataOutput) throws IOException { + par1DataOutput.writeByte(this.data); + } + + /** + * Read the actual data contents of the tag, implemented in NBT extension + * classes + */ + void load(DataInput par1DataInput) throws IOException { + this.data = par1DataInput.readByte(); + } + + /** + * Gets the type byte for the tag. + */ + public byte getId() { + return (byte) 1; + } + + public String toString() { + return "" + this.data; + } + + /** + * Creates a clone of the tag. + */ + public NBTBase copy() { + return new NBTTagByte(this.getName(), this.data); + } + + public boolean equals(Object par1Obj) { + if (super.equals(par1Obj)) { + NBTTagByte var2 = (NBTTagByte) par1Obj; + return this.data == var2.data; + } else { + return false; + } + } + + public int hashCode() { + return super.hashCode() ^ this.data; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/NBTTagByteArray.java b/sp-server/src/main/java/net/minecraft/src/NBTTagByteArray.java new file mode 100644 index 0000000..06d58eb --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/NBTTagByteArray.java @@ -0,0 +1,67 @@ +package net.minecraft.src; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; +import java.util.Arrays; + +public class NBTTagByteArray extends NBTBase { + /** The byte array stored in the tag. */ + public byte[] byteArray; + + public NBTTagByteArray(String par1Str) { + super(par1Str); + } + + public NBTTagByteArray(String par1Str, byte[] par2ArrayOfByte) { + super(par1Str); + this.byteArray = par2ArrayOfByte; + } + + /** + * Write the actual data contents of the tag, implemented in NBT extension + * classes + */ + void write(DataOutput par1DataOutput) throws IOException { + par1DataOutput.writeInt(this.byteArray.length); + par1DataOutput.write(this.byteArray); + } + + /** + * Read the actual data contents of the tag, implemented in NBT extension + * classes + */ + void load(DataInput par1DataInput) throws IOException { + int var2 = par1DataInput.readInt(); + this.byteArray = new byte[var2]; + par1DataInput.readFully(this.byteArray); + } + + /** + * Gets the type byte for the tag. + */ + public byte getId() { + return (byte) 7; + } + + public String toString() { + return "[" + this.byteArray.length + " bytes]"; + } + + /** + * Creates a clone of the tag. + */ + public NBTBase copy() { + byte[] var1 = new byte[this.byteArray.length]; + System.arraycopy(this.byteArray, 0, var1, 0, this.byteArray.length); + return new NBTTagByteArray(this.getName(), var1); + } + + public boolean equals(Object par1Obj) { + return super.equals(par1Obj) ? Arrays.equals(this.byteArray, ((NBTTagByteArray) par1Obj).byteArray) : false; + } + + public int hashCode() { + return super.hashCode() ^ Arrays.hashCode(this.byteArray); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/NBTTagCompound.java b/sp-server/src/main/java/net/minecraft/src/NBTTagCompound.java new file mode 100644 index 0000000..2f0b189 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/NBTTagCompound.java @@ -0,0 +1,398 @@ +package net.minecraft.src; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +public class NBTTagCompound extends NBTBase { + /** + * The key-value pairs for the tag. Each key is a UTF string, each value is a + * tag. + */ + private Map tagMap = new HashMap(); + + public NBTTagCompound() { + super(""); + } + + public NBTTagCompound(String par1Str) { + super(par1Str); + } + + /** + * Write the actual data contents of the tag, implemented in NBT extension + * classes + */ + void write(DataOutput par1DataOutput) throws IOException { + Iterator var2 = this.tagMap.values().iterator(); + + while (var2.hasNext()) { + NBTBase var3 = (NBTBase) var2.next(); + NBTBase.writeNamedTag(var3, par1DataOutput); + } + + par1DataOutput.writeByte(0); + } + + /** + * Read the actual data contents of the tag, implemented in NBT extension + * classes + */ + void load(DataInput par1DataInput) throws IOException { + this.tagMap.clear(); + NBTBase var2; + + while ((var2 = NBTBase.readNamedTag(par1DataInput)).getId() != 0) { + this.tagMap.put(var2.getName(), var2); + } + } + + /** + * Returns all the values in the tagMap HashMap. + */ + public Collection getTags() { + return this.tagMap.values(); + } + + /** + * Gets the type byte for the tag. + */ + public byte getId() { + return (byte) 10; + } + + /** + * Stores the given tag into the map with the given string key. This is mostly + * used to store tag lists. + */ + public void setTag(String par1Str, NBTBase par2NBTBase) { + this.tagMap.put(par1Str, par2NBTBase.setName(par1Str)); + } + + /** + * Stores a new NBTTagByte with the given byte value into the map with the given + * string key. + */ + public void setByte(String par1Str, byte par2) { + this.tagMap.put(par1Str, new NBTTagByte(par1Str, par2)); + } + + /** + * Stores a new NBTTagShort with the given short value into the map with the + * given string key. + */ + public void setShort(String par1Str, short par2) { + this.tagMap.put(par1Str, new NBTTagShort(par1Str, par2)); + } + + /** + * Stores a new NBTTagInt with the given integer value into the map with the + * given string key. + */ + public void setInteger(String par1Str, int par2) { + this.tagMap.put(par1Str, new NBTTagInt(par1Str, par2)); + } + + /** + * Stores a new NBTTagLong with the given long value into the map with the given + * string key. + */ + public void setLong(String par1Str, long par2) { + this.tagMap.put(par1Str, new NBTTagLong(par1Str, par2)); + } + + /** + * Stores a new NBTTagFloat with the given float value into the map with the + * given string key. + */ + public void setFloat(String par1Str, float par2) { + this.tagMap.put(par1Str, new NBTTagFloat(par1Str, par2)); + } + + /** + * Stores a new NBTTagDouble with the given double value into the map with the + * given string key. + */ + public void setDouble(String par1Str, double par2) { + this.tagMap.put(par1Str, new NBTTagDouble(par1Str, par2)); + } + + /** + * Stores a new NBTTagString with the given string value into the map with the + * given string key. + */ + public void setString(String par1Str, String par2Str) { + this.tagMap.put(par1Str, new NBTTagString(par1Str, par2Str)); + } + + /** + * Stores a new NBTTagByteArray with the given array as data into the map with + * the given string key. + */ + public void setByteArray(String par1Str, byte[] par2ArrayOfByte) { + this.tagMap.put(par1Str, new NBTTagByteArray(par1Str, par2ArrayOfByte)); + } + + /** + * Stores a new NBTTagIntArray with the given array as data into the map with + * the given string key. + */ + public void setIntArray(String par1Str, int[] par2ArrayOfInteger) { + this.tagMap.put(par1Str, new NBTTagIntArray(par1Str, par2ArrayOfInteger)); + } + + /** + * Stores the given NBTTagCompound into the map with the given string key. + */ + public void setCompoundTag(String par1Str, NBTTagCompound par2NBTTagCompound) { + this.tagMap.put(par1Str, par2NBTTagCompound.setName(par1Str)); + } + + /** + * Stores the given boolean value as a NBTTagByte, storing 1 for true and 0 for + * false, using the given string key. + */ + public void setBoolean(String par1Str, boolean par2) { + this.setByte(par1Str, (byte) (par2 ? 1 : 0)); + } + + /** + * gets a generic tag with the specified name + */ + public NBTBase getTag(String par1Str) { + return (NBTBase) this.tagMap.get(par1Str); + } + + /** + * Returns whether the given string has been previously stored as a key in the + * map. + */ + public boolean hasKey(String par1Str) { + return this.tagMap.containsKey(par1Str); + } + + /** + * Retrieves a byte value using the specified key, or 0 if no such key was + * stored. + */ + public byte getByte(String par1Str) { + try { + return !this.tagMap.containsKey(par1Str) ? 0 : ((NBTTagByte) this.tagMap.get(par1Str)).data; + } catch (ClassCastException var3) { + throw new ReportedException(this.createCrashReport(par1Str, 1, var3)); + } + } + + /** + * Retrieves a short value using the specified key, or 0 if no such key was + * stored. + */ + public short getShort(String par1Str) { + try { + return !this.tagMap.containsKey(par1Str) ? 0 : ((NBTTagShort) this.tagMap.get(par1Str)).data; + } catch (ClassCastException var3) { + throw new ReportedException(this.createCrashReport(par1Str, 2, var3)); + } + } + + /** + * Retrieves an integer value using the specified key, or 0 if no such key was + * stored. + */ + public int getInteger(String par1Str) { + try { + return !this.tagMap.containsKey(par1Str) ? 0 : ((NBTTagInt) this.tagMap.get(par1Str)).data; + } catch (ClassCastException var3) { + throw new ReportedException(this.createCrashReport(par1Str, 3, var3)); + } + } + + /** + * Retrieves a long value using the specified key, or 0 if no such key was + * stored. + */ + public long getLong(String par1Str) { + try { + return !this.tagMap.containsKey(par1Str) ? 0L : ((NBTTagLong) this.tagMap.get(par1Str)).data; + } catch (ClassCastException var3) { + throw new ReportedException(this.createCrashReport(par1Str, 4, var3)); + } + } + + /** + * Retrieves a float value using the specified key, or 0 if no such key was + * stored. + */ + public float getFloat(String par1Str) { + try { + return !this.tagMap.containsKey(par1Str) ? 0.0F : ((NBTTagFloat) this.tagMap.get(par1Str)).data; + } catch (ClassCastException var3) { + throw new ReportedException(this.createCrashReport(par1Str, 5, var3)); + } + } + + /** + * Retrieves a double value using the specified key, or 0 if no such key was + * stored. + */ + public double getDouble(String par1Str) { + try { + return !this.tagMap.containsKey(par1Str) ? 0.0D : ((NBTTagDouble) this.tagMap.get(par1Str)).data; + } catch (ClassCastException var3) { + throw new ReportedException(this.createCrashReport(par1Str, 6, var3)); + } + } + + /** + * Retrieves a string value using the specified key, or an empty string if no + * such key was stored. + */ + public String getString(String par1Str) { + try { + return !this.tagMap.containsKey(par1Str) ? "" : ((NBTTagString) this.tagMap.get(par1Str)).data; + } catch (ClassCastException var3) { + throw new ReportedException(this.createCrashReport(par1Str, 8, var3)); + } + } + + /** + * Retrieves a byte array using the specified key, or a zero-length array if no + * such key was stored. + */ + public byte[] getByteArray(String par1Str) { + try { + return !this.tagMap.containsKey(par1Str) ? new byte[0] + : ((NBTTagByteArray) this.tagMap.get(par1Str)).byteArray; + } catch (ClassCastException var3) { + throw new ReportedException(this.createCrashReport(par1Str, 7, var3)); + } + } + + /** + * Retrieves an int array using the specified key, or a zero-length array if no + * such key was stored. + */ + public int[] getIntArray(String par1Str) { + try { + return !this.tagMap.containsKey(par1Str) ? new int[0] + : ((NBTTagIntArray) this.tagMap.get(par1Str)).intArray; + } catch (ClassCastException var3) { + throw new ReportedException(this.createCrashReport(par1Str, 11, var3)); + } + } + + /** + * Retrieves a NBTTagCompound subtag matching the specified key, or a new empty + * NBTTagCompound if no such key was stored. + */ + public NBTTagCompound getCompoundTag(String par1Str) { + try { + return !this.tagMap.containsKey(par1Str) ? new NBTTagCompound(par1Str) + : (NBTTagCompound) this.tagMap.get(par1Str); + } catch (ClassCastException var3) { + throw new ReportedException(this.createCrashReport(par1Str, 10, var3)); + } + } + + /** + * Retrieves a NBTTagList subtag matching the specified key, or a new empty + * NBTTagList if no such key was stored. + */ + public NBTTagList getTagList(String par1Str) { + try { + return !this.tagMap.containsKey(par1Str) ? new NBTTagList(par1Str) : (NBTTagList) this.tagMap.get(par1Str); + } catch (ClassCastException var3) { + throw new ReportedException(this.createCrashReport(par1Str, 9, var3)); + } + } + + /** + * Retrieves a boolean value using the specified key, or false if no such key + * was stored. This uses the getByte method. + */ + public boolean getBoolean(String par1Str) { + return this.getByte(par1Str) != 0; + } + + /** + * Remove the specified tag. + */ + public void removeTag(String par1Str) { + this.tagMap.remove(par1Str); + } + + public String toString() { + String var1 = this.getName() + ":["; + String var3; + + for (Iterator var2 = this.tagMap.keySet().iterator(); var2 + .hasNext(); var1 = var1 + var3 + ":" + this.tagMap.get(var3) + ",") { + var3 = (String) var2.next(); + } + + return var1 + "]"; + } + + /** + * Return whether this compound has no tags. + */ + public boolean hasNoTags() { + return this.tagMap.isEmpty(); + } + + /** + * Create a crash report which indicates a NBT read error. + */ + private CrashReport createCrashReport(String par1Str, int par2, ClassCastException par3ClassCastException) { + CrashReport var4 = CrashReport.makeCrashReport(par3ClassCastException, "Reading NBT data"); + CrashReportCategory var5 = var4.makeCategoryDepth("Corrupt NBT tag", 1); + var5.addCrashSectionCallable("Tag type found", new CallableTagCompound1(this, par1Str)); + var5.addCrashSectionCallable("Tag type expected", new CallableTagCompound2(this, par2)); + var5.addCrashSection("Tag name", par1Str); + + if (this.getName() != null && this.getName().length() > 0) { + var5.addCrashSection("Tag parent", this.getName()); + } + + return var4; + } + + /** + * Creates a clone of the tag. + */ + public NBTBase copy() { + NBTTagCompound var1 = new NBTTagCompound(this.getName()); + Iterator var2 = this.tagMap.keySet().iterator(); + + while (var2.hasNext()) { + String var3 = (String) var2.next(); + var1.setTag(var3, ((NBTBase) this.tagMap.get(var3)).copy()); + } + + return var1; + } + + public boolean equals(Object par1Obj) { + if (super.equals(par1Obj)) { + NBTTagCompound var2 = (NBTTagCompound) par1Obj; + return this.tagMap.entrySet().equals(var2.tagMap.entrySet()); + } else { + return false; + } + } + + public int hashCode() { + return super.hashCode() ^ this.tagMap.hashCode(); + } + + /** + * Return the tag map for this compound. + */ + static Map getTagMap(NBTTagCompound par0NBTTagCompound) { + return par0NBTTagCompound.tagMap; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/NBTTagDouble.java b/sp-server/src/main/java/net/minecraft/src/NBTTagDouble.java new file mode 100644 index 0000000..5d89b64 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/NBTTagDouble.java @@ -0,0 +1,67 @@ +package net.minecraft.src; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; + +public class NBTTagDouble extends NBTBase { + /** The double value for the tag. */ + public double data; + + public NBTTagDouble(String par1Str) { + super(par1Str); + } + + public NBTTagDouble(String par1Str, double par2) { + super(par1Str); + this.data = par2; + } + + /** + * Write the actual data contents of the tag, implemented in NBT extension + * classes + */ + void write(DataOutput par1DataOutput) throws IOException { + par1DataOutput.writeDouble(this.data); + } + + /** + * Read the actual data contents of the tag, implemented in NBT extension + * classes + */ + void load(DataInput par1DataInput) throws IOException { + this.data = par1DataInput.readDouble(); + } + + /** + * Gets the type byte for the tag. + */ + public byte getId() { + return (byte) 6; + } + + public String toString() { + return "" + this.data; + } + + /** + * Creates a clone of the tag. + */ + public NBTBase copy() { + return new NBTTagDouble(this.getName(), this.data); + } + + public boolean equals(Object par1Obj) { + if (super.equals(par1Obj)) { + NBTTagDouble var2 = (NBTTagDouble) par1Obj; + return this.data == var2.data; + } else { + return false; + } + } + + public int hashCode() { + long var1 = Double.doubleToLongBits(this.data); + return super.hashCode() ^ (int) (var1 ^ var1 >>> 32); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/NBTTagEnd.java b/sp-server/src/main/java/net/minecraft/src/NBTTagEnd.java new file mode 100644 index 0000000..9bc8ed2 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/NBTTagEnd.java @@ -0,0 +1,43 @@ +package net.minecraft.src; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; + +public class NBTTagEnd extends NBTBase { + public NBTTagEnd() { + super((String) null); + } + + /** + * Read the actual data contents of the tag, implemented in NBT extension + * classes + */ + void load(DataInput par1DataInput) throws IOException { + } + + /** + * Write the actual data contents of the tag, implemented in NBT extension + * classes + */ + void write(DataOutput par1DataOutput) throws IOException { + } + + /** + * Gets the type byte for the tag. + */ + public byte getId() { + return (byte) 0; + } + + public String toString() { + return "END"; + } + + /** + * Creates a clone of the tag. + */ + public NBTBase copy() { + return new NBTTagEnd(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/NBTTagFloat.java b/sp-server/src/main/java/net/minecraft/src/NBTTagFloat.java new file mode 100644 index 0000000..3e2ef67 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/NBTTagFloat.java @@ -0,0 +1,66 @@ +package net.minecraft.src; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; + +public class NBTTagFloat extends NBTBase { + /** The float value for the tag. */ + public float data; + + public NBTTagFloat(String par1Str) { + super(par1Str); + } + + public NBTTagFloat(String par1Str, float par2) { + super(par1Str); + this.data = par2; + } + + /** + * Write the actual data contents of the tag, implemented in NBT extension + * classes + */ + void write(DataOutput par1DataOutput) throws IOException { + par1DataOutput.writeFloat(this.data); + } + + /** + * Read the actual data contents of the tag, implemented in NBT extension + * classes + */ + void load(DataInput par1DataInput) throws IOException { + this.data = par1DataInput.readFloat(); + } + + /** + * Gets the type byte for the tag. + */ + public byte getId() { + return (byte) 5; + } + + public String toString() { + return "" + this.data; + } + + /** + * Creates a clone of the tag. + */ + public NBTBase copy() { + return new NBTTagFloat(this.getName(), this.data); + } + + public boolean equals(Object par1Obj) { + if (super.equals(par1Obj)) { + NBTTagFloat var2 = (NBTTagFloat) par1Obj; + return this.data == var2.data; + } else { + return false; + } + } + + public int hashCode() { + return super.hashCode() ^ Float.floatToIntBits(this.data); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/NBTTagInt.java b/sp-server/src/main/java/net/minecraft/src/NBTTagInt.java new file mode 100644 index 0000000..4a621dd --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/NBTTagInt.java @@ -0,0 +1,66 @@ +package net.minecraft.src; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; + +public class NBTTagInt extends NBTBase { + /** The integer value for the tag. */ + public int data; + + public NBTTagInt(String par1Str) { + super(par1Str); + } + + public NBTTagInt(String par1Str, int par2) { + super(par1Str); + this.data = par2; + } + + /** + * Write the actual data contents of the tag, implemented in NBT extension + * classes + */ + void write(DataOutput par1DataOutput) throws IOException { + par1DataOutput.writeInt(this.data); + } + + /** + * Read the actual data contents of the tag, implemented in NBT extension + * classes + */ + void load(DataInput par1DataInput) throws IOException { + this.data = par1DataInput.readInt(); + } + + /** + * Gets the type byte for the tag. + */ + public byte getId() { + return (byte) 3; + } + + public String toString() { + return "" + this.data; + } + + /** + * Creates a clone of the tag. + */ + public NBTBase copy() { + return new NBTTagInt(this.getName(), this.data); + } + + public boolean equals(Object par1Obj) { + if (super.equals(par1Obj)) { + NBTTagInt var2 = (NBTTagInt) par1Obj; + return this.data == var2.data; + } else { + return false; + } + } + + public int hashCode() { + return super.hashCode() ^ this.data; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/NBTTagIntArray.java b/sp-server/src/main/java/net/minecraft/src/NBTTagIntArray.java new file mode 100644 index 0000000..e6d3066 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/NBTTagIntArray.java @@ -0,0 +1,79 @@ +package net.minecraft.src; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; +import java.util.Arrays; + +public class NBTTagIntArray extends NBTBase { + /** The array of saved integers */ + public int[] intArray; + + public NBTTagIntArray(String par1Str) { + super(par1Str); + } + + public NBTTagIntArray(String par1Str, int[] par2ArrayOfInteger) { + super(par1Str); + this.intArray = par2ArrayOfInteger; + } + + /** + * Write the actual data contents of the tag, implemented in NBT extension + * classes + */ + void write(DataOutput par1DataOutput) throws IOException { + par1DataOutput.writeInt(this.intArray.length); + + for (int var2 = 0; var2 < this.intArray.length; ++var2) { + par1DataOutput.writeInt(this.intArray[var2]); + } + } + + /** + * Read the actual data contents of the tag, implemented in NBT extension + * classes + */ + void load(DataInput par1DataInput) throws IOException { + int var2 = par1DataInput.readInt(); + this.intArray = new int[var2]; + + for (int var3 = 0; var3 < var2; ++var3) { + this.intArray[var3] = par1DataInput.readInt(); + } + } + + /** + * Gets the type byte for the tag. + */ + public byte getId() { + return (byte) 11; + } + + public String toString() { + return "[" + this.intArray.length + " bytes]"; + } + + /** + * Creates a clone of the tag. + */ + public NBTBase copy() { + int[] var1 = new int[this.intArray.length]; + System.arraycopy(this.intArray, 0, var1, 0, this.intArray.length); + return new NBTTagIntArray(this.getName(), var1); + } + + public boolean equals(Object par1Obj) { + if (!super.equals(par1Obj)) { + return false; + } else { + NBTTagIntArray var2 = (NBTTagIntArray) par1Obj; + return this.intArray == null && var2.intArray == null + || this.intArray != null && Arrays.equals(this.intArray, var2.intArray); + } + } + + public int hashCode() { + return super.hashCode() ^ Arrays.hashCode(this.intArray); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/NBTTagList.java b/sp-server/src/main/java/net/minecraft/src/NBTTagList.java new file mode 100644 index 0000000..356827d --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/NBTTagList.java @@ -0,0 +1,128 @@ +package net.minecraft.src; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +public class NBTTagList extends NBTBase { + /** The array list containing the tags encapsulated in this list. */ + private List tagList = new ArrayList(); + + /** + * The type byte for the tags in the list - they must all be of the same type. + */ + private byte tagType; + + public NBTTagList() { + super(""); + } + + public NBTTagList(String par1Str) { + super(par1Str); + } + + /** + * Write the actual data contents of the tag, implemented in NBT extension + * classes + */ + void write(DataOutput par1DataOutput) throws IOException { + if (!this.tagList.isEmpty()) { + this.tagType = ((NBTBase) this.tagList.get(0)).getId(); + } else { + this.tagType = 1; + } + + par1DataOutput.writeByte(this.tagType); + par1DataOutput.writeInt(this.tagList.size()); + + for (int var2 = 0; var2 < this.tagList.size(); ++var2) { + ((NBTBase) this.tagList.get(var2)).write(par1DataOutput); + } + } + + /** + * Read the actual data contents of the tag, implemented in NBT extension + * classes + */ + void load(DataInput par1DataInput) throws IOException { + this.tagType = par1DataInput.readByte(); + int var2 = par1DataInput.readInt(); + this.tagList = new ArrayList(); + + for (int var3 = 0; var3 < var2; ++var3) { + NBTBase var4 = NBTBase.newTag(this.tagType, (String) null); + var4.load(par1DataInput); + this.tagList.add(var4); + } + } + + /** + * Gets the type byte for the tag. + */ + public byte getId() { + return (byte) 9; + } + + public String toString() { + return "" + this.tagList.size() + " entries of type " + NBTBase.getTagName(this.tagType); + } + + /** + * Adds the provided tag to the end of the list. There is no check to verify + * this tag is of the same type as any previous tag. + */ + public void appendTag(NBTBase par1NBTBase) { + this.tagType = par1NBTBase.getId(); + this.tagList.add(par1NBTBase); + } + + /** + * Retrieves the tag at the specified index from the list. + */ + public NBTBase tagAt(int par1) { + return (NBTBase) this.tagList.get(par1); + } + + /** + * Returns the number of tags in the list. + */ + public int tagCount() { + return this.tagList.size(); + } + + /** + * Creates a clone of the tag. + */ + public NBTBase copy() { + NBTTagList var1 = new NBTTagList(this.getName()); + var1.tagType = this.tagType; + Iterator var2 = this.tagList.iterator(); + + while (var2.hasNext()) { + NBTBase var3 = (NBTBase) var2.next(); + NBTBase var4 = var3.copy(); + var1.tagList.add(var4); + } + + return var1; + } + + public boolean equals(Object par1Obj) { + if (super.equals(par1Obj)) { + NBTTagList var2 = (NBTTagList) par1Obj; + + if (this.tagType == var2.tagType) { + return this.tagList.equals(var2.tagList); + } + } + + return false; + } + + public int hashCode() { + return super.hashCode() ^ this.tagList.hashCode(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/NBTTagLong.java b/sp-server/src/main/java/net/minecraft/src/NBTTagLong.java new file mode 100644 index 0000000..c48b532 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/NBTTagLong.java @@ -0,0 +1,66 @@ +package net.minecraft.src; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; + +public class NBTTagLong extends NBTBase { + /** The long value for the tag. */ + public long data; + + public NBTTagLong(String par1Str) { + super(par1Str); + } + + public NBTTagLong(String par1Str, long par2) { + super(par1Str); + this.data = par2; + } + + /** + * Write the actual data contents of the tag, implemented in NBT extension + * classes + */ + void write(DataOutput par1DataOutput) throws IOException { + par1DataOutput.writeLong(this.data); + } + + /** + * Read the actual data contents of the tag, implemented in NBT extension + * classes + */ + void load(DataInput par1DataInput) throws IOException { + this.data = par1DataInput.readLong(); + } + + /** + * Gets the type byte for the tag. + */ + public byte getId() { + return (byte) 4; + } + + public String toString() { + return "" + this.data; + } + + /** + * Creates a clone of the tag. + */ + public NBTBase copy() { + return new NBTTagLong(this.getName(), this.data); + } + + public boolean equals(Object par1Obj) { + if (super.equals(par1Obj)) { + NBTTagLong var2 = (NBTTagLong) par1Obj; + return this.data == var2.data; + } else { + return false; + } + } + + public int hashCode() { + return super.hashCode() ^ (int) (this.data ^ this.data >>> 32); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/NBTTagShort.java b/sp-server/src/main/java/net/minecraft/src/NBTTagShort.java new file mode 100644 index 0000000..15f328e --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/NBTTagShort.java @@ -0,0 +1,66 @@ +package net.minecraft.src; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; + +public class NBTTagShort extends NBTBase { + /** The short value for the tag. */ + public short data; + + public NBTTagShort(String par1Str) { + super(par1Str); + } + + public NBTTagShort(String par1Str, short par2) { + super(par1Str); + this.data = par2; + } + + /** + * Write the actual data contents of the tag, implemented in NBT extension + * classes + */ + void write(DataOutput par1DataOutput) throws IOException { + par1DataOutput.writeShort(this.data); + } + + /** + * Read the actual data contents of the tag, implemented in NBT extension + * classes + */ + void load(DataInput par1DataInput) throws IOException { + this.data = par1DataInput.readShort(); + } + + /** + * Gets the type byte for the tag. + */ + public byte getId() { + return (byte) 2; + } + + public String toString() { + return "" + this.data; + } + + /** + * Creates a clone of the tag. + */ + public NBTBase copy() { + return new NBTTagShort(this.getName(), this.data); + } + + public boolean equals(Object par1Obj) { + if (super.equals(par1Obj)) { + NBTTagShort var2 = (NBTTagShort) par1Obj; + return this.data == var2.data; + } else { + return false; + } + } + + public int hashCode() { + return super.hashCode() ^ this.data; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/NBTTagString.java b/sp-server/src/main/java/net/minecraft/src/NBTTagString.java new file mode 100644 index 0000000..0d2e214 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/NBTTagString.java @@ -0,0 +1,70 @@ +package net.minecraft.src; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; + +public class NBTTagString extends NBTBase { + /** The string value for the tag (cannot be empty). */ + public String data; + + public NBTTagString(String par1Str) { + super(par1Str); + } + + public NBTTagString(String par1Str, String par2Str) { + super(par1Str); + this.data = par2Str; + + if (par2Str == null) { + throw new IllegalArgumentException("Empty string not allowed"); + } + } + + /** + * Write the actual data contents of the tag, implemented in NBT extension + * classes + */ + void write(DataOutput par1DataOutput) throws IOException { + par1DataOutput.writeUTF(this.data); + } + + /** + * Read the actual data contents of the tag, implemented in NBT extension + * classes + */ + void load(DataInput par1DataInput) throws IOException { + this.data = par1DataInput.readUTF(); + } + + /** + * Gets the type byte for the tag. + */ + public byte getId() { + return (byte) 8; + } + + public String toString() { + return "" + this.data; + } + + /** + * Creates a clone of the tag. + */ + public NBTBase copy() { + return new NBTTagString(this.getName(), this.data); + } + + public boolean equals(Object par1Obj) { + if (!super.equals(par1Obj)) { + return false; + } else { + NBTTagString var2 = (NBTTagString) par1Obj; + return this.data == null && var2.data == null || this.data != null && this.data.equals(var2.data); + } + } + + public int hashCode() { + return super.hashCode() ^ this.data.hashCode(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/NetHandler.java b/sp-server/src/main/java/net/minecraft/src/NetHandler.java new file mode 100644 index 0000000..d14614d --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/NetHandler.java @@ -0,0 +1,400 @@ +package net.minecraft.src; + +public abstract class NetHandler { + /** + * determine if it is a server handler + */ + public abstract boolean isServerHandler(); + + /** + * Handle Packet51MapChunk (full chunk update of blocks, metadata, light levels, + * and optionally biome data) + */ + public void handleMapChunk(Packet51MapChunk par1Packet51MapChunk) { + } + + /** + * Default handler called for packets that don't have their own handlers in + * NetServerHandler; kicks player from the server. + */ + public void unexpectedPacket(Packet par1Packet) { + } + + public void handleErrorMessage(String par1Str, Object[] par2ArrayOfObj) { + } + + public void handleKickDisconnect(Packet255KickDisconnect par1Packet255KickDisconnect) { + this.unexpectedPacket(par1Packet255KickDisconnect); + } + + public void handleLogin(Packet1Login par1Packet1Login) { + this.unexpectedPacket(par1Packet1Login); + } + + public void handleFlying(Packet10Flying par1Packet10Flying) { + this.unexpectedPacket(par1Packet10Flying); + } + + public void handleMultiBlockChange(Packet52MultiBlockChange par1Packet52MultiBlockChange) { + this.unexpectedPacket(par1Packet52MultiBlockChange); + } + + public void handleBlockDig(Packet14BlockDig par1Packet14BlockDig) { + this.unexpectedPacket(par1Packet14BlockDig); + } + + public void handleBlockChange(Packet53BlockChange par1Packet53BlockChange) { + this.unexpectedPacket(par1Packet53BlockChange); + } + + public void handleNamedEntitySpawn(Packet20NamedEntitySpawn par1Packet20NamedEntitySpawn) { + this.unexpectedPacket(par1Packet20NamedEntitySpawn); + } + + public void handleEntity(Packet30Entity par1Packet30Entity) { + this.unexpectedPacket(par1Packet30Entity); + } + + public void handleEntityTeleport(Packet34EntityTeleport par1Packet34EntityTeleport) { + this.unexpectedPacket(par1Packet34EntityTeleport); + } + + public void handlePlace(Packet15Place par1Packet15Place) { + this.unexpectedPacket(par1Packet15Place); + } + + public void handleBlockItemSwitch(Packet16BlockItemSwitch par1Packet16BlockItemSwitch) { + this.unexpectedPacket(par1Packet16BlockItemSwitch); + } + + public void handleDestroyEntity(Packet29DestroyEntity par1Packet29DestroyEntity) { + this.unexpectedPacket(par1Packet29DestroyEntity); + } + + public void handleCollect(Packet22Collect par1Packet22Collect) { + this.unexpectedPacket(par1Packet22Collect); + } + + public void handleChat(Packet3Chat par1Packet3Chat) { + this.unexpectedPacket(par1Packet3Chat); + } + + public void handleVehicleSpawn(Packet23VehicleSpawn par1Packet23VehicleSpawn) { + this.unexpectedPacket(par1Packet23VehicleSpawn); + } + + public void handleAnimation(Packet18Animation par1Packet18Animation) { + this.unexpectedPacket(par1Packet18Animation); + } + + /** + * runs registerPacket on the given Packet19EntityAction + */ + public void handleEntityAction(Packet19EntityAction par1Packet19EntityAction) { + this.unexpectedPacket(par1Packet19EntityAction); + } + + public void handleClientProtocol(Packet2ClientProtocol par1Packet2ClientProtocol) { + this.unexpectedPacket(par1Packet2ClientProtocol); + } + + public void handleServerAuthData(Packet253ServerAuthData par1Packet253ServerAuthData) { + this.unexpectedPacket(par1Packet253ServerAuthData); + } + + public void handleSharedKey(Packet252SharedKey par1Packet252SharedKey) { + this.unexpectedPacket(par1Packet252SharedKey); + } + + public void handleMobSpawn(Packet24MobSpawn par1Packet24MobSpawn) { + this.unexpectedPacket(par1Packet24MobSpawn); + } + + public void handleUpdateTime(Packet4UpdateTime par1Packet4UpdateTime) { + this.unexpectedPacket(par1Packet4UpdateTime); + } + + public void handleSpawnPosition(Packet6SpawnPosition par1Packet6SpawnPosition) { + this.unexpectedPacket(par1Packet6SpawnPosition); + } + + /** + * Packet handler + */ + public void handleEntityVelocity(Packet28EntityVelocity par1Packet28EntityVelocity) { + this.unexpectedPacket(par1Packet28EntityVelocity); + } + + /** + * Packet handler + */ + public void handleEntityMetadata(Packet40EntityMetadata par1Packet40EntityMetadata) { + this.unexpectedPacket(par1Packet40EntityMetadata); + } + + /** + * Packet handler + */ + public void handleAttachEntity(Packet39AttachEntity par1Packet39AttachEntity) { + this.unexpectedPacket(par1Packet39AttachEntity); + } + + public void handleUseEntity(Packet7UseEntity par1Packet7UseEntity) { + this.unexpectedPacket(par1Packet7UseEntity); + } + + /** + * Packet handler + */ + public void handleEntityStatus(Packet38EntityStatus par1Packet38EntityStatus) { + this.unexpectedPacket(par1Packet38EntityStatus); + } + + /** + * Recieves player health from the server and then proceeds to set it locally on + * the client. + */ + public void handleUpdateHealth(Packet8UpdateHealth par1Packet8UpdateHealth) { + this.unexpectedPacket(par1Packet8UpdateHealth); + } + + /** + * respawns the player + */ + public void handleRespawn(Packet9Respawn par1Packet9Respawn) { + this.unexpectedPacket(par1Packet9Respawn); + } + + public void handleExplosion(Packet60Explosion par1Packet60Explosion) { + this.unexpectedPacket(par1Packet60Explosion); + } + + public void handleOpenWindow(Packet100OpenWindow par1Packet100OpenWindow) { + this.unexpectedPacket(par1Packet100OpenWindow); + } + + public void handleCloseWindow(Packet101CloseWindow par1Packet101CloseWindow) { + this.unexpectedPacket(par1Packet101CloseWindow); + } + + public void handleWindowClick(Packet102WindowClick par1Packet102WindowClick) { + this.unexpectedPacket(par1Packet102WindowClick); + } + + public void handleSetSlot(Packet103SetSlot par1Packet103SetSlot) { + this.unexpectedPacket(par1Packet103SetSlot); + } + + public void handleWindowItems(Packet104WindowItems par1Packet104WindowItems) { + this.unexpectedPacket(par1Packet104WindowItems); + } + + /** + * Updates Client side signs + */ + public void handleUpdateSign(Packet130UpdateSign par1Packet130UpdateSign) { + this.unexpectedPacket(par1Packet130UpdateSign); + } + + public void handleUpdateProgressbar(Packet105UpdateProgressbar par1Packet105UpdateProgressbar) { + this.unexpectedPacket(par1Packet105UpdateProgressbar); + } + + public void handlePlayerInventory(Packet5PlayerInventory par1Packet5PlayerInventory) { + this.unexpectedPacket(par1Packet5PlayerInventory); + } + + public void handleTransaction(Packet106Transaction par1Packet106Transaction) { + this.unexpectedPacket(par1Packet106Transaction); + } + + /** + * Packet handler + */ + public void handleEntityPainting(Packet25EntityPainting par1Packet25EntityPainting) { + this.unexpectedPacket(par1Packet25EntityPainting); + } + + public void handleBlockEvent(Packet54PlayNoteBlock par1Packet54PlayNoteBlock) { + this.unexpectedPacket(par1Packet54PlayNoteBlock); + } + + /** + * runs registerPacket on the given Packet200Statistic + */ + public void handleStatistic(Packet200Statistic par1Packet200Statistic) { + this.unexpectedPacket(par1Packet200Statistic); + } + + public void handleSleep(Packet17Sleep par1Packet17Sleep) { + this.unexpectedPacket(par1Packet17Sleep); + } + + public void handleGameEvent(Packet70GameEvent par1Packet70GameEvent) { + this.unexpectedPacket(par1Packet70GameEvent); + } + + /** + * Handles weather packet + */ + public void handleWeather(Packet71Weather par1Packet71Weather) { + this.unexpectedPacket(par1Packet71Weather); + } + + /** + * Contains logic for handling packets containing arbitrary unique item data. + * Currently this is only for maps. + */ + public void handleMapData(Packet131MapData par1Packet131MapData) { + this.unexpectedPacket(par1Packet131MapData); + } + + public void handleDoorChange(Packet61DoorChange par1Packet61DoorChange) { + this.unexpectedPacket(par1Packet61DoorChange); + } + + /** + * Handle a server ping packet. + */ + public void handleServerPing(Packet254ServerPing par1Packet254ServerPing) { + this.unexpectedPacket(par1Packet254ServerPing); + } + + /** + * Handle an entity effect packet. + */ + public void handleEntityEffect(Packet41EntityEffect par1Packet41EntityEffect) { + this.unexpectedPacket(par1Packet41EntityEffect); + } + + /** + * Handle a remove entity effect packet. + */ + public void handleRemoveEntityEffect(Packet42RemoveEntityEffect par1Packet42RemoveEntityEffect) { + this.unexpectedPacket(par1Packet42RemoveEntityEffect); + } + + /** + * Handle a player information packet. + */ + public void handlePlayerInfo(Packet201PlayerInfo par1Packet201PlayerInfo) { + this.unexpectedPacket(par1Packet201PlayerInfo); + } + + /** + * Handle a keep alive packet. + */ + public void handleKeepAlive(Packet0KeepAlive par1Packet0KeepAlive) { + this.unexpectedPacket(par1Packet0KeepAlive); + } + + /** + * Handle an experience packet. + */ + public void handleExperience(Packet43Experience par1Packet43Experience) { + this.unexpectedPacket(par1Packet43Experience); + } + + /** + * Handle a creative slot packet. + */ + public void handleCreativeSetSlot(Packet107CreativeSetSlot par1Packet107CreativeSetSlot) { + this.unexpectedPacket(par1Packet107CreativeSetSlot); + } + + /** + * Handle a entity experience orb packet. + */ + public void handleEntityExpOrb(Packet26EntityExpOrb par1Packet26EntityExpOrb) { + this.unexpectedPacket(par1Packet26EntityExpOrb); + } + + public void handleEnchantItem(Packet108EnchantItem par1Packet108EnchantItem) { + } + + public void handleCustomPayload(Packet250CustomPayload par1Packet250CustomPayload) { + } + + public void handleEntityHeadRotation(Packet35EntityHeadRotation par1Packet35EntityHeadRotation) { + this.unexpectedPacket(par1Packet35EntityHeadRotation); + } + + public void handleTileEntityData(Packet132TileEntityData par1Packet132TileEntityData) { + this.unexpectedPacket(par1Packet132TileEntityData); + } + + /** + * Handle a player abilities packet. + */ + public void handlePlayerAbilities(Packet202PlayerAbilities par1Packet202PlayerAbilities) { + this.unexpectedPacket(par1Packet202PlayerAbilities); + } + + public void handleAutoComplete(Packet203AutoComplete par1Packet203AutoComplete) { + this.unexpectedPacket(par1Packet203AutoComplete); + } + + public void handleClientInfo(Packet204ClientInfo par1Packet204ClientInfo) { + this.unexpectedPacket(par1Packet204ClientInfo); + } + + public void handleLevelSound(Packet62LevelSound par1Packet62LevelSound) { + this.unexpectedPacket(par1Packet62LevelSound); + } + + public void handleBlockDestroy(Packet55BlockDestroy par1Packet55BlockDestroy) { + this.unexpectedPacket(par1Packet55BlockDestroy); + } + + public void handleClientCommand(Packet205ClientCommand par1Packet205ClientCommand) { + } + + public void handleMapChunks(Packet56MapChunks par1Packet56MapChunks) { + this.unexpectedPacket(par1Packet56MapChunks); + } + + /** + * If this returns false, all packets will be queued for the main thread to + * handle, even if they would otherwise be processed asynchronously. Used to + * avoid processing packets on the client before the world has been downloaded + * (which happens on the main thread) + */ + public boolean canProcessPacketsAsync() { + return false; + } + + /** + * Handle a set objective packet. + */ + public void handleSetObjective(Packet206SetObjective par1Packet206SetObjective) { + this.unexpectedPacket(par1Packet206SetObjective); + } + + /** + * Handle a set score packet. + */ + public void handleSetScore(Packet207SetScore par1Packet207SetScore) { + this.unexpectedPacket(par1Packet207SetScore); + } + + /** + * Handle a set display objective packet. + */ + public void handleSetDisplayObjective(Packet208SetDisplayObjective par1Packet208SetDisplayObjective) { + this.unexpectedPacket(par1Packet208SetDisplayObjective); + } + + /** + * Handle a set player team packet. + */ + public void handleSetPlayerTeam(Packet209SetPlayerTeam par1Packet209SetPlayerTeam) { + this.unexpectedPacket(par1Packet209SetPlayerTeam); + } + + /** + * Handle a world particles packet. + */ + public void handleWorldParticles(Packet63WorldParticles par1Packet63WorldParticles) { + this.unexpectedPacket(par1Packet63WorldParticles); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/NetLoginHandler.java b/sp-server/src/main/java/net/minecraft/src/NetLoginHandler.java new file mode 100644 index 0000000..bff1002 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/NetLoginHandler.java @@ -0,0 +1,263 @@ +package net.minecraft.src; + +import java.io.IOException; +import java.io.Serializable; +import java.net.InetAddress; +import java.net.Socket; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; +import java.util.Random; +import javax.crypto.SecretKey; +import net.minecraft.server.MinecraftServer; + +public class NetLoginHandler extends NetHandler { + /** The Random object used to generate serverId hex strings. */ + private static Random rand = new Random(); + + /** The 4 byte verify token read from a Packet252SharedKey */ + private byte[] verifyToken; + + /** Reference to the MinecraftServer object. */ + private final MinecraftServer mcServer; + public final TcpConnection myTCPConnection; + + /** + * Returns if the login handler is finished and can be removed. It is set to + * true on either error or successful login. + */ + public boolean finishedProcessing = false; + + /** While waiting to login, if this field ++'s to 600 it will kick you. */ + private int loginTimer = 0; + private String clientUsername = null; + private volatile boolean field_72544_i = false; + + /** server ID that is randomly generated by this login handler. */ + private String loginServerId = ""; + private boolean field_92079_k = false; + + /** Secret AES key obtained from the client's Packet252SharedKey */ + private SecretKey sharedKey = null; + + public NetLoginHandler(MinecraftServer par1MinecraftServer, Socket par2Socket, String par3Str) throws IOException { + this.mcServer = par1MinecraftServer; + this.myTCPConnection = new TcpConnection(par1MinecraftServer.getLogAgent(), par2Socket, par3Str, this, + par1MinecraftServer.getKeyPair().getPrivate()); + this.myTCPConnection.field_74468_e = 0; + } + + /** + * Logs the user in if a login packet is found, otherwise keeps processing + * network packets unless the timeout has occurred. + */ + public void tryLogin() { + if (this.field_72544_i) { + this.initializePlayerConnection(); + } + + if (this.loginTimer++ == 600) { + this.kickUser("Took too long to log in"); + } else { + this.myTCPConnection.processReadPackets(); + } + } + + /** + * Disconnects the user with the given reason. + */ + public void kickUser(String par1Str) { + try { + this.mcServer.getLogAgent().func_98233_a("Disconnecting " + this.getUsernameAndAddress() + ": " + par1Str); + this.myTCPConnection.addToSendQueue(new Packet255KickDisconnect(par1Str)); + this.myTCPConnection.serverShutdown(); + this.finishedProcessing = true; + } catch (Exception var3) { + var3.printStackTrace(); + } + } + + public void handleClientProtocol(Packet2ClientProtocol par1Packet2ClientProtocol) { + this.clientUsername = par1Packet2ClientProtocol.getUsername(); + + if (!this.clientUsername.equals(StringUtils.stripControlCodes(this.clientUsername))) { + this.kickUser("Invalid username!"); + } else { + PublicKey var2 = this.mcServer.getKeyPair().getPublic(); + + if (par1Packet2ClientProtocol.getProtocolVersion() != 61) { + if (par1Packet2ClientProtocol.getProtocolVersion() > 61) { + this.kickUser("Outdated server!"); + } else { + this.kickUser("Outdated client!"); + } + } else { + this.loginServerId = this.mcServer.isServerInOnlineMode() ? Long.toString(rand.nextLong(), 16) : "-"; + this.verifyToken = new byte[4]; + rand.nextBytes(this.verifyToken); + this.myTCPConnection + .addToSendQueue(new Packet253ServerAuthData(this.loginServerId, var2, this.verifyToken)); + } + } + } + + public void handleSharedKey(Packet252SharedKey par1Packet252SharedKey) { + PrivateKey var2 = this.mcServer.getKeyPair().getPrivate(); + this.sharedKey = par1Packet252SharedKey.getSharedKey(var2); + + if (!Arrays.equals(this.verifyToken, par1Packet252SharedKey.getVerifyToken(var2))) { + this.kickUser("Invalid client reply"); + } + + this.myTCPConnection.addToSendQueue(new Packet252SharedKey()); + } + + public void handleClientCommand(Packet205ClientCommand par1Packet205ClientCommand) { + if (par1Packet205ClientCommand.forceRespawn == 0) { + if (this.field_92079_k) { + this.kickUser("Duplicate login"); + return; + } + + this.field_92079_k = true; + + if (this.mcServer.isServerInOnlineMode()) { + (new ThreadLoginVerifier(this)).start(); + } else { + this.field_72544_i = true; + } + } + } + + public void handleLogin(Packet1Login par1Packet1Login) { + } + + /** + * on success the specified username is connected to the minecraftInstance, + * otherwise they are packet255'd + */ + public void initializePlayerConnection() { + String var1 = this.mcServer.getConfigurationManager() + .allowUserToConnect(this.myTCPConnection.getRemoteAddress(), this.clientUsername); + + if (var1 != null) { + this.kickUser(var1); + } else { + EntityPlayerMP var2 = this.mcServer.getConfigurationManager().createPlayerForUser(this.clientUsername); + + if (var2 != null) { + this.mcServer.getConfigurationManager().initializeConnectionToPlayer(this.myTCPConnection, var2); + } + } + + this.finishedProcessing = true; + } + + public void handleErrorMessage(String par1Str, Object[] par2ArrayOfObj) { + this.mcServer.getLogAgent().func_98233_a(this.getUsernameAndAddress() + " lost connection"); + this.finishedProcessing = true; + } + + /** + * Handle a server ping packet. + */ + public void handleServerPing(Packet254ServerPing par1Packet254ServerPing) { + try { + ServerConfigurationManager var2 = this.mcServer.getConfigurationManager(); + String var3 = null; + + if (par1Packet254ServerPing.readSuccessfully == 1) { + List var4 = Arrays.asList(new Serializable[] { Integer.valueOf(1), Integer.valueOf(61), + this.mcServer.getMinecraftVersion(), this.mcServer.getMOTD(), + Integer.valueOf(var2.getCurrentPlayerCount()), Integer.valueOf(var2.getMaxPlayers()) }); + Object var6; + + for (Iterator var5 = var4.iterator(); var5 + .hasNext(); var3 = var3 + var6.toString().replaceAll("\u0000", "")) { + var6 = var5.next(); + + if (var3 == null) { + var3 = "\u00a7"; + } else { + var3 = var3 + "\u0000"; + } + } + } else { + var3 = this.mcServer.getMOTD() + "\u00a7" + var2.getCurrentPlayerCount() + "\u00a7" + + var2.getMaxPlayers(); + } + + InetAddress var8 = null; + + if (this.myTCPConnection.getSocket() != null) { + var8 = this.myTCPConnection.getSocket().getInetAddress(); + } + + this.myTCPConnection.addToSendQueue(new Packet255KickDisconnect(var3)); + this.myTCPConnection.serverShutdown(); + + if (var8 != null && this.mcServer.getNetworkThread() instanceof DedicatedServerListenThread) { + ((DedicatedServerListenThread) this.mcServer.getNetworkThread()).func_71761_a(var8); + } + + this.finishedProcessing = true; + } catch (Exception var7) { + var7.printStackTrace(); + } + } + + /** + * Default handler called for packets that don't have their own handlers in + * NetServerHandler; kicks player from the server. + */ + public void unexpectedPacket(Packet par1Packet) { + this.kickUser("Protocol error"); + } + + public String getUsernameAndAddress() { + return this.clientUsername != null + ? this.clientUsername + " [" + this.myTCPConnection.getRemoteAddress().toString() + "]" + : this.myTCPConnection.getRemoteAddress().toString(); + } + + /** + * determine if it is a server handler + */ + public boolean isServerHandler() { + return true; + } + + /** + * Returns the server Id randomly generated by this login handler. + */ + static String getServerId(NetLoginHandler par0NetLoginHandler) { + return par0NetLoginHandler.loginServerId; + } + + /** + * Returns the reference to Minecraft Server. + */ + static MinecraftServer getLoginMinecraftServer(NetLoginHandler par0NetLoginHandler) { + return par0NetLoginHandler.mcServer; + } + + /** + * Return the secret AES sharedKey + */ + static SecretKey getSharedKey(NetLoginHandler par0NetLoginHandler) { + return par0NetLoginHandler.sharedKey; + } + + /** + * Returns the connecting client username. + */ + static String getClientUsername(NetLoginHandler par0NetLoginHandler) { + return par0NetLoginHandler.clientUsername; + } + + static boolean func_72531_a(NetLoginHandler par0NetLoginHandler, boolean par1) { + return par0NetLoginHandler.field_72544_i = par1; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/NetServerHandler.java b/sp-server/src/main/java/net/minecraft/src/NetServerHandler.java new file mode 100644 index 0000000..1c2d643 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/NetServerHandler.java @@ -0,0 +1,1007 @@ +package net.minecraft.src; + +import java.io.ByteArrayInputStream; +import java.io.DataInputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.Random; +import net.minecraft.server.MinecraftServer; + +public class NetServerHandler extends NetHandler { + /** The underlying network manager for this server handler. */ + public final INetworkManager netManager; + + /** Reference to the MinecraftServer object. */ + private final MinecraftServer mcServer; + + /** This is set to true whenever a player disconnects from the server. */ + public boolean connectionClosed = false; + + /** Reference to the EntityPlayerMP object. */ + public EntityPlayerMP playerEntity; + + /** incremented each tick */ + private int currentTicks; + + /** holds the amount of tick the player is floating */ + private int playerInAirTime; + private boolean field_72584_h; + private int keepAliveRandomID; + private long keepAliveTimeSent; + + /** The Java Random object. */ + private static Random rndmObj = new Random(); + private long ticksOfLastKeepAlive; + private int chatSpamThresholdCount = 0; + private int creativeItemCreationSpamThresholdTally = 0; + + /** The last known x position for this connection. */ + private double lastPosX; + + /** The last known y position for this connection. */ + private double lastPosY; + + /** The last known z position for this connection. */ + private double lastPosZ; + + /** is true when the player has moved since his last movement packet */ + private boolean hasMoved = true; + private IntHashMap field_72586_s = new IntHashMap(); + + public NetServerHandler(MinecraftServer par1, INetworkManager par2, EntityPlayerMP par3) { + this.mcServer = par1; + this.netManager = par2; + par2.setNetHandler(this); + this.playerEntity = par3; + par3.playerNetServerHandler = this; + } + + /** + * handle all the packets for the connection + */ + public void handlePackets() { + this.field_72584_h = false; + ++this.currentTicks; + this.mcServer.theProfiler.startSection("packetflow"); + this.netManager.processReadPackets(); + this.mcServer.theProfiler.endStartSection("keepAlive"); + + if ((long) this.currentTicks - this.ticksOfLastKeepAlive > 20L) { + this.ticksOfLastKeepAlive = (long) this.currentTicks; + this.keepAliveTimeSent = System.nanoTime() / 1000000L; + this.keepAliveRandomID = rndmObj.nextInt(); + this.sendPacket(new Packet0KeepAlive(this.keepAliveRandomID)); + } + + if (this.chatSpamThresholdCount > 0) { + --this.chatSpamThresholdCount; + } + + if (this.creativeItemCreationSpamThresholdTally > 0) { + --this.creativeItemCreationSpamThresholdTally; + } + + this.mcServer.theProfiler.endStartSection("playerTick"); + this.mcServer.theProfiler.endSection(); + } + + /** + * Kick the offending player and give a reason why + */ + public void kickPlayer(String par1Str) { + if (!this.connectionClosed) { + this.playerEntity.mountEntityAndWakeUp(); + this.sendPacket(new Packet255KickDisconnect(par1Str)); + this.netManager.serverShutdown(); + this.mcServer.getConfigurationManager().sendPacketToAllPlayers( + new Packet3Chat(EnumChatFormatting.YELLOW + this.playerEntity.username + " left the game.")); + this.mcServer.getConfigurationManager().playerLoggedOut(this.playerEntity); + this.connectionClosed = true; + } + } + + public void handleFlying(Packet10Flying par1Packet10Flying) { + WorldServer var2 = this.mcServer.worldServerForDimension(this.playerEntity.dimension); + this.field_72584_h = true; + + if (!this.playerEntity.playerConqueredTheEnd) { + double var3; + + if (!this.hasMoved) { + var3 = par1Packet10Flying.yPosition - this.lastPosY; + + if (par1Packet10Flying.xPosition == this.lastPosX && var3 * var3 < 0.01D + && par1Packet10Flying.zPosition == this.lastPosZ) { + this.hasMoved = true; + } + } + + if (this.hasMoved) { + double var5; + double var7; + double var9; + double var13; + + if (this.playerEntity.ridingEntity != null) { + float var34 = this.playerEntity.rotationYaw; + float var4 = this.playerEntity.rotationPitch; + this.playerEntity.ridingEntity.updateRiderPosition(); + var5 = this.playerEntity.posX; + var7 = this.playerEntity.posY; + var9 = this.playerEntity.posZ; + double var35 = 0.0D; + var13 = 0.0D; + + if (par1Packet10Flying.rotating) { + var34 = par1Packet10Flying.yaw; + var4 = par1Packet10Flying.pitch; + } + + if (par1Packet10Flying.moving && par1Packet10Flying.yPosition == -999.0D + && par1Packet10Flying.stance == -999.0D) { + if (Math.abs(par1Packet10Flying.xPosition) > 1.0D + || Math.abs(par1Packet10Flying.zPosition) > 1.0D) { + System.err.println(this.playerEntity.username + + " was caught trying to crash the server with an invalid position."); + this.kickPlayer("Nope!"); + return; + } + + var35 = par1Packet10Flying.xPosition; + var13 = par1Packet10Flying.zPosition; + } + + this.playerEntity.onGround = par1Packet10Flying.onGround; + this.playerEntity.onUpdateEntity(); + this.playerEntity.moveEntity(var35, 0.0D, var13); + this.playerEntity.setPositionAndRotation(var5, var7, var9, var34, var4); + this.playerEntity.motionX = var35; + this.playerEntity.motionZ = var13; + + if (this.playerEntity.ridingEntity != null) { + var2.uncheckedUpdateEntity(this.playerEntity.ridingEntity, true); + } + + if (this.playerEntity.ridingEntity != null) { + this.playerEntity.ridingEntity.updateRiderPosition(); + } + + this.mcServer.getConfigurationManager().serverUpdateMountedMovingPlayer(this.playerEntity); + this.lastPosX = this.playerEntity.posX; + this.lastPosY = this.playerEntity.posY; + this.lastPosZ = this.playerEntity.posZ; + var2.updateEntity(this.playerEntity); + return; + } + + if (this.playerEntity.isPlayerSleeping()) { + this.playerEntity.onUpdateEntity(); + this.playerEntity.setPositionAndRotation(this.lastPosX, this.lastPosY, this.lastPosZ, + this.playerEntity.rotationYaw, this.playerEntity.rotationPitch); + var2.updateEntity(this.playerEntity); + return; + } + + var3 = this.playerEntity.posY; + this.lastPosX = this.playerEntity.posX; + this.lastPosY = this.playerEntity.posY; + this.lastPosZ = this.playerEntity.posZ; + var5 = this.playerEntity.posX; + var7 = this.playerEntity.posY; + var9 = this.playerEntity.posZ; + float var11 = this.playerEntity.rotationYaw; + float var12 = this.playerEntity.rotationPitch; + + if (par1Packet10Flying.moving && par1Packet10Flying.yPosition == -999.0D + && par1Packet10Flying.stance == -999.0D) { + par1Packet10Flying.moving = false; + } + + if (par1Packet10Flying.moving) { + var5 = par1Packet10Flying.xPosition; + var7 = par1Packet10Flying.yPosition; + var9 = par1Packet10Flying.zPosition; + var13 = par1Packet10Flying.stance - par1Packet10Flying.yPosition; + + if (!this.playerEntity.isPlayerSleeping() && (var13 > 1.65D || var13 < 0.1D)) { + this.kickPlayer("Illegal stance"); + this.mcServer.getLogAgent() + .func_98236_b(this.playerEntity.username + " had an illegal stance: " + var13); + return; + } + + if (Math.abs(par1Packet10Flying.xPosition) > 3.2E7D + || Math.abs(par1Packet10Flying.zPosition) > 3.2E7D) { + this.kickPlayer("Illegal position"); + return; + } + } + + if (par1Packet10Flying.rotating) { + var11 = par1Packet10Flying.yaw; + var12 = par1Packet10Flying.pitch; + } + + this.playerEntity.onUpdateEntity(); + this.playerEntity.ySize = 0.0F; + this.playerEntity.setPositionAndRotation(this.lastPosX, this.lastPosY, this.lastPosZ, var11, var12); + + if (!this.hasMoved) { + return; + } + + var13 = var5 - this.playerEntity.posX; + double var15 = var7 - this.playerEntity.posY; + double var17 = var9 - this.playerEntity.posZ; + double var19 = Math.min(Math.abs(var13), Math.abs(this.playerEntity.motionX)); + double var21 = Math.min(Math.abs(var15), Math.abs(this.playerEntity.motionY)); + double var23 = Math.min(Math.abs(var17), Math.abs(this.playerEntity.motionZ)); + double var25 = var19 * var19 + var21 * var21 + var23 * var23; + + if (var25 > 100.0D && (!this.mcServer.isSinglePlayer() + || !this.mcServer.getServerOwner().equals(this.playerEntity.username))) { + this.mcServer.getLogAgent().func_98236_b(this.playerEntity.username + " moved too quickly! " + var13 + + "," + var15 + "," + var17 + " (" + var19 + ", " + var21 + ", " + var23 + ")"); + this.setPlayerLocation(this.lastPosX, this.lastPosY, this.lastPosZ, this.playerEntity.rotationYaw, + this.playerEntity.rotationPitch); + return; + } + + float var27 = 0.0625F; + boolean var28 = var2.getCollidingBoundingBoxes(this.playerEntity, + this.playerEntity.boundingBox.copy().contract((double) var27, (double) var27, (double) var27)) + .isEmpty(); + + if (this.playerEntity.onGround && !par1Packet10Flying.onGround && var15 > 0.0D) { + this.playerEntity.addExhaustion(0.2F); + } + + this.playerEntity.moveEntity(var13, var15, var17); + this.playerEntity.onGround = par1Packet10Flying.onGround; + this.playerEntity.addMovementStat(var13, var15, var17); + double var29 = var15; + var13 = var5 - this.playerEntity.posX; + var15 = var7 - this.playerEntity.posY; + + if (var15 > -0.5D || var15 < 0.5D) { + var15 = 0.0D; + } + + var17 = var9 - this.playerEntity.posZ; + var25 = var13 * var13 + var15 * var15 + var17 * var17; + boolean var31 = false; + + if (var25 > 0.0625D && !this.playerEntity.isPlayerSleeping() + && !this.playerEntity.theItemInWorldManager.isCreative()) { + var31 = true; + this.mcServer.getLogAgent().func_98236_b(this.playerEntity.username + " moved wrongly!"); + } + + this.playerEntity.setPositionAndRotation(var5, var7, var9, var11, var12); + boolean var32 = var2.getCollidingBoundingBoxes(this.playerEntity, + this.playerEntity.boundingBox.copy().contract((double) var27, (double) var27, (double) var27)) + .isEmpty(); + + if (var28 && (var31 || !var32) && !this.playerEntity.isPlayerSleeping()) { + this.setPlayerLocation(this.lastPosX, this.lastPosY, this.lastPosZ, var11, var12); + return; + } + + AxisAlignedBB var33 = this.playerEntity.boundingBox.copy() + .expand((double) var27, (double) var27, (double) var27).addCoord(0.0D, -0.55D, 0.0D); + + if (!this.mcServer.isFlightAllowed() && !this.playerEntity.theItemInWorldManager.isCreative() + && !var2.checkBlockCollision(var33)) { + if (var29 >= -0.03125D) { + ++this.playerInAirTime; + + if (this.playerInAirTime > 80) { + this.mcServer.getLogAgent() + .func_98236_b(this.playerEntity.username + " was kicked for floating too long!"); + this.kickPlayer("Flying is not enabled on this server"); + return; + } + } + } else { + this.playerInAirTime = 0; + } + + this.playerEntity.onGround = par1Packet10Flying.onGround; + this.mcServer.getConfigurationManager().serverUpdateMountedMovingPlayer(this.playerEntity); + this.playerEntity.handleFalling(this.playerEntity.posY - var3, par1Packet10Flying.onGround); + } + } + } + + /** + * Moves the player to the specified destination and rotation + */ + public void setPlayerLocation(double par1, double par3, double par5, float par7, float par8) { + this.hasMoved = false; + this.lastPosX = par1; + this.lastPosY = par3; + this.lastPosZ = par5; + this.playerEntity.setPositionAndRotation(par1, par3, par5, par7, par8); + this.playerEntity.playerNetServerHandler.sendPacket( + new Packet13PlayerLookMove(par1, par3 + 1.6200000047683716D, par3, par5, par7, par8, false)); + } + + public void handleBlockDig(Packet14BlockDig par1Packet14BlockDig) { + WorldServer var2 = this.mcServer.worldServerForDimension(this.playerEntity.dimension); + + if (par1Packet14BlockDig.status == 4) { + this.playerEntity.dropOneItem(false); + } else if (par1Packet14BlockDig.status == 3) { + this.playerEntity.dropOneItem(true); + } else if (par1Packet14BlockDig.status == 5) { + this.playerEntity.stopUsingItem(); + } else { + boolean var3 = false; + + if (par1Packet14BlockDig.status == 0) { + var3 = true; + } + + if (par1Packet14BlockDig.status == 1) { + var3 = true; + } + + if (par1Packet14BlockDig.status == 2) { + var3 = true; + } + + int var4 = par1Packet14BlockDig.xPosition; + int var5 = par1Packet14BlockDig.yPosition; + int var6 = par1Packet14BlockDig.zPosition; + + if (var3) { + double var7 = this.playerEntity.posX - ((double) var4 + 0.5D); + double var9 = this.playerEntity.posY - ((double) var5 + 0.5D) + 1.5D; + double var11 = this.playerEntity.posZ - ((double) var6 + 0.5D); + double var13 = var7 * var7 + var9 * var9 + var11 * var11; + + if (var13 > 36.0D) { + return; + } + + if (var5 >= this.mcServer.getBuildLimit()) { + return; + } + } + + if (par1Packet14BlockDig.status == 0) { + if (!this.mcServer.func_96290_a(var2, var4, var5, var6, this.playerEntity)) { + this.playerEntity.theItemInWorldManager.onBlockClicked(var4, var5, var6, par1Packet14BlockDig.face); + } else { + this.playerEntity.playerNetServerHandler + .sendPacket(new Packet53BlockChange(var4, var5, var6, var2)); + } + } else if (par1Packet14BlockDig.status == 2) { + this.playerEntity.theItemInWorldManager.blockRemoving(var4, var5, var6); + + if (var2.getBlockId(var4, var5, var6) != 0) { + this.playerEntity.playerNetServerHandler + .sendPacket(new Packet53BlockChange(var4, var5, var6, var2)); + } + } else if (par1Packet14BlockDig.status == 1) { + this.playerEntity.theItemInWorldManager.cancelDestroyingBlock(var4, var5, var6); + + if (var2.getBlockId(var4, var5, var6) != 0) { + this.playerEntity.playerNetServerHandler + .sendPacket(new Packet53BlockChange(var4, var5, var6, var2)); + } + } + } + } + + public void handlePlace(Packet15Place par1Packet15Place) { + WorldServer var2 = this.mcServer.worldServerForDimension(this.playerEntity.dimension); + ItemStack var3 = this.playerEntity.inventory.getCurrentItem(); + boolean var4 = false; + int var5 = par1Packet15Place.getXPosition(); + int var6 = par1Packet15Place.getYPosition(); + int var7 = par1Packet15Place.getZPosition(); + int var8 = par1Packet15Place.getDirection(); + + if (par1Packet15Place.getDirection() == 255) { + if (var3 == null) { + return; + } + + this.playerEntity.theItemInWorldManager.tryUseItem(this.playerEntity, var2, var3); + } else if (par1Packet15Place.getYPosition() >= this.mcServer.getBuildLimit() - 1 + && (par1Packet15Place.getDirection() == 1 + || par1Packet15Place.getYPosition() >= this.mcServer.getBuildLimit())) { + this.playerEntity.playerNetServerHandler.sendPacket(new Packet3Chat( + "" + EnumChatFormatting.GRAY + "Height limit for building is " + this.mcServer.getBuildLimit())); + var4 = true; + } else { + if (this.hasMoved + && this.playerEntity.getDistanceSq((double) var5 + 0.5D, (double) var6 + 0.5D, + (double) var7 + 0.5D) < 64.0D + && !this.mcServer.func_96290_a(var2, var5, var6, var7, this.playerEntity)) { + this.playerEntity.theItemInWorldManager.activateBlockOrUseItem(this.playerEntity, var2, var3, var5, + var6, var7, var8, par1Packet15Place.getXOffset(), par1Packet15Place.getYOffset(), + par1Packet15Place.getZOffset()); + } + + var4 = true; + } + + if (var4) { + this.playerEntity.playerNetServerHandler.sendPacket(new Packet53BlockChange(var5, var6, var7, var2)); + + if (var8 == 0) { + --var6; + } + + if (var8 == 1) { + ++var6; + } + + if (var8 == 2) { + --var7; + } + + if (var8 == 3) { + ++var7; + } + + if (var8 == 4) { + --var5; + } + + if (var8 == 5) { + ++var5; + } + + this.playerEntity.playerNetServerHandler.sendPacket(new Packet53BlockChange(var5, var6, var7, var2)); + } + + var3 = this.playerEntity.inventory.getCurrentItem(); + + if (var3 != null && var3.stackSize == 0) { + this.playerEntity.inventory.mainInventory[this.playerEntity.inventory.currentItem] = null; + var3 = null; + } + + if (var3 == null || var3.getMaxItemUseDuration() == 0) { + this.playerEntity.isChangingQuantityOnly = true; + this.playerEntity.inventory.mainInventory[this.playerEntity.inventory.currentItem] = ItemStack + .copyItemStack(this.playerEntity.inventory.mainInventory[this.playerEntity.inventory.currentItem]); + Slot var9 = this.playerEntity.openContainer.getSlotFromInventory(this.playerEntity.inventory, + this.playerEntity.inventory.currentItem); + this.playerEntity.openContainer.detectAndSendChanges(); + this.playerEntity.isChangingQuantityOnly = false; + + if (!ItemStack.areItemStacksEqual(this.playerEntity.inventory.getCurrentItem(), + par1Packet15Place.getItemStack())) { + this.sendPacket(new Packet103SetSlot(this.playerEntity.openContainer.windowId, var9.slotNumber, + this.playerEntity.inventory.getCurrentItem())); + } + } + } + + public void handleErrorMessage(String par1Str, Object[] par2ArrayOfObj) { + this.mcServer.getLogAgent().func_98233_a(this.playerEntity.username + " lost connection: " + par1Str); + this.mcServer.getConfigurationManager().sendPacketToAllPlayers(new Packet3Chat( + EnumChatFormatting.YELLOW + this.playerEntity.getTranslatedEntityName() + " left the game.")); + this.mcServer.getConfigurationManager().playerLoggedOut(this.playerEntity); + this.connectionClosed = true; + + if (this.mcServer.isSinglePlayer() && this.playerEntity.username.equals(this.mcServer.getServerOwner())) { + this.mcServer.getLogAgent().func_98233_a("Stopping singleplayer server as player logged out"); + this.mcServer.initiateShutdown(); + } + } + + /** + * Default handler called for packets that don't have their own handlers in + * NetServerHandler; kicks player from the server. + */ + public void unexpectedPacket(Packet par1Packet) { + this.mcServer.getLogAgent() + .func_98236_b(this.getClass() + " wasn\'t prepared to deal with a " + par1Packet.getClass()); + this.kickPlayer("Protocol error, unexpected packet"); + } + + /** + * Adds the packet to the underlying network manager's send queue. + */ + public void sendPacket(Packet par1Packet) { + if (par1Packet instanceof Packet3Chat) { + Packet3Chat var2 = (Packet3Chat) par1Packet; + int var3 = this.playerEntity.getChatVisibility(); + + if (var3 == 2) { + return; + } + + if (var3 == 1 && !var2.getIsServer()) { + return; + } + } + + try { + this.netManager.addToSendQueue(par1Packet); + } catch (Throwable var5) { + CrashReport var6 = CrashReport.makeCrashReport(var5, "Sending packet"); + CrashReportCategory var4 = var6.makeCategory("Packet being sent"); + var4.addCrashSectionCallable("Packet ID", new CallablePacketID(this, par1Packet)); + var4.addCrashSectionCallable("Packet class", new CallablePacketClass(this, par1Packet)); + throw new ReportedException(var6); + } + } + + public void handleBlockItemSwitch(Packet16BlockItemSwitch par1Packet16BlockItemSwitch) { + if (par1Packet16BlockItemSwitch.id >= 0 && par1Packet16BlockItemSwitch.id < InventoryPlayer.getHotbarSize()) { + this.playerEntity.inventory.currentItem = par1Packet16BlockItemSwitch.id; + } else { + this.mcServer.getLogAgent() + .func_98236_b(this.playerEntity.username + " tried to set an invalid carried item"); + } + } + + public void handleChat(Packet3Chat par1Packet3Chat) { + if (this.playerEntity.getChatVisibility() == 2) { + this.sendPacket(new Packet3Chat("Cannot send chat message.")); + } else { + String var2 = par1Packet3Chat.message; + + if (var2.length() > 100) { + this.kickPlayer("Chat message too long"); + } else { + var2 = var2.trim(); + + for (int var3 = 0; var3 < var2.length(); ++var3) { + if (!ChatAllowedCharacters.isAllowedCharacter(var2.charAt(var3))) { + this.kickPlayer("Illegal characters in chat"); + return; + } + } + + if (var2.startsWith("/")) { + this.handleSlashCommand(var2); + } else { + if (this.playerEntity.getChatVisibility() == 1) { + this.sendPacket(new Packet3Chat("Cannot send chat message.")); + return; + } + + var2 = "<" + this.playerEntity.getTranslatedEntityName() + "> " + var2; + this.mcServer.getLogAgent().func_98233_a(var2); + this.mcServer.getConfigurationManager().sendPacketToAllPlayers(new Packet3Chat(var2, false)); + } + + this.chatSpamThresholdCount += 20; + + if (this.chatSpamThresholdCount > 200 + && !this.mcServer.getConfigurationManager().areCommandsAllowed(this.playerEntity.username)) { + this.kickPlayer("disconnect.spam"); + } + } + } + } + + /** + * Processes a / command + */ + private void handleSlashCommand(String par1Str) { + this.mcServer.getCommandManager().executeCommand(this.playerEntity, par1Str); + } + + public void handleAnimation(Packet18Animation par1Packet18Animation) { + if (par1Packet18Animation.animate == 1) { + this.playerEntity.swingItem(); + } + } + + /** + * runs registerPacket on the given Packet19EntityAction + */ + public void handleEntityAction(Packet19EntityAction par1Packet19EntityAction) { + if (par1Packet19EntityAction.state == 1) { + this.playerEntity.setSneaking(true); + } else if (par1Packet19EntityAction.state == 2) { + this.playerEntity.setSneaking(false); + } else if (par1Packet19EntityAction.state == 4) { + this.playerEntity.setSprinting(true); + } else if (par1Packet19EntityAction.state == 5) { + this.playerEntity.setSprinting(false); + } else if (par1Packet19EntityAction.state == 3) { + this.playerEntity.wakeUpPlayer(false, true, true); + this.hasMoved = false; + } + } + + public void handleKickDisconnect(Packet255KickDisconnect par1Packet255KickDisconnect) { + this.netManager.networkShutdown("disconnect.quitting", new Object[0]); + } + + /** + * return the number of chuckDataPackets from the netManager + */ + public int getNumChunkDataPackets() { + return this.netManager.getNumChunkDataPackets(); + } + + public void handleUseEntity(Packet7UseEntity par1Packet7UseEntity) { + WorldServer var2 = this.mcServer.worldServerForDimension(this.playerEntity.dimension); + Entity var3 = var2.getEntityByID(par1Packet7UseEntity.targetEntity); + + if (var3 != null) { + boolean var4 = this.playerEntity.canEntityBeSeen(var3); + double var5 = 36.0D; + + if (!var4) { + var5 = 9.0D; + } + + if (this.playerEntity.getDistanceSqToEntity(var3) < var5) { + if (par1Packet7UseEntity.isLeftClick == 0) { + this.playerEntity.interactWith(var3); + } else if (par1Packet7UseEntity.isLeftClick == 1) { + this.playerEntity.attackTargetEntityWithCurrentItem(var3); + } + } + } + } + + public void handleClientCommand(Packet205ClientCommand par1Packet205ClientCommand) { + if (par1Packet205ClientCommand.forceRespawn == 1) { + if (this.playerEntity.playerConqueredTheEnd) { + this.playerEntity = this.mcServer.getConfigurationManager().recreatePlayerEntity(this.playerEntity, 0, + true); + } else if (this.playerEntity.getServerForPlayer().getWorldInfo().isHardcoreModeEnabled()) { + if (this.mcServer.isSinglePlayer() + && this.playerEntity.username.equals(this.mcServer.getServerOwner())) { + this.playerEntity.playerNetServerHandler + .kickPlayer("You have died. Game over, man, it\'s game over!"); + this.mcServer.deleteWorldAndStopServer(); + } else { + BanEntry var2 = new BanEntry(this.playerEntity.username); + var2.setBanReason("Death in Hardcore"); + this.mcServer.getConfigurationManager().getBannedPlayers().put(var2); + this.playerEntity.playerNetServerHandler + .kickPlayer("You have died. Game over, man, it\'s game over!"); + } + } else { + if (this.playerEntity.getHealth() > 0) { + return; + } + + this.playerEntity = this.mcServer.getConfigurationManager().recreatePlayerEntity(this.playerEntity, 0, + false); + } + } + } + + /** + * If this returns false, all packets will be queued for the main thread to + * handle, even if they would otherwise be processed asynchronously. Used to + * avoid processing packets on the client before the world has been downloaded + * (which happens on the main thread) + */ + public boolean canProcessPacketsAsync() { + return true; + } + + /** + * respawns the player + */ + public void handleRespawn(Packet9Respawn par1Packet9Respawn) { + } + + public void handleCloseWindow(Packet101CloseWindow par1Packet101CloseWindow) { + this.playerEntity.closeCraftingGui(); + } + + public void handleWindowClick(Packet102WindowClick par1Packet102WindowClick) { + if (this.playerEntity.openContainer.windowId == par1Packet102WindowClick.window_Id + && this.playerEntity.openContainer.getCanCraft(this.playerEntity)) { + ItemStack var2 = this.playerEntity.openContainer.slotClick(par1Packet102WindowClick.inventorySlot, + par1Packet102WindowClick.mouseClick, par1Packet102WindowClick.holdingShift, this.playerEntity); + + if (ItemStack.areItemStacksEqual(par1Packet102WindowClick.itemStack, var2)) { + this.playerEntity.playerNetServerHandler.sendPacket(new Packet106Transaction( + par1Packet102WindowClick.window_Id, par1Packet102WindowClick.action, true)); + this.playerEntity.isChangingQuantityOnly = true; + this.playerEntity.openContainer.detectAndSendChanges(); + this.playerEntity.updateHeldItem(); + this.playerEntity.isChangingQuantityOnly = false; + } else { + this.field_72586_s.addKey(this.playerEntity.openContainer.windowId, + Short.valueOf(par1Packet102WindowClick.action)); + this.playerEntity.playerNetServerHandler.sendPacket(new Packet106Transaction( + par1Packet102WindowClick.window_Id, par1Packet102WindowClick.action, false)); + this.playerEntity.openContainer.setCanCraft(this.playerEntity, false); + ArrayList var3 = new ArrayList(); + + for (int var4 = 0; var4 < this.playerEntity.openContainer.inventorySlots.size(); ++var4) { + var3.add(((Slot) this.playerEntity.openContainer.inventorySlots.get(var4)).getStack()); + } + + this.playerEntity.updateCraftingInventory(this.playerEntity.openContainer, var3); + } + } + } + + public void handleEnchantItem(Packet108EnchantItem par1Packet108EnchantItem) { + if (this.playerEntity.openContainer.windowId == par1Packet108EnchantItem.windowId + && this.playerEntity.openContainer.getCanCraft(this.playerEntity)) { + this.playerEntity.openContainer.enchantItem(this.playerEntity, par1Packet108EnchantItem.enchantment); + this.playerEntity.openContainer.detectAndSendChanges(); + } + } + + /** + * Handle a creative slot packet. + */ + public void handleCreativeSetSlot(Packet107CreativeSetSlot par1Packet107CreativeSetSlot) { + if (this.playerEntity.theItemInWorldManager.isCreative()) { + boolean var2 = par1Packet107CreativeSetSlot.slot < 0; + ItemStack var3 = par1Packet107CreativeSetSlot.itemStack; + boolean var4 = par1Packet107CreativeSetSlot.slot >= 1 + && par1Packet107CreativeSetSlot.slot < 36 + InventoryPlayer.getHotbarSize(); + boolean var5 = var3 == null + || var3.itemID < Item.itemsList.length && var3.itemID >= 0 && Item.itemsList[var3.itemID] != null; + boolean var6 = var3 == null || var3.getItemDamage() >= 0 && var3.getItemDamage() >= 0 + && var3.stackSize <= 64 && var3.stackSize > 0; + + if (var4 && var5 && var6) { + if (var3 == null) { + this.playerEntity.inventoryContainer.putStackInSlot(par1Packet107CreativeSetSlot.slot, + (ItemStack) null); + } else { + this.playerEntity.inventoryContainer.putStackInSlot(par1Packet107CreativeSetSlot.slot, var3); + } + + this.playerEntity.inventoryContainer.setCanCraft(this.playerEntity, true); + } else if (var2 && var5 && var6 && this.creativeItemCreationSpamThresholdTally < 200) { + this.creativeItemCreationSpamThresholdTally += 20; + EntityItem var7 = this.playerEntity.dropPlayerItem(var3); + + if (var7 != null) { + var7.setAgeToCreativeDespawnTime(); + } + } + } + } + + public void handleTransaction(Packet106Transaction par1Packet106Transaction) { + Short var2 = (Short) this.field_72586_s.lookup(this.playerEntity.openContainer.windowId); + + if (var2 != null && par1Packet106Transaction.shortWindowId == var2.shortValue() + && this.playerEntity.openContainer.windowId == par1Packet106Transaction.windowId + && !this.playerEntity.openContainer.getCanCraft(this.playerEntity)) { + this.playerEntity.openContainer.setCanCraft(this.playerEntity, true); + } + } + + /** + * Updates Client side signs + */ + public void handleUpdateSign(Packet130UpdateSign par1Packet130UpdateSign) { + WorldServer var2 = this.mcServer.worldServerForDimension(this.playerEntity.dimension); + + if (var2.blockExists(par1Packet130UpdateSign.xPosition, par1Packet130UpdateSign.yPosition, + par1Packet130UpdateSign.zPosition)) { + TileEntity var3 = var2.getBlockTileEntity(par1Packet130UpdateSign.xPosition, + par1Packet130UpdateSign.yPosition, par1Packet130UpdateSign.zPosition); + + if (var3 instanceof TileEntitySign) { + TileEntitySign var4 = (TileEntitySign) var3; + + if (!var4.isEditable()) { + this.mcServer.logWarning( + "Player " + this.playerEntity.username + " just tried to change non-editable sign"); + return; + } + } + + int var6; + int var8; + + for (var8 = 0; var8 < 4; ++var8) { + boolean var5 = true; + + if (par1Packet130UpdateSign.signLines[var8].length() > 15) { + var5 = false; + } else { + for (var6 = 0; var6 < par1Packet130UpdateSign.signLines[var8].length(); ++var6) { + if (ChatAllowedCharacters.allowedCharacters + .indexOf(par1Packet130UpdateSign.signLines[var8].charAt(var6)) < 0) { + var5 = false; + } + } + } + + if (!var5) { + par1Packet130UpdateSign.signLines[var8] = "!?"; + } + } + + if (var3 instanceof TileEntitySign) { + var8 = par1Packet130UpdateSign.xPosition; + int var9 = par1Packet130UpdateSign.yPosition; + var6 = par1Packet130UpdateSign.zPosition; + TileEntitySign var7 = (TileEntitySign) var3; + System.arraycopy(par1Packet130UpdateSign.signLines, 0, var7.signText, 0, 4); + var7.onInventoryChanged(); + var2.markBlockForUpdate(var8, var9, var6); + } + } + } + + /** + * Handle a keep alive packet. + */ + public void handleKeepAlive(Packet0KeepAlive par1Packet0KeepAlive) { + if (par1Packet0KeepAlive.randomId == this.keepAliveRandomID) { + int var2 = (int) (System.nanoTime() / 1000000L - this.keepAliveTimeSent); + this.playerEntity.ping = (this.playerEntity.ping * 3 + var2) / 4; + } + } + + /** + * determine if it is a server handler + */ + public boolean isServerHandler() { + return true; + } + + /** + * Handle a player abilities packet. + */ + public void handlePlayerAbilities(Packet202PlayerAbilities par1Packet202PlayerAbilities) { + this.playerEntity.capabilities.isFlying = par1Packet202PlayerAbilities.getFlying() + && this.playerEntity.capabilities.allowFlying; + } + + public void handleAutoComplete(Packet203AutoComplete par1Packet203AutoComplete) { + StringBuilder var2 = new StringBuilder(); + String var4; + + for (Iterator var3 = this.mcServer + .getPossibleCompletions(this.playerEntity, par1Packet203AutoComplete.getText()).iterator(); var3 + .hasNext(); var2.append(var4)) { + var4 = (String) var3.next(); + + if (var2.length() > 0) { + var2.append("\u0000"); + } + } + + this.playerEntity.playerNetServerHandler.sendPacket(new Packet203AutoComplete(var2.toString())); + } + + public void handleClientInfo(Packet204ClientInfo par1Packet204ClientInfo) { + this.playerEntity.updateClientInfo(par1Packet204ClientInfo); + } + + public void handleCustomPayload(Packet250CustomPayload par1Packet250CustomPayload) { + DataInputStream var2; + ItemStack var3; + ItemStack var4; + + if ("MC|BEdit".equals(par1Packet250CustomPayload.channel)) { + try { + var2 = new DataInputStream(new ByteArrayInputStream(par1Packet250CustomPayload.data)); + var3 = Packet.readItemStack(var2); + + if (!ItemWritableBook.validBookTagPages(var3.getTagCompound())) { + throw new IOException("Invalid book tag!"); + } + + var4 = this.playerEntity.inventory.getCurrentItem(); + + if (var3 != null && var3.itemID == Item.writableBook.itemID && var3.itemID == var4.itemID) { + var4.setTagInfo("pages", var3.getTagCompound().getTagList("pages")); + } + } catch (Exception var12) { + var12.printStackTrace(); + } + } else if ("MC|BSign".equals(par1Packet250CustomPayload.channel)) { + try { + var2 = new DataInputStream(new ByteArrayInputStream(par1Packet250CustomPayload.data)); + var3 = Packet.readItemStack(var2); + + if (!ItemEditableBook.validBookTagContents(var3.getTagCompound())) { + throw new IOException("Invalid book tag!"); + } + + var4 = this.playerEntity.inventory.getCurrentItem(); + + if (var3 != null && var3.itemID == Item.writtenBook.itemID && var4.itemID == Item.writableBook.itemID) { + var4.setTagInfo("author", new NBTTagString("author", this.playerEntity.username)); + var4.setTagInfo("title", new NBTTagString("title", var3.getTagCompound().getString("title"))); + var4.setTagInfo("pages", var3.getTagCompound().getTagList("pages")); + var4.itemID = Item.writtenBook.itemID; + } + } catch (Exception var11) { + var11.printStackTrace(); + } + } else { + int var13; + + if ("MC|TrSel".equals(par1Packet250CustomPayload.channel)) { + try { + var2 = new DataInputStream(new ByteArrayInputStream(par1Packet250CustomPayload.data)); + var13 = var2.readInt(); + Container var15 = this.playerEntity.openContainer; + + if (var15 instanceof ContainerMerchant) { + ((ContainerMerchant) var15).setCurrentRecipeIndex(var13); + } + } catch (Exception var10) { + var10.printStackTrace(); + } + } else { + int var17; + + if ("MC|AdvCdm".equals(par1Packet250CustomPayload.channel)) { + if (!this.mcServer.isCommandBlockEnabled()) { + this.playerEntity.sendChatToPlayer( + this.playerEntity.translateString("advMode.notEnabled", new Object[0])); + } else if (this.playerEntity.canCommandSenderUseCommand(2, "") + && this.playerEntity.capabilities.isCreativeMode) { + try { + var2 = new DataInputStream(new ByteArrayInputStream(par1Packet250CustomPayload.data)); + var13 = var2.readInt(); + var17 = var2.readInt(); + int var5 = var2.readInt(); + String var6 = Packet.readString(var2, 256); + TileEntity var7 = this.playerEntity.worldObj.getBlockTileEntity(var13, var17, var5); + + if (var7 != null && var7 instanceof TileEntityCommandBlock) { + ((TileEntityCommandBlock) var7).setCommand(var6); + this.playerEntity.worldObj.markBlockForUpdate(var13, var17, var5); + this.playerEntity.sendChatToPlayer("Command set: " + var6); + } + } catch (Exception var9) { + var9.printStackTrace(); + } + } else { + this.playerEntity.sendChatToPlayer( + this.playerEntity.translateString("advMode.notAllowed", new Object[0])); + } + } else if ("MC|Beacon".equals(par1Packet250CustomPayload.channel)) { + if (this.playerEntity.openContainer instanceof ContainerBeacon) { + try { + var2 = new DataInputStream(new ByteArrayInputStream(par1Packet250CustomPayload.data)); + var13 = var2.readInt(); + var17 = var2.readInt(); + ContainerBeacon var18 = (ContainerBeacon) this.playerEntity.openContainer; + Slot var19 = var18.getSlot(0); + + if (var19.getHasStack()) { + var19.decrStackSize(1); + TileEntityBeacon var20 = var18.getBeacon(); + var20.setPrimaryEffect(var13); + var20.setSecondaryEffect(var17); + var20.onInventoryChanged(); + } + } catch (Exception var8) { + var8.printStackTrace(); + } + } + } else if ("MC|ItemName".equals(par1Packet250CustomPayload.channel) + && this.playerEntity.openContainer instanceof ContainerRepair) { + ContainerRepair var14 = (ContainerRepair) this.playerEntity.openContainer; + + if (par1Packet250CustomPayload.data != null && par1Packet250CustomPayload.data.length >= 1) { + String var16 = ChatAllowedCharacters + .filerAllowedCharacters(new String(par1Packet250CustomPayload.data)); + + if (var16.length() <= 30) { + var14.updateItemName(var16); + } + } else { + var14.updateItemName(""); + } + } + } + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/NetworkListenThread.java b/sp-server/src/main/java/net/minecraft/src/NetworkListenThread.java new file mode 100644 index 0000000..be09c74 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/NetworkListenThread.java @@ -0,0 +1,65 @@ +package net.minecraft.src; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import net.minecraft.server.MinecraftServer; + +public abstract class NetworkListenThread { + /** Reference to the MinecraftServer object. */ + private final MinecraftServer mcServer; + private final List connections = Collections.synchronizedList(new ArrayList()); + + /** Whether the network listener object is listening. */ + public volatile boolean isListening = false; + + public NetworkListenThread(MinecraftServer par1MinecraftServer) throws IOException { + this.mcServer = par1MinecraftServer; + this.isListening = true; + } + + /** + * adds this connection to the list of currently connected players + */ + public void addPlayer(NetServerHandler par1NetServerHandler) { + this.connections.add(par1NetServerHandler); + } + + public void stopListening() { + this.isListening = false; + } + + /** + * Handles all incoming connections and packets + */ + public void handleNetworkListenThread() { + for (int var1 = 0; var1 < this.connections.size(); ++var1) { + NetServerHandler var2 = (NetServerHandler) this.connections.get(var1); + + try { + var2.handlePackets(); + } catch (Exception var5) { + if (var2.netManager instanceof MemoryConnection) { + CrashReport var4 = CrashReport.makeCrashReport(var5, "Ticking memory connection"); + throw new ReportedException(var4); + } + + this.mcServer.getLogAgent().logWarningException("Failed to handle packet for " + + var2.playerEntity.getEntityName() + "/" + var2.playerEntity.getPlayerIP() + ": " + var5, + var5); + var2.kickPlayer("Internal server error"); + } + + if (var2.connectionClosed) { + this.connections.remove(var1--); + } + + var2.netManager.wakeThreads(); + } + } + + public MinecraftServer getServer() { + return this.mcServer; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/NextTickListEntry.java b/sp-server/src/main/java/net/minecraft/src/NextTickListEntry.java new file mode 100644 index 0000000..d528040 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/NextTickListEntry.java @@ -0,0 +1,84 @@ +package net.minecraft.src; + +public class NextTickListEntry implements Comparable { + /** The id number for the next tick entry */ + private static long nextTickEntryID = 0L; + + /** X position this tick is occuring at */ + public int xCoord; + + /** Y position this tick is occuring at */ + public int yCoord; + + /** Z position this tick is occuring at */ + public int zCoord; + + /** + * blockID of the scheduled tick (ensures when the tick occurs its still for + * this block) + */ + public int blockID; + + /** Time this tick is scheduled to occur at */ + public long scheduledTime; + public int field_82754_f; + + /** The id of the tick entry */ + private long tickEntryID; + + public NextTickListEntry(int par1, int par2, int par3, int par4) { + this.tickEntryID = (long) (nextTickEntryID++); + this.xCoord = par1; + this.yCoord = par2; + this.zCoord = par3; + this.blockID = par4; + } + + public boolean equals(Object par1Obj) { + if (!(par1Obj instanceof NextTickListEntry)) { + return false; + } else { + NextTickListEntry var2 = (NextTickListEntry) par1Obj; + return this.xCoord == var2.xCoord && this.yCoord == var2.yCoord && this.zCoord == var2.zCoord + && Block.isAssociatedBlockID(this.blockID, var2.blockID); + } + } + + public int hashCode() { + return (this.xCoord * 1024 * 1024 + this.zCoord * 1024 + this.yCoord) * 256; + } + + /** + * Sets the scheduled time for this tick entry + */ + public NextTickListEntry setScheduledTime(long par1) { + this.scheduledTime = par1; + return this; + } + + public void func_82753_a(int par1) { + this.field_82754_f = par1; + } + + /** + * Compares this tick entry to another tick entry for sorting purposes. Compared + * first based on the scheduled time and second based on tickEntryID. + */ + public int comparer(NextTickListEntry par1NextTickListEntry) { + return this.scheduledTime < par1NextTickListEntry.scheduledTime ? -1 + : (this.scheduledTime > par1NextTickListEntry.scheduledTime ? 1 + : (this.field_82754_f != par1NextTickListEntry.field_82754_f + ? this.field_82754_f - par1NextTickListEntry.field_82754_f + : (this.tickEntryID < par1NextTickListEntry.tickEntryID ? -1 + : (this.tickEntryID > par1NextTickListEntry.tickEntryID ? 1 : 0)))); + } + + public String toString() { + return this.blockID + ": (" + this.xCoord + ", " + this.yCoord + ", " + this.zCoord + "), " + this.scheduledTime + + ", " + this.field_82754_f + ", " + this.tickEntryID; + } + + public int compareTo(Object par1Obj) { + return this.comparer((NextTickListEntry) par1Obj); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/NibbleArray.java b/sp-server/src/main/java/net/minecraft/src/NibbleArray.java new file mode 100644 index 0000000..a5a27e1 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/NibbleArray.java @@ -0,0 +1,59 @@ +package net.minecraft.src; + +public class NibbleArray { + /** + * Byte array of data stored in this holder. Possibly a light map or some chunk + * data. Data is accessed in 4-bit pieces. + */ + public final byte[] data; + + /** + * Log base 2 of the chunk height (128); applied as a shift on Z coordinate + */ + private final int depthBits; + + /** + * Log base 2 of the chunk height (128) * width (16); applied as a shift on X + * coordinate + */ + private final int depthBitsPlusFour; + + public NibbleArray(int par1, int par2) { + this.data = new byte[par1 >> 1]; + this.depthBits = par2; + this.depthBitsPlusFour = par2 + 4; + } + + public NibbleArray(byte[] par1ArrayOfByte, int par2) { + this.data = par1ArrayOfByte; + this.depthBits = par2; + this.depthBitsPlusFour = par2 + 4; + } + + /** + * Returns the nibble of data corresponding to the passed in x, y, z. y is at + * most 6 bits, z is at most 4. + */ + public int get(int par1, int par2, int par3) { + int var4 = par2 << this.depthBitsPlusFour | par3 << this.depthBits | par1; + int var5 = var4 >> 1; + int var6 = var4 & 1; + return var6 == 0 ? this.data[var5] & 15 : this.data[var5] >> 4 & 15; + } + + /** + * Arguments are x, y, z, val. Sets the nibble of data at x << 11 | z << 7 | y + * to val. + */ + public void set(int par1, int par2, int par3, int par4) { + int var5 = par2 << this.depthBitsPlusFour | par3 << this.depthBits | par1; + int var6 = var5 >> 1; + int var7 = var5 & 1; + + if (var7 == 0) { + this.data[var6] = (byte) (this.data[var6] & 240 | par4 & 15); + } else { + this.data[var6] = (byte) (this.data[var6] & 15 | (par4 & 15) << 4); + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/NibbleArrayReader.java b/sp-server/src/main/java/net/minecraft/src/NibbleArrayReader.java new file mode 100644 index 0000000..1d045f2 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/NibbleArrayReader.java @@ -0,0 +1,20 @@ +package net.minecraft.src; + +public class NibbleArrayReader { + public final byte[] data; + private final int depthBits; + private final int depthBitsPlusFour; + + public NibbleArrayReader(byte[] par1ArrayOfByte, int par2) { + this.data = par1ArrayOfByte; + this.depthBits = par2; + this.depthBitsPlusFour = par2 + 4; + } + + public int get(int par1, int par2, int par3) { + int var4 = par1 << this.depthBitsPlusFour | par3 << this.depthBits | par2; + int var5 = var4 >> 1; + int var6 = var4 & 1; + return var6 == 0 ? this.data[var5] & 15 : this.data[var5] >> 4 & 15; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/NoiseGenerator.java b/sp-server/src/main/java/net/minecraft/src/NoiseGenerator.java new file mode 100644 index 0000000..53e6d05 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/NoiseGenerator.java @@ -0,0 +1,4 @@ +package net.minecraft.src; + +public abstract class NoiseGenerator { +} diff --git a/sp-server/src/main/java/net/minecraft/src/NoiseGeneratorOctaves.java b/sp-server/src/main/java/net/minecraft/src/NoiseGeneratorOctaves.java new file mode 100644 index 0000000..34e86c8 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/NoiseGeneratorOctaves.java @@ -0,0 +1,65 @@ +package net.minecraft.src; + +import java.util.Random; + +public class NoiseGeneratorOctaves extends NoiseGenerator { + /** + * Collection of noise generation functions. Output is combined to produce + * different octaves of noise. + */ + private NoiseGeneratorPerlin[] generatorCollection; + private int octaves; + + public NoiseGeneratorOctaves(Random par1Random, int par2) { + this.octaves = par2; + this.generatorCollection = new NoiseGeneratorPerlin[par2]; + + for (int var3 = 0; var3 < par2; ++var3) { + this.generatorCollection[var3] = new NoiseGeneratorPerlin(par1Random); + } + } + + /** + * pars:(par2,3,4=noiseOffset ; so that adjacent noise segments connect) + * (pars5,6,7=x,y,zArraySize),(pars8,10,12 = x,y,z noiseScale) + */ + public double[] generateNoiseOctaves(double[] par1ArrayOfDouble, int par2, int par3, int par4, int par5, int par6, + int par7, double par8, double par10, double par12) { + if (par1ArrayOfDouble == null) { + par1ArrayOfDouble = new double[par5 * par6 * par7]; + } else { + for (int var14 = 0; var14 < par1ArrayOfDouble.length; ++var14) { + par1ArrayOfDouble[var14] = 0.0D; + } + } + + double var27 = 1.0D; + + for (int var16 = 0; var16 < this.octaves; ++var16) { + double var17 = (double) par2 * var27 * par8; + double var19 = (double) par3 * var27 * par10; + double var21 = (double) par4 * var27 * par12; + long var23 = MathHelper.floor_double_long(var17); + long var25 = MathHelper.floor_double_long(var21); + var17 -= (double) var23; + var21 -= (double) var25; + var23 %= 16777216L; + var25 %= 16777216L; + var17 += (double) var23; + var21 += (double) var25; + this.generatorCollection[var16].populateNoiseArray(par1ArrayOfDouble, var17, var19, var21, par5, par6, par7, + par8 * var27, par10 * var27, par12 * var27, var27); + var27 /= 2.0D; + } + + return par1ArrayOfDouble; + } + + /** + * Bouncer function to the main one with some default arguments. + */ + public double[] generateNoiseOctaves(double[] par1ArrayOfDouble, int par2, int par3, int par4, int par5, + double par6, double par8, double par10) { + return this.generateNoiseOctaves(par1ArrayOfDouble, par2, 10, par3, par4, 1, par5, par6, 1.0D, par8); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/NoiseGeneratorPerlin.java b/sp-server/src/main/java/net/minecraft/src/NoiseGeneratorPerlin.java new file mode 100644 index 0000000..ca4220c --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/NoiseGeneratorPerlin.java @@ -0,0 +1,199 @@ +package net.minecraft.src; + +import java.util.Random; + +public class NoiseGeneratorPerlin extends NoiseGenerator { + private int[] permutations; + public double xCoord; + public double yCoord; + public double zCoord; + + public NoiseGeneratorPerlin() { + this(new Random()); + } + + public NoiseGeneratorPerlin(Random par1Random) { + this.permutations = new int[512]; + this.xCoord = par1Random.nextDouble() * 256.0D; + this.yCoord = par1Random.nextDouble() * 256.0D; + this.zCoord = par1Random.nextDouble() * 256.0D; + int var2; + + for (var2 = 0; var2 < 256; this.permutations[var2] = var2++) { + ; + } + + for (var2 = 0; var2 < 256; ++var2) { + int var3 = par1Random.nextInt(256 - var2) + var2; + int var4 = this.permutations[var2]; + this.permutations[var2] = this.permutations[var3]; + this.permutations[var3] = var4; + this.permutations[var2 + 256] = this.permutations[var2]; + } + } + + public final double lerp(double par1, double par3, double par5) { + return par3 + par1 * (par5 - par3); + } + + public final double func_76309_a(int par1, double par2, double par4) { + int var6 = par1 & 15; + double var7 = (double) (1 - ((var6 & 8) >> 3)) * par2; + double var9 = var6 < 4 ? 0.0D : (var6 != 12 && var6 != 14 ? par4 : par2); + return ((var6 & 1) == 0 ? var7 : -var7) + ((var6 & 2) == 0 ? var9 : -var9); + } + + public final double grad(int par1, double par2, double par4, double par6) { + int var8 = par1 & 15; + double var9 = var8 < 8 ? par2 : par4; + double var11 = var8 < 4 ? par4 : (var8 != 12 && var8 != 14 ? par6 : par2); + return ((var8 & 1) == 0 ? var9 : -var9) + ((var8 & 2) == 0 ? var11 : -var11); + } + + /** + * pars: noiseArray , xOffset , yOffset , zOffset , xSize , ySize , zSize , + * xScale, yScale , zScale , noiseScale. noiseArray should be xSize*ySize*zSize + * in size + */ + public void populateNoiseArray(double[] par1ArrayOfDouble, double par2, double par4, double par6, int par8, + int par9, int par10, double par11, double par13, double par15, double par17) { + int var10001; + int var19; + int var22; + double var31; + double var35; + int var37; + double var38; + int var40; + int var41; + double var42; + int var75; + + if (par9 == 1) { + boolean var64 = false; + boolean var65 = false; + boolean var21 = false; + boolean var68 = false; + double var70 = 0.0D; + double var73 = 0.0D; + var75 = 0; + double var77 = 1.0D / par17; + + for (int var30 = 0; var30 < par8; ++var30) { + var31 = par2 + (double) var30 * par11 + this.xCoord; + int var78 = (int) var31; + + if (var31 < (double) var78) { + --var78; + } + + int var34 = var78 & 255; + var31 -= (double) var78; + var35 = var31 * var31 * var31 * (var31 * (var31 * 6.0D - 15.0D) + 10.0D); + + for (var37 = 0; var37 < par10; ++var37) { + var38 = par6 + (double) var37 * par15 + this.zCoord; + var40 = (int) var38; + + if (var38 < (double) var40) { + --var40; + } + + var41 = var40 & 255; + var38 -= (double) var40; + var42 = var38 * var38 * var38 * (var38 * (var38 * 6.0D - 15.0D) + 10.0D); + var19 = this.permutations[var34] + 0; + int var66 = this.permutations[var19] + var41; + int var67 = this.permutations[var34 + 1] + 0; + var22 = this.permutations[var67] + var41; + var70 = this.lerp(var35, this.func_76309_a(this.permutations[var66], var31, var38), + this.grad(this.permutations[var22], var31 - 1.0D, 0.0D, var38)); + var73 = this.lerp(var35, this.grad(this.permutations[var66 + 1], var31, 0.0D, var38 - 1.0D), + this.grad(this.permutations[var22 + 1], var31 - 1.0D, 0.0D, var38 - 1.0D)); + double var79 = this.lerp(var42, var70, var73); + var10001 = var75++; + par1ArrayOfDouble[var10001] += var79 * var77; + } + } + } else { + var19 = 0; + double var20 = 1.0D / par17; + var22 = -1; + boolean var23 = false; + boolean var24 = false; + boolean var25 = false; + boolean var26 = false; + boolean var27 = false; + boolean var28 = false; + double var29 = 0.0D; + var31 = 0.0D; + double var33 = 0.0D; + var35 = 0.0D; + + for (var37 = 0; var37 < par8; ++var37) { + var38 = par2 + (double) var37 * par11 + this.xCoord; + var40 = (int) var38; + + if (var38 < (double) var40) { + --var40; + } + + var41 = var40 & 255; + var38 -= (double) var40; + var42 = var38 * var38 * var38 * (var38 * (var38 * 6.0D - 15.0D) + 10.0D); + + for (int var44 = 0; var44 < par10; ++var44) { + double var45 = par6 + (double) var44 * par15 + this.zCoord; + int var47 = (int) var45; + + if (var45 < (double) var47) { + --var47; + } + + int var48 = var47 & 255; + var45 -= (double) var47; + double var49 = var45 * var45 * var45 * (var45 * (var45 * 6.0D - 15.0D) + 10.0D); + + for (int var51 = 0; var51 < par9; ++var51) { + double var52 = par4 + (double) var51 * par13 + this.yCoord; + int var54 = (int) var52; + + if (var52 < (double) var54) { + --var54; + } + + int var55 = var54 & 255; + var52 -= (double) var54; + double var56 = var52 * var52 * var52 * (var52 * (var52 * 6.0D - 15.0D) + 10.0D); + + if (var51 == 0 || var55 != var22) { + var22 = var55; + int var69 = this.permutations[var41] + var55; + int var71 = this.permutations[var69] + var48; + int var72 = this.permutations[var69 + 1] + var48; + int var74 = this.permutations[var41 + 1] + var55; + var75 = this.permutations[var74] + var48; + int var76 = this.permutations[var74 + 1] + var48; + var29 = this.lerp(var42, this.grad(this.permutations[var71], var38, var52, var45), + this.grad(this.permutations[var75], var38 - 1.0D, var52, var45)); + var31 = this.lerp(var42, this.grad(this.permutations[var72], var38, var52 - 1.0D, var45), + this.grad(this.permutations[var76], var38 - 1.0D, var52 - 1.0D, var45)); + var33 = this.lerp(var42, + this.grad(this.permutations[var71 + 1], var38, var52, var45 - 1.0D), + this.grad(this.permutations[var75 + 1], var38 - 1.0D, var52, var45 - 1.0D)); + var35 = this.lerp(var42, + this.grad(this.permutations[var72 + 1], var38, var52 - 1.0D, var45 - 1.0D), + this.grad(this.permutations[var76 + 1], var38 - 1.0D, var52 - 1.0D, var45 - 1.0D)); + } + + double var58 = this.lerp(var56, var29, var31); + double var60 = this.lerp(var56, var33, var35); + double var62 = this.lerp(var49, var58, var60); + var10001 = var19++; + par1ArrayOfDouble[var10001] += var62 * var20; + } + } + } + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/NumberInvalidException.java b/sp-server/src/main/java/net/minecraft/src/NumberInvalidException.java new file mode 100644 index 0000000..9112275 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/NumberInvalidException.java @@ -0,0 +1,11 @@ +package net.minecraft.src; + +public class NumberInvalidException extends CommandException { + public NumberInvalidException() { + this("commands.generic.num.invalid", new Object[0]); + } + + public NumberInvalidException(String par1Str, Object... par2ArrayOfObj) { + super(par1Str, par2ArrayOfObj); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/Packet.java b/sp-server/src/main/java/net/minecraft/src/Packet.java new file mode 100644 index 0000000..19f7e34 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/Packet.java @@ -0,0 +1,397 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.EOFException; +import java.io.IOException; +import java.net.Socket; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +public abstract class Packet { + /** Maps packet id to packet class */ + public static IntHashMap packetIdToClassMap = new IntHashMap(); + + /** Maps packet class to packet id */ + private static Map packetClassToIdMap = new HashMap(); + + /** List of the client's packet IDs. */ + private static Set clientPacketIdList = new HashSet(); + + /** List of the server's packet IDs. */ + private static Set serverPacketIdList = new HashSet(); + protected ILogAgent field_98193_m; + + /** the system time in milliseconds when this packet was created. */ + public final long creationTimeMillis = System.currentTimeMillis(); + public static long receivedID; + public static long receivedSize; + + /** Assumed to be sequential by the profiler. */ + public static long sentID; + public static long sentSize; + + /** + * Only true for Packet51MapChunk, Packet52MultiBlockChange, Packet53BlockChange + * and Packet59ComplexEntity. Used to separate them into a different send queue. + */ + public boolean isChunkDataPacket = false; + + /** + * Adds a two way mapping between the packet ID and packet class. + */ + static void addIdClassMapping(int par0, boolean par1, boolean par2, Class par3Class) { + if (packetIdToClassMap.containsItem(par0)) { + throw new IllegalArgumentException("Duplicate packet id:" + par0); + } else if (packetClassToIdMap.containsKey(par3Class)) { + throw new IllegalArgumentException("Duplicate packet class:" + par3Class); + } else { + packetIdToClassMap.addKey(par0, par3Class); + packetClassToIdMap.put(par3Class, Integer.valueOf(par0)); + + if (par1) { + clientPacketIdList.add(Integer.valueOf(par0)); + } + + if (par2) { + serverPacketIdList.add(Integer.valueOf(par0)); + } + } + } + + /** + * Returns a new instance of the specified Packet class. + */ + public static Packet getNewPacket(ILogAgent par0ILogAgent, int par1) { + try { + Class var2 = (Class) packetIdToClassMap.lookup(par1); + return var2 == null ? null : (Packet) var2.newInstance(); + } catch (Exception var3) { + var3.printStackTrace(); + par0ILogAgent.logSevere("Skipping packet with id " + par1); + return null; + } + } + + /** + * Writes a byte array to the DataOutputStream + */ + public static void writeByteArray(DataOutputStream par0DataOutputStream, byte[] par1ArrayOfByte) + throws IOException { + par0DataOutputStream.writeShort(par1ArrayOfByte.length); + par0DataOutputStream.write(par1ArrayOfByte); + } + + /** + * the first short in the stream indicates the number of bytes to read + */ + public static byte[] readBytesFromStream(DataInputStream par0DataInputStream) throws IOException { + short var1 = par0DataInputStream.readShort(); + + if (var1 < 0) { + throw new IOException("Key was smaller than nothing! Weird key!"); + } else { + byte[] var2 = new byte[var1]; + par0DataInputStream.readFully(var2); + return var2; + } + } + + /** + * Returns the ID of this packet. + */ + public final int getPacketId() { + return ((Integer) packetClassToIdMap.get(this.getClass())).intValue(); + } + + /** + * Read a packet, prefixed by its ID, from the data stream. + */ + public static Packet readPacket(ILogAgent par0ILogAgent, DataInputStream par1DataInputStream, boolean par2, + Socket par3Socket) throws IOException { + boolean var4 = false; + Packet var5 = null; + int var6 = par3Socket.getSoTimeout(); + int var9; + + try { + var9 = par1DataInputStream.read(); + + if (var9 == -1) { + return null; + } + + if (par2 && !serverPacketIdList.contains(Integer.valueOf(var9)) + || !par2 && !clientPacketIdList.contains(Integer.valueOf(var9))) { + throw new IOException("Bad packet id " + var9); + } + + var5 = getNewPacket(par0ILogAgent, var9); + + if (var5 == null) { + throw new IOException("Bad packet id " + var9); + } + + var5.field_98193_m = par0ILogAgent; + + if (var5 instanceof Packet254ServerPing) { + par3Socket.setSoTimeout(1500); + } + + var5.readPacketData(par1DataInputStream); + ++receivedID; + receivedSize += (long) var5.getPacketSize(); + } catch (EOFException var8) { + par0ILogAgent.logSevere("Reached end of stream"); + return null; + } + + PacketCount.countPacket(var9, (long) var5.getPacketSize()); + ++receivedID; + receivedSize += (long) var5.getPacketSize(); + par3Socket.setSoTimeout(var6); + return var5; + } + + /** + * Writes a packet, prefixed by its ID, to the data stream. + */ + public static void writePacket(Packet par0Packet, DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.write(par0Packet.getPacketId()); + par0Packet.writePacketData(par1DataOutputStream); + ++sentID; + sentSize += (long) par0Packet.getPacketSize(); + } + + /** + * Writes a String to the DataOutputStream + */ + public static void writeString(String par0Str, DataOutputStream par1DataOutputStream) throws IOException { + if (par0Str.length() > 32767) { + throw new IOException("String too big"); + } else { + par1DataOutputStream.writeShort(par0Str.length()); + par1DataOutputStream.writeChars(par0Str); + } + } + + /** + * Reads a string from a packet + */ + public static String readString(DataInputStream par0DataInputStream, int par1) throws IOException { + short var2 = par0DataInputStream.readShort(); + + if (var2 > par1) { + throw new IOException("Received string length longer than maximum allowed (" + var2 + " > " + par1 + ")"); + } else if (var2 < 0) { + throw new IOException("Received string length is less than zero! Weird string!"); + } else { + StringBuilder var3 = new StringBuilder(); + + for (int var4 = 0; var4 < var2; ++var4) { + var3.append(par0DataInputStream.readChar()); + } + + return var3.toString(); + } + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public abstract void readPacketData(DataInputStream var1) throws IOException; + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public abstract void writePacketData(DataOutputStream var1) throws IOException; + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public abstract void processPacket(NetHandler var1); + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public abstract int getPacketSize(); + + /** + * only false for the abstract Packet class, all real packets return true + */ + public boolean isRealPacket() { + return false; + } + + /** + * eg return packet30entity.entityId == entityId; WARNING : will throw if you + * compare a packet to a different packet class + */ + public boolean containsSameEntityIDAs(Packet par1Packet) { + return false; + } + + /** + * If this returns true, the packet may be processed on any thread; otherwise it + * is queued for the main thread to handle. + */ + public boolean canProcessAsync() { + return false; + } + + public String toString() { + String var1 = this.getClass().getSimpleName(); + return var1; + } + + /** + * Reads a ItemStack from the InputStream + */ + public static ItemStack readItemStack(DataInputStream par0DataInputStream) throws IOException { + ItemStack var1 = null; + short var2 = par0DataInputStream.readShort(); + + if (var2 >= 0) { + byte var3 = par0DataInputStream.readByte(); + short var4 = par0DataInputStream.readShort(); + var1 = new ItemStack(var2, var3, var4); + var1.stackTagCompound = readNBTTagCompound(par0DataInputStream); + } + + return var1; + } + + /** + * Writes the ItemStack's ID (short), then size (byte), then damage. (short) + */ + public static void writeItemStack(ItemStack par0ItemStack, DataOutputStream par1DataOutputStream) + throws IOException { + if (par0ItemStack == null) { + par1DataOutputStream.writeShort(-1); + } else { + par1DataOutputStream.writeShort(par0ItemStack.itemID); + par1DataOutputStream.writeByte(par0ItemStack.stackSize); + par1DataOutputStream.writeShort(par0ItemStack.getItemDamage()); + NBTTagCompound var2 = null; + + if (par0ItemStack.getItem().isDamageable() || par0ItemStack.getItem().getShareTag()) { + var2 = par0ItemStack.stackTagCompound; + } + + writeNBTTagCompound(var2, par1DataOutputStream); + } + } + + /** + * Reads a compressed NBTTagCompound from the InputStream + */ + public static NBTTagCompound readNBTTagCompound(DataInputStream par0DataInputStream) throws IOException { + short var1 = par0DataInputStream.readShort(); + + if (var1 < 0) { + return null; + } else { + byte[] var2 = new byte[var1]; + par0DataInputStream.readFully(var2); + return CompressedStreamTools.decompress(var2); + } + } + + /** + * Writes a compressed NBTTagCompound to the OutputStream + */ + protected static void writeNBTTagCompound(NBTTagCompound par0NBTTagCompound, DataOutputStream par1DataOutputStream) + throws IOException { + if (par0NBTTagCompound == null) { + par1DataOutputStream.writeShort(-1); + } else { + byte[] var2 = CompressedStreamTools.compress(par0NBTTagCompound); + par1DataOutputStream.writeShort((short) var2.length); + par1DataOutputStream.write(var2); + } + } + + static { + addIdClassMapping(0, true, true, Packet0KeepAlive.class); + addIdClassMapping(1, true, true, Packet1Login.class); + addIdClassMapping(2, false, true, Packet2ClientProtocol.class); + addIdClassMapping(3, true, true, Packet3Chat.class); + addIdClassMapping(4, true, false, Packet4UpdateTime.class); + addIdClassMapping(5, true, false, Packet5PlayerInventory.class); + addIdClassMapping(6, true, false, Packet6SpawnPosition.class); + addIdClassMapping(7, false, true, Packet7UseEntity.class); + addIdClassMapping(8, true, false, Packet8UpdateHealth.class); + addIdClassMapping(9, true, true, Packet9Respawn.class); + addIdClassMapping(10, true, true, Packet10Flying.class); + addIdClassMapping(11, true, true, Packet11PlayerPosition.class); + addIdClassMapping(12, true, true, Packet12PlayerLook.class); + addIdClassMapping(13, true, true, Packet13PlayerLookMove.class); + addIdClassMapping(14, false, true, Packet14BlockDig.class); + addIdClassMapping(15, false, true, Packet15Place.class); + addIdClassMapping(16, true, true, Packet16BlockItemSwitch.class); + addIdClassMapping(17, true, false, Packet17Sleep.class); + addIdClassMapping(18, true, true, Packet18Animation.class); + addIdClassMapping(19, false, true, Packet19EntityAction.class); + addIdClassMapping(20, true, false, Packet20NamedEntitySpawn.class); + addIdClassMapping(22, true, false, Packet22Collect.class); + addIdClassMapping(23, true, false, Packet23VehicleSpawn.class); + addIdClassMapping(24, true, false, Packet24MobSpawn.class); + addIdClassMapping(25, true, false, Packet25EntityPainting.class); + addIdClassMapping(26, true, false, Packet26EntityExpOrb.class); + addIdClassMapping(28, true, false, Packet28EntityVelocity.class); + addIdClassMapping(29, true, false, Packet29DestroyEntity.class); + addIdClassMapping(30, true, false, Packet30Entity.class); + addIdClassMapping(31, true, false, Packet31RelEntityMove.class); + addIdClassMapping(32, true, false, Packet32EntityLook.class); + addIdClassMapping(33, true, false, Packet33RelEntityMoveLook.class); + addIdClassMapping(34, true, false, Packet34EntityTeleport.class); + addIdClassMapping(35, true, false, Packet35EntityHeadRotation.class); + addIdClassMapping(38, true, false, Packet38EntityStatus.class); + addIdClassMapping(39, true, false, Packet39AttachEntity.class); + addIdClassMapping(40, true, false, Packet40EntityMetadata.class); + addIdClassMapping(41, true, false, Packet41EntityEffect.class); + addIdClassMapping(42, true, false, Packet42RemoveEntityEffect.class); + addIdClassMapping(43, true, false, Packet43Experience.class); + addIdClassMapping(51, true, false, Packet51MapChunk.class); + addIdClassMapping(52, true, false, Packet52MultiBlockChange.class); + addIdClassMapping(53, true, false, Packet53BlockChange.class); + addIdClassMapping(54, true, false, Packet54PlayNoteBlock.class); + addIdClassMapping(55, true, false, Packet55BlockDestroy.class); + addIdClassMapping(56, true, false, Packet56MapChunks.class); + addIdClassMapping(60, true, false, Packet60Explosion.class); + addIdClassMapping(61, true, false, Packet61DoorChange.class); + addIdClassMapping(62, true, false, Packet62LevelSound.class); + addIdClassMapping(63, true, false, Packet63WorldParticles.class); + addIdClassMapping(70, true, false, Packet70GameEvent.class); + addIdClassMapping(71, true, false, Packet71Weather.class); + addIdClassMapping(100, true, false, Packet100OpenWindow.class); + addIdClassMapping(101, true, true, Packet101CloseWindow.class); + addIdClassMapping(102, false, true, Packet102WindowClick.class); + addIdClassMapping(103, true, false, Packet103SetSlot.class); + addIdClassMapping(104, true, false, Packet104WindowItems.class); + addIdClassMapping(105, true, false, Packet105UpdateProgressbar.class); + addIdClassMapping(106, true, true, Packet106Transaction.class); + addIdClassMapping(107, true, true, Packet107CreativeSetSlot.class); + addIdClassMapping(108, false, true, Packet108EnchantItem.class); + addIdClassMapping(130, true, true, Packet130UpdateSign.class); + addIdClassMapping(131, true, false, Packet131MapData.class); + addIdClassMapping(132, true, false, Packet132TileEntityData.class); + addIdClassMapping(200, true, false, Packet200Statistic.class); + addIdClassMapping(201, true, false, Packet201PlayerInfo.class); + addIdClassMapping(202, true, true, Packet202PlayerAbilities.class); + addIdClassMapping(203, true, true, Packet203AutoComplete.class); + addIdClassMapping(204, false, true, Packet204ClientInfo.class); + addIdClassMapping(205, false, true, Packet205ClientCommand.class); + addIdClassMapping(206, true, false, Packet206SetObjective.class); + addIdClassMapping(207, true, false, Packet207SetScore.class); + addIdClassMapping(208, true, false, Packet208SetDisplayObjective.class); + addIdClassMapping(209, true, false, Packet209SetPlayerTeam.class); + addIdClassMapping(250, true, true, Packet250CustomPayload.class); + addIdClassMapping(252, true, true, Packet252SharedKey.class); + addIdClassMapping(253, true, false, Packet253ServerAuthData.class); + addIdClassMapping(254, false, true, Packet254ServerPing.class); + addIdClassMapping(255, true, true, Packet255KickDisconnect.class); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/Packet0KeepAlive.java b/sp-server/src/main/java/net/minecraft/src/Packet0KeepAlive.java new file mode 100644 index 0000000..d92837d --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/Packet0KeepAlive.java @@ -0,0 +1,67 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet0KeepAlive extends Packet { + public int randomId; + + public Packet0KeepAlive() { + } + + public Packet0KeepAlive(int par1) { + this.randomId = par1; + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleKeepAlive(this); + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.randomId = par1DataInputStream.readInt(); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeInt(this.randomId); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 4; + } + + /** + * only false for the abstract Packet class, all real packets return true + */ + public boolean isRealPacket() { + return true; + } + + /** + * eg return packet30entity.entityId == entityId; WARNING : will throw if you + * compare a packet to a different packet class + */ + public boolean containsSameEntityIDAs(Packet par1Packet) { + return true; + } + + /** + * If this returns true, the packet may be processed on any thread; otherwise it + * is queued for the main thread to handle. + */ + public boolean canProcessAsync() { + return true; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/Packet100OpenWindow.java b/sp-server/src/main/java/net/minecraft/src/Packet100OpenWindow.java new file mode 100644 index 0000000..2a5ce81 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/Packet100OpenWindow.java @@ -0,0 +1,65 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet100OpenWindow extends Packet { + public int windowId; + public int inventoryType; + public String windowTitle; + public int slotsCount; + + /** + * If false, the client will look up a string like "window.minecart". If true, + * the client uses what the server provides. + */ + public boolean useProvidedWindowTitle; + + public Packet100OpenWindow() { + } + + public Packet100OpenWindow(int par1, int par2, String par3Str, int par4, boolean par5) { + this.windowId = par1; + this.inventoryType = par2; + this.windowTitle = par3Str; + this.slotsCount = par4; + this.useProvidedWindowTitle = par5; + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleOpenWindow(this); + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.windowId = par1DataInputStream.readByte() & 255; + this.inventoryType = par1DataInputStream.readByte() & 255; + this.windowTitle = readString(par1DataInputStream, 32); + this.slotsCount = par1DataInputStream.readByte() & 255; + this.useProvidedWindowTitle = par1DataInputStream.readBoolean(); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeByte(this.windowId & 255); + par1DataOutputStream.writeByte(this.inventoryType & 255); + writeString(this.windowTitle, par1DataOutputStream); + par1DataOutputStream.writeByte(this.slotsCount & 255); + par1DataOutputStream.writeBoolean(this.useProvidedWindowTitle); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 4 + this.windowTitle.length(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/Packet101CloseWindow.java b/sp-server/src/main/java/net/minecraft/src/Packet101CloseWindow.java new file mode 100644 index 0000000..da55399 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/Packet101CloseWindow.java @@ -0,0 +1,44 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet101CloseWindow extends Packet { + public int windowId; + + public Packet101CloseWindow() { + } + + public Packet101CloseWindow(int par1) { + this.windowId = par1; + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleCloseWindow(this); + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.windowId = par1DataInputStream.readByte(); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeByte(this.windowId); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 1; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/Packet102WindowClick.java b/sp-server/src/main/java/net/minecraft/src/Packet102WindowClick.java new file mode 100644 index 0000000..49c5cb1 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/Packet102WindowClick.java @@ -0,0 +1,61 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet102WindowClick extends Packet { + /** The id of the window which was clicked. 0 for player inventory. */ + public int window_Id; + + /** The clicked slot (-999 is outside of inventory) */ + public int inventorySlot; + + /** 1 when right-clicking and otherwise 0 */ + public int mouseClick; + + /** A unique number for the action, used for transaction handling */ + public short action; + + /** Item stack for inventory */ + public ItemStack itemStack; + public int holdingShift; + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleWindowClick(this); + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.window_Id = par1DataInputStream.readByte(); + this.inventorySlot = par1DataInputStream.readShort(); + this.mouseClick = par1DataInputStream.readByte(); + this.action = par1DataInputStream.readShort(); + this.holdingShift = par1DataInputStream.readByte(); + this.itemStack = readItemStack(par1DataInputStream); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeByte(this.window_Id); + par1DataOutputStream.writeShort(this.inventorySlot); + par1DataOutputStream.writeByte(this.mouseClick); + par1DataOutputStream.writeShort(this.action); + par1DataOutputStream.writeByte(this.holdingShift); + writeItemStack(this.itemStack, par1DataOutputStream); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 11; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/Packet103SetSlot.java b/sp-server/src/main/java/net/minecraft/src/Packet103SetSlot.java new file mode 100644 index 0000000..466fd66 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/Packet103SetSlot.java @@ -0,0 +1,57 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet103SetSlot extends Packet { + /** The window which is being updated. 0 for player inventory */ + public int windowId; + + /** Slot that should be updated */ + public int itemSlot; + + /** Item stack */ + public ItemStack myItemStack; + + public Packet103SetSlot() { + } + + public Packet103SetSlot(int par1, int par2, ItemStack par3ItemStack) { + this.windowId = par1; + this.itemSlot = par2; + this.myItemStack = par3ItemStack == null ? par3ItemStack : par3ItemStack.copy(); + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleSetSlot(this); + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.windowId = par1DataInputStream.readByte(); + this.itemSlot = par1DataInputStream.readShort(); + this.myItemStack = readItemStack(par1DataInputStream); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeByte(this.windowId); + par1DataOutputStream.writeShort(this.itemSlot); + writeItemStack(this.myItemStack, par1DataOutputStream); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 8; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/Packet104WindowItems.java b/sp-server/src/main/java/net/minecraft/src/Packet104WindowItems.java new file mode 100644 index 0000000..cfb3163 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/Packet104WindowItems.java @@ -0,0 +1,68 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.util.List; + +public class Packet104WindowItems extends Packet { + /** + * The id of window which items are being sent for. 0 for player inventory. + */ + public int windowId; + + /** Stack of items */ + public ItemStack[] itemStack; + + public Packet104WindowItems() { + } + + public Packet104WindowItems(int par1, List par2List) { + this.windowId = par1; + this.itemStack = new ItemStack[par2List.size()]; + + for (int var3 = 0; var3 < this.itemStack.length; ++var3) { + ItemStack var4 = (ItemStack) par2List.get(var3); + this.itemStack[var3] = var4 == null ? null : var4.copy(); + } + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.windowId = par1DataInputStream.readByte(); + short var2 = par1DataInputStream.readShort(); + this.itemStack = new ItemStack[var2]; + + for (int var3 = 0; var3 < var2; ++var3) { + this.itemStack[var3] = readItemStack(par1DataInputStream); + } + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeByte(this.windowId); + par1DataOutputStream.writeShort(this.itemStack.length); + + for (int var2 = 0; var2 < this.itemStack.length; ++var2) { + writeItemStack(this.itemStack[var2], par1DataOutputStream); + } + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleWindowItems(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 3 + this.itemStack.length * 5; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/Packet105UpdateProgressbar.java b/sp-server/src/main/java/net/minecraft/src/Packet105UpdateProgressbar.java new file mode 100644 index 0000000..dc199c3 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/Packet105UpdateProgressbar.java @@ -0,0 +1,65 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet105UpdateProgressbar extends Packet { + /** The id of the window that the progress bar is in. */ + public int windowId; + + /** + * Which of the progress bars that should be updated. (For furnaces, 0 = + * progress arrow, 1 = fire icon) + */ + public int progressBar; + + /** + * The value of the progress bar. The maximum values vary depending on the + * progress bar. Presumably the values are specified as in-game ticks. Some + * progress bar values increase, while others decrease. For furnaces, 0 is + * empty, full progress arrow = about 180, full fire icon = about 250) + */ + public int progressBarValue; + + public Packet105UpdateProgressbar() { + } + + public Packet105UpdateProgressbar(int par1, int par2, int par3) { + this.windowId = par1; + this.progressBar = par2; + this.progressBarValue = par3; + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleUpdateProgressbar(this); + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.windowId = par1DataInputStream.readByte(); + this.progressBar = par1DataInputStream.readShort(); + this.progressBarValue = par1DataInputStream.readShort(); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeByte(this.windowId); + par1DataOutputStream.writeShort(this.progressBar); + par1DataOutputStream.writeShort(this.progressBarValue); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 5; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/Packet106Transaction.java b/sp-server/src/main/java/net/minecraft/src/Packet106Transaction.java new file mode 100644 index 0000000..1c4a177 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/Packet106Transaction.java @@ -0,0 +1,53 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet106Transaction extends Packet { + /** The id of the window that the action occurred in. */ + public int windowId; + public short shortWindowId; + public boolean accepted; + + public Packet106Transaction() { + } + + public Packet106Transaction(int par1, short par2, boolean par3) { + this.windowId = par1; + this.shortWindowId = par2; + this.accepted = par3; + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleTransaction(this); + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.windowId = par1DataInputStream.readByte(); + this.shortWindowId = par1DataInputStream.readShort(); + this.accepted = par1DataInputStream.readByte() != 0; + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeByte(this.windowId); + par1DataOutputStream.writeShort(this.shortWindowId); + par1DataOutputStream.writeByte(this.accepted ? 1 : 0); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 4; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/Packet107CreativeSetSlot.java b/sp-server/src/main/java/net/minecraft/src/Packet107CreativeSetSlot.java new file mode 100644 index 0000000..15f72bb --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/Packet107CreativeSetSlot.java @@ -0,0 +1,40 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet107CreativeSetSlot extends Packet { + public int slot; + public ItemStack itemStack; + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleCreativeSetSlot(this); + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.slot = par1DataInputStream.readShort(); + this.itemStack = readItemStack(par1DataInputStream); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeShort(this.slot); + writeItemStack(this.itemStack, par1DataOutputStream); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 8; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/Packet108EnchantItem.java b/sp-server/src/main/java/net/minecraft/src/Packet108EnchantItem.java new file mode 100644 index 0000000..dda205a --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/Packet108EnchantItem.java @@ -0,0 +1,45 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet108EnchantItem extends Packet { + public int windowId; + + /** + * The position of the enchantment on the enchantment table window, starting + * with 0 as the topmost one. + */ + public int enchantment; + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleEnchantItem(this); + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.windowId = par1DataInputStream.readByte(); + this.enchantment = par1DataInputStream.readByte(); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeByte(this.windowId); + par1DataOutputStream.writeByte(this.enchantment); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 2; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/Packet10Flying.java b/sp-server/src/main/java/net/minecraft/src/Packet10Flying.java new file mode 100644 index 0000000..2686114 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/Packet10Flying.java @@ -0,0 +1,77 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet10Flying extends Packet { + /** The player's X position. */ + public double xPosition; + + /** The player's Y position. */ + public double yPosition; + + /** The player's Z position. */ + public double zPosition; + + /** The player's stance. (boundingBox.minY) */ + public double stance; + + /** The player's yaw rotation. */ + public float yaw; + + /** The player's pitch rotation. */ + public float pitch; + + /** True if the client is on the ground. */ + public boolean onGround; + + /** Boolean set to true if the player is moving. */ + public boolean moving; + + /** Boolean set to true if the player is rotating. */ + public boolean rotating; + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleFlying(this); + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.onGround = par1DataInputStream.read() != 0; + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.write(this.onGround ? 1 : 0); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 1; + } + + /** + * only false for the abstract Packet class, all real packets return true + */ + public boolean isRealPacket() { + return true; + } + + /** + * eg return packet30entity.entityId == entityId; WARNING : will throw if you + * compare a packet to a different packet class + */ + public boolean containsSameEntityIDAs(Packet par1Packet) { + return true; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/Packet11PlayerPosition.java b/sp-server/src/main/java/net/minecraft/src/Packet11PlayerPosition.java new file mode 100644 index 0000000..85fca69 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/Packet11PlayerPosition.java @@ -0,0 +1,40 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet11PlayerPosition extends Packet10Flying { + public Packet11PlayerPosition() { + this.moving = true; + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.xPosition = par1DataInputStream.readDouble(); + this.yPosition = par1DataInputStream.readDouble(); + this.stance = par1DataInputStream.readDouble(); + this.zPosition = par1DataInputStream.readDouble(); + super.readPacketData(par1DataInputStream); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeDouble(this.xPosition); + par1DataOutputStream.writeDouble(this.yPosition); + par1DataOutputStream.writeDouble(this.stance); + par1DataOutputStream.writeDouble(this.zPosition); + super.writePacketData(par1DataOutputStream); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 33; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/Packet12PlayerLook.java b/sp-server/src/main/java/net/minecraft/src/Packet12PlayerLook.java new file mode 100644 index 0000000..1bb4a78 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/Packet12PlayerLook.java @@ -0,0 +1,36 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet12PlayerLook extends Packet10Flying { + public Packet12PlayerLook() { + this.rotating = true; + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.yaw = par1DataInputStream.readFloat(); + this.pitch = par1DataInputStream.readFloat(); + super.readPacketData(par1DataInputStream); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeFloat(this.yaw); + par1DataOutputStream.writeFloat(this.pitch); + super.writePacketData(par1DataOutputStream); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 9; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/Packet130UpdateSign.java b/sp-server/src/main/java/net/minecraft/src/Packet130UpdateSign.java new file mode 100644 index 0000000..0386b38 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/Packet130UpdateSign.java @@ -0,0 +1,71 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet130UpdateSign extends Packet { + public int xPosition; + public int yPosition; + public int zPosition; + public String[] signLines; + + public Packet130UpdateSign() { + this.isChunkDataPacket = true; + } + + public Packet130UpdateSign(int par1, int par2, int par3, String[] par4ArrayOfStr) { + this.isChunkDataPacket = true; + this.xPosition = par1; + this.yPosition = par2; + this.zPosition = par3; + this.signLines = new String[] { par4ArrayOfStr[0], par4ArrayOfStr[1], par4ArrayOfStr[2], par4ArrayOfStr[3] }; + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.xPosition = par1DataInputStream.readInt(); + this.yPosition = par1DataInputStream.readShort(); + this.zPosition = par1DataInputStream.readInt(); + this.signLines = new String[4]; + + for (int var2 = 0; var2 < 4; ++var2) { + this.signLines[var2] = readString(par1DataInputStream, 15); + } + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeInt(this.xPosition); + par1DataOutputStream.writeShort(this.yPosition); + par1DataOutputStream.writeInt(this.zPosition); + + for (int var2 = 0; var2 < 4; ++var2) { + writeString(this.signLines[var2], par1DataOutputStream); + } + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleUpdateSign(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + int var1 = 0; + + for (int var2 = 0; var2 < 4; ++var2) { + var1 += this.signLines[var2].length(); + } + + return var1; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/Packet131MapData.java b/sp-server/src/main/java/net/minecraft/src/Packet131MapData.java new file mode 100644 index 0000000..d246801 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/Packet131MapData.java @@ -0,0 +1,65 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet131MapData extends Packet { + public short itemID; + + /** + * Contains a unique ID for the item that this packet will be populating. + */ + public short uniqueID; + + /** + * Contains a buffer of arbitrary data with which to populate an individual item + * in the world. + */ + public byte[] itemData; + + public Packet131MapData() { + this.isChunkDataPacket = true; + } + + public Packet131MapData(short par1, short par2, byte[] par3ArrayOfByte) { + this.isChunkDataPacket = true; + this.itemID = par1; + this.uniqueID = par2; + this.itemData = par3ArrayOfByte; + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.itemID = par1DataInputStream.readShort(); + this.uniqueID = par1DataInputStream.readShort(); + this.itemData = new byte[par1DataInputStream.readUnsignedShort()]; + par1DataInputStream.readFully(this.itemData); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeShort(this.itemID); + par1DataOutputStream.writeShort(this.uniqueID); + par1DataOutputStream.writeShort(this.itemData.length); + par1DataOutputStream.write(this.itemData); + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleMapData(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 4 + this.itemData.length; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/Packet132TileEntityData.java b/sp-server/src/main/java/net/minecraft/src/Packet132TileEntityData.java new file mode 100644 index 0000000..6cc9726 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/Packet132TileEntityData.java @@ -0,0 +1,71 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet132TileEntityData extends Packet { + /** The X position of the tile entity to update. */ + public int xPosition; + + /** The Y position of the tile entity to update. */ + public int yPosition; + + /** The Z position of the tile entity to update. */ + public int zPosition; + + /** The type of update to perform on the tile entity. */ + public int actionType; + + /** Custom parameter 1 passed to the tile entity on update. */ + public NBTTagCompound customParam1; + + public Packet132TileEntityData() { + this.isChunkDataPacket = true; + } + + public Packet132TileEntityData(int par1, int par2, int par3, int par4, NBTTagCompound par5NBTTagCompound) { + this.isChunkDataPacket = true; + this.xPosition = par1; + this.yPosition = par2; + this.zPosition = par3; + this.actionType = par4; + this.customParam1 = par5NBTTagCompound; + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.xPosition = par1DataInputStream.readInt(); + this.yPosition = par1DataInputStream.readShort(); + this.zPosition = par1DataInputStream.readInt(); + this.actionType = par1DataInputStream.readByte(); + this.customParam1 = readNBTTagCompound(par1DataInputStream); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeInt(this.xPosition); + par1DataOutputStream.writeShort(this.yPosition); + par1DataOutputStream.writeInt(this.zPosition); + par1DataOutputStream.writeByte((byte) this.actionType); + writeNBTTagCompound(this.customParam1, par1DataOutputStream); + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleTileEntityData(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 25; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/Packet13PlayerLookMove.java b/sp-server/src/main/java/net/minecraft/src/Packet13PlayerLookMove.java new file mode 100644 index 0000000..edff4d2 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/Packet13PlayerLookMove.java @@ -0,0 +1,58 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet13PlayerLookMove extends Packet10Flying { + public Packet13PlayerLookMove() { + this.rotating = true; + this.moving = true; + } + + public Packet13PlayerLookMove(double par1, double par3, double par5, double par7, float par9, float par10, + boolean par11) { + this.xPosition = par1; + this.yPosition = par3; + this.stance = par5; + this.zPosition = par7; + this.yaw = par9; + this.pitch = par10; + this.onGround = par11; + this.rotating = true; + this.moving = true; + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.xPosition = par1DataInputStream.readDouble(); + this.yPosition = par1DataInputStream.readDouble(); + this.stance = par1DataInputStream.readDouble(); + this.zPosition = par1DataInputStream.readDouble(); + this.yaw = par1DataInputStream.readFloat(); + this.pitch = par1DataInputStream.readFloat(); + super.readPacketData(par1DataInputStream); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeDouble(this.xPosition); + par1DataOutputStream.writeDouble(this.yPosition); + par1DataOutputStream.writeDouble(this.stance); + par1DataOutputStream.writeDouble(this.zPosition); + par1DataOutputStream.writeFloat(this.yaw); + par1DataOutputStream.writeFloat(this.pitch); + super.writePacketData(par1DataOutputStream); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 41; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/Packet14BlockDig.java b/sp-server/src/main/java/net/minecraft/src/Packet14BlockDig.java new file mode 100644 index 0000000..16b4548 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/Packet14BlockDig.java @@ -0,0 +1,58 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet14BlockDig extends Packet { + /** Block X position. */ + public int xPosition; + + /** Block Y position. */ + public int yPosition; + + /** Block Z position. */ + public int zPosition; + + /** Punched face of the block. */ + public int face; + + /** Status of the digging (started, ongoing, broken). */ + public int status; + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.status = par1DataInputStream.read(); + this.xPosition = par1DataInputStream.readInt(); + this.yPosition = par1DataInputStream.read(); + this.zPosition = par1DataInputStream.readInt(); + this.face = par1DataInputStream.read(); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.write(this.status); + par1DataOutputStream.writeInt(this.xPosition); + par1DataOutputStream.write(this.yPosition); + par1DataOutputStream.writeInt(this.zPosition); + par1DataOutputStream.write(this.face); + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleBlockDig(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 11; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/Packet15Place.java b/sp-server/src/main/java/net/minecraft/src/Packet15Place.java new file mode 100644 index 0000000..507bad0 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/Packet15Place.java @@ -0,0 +1,107 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet15Place extends Packet { + private int xPosition; + private int yPosition; + private int zPosition; + + /** The offset to use for block/item placement. */ + private int direction; + private ItemStack itemStack; + + /** The offset from xPosition where the actual click took place */ + private float xOffset; + + /** The offset from yPosition where the actual click took place */ + private float yOffset; + + /** The offset from zPosition where the actual click took place */ + private float zOffset; + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.xPosition = par1DataInputStream.readInt(); + this.yPosition = par1DataInputStream.read(); + this.zPosition = par1DataInputStream.readInt(); + this.direction = par1DataInputStream.read(); + this.itemStack = readItemStack(par1DataInputStream); + this.xOffset = (float) par1DataInputStream.read() / 16.0F; + this.yOffset = (float) par1DataInputStream.read() / 16.0F; + this.zOffset = (float) par1DataInputStream.read() / 16.0F; + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeInt(this.xPosition); + par1DataOutputStream.write(this.yPosition); + par1DataOutputStream.writeInt(this.zPosition); + par1DataOutputStream.write(this.direction); + writeItemStack(this.itemStack, par1DataOutputStream); + par1DataOutputStream.write((int) (this.xOffset * 16.0F)); + par1DataOutputStream.write((int) (this.yOffset * 16.0F)); + par1DataOutputStream.write((int) (this.zOffset * 16.0F)); + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handlePlace(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 19; + } + + public int getXPosition() { + return this.xPosition; + } + + public int getYPosition() { + return this.yPosition; + } + + public int getZPosition() { + return this.zPosition; + } + + public int getDirection() { + return this.direction; + } + + public ItemStack getItemStack() { + return this.itemStack; + } + + /** + * Returns the offset from xPosition where the actual click took place + */ + public float getXOffset() { + return this.xOffset; + } + + /** + * Returns the offset from yPosition where the actual click took place + */ + public float getYOffset() { + return this.yOffset; + } + + /** + * Returns the offset from zPosition where the actual click took place + */ + public float getZOffset() { + return this.zOffset; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/Packet16BlockItemSwitch.java b/sp-server/src/main/java/net/minecraft/src/Packet16BlockItemSwitch.java new file mode 100644 index 0000000..39d1aa6 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/Packet16BlockItemSwitch.java @@ -0,0 +1,60 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet16BlockItemSwitch extends Packet { + /** The block/item id to be equipped. */ + public int id; + + public Packet16BlockItemSwitch() { + } + + public Packet16BlockItemSwitch(int par1) { + this.id = par1; + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.id = par1DataInputStream.readShort(); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeShort(this.id); + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleBlockItemSwitch(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 2; + } + + /** + * only false for the abstract Packet class, all real packets return true + */ + public boolean isRealPacket() { + return true; + } + + /** + * eg return packet30entity.entityId == entityId; WARNING : will throw if you + * compare a packet to a different packet class + */ + public boolean containsSameEntityIDAs(Packet par1Packet) { + return true; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/Packet17Sleep.java b/sp-server/src/main/java/net/minecraft/src/Packet17Sleep.java new file mode 100644 index 0000000..c619fa3 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/Packet17Sleep.java @@ -0,0 +1,60 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet17Sleep extends Packet { + public int entityID; + public int bedX; + public int bedY; + public int bedZ; + public int field_73622_e; + + public Packet17Sleep() { + } + + public Packet17Sleep(Entity par1Entity, int par2, int par3, int par4, int par5) { + this.field_73622_e = par2; + this.bedX = par3; + this.bedY = par4; + this.bedZ = par5; + this.entityID = par1Entity.entityId; + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.entityID = par1DataInputStream.readInt(); + this.field_73622_e = par1DataInputStream.readByte(); + this.bedX = par1DataInputStream.readInt(); + this.bedY = par1DataInputStream.readByte(); + this.bedZ = par1DataInputStream.readInt(); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeInt(this.entityID); + par1DataOutputStream.writeByte(this.field_73622_e); + par1DataOutputStream.writeInt(this.bedX); + par1DataOutputStream.writeByte(this.bedY); + par1DataOutputStream.writeInt(this.bedZ); + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleSleep(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 14; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/Packet18Animation.java b/sp-server/src/main/java/net/minecraft/src/Packet18Animation.java new file mode 100644 index 0000000..4221a4d --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/Packet18Animation.java @@ -0,0 +1,49 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet18Animation extends Packet { + /** The entity ID, in this case it's the player ID. */ + public int entityId; + public int animate; + + public Packet18Animation() { + } + + public Packet18Animation(Entity par1Entity, int par2) { + this.entityId = par1Entity.entityId; + this.animate = par2; + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.entityId = par1DataInputStream.readInt(); + this.animate = par1DataInputStream.readByte(); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeInt(this.entityId); + par1DataOutputStream.writeByte(this.animate); + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleAnimation(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 5; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/Packet19EntityAction.java b/sp-server/src/main/java/net/minecraft/src/Packet19EntityAction.java new file mode 100644 index 0000000..66ecfaa --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/Packet19EntityAction.java @@ -0,0 +1,43 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet19EntityAction extends Packet { + /** Player ID. */ + public int entityId; + + /** 1=sneak, 2=normal */ + public int state; + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.entityId = par1DataInputStream.readInt(); + this.state = par1DataInputStream.readByte(); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeInt(this.entityId); + par1DataOutputStream.writeByte(this.state); + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleEntityAction(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 5; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/Packet1Login.java b/sp-server/src/main/java/net/minecraft/src/Packet1Login.java new file mode 100644 index 0000000..2b8f4ae --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/Packet1Login.java @@ -0,0 +1,101 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet1Login extends Packet { + /** The player's entity ID */ + public int clientEntityId = 0; + public WorldType terrainType; + public boolean hardcoreMode; + public EnumGameType gameType; + + /** -1: The Nether, 0: The Overworld, 1: The End */ + public int dimension; + + /** The difficulty setting byte. */ + public byte difficultySetting; + + /** Defaults to 128 */ + public byte worldHeight; + + /** The maximum players. */ + public byte maxPlayers; + + public Packet1Login() { + } + + public Packet1Login(int par1, WorldType par2WorldType, EnumGameType par3EnumGameType, boolean par4, int par5, + int par6, int par7, int par8) { + this.clientEntityId = par1; + this.terrainType = par2WorldType; + this.dimension = par5; + this.difficultySetting = (byte) par6; + this.gameType = par3EnumGameType; + this.worldHeight = (byte) par7; + this.maxPlayers = (byte) par8; + this.hardcoreMode = par4; + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.clientEntityId = par1DataInputStream.readInt(); + String var2 = readString(par1DataInputStream, 16); + this.terrainType = WorldType.parseWorldType(var2); + + if (this.terrainType == null) { + this.terrainType = WorldType.DEFAULT; + } + + byte var3 = par1DataInputStream.readByte(); + this.hardcoreMode = (var3 & 8) == 8; + int var4 = var3 & -9; + this.gameType = EnumGameType.getByID(var4); + this.dimension = par1DataInputStream.readByte(); + this.difficultySetting = par1DataInputStream.readByte(); + this.worldHeight = par1DataInputStream.readByte(); + this.maxPlayers = par1DataInputStream.readByte(); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeInt(this.clientEntityId); + writeString(this.terrainType == null ? "" : this.terrainType.getWorldTypeName(), par1DataOutputStream); + int var2 = this.gameType.getID(); + + if (this.hardcoreMode) { + var2 |= 8; + } + + par1DataOutputStream.writeByte(var2); + par1DataOutputStream.writeByte(this.dimension); + par1DataOutputStream.writeByte(this.difficultySetting); + par1DataOutputStream.writeByte(this.worldHeight); + par1DataOutputStream.writeByte(this.maxPlayers); + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleLogin(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + int var1 = 0; + + if (this.terrainType != null) { + var1 = this.terrainType.getWorldTypeName().length(); + } + + return 6 + 2 * var1 + 4 + 4 + 1 + 1 + 1; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/Packet200Statistic.java b/sp-server/src/main/java/net/minecraft/src/Packet200Statistic.java new file mode 100644 index 0000000..a8294b8 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/Packet200Statistic.java @@ -0,0 +1,56 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet200Statistic extends Packet { + public int statisticId; + public int amount; + + public Packet200Statistic() { + } + + public Packet200Statistic(int par1, int par2) { + this.statisticId = par1; + this.amount = par2; + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleStatistic(this); + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.statisticId = par1DataInputStream.readInt(); + this.amount = par1DataInputStream.readByte(); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeInt(this.statisticId); + par1DataOutputStream.writeByte(this.amount); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 6; + } + + /** + * If this returns true, the packet may be processed on any thread; otherwise it + * is queued for the main thread to handle. + */ + public boolean canProcessAsync() { + return true; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/Packet201PlayerInfo.java b/sp-server/src/main/java/net/minecraft/src/Packet201PlayerInfo.java new file mode 100644 index 0000000..052614f --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/Packet201PlayerInfo.java @@ -0,0 +1,55 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet201PlayerInfo extends Packet { + /** The player's name. */ + public String playerName; + + /** Byte that tells whether the player is connected. */ + public boolean isConnected; + public int ping; + + public Packet201PlayerInfo() { + } + + public Packet201PlayerInfo(String par1Str, boolean par2, int par3) { + this.playerName = par1Str; + this.isConnected = par2; + this.ping = par3; + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.playerName = readString(par1DataInputStream, 16); + this.isConnected = par1DataInputStream.readByte() != 0; + this.ping = par1DataInputStream.readShort(); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + writeString(this.playerName, par1DataOutputStream); + par1DataOutputStream.writeByte(this.isConnected ? 1 : 0); + par1DataOutputStream.writeShort(this.ping); + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handlePlayerInfo(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return this.playerName.length() + 2 + 1 + 2; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/Packet202PlayerAbilities.java b/sp-server/src/main/java/net/minecraft/src/Packet202PlayerAbilities.java new file mode 100644 index 0000000..b604bcb --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/Packet202PlayerAbilities.java @@ -0,0 +1,157 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet202PlayerAbilities extends Packet { + /** Disables player damage. */ + private boolean disableDamage = false; + + /** Indicates whether the player is flying or not. */ + private boolean isFlying = false; + + /** Whether or not to allow the player to fly when they double jump. */ + private boolean allowFlying = false; + + /** + * Used to determine if creative mode is enabled, and therefore if items should + * be depleted on usage + */ + private boolean isCreativeMode = false; + private float flySpeed; + private float walkSpeed; + + public Packet202PlayerAbilities() { + } + + public Packet202PlayerAbilities(PlayerCapabilities par1PlayerCapabilities) { + this.setDisableDamage(par1PlayerCapabilities.disableDamage); + this.setFlying(par1PlayerCapabilities.isFlying); + this.setAllowFlying(par1PlayerCapabilities.allowFlying); + this.setCreativeMode(par1PlayerCapabilities.isCreativeMode); + this.setFlySpeed(par1PlayerCapabilities.getFlySpeed()); + this.setWalkSpeed(par1PlayerCapabilities.getWalkSpeed()); + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + byte var2 = par1DataInputStream.readByte(); + this.setDisableDamage((var2 & 1) > 0); + this.setFlying((var2 & 2) > 0); + this.setAllowFlying((var2 & 4) > 0); + this.setCreativeMode((var2 & 8) > 0); + this.setFlySpeed((float) par1DataInputStream.readByte() / 255.0F); + this.setWalkSpeed((float) par1DataInputStream.readByte() / 255.0F); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + byte var2 = 0; + + if (this.getDisableDamage()) { + var2 = (byte) (var2 | 1); + } + + if (this.getFlying()) { + var2 = (byte) (var2 | 2); + } + + if (this.getAllowFlying()) { + var2 = (byte) (var2 | 4); + } + + if (this.isCreativeMode()) { + var2 = (byte) (var2 | 8); + } + + par1DataOutputStream.writeByte(var2); + par1DataOutputStream.writeByte((int) (this.flySpeed * 255.0F)); + par1DataOutputStream.writeByte((int) (this.walkSpeed * 255.0F)); + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handlePlayerAbilities(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 2; + } + + public boolean getDisableDamage() { + return this.disableDamage; + } + + /** + * Sets whether damage is disabled or not. + */ + public void setDisableDamage(boolean par1) { + this.disableDamage = par1; + } + + public boolean getFlying() { + return this.isFlying; + } + + /** + * Sets whether we're currently flying or not. + */ + public void setFlying(boolean par1) { + this.isFlying = par1; + } + + public boolean getAllowFlying() { + return this.allowFlying; + } + + public void setAllowFlying(boolean par1) { + this.allowFlying = par1; + } + + public boolean isCreativeMode() { + return this.isCreativeMode; + } + + public void setCreativeMode(boolean par1) { + this.isCreativeMode = par1; + } + + /** + * Sets the flying speed. + */ + public void setFlySpeed(float par1) { + this.flySpeed = par1; + } + + /** + * Sets the walking speed. + */ + public void setWalkSpeed(float par1) { + this.walkSpeed = par1; + } + + /** + * only false for the abstract Packet class, all real packets return true + */ + public boolean isRealPacket() { + return true; + } + + /** + * eg return packet30entity.entityId == entityId; WARNING : will throw if you + * compare a packet to a different packet class + */ + public boolean containsSameEntityIDAs(Packet par1Packet) { + return true; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/Packet203AutoComplete.java b/sp-server/src/main/java/net/minecraft/src/Packet203AutoComplete.java new file mode 100644 index 0000000..24a3b11 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/Packet203AutoComplete.java @@ -0,0 +1,67 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet203AutoComplete extends Packet { + /** + * Sent by the client containing the text to be autocompleted. Sent by the + * server with possible completions separated by null (two bytes in UTF-16) + */ + private String text; + + public Packet203AutoComplete() { + } + + public Packet203AutoComplete(String par1Str) { + this.text = par1Str; + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.text = readString(par1DataInputStream, Packet3Chat.maxChatLength); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + writeString(this.text, par1DataOutputStream); + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleAutoComplete(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 2 + this.text.length() * 2; + } + + public String getText() { + return this.text; + } + + /** + * only false for the abstract Packet class, all real packets return true + */ + public boolean isRealPacket() { + return true; + } + + /** + * eg return packet30entity.entityId == entityId; WARNING : will throw if you + * compare a packet to a different packet class + */ + public boolean containsSameEntityIDAs(Packet par1Packet) { + return true; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/Packet204ClientInfo.java b/sp-server/src/main/java/net/minecraft/src/Packet204ClientInfo.java new file mode 100644 index 0000000..ecdbb85 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/Packet204ClientInfo.java @@ -0,0 +1,91 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet204ClientInfo extends Packet { + private String language; + private int renderDistance; + private int chatVisisble; + private boolean chatColours; + private int gameDifficulty; + private boolean showCape; + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.language = readString(par1DataInputStream, 7); + this.renderDistance = par1DataInputStream.readByte(); + byte var2 = par1DataInputStream.readByte(); + this.chatVisisble = var2 & 7; + this.chatColours = (var2 & 8) == 8; + this.gameDifficulty = par1DataInputStream.readByte(); + this.showCape = par1DataInputStream.readBoolean(); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + writeString(this.language, par1DataOutputStream); + par1DataOutputStream.writeByte(this.renderDistance); + par1DataOutputStream.writeByte(this.chatVisisble | (this.chatColours ? 1 : 0) << 3); + par1DataOutputStream.writeByte(this.gameDifficulty); + par1DataOutputStream.writeBoolean(this.showCape); + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleClientInfo(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 7; + } + + public String getLanguage() { + return this.language; + } + + public int getRenderDistance() { + return this.renderDistance; + } + + public int getChatVisibility() { + return this.chatVisisble; + } + + public boolean getChatColours() { + return this.chatColours; + } + + public int getDifficulty() { + return this.gameDifficulty; + } + + public boolean getShowCape() { + return this.showCape; + } + + /** + * only false for the abstract Packet class, all real packets return true + */ + public boolean isRealPacket() { + return true; + } + + /** + * eg return packet30entity.entityId == entityId; WARNING : will throw if you + * compare a packet to a different packet class + */ + public boolean containsSameEntityIDAs(Packet par1Packet) { + return true; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/Packet205ClientCommand.java b/sp-server/src/main/java/net/minecraft/src/Packet205ClientCommand.java new file mode 100644 index 0000000..1b2fd7e --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/Packet205ClientCommand.java @@ -0,0 +1,41 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet205ClientCommand extends Packet { + /** + * 0 sent to a netLoginHandler starts the server, 1 sent to NetServerHandler + * forces a respawn + */ + public int forceRespawn; + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.forceRespawn = par1DataInputStream.readByte(); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeByte(this.forceRespawn & 255); + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleClientCommand(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 1; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/Packet206SetObjective.java b/sp-server/src/main/java/net/minecraft/src/Packet206SetObjective.java new file mode 100644 index 0000000..33c9b0d --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/Packet206SetObjective.java @@ -0,0 +1,56 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet206SetObjective extends Packet { + public String objectiveName; + public String objectiveDisplayName; + + /** + * 0 to create scoreboard, 1 to remove scoreboard, 2 to update display text. + */ + public int change; + + public Packet206SetObjective() { + } + + public Packet206SetObjective(ScoreObjective par1, int par2) { + this.objectiveName = par1.getName(); + this.objectiveDisplayName = par1.getDisplayName(); + this.change = par2; + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.objectiveName = readString(par1DataInputStream, 16); + this.objectiveDisplayName = readString(par1DataInputStream, 32); + this.change = par1DataInputStream.readByte(); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + writeString(this.objectiveName, par1DataOutputStream); + writeString(this.objectiveDisplayName, par1DataOutputStream); + par1DataOutputStream.writeByte(this.change); + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleSetObjective(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 2 + this.objectiveName.length() + 2 + this.objectiveDisplayName.length() + 1; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/Packet207SetScore.java b/sp-server/src/main/java/net/minecraft/src/Packet207SetScore.java new file mode 100644 index 0000000..455ec4c --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/Packet207SetScore.java @@ -0,0 +1,82 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet207SetScore extends Packet { + /** An unique name to be displayed in the list. */ + public String itemName = ""; + + /** + * The unique name for the scoreboard to be updated. Only sent when + * updateOrRemove does not equal 1. + */ + public String scoreName = ""; + + /** + * The score to be displayed next to the entry. Only sent when Update/Remove + * does not equal 1. + */ + public int value = 0; + + /** 0 to create/update an item. 1 to remove an item. */ + public int updateOrRemove = 0; + + public Packet207SetScore() { + } + + public Packet207SetScore(Score par1, int par2) { + this.itemName = par1.func_96653_e(); + this.scoreName = par1.func_96645_d().getName(); + this.value = par1.func_96652_c(); + this.updateOrRemove = par2; + } + + public Packet207SetScore(String par1) { + this.itemName = par1; + this.scoreName = ""; + this.value = 0; + this.updateOrRemove = 1; + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.itemName = readString(par1DataInputStream, 16); + this.updateOrRemove = par1DataInputStream.readByte(); + + if (this.updateOrRemove != 1) { + this.scoreName = readString(par1DataInputStream, 16); + this.value = par1DataInputStream.readInt(); + } + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + writeString(this.itemName, par1DataOutputStream); + par1DataOutputStream.writeByte(this.updateOrRemove); + + if (this.updateOrRemove != 1) { + writeString(this.scoreName, par1DataOutputStream); + par1DataOutputStream.writeInt(this.value); + } + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleSetScore(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 2 + this.itemName.length() + 2 + this.scoreName.length() + 4 + 1; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/Packet208SetDisplayObjective.java b/sp-server/src/main/java/net/minecraft/src/Packet208SetDisplayObjective.java new file mode 100644 index 0000000..fec57a1 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/Packet208SetDisplayObjective.java @@ -0,0 +1,56 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet208SetDisplayObjective extends Packet { + /** The position of the scoreboard. 0 = list, 1 = sidebar, 2 = belowName. */ + public int scoreboardPosition; + + /** The unique name for the scoreboard to be displayed. */ + public String scoreName; + + public Packet208SetDisplayObjective() { + } + + public Packet208SetDisplayObjective(int par1, ScoreObjective par2ScoreObjective) { + this.scoreboardPosition = par1; + + if (par2ScoreObjective == null) { + this.scoreName = ""; + } else { + this.scoreName = par2ScoreObjective.getName(); + } + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.scoreboardPosition = par1DataInputStream.readByte(); + this.scoreName = readString(par1DataInputStream, 16); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeByte(this.scoreboardPosition); + writeString(this.scoreName, par1DataOutputStream); + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleSetDisplayObjective(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 3 + this.scoreName.length(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/Packet209SetPlayerTeam.java b/sp-server/src/main/java/net/minecraft/src/Packet209SetPlayerTeam.java new file mode 100644 index 0000000..f8bdb3a --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/Packet209SetPlayerTeam.java @@ -0,0 +1,134 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; + +public class Packet209SetPlayerTeam extends Packet { + /** A unique name for the team. */ + public String teamName = ""; + + /** Only if mode = 0 or 2. */ + public String teamDisplayName = ""; + + /** + * Only if mode = 0 or 2. Displayed before the players' name that are part of + * this team. + */ + public String teamPrefix = ""; + + /** + * Only if mode = 0 or 2. Displayed after the players' name that are part of + * this team. + */ + public String teamSuffix = ""; + + /** Only if mode = 0 or 3 or 4. Players to be added/remove from the team. */ + public Collection playerNames = new ArrayList(); + + /** + * If 0 then the team is created. If 1 then the team is removed. If 2 the team + * team information is updated. If 3 then new players are added to the team. If + * 4 then players are removed from the team. + */ + public int mode = 0; + + /** Only if mode = 0 or 2. */ + public int friendlyFire; + + public Packet209SetPlayerTeam() { + } + + public Packet209SetPlayerTeam(ScorePlayerTeam par1, int par2) { + this.teamName = par1.func_96661_b(); + this.mode = par2; + + if (par2 == 0 || par2 == 2) { + this.teamDisplayName = par1.func_96669_c(); + this.teamPrefix = par1.func_96668_e(); + this.teamSuffix = par1.func_96663_f(); + this.friendlyFire = par1.func_98299_i(); + } + + if (par2 == 0) { + this.playerNames.addAll(par1.getMembershipCollection()); + } + } + + public Packet209SetPlayerTeam(ScorePlayerTeam par1ScorePlayerTeam, Collection par2Collection, int par3) { + if (par3 != 3 && par3 != 4) { + throw new IllegalArgumentException("Method must be join or leave for player constructor"); + } else if (par2Collection != null && !par2Collection.isEmpty()) { + this.mode = par3; + this.teamName = par1ScorePlayerTeam.func_96661_b(); + this.playerNames.addAll(par2Collection); + } else { + throw new IllegalArgumentException("Players cannot be null/empty"); + } + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.teamName = readString(par1DataInputStream, 16); + this.mode = par1DataInputStream.readByte(); + + if (this.mode == 0 || this.mode == 2) { + this.teamDisplayName = readString(par1DataInputStream, 32); + this.teamPrefix = readString(par1DataInputStream, 16); + this.teamSuffix = readString(par1DataInputStream, 16); + this.friendlyFire = par1DataInputStream.readByte(); + } + + if (this.mode == 0 || this.mode == 3 || this.mode == 4) { + short var2 = par1DataInputStream.readShort(); + + for (int var3 = 0; var3 < var2; ++var3) { + this.playerNames.add(readString(par1DataInputStream, 16)); + } + } + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + writeString(this.teamName, par1DataOutputStream); + par1DataOutputStream.writeByte(this.mode); + + if (this.mode == 0 || this.mode == 2) { + writeString(this.teamDisplayName, par1DataOutputStream); + writeString(this.teamPrefix, par1DataOutputStream); + writeString(this.teamSuffix, par1DataOutputStream); + par1DataOutputStream.writeByte(this.friendlyFire); + } + + if (this.mode == 0 || this.mode == 3 || this.mode == 4) { + par1DataOutputStream.writeShort(this.playerNames.size()); + Iterator var2 = this.playerNames.iterator(); + + while (var2.hasNext()) { + String var3 = (String) var2.next(); + writeString(var3, par1DataOutputStream); + } + } + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleSetPlayerTeam(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 3 + this.teamName.length(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/Packet20NamedEntitySpawn.java b/sp-server/src/main/java/net/minecraft/src/Packet20NamedEntitySpawn.java new file mode 100644 index 0000000..d2dc7f1 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/Packet20NamedEntitySpawn.java @@ -0,0 +1,94 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.util.List; + +public class Packet20NamedEntitySpawn extends Packet { + /** The entity ID, in this case it's the player ID. */ + public int entityId; + + /** The player's name. */ + public String name; + + /** The player's X position. */ + public int xPosition; + + /** The player's Y position. */ + public int yPosition; + + /** The player's Z position. */ + public int zPosition; + + /** The player's rotation. */ + public byte rotation; + + /** The player's pitch. */ + public byte pitch; + + /** The current item the player is holding. */ + public int currentItem; + private DataWatcher metadata; + private List metadataWatchableObjects; + + public Packet20NamedEntitySpawn() { + } + + public Packet20NamedEntitySpawn(EntityPlayer par1EntityPlayer) { + this.entityId = par1EntityPlayer.entityId; + this.name = par1EntityPlayer.username; + this.xPosition = MathHelper.floor_double(par1EntityPlayer.posX * 32.0D); + this.yPosition = MathHelper.floor_double(par1EntityPlayer.posY * 32.0D); + this.zPosition = MathHelper.floor_double(par1EntityPlayer.posZ * 32.0D); + this.rotation = (byte) ((int) (par1EntityPlayer.rotationYaw * 256.0F / 360.0F)); + this.pitch = (byte) ((int) (par1EntityPlayer.rotationPitch * 256.0F / 360.0F)); + ItemStack var2 = par1EntityPlayer.inventory.getCurrentItem(); + this.currentItem = var2 == null ? 0 : var2.itemID; + this.metadata = par1EntityPlayer.getDataWatcher(); + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.entityId = par1DataInputStream.readInt(); + this.name = readString(par1DataInputStream, 16); + this.xPosition = par1DataInputStream.readInt(); + this.yPosition = par1DataInputStream.readInt(); + this.zPosition = par1DataInputStream.readInt(); + this.rotation = par1DataInputStream.readByte(); + this.pitch = par1DataInputStream.readByte(); + this.currentItem = par1DataInputStream.readShort(); + this.metadataWatchableObjects = DataWatcher.readWatchableObjects(par1DataInputStream); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeInt(this.entityId); + writeString(this.name, par1DataOutputStream); + par1DataOutputStream.writeInt(this.xPosition); + par1DataOutputStream.writeInt(this.yPosition); + par1DataOutputStream.writeInt(this.zPosition); + par1DataOutputStream.writeByte(this.rotation); + par1DataOutputStream.writeByte(this.pitch); + par1DataOutputStream.writeShort(this.currentItem); + this.metadata.writeWatchableObjects(par1DataOutputStream); + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleNamedEntitySpawn(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 28; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/Packet22Collect.java b/sp-server/src/main/java/net/minecraft/src/Packet22Collect.java new file mode 100644 index 0000000..850711b --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/Packet22Collect.java @@ -0,0 +1,51 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet22Collect extends Packet { + /** The entity on the ground that was picked up. */ + public int collectedEntityId; + + /** The entity that picked up the one from the ground. */ + public int collectorEntityId; + + public Packet22Collect() { + } + + public Packet22Collect(int par1, int par2) { + this.collectedEntityId = par1; + this.collectorEntityId = par2; + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.collectedEntityId = par1DataInputStream.readInt(); + this.collectorEntityId = par1DataInputStream.readInt(); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeInt(this.collectedEntityId); + par1DataOutputStream.writeInt(this.collectorEntityId); + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleCollect(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 8; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/Packet23VehicleSpawn.java b/sp-server/src/main/java/net/minecraft/src/Packet23VehicleSpawn.java new file mode 100644 index 0000000..22946ae --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/Packet23VehicleSpawn.java @@ -0,0 +1,156 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet23VehicleSpawn extends Packet { + /** Entity ID of the object. */ + public int entityId; + + /** The X position of the object. */ + public int xPosition; + + /** The Y position of the object. */ + public int yPosition; + + /** The Z position of the object. */ + public int zPosition; + + /** + * Not sent if the thrower entity ID is 0. The speed of this fireball along the + * X axis. + */ + public int speedX; + + /** + * Not sent if the thrower entity ID is 0. The speed of this fireball along the + * Y axis. + */ + public int speedY; + + /** + * Not sent if the thrower entity ID is 0. The speed of this fireball along the + * Z axis. + */ + public int speedZ; + + /** The pitch in steps of 2p/256 */ + public int pitch; + + /** The yaw in steps of 2p/256 */ + public int yaw; + + /** The type of object. */ + public int type; + + /** 0 if not a fireball. Otherwise, this is the Entity ID of the thrower. */ + public int throwerEntityId; + + public Packet23VehicleSpawn() { + } + + public Packet23VehicleSpawn(Entity par1Entity, int par2) { + this(par1Entity, par2, 0); + } + + public Packet23VehicleSpawn(Entity par1Entity, int par2, int par3) { + this.entityId = par1Entity.entityId; + this.xPosition = MathHelper.floor_double(par1Entity.posX * 32.0D); + this.yPosition = MathHelper.floor_double(par1Entity.posY * 32.0D); + this.zPosition = MathHelper.floor_double(par1Entity.posZ * 32.0D); + this.pitch = MathHelper.floor_float(par1Entity.rotationPitch * 256.0F / 360.0F); + this.yaw = MathHelper.floor_float(par1Entity.rotationYaw * 256.0F / 360.0F); + this.type = par2; + this.throwerEntityId = par3; + + if (par3 > 0) { + double var4 = par1Entity.motionX; + double var6 = par1Entity.motionY; + double var8 = par1Entity.motionZ; + double var10 = 3.9D; + + if (var4 < -var10) { + var4 = -var10; + } + + if (var6 < -var10) { + var6 = -var10; + } + + if (var8 < -var10) { + var8 = -var10; + } + + if (var4 > var10) { + var4 = var10; + } + + if (var6 > var10) { + var6 = var10; + } + + if (var8 > var10) { + var8 = var10; + } + + this.speedX = (int) (var4 * 8000.0D); + this.speedY = (int) (var6 * 8000.0D); + this.speedZ = (int) (var8 * 8000.0D); + } + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.entityId = par1DataInputStream.readInt(); + this.type = par1DataInputStream.readByte(); + this.xPosition = par1DataInputStream.readInt(); + this.yPosition = par1DataInputStream.readInt(); + this.zPosition = par1DataInputStream.readInt(); + this.pitch = par1DataInputStream.readByte(); + this.yaw = par1DataInputStream.readByte(); + this.throwerEntityId = par1DataInputStream.readInt(); + + if (this.throwerEntityId > 0) { + this.speedX = par1DataInputStream.readShort(); + this.speedY = par1DataInputStream.readShort(); + this.speedZ = par1DataInputStream.readShort(); + } + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeInt(this.entityId); + par1DataOutputStream.writeByte(this.type); + par1DataOutputStream.writeInt(this.xPosition); + par1DataOutputStream.writeInt(this.yPosition); + par1DataOutputStream.writeInt(this.zPosition); + par1DataOutputStream.writeByte(this.pitch); + par1DataOutputStream.writeByte(this.yaw); + par1DataOutputStream.writeInt(this.throwerEntityId); + + if (this.throwerEntityId > 0) { + par1DataOutputStream.writeShort(this.speedX); + par1DataOutputStream.writeShort(this.speedY); + par1DataOutputStream.writeShort(this.speedZ); + } + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleVehicleSpawn(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 21 + this.throwerEntityId > 0 ? 6 : 0; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/Packet24MobSpawn.java b/sp-server/src/main/java/net/minecraft/src/Packet24MobSpawn.java new file mode 100644 index 0000000..35e430e --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/Packet24MobSpawn.java @@ -0,0 +1,136 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.util.List; + +public class Packet24MobSpawn extends Packet { + /** The entity ID. */ + public int entityId; + + /** The type of mob. */ + public int type; + + /** The X position of the entity. */ + public int xPosition; + + /** The Y position of the entity. */ + public int yPosition; + + /** The Z position of the entity. */ + public int zPosition; + public int velocityX; + public int velocityY; + public int velocityZ; + + /** The yaw of the entity. */ + public byte yaw; + + /** The pitch of the entity. */ + public byte pitch; + + /** The yaw of the entity's head. */ + public byte headYaw; + + /** Indexed metadata for Mob, terminated by 0x7F */ + private DataWatcher metaData; + private List metadata; + + public Packet24MobSpawn() { + } + + public Packet24MobSpawn(EntityLiving par1EntityLiving) { + this.entityId = par1EntityLiving.entityId; + this.type = (byte) EntityList.getEntityID(par1EntityLiving); + this.xPosition = par1EntityLiving.myEntitySize.multiplyBy32AndRound(par1EntityLiving.posX); + this.yPosition = MathHelper.floor_double(par1EntityLiving.posY * 32.0D); + this.zPosition = par1EntityLiving.myEntitySize.multiplyBy32AndRound(par1EntityLiving.posZ); + this.yaw = (byte) ((int) (par1EntityLiving.rotationYaw * 256.0F / 360.0F)); + this.pitch = (byte) ((int) (par1EntityLiving.rotationPitch * 256.0F / 360.0F)); + this.headYaw = (byte) ((int) (par1EntityLiving.rotationYawHead * 256.0F / 360.0F)); + double var2 = 3.9D; + double var4 = par1EntityLiving.motionX; + double var6 = par1EntityLiving.motionY; + double var8 = par1EntityLiving.motionZ; + + if (var4 < -var2) { + var4 = -var2; + } + + if (var6 < -var2) { + var6 = -var2; + } + + if (var8 < -var2) { + var8 = -var2; + } + + if (var4 > var2) { + var4 = var2; + } + + if (var6 > var2) { + var6 = var2; + } + + if (var8 > var2) { + var8 = var2; + } + + this.velocityX = (int) (var4 * 8000.0D); + this.velocityY = (int) (var6 * 8000.0D); + this.velocityZ = (int) (var8 * 8000.0D); + this.metaData = par1EntityLiving.getDataWatcher(); + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.entityId = par1DataInputStream.readInt(); + this.type = par1DataInputStream.readByte() & 255; + this.xPosition = par1DataInputStream.readInt(); + this.yPosition = par1DataInputStream.readInt(); + this.zPosition = par1DataInputStream.readInt(); + this.yaw = par1DataInputStream.readByte(); + this.pitch = par1DataInputStream.readByte(); + this.headYaw = par1DataInputStream.readByte(); + this.velocityX = par1DataInputStream.readShort(); + this.velocityY = par1DataInputStream.readShort(); + this.velocityZ = par1DataInputStream.readShort(); + this.metadata = DataWatcher.readWatchableObjects(par1DataInputStream); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeInt(this.entityId); + par1DataOutputStream.writeByte(this.type & 255); + par1DataOutputStream.writeInt(this.xPosition); + par1DataOutputStream.writeInt(this.yPosition); + par1DataOutputStream.writeInt(this.zPosition); + par1DataOutputStream.writeByte(this.yaw); + par1DataOutputStream.writeByte(this.pitch); + par1DataOutputStream.writeByte(this.headYaw); + par1DataOutputStream.writeShort(this.velocityX); + par1DataOutputStream.writeShort(this.velocityY); + par1DataOutputStream.writeShort(this.velocityZ); + this.metaData.writeWatchableObjects(par1DataOutputStream); + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleMobSpawn(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 26; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/Packet250CustomPayload.java b/sp-server/src/main/java/net/minecraft/src/Packet250CustomPayload.java new file mode 100644 index 0000000..4be3a8f --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/Packet250CustomPayload.java @@ -0,0 +1,71 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet250CustomPayload extends Packet { + /** Name of the 'channel' used to send data */ + public String channel; + + /** Length of the data to be read */ + public int length; + + /** Any data */ + public byte[] data; + + public Packet250CustomPayload() { + } + + public Packet250CustomPayload(String par1Str, byte[] par2ArrayOfByte) { + this.channel = par1Str; + this.data = par2ArrayOfByte; + + if (par2ArrayOfByte != null) { + this.length = par2ArrayOfByte.length; + + if (this.length > 32767) { + throw new IllegalArgumentException("Payload may not be larger than 32k"); + } + } + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.channel = readString(par1DataInputStream, 20); + this.length = par1DataInputStream.readShort(); + + if (this.length > 0 && this.length < 32767) { + this.data = new byte[this.length]; + par1DataInputStream.readFully(this.data); + } + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + writeString(this.channel, par1DataOutputStream); + par1DataOutputStream.writeShort((short) this.length); + + if (this.data != null) { + par1DataOutputStream.write(this.data); + } + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleCustomPayload(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 2 + this.channel.length() * 2 + 2 + this.length; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/Packet252SharedKey.java b/sp-server/src/main/java/net/minecraft/src/Packet252SharedKey.java new file mode 100644 index 0000000..f31672b --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/Packet252SharedKey.java @@ -0,0 +1,69 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.security.PrivateKey; +import javax.crypto.SecretKey; + +public class Packet252SharedKey extends Packet { + private byte[] sharedSecret = new byte[0]; + private byte[] verifyToken = new byte[0]; + + /** + * Secret AES key decrypted from sharedSecret via the server's private RSA key + */ + private SecretKey sharedKey; + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.sharedSecret = readBytesFromStream(par1DataInputStream); + this.verifyToken = readBytesFromStream(par1DataInputStream); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + writeByteArray(par1DataOutputStream, this.sharedSecret); + writeByteArray(par1DataOutputStream, this.verifyToken); + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleSharedKey(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 2 + this.sharedSecret.length + 2 + this.verifyToken.length; + } + + /** + * Return secretKey, decrypting it from the sharedSecret byte array if needed + */ + public SecretKey getSharedKey(PrivateKey par1PrivateKey) { + return par1PrivateKey == null ? this.sharedKey + : (this.sharedKey = CryptManager.decryptSharedKey(par1PrivateKey, this.sharedSecret)); + } + + /** + * Return the secret AES sharedKey (used by client only) + */ + public SecretKey getSharedKey() { + return this.getSharedKey((PrivateKey) null); + } + + /** + * Return verifyToken, decrypting it with the server's RSA private key + */ + public byte[] getVerifyToken(PrivateKey par1PrivateKey) { + return par1PrivateKey == null ? this.verifyToken : CryptManager.decryptData(par1PrivateKey, this.verifyToken); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/Packet253ServerAuthData.java b/sp-server/src/main/java/net/minecraft/src/Packet253ServerAuthData.java new file mode 100644 index 0000000..af44cb0 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/Packet253ServerAuthData.java @@ -0,0 +1,53 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.security.PublicKey; + +public class Packet253ServerAuthData extends Packet { + private String serverId; + private PublicKey publicKey; + private byte[] verifyToken = new byte[0]; + + public Packet253ServerAuthData() { + } + + public Packet253ServerAuthData(String par1Str, PublicKey par2PublicKey, byte[] par3ArrayOfByte) { + this.serverId = par1Str; + this.publicKey = par2PublicKey; + this.verifyToken = par3ArrayOfByte; + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.serverId = readString(par1DataInputStream, 20); + this.publicKey = CryptManager.decodePublicKey(readBytesFromStream(par1DataInputStream)); + this.verifyToken = readBytesFromStream(par1DataInputStream); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + writeString(this.serverId, par1DataOutputStream); + writeByteArray(par1DataOutputStream, this.publicKey.getEncoded()); + writeByteArray(par1DataOutputStream, this.verifyToken); + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleServerAuthData(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 2 + this.serverId.length() * 2 + 2 + this.publicKey.getEncoded().length + 2 + this.verifyToken.length; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/Packet254ServerPing.java b/sp-server/src/main/java/net/minecraft/src/Packet254ServerPing.java new file mode 100644 index 0000000..ec9268a --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/Packet254ServerPing.java @@ -0,0 +1,41 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet254ServerPing extends Packet { + /** Always 1, unless readByte threw an exception. */ + public int readSuccessfully = 0; + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + try { + this.readSuccessfully = par1DataInputStream.readByte(); + } catch (Throwable var3) { + this.readSuccessfully = 0; + } + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleServerPing(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 0; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/Packet255KickDisconnect.java b/sp-server/src/main/java/net/minecraft/src/Packet255KickDisconnect.java new file mode 100644 index 0000000..829e01d --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/Packet255KickDisconnect.java @@ -0,0 +1,60 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet255KickDisconnect extends Packet { + /** Displayed to the client when the connection terminates. */ + public String reason; + + public Packet255KickDisconnect() { + } + + public Packet255KickDisconnect(String par1Str) { + this.reason = par1Str; + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.reason = readString(par1DataInputStream, 256); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + writeString(this.reason, par1DataOutputStream); + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleKickDisconnect(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return this.reason.length(); + } + + /** + * only false for the abstract Packet class, all real packets return true + */ + public boolean isRealPacket() { + return true; + } + + /** + * eg return packet30entity.entityId == entityId; WARNING : will throw if you + * compare a packet to a different packet class + */ + public boolean containsSameEntityIDAs(Packet par1Packet) { + return true; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/Packet25EntityPainting.java b/sp-server/src/main/java/net/minecraft/src/Packet25EntityPainting.java new file mode 100644 index 0000000..d2e779d --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/Packet25EntityPainting.java @@ -0,0 +1,64 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet25EntityPainting extends Packet { + public int entityId; + public int xPosition; + public int yPosition; + public int zPosition; + public int direction; + public String title; + + public Packet25EntityPainting() { + } + + public Packet25EntityPainting(EntityPainting par1EntityPainting) { + this.entityId = par1EntityPainting.entityId; + this.xPosition = par1EntityPainting.xPosition; + this.yPosition = par1EntityPainting.yPosition; + this.zPosition = par1EntityPainting.zPosition; + this.direction = par1EntityPainting.hangingDirection; + this.title = par1EntityPainting.art.title; + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.entityId = par1DataInputStream.readInt(); + this.title = readString(par1DataInputStream, EnumArt.maxArtTitleLength); + this.xPosition = par1DataInputStream.readInt(); + this.yPosition = par1DataInputStream.readInt(); + this.zPosition = par1DataInputStream.readInt(); + this.direction = par1DataInputStream.readInt(); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeInt(this.entityId); + writeString(this.title, par1DataOutputStream); + par1DataOutputStream.writeInt(this.xPosition); + par1DataOutputStream.writeInt(this.yPosition); + par1DataOutputStream.writeInt(this.zPosition); + par1DataOutputStream.writeInt(this.direction); + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleEntityPainting(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 24; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/Packet26EntityExpOrb.java b/sp-server/src/main/java/net/minecraft/src/Packet26EntityExpOrb.java new file mode 100644 index 0000000..4686f7b --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/Packet26EntityExpOrb.java @@ -0,0 +1,63 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet26EntityExpOrb extends Packet { + /** Entity ID for the XP Orb */ + public int entityId; + public int posX; + public int posY; + public int posZ; + + /** The Orbs Experience points value. */ + public int xpValue; + + public Packet26EntityExpOrb() { + } + + public Packet26EntityExpOrb(EntityXPOrb par1EntityXPOrb) { + this.entityId = par1EntityXPOrb.entityId; + this.posX = MathHelper.floor_double(par1EntityXPOrb.posX * 32.0D); + this.posY = MathHelper.floor_double(par1EntityXPOrb.posY * 32.0D); + this.posZ = MathHelper.floor_double(par1EntityXPOrb.posZ * 32.0D); + this.xpValue = par1EntityXPOrb.getXpValue(); + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.entityId = par1DataInputStream.readInt(); + this.posX = par1DataInputStream.readInt(); + this.posY = par1DataInputStream.readInt(); + this.posZ = par1DataInputStream.readInt(); + this.xpValue = par1DataInputStream.readShort(); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeInt(this.entityId); + par1DataOutputStream.writeInt(this.posX); + par1DataOutputStream.writeInt(this.posY); + par1DataOutputStream.writeInt(this.posZ); + par1DataOutputStream.writeShort(this.xpValue); + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleEntityExpOrb(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 18; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/Packet28EntityVelocity.java b/sp-server/src/main/java/net/minecraft/src/Packet28EntityVelocity.java new file mode 100644 index 0000000..24a7153 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/Packet28EntityVelocity.java @@ -0,0 +1,102 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet28EntityVelocity extends Packet { + public int entityId; + public int motionX; + public int motionY; + public int motionZ; + + public Packet28EntityVelocity() { + } + + public Packet28EntityVelocity(Entity par1Entity) { + this(par1Entity.entityId, par1Entity.motionX, par1Entity.motionY, par1Entity.motionZ); + } + + public Packet28EntityVelocity(int par1, double par2, double par4, double par6) { + this.entityId = par1; + double var8 = 3.9D; + + if (par2 < -var8) { + par2 = -var8; + } + + if (par4 < -var8) { + par4 = -var8; + } + + if (par6 < -var8) { + par6 = -var8; + } + + if (par2 > var8) { + par2 = var8; + } + + if (par4 > var8) { + par4 = var8; + } + + if (par6 > var8) { + par6 = var8; + } + + this.motionX = (int) (par2 * 8000.0D); + this.motionY = (int) (par4 * 8000.0D); + this.motionZ = (int) (par6 * 8000.0D); + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.entityId = par1DataInputStream.readInt(); + this.motionX = par1DataInputStream.readShort(); + this.motionY = par1DataInputStream.readShort(); + this.motionZ = par1DataInputStream.readShort(); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeInt(this.entityId); + par1DataOutputStream.writeShort(this.motionX); + par1DataOutputStream.writeShort(this.motionY); + par1DataOutputStream.writeShort(this.motionZ); + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleEntityVelocity(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 10; + } + + /** + * only false for the abstract Packet class, all real packets return true + */ + public boolean isRealPacket() { + return true; + } + + /** + * eg return packet30entity.entityId == entityId; WARNING : will throw if you + * compare a packet to a different packet class + */ + public boolean containsSameEntityIDAs(Packet par1Packet) { + Packet28EntityVelocity var2 = (Packet28EntityVelocity) par1Packet; + return var2.entityId == this.entityId; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/Packet29DestroyEntity.java b/sp-server/src/main/java/net/minecraft/src/Packet29DestroyEntity.java new file mode 100644 index 0000000..ed8bea1 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/Packet29DestroyEntity.java @@ -0,0 +1,53 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet29DestroyEntity extends Packet { + /** ID of the entity to be destroyed on the client. */ + public int[] entityId; + + public Packet29DestroyEntity() { + } + + public Packet29DestroyEntity(int... par1ArrayOfInteger) { + this.entityId = par1ArrayOfInteger; + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.entityId = new int[par1DataInputStream.readByte()]; + + for (int var2 = 0; var2 < this.entityId.length; ++var2) { + this.entityId[var2] = par1DataInputStream.readInt(); + } + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeByte(this.entityId.length); + + for (int var2 = 0; var2 < this.entityId.length; ++var2) { + par1DataOutputStream.writeInt(this.entityId[var2]); + } + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleDestroyEntity(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 1 + this.entityId.length * 4; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/Packet2ClientProtocol.java b/sp-server/src/main/java/net/minecraft/src/Packet2ClientProtocol.java new file mode 100644 index 0000000..1639c37 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/Packet2ClientProtocol.java @@ -0,0 +1,60 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet2ClientProtocol extends Packet { + private int protocolVersion; + private String username; + private String serverHost; + private int serverPort; + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.protocolVersion = par1DataInputStream.readByte(); + this.username = readString(par1DataInputStream, 16); + this.serverHost = readString(par1DataInputStream, 255); + this.serverPort = par1DataInputStream.readInt(); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeByte(this.protocolVersion); + writeString(this.username, par1DataOutputStream); + writeString(this.serverHost, par1DataOutputStream); + par1DataOutputStream.writeInt(this.serverPort); + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleClientProtocol(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 3 + 2 * this.username.length(); + } + + /** + * Returns the protocol version. + */ + public int getProtocolVersion() { + return this.protocolVersion; + } + + /** + * Returns the username. + */ + public String getUsername() { + return this.username; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/Packet30Entity.java b/sp-server/src/main/java/net/minecraft/src/Packet30Entity.java new file mode 100644 index 0000000..ecd074c --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/Packet30Entity.java @@ -0,0 +1,83 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet30Entity extends Packet { + /** The ID of this entity. */ + public int entityId; + + /** The X axis relative movement. */ + public byte xPosition; + + /** The Y axis relative movement. */ + public byte yPosition; + + /** The Z axis relative movement. */ + public byte zPosition; + + /** The X axis rotation. */ + public byte yaw; + + /** The Y axis rotation. */ + public byte pitch; + + /** Boolean set to true if the entity is rotating. */ + public boolean rotating = false; + + public Packet30Entity() { + } + + public Packet30Entity(int par1) { + this.entityId = par1; + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.entityId = par1DataInputStream.readInt(); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeInt(this.entityId); + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleEntity(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 4; + } + + public String toString() { + return "Entity_" + super.toString(); + } + + /** + * only false for the abstract Packet class, all real packets return true + */ + public boolean isRealPacket() { + return true; + } + + /** + * eg return packet30entity.entityId == entityId; WARNING : will throw if you + * compare a packet to a different packet class + */ + public boolean containsSameEntityIDAs(Packet par1Packet) { + Packet30Entity var2 = (Packet30Entity) par1Packet; + return var2.entityId == this.entityId; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/Packet31RelEntityMove.java b/sp-server/src/main/java/net/minecraft/src/Packet31RelEntityMove.java new file mode 100644 index 0000000..d0199a6 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/Packet31RelEntityMove.java @@ -0,0 +1,44 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet31RelEntityMove extends Packet30Entity { + public Packet31RelEntityMove() { + } + + public Packet31RelEntityMove(int par1, byte par2, byte par3, byte par4) { + super(par1); + this.xPosition = par2; + this.yPosition = par3; + this.zPosition = par4; + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + super.readPacketData(par1DataInputStream); + this.xPosition = par1DataInputStream.readByte(); + this.yPosition = par1DataInputStream.readByte(); + this.zPosition = par1DataInputStream.readByte(); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + super.writePacketData(par1DataOutputStream); + par1DataOutputStream.writeByte(this.xPosition); + par1DataOutputStream.writeByte(this.yPosition); + par1DataOutputStream.writeByte(this.zPosition); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 7; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/Packet32EntityLook.java b/sp-server/src/main/java/net/minecraft/src/Packet32EntityLook.java new file mode 100644 index 0000000..3b4034e --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/Packet32EntityLook.java @@ -0,0 +1,43 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet32EntityLook extends Packet30Entity { + public Packet32EntityLook() { + this.rotating = true; + } + + public Packet32EntityLook(int par1, byte par2, byte par3) { + super(par1); + this.yaw = par2; + this.pitch = par3; + this.rotating = true; + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + super.readPacketData(par1DataInputStream); + this.yaw = par1DataInputStream.readByte(); + this.pitch = par1DataInputStream.readByte(); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + super.writePacketData(par1DataOutputStream); + par1DataOutputStream.writeByte(this.yaw); + par1DataOutputStream.writeByte(this.pitch); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 6; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/Packet33RelEntityMoveLook.java b/sp-server/src/main/java/net/minecraft/src/Packet33RelEntityMoveLook.java new file mode 100644 index 0000000..4af3007 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/Packet33RelEntityMoveLook.java @@ -0,0 +1,52 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet33RelEntityMoveLook extends Packet30Entity { + public Packet33RelEntityMoveLook() { + this.rotating = true; + } + + public Packet33RelEntityMoveLook(int par1, byte par2, byte par3, byte par4, byte par5, byte par6) { + super(par1); + this.xPosition = par2; + this.yPosition = par3; + this.zPosition = par4; + this.yaw = par5; + this.pitch = par6; + this.rotating = true; + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + super.readPacketData(par1DataInputStream); + this.xPosition = par1DataInputStream.readByte(); + this.yPosition = par1DataInputStream.readByte(); + this.zPosition = par1DataInputStream.readByte(); + this.yaw = par1DataInputStream.readByte(); + this.pitch = par1DataInputStream.readByte(); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + super.writePacketData(par1DataOutputStream); + par1DataOutputStream.writeByte(this.xPosition); + par1DataOutputStream.writeByte(this.yPosition); + par1DataOutputStream.writeByte(this.zPosition); + par1DataOutputStream.writeByte(this.yaw); + par1DataOutputStream.writeByte(this.pitch); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 9; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/Packet34EntityTeleport.java b/sp-server/src/main/java/net/minecraft/src/Packet34EntityTeleport.java new file mode 100644 index 0000000..1b58eaa --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/Packet34EntityTeleport.java @@ -0,0 +1,100 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet34EntityTeleport extends Packet { + /** ID of the entity. */ + public int entityId; + + /** X position of the entity. */ + public int xPosition; + + /** Y position of the entity. */ + public int yPosition; + + /** Z position of the entity. */ + public int zPosition; + + /** Yaw of the entity. */ + public byte yaw; + + /** Pitch of the entity. */ + public byte pitch; + + public Packet34EntityTeleport() { + } + + public Packet34EntityTeleport(Entity par1Entity) { + this.entityId = par1Entity.entityId; + this.xPosition = MathHelper.floor_double(par1Entity.posX * 32.0D); + this.yPosition = MathHelper.floor_double(par1Entity.posY * 32.0D); + this.zPosition = MathHelper.floor_double(par1Entity.posZ * 32.0D); + this.yaw = (byte) ((int) (par1Entity.rotationYaw * 256.0F / 360.0F)); + this.pitch = (byte) ((int) (par1Entity.rotationPitch * 256.0F / 360.0F)); + } + + public Packet34EntityTeleport(int par1, int par2, int par3, int par4, byte par5, byte par6) { + this.entityId = par1; + this.xPosition = par2; + this.yPosition = par3; + this.zPosition = par4; + this.yaw = par5; + this.pitch = par6; + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.entityId = par1DataInputStream.readInt(); + this.xPosition = par1DataInputStream.readInt(); + this.yPosition = par1DataInputStream.readInt(); + this.zPosition = par1DataInputStream.readInt(); + this.yaw = (byte) par1DataInputStream.read(); + this.pitch = (byte) par1DataInputStream.read(); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeInt(this.entityId); + par1DataOutputStream.writeInt(this.xPosition); + par1DataOutputStream.writeInt(this.yPosition); + par1DataOutputStream.writeInt(this.zPosition); + par1DataOutputStream.write(this.yaw); + par1DataOutputStream.write(this.pitch); + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleEntityTeleport(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 34; + } + + /** + * only false for the abstract Packet class, all real packets return true + */ + public boolean isRealPacket() { + return true; + } + + /** + * eg return packet30entity.entityId == entityId; WARNING : will throw if you + * compare a packet to a different packet class + */ + public boolean containsSameEntityIDAs(Packet par1Packet) { + Packet34EntityTeleport var2 = (Packet34EntityTeleport) par1Packet; + return var2.entityId == this.entityId; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/Packet35EntityHeadRotation.java b/sp-server/src/main/java/net/minecraft/src/Packet35EntityHeadRotation.java new file mode 100644 index 0000000..62962cc --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/Packet35EntityHeadRotation.java @@ -0,0 +1,72 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet35EntityHeadRotation extends Packet { + public int entityId; + public byte headRotationYaw; + + public Packet35EntityHeadRotation() { + } + + public Packet35EntityHeadRotation(int par1, byte par2) { + this.entityId = par1; + this.headRotationYaw = par2; + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.entityId = par1DataInputStream.readInt(); + this.headRotationYaw = par1DataInputStream.readByte(); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeInt(this.entityId); + par1DataOutputStream.writeByte(this.headRotationYaw); + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleEntityHeadRotation(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 5; + } + + /** + * only false for the abstract Packet class, all real packets return true + */ + public boolean isRealPacket() { + return true; + } + + /** + * eg return packet30entity.entityId == entityId; WARNING : will throw if you + * compare a packet to a different packet class + */ + public boolean containsSameEntityIDAs(Packet par1Packet) { + Packet35EntityHeadRotation var2 = (Packet35EntityHeadRotation) par1Packet; + return var2.entityId == this.entityId; + } + + /** + * If this returns true, the packet may be processed on any thread; otherwise it + * is queued for the main thread to handle. + */ + public boolean canProcessAsync() { + return true; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/Packet38EntityStatus.java b/sp-server/src/main/java/net/minecraft/src/Packet38EntityStatus.java new file mode 100644 index 0000000..f675fd7 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/Packet38EntityStatus.java @@ -0,0 +1,50 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet38EntityStatus extends Packet { + public int entityId; + + /** 2 for hurt, 3 for dead */ + public byte entityStatus; + + public Packet38EntityStatus() { + } + + public Packet38EntityStatus(int par1, byte par2) { + this.entityId = par1; + this.entityStatus = par2; + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.entityId = par1DataInputStream.readInt(); + this.entityStatus = par1DataInputStream.readByte(); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeInt(this.entityId); + par1DataOutputStream.writeByte(this.entityStatus); + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleEntityStatus(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 5; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/Packet39AttachEntity.java b/sp-server/src/main/java/net/minecraft/src/Packet39AttachEntity.java new file mode 100644 index 0000000..2b390d3 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/Packet39AttachEntity.java @@ -0,0 +1,64 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet39AttachEntity extends Packet { + public int entityId; + public int vehicleEntityId; + + public Packet39AttachEntity() { + } + + public Packet39AttachEntity(Entity par1Entity, Entity par2Entity) { + this.entityId = par1Entity.entityId; + this.vehicleEntityId = par2Entity != null ? par2Entity.entityId : -1; + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 8; + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.entityId = par1DataInputStream.readInt(); + this.vehicleEntityId = par1DataInputStream.readInt(); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeInt(this.entityId); + par1DataOutputStream.writeInt(this.vehicleEntityId); + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleAttachEntity(this); + } + + /** + * only false for the abstract Packet class, all real packets return true + */ + public boolean isRealPacket() { + return true; + } + + /** + * eg return packet30entity.entityId == entityId; WARNING : will throw if you + * compare a packet to a different packet class + */ + public boolean containsSameEntityIDAs(Packet par1Packet) { + Packet39AttachEntity var2 = (Packet39AttachEntity) par1Packet; + return var2.entityId == this.entityId; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/Packet3Chat.java b/sp-server/src/main/java/net/minecraft/src/Packet3Chat.java new file mode 100644 index 0000000..426b9ea --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/Packet3Chat.java @@ -0,0 +1,76 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet3Chat extends Packet { + /** Maximum number of characters allowed in chat string in each packet. */ + public static int maxChatLength = 119; + + /** The message being sent. */ + public String message; + private boolean isServer; + + public Packet3Chat() { + this.isServer = true; + } + + public Packet3Chat(String par1Str) { + this(par1Str, true); + } + + public Packet3Chat(String par1Str, boolean par2) { + this.isServer = true; + + if (par1Str.length() > maxChatLength) { + par1Str = par1Str.substring(0, maxChatLength); + } + + this.message = par1Str; + this.isServer = par2; + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.message = readString(par1DataInputStream, maxChatLength); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + writeString(this.message, par1DataOutputStream); + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleChat(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 2 + this.message.length() * 2; + } + + /** + * Get whether this is a server + */ + public boolean getIsServer() { + return this.isServer; + } + + /** + * If this returns true, the packet may be processed on any thread; otherwise it + * is queued for the main thread to handle. + */ + public boolean canProcessAsync() { + return !this.message.startsWith("/"); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/Packet40EntityMetadata.java b/sp-server/src/main/java/net/minecraft/src/Packet40EntityMetadata.java new file mode 100644 index 0000000..73e33d5 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/Packet40EntityMetadata.java @@ -0,0 +1,54 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.util.List; + +public class Packet40EntityMetadata extends Packet { + public int entityId; + private List metadata; + + public Packet40EntityMetadata() { + } + + public Packet40EntityMetadata(int par1, DataWatcher par2DataWatcher, boolean par3) { + this.entityId = par1; + + if (par3) { + this.metadata = par2DataWatcher.getAllWatched(); + } else { + this.metadata = par2DataWatcher.unwatchAndReturnAllWatched(); + } + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.entityId = par1DataInputStream.readInt(); + this.metadata = DataWatcher.readWatchableObjects(par1DataInputStream); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeInt(this.entityId); + DataWatcher.writeObjectsInListToStream(this.metadata, par1DataOutputStream); + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleEntityMetadata(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 5; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/Packet41EntityEffect.java b/sp-server/src/main/java/net/minecraft/src/Packet41EntityEffect.java new file mode 100644 index 0000000..0da5e0d --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/Packet41EntityEffect.java @@ -0,0 +1,79 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet41EntityEffect extends Packet { + public int entityId; + public byte effectId; + + /** The effect's amplifier. */ + public byte effectAmplifier; + public short duration; + + public Packet41EntityEffect() { + } + + public Packet41EntityEffect(int par1, PotionEffect par2PotionEffect) { + this.entityId = par1; + this.effectId = (byte) (par2PotionEffect.getPotionID() & 255); + this.effectAmplifier = (byte) (par2PotionEffect.getAmplifier() & 255); + + if (par2PotionEffect.getDuration() > 32767) { + this.duration = 32767; + } else { + this.duration = (short) par2PotionEffect.getDuration(); + } + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.entityId = par1DataInputStream.readInt(); + this.effectId = par1DataInputStream.readByte(); + this.effectAmplifier = par1DataInputStream.readByte(); + this.duration = par1DataInputStream.readShort(); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeInt(this.entityId); + par1DataOutputStream.writeByte(this.effectId); + par1DataOutputStream.writeByte(this.effectAmplifier); + par1DataOutputStream.writeShort(this.duration); + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleEntityEffect(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 8; + } + + /** + * only false for the abstract Packet class, all real packets return true + */ + public boolean isRealPacket() { + return true; + } + + /** + * eg return packet30entity.entityId == entityId; WARNING : will throw if you + * compare a packet to a different packet class + */ + public boolean containsSameEntityIDAs(Packet par1Packet) { + Packet41EntityEffect var2 = (Packet41EntityEffect) par1Packet; + return var2.entityId == this.entityId && var2.effectId == this.effectId; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/Packet42RemoveEntityEffect.java b/sp-server/src/main/java/net/minecraft/src/Packet42RemoveEntityEffect.java new file mode 100644 index 0000000..448f37e --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/Packet42RemoveEntityEffect.java @@ -0,0 +1,51 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet42RemoveEntityEffect extends Packet { + /** The ID of the entity which an effect is being removed from. */ + public int entityId; + + /** The ID of the effect which is being removed from an entity. */ + public byte effectId; + + public Packet42RemoveEntityEffect() { + } + + public Packet42RemoveEntityEffect(int par1, PotionEffect par2PotionEffect) { + this.entityId = par1; + this.effectId = (byte) (par2PotionEffect.getPotionID() & 255); + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.entityId = par1DataInputStream.readInt(); + this.effectId = par1DataInputStream.readByte(); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeInt(this.entityId); + par1DataOutputStream.writeByte(this.effectId); + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleRemoveEntityEffect(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 5; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/Packet43Experience.java b/sp-server/src/main/java/net/minecraft/src/Packet43Experience.java new file mode 100644 index 0000000..8fcc2da --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/Packet43Experience.java @@ -0,0 +1,72 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet43Experience extends Packet { + /** The current experience bar points. */ + public float experience; + + /** The total experience points. */ + public int experienceTotal; + + /** The experience level. */ + public int experienceLevel; + + public Packet43Experience() { + } + + public Packet43Experience(float par1, int par2, int par3) { + this.experience = par1; + this.experienceTotal = par2; + this.experienceLevel = par3; + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.experience = par1DataInputStream.readFloat(); + this.experienceLevel = par1DataInputStream.readShort(); + this.experienceTotal = par1DataInputStream.readShort(); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeFloat(this.experience); + par1DataOutputStream.writeShort(this.experienceLevel); + par1DataOutputStream.writeShort(this.experienceTotal); + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleExperience(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 4; + } + + /** + * only false for the abstract Packet class, all real packets return true + */ + public boolean isRealPacket() { + return true; + } + + /** + * eg return packet30entity.entityId == entityId; WARNING : will throw if you + * compare a packet to a different packet class + */ + public boolean containsSameEntityIDAs(Packet par1Packet) { + return true; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/Packet4UpdateTime.java b/sp-server/src/main/java/net/minecraft/src/Packet4UpdateTime.java new file mode 100644 index 0000000..58b6ad8 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/Packet4UpdateTime.java @@ -0,0 +1,74 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet4UpdateTime extends Packet { + /** World age in ticks. */ + public long worldAge; + + /** The world time in minutes. */ + public long time; + + public Packet4UpdateTime() { + } + + public Packet4UpdateTime(long par1, long par3) { + this.worldAge = par1; + this.time = par3; + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.worldAge = par1DataInputStream.readLong(); + this.time = par1DataInputStream.readLong(); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeLong(this.worldAge); + par1DataOutputStream.writeLong(this.time); + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleUpdateTime(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 16; + } + + /** + * only false for the abstract Packet class, all real packets return true + */ + public boolean isRealPacket() { + return true; + } + + /** + * eg return packet30entity.entityId == entityId; WARNING : will throw if you + * compare a packet to a different packet class + */ + public boolean containsSameEntityIDAs(Packet par1Packet) { + return true; + } + + /** + * If this returns true, the packet may be processed on any thread; otherwise it + * is queued for the main thread to handle. + */ + public boolean canProcessAsync() { + return true; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/Packet51MapChunk.java b/sp-server/src/main/java/net/minecraft/src/Packet51MapChunk.java new file mode 100644 index 0000000..9b9b788 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/Packet51MapChunk.java @@ -0,0 +1,222 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.util.zip.DataFormatException; +import java.util.zip.Deflater; +import java.util.zip.Inflater; + +public class Packet51MapChunk extends Packet { + /** The x-position of the transmitted chunk, in chunk coordinates. */ + public int xCh; + + /** The z-position of the transmitted chunk, in chunk coordinates. */ + public int zCh; + + /** + * The y-position of the lowest chunk Section in the transmitted chunk, in chunk + * coordinates. + */ + public int yChMin; + + /** + * The y-position of the highest chunk Section in the transmitted chunk, in + * chunk coordinates. + */ + public int yChMax; + + /** The transmitted chunk data, decompressed. */ + private byte[] chunkData; + + /** The compressed chunk data */ + private byte[] compressedChunkData; + + /** + * Whether to initialize the Chunk before applying the effect of the + * Packet51MapChunk. + */ + public boolean includeInitialize; + + /** The length of the compressed chunk data byte array. */ + private int tempLength; + + /** A temporary storage for the compressed chunk data byte array. */ + private static byte[] temp = new byte[196864]; + + public Packet51MapChunk() { + this.isChunkDataPacket = true; + } + + public Packet51MapChunk(Chunk par1Chunk, boolean par2, int par3) { + this.isChunkDataPacket = true; + this.xCh = par1Chunk.xPosition; + this.zCh = par1Chunk.zPosition; + this.includeInitialize = par2; + Packet51MapChunkData var4 = getMapChunkData(par1Chunk, par2, par3); + Deflater var5 = new Deflater(-1); + this.yChMax = var4.chunkHasAddSectionFlag; + this.yChMin = var4.chunkExistFlag; + + try { + this.compressedChunkData = var4.compressedData; + var5.setInput(var4.compressedData, 0, var4.compressedData.length); + var5.finish(); + this.chunkData = new byte[var4.compressedData.length]; + this.tempLength = var5.deflate(this.chunkData); + } finally { + var5.end(); + } + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.xCh = par1DataInputStream.readInt(); + this.zCh = par1DataInputStream.readInt(); + this.includeInitialize = par1DataInputStream.readBoolean(); + this.yChMin = par1DataInputStream.readShort(); + this.yChMax = par1DataInputStream.readShort(); + this.tempLength = par1DataInputStream.readInt(); + + if (temp.length < this.tempLength) { + temp = new byte[this.tempLength]; + } + + par1DataInputStream.readFully(temp, 0, this.tempLength); + int var2 = 0; + int var3; + + for (var3 = 0; var3 < 16; ++var3) { + var2 += this.yChMin >> var3 & 1; + } + + var3 = 12288 * var2; + + if (this.includeInitialize) { + var3 += 256; + } + + this.compressedChunkData = new byte[var3]; + Inflater var4 = new Inflater(); + var4.setInput(temp, 0, this.tempLength); + + try { + var4.inflate(this.compressedChunkData); + } catch (DataFormatException var9) { + throw new IOException("Bad compressed data format"); + } finally { + var4.end(); + } + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeInt(this.xCh); + par1DataOutputStream.writeInt(this.zCh); + par1DataOutputStream.writeBoolean(this.includeInitialize); + par1DataOutputStream.writeShort((short) (this.yChMin & 65535)); + par1DataOutputStream.writeShort((short) (this.yChMax & 65535)); + par1DataOutputStream.writeInt(this.tempLength); + par1DataOutputStream.write(this.chunkData, 0, this.tempLength); + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleMapChunk(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 17 + this.tempLength; + } + + public static Packet51MapChunkData getMapChunkData(Chunk par0Chunk, boolean par1, int par2) { + int var3 = 0; + ExtendedBlockStorage[] var4 = par0Chunk.getBlockStorageArray(); + int var5 = 0; + Packet51MapChunkData var6 = new Packet51MapChunkData(); + byte[] var7 = temp; + + if (par1) { + par0Chunk.sendUpdates = true; + } + + int var8; + + for (var8 = 0; var8 < var4.length; ++var8) { + if (var4[var8] != null && (!par1 || !var4[var8].isEmpty()) && (par2 & 1 << var8) != 0) { + var6.chunkExistFlag |= 1 << var8; + + if (var4[var8].getBlockMSBArray() != null) { + var6.chunkHasAddSectionFlag |= 1 << var8; + ++var5; + } + } + } + + for (var8 = 0; var8 < var4.length; ++var8) { + if (var4[var8] != null && (!par1 || !var4[var8].isEmpty()) && (par2 & 1 << var8) != 0) { + byte[] var9 = var4[var8].getBlockLSBArray(); + System.arraycopy(var9, 0, var7, var3, var9.length); + var3 += var9.length; + } + } + + NibbleArray var10; + + for (var8 = 0; var8 < var4.length; ++var8) { + if (var4[var8] != null && (!par1 || !var4[var8].isEmpty()) && (par2 & 1 << var8) != 0) { + var10 = var4[var8].getMetadataArray(); + System.arraycopy(var10.data, 0, var7, var3, var10.data.length); + var3 += var10.data.length; + } + } + + for (var8 = 0; var8 < var4.length; ++var8) { + if (var4[var8] != null && (!par1 || !var4[var8].isEmpty()) && (par2 & 1 << var8) != 0) { + var10 = var4[var8].getBlocklightArray(); + System.arraycopy(var10.data, 0, var7, var3, var10.data.length); + var3 += var10.data.length; + } + } + + if (!par0Chunk.worldObj.provider.hasNoSky) { + for (var8 = 0; var8 < var4.length; ++var8) { + if (var4[var8] != null && (!par1 || !var4[var8].isEmpty()) && (par2 & 1 << var8) != 0) { + var10 = var4[var8].getSkylightArray(); + System.arraycopy(var10.data, 0, var7, var3, var10.data.length); + var3 += var10.data.length; + } + } + } + + if (var5 > 0) { + for (var8 = 0; var8 < var4.length; ++var8) { + if (var4[var8] != null && (!par1 || !var4[var8].isEmpty()) && var4[var8].getBlockMSBArray() != null + && (par2 & 1 << var8) != 0) { + var10 = var4[var8].getBlockMSBArray(); + System.arraycopy(var10.data, 0, var7, var3, var10.data.length); + var3 += var10.data.length; + } + } + } + + if (par1) { + byte[] var11 = par0Chunk.getBiomeArray(); + System.arraycopy(var11, 0, var7, var3, var11.length); + var3 += var11.length; + } + + var6.compressedData = new byte[var3]; + System.arraycopy(var7, 0, var6.compressedData, 0, var3); + return var6; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/Packet51MapChunkData.java b/sp-server/src/main/java/net/minecraft/src/Packet51MapChunkData.java new file mode 100644 index 0000000..b15a3e3 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/Packet51MapChunkData.java @@ -0,0 +1,7 @@ +package net.minecraft.src; + +public class Packet51MapChunkData { + public byte[] compressedData; + public int chunkExistFlag; + public int chunkHasAddSectionFlag; +} diff --git a/sp-server/src/main/java/net/minecraft/src/Packet52MultiBlockChange.java b/sp-server/src/main/java/net/minecraft/src/Packet52MultiBlockChange.java new file mode 100644 index 0000000..b10bf27 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/Packet52MultiBlockChange.java @@ -0,0 +1,111 @@ +package net.minecraft.src; + +import java.io.ByteArrayOutputStream; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet52MultiBlockChange extends Packet { + /** Chunk X position. */ + public int xPosition; + + /** Chunk Z position. */ + public int zPosition; + + /** The metadata for each block changed. */ + public byte[] metadataArray; + + /** The size of the arrays. */ + public int size; + private static byte[] field_73449_e = new byte[0]; + + public Packet52MultiBlockChange() { + this.isChunkDataPacket = true; + } + + public Packet52MultiBlockChange(int par1, int par2, short[] par3ArrayOfShort, int par4, World par5World) { + this.isChunkDataPacket = true; + this.xPosition = par1; + this.zPosition = par2; + this.size = par4; + int var6 = 4 * par4; + Chunk var7 = par5World.getChunkFromChunkCoords(par1, par2); + + try { + if (par4 >= 64) { + this.field_98193_m.func_98233_a("ChunkTilesUpdatePacket compress " + par4); + + if (field_73449_e.length < var6) { + field_73449_e = new byte[var6]; + } + } else { + ByteArrayOutputStream var8 = new ByteArrayOutputStream(var6); + DataOutputStream var9 = new DataOutputStream(var8); + + for (int var10 = 0; var10 < par4; ++var10) { + int var11 = par3ArrayOfShort[var10] >> 12 & 15; + int var12 = par3ArrayOfShort[var10] >> 8 & 15; + int var13 = par3ArrayOfShort[var10] & 255; + var9.writeShort(par3ArrayOfShort[var10]); + var9.writeShort((short) ((var7.getBlockID(var11, var13, var12) & 4095) << 4 + | var7.getBlockMetadata(var11, var13, var12) & 15)); + } + + this.metadataArray = var8.toByteArray(); + + if (this.metadataArray.length != var6) { + throw new RuntimeException( + "Expected length " + var6 + " doesn\'t match received length " + this.metadataArray.length); + } + } + } catch (IOException var14) { + this.field_98193_m.logSevereException("Couldn\'t create chunk packet", var14); + this.metadataArray = null; + } + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.xPosition = par1DataInputStream.readInt(); + this.zPosition = par1DataInputStream.readInt(); + this.size = par1DataInputStream.readShort() & 65535; + int var2 = par1DataInputStream.readInt(); + + if (var2 > 0) { + this.metadataArray = new byte[var2]; + par1DataInputStream.readFully(this.metadataArray); + } + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeInt(this.xPosition); + par1DataOutputStream.writeInt(this.zPosition); + par1DataOutputStream.writeShort((short) this.size); + + if (this.metadataArray != null) { + par1DataOutputStream.writeInt(this.metadataArray.length); + par1DataOutputStream.write(this.metadataArray); + } else { + par1DataOutputStream.writeInt(0); + } + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleMultiBlockChange(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 10 + this.size * 4; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/Packet53BlockChange.java b/sp-server/src/main/java/net/minecraft/src/Packet53BlockChange.java new file mode 100644 index 0000000..cbc4a83 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/Packet53BlockChange.java @@ -0,0 +1,71 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet53BlockChange extends Packet { + /** Block X position. */ + public int xPosition; + + /** Block Y position. */ + public int yPosition; + + /** Block Z position. */ + public int zPosition; + + /** The new block type for the block. */ + public int type; + + /** Metadata of the block. */ + public int metadata; + + public Packet53BlockChange() { + this.isChunkDataPacket = true; + } + + public Packet53BlockChange(int par1, int par2, int par3, World par4World) { + this.isChunkDataPacket = true; + this.xPosition = par1; + this.yPosition = par2; + this.zPosition = par3; + this.type = par4World.getBlockId(par1, par2, par3); + this.metadata = par4World.getBlockMetadata(par1, par2, par3); + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.xPosition = par1DataInputStream.readInt(); + this.yPosition = par1DataInputStream.read(); + this.zPosition = par1DataInputStream.readInt(); + this.type = par1DataInputStream.readShort(); + this.metadata = par1DataInputStream.read(); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeInt(this.xPosition); + par1DataOutputStream.write(this.yPosition); + par1DataOutputStream.writeInt(this.zPosition); + par1DataOutputStream.writeShort(this.type); + par1DataOutputStream.write(this.metadata); + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleBlockChange(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 11; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/Packet54PlayNoteBlock.java b/sp-server/src/main/java/net/minecraft/src/Packet54PlayNoteBlock.java new file mode 100644 index 0000000..7a9a9b7 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/Packet54PlayNoteBlock.java @@ -0,0 +1,73 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet54PlayNoteBlock extends Packet { + public int xLocation; + public int yLocation; + public int zLocation; + + /** 1=Double Bass, 2=Snare Drum, 3=Clicks / Sticks, 4=Bass Drum, 5=Harp */ + public int instrumentType; + + /** + * The pitch of the note (between 0-24 inclusive where 0 is the lowest and 24 is + * the highest). + */ + public int pitch; + + /** The block ID this action is set for. */ + public int blockId; + + public Packet54PlayNoteBlock() { + } + + public Packet54PlayNoteBlock(int par1, int par2, int par3, int par4, int par5, int par6) { + this.xLocation = par1; + this.yLocation = par2; + this.zLocation = par3; + this.instrumentType = par5; + this.pitch = par6; + this.blockId = par4; + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.xLocation = par1DataInputStream.readInt(); + this.yLocation = par1DataInputStream.readShort(); + this.zLocation = par1DataInputStream.readInt(); + this.instrumentType = par1DataInputStream.read(); + this.pitch = par1DataInputStream.read(); + this.blockId = par1DataInputStream.readShort() & 4095; + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeInt(this.xLocation); + par1DataOutputStream.writeShort(this.yLocation); + par1DataOutputStream.writeInt(this.zLocation); + par1DataOutputStream.write(this.instrumentType); + par1DataOutputStream.write(this.pitch); + par1DataOutputStream.writeShort(this.blockId & 4095); + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleBlockEvent(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 14; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/Packet55BlockDestroy.java b/sp-server/src/main/java/net/minecraft/src/Packet55BlockDestroy.java new file mode 100644 index 0000000..3b83755 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/Packet55BlockDestroy.java @@ -0,0 +1,85 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet55BlockDestroy extends Packet { + /** Entity breaking the block */ + private int entityId; + + /** X posiiton of the block */ + private int posX; + + /** Y position of the block */ + private int posY; + + /** Z position of the block */ + private int posZ; + + /** How far destroyed this block is */ + private int destroyedStage; + + public Packet55BlockDestroy() { + } + + public Packet55BlockDestroy(int par1, int par2, int par3, int par4, int par5) { + this.entityId = par1; + this.posX = par2; + this.posY = par3; + this.posZ = par4; + this.destroyedStage = par5; + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.entityId = par1DataInputStream.readInt(); + this.posX = par1DataInputStream.readInt(); + this.posY = par1DataInputStream.readInt(); + this.posZ = par1DataInputStream.readInt(); + this.destroyedStage = par1DataInputStream.read(); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeInt(this.entityId); + par1DataOutputStream.writeInt(this.posX); + par1DataOutputStream.writeInt(this.posY); + par1DataOutputStream.writeInt(this.posZ); + par1DataOutputStream.write(this.destroyedStage); + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleBlockDestroy(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 13; + } + + /** + * only false for the abstract Packet class, all real packets return true + */ + public boolean isRealPacket() { + return true; + } + + /** + * eg return packet30entity.entityId == entityId; WARNING : will throw if you + * compare a packet to a different packet class + */ + public boolean containsSameEntityIDAs(Packet par1Packet) { + Packet55BlockDestroy var2 = (Packet55BlockDestroy) par1Packet; + return var2.entityId == this.entityId; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/Packet56MapChunks.java b/sp-server/src/main/java/net/minecraft/src/Packet56MapChunks.java new file mode 100644 index 0000000..b8dd0b9 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/Packet56MapChunks.java @@ -0,0 +1,168 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.util.List; +import java.util.zip.DataFormatException; +import java.util.zip.Deflater; +import java.util.zip.Inflater; + +public class Packet56MapChunks extends Packet { + private int[] chunkPostX; + private int[] chunkPosZ; + public int[] field_73590_a; + public int[] field_73588_b; + + /** The compressed chunk data buffer */ + private byte[] chunkDataBuffer; + private byte[][] field_73584_f; + + /** total size of the compressed data */ + private int dataLength; + + /** + * Whether or not the chunk data contains a light nibble array. This is true in + * the main world, false in the end + nether. + */ + private boolean skyLightSent; + private static byte[] chunkDataNotCompressed = new byte[0]; + + public Packet56MapChunks() { + } + + public Packet56MapChunks(List par1List) { + int var2 = par1List.size(); + this.chunkPostX = new int[var2]; + this.chunkPosZ = new int[var2]; + this.field_73590_a = new int[var2]; + this.field_73588_b = new int[var2]; + this.field_73584_f = new byte[var2][]; + this.skyLightSent = !par1List.isEmpty() && !((Chunk) par1List.get(0)).worldObj.provider.hasNoSky; + int var3 = 0; + + for (int var4 = 0; var4 < var2; ++var4) { + Chunk var5 = (Chunk) par1List.get(var4); + Packet51MapChunkData var6 = Packet51MapChunk.getMapChunkData(var5, true, 65535); + + if (chunkDataNotCompressed.length < var3 + var6.compressedData.length) { + byte[] var7 = new byte[var3 + var6.compressedData.length]; + System.arraycopy(chunkDataNotCompressed, 0, var7, 0, chunkDataNotCompressed.length); + chunkDataNotCompressed = var7; + } + + System.arraycopy(var6.compressedData, 0, chunkDataNotCompressed, var3, var6.compressedData.length); + var3 += var6.compressedData.length; + this.chunkPostX[var4] = var5.xPosition; + this.chunkPosZ[var4] = var5.zPosition; + this.field_73590_a[var4] = var6.chunkExistFlag; + this.field_73588_b[var4] = var6.chunkHasAddSectionFlag; + this.field_73584_f[var4] = var6.compressedData; + } + + Deflater var11 = new Deflater(-1); + + try { + var11.setInput(chunkDataNotCompressed, 0, var3); + var11.finish(); + this.chunkDataBuffer = new byte[var3]; + this.dataLength = var11.deflate(this.chunkDataBuffer); + } finally { + var11.end(); + } + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + short var2 = par1DataInputStream.readShort(); + this.dataLength = par1DataInputStream.readInt(); + this.skyLightSent = par1DataInputStream.readBoolean(); + this.chunkPostX = new int[var2]; + this.chunkPosZ = new int[var2]; + this.field_73590_a = new int[var2]; + this.field_73588_b = new int[var2]; + this.field_73584_f = new byte[var2][]; + + if (chunkDataNotCompressed.length < this.dataLength) { + chunkDataNotCompressed = new byte[this.dataLength]; + } + + par1DataInputStream.readFully(chunkDataNotCompressed, 0, this.dataLength); + byte[] var3 = new byte[196864 * var2]; + Inflater var4 = new Inflater(); + var4.setInput(chunkDataNotCompressed, 0, this.dataLength); + + try { + var4.inflate(var3); + } catch (DataFormatException var12) { + throw new IOException("Bad compressed data format"); + } finally { + var4.end(); + } + + int var5 = 0; + + for (int var6 = 0; var6 < var2; ++var6) { + this.chunkPostX[var6] = par1DataInputStream.readInt(); + this.chunkPosZ[var6] = par1DataInputStream.readInt(); + this.field_73590_a[var6] = par1DataInputStream.readShort(); + this.field_73588_b[var6] = par1DataInputStream.readShort(); + int var7 = 0; + int var8 = 0; + int var9; + + for (var9 = 0; var9 < 16; ++var9) { + var7 += this.field_73590_a[var6] >> var9 & 1; + var8 += this.field_73588_b[var6] >> var9 & 1; + } + + var9 = 2048 * 4 * var7 + 256; + var9 += 2048 * var8; + + if (this.skyLightSent) { + var9 += 2048 * var7; + } + + this.field_73584_f[var6] = new byte[var9]; + System.arraycopy(var3, var5, this.field_73584_f[var6], 0, var9); + var5 += var9; + } + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeShort(this.chunkPostX.length); + par1DataOutputStream.writeInt(this.dataLength); + par1DataOutputStream.writeBoolean(this.skyLightSent); + par1DataOutputStream.write(this.chunkDataBuffer, 0, this.dataLength); + + for (int var2 = 0; var2 < this.chunkPostX.length; ++var2) { + par1DataOutputStream.writeInt(this.chunkPostX[var2]); + par1DataOutputStream.writeInt(this.chunkPosZ[var2]); + par1DataOutputStream.writeShort((short) (this.field_73590_a[var2] & 65535)); + par1DataOutputStream.writeShort((short) (this.field_73588_b[var2] & 65535)); + } + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleMapChunks(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 6 + this.dataLength + 12 * this.getNumberOfChunkInPacket(); + } + + public int getNumberOfChunkInPacket() { + return this.chunkPostX.length; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/Packet5PlayerInventory.java b/sp-server/src/main/java/net/minecraft/src/Packet5PlayerInventory.java new file mode 100644 index 0000000..319325e --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/Packet5PlayerInventory.java @@ -0,0 +1,73 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet5PlayerInventory extends Packet { + /** Entity ID of the object. */ + public int entityID; + + /** Equipment slot: 0=held, 1-4=armor slot */ + public int slot; + + /** The item in the slot format (an ItemStack) */ + private ItemStack itemSlot; + + public Packet5PlayerInventory() { + } + + public Packet5PlayerInventory(int par1, int par2, ItemStack par3ItemStack) { + this.entityID = par1; + this.slot = par2; + this.itemSlot = par3ItemStack == null ? null : par3ItemStack.copy(); + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.entityID = par1DataInputStream.readInt(); + this.slot = par1DataInputStream.readShort(); + this.itemSlot = readItemStack(par1DataInputStream); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeInt(this.entityID); + par1DataOutputStream.writeShort(this.slot); + writeItemStack(this.itemSlot, par1DataOutputStream); + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handlePlayerInventory(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 8; + } + + /** + * only false for the abstract Packet class, all real packets return true + */ + public boolean isRealPacket() { + return true; + } + + /** + * eg return packet30entity.entityId == entityId; WARNING : will throw if you + * compare a packet to a different packet class + */ + public boolean containsSameEntityIDAs(Packet par1Packet) { + Packet5PlayerInventory var2 = (Packet5PlayerInventory) par1Packet; + return var2.entityID == this.entityID && var2.slot == this.slot; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/Packet60Explosion.java b/sp-server/src/main/java/net/minecraft/src/Packet60Explosion.java new file mode 100644 index 0000000..95deeeb --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/Packet60Explosion.java @@ -0,0 +1,111 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +public class Packet60Explosion extends Packet { + public double explosionX; + public double explosionY; + public double explosionZ; + public float explosionSize; + public List chunkPositionRecords; + + /** X velocity of the player being pushed by the explosion */ + private float playerVelocityX; + + /** Y velocity of the player being pushed by the explosion */ + private float playerVelocityY; + + /** Z velocity of the player being pushed by the explosion */ + private float playerVelocityZ; + + public Packet60Explosion() { + } + + public Packet60Explosion(double par1, double par3, double par5, float par7, List par8List, Vec3 par9Vec3) { + this.explosionX = par1; + this.explosionY = par3; + this.explosionZ = par5; + this.explosionSize = par7; + this.chunkPositionRecords = new ArrayList(par8List); + + if (par9Vec3 != null) { + this.playerVelocityX = (float) par9Vec3.xCoord; + this.playerVelocityY = (float) par9Vec3.yCoord; + this.playerVelocityZ = (float) par9Vec3.zCoord; + } + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.explosionX = par1DataInputStream.readDouble(); + this.explosionY = par1DataInputStream.readDouble(); + this.explosionZ = par1DataInputStream.readDouble(); + this.explosionSize = par1DataInputStream.readFloat(); + int var2 = par1DataInputStream.readInt(); + this.chunkPositionRecords = new ArrayList(var2); + int var3 = (int) this.explosionX; + int var4 = (int) this.explosionY; + int var5 = (int) this.explosionZ; + + for (int var6 = 0; var6 < var2; ++var6) { + int var7 = par1DataInputStream.readByte() + var3; + int var8 = par1DataInputStream.readByte() + var4; + int var9 = par1DataInputStream.readByte() + var5; + this.chunkPositionRecords.add(new ChunkPosition(var7, var8, var9)); + } + + this.playerVelocityX = par1DataInputStream.readFloat(); + this.playerVelocityY = par1DataInputStream.readFloat(); + this.playerVelocityZ = par1DataInputStream.readFloat(); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeDouble(this.explosionX); + par1DataOutputStream.writeDouble(this.explosionY); + par1DataOutputStream.writeDouble(this.explosionZ); + par1DataOutputStream.writeFloat(this.explosionSize); + par1DataOutputStream.writeInt(this.chunkPositionRecords.size()); + int var2 = (int) this.explosionX; + int var3 = (int) this.explosionY; + int var4 = (int) this.explosionZ; + Iterator var5 = this.chunkPositionRecords.iterator(); + + while (var5.hasNext()) { + ChunkPosition var6 = (ChunkPosition) var5.next(); + int var7 = var6.x - var2; + int var8 = var6.y - var3; + int var9 = var6.z - var4; + par1DataOutputStream.writeByte(var7); + par1DataOutputStream.writeByte(var8); + par1DataOutputStream.writeByte(var9); + } + + par1DataOutputStream.writeFloat(this.playerVelocityX); + par1DataOutputStream.writeFloat(this.playerVelocityY); + par1DataOutputStream.writeFloat(this.playerVelocityZ); + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleExplosion(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 32 + this.chunkPositionRecords.size() * 3 + 3; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/Packet61DoorChange.java b/sp-server/src/main/java/net/minecraft/src/Packet61DoorChange.java new file mode 100644 index 0000000..3472c38 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/Packet61DoorChange.java @@ -0,0 +1,64 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet61DoorChange extends Packet { + public int sfxID; + public int auxData; + public int posX; + public int posY; + public int posZ; + private boolean disableRelativeVolume; + + public Packet61DoorChange() { + } + + public Packet61DoorChange(int par1, int par2, int par3, int par4, int par5, boolean par6) { + this.sfxID = par1; + this.posX = par2; + this.posY = par3; + this.posZ = par4; + this.auxData = par5; + this.disableRelativeVolume = par6; + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.sfxID = par1DataInputStream.readInt(); + this.posX = par1DataInputStream.readInt(); + this.posY = par1DataInputStream.readByte() & 255; + this.posZ = par1DataInputStream.readInt(); + this.auxData = par1DataInputStream.readInt(); + this.disableRelativeVolume = par1DataInputStream.readBoolean(); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeInt(this.sfxID); + par1DataOutputStream.writeInt(this.posX); + par1DataOutputStream.writeByte(this.posY & 255); + par1DataOutputStream.writeInt(this.posZ); + par1DataOutputStream.writeInt(this.auxData); + par1DataOutputStream.writeBoolean(this.disableRelativeVolume); + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleDoorChange(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 21; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/Packet62LevelSound.java b/sp-server/src/main/java/net/minecraft/src/Packet62LevelSound.java new file mode 100644 index 0000000..8b4a7ea --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/Packet62LevelSound.java @@ -0,0 +1,83 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet62LevelSound extends Packet { + /** e.g. step.grass */ + private String soundName; + + /** Effect X multiplied by 8 */ + private int effectX; + + /** Effect Y multiplied by 8 */ + private int effectY = Integer.MAX_VALUE; + + /** Effect Z multiplied by 8 */ + private int effectZ; + + /** 1 is 100%. Can be more. */ + private float volume; + + /** 63 is 100%. Can be more. */ + private int pitch; + + public Packet62LevelSound() { + } + + public Packet62LevelSound(String par1Str, double par2, double par4, double par6, float par8, float par9) { + this.soundName = par1Str; + this.effectX = (int) (par2 * 8.0D); + this.effectY = (int) (par4 * 8.0D); + this.effectZ = (int) (par6 * 8.0D); + this.volume = par8; + this.pitch = (int) (par9 * 63.0F); + + if (this.pitch < 0) { + this.pitch = 0; + } + + if (this.pitch > 255) { + this.pitch = 255; + } + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.soundName = readString(par1DataInputStream, 32); + this.effectX = par1DataInputStream.readInt(); + this.effectY = par1DataInputStream.readInt(); + this.effectZ = par1DataInputStream.readInt(); + this.volume = par1DataInputStream.readFloat(); + this.pitch = par1DataInputStream.readUnsignedByte(); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + writeString(this.soundName, par1DataOutputStream); + par1DataOutputStream.writeInt(this.effectX); + par1DataOutputStream.writeInt(this.effectY); + par1DataOutputStream.writeInt(this.effectZ); + par1DataOutputStream.writeFloat(this.volume); + par1DataOutputStream.writeByte(this.pitch); + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleLevelSound(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 24; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/Packet63WorldParticles.java b/sp-server/src/main/java/net/minecraft/src/Packet63WorldParticles.java new file mode 100644 index 0000000..e493bcf --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/Packet63WorldParticles.java @@ -0,0 +1,90 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet63WorldParticles extends Packet { + /** + * The name of the particle to create. A list can be found at + * https://gist.github.com/thinkofdeath/5110835 + */ + private String particleName; + + /** X position of the particle. */ + private float posX; + + /** Y position of the particle. */ + private float posY; + + /** Z position of the particle. */ + private float posZ; + + /** + * This is added to the X position after being multiplied by + * random.nextGaussian() + */ + private float offsetX; + + /** + * This is added to the Y position after being multiplied by + * random.nextGaussian() + */ + private float offsetY; + + /** + * This is added to the Z position after being multiplied by + * random.nextGaussian() + */ + private float offsetZ; + + /** The speed of each particle. */ + private float speed; + + /** The number of particles to create. */ + private int quantity; + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.particleName = readString(par1DataInputStream, 64); + this.posX = par1DataInputStream.readFloat(); + this.posY = par1DataInputStream.readFloat(); + this.posZ = par1DataInputStream.readFloat(); + this.offsetX = par1DataInputStream.readFloat(); + this.offsetY = par1DataInputStream.readFloat(); + this.offsetZ = par1DataInputStream.readFloat(); + this.speed = par1DataInputStream.readFloat(); + this.quantity = par1DataInputStream.readInt(); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + writeString(this.particleName, par1DataOutputStream); + par1DataOutputStream.writeFloat(this.posX); + par1DataOutputStream.writeFloat(this.posY); + par1DataOutputStream.writeFloat(this.posZ); + par1DataOutputStream.writeFloat(this.offsetX); + par1DataOutputStream.writeFloat(this.offsetY); + par1DataOutputStream.writeFloat(this.offsetZ); + par1DataOutputStream.writeFloat(this.speed); + par1DataOutputStream.writeInt(this.quantity); + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleWorldParticles(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 64; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/Packet6SpawnPosition.java b/sp-server/src/main/java/net/minecraft/src/Packet6SpawnPosition.java new file mode 100644 index 0000000..896fa06 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/Packet6SpawnPosition.java @@ -0,0 +1,80 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet6SpawnPosition extends Packet { + /** X coordinate of spawn. */ + public int xPosition; + + /** Y coordinate of spawn. */ + public int yPosition; + + /** Z coordinate of spawn. */ + public int zPosition; + + public Packet6SpawnPosition() { + } + + public Packet6SpawnPosition(int par1, int par2, int par3) { + this.xPosition = par1; + this.yPosition = par2; + this.zPosition = par3; + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.xPosition = par1DataInputStream.readInt(); + this.yPosition = par1DataInputStream.readInt(); + this.zPosition = par1DataInputStream.readInt(); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeInt(this.xPosition); + par1DataOutputStream.writeInt(this.yPosition); + par1DataOutputStream.writeInt(this.zPosition); + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleSpawnPosition(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 12; + } + + /** + * only false for the abstract Packet class, all real packets return true + */ + public boolean isRealPacket() { + return true; + } + + /** + * eg return packet30entity.entityId == entityId; WARNING : will throw if you + * compare a packet to a different packet class + */ + public boolean containsSameEntityIDAs(Packet par1Packet) { + return true; + } + + /** + * If this returns true, the packet may be processed on any thread; otherwise it + * is queued for the main thread to handle. + */ + public boolean canProcessAsync() { + return false; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/Packet70GameEvent.java b/sp-server/src/main/java/net/minecraft/src/Packet70GameEvent.java new file mode 100644 index 0000000..2d4fa5a --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/Packet70GameEvent.java @@ -0,0 +1,59 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet70GameEvent extends Packet { + /** + * The client prints clientMessage[eventType] to chat when this packet is + * received. + */ + public static final String[] clientMessage = new String[] { "tile.bed.notValid", null, null, "gameMode.changed" }; + + /** 0: Invalid bed, 1: Rain starts, 2: Rain stops, 3: Game mode changed. */ + public int eventType; + + /** + * When reason==3, the game mode to set. See EnumGameType for a list of values. + */ + public int gameMode; + + public Packet70GameEvent() { + } + + public Packet70GameEvent(int par1, int par2) { + this.eventType = par1; + this.gameMode = par2; + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.eventType = par1DataInputStream.readByte(); + this.gameMode = par1DataInputStream.readByte(); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeByte(this.eventType); + par1DataOutputStream.writeByte(this.gameMode); + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleGameEvent(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 2; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/Packet71Weather.java b/sp-server/src/main/java/net/minecraft/src/Packet71Weather.java new file mode 100644 index 0000000..225b859 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/Packet71Weather.java @@ -0,0 +1,63 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet71Weather extends Packet { + public int entityID; + public int posX; + public int posY; + public int posZ; + public int isLightningBolt; + + public Packet71Weather() { + } + + public Packet71Weather(Entity par1Entity) { + this.entityID = par1Entity.entityId; + this.posX = MathHelper.floor_double(par1Entity.posX * 32.0D); + this.posY = MathHelper.floor_double(par1Entity.posY * 32.0D); + this.posZ = MathHelper.floor_double(par1Entity.posZ * 32.0D); + + if (par1Entity instanceof EntityLightningBolt) { + this.isLightningBolt = 1; + } + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.entityID = par1DataInputStream.readInt(); + this.isLightningBolt = par1DataInputStream.readByte(); + this.posX = par1DataInputStream.readInt(); + this.posY = par1DataInputStream.readInt(); + this.posZ = par1DataInputStream.readInt(); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeInt(this.entityID); + par1DataOutputStream.writeByte(this.isLightningBolt); + par1DataOutputStream.writeInt(this.posX); + par1DataOutputStream.writeInt(this.posY); + par1DataOutputStream.writeInt(this.posZ); + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleWeather(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 17; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/Packet7UseEntity.java b/sp-server/src/main/java/net/minecraft/src/Packet7UseEntity.java new file mode 100644 index 0000000..dd943db --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/Packet7UseEntity.java @@ -0,0 +1,51 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet7UseEntity extends Packet { + /** The entity of the player (ignored by the server) */ + public int playerEntityId; + + /** The entity the player is interacting with */ + public int targetEntity; + + /** + * Seems to be true when the player is pointing at an entity and left-clicking + * and false when right-clicking. + */ + public int isLeftClick; + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.playerEntityId = par1DataInputStream.readInt(); + this.targetEntity = par1DataInputStream.readInt(); + this.isLeftClick = par1DataInputStream.readByte(); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeInt(this.playerEntityId); + par1DataOutputStream.writeInt(this.targetEntity); + par1DataOutputStream.writeByte(this.isLeftClick); + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleUseEntity(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 9; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/Packet8UpdateHealth.java b/sp-server/src/main/java/net/minecraft/src/Packet8UpdateHealth.java new file mode 100644 index 0000000..8e91d67 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/Packet8UpdateHealth.java @@ -0,0 +1,73 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet8UpdateHealth extends Packet { + /** Variable used for incoming health packets */ + public int healthMP; + public int food; + + /** + * Players logging on get a saturation of 5.0. Eating food increases the + * saturation as well as the food bar. + */ + public float foodSaturation; + + public Packet8UpdateHealth() { + } + + public Packet8UpdateHealth(int par1, int par2, float par3) { + this.healthMP = par1; + this.food = par2; + this.foodSaturation = par3; + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.healthMP = par1DataInputStream.readShort(); + this.food = par1DataInputStream.readShort(); + this.foodSaturation = par1DataInputStream.readFloat(); + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeShort(this.healthMP); + par1DataOutputStream.writeShort(this.food); + par1DataOutputStream.writeFloat(this.foodSaturation); + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleUpdateHealth(this); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 8; + } + + /** + * only false for the abstract Packet class, all real packets return true + */ + public boolean isRealPacket() { + return true; + } + + /** + * eg return packet30entity.entityId == entityId; WARNING : will throw if you + * compare a packet to a different packet class + */ + public boolean containsSameEntityIDAs(Packet par1Packet) { + return true; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/Packet9Respawn.java b/sp-server/src/main/java/net/minecraft/src/Packet9Respawn.java new file mode 100644 index 0000000..5eb12f4 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/Packet9Respawn.java @@ -0,0 +1,72 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class Packet9Respawn extends Packet { + public int respawnDimension; + + /** + * The difficulty setting. 0 through 3 for peaceful, easy, normal, hard. The + * client always sends 1. + */ + public int difficulty; + + /** Defaults to 128 */ + public int worldHeight; + public EnumGameType gameType; + public WorldType terrainType; + + public Packet9Respawn() { + } + + public Packet9Respawn(int par1, byte par2, WorldType par3WorldType, int par4, EnumGameType par5EnumGameType) { + this.respawnDimension = par1; + this.difficulty = par2; + this.worldHeight = par4; + this.gameType = par5EnumGameType; + this.terrainType = par3WorldType; + } + + /** + * Passes this Packet on to the NetHandler for processing. + */ + public void processPacket(NetHandler par1NetHandler) { + par1NetHandler.handleRespawn(this); + } + + /** + * Abstract. Reads the raw packet data from the data stream. + */ + public void readPacketData(DataInputStream par1DataInputStream) throws IOException { + this.respawnDimension = par1DataInputStream.readInt(); + this.difficulty = par1DataInputStream.readByte(); + this.gameType = EnumGameType.getByID(par1DataInputStream.readByte()); + this.worldHeight = par1DataInputStream.readShort(); + String var2 = readString(par1DataInputStream, 16); + this.terrainType = WorldType.parseWorldType(var2); + + if (this.terrainType == null) { + this.terrainType = WorldType.DEFAULT; + } + } + + /** + * Abstract. Writes the raw packet data to the data stream. + */ + public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException { + par1DataOutputStream.writeInt(this.respawnDimension); + par1DataOutputStream.writeByte(this.difficulty); + par1DataOutputStream.writeByte(this.gameType.getID()); + par1DataOutputStream.writeShort(this.worldHeight); + writeString(this.terrainType.getWorldTypeName(), par1DataOutputStream); + } + + /** + * Abstract. Return the size of the packet (not counting the header). + */ + public int getPacketSize() { + return 8 + (this.terrainType == null ? 0 : this.terrainType.getWorldTypeName().length()); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/PacketCount.java b/sp-server/src/main/java/net/minecraft/src/PacketCount.java new file mode 100644 index 0000000..39bf67e --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/PacketCount.java @@ -0,0 +1,36 @@ +package net.minecraft.src; + +import java.util.HashMap; +import java.util.Map; + +public class PacketCount { + /** If false, countPacket does nothing */ + public static boolean allowCounting = true; + + /** A count of the total number of each packet sent grouped by IDs. */ + private static final Map packetCountForID = new HashMap(); + + /** A count of the total size of each packet sent grouped by IDs. */ + private static final Map sizeCountForID = new HashMap(); + + /** Used to make threads queue to add packets */ + private static final Object lock = new Object(); + + public static void countPacket(int par0, long par1) { + if (allowCounting) { + Object var3 = lock; + + synchronized (lock) { + if (packetCountForID.containsKey(Integer.valueOf(par0))) { + packetCountForID.put(Integer.valueOf(par0), + Long.valueOf(((Long) packetCountForID.get(Integer.valueOf(par0))).longValue() + 1L)); + sizeCountForID.put(Integer.valueOf(par0), + Long.valueOf(((Long) sizeCountForID.get(Integer.valueOf(par0))).longValue() + par1)); + } else { + packetCountForID.put(Integer.valueOf(par0), Long.valueOf(1L)); + sizeCountForID.put(Integer.valueOf(par0), Long.valueOf(par1)); + } + } + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/Path.java b/sp-server/src/main/java/net/minecraft/src/Path.java new file mode 100644 index 0000000..218178c --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/Path.java @@ -0,0 +1,147 @@ +package net.minecraft.src; + +public class Path { + /** Contains the points in this path */ + private PathPoint[] pathPoints = new PathPoint[1024]; + + /** The number of points in this path */ + private int count = 0; + + /** + * Adds a point to the path + */ + public PathPoint addPoint(PathPoint par1PathPoint) { + if (par1PathPoint.index >= 0) { + throw new IllegalStateException("OW KNOWS!"); + } else { + if (this.count == this.pathPoints.length) { + PathPoint[] var2 = new PathPoint[this.count << 1]; + System.arraycopy(this.pathPoints, 0, var2, 0, this.count); + this.pathPoints = var2; + } + + this.pathPoints[this.count] = par1PathPoint; + par1PathPoint.index = this.count; + this.sortBack(this.count++); + return par1PathPoint; + } + } + + /** + * Clears the path + */ + public void clearPath() { + this.count = 0; + } + + /** + * Returns and removes the first point in the path + */ + public PathPoint dequeue() { + PathPoint var1 = this.pathPoints[0]; + this.pathPoints[0] = this.pathPoints[--this.count]; + this.pathPoints[this.count] = null; + + if (this.count > 0) { + this.sortForward(0); + } + + var1.index = -1; + return var1; + } + + /** + * Changes the provided point's distance to target + */ + public void changeDistance(PathPoint par1PathPoint, float par2) { + float var3 = par1PathPoint.distanceToTarget; + par1PathPoint.distanceToTarget = par2; + + if (par2 < var3) { + this.sortBack(par1PathPoint.index); + } else { + this.sortForward(par1PathPoint.index); + } + } + + /** + * Sorts a point to the left + */ + private void sortBack(int par1) { + PathPoint var2 = this.pathPoints[par1]; + int var4; + + for (float var3 = var2.distanceToTarget; par1 > 0; par1 = var4) { + var4 = par1 - 1 >> 1; + PathPoint var5 = this.pathPoints[var4]; + + if (var3 >= var5.distanceToTarget) { + break; + } + + this.pathPoints[par1] = var5; + var5.index = par1; + } + + this.pathPoints[par1] = var2; + var2.index = par1; + } + + /** + * Sorts a point to the right + */ + private void sortForward(int par1) { + PathPoint var2 = this.pathPoints[par1]; + float var3 = var2.distanceToTarget; + + while (true) { + int var4 = 1 + (par1 << 1); + int var5 = var4 + 1; + + if (var4 >= this.count) { + break; + } + + PathPoint var6 = this.pathPoints[var4]; + float var7 = var6.distanceToTarget; + PathPoint var8; + float var9; + + if (var5 >= this.count) { + var8 = null; + var9 = Float.POSITIVE_INFINITY; + } else { + var8 = this.pathPoints[var5]; + var9 = var8.distanceToTarget; + } + + if (var7 < var9) { + if (var7 >= var3) { + break; + } + + this.pathPoints[par1] = var6; + var6.index = par1; + par1 = var4; + } else { + if (var9 >= var3) { + break; + } + + this.pathPoints[par1] = var8; + var8.index = par1; + par1 = var5; + } + } + + this.pathPoints[par1] = var2; + var2.index = par1; + } + + /** + * Returns true if this path contains no points + */ + public boolean isPathEmpty() { + return this.count == 0; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/PathEntity.java b/sp-server/src/main/java/net/minecraft/src/PathEntity.java new file mode 100644 index 0000000..db40ddc --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/PathEntity.java @@ -0,0 +1,109 @@ +package net.minecraft.src; + +public class PathEntity { + /** The actual points in the path */ + private final PathPoint[] points; + + /** PathEntity Array Index the Entity is currently targeting */ + private int currentPathIndex; + + /** The total length of the path */ + private int pathLength; + + public PathEntity(PathPoint[] par1ArrayOfPathPoint) { + this.points = par1ArrayOfPathPoint; + this.pathLength = par1ArrayOfPathPoint.length; + } + + /** + * Directs this path to the next point in its array + */ + public void incrementPathIndex() { + ++this.currentPathIndex; + } + + /** + * Returns true if this path has reached the end + */ + public boolean isFinished() { + return this.currentPathIndex >= this.pathLength; + } + + /** + * returns the last PathPoint of the Array + */ + public PathPoint getFinalPathPoint() { + return this.pathLength > 0 ? this.points[this.pathLength - 1] : null; + } + + /** + * return the PathPoint located at the specified PathIndex, usually the current + * one + */ + public PathPoint getPathPointFromIndex(int par1) { + return this.points[par1]; + } + + public int getCurrentPathLength() { + return this.pathLength; + } + + public void setCurrentPathLength(int par1) { + this.pathLength = par1; + } + + public int getCurrentPathIndex() { + return this.currentPathIndex; + } + + public void setCurrentPathIndex(int par1) { + this.currentPathIndex = par1; + } + + /** + * Gets the vector of the PathPoint associated with the given index. + */ + public Vec3 getVectorFromIndex(Entity par1Entity, int par2) { + double var3 = (double) this.points[par2].xCoord + (double) ((int) (par1Entity.width + 1.0F)) * 0.5D; + double var5 = (double) this.points[par2].yCoord; + double var7 = (double) this.points[par2].zCoord + (double) ((int) (par1Entity.width + 1.0F)) * 0.5D; + return par1Entity.worldObj.getWorldVec3Pool().getVecFromPool(var3, var5, var7); + } + + /** + * returns the current PathEntity target node as Vec3D + */ + public Vec3 getPosition(Entity par1Entity) { + return this.getVectorFromIndex(par1Entity, this.currentPathIndex); + } + + /** + * Returns true if the EntityPath are the same. Non instance related equals. + */ + public boolean isSamePath(PathEntity par1PathEntity) { + if (par1PathEntity == null) { + return false; + } else if (par1PathEntity.points.length != this.points.length) { + return false; + } else { + for (int var2 = 0; var2 < this.points.length; ++var2) { + if (this.points[var2].xCoord != par1PathEntity.points[var2].xCoord + || this.points[var2].yCoord != par1PathEntity.points[var2].yCoord + || this.points[var2].zCoord != par1PathEntity.points[var2].zCoord) { + return false; + } + } + + return true; + } + } + + /** + * Returns true if the final PathPoint in the PathEntity is equal to Vec3D + * coords. + */ + public boolean isDestinationSame(Vec3 par1Vec3) { + PathPoint var2 = this.getFinalPathPoint(); + return var2 == null ? false : var2.xCoord == (int) par1Vec3.xCoord && var2.zCoord == (int) par1Vec3.zCoord; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/PathFinder.java b/sp-server/src/main/java/net/minecraft/src/PathFinder.java new file mode 100644 index 0000000..ad9e134 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/PathFinder.java @@ -0,0 +1,349 @@ +package net.minecraft.src; + +public class PathFinder { + /** Used to find obstacles */ + private IBlockAccess worldMap; + + /** The path being generated */ + private Path path = new Path(); + + /** The points in the path */ + private IntHashMap pointMap = new IntHashMap(); + + /** Selection of path points to add to the path */ + private PathPoint[] pathOptions = new PathPoint[32]; + + /** should the PathFinder go through wodden door blocks */ + private boolean isWoddenDoorAllowed; + + /** + * should the PathFinder disregard BlockMovement type materials in its path + */ + private boolean isMovementBlockAllowed; + private boolean isPathingInWater; + + /** tells the FathFinder to not stop pathing underwater */ + private boolean canEntityDrown; + + public PathFinder(IBlockAccess par1IBlockAccess, boolean par2, boolean par3, boolean par4, boolean par5) { + this.worldMap = par1IBlockAccess; + this.isWoddenDoorAllowed = par2; + this.isMovementBlockAllowed = par3; + this.isPathingInWater = par4; + this.canEntityDrown = par5; + } + + /** + * Creates a path from one entity to another within a minimum distance + */ + public PathEntity createEntityPathTo(Entity par1Entity, Entity par2Entity, float par3) { + return this.createEntityPathTo(par1Entity, par2Entity.posX, par2Entity.boundingBox.minY, par2Entity.posZ, par3); + } + + /** + * Creates a path from an entity to a specified location within a minimum + * distance + */ + public PathEntity createEntityPathTo(Entity par1Entity, int par2, int par3, int par4, float par5) { + return this.createEntityPathTo(par1Entity, (double) ((float) par2 + 0.5F), (double) ((float) par3 + 0.5F), + (double) ((float) par4 + 0.5F), par5); + } + + /** + * Internal implementation of creating a path from an entity to a point + */ + private PathEntity createEntityPathTo(Entity par1Entity, double par2, double par4, double par6, float par8) { + this.path.clearPath(); + this.pointMap.clearMap(); + boolean var9 = this.isPathingInWater; + int var10 = MathHelper.floor_double(par1Entity.boundingBox.minY + 0.5D); + + if (this.canEntityDrown && par1Entity.isInWater()) { + var10 = (int) par1Entity.boundingBox.minY; + + for (int var11 = this.worldMap.getBlockId(MathHelper.floor_double(par1Entity.posX), var10, + MathHelper.floor_double(par1Entity.posZ)); var11 == Block.waterMoving.blockID + || var11 == Block.waterStill.blockID; var11 = this.worldMap.getBlockId( + MathHelper.floor_double(par1Entity.posX), var10, + MathHelper.floor_double(par1Entity.posZ))) { + ++var10; + } + + var9 = this.isPathingInWater; + this.isPathingInWater = false; + } else { + var10 = MathHelper.floor_double(par1Entity.boundingBox.minY + 0.5D); + } + + PathPoint var15 = this.openPoint(MathHelper.floor_double(par1Entity.boundingBox.minX), var10, + MathHelper.floor_double(par1Entity.boundingBox.minZ)); + PathPoint var12 = this.openPoint(MathHelper.floor_double(par2 - (double) (par1Entity.width / 2.0F)), + MathHelper.floor_double(par4), MathHelper.floor_double(par6 - (double) (par1Entity.width / 2.0F))); + PathPoint var13 = new PathPoint(MathHelper.floor_float(par1Entity.width + 1.0F), + MathHelper.floor_float(par1Entity.height + 1.0F), MathHelper.floor_float(par1Entity.width + 1.0F)); + PathEntity var14 = this.addToPath(par1Entity, var15, var12, var13, par8); + this.isPathingInWater = var9; + return var14; + } + + /** + * Adds a path from start to end and returns the whole path (args: unused, + * start, end, unused, maxDistance) + */ + private PathEntity addToPath(Entity par1Entity, PathPoint par2PathPoint, PathPoint par3PathPoint, + PathPoint par4PathPoint, float par5) { + par2PathPoint.totalPathDistance = 0.0F; + par2PathPoint.distanceToNext = par2PathPoint.func_75832_b(par3PathPoint); + par2PathPoint.distanceToTarget = par2PathPoint.distanceToNext; + this.path.clearPath(); + this.path.addPoint(par2PathPoint); + PathPoint var6 = par2PathPoint; + + while (!this.path.isPathEmpty()) { + PathPoint var7 = this.path.dequeue(); + + if (var7.equals(par3PathPoint)) { + return this.createEntityPath(par2PathPoint, par3PathPoint); + } + + if (var7.func_75832_b(par3PathPoint) < var6.func_75832_b(par3PathPoint)) { + var6 = var7; + } + + var7.isFirst = true; + int var8 = this.findPathOptions(par1Entity, var7, par4PathPoint, par3PathPoint, par5); + + for (int var9 = 0; var9 < var8; ++var9) { + PathPoint var10 = this.pathOptions[var9]; + float var11 = var7.totalPathDistance + var7.func_75832_b(var10); + + if (!var10.isAssigned() || var11 < var10.totalPathDistance) { + var10.previous = var7; + var10.totalPathDistance = var11; + var10.distanceToNext = var10.func_75832_b(par3PathPoint); + + if (var10.isAssigned()) { + this.path.changeDistance(var10, var10.totalPathDistance + var10.distanceToNext); + } else { + var10.distanceToTarget = var10.totalPathDistance + var10.distanceToNext; + this.path.addPoint(var10); + } + } + } + } + + if (var6 == par2PathPoint) { + return null; + } else { + return this.createEntityPath(par2PathPoint, var6); + } + } + + /** + * populates pathOptions with available points and returns the number of options + * found (args: unused1, currentPoint, unused2, targetPoint, maxDistance) + */ + private int findPathOptions(Entity par1Entity, PathPoint par2PathPoint, PathPoint par3PathPoint, + PathPoint par4PathPoint, float par5) { + int var6 = 0; + byte var7 = 0; + + if (this.getVerticalOffset(par1Entity, par2PathPoint.xCoord, par2PathPoint.yCoord + 1, par2PathPoint.zCoord, + par3PathPoint) == 1) { + var7 = 1; + } + + PathPoint var8 = this.getSafePoint(par1Entity, par2PathPoint.xCoord, par2PathPoint.yCoord, + par2PathPoint.zCoord + 1, par3PathPoint, var7); + PathPoint var9 = this.getSafePoint(par1Entity, par2PathPoint.xCoord - 1, par2PathPoint.yCoord, + par2PathPoint.zCoord, par3PathPoint, var7); + PathPoint var10 = this.getSafePoint(par1Entity, par2PathPoint.xCoord + 1, par2PathPoint.yCoord, + par2PathPoint.zCoord, par3PathPoint, var7); + PathPoint var11 = this.getSafePoint(par1Entity, par2PathPoint.xCoord, par2PathPoint.yCoord, + par2PathPoint.zCoord - 1, par3PathPoint, var7); + + if (var8 != null && !var8.isFirst && var8.distanceTo(par4PathPoint) < par5) { + this.pathOptions[var6++] = var8; + } + + if (var9 != null && !var9.isFirst && var9.distanceTo(par4PathPoint) < par5) { + this.pathOptions[var6++] = var9; + } + + if (var10 != null && !var10.isFirst && var10.distanceTo(par4PathPoint) < par5) { + this.pathOptions[var6++] = var10; + } + + if (var11 != null && !var11.isFirst && var11.distanceTo(par4PathPoint) < par5) { + this.pathOptions[var6++] = var11; + } + + return var6; + } + + /** + * Returns a point that the entity can safely move to + */ + private PathPoint getSafePoint(Entity par1Entity, int par2, int par3, int par4, PathPoint par5PathPoint, int par6) { + PathPoint var7 = null; + int var8 = this.getVerticalOffset(par1Entity, par2, par3, par4, par5PathPoint); + + if (var8 == 2) { + return this.openPoint(par2, par3, par4); + } else { + if (var8 == 1) { + var7 = this.openPoint(par2, par3, par4); + } + + if (var7 == null && par6 > 0 && var8 != -3 && var8 != -4 + && this.getVerticalOffset(par1Entity, par2, par3 + par6, par4, par5PathPoint) == 1) { + var7 = this.openPoint(par2, par3 + par6, par4); + par3 += par6; + } + + if (var7 != null) { + int var9 = 0; + int var10 = 0; + + while (par3 > 0) { + var10 = this.getVerticalOffset(par1Entity, par2, par3 - 1, par4, par5PathPoint); + + if (this.isPathingInWater && var10 == -1) { + return null; + } + + if (var10 != 1) { + break; + } + + if (var9++ >= par1Entity.func_82143_as()) { + return null; + } + + --par3; + + if (par3 > 0) { + var7 = this.openPoint(par2, par3, par4); + } + } + + if (var10 == -2) { + return null; + } + } + + return var7; + } + } + + /** + * Returns a mapped point or creates and adds one + */ + private final PathPoint openPoint(int par1, int par2, int par3) { + int var4 = PathPoint.makeHash(par1, par2, par3); + PathPoint var5 = (PathPoint) this.pointMap.lookup(var4); + + if (var5 == null) { + var5 = new PathPoint(par1, par2, par3); + this.pointMap.addKey(var4, var5); + } + + return var5; + } + + /** + * Given an x y z, returns a vertical offset needed to search to find a block to + * stand on + */ + public int getVerticalOffset(Entity par1Entity, int par2, int par3, int par4, PathPoint par5PathPoint) { + return func_82565_a(par1Entity, par2, par3, par4, par5PathPoint, this.isPathingInWater, + this.isMovementBlockAllowed, this.isWoddenDoorAllowed); + } + + public static int func_82565_a(Entity par0Entity, int par1, int par2, int par3, PathPoint par4PathPoint, + boolean par5, boolean par6, boolean par7) { + boolean var8 = false; + + for (int var9 = par1; var9 < par1 + par4PathPoint.xCoord; ++var9) { + for (int var10 = par2; var10 < par2 + par4PathPoint.yCoord; ++var10) { + for (int var11 = par3; var11 < par3 + par4PathPoint.zCoord; ++var11) { + int var12 = par0Entity.worldObj.getBlockId(var9, var10, var11); + + if (var12 > 0) { + if (var12 == Block.trapdoor.blockID) { + var8 = true; + } else if (var12 != Block.waterMoving.blockID && var12 != Block.waterStill.blockID) { + if (!par7 && var12 == Block.doorWood.blockID) { + return 0; + } + } else { + if (par5) { + return -1; + } + + var8 = true; + } + + Block var13 = Block.blocksList[var12]; + int var14 = var13.getRenderType(); + + if (par0Entity.worldObj.blockGetRenderType(var9, var10, var11) == 9) { + int var18 = MathHelper.floor_double(par0Entity.posX); + int var16 = MathHelper.floor_double(par0Entity.posY); + int var17 = MathHelper.floor_double(par0Entity.posZ); + + if (par0Entity.worldObj.blockGetRenderType(var18, var16, var17) != 9 + && par0Entity.worldObj.blockGetRenderType(var18, var16 - 1, var17) != 9) { + return -3; + } + } else if (!var13.getBlocksMovement(par0Entity.worldObj, var9, var10, var11) + && (!par6 || var12 != Block.doorWood.blockID)) { + if (var14 == 11 || var12 == Block.fenceGate.blockID || var14 == 32) { + return -3; + } + + if (var12 == Block.trapdoor.blockID) { + return -4; + } + + Material var15 = var13.blockMaterial; + + if (var15 != Material.lava) { + return 0; + } + + if (!par0Entity.handleLavaMovement()) { + return -2; + } + } + } + } + } + } + + return var8 ? 2 : 1; + } + + /** + * Returns a new PathEntity for a given start and end point + */ + private PathEntity createEntityPath(PathPoint par1PathPoint, PathPoint par2PathPoint) { + int var3 = 1; + PathPoint var4; + + for (var4 = par2PathPoint; var4.previous != null; var4 = var4.previous) { + ++var3; + } + + PathPoint[] var5 = new PathPoint[var3]; + var4 = par2PathPoint; + --var3; + + for (var5[var3] = par2PathPoint; var4.previous != null; var5[var3] = var4) { + var4 = var4.previous; + --var3; + } + + return new PathEntity(var5); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/PathNavigate.java b/sp-server/src/main/java/net/minecraft/src/PathNavigate.java new file mode 100644 index 0000000..808a79d --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/PathNavigate.java @@ -0,0 +1,458 @@ +package net.minecraft.src; + +public class PathNavigate { + private EntityLiving theEntity; + private World worldObj; + + /** The PathEntity being followed. */ + private PathEntity currentPath; + private float speed; + + /** + * The number of blocks (extra) +/- in each axis that get pulled out as cache + * for the pathfinder's search space + */ + private float pathSearchRange; + private boolean noSunPathfind = false; + + /** Time, in number of ticks, following the current path */ + private int totalTicks; + + /** + * The time when the last position check was done (to detect successful + * movement) + */ + private int ticksAtLastPos; + + /** + * Coordinates of the entity's position last time a check was done (part of + * monitoring getting 'stuck') + */ + private Vec3 lastPosCheck = Vec3.createVectorHelper(0.0D, 0.0D, 0.0D); + + /** + * Specifically, if a wooden door block is even considered to be passable by the + * pathfinder + */ + private boolean canPassOpenWoodenDoors = true; + + /** If door blocks are considered passable even when closed */ + private boolean canPassClosedWoodenDoors = false; + + /** If water blocks are avoided (at least by the pathfinder) */ + private boolean avoidsWater = false; + + /** + * If the entity can swim. Swimming AI enables this and the pathfinder will also + * cause the entity to swim straight upwards when underwater + */ + private boolean canSwim = false; + + public PathNavigate(EntityLiving par1EntityLiving, World par2World, float par3) { + this.theEntity = par1EntityLiving; + this.worldObj = par2World; + this.pathSearchRange = par3; + } + + public void setAvoidsWater(boolean par1) { + this.avoidsWater = par1; + } + + public boolean getAvoidsWater() { + return this.avoidsWater; + } + + public void setBreakDoors(boolean par1) { + this.canPassClosedWoodenDoors = par1; + } + + /** + * Sets if the entity can enter open doors + */ + public void setEnterDoors(boolean par1) { + this.canPassOpenWoodenDoors = par1; + } + + /** + * Returns true if the entity can break doors, false otherwise + */ + public boolean getCanBreakDoors() { + return this.canPassClosedWoodenDoors; + } + + /** + * Sets if the path should avoid sunlight + */ + public void setAvoidSun(boolean par1) { + this.noSunPathfind = par1; + } + + /** + * Sets the speed + */ + public void setSpeed(float par1) { + this.speed = par1; + } + + /** + * Sets if the entity can swim + */ + public void setCanSwim(boolean par1) { + this.canSwim = par1; + } + + /** + * Returns the path to the given coordinates + */ + public PathEntity getPathToXYZ(double par1, double par3, double par5) { + return !this.canNavigate() ? null + : this.worldObj.getEntityPathToXYZ(this.theEntity, MathHelper.floor_double(par1), (int) par3, + MathHelper.floor_double(par5), this.pathSearchRange, this.canPassOpenWoodenDoors, + this.canPassClosedWoodenDoors, this.avoidsWater, this.canSwim); + } + + /** + * Try to find and set a path to XYZ. Returns true if successful. + */ + public boolean tryMoveToXYZ(double par1, double par3, double par5, float par7) { + PathEntity var8 = this.getPathToXYZ((double) MathHelper.floor_double(par1), (double) ((int) par3), + (double) MathHelper.floor_double(par5)); + return this.setPath(var8, par7); + } + + /** + * Returns the path to the given EntityLiving + */ + public PathEntity getPathToEntityLiving(EntityLiving par1EntityLiving) { + return !this.canNavigate() ? null + : this.worldObj.getPathEntityToEntity(this.theEntity, par1EntityLiving, this.pathSearchRange, + this.canPassOpenWoodenDoors, this.canPassClosedWoodenDoors, this.avoidsWater, this.canSwim); + } + + /** + * Try to find and set a path to EntityLiving. Returns true if successful. + */ + public boolean tryMoveToEntityLiving(EntityLiving par1EntityLiving, float par2) { + PathEntity var3 = this.getPathToEntityLiving(par1EntityLiving); + return var3 != null ? this.setPath(var3, par2) : false; + } + + /** + * sets the active path data if path is 100% unique compared to old path, checks + * to adjust path for sun avoiding ents and stores end coords + */ + public boolean setPath(PathEntity par1PathEntity, float par2) { + if (par1PathEntity == null) { + this.currentPath = null; + return false; + } else { + if (!par1PathEntity.isSamePath(this.currentPath)) { + this.currentPath = par1PathEntity; + } + + if (this.noSunPathfind) { + this.removeSunnyPath(); + } + + if (this.currentPath.getCurrentPathLength() == 0) { + return false; + } else { + this.speed = par2; + Vec3 var3 = this.getEntityPosition(); + this.ticksAtLastPos = this.totalTicks; + this.lastPosCheck.xCoord = var3.xCoord; + this.lastPosCheck.yCoord = var3.yCoord; + this.lastPosCheck.zCoord = var3.zCoord; + return true; + } + } + } + + /** + * gets the actively used PathEntity + */ + public PathEntity getPath() { + return this.currentPath; + } + + public void onUpdateNavigation() { + ++this.totalTicks; + + if (!this.noPath()) { + if (this.canNavigate()) { + this.pathFollow(); + } + + if (!this.noPath()) { + Vec3 var1 = this.currentPath.getPosition(this.theEntity); + + if (var1 != null) { + this.theEntity.getMoveHelper().setMoveTo(var1.xCoord, var1.yCoord, var1.zCoord, this.speed); + } + } + } + } + + private void pathFollow() { + Vec3 var1 = this.getEntityPosition(); + int var2 = this.currentPath.getCurrentPathLength(); + + for (int var3 = this.currentPath.getCurrentPathIndex(); var3 < this.currentPath + .getCurrentPathLength(); ++var3) { + if (this.currentPath.getPathPointFromIndex(var3).yCoord != (int) var1.yCoord) { + var2 = var3; + break; + } + } + + float var8 = this.theEntity.width * this.theEntity.width; + int var4; + + for (var4 = this.currentPath.getCurrentPathIndex(); var4 < var2; ++var4) { + if (var1.squareDistanceTo(this.currentPath.getVectorFromIndex(this.theEntity, var4)) < (double) var8) { + this.currentPath.setCurrentPathIndex(var4 + 1); + } + } + + var4 = MathHelper.ceiling_float_int(this.theEntity.width); + int var5 = (int) this.theEntity.height + 1; + int var6 = var4; + + for (int var7 = var2 - 1; var7 >= this.currentPath.getCurrentPathIndex(); --var7) { + if (this.isDirectPathBetweenPoints(var1, this.currentPath.getVectorFromIndex(this.theEntity, var7), var4, + var5, var6)) { + this.currentPath.setCurrentPathIndex(var7); + break; + } + } + + if (this.totalTicks - this.ticksAtLastPos > 100) { + if (var1.squareDistanceTo(this.lastPosCheck) < 2.25D) { + this.clearPathEntity(); + } + + this.ticksAtLastPos = this.totalTicks; + this.lastPosCheck.xCoord = var1.xCoord; + this.lastPosCheck.yCoord = var1.yCoord; + this.lastPosCheck.zCoord = var1.zCoord; + } + } + + /** + * If null path or reached the end + */ + public boolean noPath() { + return this.currentPath == null || this.currentPath.isFinished(); + } + + /** + * sets active PathEntity to null + */ + public void clearPathEntity() { + this.currentPath = null; + } + + private Vec3 getEntityPosition() { + return this.worldObj.getWorldVec3Pool().getVecFromPool(this.theEntity.posX, (double) this.getPathableYPos(), + this.theEntity.posZ); + } + + /** + * Gets the safe pathing Y position for the entity depending on if it can path + * swim or not + */ + private int getPathableYPos() { + if (this.theEntity.isInWater() && this.canSwim) { + int var1 = (int) this.theEntity.boundingBox.minY; + int var2 = this.worldObj.getBlockId(MathHelper.floor_double(this.theEntity.posX), var1, + MathHelper.floor_double(this.theEntity.posZ)); + int var3 = 0; + + do { + if (var2 != Block.waterMoving.blockID && var2 != Block.waterStill.blockID) { + return var1; + } + + ++var1; + var2 = this.worldObj.getBlockId(MathHelper.floor_double(this.theEntity.posX), var1, + MathHelper.floor_double(this.theEntity.posZ)); + ++var3; + } while (var3 <= 16); + + return (int) this.theEntity.boundingBox.minY; + } else { + return (int) (this.theEntity.boundingBox.minY + 0.5D); + } + } + + /** + * If on ground or swimming and can swim + */ + private boolean canNavigate() { + return this.theEntity.onGround || this.canSwim && this.isInFluid(); + } + + /** + * Returns true if the entity is in water or lava, false otherwise + */ + private boolean isInFluid() { + return this.theEntity.isInWater() || this.theEntity.handleLavaMovement(); + } + + /** + * Trims path data from the end to the first sun covered block + */ + private void removeSunnyPath() { + if (!this.worldObj.canBlockSeeTheSky(MathHelper.floor_double(this.theEntity.posX), + (int) (this.theEntity.boundingBox.minY + 0.5D), MathHelper.floor_double(this.theEntity.posZ))) { + for (int var1 = 0; var1 < this.currentPath.getCurrentPathLength(); ++var1) { + PathPoint var2 = this.currentPath.getPathPointFromIndex(var1); + + if (this.worldObj.canBlockSeeTheSky(var2.xCoord, var2.yCoord, var2.zCoord)) { + this.currentPath.setCurrentPathLength(var1 - 1); + return; + } + } + } + } + + /** + * Returns true when an entity of specified size could safely walk in a straight + * line between the two points. Args: pos1, pos2, entityXSize, entityYSize, + * entityZSize + */ + private boolean isDirectPathBetweenPoints(Vec3 par1Vec3, Vec3 par2Vec3, int par3, int par4, int par5) { + int var6 = MathHelper.floor_double(par1Vec3.xCoord); + int var7 = MathHelper.floor_double(par1Vec3.zCoord); + double var8 = par2Vec3.xCoord - par1Vec3.xCoord; + double var10 = par2Vec3.zCoord - par1Vec3.zCoord; + double var12 = var8 * var8 + var10 * var10; + + if (var12 < 1.0E-8D) { + return false; + } else { + double var14 = 1.0D / Math.sqrt(var12); + var8 *= var14; + var10 *= var14; + par3 += 2; + par5 += 2; + + if (!this.isSafeToStandAt(var6, (int) par1Vec3.yCoord, var7, par3, par4, par5, par1Vec3, var8, var10)) { + return false; + } else { + par3 -= 2; + par5 -= 2; + double var16 = 1.0D / Math.abs(var8); + double var18 = 1.0D / Math.abs(var10); + double var20 = (double) (var6 * 1) - par1Vec3.xCoord; + double var22 = (double) (var7 * 1) - par1Vec3.zCoord; + + if (var8 >= 0.0D) { + ++var20; + } + + if (var10 >= 0.0D) { + ++var22; + } + + var20 /= var8; + var22 /= var10; + int var24 = var8 < 0.0D ? -1 : 1; + int var25 = var10 < 0.0D ? -1 : 1; + int var26 = MathHelper.floor_double(par2Vec3.xCoord); + int var27 = MathHelper.floor_double(par2Vec3.zCoord); + int var28 = var26 - var6; + int var29 = var27 - var7; + + do { + if (var28 * var24 <= 0 && var29 * var25 <= 0) { + return true; + } + + if (var20 < var22) { + var20 += var16; + var6 += var24; + var28 = var26 - var6; + } else { + var22 += var18; + var7 += var25; + var29 = var27 - var7; + } + } while (this.isSafeToStandAt(var6, (int) par1Vec3.yCoord, var7, par3, par4, par5, par1Vec3, var8, + var10)); + + return false; + } + } + } + + /** + * Returns true when an entity could stand at a position, including solid blocks + * under the entire entity. Args: xOffset, yOffset, zOffset, entityXSize, + * entityYSize, entityZSize, originPosition, vecX, vecZ + */ + private boolean isSafeToStandAt(int par1, int par2, int par3, int par4, int par5, int par6, Vec3 par7Vec3, + double par8, double par10) { + int var12 = par1 - par4 / 2; + int var13 = par3 - par6 / 2; + + if (!this.isPositionClear(var12, par2, var13, par4, par5, par6, par7Vec3, par8, par10)) { + return false; + } else { + for (int var14 = var12; var14 < var12 + par4; ++var14) { + for (int var15 = var13; var15 < var13 + par6; ++var15) { + double var16 = (double) var14 + 0.5D - par7Vec3.xCoord; + double var18 = (double) var15 + 0.5D - par7Vec3.zCoord; + + if (var16 * par8 + var18 * par10 >= 0.0D) { + int var20 = this.worldObj.getBlockId(var14, par2 - 1, var15); + + if (var20 <= 0) { + return false; + } + + Material var21 = Block.blocksList[var20].blockMaterial; + + if (var21 == Material.water && !this.theEntity.isInWater()) { + return false; + } + + if (var21 == Material.lava) { + return false; + } + } + } + } + + return true; + } + } + + /** + * Returns true if an entity does not collide with any solid blocks at the + * position. Args: xOffset, yOffset, zOffset, entityXSize, entityYSize, + * entityZSize, originPosition, vecX, vecZ + */ + private boolean isPositionClear(int par1, int par2, int par3, int par4, int par5, int par6, Vec3 par7Vec3, + double par8, double par10) { + for (int var12 = par1; var12 < par1 + par4; ++var12) { + for (int var13 = par2; var13 < par2 + par5; ++var13) { + for (int var14 = par3; var14 < par3 + par6; ++var14) { + double var15 = (double) var12 + 0.5D - par7Vec3.xCoord; + double var17 = (double) var14 + 0.5D - par7Vec3.zCoord; + + if (var15 * par8 + var17 * par10 >= 0.0D) { + int var19 = this.worldObj.getBlockId(var12, var13, var14); + + if (var19 > 0 + && !Block.blocksList[var19].getBlocksMovement(this.worldObj, var12, var13, var14)) { + return false; + } + } + } + } + } + + return true; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/PathPoint.java b/sp-server/src/main/java/net/minecraft/src/PathPoint.java new file mode 100644 index 0000000..dac2d28 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/PathPoint.java @@ -0,0 +1,87 @@ +package net.minecraft.src; + +public class PathPoint { + /** The x coordinate of this point */ + public final int xCoord; + + /** The y coordinate of this point */ + public final int yCoord; + + /** The z coordinate of this point */ + public final int zCoord; + + /** A hash of the coordinates used to identify this point */ + private final int hash; + + /** The index of this point in its assigned path */ + int index = -1; + + /** The distance along the path to this point */ + float totalPathDistance; + + /** The linear distance to the next point */ + float distanceToNext; + + /** The distance to the target */ + float distanceToTarget; + + /** The point preceding this in its assigned path */ + PathPoint previous; + + /** Indicates this is the origin */ + public boolean isFirst = false; + + public PathPoint(int par1, int par2, int par3) { + this.xCoord = par1; + this.yCoord = par2; + this.zCoord = par3; + this.hash = makeHash(par1, par2, par3); + } + + public static int makeHash(int par0, int par1, int par2) { + return par1 & 255 | (par0 & 32767) << 8 | (par2 & 32767) << 24 | (par0 < 0 ? Integer.MIN_VALUE : 0) + | (par2 < 0 ? 32768 : 0); + } + + /** + * Returns the linear distance to another path point + */ + public float distanceTo(PathPoint par1PathPoint) { + float var2 = (float) (par1PathPoint.xCoord - this.xCoord); + float var3 = (float) (par1PathPoint.yCoord - this.yCoord); + float var4 = (float) (par1PathPoint.zCoord - this.zCoord); + return MathHelper.sqrt_float(var2 * var2 + var3 * var3 + var4 * var4); + } + + public float func_75832_b(PathPoint par1PathPoint) { + float var2 = (float) (par1PathPoint.xCoord - this.xCoord); + float var3 = (float) (par1PathPoint.yCoord - this.yCoord); + float var4 = (float) (par1PathPoint.zCoord - this.zCoord); + return var2 * var2 + var3 * var3 + var4 * var4; + } + + public boolean equals(Object par1Obj) { + if (!(par1Obj instanceof PathPoint)) { + return false; + } else { + PathPoint var2 = (PathPoint) par1Obj; + return this.hash == var2.hash && this.xCoord == var2.xCoord && this.yCoord == var2.yCoord + && this.zCoord == var2.zCoord; + } + } + + public int hashCode() { + return this.hash; + } + + /** + * Returns true if this point has already been assigned to a path + */ + public boolean isAssigned() { + return this.index >= 0; + } + + public String toString() { + return this.xCoord + ", " + this.yCoord + ", " + this.zCoord; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/PlayerCapabilities.java b/sp-server/src/main/java/net/minecraft/src/PlayerCapabilities.java new file mode 100644 index 0000000..0fd3fe1 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/PlayerCapabilities.java @@ -0,0 +1,62 @@ +package net.minecraft.src; + +public class PlayerCapabilities { + /** Disables player damage. */ + public boolean disableDamage = false; + + /** Sets/indicates whether the player is flying. */ + public boolean isFlying = false; + + /** whether or not to allow the player to fly when they double jump. */ + public boolean allowFlying = false; + + /** + * Used to determine if creative mode is enabled, and therefore if items should + * be depleted on usage + */ + public boolean isCreativeMode = false; + + /** Indicates whether the player is allowed to modify the surroundings */ + public boolean allowEdit = true; + private float flySpeed = 0.05F; + private float walkSpeed = 0.1F; + + public void writeCapabilitiesToNBT(NBTTagCompound par1NBTTagCompound) { + NBTTagCompound var2 = new NBTTagCompound(); + var2.setBoolean("invulnerable", this.disableDamage); + var2.setBoolean("flying", this.isFlying); + var2.setBoolean("mayfly", this.allowFlying); + var2.setBoolean("instabuild", this.isCreativeMode); + var2.setBoolean("mayBuild", this.allowEdit); + var2.setFloat("flySpeed", this.flySpeed); + var2.setFloat("walkSpeed", this.walkSpeed); + par1NBTTagCompound.setTag("abilities", var2); + } + + public void readCapabilitiesFromNBT(NBTTagCompound par1NBTTagCompound) { + if (par1NBTTagCompound.hasKey("abilities")) { + NBTTagCompound var2 = par1NBTTagCompound.getCompoundTag("abilities"); + this.disableDamage = var2.getBoolean("invulnerable"); + this.isFlying = var2.getBoolean("flying"); + this.allowFlying = var2.getBoolean("mayfly"); + this.isCreativeMode = var2.getBoolean("instabuild"); + + if (var2.hasKey("flySpeed")) { + this.flySpeed = var2.getFloat("flySpeed"); + this.walkSpeed = var2.getFloat("walkSpeed"); + } + + if (var2.hasKey("mayBuild")) { + this.allowEdit = var2.getBoolean("mayBuild"); + } + } + } + + public float getFlySpeed() { + return this.flySpeed; + } + + public float getWalkSpeed() { + return this.walkSpeed; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/PlayerInstance.java b/sp-server/src/main/java/net/minecraft/src/PlayerInstance.java new file mode 100644 index 0000000..9524e16 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/PlayerInstance.java @@ -0,0 +1,189 @@ +package net.minecraft.src; + +import java.util.ArrayList; +import java.util.List; + +class PlayerInstance { + /** the list of all players in this instance (chunk) */ + private final List players; + + /** the chunk the player currently resides in */ + private final ChunkCoordIntPair currentChunk; + + /** array of blocks to update this tick */ + private short[] blocksToUpdate; + + /** the number of blocks that need to be updated next tick */ + private int numBlocksToUpdate; + private int field_73260_f; + + final PlayerManager thePlayerManager; + + public PlayerInstance(PlayerManager par1PlayerManager, int par2, int par3) { + this.thePlayerManager = par1PlayerManager; + this.players = new ArrayList(); + this.blocksToUpdate = new short[64]; + this.numBlocksToUpdate = 0; + this.currentChunk = new ChunkCoordIntPair(par2, par3); + par1PlayerManager.getMinecraftServer().theChunkProviderServer.loadChunk(par2, par3); + } + + /** + * adds this player to the playerInstance + */ + public void addPlayer(EntityPlayerMP par1EntityPlayerMP) { + if (this.players.contains(par1EntityPlayerMP)) { + throw new IllegalStateException("Failed to add player. " + par1EntityPlayerMP + " already is in chunk " + + this.currentChunk.chunkXPos + ", " + this.currentChunk.chunkZPos); + } else { + this.players.add(par1EntityPlayerMP); + par1EntityPlayerMP.loadedChunks.add(this.currentChunk); + } + } + + /** + * remove player from this instance + */ + public void removePlayer(EntityPlayerMP par1EntityPlayerMP) { + if (this.players.contains(par1EntityPlayerMP)) { + par1EntityPlayerMP.playerNetServerHandler.sendPacket( + new Packet51MapChunk(PlayerManager.getWorldServer(this.thePlayerManager).getChunkFromChunkCoords( + this.currentChunk.chunkXPos, this.currentChunk.chunkZPos), true, 0)); + this.players.remove(par1EntityPlayerMP); + par1EntityPlayerMP.loadedChunks.remove(this.currentChunk); + + if (this.players.isEmpty()) { + long var2 = (long) this.currentChunk.chunkXPos + 2147483647L + | (long) this.currentChunk.chunkZPos + 2147483647L << 32; + PlayerManager.getChunkWatchers(this.thePlayerManager).remove(var2); + + if (this.numBlocksToUpdate > 0) { + PlayerManager.getChunkWatchersWithPlayers(this.thePlayerManager).remove(this); + } + + this.thePlayerManager.getMinecraftServer().theChunkProviderServer.dropChunk(this.currentChunk.chunkXPos, + this.currentChunk.chunkZPos); + } + } + } + + /** + * mark the block as changed so that it will update clients who need to know + * about it + */ + public void markBlockNeedsUpdate(int par1, int par2, int par3) { + if (this.numBlocksToUpdate == 0) { + PlayerManager.getChunkWatchersWithPlayers(this.thePlayerManager).add(this); + } + + this.field_73260_f |= 1 << (par2 >> 4); + + if (this.numBlocksToUpdate < 64) { + short var4 = (short) (par1 << 12 | par3 << 8 | par2); + + for (int var5 = 0; var5 < this.numBlocksToUpdate; ++var5) { + if (this.blocksToUpdate[var5] == var4) { + return; + } + } + + this.blocksToUpdate[this.numBlocksToUpdate++] = var4; + } + } + + /** + * sends the packet to all players in the current instance + */ + public void sendPacketToPlayersInInstance(Packet par1Packet) { + for (int var2 = 0; var2 < this.players.size(); ++var2) { + EntityPlayerMP var3 = (EntityPlayerMP) this.players.get(var2); + + if (!var3.loadedChunks.contains(this.currentChunk)) { + var3.playerNetServerHandler.sendPacket(par1Packet); + } + } + } + + public void onUpdate() { + if (this.numBlocksToUpdate != 0) { + int var1; + int var2; + int var3; + + if (this.numBlocksToUpdate == 1) { + var1 = this.currentChunk.chunkXPos * 16 + (this.blocksToUpdate[0] >> 12 & 15); + var2 = this.blocksToUpdate[0] & 255; + var3 = this.currentChunk.chunkZPos * 16 + (this.blocksToUpdate[0] >> 8 & 15); + this.sendPacketToPlayersInInstance( + new Packet53BlockChange(var1, var2, var3, PlayerManager.getWorldServer(this.thePlayerManager))); + + if (PlayerManager.getWorldServer(this.thePlayerManager).blockHasTileEntity(var1, var2, var3)) { + this.updateTileEntity( + PlayerManager.getWorldServer(this.thePlayerManager).getBlockTileEntity(var1, var2, var3)); + } + } else { + int var4; + + if (this.numBlocksToUpdate == 64) { + var1 = this.currentChunk.chunkXPos * 16; + var2 = this.currentChunk.chunkZPos * 16; + this.sendPacketToPlayersInInstance(new Packet51MapChunk( + PlayerManager.getWorldServer(this.thePlayerManager) + .getChunkFromChunkCoords(this.currentChunk.chunkXPos, this.currentChunk.chunkZPos), + false, this.field_73260_f)); + + for (var3 = 0; var3 < 16; ++var3) { + if ((this.field_73260_f & 1 << var3) != 0) { + var4 = var3 << 4; + List var5 = PlayerManager.getWorldServer(this.thePlayerManager).getTileEntityList(var1, + var4, var2, var1 + 16, var4 + 16, var2 + 16); + + for (int var6 = 0; var6 < var5.size(); ++var6) { + this.updateTileEntity((TileEntity) var5.get(var6)); + } + } + } + } else { + this.sendPacketToPlayersInInstance(new Packet52MultiBlockChange(this.currentChunk.chunkXPos, + this.currentChunk.chunkZPos, this.blocksToUpdate, this.numBlocksToUpdate, + PlayerManager.getWorldServer(this.thePlayerManager))); + + for (var1 = 0; var1 < this.numBlocksToUpdate; ++var1) { + var2 = this.currentChunk.chunkXPos * 16 + (this.blocksToUpdate[var1] >> 12 & 15); + var3 = this.blocksToUpdate[var1] & 255; + var4 = this.currentChunk.chunkZPos * 16 + (this.blocksToUpdate[var1] >> 8 & 15); + + if (PlayerManager.getWorldServer(this.thePlayerManager).blockHasTileEntity(var2, var3, var4)) { + this.updateTileEntity(PlayerManager.getWorldServer(this.thePlayerManager) + .getBlockTileEntity(var2, var3, var4)); + } + } + } + } + + this.numBlocksToUpdate = 0; + this.field_73260_f = 0; + } + } + + /** + * sends players update packet about the given entity + */ + private void updateTileEntity(TileEntity par1TileEntity) { + if (par1TileEntity != null) { + Packet var2 = par1TileEntity.getDescriptionPacket(); + + if (var2 != null) { + this.sendPacketToPlayersInInstance(var2); + } + } + } + + static ChunkCoordIntPair getChunkLocation(PlayerInstance par0PlayerInstance) { + return par0PlayerInstance.currentChunk; + } + + static List getPlayersInChunk(PlayerInstance par0PlayerInstance) { + return par0PlayerInstance.players; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/PlayerListBox.java b/sp-server/src/main/java/net/minecraft/src/PlayerListBox.java new file mode 100644 index 0000000..29bc118 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/PlayerListBox.java @@ -0,0 +1,34 @@ +package net.minecraft.src; + +import java.util.Vector; +import javax.swing.JList; +import net.minecraft.server.MinecraftServer; + +public class PlayerListBox extends JList implements IUpdatePlayerListBox { + /** Reference to the MinecraftServer object. */ + private MinecraftServer mcServer; + + /** Counts the number of updates. */ + private int updateCounter = 0; + + public PlayerListBox(MinecraftServer par1MinecraftServer) { + this.mcServer = par1MinecraftServer; + par1MinecraftServer.func_82010_a(this); + } + + /** + * Updates the JList with a new model. + */ + public void update() { + if (this.updateCounter++ % 20 == 0) { + Vector var1 = new Vector(); + + for (int var2 = 0; var2 < this.mcServer.getConfigurationManager().playerEntityList.size(); ++var2) { + var1.add( + ((EntityPlayerMP) this.mcServer.getConfigurationManager().playerEntityList.get(var2)).username); + } + + this.setListData(var1); + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/PlayerManager.java b/sp-server/src/main/java/net/minecraft/src/PlayerManager.java new file mode 100644 index 0000000..e96997c --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/PlayerManager.java @@ -0,0 +1,251 @@ +package net.minecraft.src; + +import java.util.ArrayList; +import java.util.List; + +public class PlayerManager { + private final WorldServer theWorldServer; + + /** players in the current instance */ + private final List players = new ArrayList(); + + /** the hash of all playerInstances created */ + private final LongHashMap playerInstances = new LongHashMap(); + + /** the playerInstances(chunks) that need to be updated */ + private final List playerInstancesToUpdate = new ArrayList(); + + /** + * Number of chunks the server sends to the client. Valid 3<=x<=15. In + * server.properties. + */ + private final int playerViewRadius; + + /** x, z direction vectors: east, south, west, north */ + private final int[][] xzDirectionsConst = new int[][] { { 1, 0 }, { 0, 1 }, { -1, 0 }, { 0, -1 } }; + + public PlayerManager(WorldServer par1WorldServer, int par2) { + if (par2 > 15) { + throw new IllegalArgumentException("Too big view radius!"); + } else if (par2 < 3) { + throw new IllegalArgumentException("Too small view radius!"); + } else { + this.playerViewRadius = par2; + this.theWorldServer = par1WorldServer; + } + } + + /** + * Returns the MinecraftServer associated with the PlayerManager. + */ + public WorldServer getMinecraftServer() { + return this.theWorldServer; + } + + /** + * updates all the player instances that need to be updated + */ + public void updatePlayerInstances() { + for (int var1 = 0; var1 < this.playerInstancesToUpdate.size(); ++var1) { + ((PlayerInstance) this.playerInstancesToUpdate.get(var1)).onUpdate(); + } + + this.playerInstancesToUpdate.clear(); + + if (this.players.isEmpty()) { + WorldProvider var2 = this.theWorldServer.provider; + + if (!var2.canRespawnHere()) { + this.theWorldServer.theChunkProviderServer.unloadAllChunks(); + } + } + } + + /** + * passi n the chunk x and y and a flag as to whether or not the instance should + * be made if it doesnt exist + */ + private PlayerInstance getPlayerInstance(int par1, int par2, boolean par3) { + long var4 = (long) par1 + 2147483647L | (long) par2 + 2147483647L << 32; + PlayerInstance var6 = (PlayerInstance) this.playerInstances.getValueByKey(var4); + + if (var6 == null && par3) { + var6 = new PlayerInstance(this, par1, par2); + this.playerInstances.add(var4, var6); + } + + return var6; + } + + public void markBlockNeedsUpdate(int par1, int par2, int par3) { + int var4 = par1 >> 4; + int var5 = par3 >> 4; + PlayerInstance var6 = this.getPlayerInstance(var4, var5, false); + + if (var6 != null) { + var6.markBlockNeedsUpdate(par1 & 15, par2, par3 & 15); + } + } + + /** + * Adds an EntityPlayerMP to the PlayerManager. + */ + public void addPlayer(EntityPlayerMP par1EntityPlayerMP) { + int var2 = (int) par1EntityPlayerMP.posX >> 4; + int var3 = (int) par1EntityPlayerMP.posZ >> 4; + par1EntityPlayerMP.managedPosX = par1EntityPlayerMP.posX; + par1EntityPlayerMP.managedPosZ = par1EntityPlayerMP.posZ; + + for (int var4 = var2 - this.playerViewRadius; var4 <= var2 + this.playerViewRadius; ++var4) { + for (int var5 = var3 - this.playerViewRadius; var5 <= var3 + this.playerViewRadius; ++var5) { + this.getPlayerInstance(var4, var5, true).addPlayer(par1EntityPlayerMP); + } + } + + this.players.add(par1EntityPlayerMP); + this.filterChunkLoadQueue(par1EntityPlayerMP); + } + + /** + * Removes all chunks from the given player's chunk load queue that are not in + * viewing range of the player. + */ + public void filterChunkLoadQueue(EntityPlayerMP par1EntityPlayerMP) { + ArrayList var2 = new ArrayList(par1EntityPlayerMP.loadedChunks); + int var3 = 0; + int var4 = this.playerViewRadius; + int var5 = (int) par1EntityPlayerMP.posX >> 4; + int var6 = (int) par1EntityPlayerMP.posZ >> 4; + int var7 = 0; + int var8 = 0; + ChunkCoordIntPair var9 = PlayerInstance.getChunkLocation(this.getPlayerInstance(var5, var6, true)); + par1EntityPlayerMP.loadedChunks.clear(); + + if (var2.contains(var9)) { + par1EntityPlayerMP.loadedChunks.add(var9); + } + + int var10; + + for (var10 = 1; var10 <= var4 * 2; ++var10) { + for (int var11 = 0; var11 < 2; ++var11) { + int[] var12 = this.xzDirectionsConst[var3++ % 4]; + + for (int var13 = 0; var13 < var10; ++var13) { + var7 += var12[0]; + var8 += var12[1]; + var9 = PlayerInstance.getChunkLocation(this.getPlayerInstance(var5 + var7, var6 + var8, true)); + + if (var2.contains(var9)) { + par1EntityPlayerMP.loadedChunks.add(var9); + } + } + } + } + + var3 %= 4; + + for (var10 = 0; var10 < var4 * 2; ++var10) { + var7 += this.xzDirectionsConst[var3][0]; + var8 += this.xzDirectionsConst[var3][1]; + var9 = PlayerInstance.getChunkLocation(this.getPlayerInstance(var5 + var7, var6 + var8, true)); + + if (var2.contains(var9)) { + par1EntityPlayerMP.loadedChunks.add(var9); + } + } + } + + /** + * Removes an EntityPlayerMP from the PlayerManager. + */ + public void removePlayer(EntityPlayerMP par1EntityPlayerMP) { + int var2 = (int) par1EntityPlayerMP.managedPosX >> 4; + int var3 = (int) par1EntityPlayerMP.managedPosZ >> 4; + + for (int var4 = var2 - this.playerViewRadius; var4 <= var2 + this.playerViewRadius; ++var4) { + for (int var5 = var3 - this.playerViewRadius; var5 <= var3 + this.playerViewRadius; ++var5) { + PlayerInstance var6 = this.getPlayerInstance(var4, var5, false); + + if (var6 != null) { + var6.removePlayer(par1EntityPlayerMP); + } + } + } + + this.players.remove(par1EntityPlayerMP); + } + + private boolean func_72684_a(int par1, int par2, int par3, int par4, int par5) { + int var6 = par1 - par3; + int var7 = par2 - par4; + return var6 >= -par5 && var6 <= par5 ? var7 >= -par5 && var7 <= par5 : false; + } + + /** + * update chunks around a player being moved by server logic (e.g. cart, boat) + */ + public void updateMountedMovingPlayer(EntityPlayerMP par1EntityPlayerMP) { + int var2 = (int) par1EntityPlayerMP.posX >> 4; + int var3 = (int) par1EntityPlayerMP.posZ >> 4; + double var4 = par1EntityPlayerMP.managedPosX - par1EntityPlayerMP.posX; + double var6 = par1EntityPlayerMP.managedPosZ - par1EntityPlayerMP.posZ; + double var8 = var4 * var4 + var6 * var6; + + if (var8 >= 64.0D) { + int var10 = (int) par1EntityPlayerMP.managedPosX >> 4; + int var11 = (int) par1EntityPlayerMP.managedPosZ >> 4; + int var12 = this.playerViewRadius; + int var13 = var2 - var10; + int var14 = var3 - var11; + + if (var13 != 0 || var14 != 0) { + for (int var15 = var2 - var12; var15 <= var2 + var12; ++var15) { + for (int var16 = var3 - var12; var16 <= var3 + var12; ++var16) { + if (!this.func_72684_a(var15, var16, var10, var11, var12)) { + this.getPlayerInstance(var15, var16, true).addPlayer(par1EntityPlayerMP); + } + + if (!this.func_72684_a(var15 - var13, var16 - var14, var2, var3, var12)) { + PlayerInstance var17 = this.getPlayerInstance(var15 - var13, var16 - var14, false); + + if (var17 != null) { + var17.removePlayer(par1EntityPlayerMP); + } + } + } + } + + this.filterChunkLoadQueue(par1EntityPlayerMP); + par1EntityPlayerMP.managedPosX = par1EntityPlayerMP.posX; + par1EntityPlayerMP.managedPosZ = par1EntityPlayerMP.posZ; + } + } + } + + public boolean isPlayerWatchingChunk(EntityPlayerMP par1EntityPlayerMP, int par2, int par3) { + PlayerInstance var4 = this.getPlayerInstance(par2, par3, false); + return var4 == null ? false + : PlayerInstance.getPlayersInChunk(var4).contains(par1EntityPlayerMP) + && !par1EntityPlayerMP.loadedChunks.contains(PlayerInstance.getChunkLocation(var4)); + } + + /** + * Get the furthest viewable block given player's view distance + */ + public static int getFurthestViewableBlock(int par0) { + return par0 * 16 - 16; + } + + static WorldServer getWorldServer(PlayerManager par0PlayerManager) { + return par0PlayerManager.theWorldServer; + } + + static LongHashMap getChunkWatchers(PlayerManager par0PlayerManager) { + return par0PlayerManager.playerInstances; + } + + static List getChunkWatchersWithPlayers(PlayerManager par0PlayerManager) { + return par0PlayerManager.playerInstancesToUpdate; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/PlayerNotFoundException.java b/sp-server/src/main/java/net/minecraft/src/PlayerNotFoundException.java new file mode 100644 index 0000000..f078172 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/PlayerNotFoundException.java @@ -0,0 +1,11 @@ +package net.minecraft.src; + +public class PlayerNotFoundException extends CommandException { + public PlayerNotFoundException() { + this("commands.generic.player.notFound", new Object[0]); + } + + public PlayerNotFoundException(String par1Str, Object... par2ArrayOfObj) { + super(par1Str, par2ArrayOfObj); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/PlayerPositionComparator.java b/sp-server/src/main/java/net/minecraft/src/PlayerPositionComparator.java new file mode 100644 index 0000000..923eeaa --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/PlayerPositionComparator.java @@ -0,0 +1,26 @@ +package net.minecraft.src; + +import java.util.Comparator; + +public class PlayerPositionComparator implements Comparator { + private final ChunkCoordinates theChunkCoordinates; + + public PlayerPositionComparator(ChunkCoordinates par1ChunkCoordinates) { + this.theChunkCoordinates = par1ChunkCoordinates; + } + + /** + * Compare the position of two players. + */ + public int comparePlayers(EntityPlayerMP par1EntityPlayerMP, EntityPlayerMP par2EntityPlayerMP) { + double var3 = par1EntityPlayerMP.getDistanceSq((double) this.theChunkCoordinates.posX, + (double) this.theChunkCoordinates.posY, (double) this.theChunkCoordinates.posZ); + double var5 = par2EntityPlayerMP.getDistanceSq((double) this.theChunkCoordinates.posX, + (double) this.theChunkCoordinates.posY, (double) this.theChunkCoordinates.posZ); + return var3 < var5 ? -1 : (var3 > var5 ? 1 : 0); + } + + public int compare(Object par1Obj, Object par2Obj) { + return this.comparePlayers((EntityPlayerMP) par1Obj, (EntityPlayerMP) par2Obj); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/PlayerSelector.java b/sp-server/src/main/java/net/minecraft/src/PlayerSelector.java new file mode 100644 index 0000000..82f9c68 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/PlayerSelector.java @@ -0,0 +1,291 @@ +package net.minecraft.src; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import net.minecraft.server.MinecraftServer; + +public class PlayerSelector { + /** + * This matches the at-tokens introduced for command blocks, including their + * arguments, if any. + */ + private static final Pattern tokenPattern = Pattern.compile("^@([parf])(?:\\[([\\w=,!-]*)\\])?$"); + + /** + * This matches things like "-1,,4", and is used for getting x,y,z,range from + * the token's argument list. + */ + private static final Pattern intListPattern = Pattern.compile("\\G([-!]?\\w*)(?:$|,)"); + + /** + * This matches things like "rm=4,c=2" and is used for handling named token + * arguments. + */ + private static final Pattern keyValueListPattern = Pattern.compile("\\G(\\w+)=([-!]?\\w*)(?:$|,)"); + + /** + * Returns the one player that matches the given at-token. Returns null if more + * than one player matches. + */ + public static EntityPlayerMP matchOnePlayer(ICommandSender par0ICommandSender, String par1Str) { + EntityPlayerMP[] var2 = matchPlayers(par0ICommandSender, par1Str); + return var2 != null && var2.length == 1 ? var2[0] : null; + } + + /** + * Returns a nicely-formatted string listing the matching players. + */ + public static String matchPlayersAsString(ICommandSender par0ICommandSender, String par1Str) { + EntityPlayerMP[] var2 = matchPlayers(par0ICommandSender, par1Str); + + if (var2 != null && var2.length != 0) { + String[] var3 = new String[var2.length]; + + for (int var4 = 0; var4 < var3.length; ++var4) { + var3[var4] = var2[var4].getTranslatedEntityName(); + } + + return CommandBase.joinNiceString(var3); + } else { + return null; + } + } + + /** + * Returns an array of all players matched by the given at-token. + */ + public static EntityPlayerMP[] matchPlayers(ICommandSender par0ICommandSender, String par1Str) { + Matcher var2 = tokenPattern.matcher(par1Str); + + if (var2.matches()) { + Map var3 = getArgumentMap(var2.group(2)); + String var4 = var2.group(1); + int var5 = getDefaultMinimumRange(var4); + int var6 = getDefaultMaximumRange(var4); + int var7 = getDefaultMinimumLevel(var4); + int var8 = getDefaultMaximumLevel(var4); + int var9 = getDefaultCount(var4); + int var10 = EnumGameType.NOT_SET.getID(); + ChunkCoordinates var11 = par0ICommandSender.getCommandSenderPosition(); + Map var12 = func_96560_a(var3); + String var13 = null; + String var14 = null; + + if (var3.containsKey("rm")) { + var5 = MathHelper.parseIntWithDefault((String) var3.get("rm"), var5); + } + + if (var3.containsKey("r")) { + var6 = MathHelper.parseIntWithDefault((String) var3.get("r"), var6); + } + + if (var3.containsKey("lm")) { + var7 = MathHelper.parseIntWithDefault((String) var3.get("lm"), var7); + } + + if (var3.containsKey("l")) { + var8 = MathHelper.parseIntWithDefault((String) var3.get("l"), var8); + } + + if (var3.containsKey("x")) { + var11.posX = MathHelper.parseIntWithDefault((String) var3.get("x"), var11.posX); + } + + if (var3.containsKey("y")) { + var11.posY = MathHelper.parseIntWithDefault((String) var3.get("y"), var11.posY); + } + + if (var3.containsKey("z")) { + var11.posZ = MathHelper.parseIntWithDefault((String) var3.get("z"), var11.posZ); + } + + if (var3.containsKey("m")) { + var10 = MathHelper.parseIntWithDefault((String) var3.get("m"), var10); + } + + if (var3.containsKey("c")) { + var9 = MathHelper.parseIntWithDefault((String) var3.get("c"), var9); + } + + if (var3.containsKey("team")) { + var14 = (String) var3.get("team"); + } + + if (var3.containsKey("name")) { + var13 = (String) var3.get("name"); + } + + List var15; + + if (!var4.equals("p") && !var4.equals("a")) { + if (!var4.equals("r")) { + return null; + } else { + var15 = MinecraftServer.getServer().getConfigurationManager().findPlayers(var11, var5, var6, 0, + var10, var7, var8, var12, var13, var14); + Collections.shuffle(var15); + var15 = var15.subList(0, Math.min(var9, var15.size())); + return var15 != null && !var15.isEmpty() ? (EntityPlayerMP[]) var15.toArray(new EntityPlayerMP[0]) + : new EntityPlayerMP[0]; + } + } else { + var15 = MinecraftServer.getServer().getConfigurationManager().findPlayers(var11, var5, var6, var9, + var10, var7, var8, var12, var13, var14); + return var15 != null && !var15.isEmpty() ? (EntityPlayerMP[]) var15.toArray(new EntityPlayerMP[0]) + : new EntityPlayerMP[0]; + } + } else { + return null; + } + } + + public static Map func_96560_a(Map par0Map) { + HashMap var1 = new HashMap(); + Iterator var2 = par0Map.keySet().iterator(); + + while (var2.hasNext()) { + String var3 = (String) var2.next(); + + if (var3.startsWith("score_") && var3.length() > "score_".length()) { + String var4 = var3.substring("score_".length()); + var1.put(var4, Integer.valueOf(MathHelper.parseIntWithDefault((String) par0Map.get(var3), 1))); + } + } + + return var1; + } + + /** + * Returns whether the given pattern can match more than one player. + */ + public static boolean matchesMultiplePlayers(String par0Str) { + Matcher var1 = tokenPattern.matcher(par0Str); + + if (var1.matches()) { + Map var2 = getArgumentMap(var1.group(2)); + String var3 = var1.group(1); + int var4 = getDefaultCount(var3); + + if (var2.containsKey("c")) { + var4 = MathHelper.parseIntWithDefault((String) var2.get("c"), var4); + } + + return var4 != 1; + } else { + return false; + } + } + + /** + * Returns whether the given token (parameter 1) has exactly the given arguments + * (parameter 2). + */ + public static boolean hasTheseArguments(String par0Str, String par1Str) { + Matcher var2 = tokenPattern.matcher(par0Str); + + if (var2.matches()) { + String var3 = var2.group(1); + return par1Str == null || par1Str.equals(var3); + } else { + return false; + } + } + + /** + * Returns whether the given token has any arguments set. + */ + public static boolean hasArguments(String par0Str) { + return hasTheseArguments(par0Str, (String) null); + } + + /** + * Gets the default minimum range (argument rm). + */ + private static final int getDefaultMinimumRange(String par0Str) { + return 0; + } + + /** + * Gets the default maximum range (argument r). + */ + private static final int getDefaultMaximumRange(String par0Str) { + return 0; + } + + /** + * Gets the default maximum experience level (argument l) + */ + private static final int getDefaultMaximumLevel(String par0Str) { + return Integer.MAX_VALUE; + } + + /** + * Gets the default minimum experience level (argument lm) + */ + private static final int getDefaultMinimumLevel(String par0Str) { + return 0; + } + + /** + * Gets the default number of players to return (argument c, 0 for infinite) + */ + private static final int getDefaultCount(String par0Str) { + return par0Str.equals("a") ? 0 : 1; + } + + /** + * Parses the given argument string, turning it into a HashMap<String, + * String> of name->value. + */ + private static Map getArgumentMap(String par0Str) { + HashMap var1 = new HashMap(); + + if (par0Str == null) { + return var1; + } else { + Matcher var2 = intListPattern.matcher(par0Str); + int var3 = 0; + int var4; + + for (var4 = -1; var2.find(); var4 = var2.end()) { + String var5 = null; + + switch (var3++) { + case 0: + var5 = "x"; + break; + + case 1: + var5 = "y"; + break; + + case 2: + var5 = "z"; + break; + + case 3: + var5 = "r"; + } + + if (var5 != null && var2.group(1).length() > 0) { + var1.put(var5, var2.group(1)); + } + } + + if (var4 < par0Str.length()) { + var2 = keyValueListPattern.matcher(var4 == -1 ? par0Str : par0Str.substring(var4)); + + while (var2.find()) { + var1.put(var2.group(1), var2.group(2)); + } + } + + return var1; + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/PlayerUsageSnooper.java b/sp-server/src/main/java/net/minecraft/src/PlayerUsageSnooper.java new file mode 100644 index 0000000..3836c5a --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/PlayerUsageSnooper.java @@ -0,0 +1,132 @@ +package net.minecraft.src; + +import java.lang.management.ManagementFactory; +import java.lang.management.RuntimeMXBean; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Timer; +import java.util.UUID; + +public class PlayerUsageSnooper { + /** String map for report data */ + private Map dataMap = new HashMap(); + private final String uniqueID = UUID.randomUUID().toString(); + + /** URL of the server to send the report to */ + private final URL serverUrl; + private final IPlayerUsage playerStatsCollector; + + /** set to fire the snooperThread every 15 mins */ + private final Timer threadTrigger = new Timer("Snooper Timer", true); + private final Object syncLock = new Object(); + private final long field_98224_g = System.currentTimeMillis(); + private boolean isRunning = false; + + /** incremented on every getSelfCounterFor */ + private int selfCounter = 0; + + public PlayerUsageSnooper(String par1Str, IPlayerUsage par2IPlayerUsage) { + try { + this.serverUrl = new URL("http://snoop.minecraft.net/" + par1Str + "?version=" + 1); + } catch (MalformedURLException var4) { + throw new IllegalArgumentException(); + } + + this.playerStatsCollector = par2IPlayerUsage; + } + + /** + * Note issuing start multiple times is not an error. + */ + public void startSnooper() { + if (!this.isRunning) { + this.isRunning = true; + this.addBaseDataToSnooper(); + this.threadTrigger.schedule(new PlayerUsageSnooperThread(this), 0L, 900000L); + } + } + + private void addBaseDataToSnooper() { + this.addJvmArgsToSnooper(); + this.addData("snooper_token", this.uniqueID); + this.addData("os_name", System.getProperty("os.name")); + this.addData("os_version", System.getProperty("os.version")); + this.addData("os_architecture", System.getProperty("os.arch")); + this.addData("java_version", System.getProperty("java.version")); + this.addData("version", "1.5.2"); + this.playerStatsCollector.addServerTypeToSnooper(this); + } + + private void addJvmArgsToSnooper() { + RuntimeMXBean var1 = ManagementFactory.getRuntimeMXBean(); + List var2 = var1.getInputArguments(); + int var3 = 0; + Iterator var4 = var2.iterator(); + + while (var4.hasNext()) { + String var5 = (String) var4.next(); + + if (var5.startsWith("-X")) { + this.addData("jvm_arg[" + var3++ + "]", var5); + } + } + + this.addData("jvm_args", Integer.valueOf(var3)); + } + + public void addMemoryStatsToSnooper() { + this.addData("memory_total", Long.valueOf(Runtime.getRuntime().totalMemory())); + this.addData("memory_max", Long.valueOf(Runtime.getRuntime().maxMemory())); + this.addData("memory_free", Long.valueOf(Runtime.getRuntime().freeMemory())); + this.addData("cpu_cores", Integer.valueOf(Runtime.getRuntime().availableProcessors())); + this.addData("run_time", Long.valueOf((System.currentTimeMillis() - this.field_98224_g) / 60L * 1000L)); + this.playerStatsCollector.addServerStatsToSnooper(this); + } + + /** + * Adds information to the report + */ + public void addData(String par1Str, Object par2Obj) { + Object var3 = this.syncLock; + + synchronized (this.syncLock) { + this.dataMap.put(par1Str, par2Obj); + } + } + + public boolean isSnooperRunning() { + return this.isRunning; + } + + public void stopSnooper() { + this.threadTrigger.cancel(); + } + + static IPlayerUsage getStatsCollectorFor(PlayerUsageSnooper par0PlayerUsageSnooper) { + return par0PlayerUsageSnooper.playerStatsCollector; + } + + static Object getSyncLockFor(PlayerUsageSnooper par0PlayerUsageSnooper) { + return par0PlayerUsageSnooper.syncLock; + } + + static Map getDataMapFor(PlayerUsageSnooper par0PlayerUsageSnooper) { + return par0PlayerUsageSnooper.dataMap; + } + + /** + * returns a value indicating how many times this function has been run on the + * snooper + */ + static int getSelfCounterFor(PlayerUsageSnooper par0PlayerUsageSnooper) { + return par0PlayerUsageSnooper.selfCounter++; + } + + static URL getServerUrlFor(PlayerUsageSnooper par0PlayerUsageSnooper) { + return par0PlayerUsageSnooper.serverUrl; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/PlayerUsageSnooperThread.java b/sp-server/src/main/java/net/minecraft/src/PlayerUsageSnooperThread.java new file mode 100644 index 0000000..b11133d --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/PlayerUsageSnooperThread.java @@ -0,0 +1,27 @@ +package net.minecraft.src; + +import java.util.HashMap; +import java.util.TimerTask; + +class PlayerUsageSnooperThread extends TimerTask { + /** The PlayerUsageSnooper object. */ + final PlayerUsageSnooper snooper; + + PlayerUsageSnooperThread(PlayerUsageSnooper par1PlayerUsageSnooper) { + this.snooper = par1PlayerUsageSnooper; + } + + public void run() { + if (PlayerUsageSnooper.getStatsCollectorFor(this.snooper).isSnooperEnabled()) { + HashMap var1; + + synchronized (PlayerUsageSnooper.getSyncLockFor(this.snooper)) { + var1 = new HashMap(PlayerUsageSnooper.getDataMapFor(this.snooper)); + var1.put("snooper_count", Integer.valueOf(PlayerUsageSnooper.getSelfCounterFor(this.snooper))); + } + + HttpUtil.sendPost(PlayerUsageSnooper.getStatsCollectorFor(this.snooper).getLogAgent(), + PlayerUsageSnooper.getServerUrlFor(this.snooper), var1, true); + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/PortalPosition.java b/sp-server/src/main/java/net/minecraft/src/PortalPosition.java new file mode 100644 index 0000000..0d728f2 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/PortalPosition.java @@ -0,0 +1,15 @@ +package net.minecraft.src; + +public class PortalPosition extends ChunkCoordinates { + /** The worldtime at which this PortalPosition was last verified */ + public long lastUpdateTime; + + /** The teleporter to which this PortalPosition applies */ + final Teleporter teleporterInstance; + + public PortalPosition(Teleporter par1Teleporter, int par2, int par3, int par4, long par5) { + super(par2, par3, par4); + this.teleporterInstance = par1Teleporter; + this.lastUpdateTime = par5; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/PositionImpl.java b/sp-server/src/main/java/net/minecraft/src/PositionImpl.java new file mode 100644 index 0000000..e0ca181 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/PositionImpl.java @@ -0,0 +1,25 @@ +package net.minecraft.src; + +public class PositionImpl implements IPosition { + protected final double x; + protected final double y; + protected final double z; + + public PositionImpl(double par1, double par3, double par5) { + this.x = par1; + this.y = par3; + this.z = par5; + } + + public double getX() { + return this.x; + } + + public double getY() { + return this.y; + } + + public double getZ() { + return this.z; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/Potion.java b/sp-server/src/main/java/net/minecraft/src/Potion.java new file mode 100644 index 0000000..52a37cc --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/Potion.java @@ -0,0 +1,235 @@ +package net.minecraft.src; + +public class Potion { + /** The array of potion types. */ + public static final Potion[] potionTypes = new Potion[32]; + public static final Potion field_76423_b = null; + public static final Potion moveSpeed = (new Potion(1, false, 8171462)).setPotionName("potion.moveSpeed") + .setIconIndex(0, 0); + public static final Potion moveSlowdown = (new Potion(2, true, 5926017)).setPotionName("potion.moveSlowdown") + .setIconIndex(1, 0); + public static final Potion digSpeed = (new Potion(3, false, 14270531)).setPotionName("potion.digSpeed") + .setIconIndex(2, 0).setEffectiveness(1.5D); + public static final Potion digSlowdown = (new Potion(4, true, 4866583)).setPotionName("potion.digSlowDown") + .setIconIndex(3, 0); + public static final Potion damageBoost = (new Potion(5, false, 9643043)).setPotionName("potion.damageBoost") + .setIconIndex(4, 0); + public static final Potion heal = (new PotionHealth(6, false, 16262179)).setPotionName("potion.heal"); + public static final Potion harm = (new PotionHealth(7, true, 4393481)).setPotionName("potion.harm"); + public static final Potion jump = (new Potion(8, false, 7889559)).setPotionName("potion.jump").setIconIndex(2, 1); + public static final Potion confusion = (new Potion(9, true, 5578058)).setPotionName("potion.confusion") + .setIconIndex(3, 1).setEffectiveness(0.25D); + + /** The regeneration Potion object. */ + public static final Potion regeneration = (new Potion(10, false, 13458603)).setPotionName("potion.regeneration") + .setIconIndex(7, 0).setEffectiveness(0.25D); + public static final Potion resistance = (new Potion(11, false, 10044730)).setPotionName("potion.resistance") + .setIconIndex(6, 1); + + /** The fire resistance Potion object. */ + public static final Potion fireResistance = (new Potion(12, false, 14981690)).setPotionName("potion.fireResistance") + .setIconIndex(7, 1); + + /** The water breathing Potion object. */ + public static final Potion waterBreathing = (new Potion(13, false, 3035801)).setPotionName("potion.waterBreathing") + .setIconIndex(0, 2); + + /** The invisibility Potion object. */ + public static final Potion invisibility = (new Potion(14, false, 8356754)).setPotionName("potion.invisibility") + .setIconIndex(0, 1); + + /** The blindness Potion object. */ + public static final Potion blindness = (new Potion(15, true, 2039587)).setPotionName("potion.blindness") + .setIconIndex(5, 1).setEffectiveness(0.25D); + + /** The night vision Potion object. */ + public static final Potion nightVision = (new Potion(16, false, 2039713)).setPotionName("potion.nightVision") + .setIconIndex(4, 1); + + /** The hunger Potion object. */ + public static final Potion hunger = (new Potion(17, true, 5797459)).setPotionName("potion.hunger").setIconIndex(1, + 1); + + /** The weakness Potion object. */ + public static final Potion weakness = (new Potion(18, true, 4738376)).setPotionName("potion.weakness") + .setIconIndex(5, 0); + + /** The poison Potion object. */ + public static final Potion poison = (new Potion(19, true, 5149489)).setPotionName("potion.poison") + .setIconIndex(6, 0).setEffectiveness(0.25D); + + /** The wither Potion object. */ + public static final Potion wither = (new Potion(20, true, 3484199)).setPotionName("potion.wither") + .setIconIndex(1, 2).setEffectiveness(0.25D); + public static final Potion field_76434_w = null; + public static final Potion field_76444_x = null; + public static final Potion field_76443_y = null; + public static final Potion field_76442_z = null; + public static final Potion field_76409_A = null; + public static final Potion field_76410_B = null; + public static final Potion field_76411_C = null; + public static final Potion field_76405_D = null; + public static final Potion field_76406_E = null; + public static final Potion field_76407_F = null; + public static final Potion field_76408_G = null; + + /** The Id of a Potion object. */ + public final int id; + + /** The name of the Potion. */ + private String name = ""; + + /** The index for the icon displayed when the potion effect is active. */ + private int statusIconIndex = -1; + + /** + * This field indicated if the effect is 'bad' - negative - for the entity. + */ + private final boolean isBadEffect; + private double effectiveness; + private boolean usable; + + /** Is the color of the liquid for this potion. */ + private final int liquidColor; + + protected Potion(int par1, boolean par2, int par3) { + this.id = par1; + potionTypes[par1] = this; + this.isBadEffect = par2; + + if (par2) { + this.effectiveness = 0.5D; + } else { + this.effectiveness = 1.0D; + } + + this.liquidColor = par3; + } + + /** + * Sets the index for the icon displayed in the player's inventory when the + * status is active. + */ + protected Potion setIconIndex(int par1, int par2) { + this.statusIconIndex = par1 + par2 * 8; + return this; + } + + /** + * returns the ID of the potion + */ + public int getId() { + return this.id; + } + + public void performEffect(EntityLiving par1EntityLiving, int par2) { + if (this.id == regeneration.id) { + if (par1EntityLiving.getHealth() < par1EntityLiving.getMaxHealth()) { + par1EntityLiving.heal(1); + } + } else if (this.id == poison.id) { + if (par1EntityLiving.getHealth() > 1) { + par1EntityLiving.attackEntityFrom(DamageSource.magic, 1); + } + } else if (this.id == wither.id) { + par1EntityLiving.attackEntityFrom(DamageSource.wither, 1); + } else if (this.id == hunger.id && par1EntityLiving instanceof EntityPlayer) { + ((EntityPlayer) par1EntityLiving).addExhaustion(0.025F * (float) (par2 + 1)); + } else if ((this.id != heal.id || par1EntityLiving.isEntityUndead()) + && (this.id != harm.id || !par1EntityLiving.isEntityUndead())) { + if (this.id == harm.id && !par1EntityLiving.isEntityUndead() + || this.id == heal.id && par1EntityLiving.isEntityUndead()) { + par1EntityLiving.attackEntityFrom(DamageSource.magic, 6 << par2); + } + } else { + par1EntityLiving.heal(6 << par2); + } + } + + /** + * Hits the provided entity with this potion's instant effect. + */ + public void affectEntity(EntityLiving par1EntityLiving, EntityLiving par2EntityLiving, int par3, double par4) { + int var6; + + if ((this.id != heal.id || par2EntityLiving.isEntityUndead()) + && (this.id != harm.id || !par2EntityLiving.isEntityUndead())) { + if (this.id == harm.id && !par2EntityLiving.isEntityUndead() + || this.id == heal.id && par2EntityLiving.isEntityUndead()) { + var6 = (int) (par4 * (double) (6 << par3) + 0.5D); + + if (par1EntityLiving == null) { + par2EntityLiving.attackEntityFrom(DamageSource.magic, var6); + } else { + par2EntityLiving.attackEntityFrom( + DamageSource.causeIndirectMagicDamage(par2EntityLiving, par1EntityLiving), var6); + } + } + } else { + var6 = (int) (par4 * (double) (6 << par3) + 0.5D); + par2EntityLiving.heal(var6); + } + } + + /** + * Returns true if the potion has an instant effect instead of a continuous one + * (eg Harming) + */ + public boolean isInstant() { + return false; + } + + /** + * checks if Potion effect is ready to be applied this tick. + */ + public boolean isReady(int par1, int par2) { + int var3; + + if (this.id != regeneration.id && this.id != poison.id) { + if (this.id == wither.id) { + var3 = 40 >> par2; + return var3 > 0 ? par1 % var3 == 0 : true; + } else { + return this.id == hunger.id; + } + } else { + var3 = 25 >> par2; + return var3 > 0 ? par1 % var3 == 0 : true; + } + } + + /** + * Set the potion name. + */ + public Potion setPotionName(String par1Str) { + this.name = par1Str; + return this; + } + + /** + * returns the name of the potion + */ + public String getName() { + return this.name; + } + + protected Potion setEffectiveness(double par1) { + this.effectiveness = par1; + return this; + } + + public double getEffectiveness() { + return this.effectiveness; + } + + public boolean isUsable() { + return this.usable; + } + + /** + * Returns the color of the potion liquid. + */ + public int getLiquidColor() { + return this.liquidColor; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/PotionEffect.java b/sp-server/src/main/java/net/minecraft/src/PotionEffect.java new file mode 100644 index 0000000..16495e7 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/PotionEffect.java @@ -0,0 +1,170 @@ +package net.minecraft.src; + +public class PotionEffect { + /** ID value of the potion this effect matches. */ + private int potionID; + + /** The duration of the potion effect */ + private int duration; + + /** The amplifier of the potion effect */ + private int amplifier; + + /** Whether the potion is a splash potion */ + private boolean isSplashPotion; + + /** Whether the potion effect came from a beacon */ + private boolean isAmbient; + + public PotionEffect(int par1, int par2) { + this(par1, par2, 0); + } + + public PotionEffect(int par1, int par2, int par3) { + this(par1, par2, par3, false); + } + + public PotionEffect(int par1, int par2, int par3, boolean par4) { + this.potionID = par1; + this.duration = par2; + this.amplifier = par3; + this.isAmbient = par4; + } + + public PotionEffect(PotionEffect par1PotionEffect) { + this.potionID = par1PotionEffect.potionID; + this.duration = par1PotionEffect.duration; + this.amplifier = par1PotionEffect.amplifier; + } + + /** + * merges the input PotionEffect into this one if this.amplifier <= + * tomerge.amplifier. The duration in the supplied potion effect is assumed to + * be greater. + */ + public void combine(PotionEffect par1PotionEffect) { + if (this.potionID != par1PotionEffect.potionID) { + System.err.println("This method should only be called for matching effects!"); + } + + if (par1PotionEffect.amplifier > this.amplifier) { + this.amplifier = par1PotionEffect.amplifier; + this.duration = par1PotionEffect.duration; + } else if (par1PotionEffect.amplifier == this.amplifier && this.duration < par1PotionEffect.duration) { + this.duration = par1PotionEffect.duration; + } else if (!par1PotionEffect.isAmbient && this.isAmbient) { + this.isAmbient = par1PotionEffect.isAmbient; + } + } + + /** + * Retrieve the ID of the potion this effect matches. + */ + public int getPotionID() { + return this.potionID; + } + + public int getDuration() { + return this.duration; + } + + public int getAmplifier() { + return this.amplifier; + } + + public boolean isSplashPotionEffect() { + return this.isSplashPotion; + } + + /** + * Set whether this potion is a splash potion. + */ + public void setSplashPotion(boolean par1) { + this.isSplashPotion = par1; + } + + /** + * Gets whether this potion effect originated from a beacon + */ + public boolean getIsAmbient() { + return this.isAmbient; + } + + public boolean onUpdate(EntityLiving par1EntityLiving) { + if (this.duration > 0) { + if (Potion.potionTypes[this.potionID].isReady(this.duration, this.amplifier)) { + this.performEffect(par1EntityLiving); + } + + this.deincrementDuration(); + } + + return this.duration > 0; + } + + private int deincrementDuration() { + return --this.duration; + } + + public void performEffect(EntityLiving par1EntityLiving) { + if (this.duration > 0) { + Potion.potionTypes[this.potionID].performEffect(par1EntityLiving, this.amplifier); + } + } + + public String getEffectName() { + return Potion.potionTypes[this.potionID].getName(); + } + + public int hashCode() { + return this.potionID; + } + + public String toString() { + String var1 = ""; + + if (this.getAmplifier() > 0) { + var1 = this.getEffectName() + " x " + (this.getAmplifier() + 1) + ", Duration: " + this.getDuration(); + } else { + var1 = this.getEffectName() + ", Duration: " + this.getDuration(); + } + + if (this.isSplashPotion) { + var1 = var1 + ", Splash: true"; + } + + return Potion.potionTypes[this.potionID].isUsable() ? "(" + var1 + ")" : var1; + } + + public boolean equals(Object par1Obj) { + if (!(par1Obj instanceof PotionEffect)) { + return false; + } else { + PotionEffect var2 = (PotionEffect) par1Obj; + return this.potionID == var2.potionID && this.amplifier == var2.amplifier && this.duration == var2.duration + && this.isSplashPotion == var2.isSplashPotion && this.isAmbient == var2.isAmbient; + } + } + + /** + * Write a custom potion effect to a potion item's NBT data. + */ + public NBTTagCompound writeCustomPotionEffectToNBT(NBTTagCompound par1NBTTagCompound) { + par1NBTTagCompound.setByte("Id", (byte) this.getPotionID()); + par1NBTTagCompound.setByte("Amplifier", (byte) this.getAmplifier()); + par1NBTTagCompound.setInteger("Duration", this.getDuration()); + par1NBTTagCompound.setBoolean("Ambient", this.getIsAmbient()); + return par1NBTTagCompound; + } + + /** + * Read a custom potion effect from a potion item's NBT data. + */ + public static PotionEffect readCustomPotionEffectFromNBT(NBTTagCompound par0NBTTagCompound) { + byte var1 = par0NBTTagCompound.getByte("Id"); + byte var2 = par0NBTTagCompound.getByte("Amplifier"); + int var3 = par0NBTTagCompound.getInteger("Duration"); + boolean var4 = par0NBTTagCompound.getBoolean("Ambient"); + return new PotionEffect(var1, var3, var2, var4); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/PotionHealth.java b/sp-server/src/main/java/net/minecraft/src/PotionHealth.java new file mode 100644 index 0000000..f9d60e3 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/PotionHealth.java @@ -0,0 +1,22 @@ +package net.minecraft.src; + +public class PotionHealth extends Potion { + public PotionHealth(int par1, boolean par2, int par3) { + super(par1, par2, par3); + } + + /** + * Returns true if the potion has an instant effect instead of a continuous one + * (eg Harming) + */ + public boolean isInstant() { + return true; + } + + /** + * checks if Potion effect is ready to be applied this tick. + */ + public boolean isReady(int par1, int par2) { + return par1 >= 1; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/PotionHelper.java b/sp-server/src/main/java/net/minecraft/src/PotionHelper.java new file mode 100644 index 0000000..f171ac1 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/PotionHelper.java @@ -0,0 +1,481 @@ +package net.minecraft.src; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; + +public class PotionHelper { + public static final String field_77924_a = null; + public static final String sugarEffect; + public static final String ghastTearEffect = "+0-1-2-3&4-4+13"; + public static final String spiderEyeEffect; + public static final String fermentedSpiderEyeEffect; + public static final String speckledMelonEffect; + public static final String blazePowderEffect; + public static final String magmaCreamEffect; + public static final String redstoneEffect; + public static final String glowstoneEffect; + public static final String gunpowderEffect; + public static final String goldenCarrotEffect; + private static final HashMap potionRequirements = new HashMap(); + + /** Potion effect amplifier map */ + private static final HashMap potionAmplifiers = new HashMap(); + private static final HashMap field_77925_n; + + /** An array of possible potion prefix names, as translation IDs. */ + private static final String[] potionPrefixes; + + /** + * Checks if the bit at 1 << j is on in i. + */ + public static boolean checkFlag(int par0, int par1) { + return (par0 & 1 << par1) != 0; + } + + /** + * Returns 1 if the flag is set, 0 if it is not set. + */ + private static int isFlagSet(int par0, int par1) { + return checkFlag(par0, par1) ? 1 : 0; + } + + /** + * Returns 0 if the flag is set, 1 if it is not set. + */ + private static int isFlagUnset(int par0, int par1) { + return checkFlag(par0, par1) ? 0 : 1; + } + + public static int func_77909_a(int par0) { + return func_77908_a(par0, 5, 4, 3, 2, 1); + } + + /** + * Given a {@link Collection}<{@link PotionEffect}> will return an Integer + * color. + */ + public static int calcPotionLiquidColor(Collection par0Collection) { + int var1 = 3694022; + + if (par0Collection != null && !par0Collection.isEmpty()) { + float var2 = 0.0F; + float var3 = 0.0F; + float var4 = 0.0F; + float var5 = 0.0F; + Iterator var6 = par0Collection.iterator(); + + while (var6.hasNext()) { + PotionEffect var7 = (PotionEffect) var6.next(); + int var8 = Potion.potionTypes[var7.getPotionID()].getLiquidColor(); + + for (int var9 = 0; var9 <= var7.getAmplifier(); ++var9) { + var2 += (float) (var8 >> 16 & 255) / 255.0F; + var3 += (float) (var8 >> 8 & 255) / 255.0F; + var4 += (float) (var8 >> 0 & 255) / 255.0F; + ++var5; + } + } + + var2 = var2 / var5 * 255.0F; + var3 = var3 / var5 * 255.0F; + var4 = var4 / var5 * 255.0F; + return (int) var2 << 16 | (int) var3 << 8 | (int) var4; + } else { + return var1; + } + } + + public static boolean func_82817_b(Collection par0Collection) { + Iterator var1 = par0Collection.iterator(); + PotionEffect var2; + + do { + if (!var1.hasNext()) { + return true; + } + + var2 = (PotionEffect) var1.next(); + } while (var2.getIsAmbient()); + + return false; + } + + public static String func_77905_c(int par0) { + int var1 = func_77909_a(par0); + return potionPrefixes[var1]; + } + + private static int func_77904_a(boolean par0, boolean par1, boolean par2, int par3, int par4, int par5, int par6) { + int var7 = 0; + + if (par0) { + var7 = isFlagUnset(par6, par4); + } else if (par3 != -1) { + if (par3 == 0 && countSetFlags(par6) == par4) { + var7 = 1; + } else if (par3 == 1 && countSetFlags(par6) > par4) { + var7 = 1; + } else if (par3 == 2 && countSetFlags(par6) < par4) { + var7 = 1; + } + } else { + var7 = isFlagSet(par6, par4); + } + + if (par1) { + var7 *= par5; + } + + if (par2) { + var7 *= -1; + } + + return var7; + } + + /** + * Returns the number of 1 bits in the given integer. + */ + private static int countSetFlags(int par0) { + int var1; + + for (var1 = 0; par0 > 0; ++var1) { + par0 &= par0 - 1; + } + + return var1; + } + + private static int parsePotionEffects(String par0Str, int par1, int par2, int par3) { + if (par1 < par0Str.length() && par2 >= 0 && par1 < par2) { + int var4 = par0Str.indexOf(124, par1); + int var5; + int var17; + + if (var4 >= 0 && var4 < par2) { + var5 = parsePotionEffects(par0Str, par1, var4 - 1, par3); + + if (var5 > 0) { + return var5; + } else { + var17 = parsePotionEffects(par0Str, var4 + 1, par2, par3); + return var17 > 0 ? var17 : 0; + } + } else { + var5 = par0Str.indexOf(38, par1); + + if (var5 >= 0 && var5 < par2) { + var17 = parsePotionEffects(par0Str, par1, var5 - 1, par3); + + if (var17 <= 0) { + return 0; + } else { + int var18 = parsePotionEffects(par0Str, var5 + 1, par2, par3); + return var18 <= 0 ? 0 : (var17 > var18 ? var17 : var18); + } + } else { + boolean var6 = false; + boolean var7 = false; + boolean var8 = false; + boolean var9 = false; + boolean var10 = false; + byte var11 = -1; + int var12 = 0; + int var13 = 0; + int var14 = 0; + + for (int var15 = par1; var15 < par2; ++var15) { + char var16 = par0Str.charAt(var15); + + if (var16 >= 48 && var16 <= 57) { + if (var6) { + var13 = var16 - 48; + var7 = true; + } else { + var12 *= 10; + var12 += var16 - 48; + var8 = true; + } + } else if (var16 == 42) { + var6 = true; + } else if (var16 == 33) { + if (var8) { + var14 += func_77904_a(var9, var7, var10, var11, var12, var13, par3); + var9 = false; + var10 = false; + var6 = false; + var7 = false; + var8 = false; + var13 = 0; + var12 = 0; + var11 = -1; + } + + var9 = true; + } else if (var16 == 45) { + if (var8) { + var14 += func_77904_a(var9, var7, var10, var11, var12, var13, par3); + var9 = false; + var10 = false; + var6 = false; + var7 = false; + var8 = false; + var13 = 0; + var12 = 0; + var11 = -1; + } + + var10 = true; + } else if (var16 != 61 && var16 != 60 && var16 != 62) { + if (var16 == 43 && var8) { + var14 += func_77904_a(var9, var7, var10, var11, var12, var13, par3); + var9 = false; + var10 = false; + var6 = false; + var7 = false; + var8 = false; + var13 = 0; + var12 = 0; + var11 = -1; + } + } else { + if (var8) { + var14 += func_77904_a(var9, var7, var10, var11, var12, var13, par3); + var9 = false; + var10 = false; + var6 = false; + var7 = false; + var8 = false; + var13 = 0; + var12 = 0; + var11 = -1; + } + + if (var16 == 61) { + var11 = 0; + } else if (var16 == 60) { + var11 = 2; + } else if (var16 == 62) { + var11 = 1; + } + } + } + + if (var8) { + var14 += func_77904_a(var9, var7, var10, var11, var12, var13, par3); + } + + return var14; + } + } + } else { + return 0; + } + } + + /** + * Returns a list of effects for the specified potion damage value. + */ + public static List getPotionEffects(int par0, boolean par1) { + ArrayList var2 = null; + Potion[] var3 = Potion.potionTypes; + int var4 = var3.length; + + for (int var5 = 0; var5 < var4; ++var5) { + Potion var6 = var3[var5]; + + if (var6 != null && (!var6.isUsable() || par1)) { + String var7 = (String) potionRequirements.get(Integer.valueOf(var6.getId())); + + if (var7 != null) { + int var8 = parsePotionEffects(var7, 0, var7.length(), par0); + + if (var8 > 0) { + int var9 = 0; + String var10 = (String) potionAmplifiers.get(Integer.valueOf(var6.getId())); + + if (var10 != null) { + var9 = parsePotionEffects(var10, 0, var10.length(), par0); + + if (var9 < 0) { + var9 = 0; + } + } + + if (var6.isInstant()) { + var8 = 1; + } else { + var8 = 1200 * (var8 * 3 + (var8 - 1) * 2); + var8 >>= var9; + var8 = (int) Math.round((double) var8 * var6.getEffectiveness()); + + if ((par0 & 16384) != 0) { + var8 = (int) Math.round((double) var8 * 0.75D + 0.5D); + } + } + + if (var2 == null) { + var2 = new ArrayList(); + } + + PotionEffect var11 = new PotionEffect(var6.getId(), var8, var9); + + if ((par0 & 16384) != 0) { + var11.setSplashPotion(true); + } + + var2.add(var11); + } + } + } + } + + return var2; + } + + /** + * Manipulates the specified bit of the potion damage value according to the + * rules passed from applyIngredient. + */ + private static int brewBitOperations(int par0, int par1, boolean par2, boolean par3, boolean par4) { + if (par4) { + if (!checkFlag(par0, par1)) { + return 0; + } + } else if (par2) { + par0 &= ~(1 << par1); + } else if (par3) { + if ((par0 & 1 << par1) == 0) { + par0 |= 1 << par1; + } else { + par0 &= ~(1 << par1); + } + } else { + par0 |= 1 << par1; + } + + return par0; + } + + /** + * Returns the new potion damage value after the specified ingredient info is + * applied to the specified potion. + */ + public static int applyIngredient(int par0, String par1Str) { + byte var2 = 0; + int var3 = par1Str.length(); + boolean var4 = false; + boolean var5 = false; + boolean var6 = false; + boolean var7 = false; + int var8 = 0; + + for (int var9 = var2; var9 < var3; ++var9) { + char var10 = par1Str.charAt(var9); + + if (var10 >= 48 && var10 <= 57) { + var8 *= 10; + var8 += var10 - 48; + var4 = true; + } else if (var10 == 33) { + if (var4) { + par0 = brewBitOperations(par0, var8, var6, var5, var7); + var7 = false; + var5 = false; + var6 = false; + var4 = false; + var8 = 0; + } + + var5 = true; + } else if (var10 == 45) { + if (var4) { + par0 = brewBitOperations(par0, var8, var6, var5, var7); + var7 = false; + var5 = false; + var6 = false; + var4 = false; + var8 = 0; + } + + var6 = true; + } else if (var10 == 43) { + if (var4) { + par0 = brewBitOperations(par0, var8, var6, var5, var7); + var7 = false; + var5 = false; + var6 = false; + var4 = false; + var8 = 0; + } + } else if (var10 == 38) { + if (var4) { + par0 = brewBitOperations(par0, var8, var6, var5, var7); + var7 = false; + var5 = false; + var6 = false; + var4 = false; + var8 = 0; + } + + var7 = true; + } + } + + if (var4) { + par0 = brewBitOperations(par0, var8, var6, var5, var7); + } + + return par0 & 32767; + } + + public static int func_77908_a(int par0, int par1, int par2, int par3, int par4, int par5) { + return (checkFlag(par0, par1) ? 16 : 0) | (checkFlag(par0, par2) ? 8 : 0) | (checkFlag(par0, par3) ? 4 : 0) + | (checkFlag(par0, par4) ? 2 : 0) | (checkFlag(par0, par5) ? 1 : 0); + } + + static { + potionRequirements.put(Integer.valueOf(Potion.regeneration.getId()), "0 & !1 & !2 & !3 & 0+6"); + sugarEffect = "-0+1-2-3&4-4+13"; + potionRequirements.put(Integer.valueOf(Potion.moveSpeed.getId()), "!0 & 1 & !2 & !3 & 1+6"); + magmaCreamEffect = "+0+1-2-3&4-4+13"; + potionRequirements.put(Integer.valueOf(Potion.fireResistance.getId()), "0 & 1 & !2 & !3 & 0+6"); + speckledMelonEffect = "+0-1+2-3&4-4+13"; + potionRequirements.put(Integer.valueOf(Potion.heal.getId()), "0 & !1 & 2 & !3"); + spiderEyeEffect = "-0-1+2-3&4-4+13"; + potionRequirements.put(Integer.valueOf(Potion.poison.getId()), "!0 & !1 & 2 & !3 & 2+6"); + fermentedSpiderEyeEffect = "-0+3-4+13"; + potionRequirements.put(Integer.valueOf(Potion.weakness.getId()), "!0 & !1 & !2 & 3 & 3+6"); + potionRequirements.put(Integer.valueOf(Potion.harm.getId()), "!0 & !1 & 2 & 3"); + potionRequirements.put(Integer.valueOf(Potion.moveSlowdown.getId()), "!0 & 1 & !2 & 3 & 3+6"); + blazePowderEffect = "+0-1-2+3&4-4+13"; + potionRequirements.put(Integer.valueOf(Potion.damageBoost.getId()), "0 & !1 & !2 & 3 & 3+6"); + goldenCarrotEffect = "-0+1+2-3+13&4-4"; + potionRequirements.put(Integer.valueOf(Potion.nightVision.getId()), "!0 & 1 & 2 & !3 & 2+6"); + potionRequirements.put(Integer.valueOf(Potion.invisibility.getId()), "!0 & 1 & 2 & 3 & 2+6"); + glowstoneEffect = "+5-6-7"; + potionAmplifiers.put(Integer.valueOf(Potion.moveSpeed.getId()), "5"); + potionAmplifiers.put(Integer.valueOf(Potion.digSpeed.getId()), "5"); + potionAmplifiers.put(Integer.valueOf(Potion.damageBoost.getId()), "5"); + potionAmplifiers.put(Integer.valueOf(Potion.regeneration.getId()), "5"); + potionAmplifiers.put(Integer.valueOf(Potion.harm.getId()), "5"); + potionAmplifiers.put(Integer.valueOf(Potion.heal.getId()), "5"); + potionAmplifiers.put(Integer.valueOf(Potion.resistance.getId()), "5"); + potionAmplifiers.put(Integer.valueOf(Potion.poison.getId()), "5"); + redstoneEffect = "-5+6-7"; + gunpowderEffect = "+14&13-13"; + field_77925_n = new HashMap(); + potionPrefixes = new String[] { "potion.prefix.mundane", "potion.prefix.uninteresting", "potion.prefix.bland", + "potion.prefix.clear", "potion.prefix.milky", "potion.prefix.diffuse", "potion.prefix.artless", + "potion.prefix.thin", "potion.prefix.awkward", "potion.prefix.flat", "potion.prefix.bulky", + "potion.prefix.bungling", "potion.prefix.buttered", "potion.prefix.smooth", "potion.prefix.suave", + "potion.prefix.debonair", "potion.prefix.thick", "potion.prefix.elegant", "potion.prefix.fancy", + "potion.prefix.charming", "potion.prefix.dashing", "potion.prefix.refined", "potion.prefix.cordial", + "potion.prefix.sparkling", "potion.prefix.potent", "potion.prefix.foul", "potion.prefix.odorless", + "potion.prefix.rank", "potion.prefix.harsh", "potion.prefix.acrid", "potion.prefix.gross", + "potion.prefix.stinky" }; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/Profiler.java b/sp-server/src/main/java/net/minecraft/src/Profiler.java new file mode 100644 index 0000000..66452ac --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/Profiler.java @@ -0,0 +1,162 @@ +package net.minecraft.src; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +public class Profiler { + /** List of parent sections */ + private final List sectionList = new ArrayList(); + + /** List of timestamps (System.nanoTime) */ + private final List timestampList = new ArrayList(); + + /** Flag profiling enabled */ + public boolean profilingEnabled = false; + + /** Current profiling section */ + private String profilingSection = ""; + + /** Profiling map */ + private final Map profilingMap = new HashMap(); + + /** + * Clear profiling. + */ + public void clearProfiling() { + this.profilingMap.clear(); + this.profilingSection = ""; + this.sectionList.clear(); + } + + /** + * Start section + */ + public void startSection(String par1Str) { + if (this.profilingEnabled) { + if (this.profilingSection.length() > 0) { + this.profilingSection = this.profilingSection + "."; + } + + this.profilingSection = this.profilingSection + par1Str; + this.sectionList.add(this.profilingSection); + this.timestampList.add(Long.valueOf(System.nanoTime())); + } + } + + /** + * End section + */ + public void endSection() { + if (this.profilingEnabled) { + long var1 = System.nanoTime(); + long var3 = ((Long) this.timestampList.remove(this.timestampList.size() - 1)).longValue(); + this.sectionList.remove(this.sectionList.size() - 1); + long var5 = var1 - var3; + + if (this.profilingMap.containsKey(this.profilingSection)) { + this.profilingMap.put(this.profilingSection, + Long.valueOf(((Long) this.profilingMap.get(this.profilingSection)).longValue() + var5)); + } else { + this.profilingMap.put(this.profilingSection, Long.valueOf(var5)); + } + + if (var5 > 100000000L) { + System.out.println("Something\'s taking too long! \'" + this.profilingSection + "\' took aprox " + + (double) var5 / 1000000.0D + " ms"); + } + + this.profilingSection = !this.sectionList.isEmpty() + ? (String) this.sectionList.get(this.sectionList.size() - 1) + : ""; + } + } + + /** + * Get profiling data + */ + public List getProfilingData(String par1Str) { + if (!this.profilingEnabled) { + return null; + } else { + long var3 = this.profilingMap.containsKey("root") ? ((Long) this.profilingMap.get("root")).longValue() : 0L; + long var5 = this.profilingMap.containsKey(par1Str) ? ((Long) this.profilingMap.get(par1Str)).longValue() + : -1L; + ArrayList var7 = new ArrayList(); + + if (par1Str.length() > 0) { + par1Str = par1Str + "."; + } + + long var8 = 0L; + Iterator var10 = this.profilingMap.keySet().iterator(); + + while (var10.hasNext()) { + String var11 = (String) var10.next(); + + if (var11.length() > par1Str.length() && var11.startsWith(par1Str) + && var11.indexOf(".", par1Str.length() + 1) < 0) { + var8 += ((Long) this.profilingMap.get(var11)).longValue(); + } + } + + float var20 = (float) var8; + + if (var8 < var5) { + var8 = var5; + } + + if (var3 < var8) { + var3 = var8; + } + + Iterator var21 = this.profilingMap.keySet().iterator(); + String var12; + + while (var21.hasNext()) { + var12 = (String) var21.next(); + + if (var12.length() > par1Str.length() && var12.startsWith(par1Str) + && var12.indexOf(".", par1Str.length() + 1) < 0) { + long var13 = ((Long) this.profilingMap.get(var12)).longValue(); + double var15 = (double) var13 * 100.0D / (double) var8; + double var17 = (double) var13 * 100.0D / (double) var3; + String var19 = var12.substring(par1Str.length()); + var7.add(new ProfilerResult(var19, var15, var17)); + } + } + + var21 = this.profilingMap.keySet().iterator(); + + while (var21.hasNext()) { + var12 = (String) var21.next(); + this.profilingMap.put(var12, + Long.valueOf(((Long) this.profilingMap.get(var12)).longValue() * 999L / 1000L)); + } + + if ((float) var8 > var20) { + var7.add(new ProfilerResult("unspecified", (double) ((float) var8 - var20) * 100.0D / (double) var8, + (double) ((float) var8 - var20) * 100.0D / (double) var3)); + } + + Collections.sort(var7); + var7.add(0, new ProfilerResult(par1Str, 100.0D, (double) var8 * 100.0D / (double) var3)); + return var7; + } + } + + /** + * End current section and start a new section + */ + public void endStartSection(String par1Str) { + this.endSection(); + this.startSection(par1Str); + } + + public String getNameOfLastSection() { + return this.sectionList.size() == 0 ? "[UNKNOWN]" : (String) this.sectionList.get(this.sectionList.size() - 1); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ProfilerResult.java b/sp-server/src/main/java/net/minecraft/src/ProfilerResult.java new file mode 100644 index 0000000..b9758a8 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ProfilerResult.java @@ -0,0 +1,23 @@ +package net.minecraft.src; + +public final class ProfilerResult implements Comparable { + public double field_76332_a; + public double field_76330_b; + public String field_76331_c; + + public ProfilerResult(String par1Str, double par2, double par4) { + this.field_76331_c = par1Str; + this.field_76332_a = par2; + this.field_76330_b = par4; + } + + public int func_76328_a(ProfilerResult par1ProfilerResult) { + return par1ProfilerResult.field_76332_a < this.field_76332_a ? -1 + : (par1ProfilerResult.field_76332_a > this.field_76332_a ? 1 + : par1ProfilerResult.field_76331_c.compareTo(this.field_76331_c)); + } + + public int compareTo(Object par1Obj) { + return this.func_76328_a((ProfilerResult) par1Obj); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/PropertyManager.java b/sp-server/src/main/java/net/minecraft/src/PropertyManager.java new file mode 100644 index 0000000..d02f6ef --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/PropertyManager.java @@ -0,0 +1,129 @@ +package net.minecraft.src; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.Properties; + +public class PropertyManager { + /** The server properties object. */ + private final Properties serverProperties = new Properties(); + + /** Reference to the logger. */ + private final ILogAgent logger; + + /** The server properties file. */ + private final File serverPropertiesFile; + + public PropertyManager(File par1File, ILogAgent par2ILogAgent) { + this.serverPropertiesFile = par1File; + this.logger = par2ILogAgent; + + if (par1File.exists()) { + FileInputStream var3 = null; + + try { + var3 = new FileInputStream(par1File); + this.serverProperties.load(var3); + } catch (Exception var13) { + par2ILogAgent.logWarningException("Failed to load " + par1File, var13); + this.generateNewProperties(); + } finally { + if (var3 != null) { + try { + var3.close(); + } catch (IOException var12) { + ; + } + } + } + } else { + par2ILogAgent.func_98236_b(par1File + " does not exist"); + this.generateNewProperties(); + } + } + + /** + * Generates a new properties file. + */ + public void generateNewProperties() { + this.logger.func_98233_a("Generating new properties file"); + this.saveProperties(); + } + + /** + * Writes the properties to the properties file. + */ + public void saveProperties() { + FileOutputStream var1 = null; + + try { + var1 = new FileOutputStream(this.serverPropertiesFile); + this.serverProperties.store(var1, "Minecraft server properties"); + } catch (Exception var11) { + this.logger.logWarningException("Failed to save " + this.serverPropertiesFile, var11); + this.generateNewProperties(); + } finally { + if (var1 != null) { + try { + var1.close(); + } catch (IOException var10) { + ; + } + } + } + } + + /** + * Returns this PropertyManager's file object used for property saving. + */ + public File getPropertiesFile() { + return this.serverPropertiesFile; + } + + /** + * Returns a string property. If the property doesn't exist the default is + * returned. + */ + public String getStringProperty(String par1Str, String par2Str) { + if (!this.serverProperties.containsKey(par1Str)) { + this.serverProperties.setProperty(par1Str, par2Str); + this.saveProperties(); + } + + return this.serverProperties.getProperty(par1Str, par2Str); + } + + /** + * Gets an integer property. If it does not exist, set it to the specified + * value. + */ + public int getIntProperty(String par1Str, int par2) { + try { + return Integer.parseInt(this.getStringProperty(par1Str, "" + par2)); + } catch (Exception var4) { + this.serverProperties.setProperty(par1Str, "" + par2); + return par2; + } + } + + /** + * Gets a boolean property. If it does not exist, set it to the specified value. + */ + public boolean getBooleanProperty(String par1Str, boolean par2) { + try { + return Boolean.parseBoolean(this.getStringProperty(par1Str, "" + par2)); + } catch (Exception var4) { + this.serverProperties.setProperty(par1Str, "" + par2); + return par2; + } + } + + /** + * Saves an Object with the given property name. + */ + public void setProperty(String par1Str, Object par2Obj) { + this.serverProperties.setProperty(par1Str, "" + par2Obj); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/RConConsoleSource.java b/sp-server/src/main/java/net/minecraft/src/RConConsoleSource.java new file mode 100644 index 0000000..e111b3f --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/RConConsoleSource.java @@ -0,0 +1,55 @@ +package net.minecraft.src; + +public class RConConsoleSource implements ICommandSender { + /** Single instance of RConConsoleSource */ + public static final RConConsoleSource instance = new RConConsoleSource(); + + /** RCon string buffer for log. */ + private StringBuffer buffer = new StringBuffer(); + + /** + * Clears the RCon log + */ + public void resetLog() { + this.buffer.setLength(0); + } + + /** + * Gets the contents of the RCon log + */ + public String getLogContents() { + return this.buffer.toString(); + } + + /** + * Gets the name of this command sender (usually username, but possibly "Rcon") + */ + public String getCommandSenderName() { + return "Rcon"; + } + + public void sendChatToPlayer(String par1Str) { + this.buffer.append(par1Str); + } + + /** + * Returns true if the command sender is allowed to use the given command. + */ + public boolean canCommandSenderUseCommand(int par1, String par2Str) { + return true; + } + + /** + * Translates and formats the given string key with the given arguments. + */ + public String translateString(String par1Str, Object... par2ArrayOfObj) { + return StringTranslate.getInstance().translateKeyFormat(par1Str, par2ArrayOfObj); + } + + /** + * Return the position for this command sender. + */ + public ChunkCoordinates getCommandSenderPosition() { + return new ChunkCoordinates(0, 0, 0); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/RConOutputStream.java b/sp-server/src/main/java/net/minecraft/src/RConOutputStream.java new file mode 100644 index 0000000..01f4dba --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/RConOutputStream.java @@ -0,0 +1,61 @@ +package net.minecraft.src; + +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class RConOutputStream { + /** Output stream */ + private ByteArrayOutputStream byteArrayOutput; + + /** ByteArrayOutputStream wrapper */ + private DataOutputStream output; + + public RConOutputStream(int par1) { + this.byteArrayOutput = new ByteArrayOutputStream(par1); + this.output = new DataOutputStream(this.byteArrayOutput); + } + + /** + * Writes the given byte array to the output stream + */ + public void writeByteArray(byte[] par1ArrayOfByte) throws IOException { + this.output.write(par1ArrayOfByte, 0, par1ArrayOfByte.length); + } + + /** + * Writes the given String to the output stream + */ + public void writeString(String par1Str) throws IOException { + this.output.writeBytes(par1Str); + this.output.write(0); + } + + /** + * Writes the given int to the output stream + */ + public void writeInt(int par1) throws IOException { + this.output.write(par1); + } + + /** + * Writes the given short to the output stream + */ + public void writeShort(short par1) throws IOException { + this.output.writeShort(Short.reverseBytes(par1)); + } + + /** + * Returns the contents of the output stream as a byte array + */ + public byte[] toByteArray() { + return this.byteArrayOutput.toByteArray(); + } + + /** + * Resets the byte array output. + */ + public void reset() { + this.byteArrayOutput.reset(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/RConThreadBase.java b/sp-server/src/main/java/net/minecraft/src/RConThreadBase.java new file mode 100644 index 0000000..01be0d0 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/RConThreadBase.java @@ -0,0 +1,192 @@ +package net.minecraft.src; + +import java.io.IOException; +import java.net.DatagramSocket; +import java.net.ServerSocket; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +public abstract class RConThreadBase implements Runnable { + /** True if the Thread is running, false otherwise */ + protected boolean running = false; + + /** Reference to the IServer object. */ + protected IServer server; + + /** Thread for this runnable class */ + protected Thread rconThread; + protected int field_72615_d = 5; + + /** A list of registered DatagramSockets */ + protected List socketList = new ArrayList(); + + /** A list of registered ServerSockets */ + protected List serverSocketList = new ArrayList(); + + RConThreadBase(IServer par1IServer) { + this.server = par1IServer; + + if (this.server.isDebuggingEnabled()) { + this.logWarning("Debugging is enabled, performance maybe reduced!"); + } + } + + /** + * Creates a new Thread object from this class and starts running + */ + public synchronized void startThread() { + this.rconThread = new Thread(this); + this.rconThread.start(); + this.running = true; + } + + /** + * Returns true if the Thread is running, false otherwise + */ + public boolean isRunning() { + return this.running; + } + + /** + * Log debug message + */ + protected void logDebug(String par1Str) { + this.server.logDebug(par1Str); + } + + /** + * Log information message + */ + protected void logInfo(String par1Str) { + this.server.logInfo(par1Str); + } + + /** + * Log warning message + */ + protected void logWarning(String par1Str) { + this.server.logWarning(par1Str); + } + + /** + * Log severe error message + */ + protected void logSevere(String par1Str) { + this.server.logSevere(par1Str); + } + + /** + * Returns the number of players on the server + */ + protected int getNumberOfPlayers() { + return this.server.getCurrentPlayerCount(); + } + + /** + * Registers a DatagramSocket with this thread + */ + protected void registerSocket(DatagramSocket par1DatagramSocket) { + this.logDebug("registerSocket: " + par1DatagramSocket); + this.socketList.add(par1DatagramSocket); + } + + /** + * Closes the specified DatagramSocket + */ + protected boolean closeSocket(DatagramSocket par1DatagramSocket, boolean par2) { + this.logDebug("closeSocket: " + par1DatagramSocket); + + if (null == par1DatagramSocket) { + return false; + } else { + boolean var3 = false; + + if (!par1DatagramSocket.isClosed()) { + par1DatagramSocket.close(); + var3 = true; + } + + if (par2) { + this.socketList.remove(par1DatagramSocket); + } + + return var3; + } + } + + /** + * Closes the specified ServerSocket + */ + protected boolean closeServerSocket(ServerSocket par1ServerSocket) { + return this.closeServerSocket_do(par1ServerSocket, true); + } + + /** + * Closes the specified ServerSocket + */ + protected boolean closeServerSocket_do(ServerSocket par1ServerSocket, boolean par2) { + this.logDebug("closeSocket: " + par1ServerSocket); + + if (null == par1ServerSocket) { + return false; + } else { + boolean var3 = false; + + try { + if (!par1ServerSocket.isClosed()) { + par1ServerSocket.close(); + var3 = true; + } + } catch (IOException var5) { + this.logWarning("IO: " + var5.getMessage()); + } + + if (par2) { + this.serverSocketList.remove(par1ServerSocket); + } + + return var3; + } + } + + /** + * Closes all of the opened sockets + */ + protected void closeAllSockets() { + this.closeAllSockets_do(false); + } + + /** + * Closes all of the opened sockets + */ + protected void closeAllSockets_do(boolean par1) { + int var2 = 0; + Iterator var3 = this.socketList.iterator(); + + while (var3.hasNext()) { + DatagramSocket var4 = (DatagramSocket) var3.next(); + + if (this.closeSocket(var4, false)) { + ++var2; + } + } + + this.socketList.clear(); + var3 = this.serverSocketList.iterator(); + + while (var3.hasNext()) { + ServerSocket var5 = (ServerSocket) var3.next(); + + if (this.closeServerSocket_do(var5, false)) { + ++var2; + } + } + + this.serverSocketList.clear(); + + if (par1 && 0 < var2) { + this.logWarning("Force closed " + var2 + " sockets"); + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/RConThreadClient.java b/sp-server/src/main/java/net/minecraft/src/RConThreadClient.java new file mode 100644 index 0000000..68bda8b --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/RConThreadClient.java @@ -0,0 +1,161 @@ +package net.minecraft.src; + +import java.io.BufferedInputStream; +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.net.Socket; +import java.net.SocketTimeoutException; + +public class RConThreadClient extends RConThreadBase { + /** + * True if the client has succefssfully logged into the RCon, otherwise false + */ + private boolean loggedIn = false; + + /** The client's Socket connection */ + private Socket clientSocket; + + /** A buffer for incoming Socket data */ + private byte[] buffer = new byte[1460]; + + /** The RCon password */ + private String rconPassword; + + RConThreadClient(IServer par1IServer, Socket par2Socket) { + super(par1IServer); + this.clientSocket = par2Socket; + + try { + this.clientSocket.setSoTimeout(0); + } catch (Exception var4) { + this.running = false; + } + + this.rconPassword = par1IServer.getStringProperty("rcon.password", ""); + this.logInfo("Rcon connection from: " + par2Socket.getInetAddress()); + } + + public void run() { + try { + while (true) { + if (!this.running) { + break; + } + + BufferedInputStream var1 = new BufferedInputStream(this.clientSocket.getInputStream()); + int var2 = var1.read(this.buffer, 0, 1460); + + if (10 > var2) { + return; + } + + byte var3 = 0; + int var4 = RConUtils.getBytesAsLEInt(this.buffer, 0, var2); + + if (var4 == var2 - 4) { + int var21 = var3 + 4; + int var5 = RConUtils.getBytesAsLEInt(this.buffer, var21, var2); + var21 += 4; + int var6 = RConUtils.getRemainingBytesAsLEInt(this.buffer, var21); + var21 += 4; + + switch (var6) { + case 2: + if (this.loggedIn) { + String var8 = RConUtils.getBytesAsString(this.buffer, var21, var2); + + try { + this.sendMultipacketResponse(var5, this.server.handleRConCommand(var8)); + } catch (Exception var16) { + this.sendMultipacketResponse(var5, + "Error executing: " + var8 + " (" + var16.getMessage() + ")"); + } + + continue; + } + + this.sendLoginFailedResponse(); + continue; + + case 3: + String var7 = RConUtils.getBytesAsString(this.buffer, var21, var2); + int var10000 = var21 + var7.length(); + + if (0 != var7.length() && var7.equals(this.rconPassword)) { + this.loggedIn = true; + this.sendResponse(var5, 2, ""); + continue; + } + + this.loggedIn = false; + this.sendLoginFailedResponse(); + continue; + + default: + this.sendMultipacketResponse(var5, + String.format("Unknown request %s", new Object[] { Integer.toHexString(var6) })); + continue; + } + } + } + } catch (SocketTimeoutException var17) { + } catch (IOException var18) { + } catch (Exception var19) { + System.out.println(var19); + } finally { + this.closeSocket(); + } + } + + /** + * Sends the given response message to the client + */ + private void sendResponse(int par1, int par2, String par3Str) throws IOException { + ByteArrayOutputStream var4 = new ByteArrayOutputStream(1248); + DataOutputStream var5 = new DataOutputStream(var4); + var5.writeInt(Integer.reverseBytes(par3Str.length() + 10)); + var5.writeInt(Integer.reverseBytes(par1)); + var5.writeInt(Integer.reverseBytes(par2)); + var5.writeBytes(par3Str); + var5.write(0); + var5.write(0); + this.clientSocket.getOutputStream().write(var4.toByteArray()); + } + + /** + * Sends the standard RCon 'authorization failed' response packet + */ + private void sendLoginFailedResponse() throws IOException { + this.sendResponse(-1, 2, ""); + } + + /** + * Splits the response message into individual packets and sends each one + */ + private void sendMultipacketResponse(int par1, String par2Str) throws IOException { + int var3 = par2Str.length(); + + do { + int var4 = 4096 <= var3 ? 4096 : var3; + this.sendResponse(par1, 0, par2Str.substring(0, var4)); + par2Str = par2Str.substring(var4); + var3 = par2Str.length(); + } while (0 != var3); + } + + /** + * Closes the client socket + */ + private void closeSocket() { + if (null != this.clientSocket) { + try { + this.clientSocket.close(); + } catch (IOException var2) { + this.logWarning("IO: " + var2.getMessage()); + } + + this.clientSocket = null; + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/RConThreadMain.java b/sp-server/src/main/java/net/minecraft/src/RConThreadMain.java new file mode 100644 index 0000000..59265f7 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/RConThreadMain.java @@ -0,0 +1,126 @@ +package net.minecraft.src; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.ServerSocket; +import java.net.Socket; +import java.net.SocketTimeoutException; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Map.Entry; + +public class RConThreadMain extends RConThreadBase { + /** Port RCon is running on */ + private int rconPort; + + /** Port the server is running on */ + private int serverPort; + + /** Hostname RCon is running on */ + private String hostname; + + /** The RCon ServerSocket. */ + private ServerSocket serverSocket = null; + + /** The RCon password */ + private String rconPassword; + + /** A map of client addresses to their running Threads */ + private Map clientThreads; + + public RConThreadMain(IServer par1IServer) { + super(par1IServer); + this.rconPort = par1IServer.getIntProperty("rcon.port", 0); + this.rconPassword = par1IServer.getStringProperty("rcon.password", ""); + this.hostname = par1IServer.getHostname(); + this.serverPort = par1IServer.getPort(); + + if (0 == this.rconPort) { + this.rconPort = this.serverPort + 10; + this.logInfo("Setting default rcon port to " + this.rconPort); + par1IServer.setProperty("rcon.port", Integer.valueOf(this.rconPort)); + + if (0 == this.rconPassword.length()) { + par1IServer.setProperty("rcon.password", ""); + } + + par1IServer.saveProperties(); + } + + if (0 == this.hostname.length()) { + this.hostname = "0.0.0.0"; + } + + this.initClientThreadList(); + this.serverSocket = null; + } + + private void initClientThreadList() { + this.clientThreads = new HashMap(); + } + + /** + * Cleans up the clientThreads map by removing client Threads that are not + * running + */ + private void cleanClientThreadsMap() { + Iterator var1 = this.clientThreads.entrySet().iterator(); + + while (var1.hasNext()) { + Entry var2 = (Entry) var1.next(); + + if (!((RConThreadClient) var2.getValue()).isRunning()) { + var1.remove(); + } + } + } + + public void run() { + this.logInfo("RCON running on " + this.hostname + ":" + this.rconPort); + + try { + while (this.running) { + try { + Socket var1 = this.serverSocket.accept(); + var1.setSoTimeout(500); + RConThreadClient var2 = new RConThreadClient(this.server, var1); + var2.startThread(); + this.clientThreads.put(var1.getRemoteSocketAddress(), var2); + this.cleanClientThreadsMap(); + } catch (SocketTimeoutException var7) { + this.cleanClientThreadsMap(); + } catch (IOException var8) { + if (this.running) { + this.logInfo("IO: " + var8.getMessage()); + } + } + } + } finally { + this.closeServerSocket(this.serverSocket); + } + } + + /** + * Creates a new Thread object from this class and starts running + */ + public void startThread() { + if (0 == this.rconPassword.length()) { + this.logWarning("No rcon password set in \'" + this.server.getSettingsFilename() + "\', rcon disabled!"); + } else if (0 < this.rconPort && 65535 >= this.rconPort) { + if (!this.running) { + try { + this.serverSocket = new ServerSocket(this.rconPort, 0, InetAddress.getByName(this.hostname)); + this.serverSocket.setSoTimeout(500); + super.startThread(); + } catch (IOException var2) { + this.logWarning("Unable to initialise rcon on " + this.hostname + ":" + this.rconPort + " : " + + var2.getMessage()); + } + } + } else { + this.logWarning("Invalid rcon port " + this.rconPort + " found in \'" + this.server.getSettingsFilename() + + "\', rcon disabled!"); + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/RConThreadQuery.java b/sp-server/src/main/java/net/minecraft/src/RConThreadQuery.java new file mode 100644 index 0000000..013840a --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/RConThreadQuery.java @@ -0,0 +1,355 @@ +package net.minecraft.src; + +import java.io.IOException; +import java.net.DatagramPacket; +import java.net.DatagramSocket; +import java.net.InetAddress; +import java.net.PortUnreachableException; +import java.net.SocketAddress; +import java.net.SocketException; +import java.net.SocketTimeoutException; +import java.net.UnknownHostException; +import java.util.Date; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Map.Entry; + +public class RConThreadQuery extends RConThreadBase { + /** The time of the last client auth check */ + private long lastAuthCheckTime; + + /** The RCon query port */ + private int queryPort; + + /** Port the server is running on */ + private int serverPort; + + /** The maximum number of players allowed on the server */ + private int maxPlayers; + + /** The current server message of the day */ + private String serverMotd; + + /** The name of the currently loaded world */ + private String worldName; + + /** The remote socket querying the server */ + private DatagramSocket querySocket = null; + + /** A buffer for incoming DatagramPackets */ + private byte[] buffer = new byte[1460]; + + /** Storage for incoming DatagramPackets */ + private DatagramPacket incomingPacket = null; + private Map field_72644_p; + + /** The hostname of this query server */ + private String queryHostname; + + /** The hostname of the running server */ + private String serverHostname; + + /** A map of SocketAddress objects to RConThreadQueryAuth objects */ + private Map queryClients; + + /** + * The time that this RConThreadQuery was constructed, from (new + * Date()).getTime() + */ + private long time; + + /** The RConQuery output stream */ + private RConOutputStream output; + + /** The time of the last query response sent */ + private long lastQueryResponseTime; + + public RConThreadQuery(IServer par1IServer) { + super(par1IServer); + this.queryPort = par1IServer.getIntProperty("query.port", 0); + this.serverHostname = par1IServer.getHostname(); + this.serverPort = par1IServer.getPort(); + this.serverMotd = par1IServer.getMotd(); + this.maxPlayers = par1IServer.getMaxPlayers(); + this.worldName = par1IServer.getFolderName(); + this.lastQueryResponseTime = 0L; + this.queryHostname = "0.0.0.0"; + + if (0 != this.serverHostname.length() && !this.queryHostname.equals(this.serverHostname)) { + this.queryHostname = this.serverHostname; + } else { + this.serverHostname = "0.0.0.0"; + + try { + InetAddress var2 = InetAddress.getLocalHost(); + this.queryHostname = var2.getHostAddress(); + } catch (UnknownHostException var3) { + this.logWarning("Unable to determine local host IP, please set server-ip in \'" + + par1IServer.getSettingsFilename() + "\' : " + var3.getMessage()); + } + } + + if (0 == this.queryPort) { + this.queryPort = this.serverPort; + this.logInfo("Setting default query port to " + this.queryPort); + par1IServer.setProperty("query.port", Integer.valueOf(this.queryPort)); + par1IServer.setProperty("debug", Boolean.valueOf(false)); + par1IServer.saveProperties(); + } + + this.field_72644_p = new HashMap(); + this.output = new RConOutputStream(1460); + this.queryClients = new HashMap(); + this.time = (new Date()).getTime(); + } + + /** + * Sends a byte array as a DatagramPacket response to the client who sent the + * given DatagramPacket + */ + private void sendResponsePacket(byte[] par1ArrayOfByte, DatagramPacket par2DatagramPacket) throws IOException { + this.querySocket.send( + new DatagramPacket(par1ArrayOfByte, par1ArrayOfByte.length, par2DatagramPacket.getSocketAddress())); + } + + /** + * Parses an incoming DatagramPacket, returning true if the packet was valid + */ + private boolean parseIncomingPacket(DatagramPacket par1DatagramPacket) throws IOException { + byte[] var2 = par1DatagramPacket.getData(); + int var3 = par1DatagramPacket.getLength(); + SocketAddress var4 = par1DatagramPacket.getSocketAddress(); + this.logDebug("Packet len " + var3 + " [" + var4 + "]"); + + if (3 <= var3 && -2 == var2[0] && -3 == var2[1]) { + this.logDebug("Packet \'" + RConUtils.getByteAsHexString(var2[2]) + "\' [" + var4 + "]"); + + switch (var2[2]) { + case 0: + if (!this.verifyClientAuth(par1DatagramPacket).booleanValue()) { + this.logDebug("Invalid challenge [" + var4 + "]"); + return false; + } else if (15 == var3) { + this.sendResponsePacket(this.createQueryResponse(par1DatagramPacket), par1DatagramPacket); + this.logDebug("Rules [" + var4 + "]"); + } else { + RConOutputStream var5 = new RConOutputStream(1460); + var5.writeInt(0); + var5.writeByteArray(this.getRequestID(par1DatagramPacket.getSocketAddress())); + var5.writeString(this.serverMotd); + var5.writeString("SMP"); + var5.writeString(this.worldName); + var5.writeString(Integer.toString(this.getNumberOfPlayers())); + var5.writeString(Integer.toString(this.maxPlayers)); + var5.writeShort((short) this.serverPort); + var5.writeString(this.queryHostname); + this.sendResponsePacket(var5.toByteArray(), par1DatagramPacket); + this.logDebug("Status [" + var4 + "]"); + } + + case 9: + this.sendAuthChallenge(par1DatagramPacket); + this.logDebug("Challenge [" + var4 + "]"); + return true; + + default: + return true; + } + } else { + this.logDebug("Invalid packet [" + var4 + "]"); + return false; + } + } + + /** + * Creates a query response as a byte array for the specified query + * DatagramPacket + */ + private byte[] createQueryResponse(DatagramPacket par1DatagramPacket) throws IOException { + long var2 = System.currentTimeMillis(); + + if (var2 < this.lastQueryResponseTime + 5000L) { + byte[] var7 = this.output.toByteArray(); + byte[] var8 = this.getRequestID(par1DatagramPacket.getSocketAddress()); + var7[1] = var8[0]; + var7[2] = var8[1]; + var7[3] = var8[2]; + var7[4] = var8[3]; + return var7; + } else { + this.lastQueryResponseTime = var2; + this.output.reset(); + this.output.writeInt(0); + this.output.writeByteArray(this.getRequestID(par1DatagramPacket.getSocketAddress())); + this.output.writeString("splitnum"); + this.output.writeInt(128); + this.output.writeInt(0); + this.output.writeString("hostname"); + this.output.writeString(this.serverMotd); + this.output.writeString("gametype"); + this.output.writeString("SMP"); + this.output.writeString("game_id"); + this.output.writeString("MINECRAFT"); + this.output.writeString("version"); + this.output.writeString(this.server.getMinecraftVersion()); + this.output.writeString("plugins"); + this.output.writeString(this.server.getPlugins()); + this.output.writeString("map"); + this.output.writeString(this.worldName); + this.output.writeString("numplayers"); + this.output.writeString("" + this.getNumberOfPlayers()); + this.output.writeString("maxplayers"); + this.output.writeString("" + this.maxPlayers); + this.output.writeString("hostport"); + this.output.writeString("" + this.serverPort); + this.output.writeString("hostip"); + this.output.writeString(this.queryHostname); + this.output.writeInt(0); + this.output.writeInt(1); + this.output.writeString("player_"); + this.output.writeInt(0); + String[] var4 = this.server.getAllUsernames(); + byte var5 = (byte) var4.length; + + for (byte var6 = (byte) (var5 - 1); var6 >= 0; --var6) { + this.output.writeString(var4[var6]); + } + + this.output.writeInt(0); + return this.output.toByteArray(); + } + } + + /** + * Returns the request ID provided by the authorized client + */ + private byte[] getRequestID(SocketAddress par1SocketAddress) { + return ((RConThreadQueryAuth) this.queryClients.get(par1SocketAddress)).getRequestId(); + } + + /** + * Returns true if the client has a valid auth, otherwise false + */ + private Boolean verifyClientAuth(DatagramPacket par1DatagramPacket) { + SocketAddress var2 = par1DatagramPacket.getSocketAddress(); + + if (!this.queryClients.containsKey(var2)) { + return Boolean.valueOf(false); + } else { + byte[] var3 = par1DatagramPacket.getData(); + return ((RConThreadQueryAuth) this.queryClients.get(var2)).getRandomChallenge() != RConUtils + .getBytesAsBEint(var3, 7, par1DatagramPacket.getLength()) ? Boolean.valueOf(false) + : Boolean.valueOf(true); + } + } + + /** + * Sends an auth challenge DatagramPacket to the client and adds the client to + * the queryClients map + */ + private void sendAuthChallenge(DatagramPacket par1DatagramPacket) throws IOException { + RConThreadQueryAuth var2 = new RConThreadQueryAuth(this, par1DatagramPacket); + this.queryClients.put(par1DatagramPacket.getSocketAddress(), var2); + this.sendResponsePacket(var2.getChallengeValue(), par1DatagramPacket); + } + + /** + * Removes all clients whose auth is no longer valid + */ + private void cleanQueryClientsMap() { + if (this.running) { + long var1 = System.currentTimeMillis(); + + if (var1 >= this.lastAuthCheckTime + 30000L) { + this.lastAuthCheckTime = var1; + Iterator var3 = this.queryClients.entrySet().iterator(); + + while (var3.hasNext()) { + Entry var4 = (Entry) var3.next(); + + if (((RConThreadQueryAuth) var4.getValue()).hasExpired(var1).booleanValue()) { + var3.remove(); + } + } + } + } + } + + public void run() { + this.logInfo("Query running on " + this.serverHostname + ":" + this.queryPort); + this.lastAuthCheckTime = System.currentTimeMillis(); + this.incomingPacket = new DatagramPacket(this.buffer, this.buffer.length); + + try { + while (this.running) { + try { + this.querySocket.receive(this.incomingPacket); + this.cleanQueryClientsMap(); + this.parseIncomingPacket(this.incomingPacket); + } catch (SocketTimeoutException var7) { + this.cleanQueryClientsMap(); + } catch (PortUnreachableException var8) { + ; + } catch (IOException var9) { + this.stopWithException(var9); + } + } + } finally { + this.closeAllSockets(); + } + } + + /** + * Creates a new Thread object from this class and starts running + */ + public void startThread() { + if (!this.running) { + if (0 < this.queryPort && 65535 >= this.queryPort) { + if (this.initQuerySystem()) { + super.startThread(); + } + } else { + this.logWarning("Invalid query port " + this.queryPort + " found in \'" + + this.server.getSettingsFilename() + "\' (queries disabled)"); + } + } + } + + /** + * Stops the query server and reports the given Exception + */ + private void stopWithException(Exception par1Exception) { + if (this.running) { + this.logWarning("Unexpected exception, buggy JRE? (" + par1Exception.toString() + ")"); + + if (!this.initQuerySystem()) { + this.logSevere("Failed to recover from buggy JRE, shutting down!"); + this.running = false; + } + } + } + + /** + * Initializes the query system by binding it to a port + */ + private boolean initQuerySystem() { + try { + this.querySocket = new DatagramSocket(this.queryPort, InetAddress.getByName(this.serverHostname)); + this.registerSocket(this.querySocket); + this.querySocket.setSoTimeout(500); + return true; + } catch (SocketException var2) { + this.logWarning("Unable to initialise query system on " + this.serverHostname + ":" + this.queryPort + + " (Socket): " + var2.getMessage()); + } catch (UnknownHostException var3) { + this.logWarning("Unable to initialise query system on " + this.serverHostname + ":" + this.queryPort + + " (Unknown Host): " + var3.getMessage()); + } catch (Exception var4) { + this.logWarning("Unable to initialise query system on " + this.serverHostname + ":" + this.queryPort + + " (E): " + var4.getMessage()); + } + + return false; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/RConThreadQueryAuth.java b/sp-server/src/main/java/net/minecraft/src/RConThreadQueryAuth.java new file mode 100644 index 0000000..1f28ebe --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/RConThreadQueryAuth.java @@ -0,0 +1,70 @@ +package net.minecraft.src; + +import java.net.DatagramPacket; +import java.util.Date; +import java.util.Random; + +class RConThreadQueryAuth { + /** The creation timestamp for this auth */ + private long timestamp; + + /** A random integer value to be used for client response authentication */ + private int randomChallenge; + + /** A client-provided request ID associated with this query. */ + private byte[] requestId; + + /** A unique string of bytes used to verify client auth */ + private byte[] challengeValue; + + /** The request ID stored as a String */ + private String requestIdAsString; + + /** The RConThreadQuery that this is probably an inner class of */ + final RConThreadQuery queryThread; + + public RConThreadQueryAuth(RConThreadQuery par1RConThreadQuery, DatagramPacket par2DatagramPacket) { + this.queryThread = par1RConThreadQuery; + this.timestamp = (new Date()).getTime(); + byte[] var3 = par2DatagramPacket.getData(); + this.requestId = new byte[4]; + this.requestId[0] = var3[3]; + this.requestId[1] = var3[4]; + this.requestId[2] = var3[5]; + this.requestId[3] = var3[6]; + this.requestIdAsString = new String(this.requestId); + this.randomChallenge = (new Random()).nextInt(16777216); + this.challengeValue = String + .format("\t%s%d\u0000", new Object[] { this.requestIdAsString, Integer.valueOf(this.randomChallenge) }) + .getBytes(); + } + + /** + * Returns true if the auth's creation timestamp is less than the given time, + * otherwise false + */ + public Boolean hasExpired(long par1) { + return Boolean.valueOf(this.timestamp < par1); + } + + /** + * Returns the random challenge number assigned to this auth + */ + public int getRandomChallenge() { + return this.randomChallenge; + } + + /** + * Returns the auth challenge value + */ + public byte[] getChallengeValue() { + return this.challengeValue; + } + + /** + * Returns the request ID provided by the client. + */ + public byte[] getRequestId() { + return this.requestId; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/RConUtils.java b/sp-server/src/main/java/net/minecraft/src/RConUtils.java new file mode 100644 index 0000000..f9e4ed4 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/RConUtils.java @@ -0,0 +1,55 @@ +package net.minecraft.src; + +public class RConUtils { + /** Translation array of decimal to hex digits */ + public static char[] hexDigits = new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', + 'e', 'f' }; + + /** + * Read a null-terminated string from the given byte array + */ + public static String getBytesAsString(byte[] par0ArrayOfByte, int par1, int par2) { + int var3 = par2 - 1; + int var4; + + for (var4 = par1 > var3 ? var3 : par1; 0 != par0ArrayOfByte[var4] && var4 < var3; ++var4) { + ; + } + + return new String(par0ArrayOfByte, par1, var4 - par1); + } + + /** + * Read 4 bytes from the + */ + public static int getRemainingBytesAsLEInt(byte[] par0ArrayOfByte, int par1) { + return getBytesAsLEInt(par0ArrayOfByte, par1, par0ArrayOfByte.length); + } + + /** + * Read 4 bytes from the given array in little-endian format and return them as + * an int + */ + public static int getBytesAsLEInt(byte[] par0ArrayOfByte, int par1, int par2) { + return 0 > par2 - par1 - 4 ? 0 + : par0ArrayOfByte[par1 + 3] << 24 | (par0ArrayOfByte[par1 + 2] & 255) << 16 + | (par0ArrayOfByte[par1 + 1] & 255) << 8 | par0ArrayOfByte[par1] & 255; + } + + /** + * Read 4 bytes from the given array in big-endian format and return them as an + * int + */ + public static int getBytesAsBEint(byte[] par0ArrayOfByte, int par1, int par2) { + return 0 > par2 - par1 - 4 ? 0 + : par0ArrayOfByte[par1] << 24 | (par0ArrayOfByte[par1 + 1] & 255) << 16 + | (par0ArrayOfByte[par1 + 2] & 255) << 8 | par0ArrayOfByte[par1 + 3] & 255; + } + + /** + * Returns a String representation of the byte in hexadecimal format + */ + public static String getByteAsHexString(byte par0) { + return "" + hexDigits[(par0 & 240) >>> 4] + hexDigits[par0 & 15]; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/RandomPositionGenerator.java b/sp-server/src/main/java/net/minecraft/src/RandomPositionGenerator.java new file mode 100644 index 0000000..492206d --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/RandomPositionGenerator.java @@ -0,0 +1,99 @@ +package net.minecraft.src; + +import java.util.Random; + +public class RandomPositionGenerator { + /** + * used to store a driection when the user passes a point to move towards or + * away from. WARNING: NEVER THREAD SAFE. MULTIPLE findTowards and findAway + * calls, will share this var + */ + private static Vec3 staticVector = Vec3.createVectorHelper(0.0D, 0.0D, 0.0D); + + /** + * finds a random target within par1(x,z) and par2 (y) blocks + */ + public static Vec3 findRandomTarget(EntityCreature par0EntityCreature, int par1, int par2) { + return findRandomTargetBlock(par0EntityCreature, par1, par2, (Vec3) null); + } + + /** + * finds a random target within par1(x,z) and par2 (y) blocks in the direction + * of the point par3 + */ + public static Vec3 findRandomTargetBlockTowards(EntityCreature par0EntityCreature, int par1, int par2, + Vec3 par3Vec3) { + staticVector.xCoord = par3Vec3.xCoord - par0EntityCreature.posX; + staticVector.yCoord = par3Vec3.yCoord - par0EntityCreature.posY; + staticVector.zCoord = par3Vec3.zCoord - par0EntityCreature.posZ; + return findRandomTargetBlock(par0EntityCreature, par1, par2, staticVector); + } + + /** + * finds a random target within par1(x,z) and par2 (y) blocks in the reverse + * direction of the point par3 + */ + public static Vec3 findRandomTargetBlockAwayFrom(EntityCreature par0EntityCreature, int par1, int par2, + Vec3 par3Vec3) { + staticVector.xCoord = par0EntityCreature.posX - par3Vec3.xCoord; + staticVector.yCoord = par0EntityCreature.posY - par3Vec3.yCoord; + staticVector.zCoord = par0EntityCreature.posZ - par3Vec3.zCoord; + return findRandomTargetBlock(par0EntityCreature, par1, par2, staticVector); + } + + /** + * searches 10 blocks at random in a within par1(x,z) and par2 (y) distance, + * ignores those not in the direction of par3Vec3, then points to the tile for + * which creature.getBlockPathWeight returns the highest number + */ + private static Vec3 findRandomTargetBlock(EntityCreature par0EntityCreature, int par1, int par2, Vec3 par3Vec3) { + Random var4 = par0EntityCreature.getRNG(); + boolean var5 = false; + int var6 = 0; + int var7 = 0; + int var8 = 0; + float var9 = -99999.0F; + boolean var10; + + if (par0EntityCreature.hasHome()) { + double var11 = (double) (par0EntityCreature.getHomePosition().getDistanceSquared( + MathHelper.floor_double(par0EntityCreature.posX), MathHelper.floor_double(par0EntityCreature.posY), + MathHelper.floor_double(par0EntityCreature.posZ)) + 4.0F); + double var13 = (double) (par0EntityCreature.getMaximumHomeDistance() + (float) par1); + var10 = var11 < var13 * var13; + } else { + var10 = false; + } + + for (int var16 = 0; var16 < 10; ++var16) { + int var12 = var4.nextInt(2 * par1) - par1; + int var17 = var4.nextInt(2 * par2) - par2; + int var14 = var4.nextInt(2 * par1) - par1; + + if (par3Vec3 == null || (double) var12 * par3Vec3.xCoord + (double) var14 * par3Vec3.zCoord >= 0.0D) { + var12 += MathHelper.floor_double(par0EntityCreature.posX); + var17 += MathHelper.floor_double(par0EntityCreature.posY); + var14 += MathHelper.floor_double(par0EntityCreature.posZ); + + if (!var10 || par0EntityCreature.isWithinHomeDistance(var12, var17, var14)) { + float var15 = par0EntityCreature.getBlockPathWeight(var12, var17, var14); + + if (var15 > var9) { + var9 = var15; + var6 = var12; + var7 = var17; + var8 = var14; + var5 = true; + } + } + } + } + + if (var5) { + return par0EntityCreature.worldObj.getWorldVec3Pool().getVecFromPool((double) var6, (double) var7, + (double) var8); + } else { + return null; + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/RecipeFireworks.java b/sp-server/src/main/java/net/minecraft/src/RecipeFireworks.java new file mode 100644 index 0000000..f1299c9 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/RecipeFireworks.java @@ -0,0 +1,181 @@ +package net.minecraft.src; + +import java.util.ArrayList; + +public class RecipeFireworks implements IRecipe { + private ItemStack field_92102_a; + + /** + * Used to check if a recipe matches current crafting inventory + */ + public boolean matches(InventoryCrafting par1InventoryCrafting, World par2World) { + this.field_92102_a = null; + int var3 = 0; + int var4 = 0; + int var5 = 0; + int var6 = 0; + int var7 = 0; + int var8 = 0; + + for (int var9 = 0; var9 < par1InventoryCrafting.getSizeInventory(); ++var9) { + ItemStack var10 = par1InventoryCrafting.getStackInSlot(var9); + + if (var10 != null) { + if (var10.itemID == Item.gunpowder.itemID) { + ++var4; + } else if (var10.itemID == Item.fireworkCharge.itemID) { + ++var6; + } else if (var10.itemID == Item.dyePowder.itemID) { + ++var5; + } else if (var10.itemID == Item.paper.itemID) { + ++var3; + } else if (var10.itemID == Item.lightStoneDust.itemID) { + ++var7; + } else if (var10.itemID == Item.diamond.itemID) { + ++var7; + } else if (var10.itemID == Item.fireballCharge.itemID) { + ++var8; + } else if (var10.itemID == Item.feather.itemID) { + ++var8; + } else if (var10.itemID == Item.goldNugget.itemID) { + ++var8; + } else { + if (var10.itemID != Item.skull.itemID) { + return false; + } + + ++var8; + } + } + } + + var7 += var5 + var8; + + if (var4 <= 3 && var3 <= 1) { + NBTTagCompound var16; + NBTTagCompound var19; + + if (var4 >= 1 && var3 == 1 && var7 == 0) { + this.field_92102_a = new ItemStack(Item.firework); + + if (var6 > 0) { + var16 = new NBTTagCompound(); + var19 = new NBTTagCompound("Fireworks"); + NBTTagList var25 = new NBTTagList("Explosions"); + + for (int var22 = 0; var22 < par1InventoryCrafting.getSizeInventory(); ++var22) { + ItemStack var26 = par1InventoryCrafting.getStackInSlot(var22); + + if (var26 != null && var26.itemID == Item.fireworkCharge.itemID && var26.hasTagCompound() + && var26.getTagCompound().hasKey("Explosion")) { + var25.appendTag(var26.getTagCompound().getCompoundTag("Explosion")); + } + } + + var19.setTag("Explosions", var25); + var19.setByte("Flight", (byte) var4); + var16.setTag("Fireworks", var19); + this.field_92102_a.setTagCompound(var16); + } + + return true; + } else if (var4 == 1 && var3 == 0 && var6 == 0 && var5 > 0 && var8 <= 1) { + this.field_92102_a = new ItemStack(Item.fireworkCharge); + var16 = new NBTTagCompound(); + var19 = new NBTTagCompound("Explosion"); + byte var23 = 0; + ArrayList var12 = new ArrayList(); + + for (int var13 = 0; var13 < par1InventoryCrafting.getSizeInventory(); ++var13) { + ItemStack var14 = par1InventoryCrafting.getStackInSlot(var13); + + if (var14 != null) { + if (var14.itemID == Item.dyePowder.itemID) { + var12.add(Integer.valueOf(ItemDye.dyeColors[var14.getItemDamage()])); + } else if (var14.itemID == Item.lightStoneDust.itemID) { + var19.setBoolean("Flicker", true); + } else if (var14.itemID == Item.diamond.itemID) { + var19.setBoolean("Trail", true); + } else if (var14.itemID == Item.fireballCharge.itemID) { + var23 = 1; + } else if (var14.itemID == Item.feather.itemID) { + var23 = 4; + } else if (var14.itemID == Item.goldNugget.itemID) { + var23 = 2; + } else if (var14.itemID == Item.skull.itemID) { + var23 = 3; + } + } + } + + int[] var24 = new int[var12.size()]; + + for (int var27 = 0; var27 < var24.length; ++var27) { + var24[var27] = ((Integer) var12.get(var27)).intValue(); + } + + var19.setIntArray("Colors", var24); + var19.setByte("Type", var23); + var16.setTag("Explosion", var19); + this.field_92102_a.setTagCompound(var16); + return true; + } else if (var4 == 0 && var3 == 0 && var6 == 1 && var5 > 0 && var5 == var7) { + ArrayList var15 = new ArrayList(); + + for (int var17 = 0; var17 < par1InventoryCrafting.getSizeInventory(); ++var17) { + ItemStack var11 = par1InventoryCrafting.getStackInSlot(var17); + + if (var11 != null) { + if (var11.itemID == Item.dyePowder.itemID) { + var15.add(Integer.valueOf(ItemDye.dyeColors[var11.getItemDamage()])); + } else if (var11.itemID == Item.fireworkCharge.itemID) { + this.field_92102_a = var11.copy(); + this.field_92102_a.stackSize = 1; + } + } + } + + int[] var18 = new int[var15.size()]; + + for (int var20 = 0; var20 < var18.length; ++var20) { + var18[var20] = ((Integer) var15.get(var20)).intValue(); + } + + if (this.field_92102_a != null && this.field_92102_a.hasTagCompound()) { + NBTTagCompound var21 = this.field_92102_a.getTagCompound().getCompoundTag("Explosion"); + + if (var21 == null) { + return false; + } else { + var21.setIntArray("FadeColors", var18); + return true; + } + } else { + return false; + } + } else { + return false; + } + } else { + return false; + } + } + + /** + * Returns an Item that is the result of this recipe + */ + public ItemStack getCraftingResult(InventoryCrafting par1InventoryCrafting) { + return this.field_92102_a.copy(); + } + + /** + * Returns the size of the recipe area + */ + public int getRecipeSize() { + return 10; + } + + public ItemStack getRecipeOutput() { + return this.field_92102_a; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/RecipeSorter.java b/sp-server/src/main/java/net/minecraft/src/RecipeSorter.java new file mode 100644 index 0000000..e658db9 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/RecipeSorter.java @@ -0,0 +1,22 @@ +package net.minecraft.src; + +import java.util.Comparator; + +class RecipeSorter implements Comparator { + final CraftingManager craftingManager; + + RecipeSorter(CraftingManager par1CraftingManager) { + this.craftingManager = par1CraftingManager; + } + + public int compareRecipes(IRecipe par1IRecipe, IRecipe par2IRecipe) { + return par1IRecipe instanceof ShapelessRecipes && par2IRecipe instanceof ShapedRecipes ? 1 + : (par2IRecipe instanceof ShapelessRecipes && par1IRecipe instanceof ShapedRecipes ? -1 + : (par2IRecipe.getRecipeSize() < par1IRecipe.getRecipeSize() ? -1 + : (par2IRecipe.getRecipeSize() > par1IRecipe.getRecipeSize() ? 1 : 0))); + } + + public int compare(Object par1Obj, Object par2Obj) { + return this.compareRecipes((IRecipe) par1Obj, (IRecipe) par2Obj); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/RecipesArmor.java b/sp-server/src/main/java/net/minecraft/src/RecipesArmor.java new file mode 100644 index 0000000..eabd48b --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/RecipesArmor.java @@ -0,0 +1,30 @@ +package net.minecraft.src; + +public class RecipesArmor { + private String[][] recipePatterns = new String[][] { { "XXX", "X X" }, { "X X", "XXX", "XXX" }, + { "XXX", "X X", "X X" }, { "X X", "X X" } }; + private Object[][] recipeItems; + + public RecipesArmor() { + this.recipeItems = new Object[][] { { Item.leather, Block.fire, Item.ingotIron, Item.diamond, Item.ingotGold }, + { Item.helmetLeather, Item.helmetChain, Item.helmetIron, Item.helmetDiamond, Item.helmetGold }, + { Item.plateLeather, Item.plateChain, Item.plateIron, Item.plateDiamond, Item.plateGold }, + { Item.legsLeather, Item.legsChain, Item.legsIron, Item.legsDiamond, Item.legsGold }, + { Item.bootsLeather, Item.bootsChain, Item.bootsIron, Item.bootsDiamond, Item.bootsGold } }; + } + + /** + * Adds the armor recipes to the CraftingManager. + */ + public void addRecipes(CraftingManager par1CraftingManager) { + for (int var2 = 0; var2 < this.recipeItems[0].length; ++var2) { + Object var3 = this.recipeItems[0][var2]; + + for (int var4 = 0; var4 < this.recipeItems.length - 1; ++var4) { + Item var5 = (Item) this.recipeItems[var4 + 1][var2]; + par1CraftingManager.addRecipe(new ItemStack(var5), + new Object[] { this.recipePatterns[var4], 'X', var3 }); + } + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/RecipesArmorDyes.java b/sp-server/src/main/java/net/minecraft/src/RecipesArmorDyes.java new file mode 100644 index 0000000..0bf202b --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/RecipesArmorDyes.java @@ -0,0 +1,124 @@ +package net.minecraft.src; + +import java.util.ArrayList; + +public class RecipesArmorDyes implements IRecipe { + /** + * Used to check if a recipe matches current crafting inventory + */ + public boolean matches(InventoryCrafting par1InventoryCrafting, World par2World) { + ItemStack var3 = null; + ArrayList var4 = new ArrayList(); + + for (int var5 = 0; var5 < par1InventoryCrafting.getSizeInventory(); ++var5) { + ItemStack var6 = par1InventoryCrafting.getStackInSlot(var5); + + if (var6 != null) { + if (var6.getItem() instanceof ItemArmor) { + ItemArmor var7 = (ItemArmor) var6.getItem(); + + if (var7.getArmorMaterial() != EnumArmorMaterial.CLOTH || var3 != null) { + return false; + } + + var3 = var6; + } else { + if (var6.itemID != Item.dyePowder.itemID) { + return false; + } + + var4.add(var6); + } + } + } + + return var3 != null && !var4.isEmpty(); + } + + /** + * Returns an Item that is the result of this recipe + */ + public ItemStack getCraftingResult(InventoryCrafting par1InventoryCrafting) { + ItemStack var2 = null; + int[] var3 = new int[3]; + int var4 = 0; + int var5 = 0; + ItemArmor var6 = null; + int var7; + int var9; + float var10; + float var11; + int var17; + + for (var7 = 0; var7 < par1InventoryCrafting.getSizeInventory(); ++var7) { + ItemStack var8 = par1InventoryCrafting.getStackInSlot(var7); + + if (var8 != null) { + if (var8.getItem() instanceof ItemArmor) { + var6 = (ItemArmor) var8.getItem(); + + if (var6.getArmorMaterial() != EnumArmorMaterial.CLOTH || var2 != null) { + return null; + } + + var2 = var8.copy(); + var2.stackSize = 1; + + if (var6.hasColor(var8)) { + var9 = var6.getColor(var2); + var10 = (float) (var9 >> 16 & 255) / 255.0F; + var11 = (float) (var9 >> 8 & 255) / 255.0F; + float var12 = (float) (var9 & 255) / 255.0F; + var4 = (int) ((float) var4 + Math.max(var10, Math.max(var11, var12)) * 255.0F); + var3[0] = (int) ((float) var3[0] + var10 * 255.0F); + var3[1] = (int) ((float) var3[1] + var11 * 255.0F); + var3[2] = (int) ((float) var3[2] + var12 * 255.0F); + ++var5; + } + } else { + if (var8.itemID != Item.dyePowder.itemID) { + return null; + } + + float[] var14 = EntitySheep.fleeceColorTable[BlockCloth.getBlockFromDye(var8.getItemDamage())]; + int var15 = (int) (var14[0] * 255.0F); + int var16 = (int) (var14[1] * 255.0F); + var17 = (int) (var14[2] * 255.0F); + var4 += Math.max(var15, Math.max(var16, var17)); + var3[0] += var15; + var3[1] += var16; + var3[2] += var17; + ++var5; + } + } + } + + if (var6 == null) { + return null; + } else { + var7 = var3[0] / var5; + int var13 = var3[1] / var5; + var9 = var3[2] / var5; + var10 = (float) var4 / (float) var5; + var11 = (float) Math.max(var7, Math.max(var13, var9)); + var7 = (int) ((float) var7 * var10 / var11); + var13 = (int) ((float) var13 * var10 / var11); + var9 = (int) ((float) var9 * var10 / var11); + var17 = (var7 << 8) + var13; + var17 = (var17 << 8) + var9; + var6.func_82813_b(var2, var17); + return var2; + } + } + + /** + * Returns the size of the recipe area + */ + public int getRecipeSize() { + return 10; + } + + public ItemStack getRecipeOutput() { + return null; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/RecipesCrafting.java b/sp-server/src/main/java/net/minecraft/src/RecipesCrafting.java new file mode 100644 index 0000000..1910997 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/RecipesCrafting.java @@ -0,0 +1,39 @@ +package net.minecraft.src; + +public class RecipesCrafting { + /** + * Adds the crafting recipes to the CraftingManager. + */ + public void addRecipes(CraftingManager par1CraftingManager) { + par1CraftingManager.addRecipe(new ItemStack(Block.chest), + new Object[] { "###", "# #", "###", '#', Block.planks }); + par1CraftingManager.addRecipe(new ItemStack(Block.chestTrapped), + new Object[] { "#-", '#', Block.chest, '-', Block.tripWireSource }); + par1CraftingManager.addRecipe(new ItemStack(Block.enderChest), + new Object[] { "###", "#E#", "###", '#', Block.obsidian, 'E', Item.eyeOfEnder }); + par1CraftingManager.addRecipe(new ItemStack(Block.furnaceIdle), + new Object[] { "###", "# #", "###", '#', Block.cobblestone }); + par1CraftingManager.addRecipe(new ItemStack(Block.workbench), new Object[] { "##", "##", '#', Block.planks }); + par1CraftingManager.addRecipe(new ItemStack(Block.sandStone), new Object[] { "##", "##", '#', Block.sand }); + par1CraftingManager.addRecipe(new ItemStack(Block.sandStone, 4, 2), + new Object[] { "##", "##", '#', Block.sandStone }); + par1CraftingManager.addRecipe(new ItemStack(Block.sandStone, 1, 1), + new Object[] { "#", "#", '#', new ItemStack(Block.stoneSingleSlab, 1, 1) }); + par1CraftingManager.addRecipe(new ItemStack(Block.blockNetherQuartz, 1, 1), + new Object[] { "#", "#", '#', new ItemStack(Block.stoneSingleSlab, 1, 7) }); + par1CraftingManager.addRecipe(new ItemStack(Block.blockNetherQuartz, 2, 2), + new Object[] { "#", "#", '#', new ItemStack(Block.blockNetherQuartz, 1, 0) }); + par1CraftingManager.addRecipe(new ItemStack(Block.stoneBrick, 4), + new Object[] { "##", "##", '#', Block.stone }); + par1CraftingManager.addRecipe(new ItemStack(Block.fenceIron, 16), + new Object[] { "###", "###", '#', Item.ingotIron }); + par1CraftingManager.addRecipe(new ItemStack(Block.thinGlass, 16), + new Object[] { "###", "###", '#', Block.glass }); + par1CraftingManager.addRecipe(new ItemStack(Block.redstoneLampIdle, 1), + new Object[] { " R ", "RGR", " R ", 'R', Item.redstone, 'G', Block.glowStone }); + par1CraftingManager.addRecipe(new ItemStack(Block.beacon, 1), + new Object[] { "GGG", "GSG", "OOO", 'G', Block.glass, 'S', Item.netherStar, 'O', Block.obsidian }); + par1CraftingManager.addRecipe(new ItemStack(Block.netherBrick, 1), + new Object[] { "NN", "NN", 'N', Item.netherrackBrick }); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/RecipesDyes.java b/sp-server/src/main/java/net/minecraft/src/RecipesDyes.java new file mode 100644 index 0000000..d9213ad --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/RecipesDyes.java @@ -0,0 +1,46 @@ +package net.minecraft.src; + +public class RecipesDyes { + /** + * Adds the dye recipes to the CraftingManager. + */ + public void addRecipes(CraftingManager par1CraftingManager) { + for (int var2 = 0; var2 < 16; ++var2) { + par1CraftingManager.addShapelessRecipe(new ItemStack(Block.cloth, 1, BlockCloth.getDyeFromBlock(var2)), + new Object[] { new ItemStack(Item.dyePowder, 1, var2), + new ItemStack(Item.itemsList[Block.cloth.blockID], 1, 0) }); + } + + par1CraftingManager.addShapelessRecipe(new ItemStack(Item.dyePowder, 2, 11), + new Object[] { Block.plantYellow }); + par1CraftingManager.addShapelessRecipe(new ItemStack(Item.dyePowder, 2, 1), new Object[] { Block.plantRed }); + par1CraftingManager.addShapelessRecipe(new ItemStack(Item.dyePowder, 3, 15), new Object[] { Item.bone }); + par1CraftingManager.addShapelessRecipe(new ItemStack(Item.dyePowder, 2, 9), + new Object[] { new ItemStack(Item.dyePowder, 1, 1), new ItemStack(Item.dyePowder, 1, 15) }); + par1CraftingManager.addShapelessRecipe(new ItemStack(Item.dyePowder, 2, 14), + new Object[] { new ItemStack(Item.dyePowder, 1, 1), new ItemStack(Item.dyePowder, 1, 11) }); + par1CraftingManager.addShapelessRecipe(new ItemStack(Item.dyePowder, 2, 10), + new Object[] { new ItemStack(Item.dyePowder, 1, 2), new ItemStack(Item.dyePowder, 1, 15) }); + par1CraftingManager.addShapelessRecipe(new ItemStack(Item.dyePowder, 2, 8), + new Object[] { new ItemStack(Item.dyePowder, 1, 0), new ItemStack(Item.dyePowder, 1, 15) }); + par1CraftingManager.addShapelessRecipe(new ItemStack(Item.dyePowder, 2, 7), + new Object[] { new ItemStack(Item.dyePowder, 1, 8), new ItemStack(Item.dyePowder, 1, 15) }); + par1CraftingManager.addShapelessRecipe(new ItemStack(Item.dyePowder, 3, 7), + new Object[] { new ItemStack(Item.dyePowder, 1, 0), new ItemStack(Item.dyePowder, 1, 15), + new ItemStack(Item.dyePowder, 1, 15) }); + par1CraftingManager.addShapelessRecipe(new ItemStack(Item.dyePowder, 2, 12), + new Object[] { new ItemStack(Item.dyePowder, 1, 4), new ItemStack(Item.dyePowder, 1, 15) }); + par1CraftingManager.addShapelessRecipe(new ItemStack(Item.dyePowder, 2, 6), + new Object[] { new ItemStack(Item.dyePowder, 1, 4), new ItemStack(Item.dyePowder, 1, 2) }); + par1CraftingManager.addShapelessRecipe(new ItemStack(Item.dyePowder, 2, 5), + new Object[] { new ItemStack(Item.dyePowder, 1, 4), new ItemStack(Item.dyePowder, 1, 1) }); + par1CraftingManager.addShapelessRecipe(new ItemStack(Item.dyePowder, 2, 13), + new Object[] { new ItemStack(Item.dyePowder, 1, 5), new ItemStack(Item.dyePowder, 1, 9) }); + par1CraftingManager.addShapelessRecipe(new ItemStack(Item.dyePowder, 3, 13), + new Object[] { new ItemStack(Item.dyePowder, 1, 4), new ItemStack(Item.dyePowder, 1, 1), + new ItemStack(Item.dyePowder, 1, 9) }); + par1CraftingManager.addShapelessRecipe(new ItemStack(Item.dyePowder, 4, 13), + new Object[] { new ItemStack(Item.dyePowder, 1, 4), new ItemStack(Item.dyePowder, 1, 1), + new ItemStack(Item.dyePowder, 1, 1), new ItemStack(Item.dyePowder, 1, 15) }); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/RecipesFood.java b/sp-server/src/main/java/net/minecraft/src/RecipesFood.java new file mode 100644 index 0000000..baa11a7 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/RecipesFood.java @@ -0,0 +1,26 @@ +package net.minecraft.src; + +public class RecipesFood { + /** + * Adds the food recipes to the CraftingManager. + */ + public void addRecipes(CraftingManager par1CraftingManager) { + par1CraftingManager.addShapelessRecipe(new ItemStack(Item.bowlSoup), + new Object[] { Block.mushroomBrown, Block.mushroomRed, Item.bowlEmpty }); + par1CraftingManager.addRecipe(new ItemStack(Item.cookie, 8), + new Object[] { "#X#", 'X', new ItemStack(Item.dyePowder, 1, 3), '#', Item.wheat }); + par1CraftingManager.addRecipe(new ItemStack(Block.melon), + new Object[] { "MMM", "MMM", "MMM", 'M', Item.melon }); + par1CraftingManager.addRecipe(new ItemStack(Item.melonSeeds), new Object[] { "M", 'M', Item.melon }); + par1CraftingManager.addRecipe(new ItemStack(Item.pumpkinSeeds, 4), new Object[] { "M", 'M', Block.pumpkin }); + par1CraftingManager.addShapelessRecipe(new ItemStack(Item.pumpkinPie), + new Object[] { Block.pumpkin, Item.sugar, Item.egg }); + par1CraftingManager.addShapelessRecipe(new ItemStack(Item.fermentedSpiderEye), + new Object[] { Item.spiderEye, Block.mushroomBrown, Item.sugar }); + par1CraftingManager.addShapelessRecipe(new ItemStack(Item.speckledMelon), + new Object[] { Item.melon, Item.goldNugget }); + par1CraftingManager.addShapelessRecipe(new ItemStack(Item.blazePowder, 2), new Object[] { Item.blazeRod }); + par1CraftingManager.addShapelessRecipe(new ItemStack(Item.magmaCream), + new Object[] { Item.blazePowder, Item.slimeBall }); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/RecipesIngots.java b/sp-server/src/main/java/net/minecraft/src/RecipesIngots.java new file mode 100644 index 0000000..add44ae --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/RecipesIngots.java @@ -0,0 +1,30 @@ +package net.minecraft.src; + +public class RecipesIngots { + private Object[][] recipeItems; + + public RecipesIngots() { + this.recipeItems = new Object[][] { { Block.blockGold, new ItemStack(Item.ingotGold, 9) }, + { Block.blockIron, new ItemStack(Item.ingotIron, 9) }, + { Block.blockDiamond, new ItemStack(Item.diamond, 9) }, + { Block.blockEmerald, new ItemStack(Item.emerald, 9) }, + { Block.blockLapis, new ItemStack(Item.dyePowder, 9, 4) }, + { Block.blockRedstone, new ItemStack(Item.redstone, 9) } }; + } + + /** + * Adds the ingot recipes to the CraftingManager. + */ + public void addRecipes(CraftingManager par1CraftingManager) { + for (int var2 = 0; var2 < this.recipeItems.length; ++var2) { + Block var3 = (Block) this.recipeItems[var2][0]; + ItemStack var4 = (ItemStack) this.recipeItems[var2][1]; + par1CraftingManager.addRecipe(new ItemStack(var3), new Object[] { "###", "###", "###", '#', var4 }); + par1CraftingManager.addRecipe(var4, new Object[] { "#", '#', var3 }); + } + + par1CraftingManager.addRecipe(new ItemStack(Item.ingotGold), + new Object[] { "###", "###", "###", '#', Item.goldNugget }); + par1CraftingManager.addRecipe(new ItemStack(Item.goldNugget, 9), new Object[] { "#", '#', Item.ingotGold }); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/RecipesMapCloning.java b/sp-server/src/main/java/net/minecraft/src/RecipesMapCloning.java new file mode 100644 index 0000000..fa7ec00 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/RecipesMapCloning.java @@ -0,0 +1,84 @@ +package net.minecraft.src; + +public class RecipesMapCloning implements IRecipe { + /** + * Used to check if a recipe matches current crafting inventory + */ + public boolean matches(InventoryCrafting par1InventoryCrafting, World par2World) { + int var3 = 0; + ItemStack var4 = null; + + for (int var5 = 0; var5 < par1InventoryCrafting.getSizeInventory(); ++var5) { + ItemStack var6 = par1InventoryCrafting.getStackInSlot(var5); + + if (var6 != null) { + if (var6.itemID == Item.map.itemID) { + if (var4 != null) { + return false; + } + + var4 = var6; + } else { + if (var6.itemID != Item.emptyMap.itemID) { + return false; + } + + ++var3; + } + } + } + + return var4 != null && var3 > 0; + } + + /** + * Returns an Item that is the result of this recipe + */ + public ItemStack getCraftingResult(InventoryCrafting par1InventoryCrafting) { + int var2 = 0; + ItemStack var3 = null; + + for (int var4 = 0; var4 < par1InventoryCrafting.getSizeInventory(); ++var4) { + ItemStack var5 = par1InventoryCrafting.getStackInSlot(var4); + + if (var5 != null) { + if (var5.itemID == Item.map.itemID) { + if (var3 != null) { + return null; + } + + var3 = var5; + } else { + if (var5.itemID != Item.emptyMap.itemID) { + return null; + } + + ++var2; + } + } + } + + if (var3 != null && var2 >= 1) { + ItemStack var6 = new ItemStack(Item.map, var2 + 1, var3.getItemDamage()); + + if (var3.hasDisplayName()) { + var6.setItemName(var3.getDisplayName()); + } + + return var6; + } else { + return null; + } + } + + /** + * Returns the size of the recipe area + */ + public int getRecipeSize() { + return 9; + } + + public ItemStack getRecipeOutput() { + return null; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/RecipesMapExtending.java b/sp-server/src/main/java/net/minecraft/src/RecipesMapExtending.java new file mode 100644 index 0000000..9bd9c70 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/RecipesMapExtending.java @@ -0,0 +1,62 @@ +package net.minecraft.src; + +public class RecipesMapExtending extends ShapedRecipes { + public RecipesMapExtending() { + super(3, 3, + new ItemStack[] { new ItemStack(Item.paper), new ItemStack(Item.paper), new ItemStack(Item.paper), + new ItemStack(Item.paper), new ItemStack(Item.map, 0, 32767), new ItemStack(Item.paper), + new ItemStack(Item.paper), new ItemStack(Item.paper), new ItemStack(Item.paper) }, + new ItemStack(Item.emptyMap, 0, 0)); + } + + /** + * Used to check if a recipe matches current crafting inventory + */ + public boolean matches(InventoryCrafting par1InventoryCrafting, World par2World) { + if (!super.matches(par1InventoryCrafting, par2World)) { + return false; + } else { + ItemStack var3 = null; + + for (int var4 = 0; var4 < par1InventoryCrafting.getSizeInventory() && var3 == null; ++var4) { + ItemStack var5 = par1InventoryCrafting.getStackInSlot(var4); + + if (var5 != null && var5.itemID == Item.map.itemID) { + var3 = var5; + } + } + + if (var3 == null) { + return false; + } else { + MapData var6 = Item.map.getMapData(var3, par2World); + return var6 == null ? false : var6.scale < 4; + } + } + } + + /** + * Returns an Item that is the result of this recipe + */ + public ItemStack getCraftingResult(InventoryCrafting par1InventoryCrafting) { + ItemStack var2 = null; + + for (int var3 = 0; var3 < par1InventoryCrafting.getSizeInventory() && var2 == null; ++var3) { + ItemStack var4 = par1InventoryCrafting.getStackInSlot(var3); + + if (var4 != null && var4.itemID == Item.map.itemID) { + var2 = var4; + } + } + + var2 = var2.copy(); + var2.stackSize = 1; + + if (var2.getTagCompound() == null) { + var2.setTagCompound(new NBTTagCompound()); + } + + var2.getTagCompound().setBoolean("map_is_scaling", true); + return var2; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/RecipesTools.java b/sp-server/src/main/java/net/minecraft/src/RecipesTools.java new file mode 100644 index 0000000..3bf3894 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/RecipesTools.java @@ -0,0 +1,33 @@ +package net.minecraft.src; + +public class RecipesTools { + private String[][] recipePatterns = new String[][] { { "XXX", " # ", " # " }, { "X", "#", "#" }, + { "XX", "X#", " #" }, { "XX", " #", " #" } }; + private Object[][] recipeItems; + + public RecipesTools() { + this.recipeItems = new Object[][] { + { Block.planks, Block.cobblestone, Item.ingotIron, Item.diamond, Item.ingotGold }, + { Item.pickaxeWood, Item.pickaxeStone, Item.pickaxeIron, Item.pickaxeDiamond, Item.pickaxeGold }, + { Item.shovelWood, Item.shovelStone, Item.shovelIron, Item.shovelDiamond, Item.shovelGold }, + { Item.axeWood, Item.axeStone, Item.axeIron, Item.axeDiamond, Item.axeGold }, + { Item.hoeWood, Item.hoeStone, Item.hoeIron, Item.hoeDiamond, Item.hoeGold } }; + } + + /** + * Adds the tool recipes to the CraftingManager. + */ + public void addRecipes(CraftingManager par1CraftingManager) { + for (int var2 = 0; var2 < this.recipeItems[0].length; ++var2) { + Object var3 = this.recipeItems[0][var2]; + + for (int var4 = 0; var4 < this.recipeItems.length - 1; ++var4) { + Item var5 = (Item) this.recipeItems[var4 + 1][var2]; + par1CraftingManager.addRecipe(new ItemStack(var5), + new Object[] { this.recipePatterns[var4], '#', Item.stick, 'X', var3 }); + } + } + + par1CraftingManager.addRecipe(new ItemStack(Item.shears), new Object[] { " #", "# ", '#', Item.ingotIron }); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/RecipesWeapons.java b/sp-server/src/main/java/net/minecraft/src/RecipesWeapons.java new file mode 100644 index 0000000..7596fa5 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/RecipesWeapons.java @@ -0,0 +1,32 @@ +package net.minecraft.src; + +public class RecipesWeapons { + private String[][] recipePatterns = new String[][] { { "X", "X", "#" } }; + private Object[][] recipeItems; + + public RecipesWeapons() { + this.recipeItems = new Object[][] { + { Block.planks, Block.cobblestone, Item.ingotIron, Item.diamond, Item.ingotGold }, + { Item.swordWood, Item.swordStone, Item.swordIron, Item.swordDiamond, Item.swordGold } }; + } + + /** + * Adds the weapon recipes to the CraftingManager. + */ + public void addRecipes(CraftingManager par1CraftingManager) { + for (int var2 = 0; var2 < this.recipeItems[0].length; ++var2) { + Object var3 = this.recipeItems[0][var2]; + + for (int var4 = 0; var4 < this.recipeItems.length - 1; ++var4) { + Item var5 = (Item) this.recipeItems[var4 + 1][var2]; + par1CraftingManager.addRecipe(new ItemStack(var5), + new Object[] { this.recipePatterns[var4], '#', Item.stick, 'X', var3 }); + } + } + + par1CraftingManager.addRecipe(new ItemStack(Item.bow, 1), + new Object[] { " #X", "# X", " #X", 'X', Item.silk, '#', Item.stick }); + par1CraftingManager.addRecipe(new ItemStack(Item.arrow, 4), + new Object[] { "X", "#", "Y", 'Y', Item.feather, 'X', Item.flint, '#', Item.stick }); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/RedstoneUpdateInfo.java b/sp-server/src/main/java/net/minecraft/src/RedstoneUpdateInfo.java new file mode 100644 index 0000000..be32de2 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/RedstoneUpdateInfo.java @@ -0,0 +1,15 @@ +package net.minecraft.src; + +class RedstoneUpdateInfo { + int x; + int y; + int z; + long updateTime; + + public RedstoneUpdateInfo(int par1, int par2, int par3, long par4) { + this.x = par1; + this.y = par2; + this.z = par3; + this.updateTime = par4; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/RegionFile.java b/sp-server/src/main/java/net/minecraft/src/RegionFile.java new file mode 100644 index 0000000..bb4ff9a --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/RegionFile.java @@ -0,0 +1,284 @@ +package net.minecraft.src; + +import java.io.BufferedInputStream; +import java.io.ByteArrayInputStream; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.File; +import java.io.IOException; +import java.io.RandomAccessFile; +import java.util.ArrayList; +import java.util.zip.DeflaterOutputStream; +import java.util.zip.GZIPInputStream; +import java.util.zip.InflaterInputStream; + +public class RegionFile { + private static final byte[] emptySector = new byte[4096]; + private final File fileName; + private RandomAccessFile dataFile; + private final int[] offsets = new int[1024]; + private final int[] chunkTimestamps = new int[1024]; + private ArrayList sectorFree; + + /** McRegion sizeDelta */ + private int sizeDelta; + private long lastModified = 0L; + + public RegionFile(File par1File) { + this.fileName = par1File; + this.sizeDelta = 0; + + try { + if (par1File.exists()) { + this.lastModified = par1File.lastModified(); + } + + this.dataFile = new RandomAccessFile(par1File, "rw"); + int var2; + + if (this.dataFile.length() < 4096L) { + for (var2 = 0; var2 < 1024; ++var2) { + this.dataFile.writeInt(0); + } + + for (var2 = 0; var2 < 1024; ++var2) { + this.dataFile.writeInt(0); + } + + this.sizeDelta += 8192; + } + + if ((this.dataFile.length() & 4095L) != 0L) { + for (var2 = 0; (long) var2 < (this.dataFile.length() & 4095L); ++var2) { + this.dataFile.write(0); + } + } + + var2 = (int) this.dataFile.length() / 4096; + this.sectorFree = new ArrayList(var2); + int var3; + + for (var3 = 0; var3 < var2; ++var3) { + this.sectorFree.add(Boolean.valueOf(true)); + } + + this.sectorFree.set(0, Boolean.valueOf(false)); + this.sectorFree.set(1, Boolean.valueOf(false)); + this.dataFile.seek(0L); + int var4; + + for (var3 = 0; var3 < 1024; ++var3) { + var4 = this.dataFile.readInt(); + this.offsets[var3] = var4; + + if (var4 != 0 && (var4 >> 8) + (var4 & 255) <= this.sectorFree.size()) { + for (int var5 = 0; var5 < (var4 & 255); ++var5) { + this.sectorFree.set((var4 >> 8) + var5, Boolean.valueOf(false)); + } + } + } + + for (var3 = 0; var3 < 1024; ++var3) { + var4 = this.dataFile.readInt(); + this.chunkTimestamps[var3] = var4; + } + } catch (IOException var6) { + var6.printStackTrace(); + } + } + + /** + * args: x, y - get uncompressed chunk stream from the region file + */ + public synchronized DataInputStream getChunkDataInputStream(int par1, int par2) { + if (this.outOfBounds(par1, par2)) { + return null; + } else { + try { + int var3 = this.getOffset(par1, par2); + + if (var3 == 0) { + return null; + } else { + int var4 = var3 >> 8; + int var5 = var3 & 255; + + if (var4 + var5 > this.sectorFree.size()) { + return null; + } else { + this.dataFile.seek((long) (var4 * 4096)); + int var6 = this.dataFile.readInt(); + + if (var6 > 4096 * var5) { + return null; + } else if (var6 <= 0) { + return null; + } else { + byte var7 = this.dataFile.readByte(); + byte[] var8; + + if (var7 == 1) { + var8 = new byte[var6 - 1]; + this.dataFile.read(var8); + return new DataInputStream( + new BufferedInputStream(new GZIPInputStream(new ByteArrayInputStream(var8)))); + } else if (var7 == 2) { + var8 = new byte[var6 - 1]; + this.dataFile.read(var8); + return new DataInputStream(new BufferedInputStream( + new InflaterInputStream(new ByteArrayInputStream(var8)))); + } else { + return null; + } + } + } + } + } catch (IOException var9) { + return null; + } + } + } + + /** + * args: x, z - get an output stream used to write chunk data, data is on disk + * when the returned stream is closed + */ + public DataOutputStream getChunkDataOutputStream(int par1, int par2) { + return this.outOfBounds(par1, par2) ? null + : new DataOutputStream(new DeflaterOutputStream(new RegionFileChunkBuffer(this, par1, par2))); + } + + /** + * args: x, z, data, length - write chunk data at (x, z) to disk + */ + protected synchronized void write(int par1, int par2, byte[] par3ArrayOfByte, int par4) { + try { + int var5 = this.getOffset(par1, par2); + int var6 = var5 >> 8; + int var7 = var5 & 255; + int var8 = (par4 + 5) / 4096 + 1; + + if (var8 >= 256) { + return; + } + + if (var6 != 0 && var7 == var8) { + this.write(var6, par3ArrayOfByte, par4); + } else { + int var9; + + for (var9 = 0; var9 < var7; ++var9) { + this.sectorFree.set(var6 + var9, Boolean.valueOf(true)); + } + + var9 = this.sectorFree.indexOf(Boolean.valueOf(true)); + int var10 = 0; + int var11; + + if (var9 != -1) { + for (var11 = var9; var11 < this.sectorFree.size(); ++var11) { + if (var10 != 0) { + if (((Boolean) this.sectorFree.get(var11)).booleanValue()) { + ++var10; + } else { + var10 = 0; + } + } else if (((Boolean) this.sectorFree.get(var11)).booleanValue()) { + var9 = var11; + var10 = 1; + } + + if (var10 >= var8) { + break; + } + } + } + + if (var10 >= var8) { + var6 = var9; + this.setOffset(par1, par2, var9 << 8 | var8); + + for (var11 = 0; var11 < var8; ++var11) { + this.sectorFree.set(var6 + var11, Boolean.valueOf(false)); + } + + this.write(var6, par3ArrayOfByte, par4); + } else { + this.dataFile.seek(this.dataFile.length()); + var6 = this.sectorFree.size(); + + for (var11 = 0; var11 < var8; ++var11) { + this.dataFile.write(emptySector); + this.sectorFree.add(Boolean.valueOf(false)); + } + + this.sizeDelta += 4096 * var8; + this.write(var6, par3ArrayOfByte, par4); + this.setOffset(par1, par2, var6 << 8 | var8); + } + } + + this.setChunkTimestamp(par1, par2, (int) (System.currentTimeMillis() / 1000L)); + } catch (IOException var12) { + var12.printStackTrace(); + } + } + + /** + * args: sectorNumber, data, length - write the chunk data to this RegionFile + */ + private void write(int par1, byte[] par2ArrayOfByte, int par3) throws IOException { + this.dataFile.seek((long) (par1 * 4096)); + this.dataFile.writeInt(par3 + 1); + this.dataFile.writeByte(2); + this.dataFile.write(par2ArrayOfByte, 0, par3); + } + + /** + * args: x, z - check region bounds + */ + private boolean outOfBounds(int par1, int par2) { + return par1 < 0 || par1 >= 32 || par2 < 0 || par2 >= 32; + } + + /** + * args: x, y - get chunk's offset in region file + */ + private int getOffset(int par1, int par2) { + return this.offsets[par1 + par2 * 32]; + } + + /** + * args: x, z, - true if chunk has been saved / converted + */ + public boolean isChunkSaved(int par1, int par2) { + return this.getOffset(par1, par2) != 0; + } + + /** + * args: x, z, offset - sets the chunk's offset in the region file + */ + private void setOffset(int par1, int par2, int par3) throws IOException { + this.offsets[par1 + par2 * 32] = par3; + this.dataFile.seek((long) ((par1 + par2 * 32) * 4)); + this.dataFile.writeInt(par3); + } + + /** + * args: x, z, timestamp - sets the chunk's write timestamp + */ + private void setChunkTimestamp(int par1, int par2, int par3) throws IOException { + this.chunkTimestamps[par1 + par2 * 32] = par3; + this.dataFile.seek((long) (4096 + (par1 + par2 * 32) * 4)); + this.dataFile.writeInt(par3); + } + + /** + * close this RegionFile and prevent further writes + */ + public void close() throws IOException { + if (this.dataFile != null) { + this.dataFile.close(); + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/RegionFileCache.java b/sp-server/src/main/java/net/minecraft/src/RegionFileCache.java new file mode 100644 index 0000000..9d67f19 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/RegionFileCache.java @@ -0,0 +1,75 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.File; +import java.io.IOException; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +public class RegionFileCache { + /** A map containing Files as keys and RegionFiles as values */ + private static final Map regionsByFilename = new HashMap(); + + public static synchronized RegionFile createOrLoadRegionFile(File par0File, int par1, int par2) { + File var3 = new File(par0File, "region"); + File var4 = new File(var3, "r." + (par1 >> 5) + "." + (par2 >> 5) + ".mca"); + RegionFile var5 = (RegionFile) regionsByFilename.get(var4); + + if (var5 != null) { + return var5; + } else { + if (!var3.exists()) { + var3.mkdirs(); + } + + if (regionsByFilename.size() >= 256) { + clearRegionFileReferences(); + } + + RegionFile var6 = new RegionFile(var4); + regionsByFilename.put(var4, var6); + return var6; + } + } + + /** + * clears region file references + */ + public static synchronized void clearRegionFileReferences() { + Iterator var0 = regionsByFilename.values().iterator(); + + while (var0.hasNext()) { + RegionFile var1 = (RegionFile) var0.next(); + + try { + if (var1 != null) { + var1.close(); + } + } catch (IOException var3) { + var3.printStackTrace(); + } + } + + regionsByFilename.clear(); + } + + /** + * Returns an input stream for the specified chunk. Args: worldDir, chunkX, + * chunkZ + */ + public static DataInputStream getChunkInputStream(File par0File, int par1, int par2) { + RegionFile var3 = createOrLoadRegionFile(par0File, par1, par2); + return var3.getChunkDataInputStream(par1 & 31, par2 & 31); + } + + /** + * Returns an output stream for the specified chunk. Args: worldDir, chunkX, + * chunkZ + */ + public static DataOutputStream getChunkOutputStream(File par0File, int par1, int par2) { + RegionFile var3 = createOrLoadRegionFile(par0File, par1, par2); + return var3.getChunkDataOutputStream(par1 & 31, par2 & 31); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/RegionFileChunkBuffer.java b/sp-server/src/main/java/net/minecraft/src/RegionFileChunkBuffer.java new file mode 100644 index 0000000..c14f2d3 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/RegionFileChunkBuffer.java @@ -0,0 +1,22 @@ +package net.minecraft.src; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +class RegionFileChunkBuffer extends ByteArrayOutputStream { + private int chunkX; + private int chunkZ; + + final RegionFile regionFile; + + public RegionFileChunkBuffer(RegionFile par1RegionFile, int par2, int par3) { + super(8096); + this.regionFile = par1RegionFile; + this.chunkX = par2; + this.chunkZ = par3; + } + + public void close() throws IOException { + this.regionFile.write(this.chunkX, this.chunkZ, this.buf, this.count); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/RegistryDefaulted.java b/sp-server/src/main/java/net/minecraft/src/RegistryDefaulted.java new file mode 100644 index 0000000..4881f01 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/RegistryDefaulted.java @@ -0,0 +1,17 @@ +package net.minecraft.src; + +public class RegistryDefaulted extends RegistrySimple { + /** + * Default object for this registry, returned when an object is not found. + */ + private final Object defaultObject; + + public RegistryDefaulted(Object par1Obj) { + this.defaultObject = par1Obj; + } + + public Object func_82594_a(Object par1Obj) { + Object var2 = super.func_82594_a(par1Obj); + return var2 == null ? this.defaultObject : var2; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/RegistrySimple.java b/sp-server/src/main/java/net/minecraft/src/RegistrySimple.java new file mode 100644 index 0000000..9ebb4d8 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/RegistrySimple.java @@ -0,0 +1,20 @@ +package net.minecraft.src; + +import java.util.HashMap; +import java.util.Map; + +public class RegistrySimple implements IRegistry { + /** Objects registered on this registry. */ + protected final Map registryObjects = new HashMap(); + + public Object func_82594_a(Object par1Obj) { + return this.registryObjects.get(par1Obj); + } + + /** + * Register an object on this registry. + */ + public void putObject(Object par1Obj, Object par2Obj) { + this.registryObjects.put(par1Obj, par2Obj); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ReportedException.java b/sp-server/src/main/java/net/minecraft/src/ReportedException.java new file mode 100644 index 0000000..5cedfac --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ReportedException.java @@ -0,0 +1,25 @@ +package net.minecraft.src; + +public class ReportedException extends RuntimeException { + /** Instance of CrashReport. */ + private final CrashReport theReportedExceptionCrashReport; + + public ReportedException(CrashReport par1CrashReport) { + this.theReportedExceptionCrashReport = par1CrashReport; + } + + /** + * Gets the CrashReport wrapped by this exception. + */ + public CrashReport getCrashReport() { + return this.theReportedExceptionCrashReport; + } + + public Throwable getCause() { + return this.theReportedExceptionCrashReport.getCrashCause(); + } + + public String getMessage() { + return this.theReportedExceptionCrashReport.getDescription(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/SaveFormatOld.java b/sp-server/src/main/java/net/minecraft/src/SaveFormatOld.java new file mode 100644 index 0000000..ac883f6 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/SaveFormatOld.java @@ -0,0 +1,141 @@ +package net.minecraft.src; + +import java.io.File; +import java.io.FileInputStream; + +public class SaveFormatOld implements ISaveFormat { + /** + * Reference to the File object representing the directory for the world saves + */ + protected final File savesDirectory; + + public SaveFormatOld(File par1File) { + if (!par1File.exists()) { + par1File.mkdirs(); + } + + this.savesDirectory = par1File; + } + + public void flushCache() { + } + + /** + * gets the world info + */ + public WorldInfo getWorldInfo(String par1Str) { + File var2 = new File(this.savesDirectory, par1Str); + + if (!var2.exists()) { + return null; + } else { + File var3 = new File(var2, "level.dat"); + NBTTagCompound var4; + NBTTagCompound var5; + + if (var3.exists()) { + try { + var4 = CompressedStreamTools.readCompressed(new FileInputStream(var3)); + var5 = var4.getCompoundTag("Data"); + return new WorldInfo(var5); + } catch (Exception var7) { + var7.printStackTrace(); + } + } + + var3 = new File(var2, "level.dat_old"); + + if (var3.exists()) { + try { + var4 = CompressedStreamTools.readCompressed(new FileInputStream(var3)); + var5 = var4.getCompoundTag("Data"); + return new WorldInfo(var5); + } catch (Exception var6) { + var6.printStackTrace(); + } + } + + return null; + } + } + + /** + * @args: Takes one argument - the name of the directory of the world to + * delete. @desc: Delete the world by deleting the associated directory + * recursively. + */ + public boolean deleteWorldDirectory(String par1Str) { + File var2 = new File(this.savesDirectory, par1Str); + + if (!var2.exists()) { + return true; + } else { + System.out.println("Deleting level " + par1Str); + + for (int var3 = 1; var3 <= 5; ++var3) { + System.out.println("Attempt " + var3 + "..."); + + if (deleteFiles(var2.listFiles())) { + break; + } + + System.out.println("Unsuccessful in deleting contents."); + + if (var3 < 5) { + try { + Thread.sleep(500L); + } catch (InterruptedException var5) { + ; + } + } + } + + return var2.delete(); + } + } + + /** + * @args: Takes one argument - the list of files and directories to + * delete. @desc: Deletes the files and directory listed in the list + * recursively. + */ + protected static boolean deleteFiles(File[] par0ArrayOfFile) { + for (int var1 = 0; var1 < par0ArrayOfFile.length; ++var1) { + File var2 = par0ArrayOfFile[var1]; + System.out.println("Deleting " + var2); + + if (var2.isDirectory() && !deleteFiles(var2.listFiles())) { + System.out.println("Couldn\'t delete directory " + var2); + return false; + } + + if (!var2.delete()) { + System.out.println("Couldn\'t delete file " + var2); + return false; + } + } + + return true; + } + + /** + * Returns back a loader for the specified save directory + */ + public ISaveHandler getSaveLoader(String par1Str, boolean par2) { + return new SaveHandler(this.savesDirectory, par1Str, par2); + } + + /** + * gets if the map is old chunk saving (true) or McRegion (false) + */ + public boolean isOldMapFormat(String par1Str) { + return false; + } + + /** + * converts the map to mcRegion + */ + public boolean convertMapFormat(String par1Str, IProgressUpdate par2IProgressUpdate) { + return false; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/SaveHandler.java b/sp-server/src/main/java/net/minecraft/src/SaveHandler.java new file mode 100644 index 0000000..6240892 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/SaveHandler.java @@ -0,0 +1,287 @@ +package net.minecraft.src; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import net.minecraft.server.MinecraftServer; + +public class SaveHandler implements ISaveHandler, IPlayerFileData { + /** The directory in which to save world data. */ + private final File worldDirectory; + + /** The directory in which to save player data. */ + private final File playersDirectory; + private final File mapDataDir; + + /** + * The time in milliseconds when this field was initialized. Stored in the + * session lock file. + */ + private final long initializationTime = System.currentTimeMillis(); + + /** The directory name of the world */ + private final String saveDirectoryName; + + public SaveHandler(File par1File, String par2Str, boolean par3) { + this.worldDirectory = new File(par1File, par2Str); + this.worldDirectory.mkdirs(); + this.playersDirectory = new File(this.worldDirectory, "players"); + this.mapDataDir = new File(this.worldDirectory, "data"); + this.mapDataDir.mkdirs(); + this.saveDirectoryName = par2Str; + + if (par3) { + this.playersDirectory.mkdirs(); + } + + this.setSessionLock(); + } + + /** + * Creates a session lock file for this process + */ + private void setSessionLock() { + try { + File var1 = new File(this.worldDirectory, "session.lock"); + DataOutputStream var2 = new DataOutputStream(new FileOutputStream(var1)); + + try { + var2.writeLong(this.initializationTime); + } finally { + var2.close(); + } + } catch (IOException var7) { + var7.printStackTrace(); + throw new RuntimeException("Failed to check session lock, aborting"); + } + } + + /** + * Gets the File object corresponding to the base directory of this world. + */ + protected File getWorldDirectory() { + return this.worldDirectory; + } + + /** + * Checks the session lock to prevent save collisions + */ + public void checkSessionLock() throws MinecraftException { + try { + File var1 = new File(this.worldDirectory, "session.lock"); + DataInputStream var2 = new DataInputStream(new FileInputStream(var1)); + + try { + if (var2.readLong() != this.initializationTime) { + throw new MinecraftException("The save is being accessed from another location, aborting"); + } + } finally { + var2.close(); + } + } catch (IOException var7) { + throw new MinecraftException("Failed to check session lock, aborting"); + } + } + + /** + * initializes and returns the chunk loader for the specified world provider + */ + public IChunkLoader getChunkLoader(WorldProvider par1WorldProvider) { + throw new RuntimeException("Old Chunk Storage is no longer supported."); + } + + /** + * Loads and returns the world info + */ + public WorldInfo loadWorldInfo() { + File var1 = new File(this.worldDirectory, "level.dat"); + NBTTagCompound var2; + NBTTagCompound var3; + + if (var1.exists()) { + try { + var2 = CompressedStreamTools.readCompressed(new FileInputStream(var1)); + var3 = var2.getCompoundTag("Data"); + return new WorldInfo(var3); + } catch (Exception var5) { + var5.printStackTrace(); + } + } + + var1 = new File(this.worldDirectory, "level.dat_old"); + + if (var1.exists()) { + try { + var2 = CompressedStreamTools.readCompressed(new FileInputStream(var1)); + var3 = var2.getCompoundTag("Data"); + return new WorldInfo(var3); + } catch (Exception var4) { + var4.printStackTrace(); + } + } + + return null; + } + + /** + * Saves the given World Info with the given NBTTagCompound as the Player. + */ + public void saveWorldInfoWithPlayer(WorldInfo par1WorldInfo, NBTTagCompound par2NBTTagCompound) { + NBTTagCompound var3 = par1WorldInfo.cloneNBTCompound(par2NBTTagCompound); + NBTTagCompound var4 = new NBTTagCompound(); + var4.setTag("Data", var3); + + try { + File var5 = new File(this.worldDirectory, "level.dat_new"); + File var6 = new File(this.worldDirectory, "level.dat_old"); + File var7 = new File(this.worldDirectory, "level.dat"); + CompressedStreamTools.writeCompressed(var4, new FileOutputStream(var5)); + + if (var6.exists()) { + var6.delete(); + } + + var7.renameTo(var6); + + if (var7.exists()) { + var7.delete(); + } + + var5.renameTo(var7); + + if (var5.exists()) { + var5.delete(); + } + } catch (Exception var8) { + var8.printStackTrace(); + } + } + + /** + * used to update level.dat from old format to MCRegion format + */ + public void saveWorldInfo(WorldInfo par1WorldInfo) { + NBTTagCompound var2 = par1WorldInfo.getNBTTagCompound(); + NBTTagCompound var3 = new NBTTagCompound(); + var3.setTag("Data", var2); + + try { + File var4 = new File(this.worldDirectory, "level.dat_new"); + File var5 = new File(this.worldDirectory, "level.dat_old"); + File var6 = new File(this.worldDirectory, "level.dat"); + CompressedStreamTools.writeCompressed(var3, new FileOutputStream(var4)); + + if (var5.exists()) { + var5.delete(); + } + + var6.renameTo(var5); + + if (var6.exists()) { + var6.delete(); + } + + var4.renameTo(var6); + + if (var4.exists()) { + var4.delete(); + } + } catch (Exception var7) { + var7.printStackTrace(); + } + } + + /** + * Writes the player data to disk from the specified PlayerEntityMP. + */ + public void writePlayerData(EntityPlayer par1EntityPlayer) { + try { + NBTTagCompound var2 = new NBTTagCompound(); + par1EntityPlayer.writeToNBT(var2); + File var3 = new File(this.playersDirectory, par1EntityPlayer.username + ".dat.tmp"); + File var4 = new File(this.playersDirectory, par1EntityPlayer.username + ".dat"); + CompressedStreamTools.writeCompressed(var2, new FileOutputStream(var3)); + + if (var4.exists()) { + var4.delete(); + } + + var3.renameTo(var4); + } catch (Exception var5) { + MinecraftServer.getServer().getLogAgent() + .func_98236_b("Failed to save player data for " + par1EntityPlayer.username); + } + } + + /** + * Reads the player data from disk into the specified PlayerEntityMP. + */ + public NBTTagCompound readPlayerData(EntityPlayer par1EntityPlayer) { + NBTTagCompound var2 = this.getPlayerData(par1EntityPlayer.username); + + if (var2 != null) { + par1EntityPlayer.readFromNBT(var2); + } + + return var2; + } + + /** + * Gets the player data for the given playername as a NBTTagCompound. + */ + public NBTTagCompound getPlayerData(String par1Str) { + try { + File var2 = new File(this.playersDirectory, par1Str + ".dat"); + + if (var2.exists()) { + return CompressedStreamTools.readCompressed(new FileInputStream(var2)); + } + } catch (Exception var3) { + MinecraftServer.getServer().getLogAgent().func_98236_b("Failed to load player data for " + par1Str); + } + + return null; + } + + public IPlayerFileData getPlayerNBTManager() { + return this; + } + + /** + * Returns an array of usernames for which player.dat exists for. + */ + public String[] getAvailablePlayerDat() { + String[] var1 = this.playersDirectory.list(); + + for (int var2 = 0; var2 < var1.length; ++var2) { + if (var1[var2].endsWith(".dat")) { + var1[var2] = var1[var2].substring(0, var1[var2].length() - 4); + } + } + + return var1; + } + + /** + * Called to flush all changes to disk, waiting for them to complete. + */ + public void flush() { + } + + /** + * Gets the file location of the given map + */ + public File getMapFileFromName(String par1Str) { + return new File(this.mapDataDir, par1Str + ".dat"); + } + + /** + * Returns the name of the directory where world information is saved. + */ + public String getWorldDirectoryName() { + return this.saveDirectoryName; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/Score.java b/sp-server/src/main/java/net/minecraft/src/Score.java new file mode 100644 index 0000000..59acc03 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/Score.java @@ -0,0 +1,71 @@ +package net.minecraft.src; + +import java.util.Comparator; +import java.util.List; + +public class Score { + public static final Comparator field_96658_a = new ScoreComparator(); + private final Scoreboard theScoreboard; + private final ScoreObjective field_96657_c; + private final String field_96654_d; + private int field_96655_e; + + public Score(Scoreboard par1Scoreboard, ScoreObjective par2ScoreObjective, String par3Str) { + this.theScoreboard = par1Scoreboard; + this.field_96657_c = par2ScoreObjective; + this.field_96654_d = par3Str; + } + + public void func_96649_a(int par1) { + if (this.field_96657_c.getCriteria().isReadOnly()) { + throw new IllegalStateException("Cannot modify read-only score"); + } else { + this.func_96647_c(this.func_96652_c() + par1); + } + } + + public void func_96646_b(int par1) { + if (this.field_96657_c.getCriteria().isReadOnly()) { + throw new IllegalStateException("Cannot modify read-only score"); + } else { + this.func_96647_c(this.func_96652_c() - par1); + } + } + + public void func_96648_a() { + if (this.field_96657_c.getCriteria().isReadOnly()) { + throw new IllegalStateException("Cannot modify read-only score"); + } else { + this.func_96649_a(1); + } + } + + public int func_96652_c() { + return this.field_96655_e; + } + + public void func_96647_c(int par1) { + int var2 = this.field_96655_e; + this.field_96655_e = par1; + + if (var2 != par1) { + this.func_96650_f().func_96536_a(this); + } + } + + public ScoreObjective func_96645_d() { + return this.field_96657_c; + } + + public String func_96653_e() { + return this.field_96654_d; + } + + public Scoreboard func_96650_f() { + return this.theScoreboard; + } + + public void func_96651_a(List par1List) { + this.func_96647_c(this.field_96657_c.getCriteria().func_96635_a(par1List)); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ScoreComparator.java b/sp-server/src/main/java/net/minecraft/src/ScoreComparator.java new file mode 100644 index 0000000..924521f --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ScoreComparator.java @@ -0,0 +1,14 @@ +package net.minecraft.src; + +import java.util.Comparator; + +final class ScoreComparator implements Comparator { + public int func_96659_a(Score par1Score, Score par2Score) { + return par1Score.func_96652_c() > par2Score.func_96652_c() ? 1 + : (par1Score.func_96652_c() < par2Score.func_96652_c() ? -1 : 0); + } + + public int compare(Object par1Obj, Object par2Obj) { + return this.func_96659_a((Score) par1Obj, (Score) par2Obj); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ScoreDummyCriteria.java b/sp-server/src/main/java/net/minecraft/src/ScoreDummyCriteria.java new file mode 100644 index 0000000..68c8a32 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ScoreDummyCriteria.java @@ -0,0 +1,24 @@ +package net.minecraft.src; + +import java.util.List; + +public class ScoreDummyCriteria implements ScoreObjectiveCriteria { + private final String field_96644_g; + + public ScoreDummyCriteria(String par1Str) { + this.field_96644_g = par1Str; + ScoreObjectiveCriteria.field_96643_a.put(par1Str, this); + } + + public String func_96636_a() { + return this.field_96644_g; + } + + public int func_96635_a(List par1List) { + return 0; + } + + public boolean isReadOnly() { + return false; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ScoreHealthCriteria.java b/sp-server/src/main/java/net/minecraft/src/ScoreHealthCriteria.java new file mode 100644 index 0000000..99748d2 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ScoreHealthCriteria.java @@ -0,0 +1,40 @@ +package net.minecraft.src; + +import java.util.Iterator; +import java.util.List; + +public class ScoreHealthCriteria extends ScoreDummyCriteria { + public ScoreHealthCriteria(String par1Str) { + super(par1Str); + } + + public int func_96635_a(List par1List) { + float var2 = 0.0F; + int var5; + float var6; + + for (Iterator var3 = par1List.iterator(); var3.hasNext(); var2 += (float) var5 / var6) { + EntityPlayer var4 = (EntityPlayer) var3.next(); + var5 = var4.getHealth(); + var6 = (float) var4.getMaxHealth(); + + if (var5 < 0) { + var5 = 0; + } + + if ((float) var5 > var6) { + var5 = var4.getMaxHealth(); + } + } + + if (par1List.size() > 0) { + var2 /= (float) par1List.size(); + } + + return MathHelper.floor_float(var2 * 19.0F) + (var2 > 0.0F ? 1 : 0); + } + + public boolean isReadOnly() { + return true; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ScoreObjective.java b/sp-server/src/main/java/net/minecraft/src/ScoreObjective.java new file mode 100644 index 0000000..4788598 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ScoreObjective.java @@ -0,0 +1,35 @@ +package net.minecraft.src; + +public class ScoreObjective { + private final Scoreboard theScoreboard; + private final String name; + + /** The ScoreObjectiveCriteria for this objetive */ + private final ScoreObjectiveCriteria objectiveCriteria; + private String displayName; + + public ScoreObjective(Scoreboard par1Scoreboard, String par2Str, + ScoreObjectiveCriteria par3ScoreObjectiveCriteria) { + this.theScoreboard = par1Scoreboard; + this.name = par2Str; + this.objectiveCriteria = par3ScoreObjectiveCriteria; + this.displayName = par2Str; + } + + public String getName() { + return this.name; + } + + public ScoreObjectiveCriteria getCriteria() { + return this.objectiveCriteria; + } + + public String getDisplayName() { + return this.displayName; + } + + public void setDisplayName(String par1Str) { + this.displayName = par1Str; + this.theScoreboard.func_96532_b(this); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ScoreObjectiveCriteria.java b/sp-server/src/main/java/net/minecraft/src/ScoreObjectiveCriteria.java new file mode 100644 index 0000000..df4ca25 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ScoreObjectiveCriteria.java @@ -0,0 +1,20 @@ +package net.minecraft.src; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public interface ScoreObjectiveCriteria { + Map field_96643_a = new HashMap(); + ScoreObjectiveCriteria field_96641_b = new ScoreDummyCriteria("dummy"); + ScoreObjectiveCriteria field_96642_c = new ScoreDummyCriteria("deathCount"); + ScoreObjectiveCriteria field_96639_d = new ScoreDummyCriteria("playerKillCount"); + ScoreObjectiveCriteria field_96640_e = new ScoreDummyCriteria("totalKillCount"); + ScoreObjectiveCriteria field_96638_f = new ScoreHealthCriteria("health"); + + String func_96636_a(); + + int func_96635_a(List var1); + + boolean isReadOnly(); +} diff --git a/sp-server/src/main/java/net/minecraft/src/ScorePlayerTeam.java b/sp-server/src/main/java/net/minecraft/src/ScorePlayerTeam.java new file mode 100644 index 0000000..13b4f15 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ScorePlayerTeam.java @@ -0,0 +1,109 @@ +package net.minecraft.src; + +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; + +public class ScorePlayerTeam { + private final Scoreboard theScoreboard; + private final String field_96675_b; + + /** A set of all team member usernames. */ + private final Set membershipSet = new HashSet(); + private String field_96673_d; + private String field_96674_e = ""; + private String field_96671_f = ""; + private boolean field_96672_g = true; + private boolean field_98301_h = true; + + public ScorePlayerTeam(Scoreboard par1Scoreboard, String par2Str) { + this.theScoreboard = par1Scoreboard; + this.field_96675_b = par2Str; + this.field_96673_d = par2Str; + } + + public String func_96661_b() { + return this.field_96675_b; + } + + public String func_96669_c() { + return this.field_96673_d; + } + + public void func_96664_a(String par1Str) { + if (par1Str == null) { + throw new IllegalArgumentException("Name cannot be null"); + } else { + this.field_96673_d = par1Str; + this.theScoreboard.func_96538_b(this); + } + } + + public Collection getMembershipCollection() { + return this.membershipSet; + } + + public String func_96668_e() { + return this.field_96674_e; + } + + public void func_96666_b(String par1Str) { + if (par1Str == null) { + throw new IllegalArgumentException("Prefix cannot be null"); + } else { + this.field_96674_e = par1Str; + this.theScoreboard.func_96538_b(this); + } + } + + public String func_96663_f() { + return this.field_96671_f; + } + + public void func_96662_c(String par1Str) { + if (par1Str == null) { + throw new IllegalArgumentException("Suffix cannot be null"); + } else { + this.field_96671_f = par1Str; + this.theScoreboard.func_96538_b(this); + } + } + + public static String func_96667_a(ScorePlayerTeam par0ScorePlayerTeam, String par1Str) { + return par0ScorePlayerTeam == null ? par1Str + : par0ScorePlayerTeam.func_96668_e() + par1Str + par0ScorePlayerTeam.func_96663_f(); + } + + public boolean func_96665_g() { + return this.field_96672_g; + } + + public void func_96660_a(boolean par1) { + this.field_96672_g = par1; + this.theScoreboard.func_96538_b(this); + } + + public boolean func_98297_h() { + return this.field_98301_h; + } + + public void func_98300_b(boolean par1) { + this.field_98301_h = par1; + this.theScoreboard.func_96538_b(this); + } + + public int func_98299_i() { + int var1 = 0; + int var2 = 0; + + if (this.func_96665_g()) { + var1 |= 1 << var2++; + } + + if (this.func_98297_h()) { + var1 |= 1 << var2++; + } + + return var1; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/Scoreboard.java b/sp-server/src/main/java/net/minecraft/src/Scoreboard.java new file mode 100644 index 0000000..fd6e0e6 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/Scoreboard.java @@ -0,0 +1,295 @@ +package net.minecraft.src; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +public class Scoreboard { + /** Map of objective names to ScoreObjective objects. */ + private final Map scoreObjectives = new HashMap(); + private final Map field_96543_b = new HashMap(); + private final Map field_96544_c = new HashMap(); + private final ScoreObjective[] field_96541_d = new ScoreObjective[3]; + private final Map field_96542_e = new HashMap(); + + /** Map of usernames to ScorePlayerTeam objects. */ + private final Map teamMemberships = new HashMap(); + + /** + * Returns a ScoreObjective for the objective name + */ + public ScoreObjective getObjective(String par1Str) { + return (ScoreObjective) this.scoreObjectives.get(par1Str); + } + + public ScoreObjective func_96535_a(String par1Str, ScoreObjectiveCriteria par2ScoreObjectiveCriteria) { + ScoreObjective var3 = this.getObjective(par1Str); + + if (var3 != null) { + throw new IllegalArgumentException("An objective with the name \'" + par1Str + "\' already exists!"); + } else { + var3 = new ScoreObjective(this, par1Str, par2ScoreObjectiveCriteria); + Object var4 = (List) this.field_96543_b.get(par2ScoreObjectiveCriteria); + + if (var4 == null) { + var4 = new ArrayList(); + this.field_96543_b.put(par2ScoreObjectiveCriteria, var4); + } + + ((List) var4).add(var3); + this.scoreObjectives.put(par1Str, var3); + this.func_96522_a(var3); + return var3; + } + } + + public Collection func_96520_a(ScoreObjectiveCriteria par1ScoreObjectiveCriteria) { + Collection var2 = (Collection) this.field_96543_b.get(par1ScoreObjectiveCriteria); + return var2 == null ? new ArrayList() : new ArrayList(var2); + } + + public Score func_96529_a(String par1Str, ScoreObjective par2ScoreObjective) { + Object var3 = (Map) this.field_96544_c.get(par1Str); + + if (var3 == null) { + var3 = new HashMap(); + this.field_96544_c.put(par1Str, var3); + } + + Score var4 = (Score) ((Map) var3).get(par2ScoreObjective); + + if (var4 == null) { + var4 = new Score(this, par2ScoreObjective, par1Str); + ((Map) var3).put(par2ScoreObjective, var4); + } + + return var4; + } + + public Collection func_96534_i(ScoreObjective par1ScoreObjective) { + ArrayList var2 = new ArrayList(); + Iterator var3 = this.field_96544_c.values().iterator(); + + while (var3.hasNext()) { + Map var4 = (Map) var3.next(); + Score var5 = (Score) var4.get(par1ScoreObjective); + + if (var5 != null) { + var2.add(var5); + } + } + + Collections.sort(var2, Score.field_96658_a); + return var2; + } + + public Collection getScoreObjectives() { + return this.scoreObjectives.values(); + } + + public Collection getObjectiveNames() { + return this.field_96544_c.keySet(); + } + + public void func_96515_c(String par1Str) { + Map var2 = (Map) this.field_96544_c.remove(par1Str); + + if (var2 != null) { + this.func_96516_a(par1Str); + } + } + + public Collection func_96528_e() { + Collection var1 = this.field_96544_c.values(); + ArrayList var2 = new ArrayList(); + + if (var1 != null) { + Iterator var3 = var1.iterator(); + + while (var3.hasNext()) { + Map var4 = (Map) var3.next(); + var2.addAll(var4.values()); + } + } + + return var2; + } + + public Map func_96510_d(String par1Str) { + Object var2 = (Map) this.field_96544_c.get(par1Str); + + if (var2 == null) { + var2 = new HashMap(); + } + + return (Map) var2; + } + + public void func_96519_k(ScoreObjective par1ScoreObjective) { + this.scoreObjectives.remove(par1ScoreObjective.getName()); + + for (int var2 = 0; var2 < 3; ++var2) { + if (this.func_96539_a(var2) == par1ScoreObjective) { + this.func_96530_a(var2, (ScoreObjective) null); + } + } + + List var5 = (List) this.field_96543_b.get(par1ScoreObjective.getCriteria()); + + if (var5 != null) { + var5.remove(par1ScoreObjective); + } + + Iterator var3 = this.field_96544_c.values().iterator(); + + while (var3.hasNext()) { + Map var4 = (Map) var3.next(); + var4.remove(par1ScoreObjective); + } + + this.func_96533_c(par1ScoreObjective); + } + + public void func_96530_a(int par1, ScoreObjective par2ScoreObjective) { + this.field_96541_d[par1] = par2ScoreObjective; + } + + public ScoreObjective func_96539_a(int par1) { + return this.field_96541_d[par1]; + } + + public ScorePlayerTeam func_96508_e(String par1Str) { + return (ScorePlayerTeam) this.field_96542_e.get(par1Str); + } + + public ScorePlayerTeam func_96527_f(String par1Str) { + ScorePlayerTeam var2 = this.func_96508_e(par1Str); + + if (var2 != null) { + throw new IllegalArgumentException("An objective with the name \'" + par1Str + "\' already exists!"); + } else { + var2 = new ScorePlayerTeam(this, par1Str); + this.field_96542_e.put(par1Str, var2); + this.func_96523_a(var2); + return var2; + } + } + + public void func_96511_d(ScorePlayerTeam par1ScorePlayerTeam) { + this.field_96542_e.remove(par1ScorePlayerTeam.func_96661_b()); + Iterator var2 = par1ScorePlayerTeam.getMembershipCollection().iterator(); + + while (var2.hasNext()) { + String var3 = (String) var2.next(); + this.teamMemberships.remove(var3); + } + + this.func_96513_c(par1ScorePlayerTeam); + } + + public void func_96521_a(String par1Str, ScorePlayerTeam par2ScorePlayerTeam) { + if (this.getPlayersTeam(par1Str) != null) { + this.func_96524_g(par1Str); + } + + this.teamMemberships.put(par1Str, par2ScorePlayerTeam); + par2ScorePlayerTeam.getMembershipCollection().add(par1Str); + } + + public boolean func_96524_g(String par1Str) { + ScorePlayerTeam var2 = this.getPlayersTeam(par1Str); + + if (var2 != null) { + this.removePlayerFromTeam(par1Str, var2); + return true; + } else { + return false; + } + } + + /** + * Removes the given username from the given ScorePlayerTeam. If the player is + * not on the team then an IllegalStateException is thrown. + */ + public void removePlayerFromTeam(String par1Str, ScorePlayerTeam par2ScorePlayerTeam) { + if (this.getPlayersTeam(par1Str) != par2ScorePlayerTeam) { + throw new IllegalStateException( + "Player is either on another team or not on any team. Cannot remove from team \'" + + par2ScorePlayerTeam.func_96661_b() + "\'."); + } else { + this.teamMemberships.remove(par1Str); + par2ScorePlayerTeam.getMembershipCollection().remove(par1Str); + } + } + + public Collection func_96531_f() { + return this.field_96542_e.keySet(); + } + + public Collection func_96525_g() { + return this.field_96542_e.values(); + } + + /** + * Gets the ScorePlayerTeam object for the given username. + */ + public ScorePlayerTeam getPlayersTeam(String par1Str) { + return (ScorePlayerTeam) this.teamMemberships.get(par1Str); + } + + public void func_96522_a(ScoreObjective par1ScoreObjective) { + } + + public void func_96532_b(ScoreObjective par1ScoreObjective) { + } + + public void func_96533_c(ScoreObjective par1ScoreObjective) { + } + + public void func_96536_a(Score par1Score) { + } + + public void func_96516_a(String par1Str) { + } + + public void func_96523_a(ScorePlayerTeam par1ScorePlayerTeam) { + } + + public void func_96538_b(ScorePlayerTeam par1ScorePlayerTeam) { + } + + public void func_96513_c(ScorePlayerTeam par1ScorePlayerTeam) { + } + + /** + * Returns 'list' for 0, 'sidebar' for 1, 'belowName for 2, otherwise null. + */ + public static String getObjectiveDisplaySlot(int par0) { + switch (par0) { + case 0: + return "list"; + + case 1: + return "sidebar"; + + case 2: + return "belowName"; + + default: + return null; + } + } + + /** + * Returns 0 for (case-insensitive) 'list', 1 for 'sidebar', 2 for 'belowName', + * otherwise -1. + */ + public static int getObjectiveDisplaySlotNumber(String par0Str) { + return par0Str.equalsIgnoreCase("list") ? 0 + : (par0Str.equalsIgnoreCase("sidebar") ? 1 : (par0Str.equalsIgnoreCase("belowName") ? 2 : -1)); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ScoreboardSaveData.java b/sp-server/src/main/java/net/minecraft/src/ScoreboardSaveData.java new file mode 100644 index 0000000..caba922 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ScoreboardSaveData.java @@ -0,0 +1,198 @@ +package net.minecraft.src; + +import java.util.Collection; +import java.util.Iterator; +import net.minecraft.server.MinecraftServer; + +public class ScoreboardSaveData extends WorldSavedData { + private Scoreboard field_96507_a; + private NBTTagCompound field_96506_b; + + public ScoreboardSaveData() { + this("scoreboard"); + } + + public ScoreboardSaveData(String par1Str) { + super(par1Str); + } + + public void func_96499_a(Scoreboard par1Scoreboard) { + this.field_96507_a = par1Scoreboard; + + if (this.field_96506_b != null) { + this.readFromNBT(this.field_96506_b); + } + } + + /** + * reads in data from the NBTTagCompound into this MapDataBase + */ + public void readFromNBT(NBTTagCompound par1NBTTagCompound) { + if (this.field_96507_a == null) { + this.field_96506_b = par1NBTTagCompound; + } else { + this.func_96501_b(par1NBTTagCompound.getTagList("Objectives")); + this.func_96500_c(par1NBTTagCompound.getTagList("PlayerScores")); + + if (par1NBTTagCompound.hasKey("DisplaySlots")) { + this.func_96504_c(par1NBTTagCompound.getCompoundTag("DisplaySlots")); + } + + if (par1NBTTagCompound.hasKey("Teams")) { + this.func_96498_a(par1NBTTagCompound.getTagList("Teams")); + } + } + } + + protected void func_96498_a(NBTTagList par1NBTTagList) { + for (int var2 = 0; var2 < par1NBTTagList.tagCount(); ++var2) { + NBTTagCompound var3 = (NBTTagCompound) par1NBTTagList.tagAt(var2); + ScorePlayerTeam var4 = this.field_96507_a.func_96527_f(var3.getString("Name")); + var4.func_96664_a(var3.getString("DisplayName")); + var4.func_96666_b(var3.getString("Prefix")); + var4.func_96662_c(var3.getString("Suffix")); + + if (var3.hasKey("AllowFriendlyFire")) { + var4.func_96660_a(var3.getBoolean("AllowFriendlyFire")); + } + + if (var3.hasKey("SeeFriendlyInvisibles")) { + var4.func_98300_b(var3.getBoolean("SeeFriendlyInvisibles")); + } + + this.func_96502_a(var4, var3.getTagList("Players")); + } + } + + protected void func_96502_a(ScorePlayerTeam par1ScorePlayerTeam, NBTTagList par2NBTTagList) { + for (int var3 = 0; var3 < par2NBTTagList.tagCount(); ++var3) { + this.field_96507_a.func_96521_a(((NBTTagString) par2NBTTagList.tagAt(var3)).data, par1ScorePlayerTeam); + } + } + + protected void func_96504_c(NBTTagCompound par1NBTTagCompound) { + for (int var2 = 0; var2 < 3; ++var2) { + if (par1NBTTagCompound.hasKey("slot_" + var2)) { + String var3 = par1NBTTagCompound.getString("slot_" + var2); + ScoreObjective var4 = this.field_96507_a.getObjective(var3); + this.field_96507_a.func_96530_a(var2, var4); + } + } + } + + protected void func_96501_b(NBTTagList par1NBTTagList) { + for (int var2 = 0; var2 < par1NBTTagList.tagCount(); ++var2) { + NBTTagCompound var3 = (NBTTagCompound) par1NBTTagList.tagAt(var2); + ScoreObjectiveCriteria var4 = (ScoreObjectiveCriteria) ScoreObjectiveCriteria.field_96643_a + .get(var3.getString("CriteriaName")); + ScoreObjective var5 = this.field_96507_a.func_96535_a(var3.getString("Name"), var4); + var5.setDisplayName(var3.getString("DisplayName")); + } + } + + protected void func_96500_c(NBTTagList par1NBTTagList) { + for (int var2 = 0; var2 < par1NBTTagList.tagCount(); ++var2) { + NBTTagCompound var3 = (NBTTagCompound) par1NBTTagList.tagAt(var2); + ScoreObjective var4 = this.field_96507_a.getObjective(var3.getString("Objective")); + Score var5 = this.field_96507_a.func_96529_a(var3.getString("Name"), var4); + var5.func_96647_c(var3.getInteger("Score")); + } + } + + /** + * write data to NBTTagCompound from this MapDataBase, similar to Entities and + * TileEntities + */ + public void writeToNBT(NBTTagCompound par1NBTTagCompound) { + if (this.field_96507_a == null) { + MinecraftServer.getServer().getLogAgent() + .func_98236_b("Tried to save scoreboard without having a scoreboard..."); + } else { + par1NBTTagCompound.setTag("Objectives", this.func_96505_b()); + par1NBTTagCompound.setTag("PlayerScores", this.func_96503_e()); + par1NBTTagCompound.setTag("Teams", this.func_96496_a()); + this.func_96497_d(par1NBTTagCompound); + } + } + + protected NBTTagList func_96496_a() { + NBTTagList var1 = new NBTTagList(); + Collection var2 = this.field_96507_a.func_96525_g(); + Iterator var3 = var2.iterator(); + + while (var3.hasNext()) { + ScorePlayerTeam var4 = (ScorePlayerTeam) var3.next(); + NBTTagCompound var5 = new NBTTagCompound(); + var5.setString("Name", var4.func_96661_b()); + var5.setString("DisplayName", var4.func_96669_c()); + var5.setString("Prefix", var4.func_96668_e()); + var5.setString("Suffix", var4.func_96663_f()); + var5.setBoolean("AllowFriendlyFire", var4.func_96665_g()); + var5.setBoolean("SeeFriendlyInvisibles", var4.func_98297_h()); + NBTTagList var6 = new NBTTagList(); + Iterator var7 = var4.getMembershipCollection().iterator(); + + while (var7.hasNext()) { + String var8 = (String) var7.next(); + var6.appendTag(new NBTTagString("", var8)); + } + + var5.setTag("Players", var6); + var1.appendTag(var5); + } + + return var1; + } + + protected void func_96497_d(NBTTagCompound par1NBTTagCompound) { + NBTTagCompound var2 = new NBTTagCompound(); + boolean var3 = false; + + for (int var4 = 0; var4 < 3; ++var4) { + ScoreObjective var5 = this.field_96507_a.func_96539_a(var4); + + if (var5 != null) { + var2.setString("slot_" + var4, var5.getName()); + var3 = true; + } + } + + if (var3) { + par1NBTTagCompound.setCompoundTag("DisplaySlots", var2); + } + } + + protected NBTTagList func_96505_b() { + NBTTagList var1 = new NBTTagList(); + Collection var2 = this.field_96507_a.getScoreObjectives(); + Iterator var3 = var2.iterator(); + + while (var3.hasNext()) { + ScoreObjective var4 = (ScoreObjective) var3.next(); + NBTTagCompound var5 = new NBTTagCompound(); + var5.setString("Name", var4.getName()); + var5.setString("CriteriaName", var4.getCriteria().func_96636_a()); + var5.setString("DisplayName", var4.getDisplayName()); + var1.appendTag(var5); + } + + return var1; + } + + protected NBTTagList func_96503_e() { + NBTTagList var1 = new NBTTagList(); + Collection var2 = this.field_96507_a.func_96528_e(); + Iterator var3 = var2.iterator(); + + while (var3.hasNext()) { + Score var4 = (Score) var3.next(); + NBTTagCompound var5 = new NBTTagCompound(); + var5.setString("Name", var4.func_96653_e()); + var5.setString("Objective", var4.func_96645_d().getName()); + var5.setInteger("Score", var4.func_96652_c()); + var1.appendTag(var5); + } + + return var1; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ServerBlockEvent.java b/sp-server/src/main/java/net/minecraft/src/ServerBlockEvent.java new file mode 100644 index 0000000..4f7f9b9 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ServerBlockEvent.java @@ -0,0 +1,4 @@ +package net.minecraft.src; + +class ServerBlockEvent { +} diff --git a/sp-server/src/main/java/net/minecraft/src/ServerBlockEventList.java b/sp-server/src/main/java/net/minecraft/src/ServerBlockEventList.java new file mode 100644 index 0000000..55215ce --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ServerBlockEventList.java @@ -0,0 +1,12 @@ +package net.minecraft.src; + +import java.util.ArrayList; + +class ServerBlockEventList extends ArrayList { + private ServerBlockEventList() { + } + + ServerBlockEventList(ServerBlockEvent par1ServerBlockEvent) { + this(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ServerCommand.java b/sp-server/src/main/java/net/minecraft/src/ServerCommand.java new file mode 100644 index 0000000..2bf2776 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ServerCommand.java @@ -0,0 +1,12 @@ +package net.minecraft.src; + +public class ServerCommand { + /** The command string. */ + public final String command; + public final ICommandSender sender; + + public ServerCommand(String par1Str, ICommandSender par2ICommandSender) { + this.command = par1Str; + this.sender = par2ICommandSender; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ServerCommandManager.java b/sp-server/src/main/java/net/minecraft/src/ServerCommandManager.java new file mode 100644 index 0000000..14b4462 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ServerCommandManager.java @@ -0,0 +1,91 @@ +package net.minecraft.src; + +import java.util.Iterator; +import net.minecraft.server.MinecraftServer; + +public class ServerCommandManager extends CommandHandler implements IAdminCommand { + public ServerCommandManager() { + this.registerCommand(new CommandTime()); + this.registerCommand(new CommandGameMode()); + this.registerCommand(new CommandDifficulty()); + this.registerCommand(new CommandDefaultGameMode()); + this.registerCommand(new CommandKill()); + this.registerCommand(new CommandToggleDownfall()); + this.registerCommand(new CommandWeather()); + this.registerCommand(new CommandXP()); + this.registerCommand(new CommandServerTp()); + this.registerCommand(new CommandGive()); + this.registerCommand(new CommandEffect()); + this.registerCommand(new CommandEnchant()); + this.registerCommand(new CommandServerEmote()); + this.registerCommand(new CommandShowSeed()); + this.registerCommand(new CommandHelp()); + this.registerCommand(new CommandDebug()); + this.registerCommand(new CommandServerMessage()); + this.registerCommand(new CommandServerSay()); + this.registerCommand(new CommandSetSpawnpoint()); + this.registerCommand(new CommandGameRule()); + this.registerCommand(new CommandClearInventory()); + this.registerCommand(new ServerCommandTestFor()); + this.registerCommand(new ServerCommandScoreboard()); + + if (MinecraftServer.getServer().isDedicatedServer()) { + this.registerCommand(new CommandServerOp()); + this.registerCommand(new CommandServerDeop()); + this.registerCommand(new CommandServerStop()); + this.registerCommand(new CommandServerSaveAll()); + this.registerCommand(new CommandServerSaveOff()); + this.registerCommand(new CommandServerSaveOn()); + this.registerCommand(new CommandServerBanIp()); + this.registerCommand(new CommandServerPardonIp()); + this.registerCommand(new CommandServerBan()); + this.registerCommand(new CommandServerBanlist()); + this.registerCommand(new CommandServerPardon()); + this.registerCommand(new CommandServerKick()); + this.registerCommand(new CommandServerList()); + this.registerCommand(new CommandServerWhitelist()); + } else { + this.registerCommand(new CommandServerPublishLocal()); + } + + CommandBase.setAdminCommander(this); + } + + /** + * Sends a message to the admins of the server from a given CommandSender with + * the given resource string and given extra srings. If the int par2 is even or + * zero, the original sender is also notified. + */ + public void notifyAdmins(ICommandSender par1ICommandSender, int par2, String par3Str, Object... par4ArrayOfObj) { + boolean var5 = true; + + if (par1ICommandSender instanceof TileEntityCommandBlock && !MinecraftServer.getServer().worldServers[0] + .getGameRules().getGameRuleBooleanValue("commandBlockOutput")) { + var5 = false; + } + + if (var5) { + Iterator var6 = MinecraftServer.getServer().getConfigurationManager().playerEntityList.iterator(); + + while (var6.hasNext()) { + EntityPlayerMP var7 = (EntityPlayerMP) var6.next(); + + if (var7 != par1ICommandSender + && MinecraftServer.getServer().getConfigurationManager().areCommandsAllowed(var7.username)) { + var7.sendChatToPlayer("" + EnumChatFormatting.GRAY + "" + EnumChatFormatting.ITALIC + "[" + + par1ICommandSender.getCommandSenderName() + ": " + + var7.translateString(par3Str, par4ArrayOfObj) + "]"); + } + } + } + + if (par1ICommandSender != MinecraftServer.getServer()) { + MinecraftServer.getServer().getLogAgent().func_98233_a("[" + par1ICommandSender.getCommandSenderName() + + ": " + MinecraftServer.getServer().translateString(par3Str, par4ArrayOfObj) + "]"); + } + + if ((par2 & 1) != 1) { + par1ICommandSender.sendChatToPlayer(par1ICommandSender.translateString(par3Str, par4ArrayOfObj)); + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ServerCommandScoreboard.java b/sp-server/src/main/java/net/minecraft/src/ServerCommandScoreboard.java new file mode 100644 index 0000000..8308a93 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ServerCommandScoreboard.java @@ -0,0 +1,745 @@ +package net.minecraft.src; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import net.minecraft.server.MinecraftServer; + +public class ServerCommandScoreboard extends CommandBase { + public String getCommandName() { + return "scoreboard"; + } + + /** + * Return the required permission level for this command. + */ + public int getRequiredPermissionLevel() { + return 2; + } + + public void processCommand(ICommandSender par1ICommandSender, String[] par2ArrayOfStr) { + if (par2ArrayOfStr.length >= 1) { + if (par2ArrayOfStr[0].equalsIgnoreCase("objectives")) { + if (par2ArrayOfStr.length == 1) { + throw new WrongUsageException("commands.scoreboard.objectives.usage", new Object[0]); + } + + if (par2ArrayOfStr[1].equalsIgnoreCase("list")) { + this.getObjectivesList(par1ICommandSender); + } else if (par2ArrayOfStr[1].equalsIgnoreCase("add")) { + if (par2ArrayOfStr.length < 4) { + throw new WrongUsageException("commands.scoreboard.objectives.add.usage", new Object[0]); + } + + this.addObjective(par1ICommandSender, par2ArrayOfStr, 2); + } else if (par2ArrayOfStr[1].equalsIgnoreCase("remove")) { + if (par2ArrayOfStr.length != 3) { + throw new WrongUsageException("commands.scoreboard.objectives.remove.usage", new Object[0]); + } + + this.removeObjective(par1ICommandSender, par2ArrayOfStr[2]); + } else { + if (!par2ArrayOfStr[1].equalsIgnoreCase("setdisplay")) { + throw new WrongUsageException("commands.scoreboard.objectives.usage", new Object[0]); + } + + if (par2ArrayOfStr.length != 3 && par2ArrayOfStr.length != 4) { + throw new WrongUsageException("commands.scoreboard.objectives.setdisplay.usage", new Object[0]); + } + + this.setObjectivesDisplay(par1ICommandSender, par2ArrayOfStr, 2); + } + + return; + } + + if (par2ArrayOfStr[0].equalsIgnoreCase("players")) { + if (par2ArrayOfStr.length == 1) { + throw new WrongUsageException("commands.scoreboard.players.usage", new Object[0]); + } + + if (par2ArrayOfStr[1].equalsIgnoreCase("list")) { + if (par2ArrayOfStr.length > 3) { + throw new WrongUsageException("commands.scoreboard.players.list.usage", new Object[0]); + } + + this.listPlayers(par1ICommandSender, par2ArrayOfStr, 2); + } else if (par2ArrayOfStr[1].equalsIgnoreCase("add")) { + if (par2ArrayOfStr.length != 5) { + throw new WrongUsageException("commands.scoreboard.players.add.usage", new Object[0]); + } + + this.setPlayerScore(par1ICommandSender, par2ArrayOfStr, 2); + } else if (par2ArrayOfStr[1].equalsIgnoreCase("remove")) { + if (par2ArrayOfStr.length != 5) { + throw new WrongUsageException("commands.scoreboard.players.remove.usage", new Object[0]); + } + + this.setPlayerScore(par1ICommandSender, par2ArrayOfStr, 2); + } else if (par2ArrayOfStr[1].equalsIgnoreCase("set")) { + if (par2ArrayOfStr.length != 5) { + throw new WrongUsageException("commands.scoreboard.players.set.usage", new Object[0]); + } + + this.setPlayerScore(par1ICommandSender, par2ArrayOfStr, 2); + } else { + if (!par2ArrayOfStr[1].equalsIgnoreCase("reset")) { + throw new WrongUsageException("commands.scoreboard.players.usage", new Object[0]); + } + + if (par2ArrayOfStr.length != 3) { + throw new WrongUsageException("commands.scoreboard.players.reset.usage", new Object[0]); + } + + this.resetPlayerScore(par1ICommandSender, par2ArrayOfStr, 2); + } + + return; + } + + if (par2ArrayOfStr[0].equalsIgnoreCase("teams")) { + if (par2ArrayOfStr.length == 1) { + throw new WrongUsageException("commands.scoreboard.teams.usage", new Object[0]); + } + + if (par2ArrayOfStr[1].equalsIgnoreCase("list")) { + if (par2ArrayOfStr.length > 3) { + throw new WrongUsageException("commands.scoreboard.teams.list.usage", new Object[0]); + } + + this.getTeamList(par1ICommandSender, par2ArrayOfStr, 2); + } else if (par2ArrayOfStr[1].equalsIgnoreCase("add")) { + if (par2ArrayOfStr.length < 3) { + throw new WrongUsageException("commands.scoreboard.teams.add.usage", new Object[0]); + } + + this.addTeam(par1ICommandSender, par2ArrayOfStr, 2); + } else if (par2ArrayOfStr[1].equalsIgnoreCase("remove")) { + if (par2ArrayOfStr.length != 3) { + throw new WrongUsageException("commands.scoreboard.teams.remove.usage", new Object[0]); + } + + this.removeTeam(par1ICommandSender, par2ArrayOfStr, 2); + } else if (par2ArrayOfStr[1].equalsIgnoreCase("empty")) { + if (par2ArrayOfStr.length != 3) { + throw new WrongUsageException("commands.scoreboard.teams.empty.usage", new Object[0]); + } + + this.emptyTeam(par1ICommandSender, par2ArrayOfStr, 2); + } else if (par2ArrayOfStr[1].equalsIgnoreCase("join")) { + if (par2ArrayOfStr.length < 4 + && (par2ArrayOfStr.length != 3 || !(par1ICommandSender instanceof EntityPlayer))) { + throw new WrongUsageException("commands.scoreboard.teams.join.usage", new Object[0]); + } + + this.joinTeam(par1ICommandSender, par2ArrayOfStr, 2); + } else if (par2ArrayOfStr[1].equalsIgnoreCase("leave")) { + if (par2ArrayOfStr.length < 3 && !(par1ICommandSender instanceof EntityPlayer)) { + throw new WrongUsageException("commands.scoreboard.teams.leave.usage", new Object[0]); + } + + this.leaveTeam(par1ICommandSender, par2ArrayOfStr, 2); + } else { + if (!par2ArrayOfStr[1].equalsIgnoreCase("option")) { + throw new WrongUsageException("commands.scoreboard.teams.usage", new Object[0]); + } + + if (par2ArrayOfStr.length != 4 && par2ArrayOfStr.length != 5) { + throw new WrongUsageException("commands.scoreboard.teams.option.usage", new Object[0]); + } + + this.setTeamOption(par1ICommandSender, par2ArrayOfStr, 2); + } + + return; + } + } + + throw new WrongUsageException("commands.scoreboard.usage", new Object[0]); + } + + protected Scoreboard getScoreboardFromWorldServer() { + return MinecraftServer.getServer().worldServerForDimension(0).getScoreboard(); + } + + /** + * User-safe version of Scoreboard.getObjective, does checks against the + * objective not being found and whether it's read-only or not. If true, the + * second parameter makes the function throw an exception if the objective is + * read- only. + */ + protected ScoreObjective getScoreObjective(String par1Str, boolean par2) { + Scoreboard var3 = this.getScoreboardFromWorldServer(); + ScoreObjective var4 = var3.getObjective(par1Str); + + if (var4 == null) { + throw new CommandException("commands.scoreboard.objectiveNotFound", new Object[] { par1Str }); + } else if (par2 && var4.getCriteria().isReadOnly()) { + throw new CommandException("commands.scoreboard.objectiveReadOnly", new Object[] { par1Str }); + } else { + return var4; + } + } + + /** + * Returns the ScorePlayerTeam for the given team name. + */ + protected ScorePlayerTeam getTeam(String par1Str) { + Scoreboard var2 = this.getScoreboardFromWorldServer(); + ScorePlayerTeam var3 = var2.func_96508_e(par1Str); + + if (var3 == null) { + throw new CommandException("commands.scoreboard.teamNotFound", new Object[] { par1Str }); + } else { + return var3; + } + } + + /** + * Handler for the 'scoreboard objectives add' command. + */ + protected void addObjective(ICommandSender par1ICommandSender, String[] par2ArrayOfStr, int par3) { + String var4 = par2ArrayOfStr[par3++]; + String var5 = par2ArrayOfStr[par3++]; + Scoreboard var6 = this.getScoreboardFromWorldServer(); + ScoreObjectiveCriteria var7 = (ScoreObjectiveCriteria) ScoreObjectiveCriteria.field_96643_a.get(var5); + + if (var7 == null) { + String[] var10 = (String[]) ScoreObjectiveCriteria.field_96643_a.keySet().toArray(new String[0]); + throw new WrongUsageException("commands.scoreboard.objectives.add.wrongType", + new Object[] { joinNiceString(var10) }); + } else if (var6.getObjective(var4) != null) { + throw new CommandException("commands.scoreboard.objectives.add.alreadyExists", new Object[] { var4 }); + } else if (var4.length() > 16) { + throw new SyntaxErrorException("commands.scoreboard.objectives.add.tooLong", + new Object[] { var4, Integer.valueOf(16) }); + } else { + ScoreObjective var8 = var6.func_96535_a(var4, var7); + + if (par2ArrayOfStr.length > par3) { + String var9 = func_82360_a(par1ICommandSender, par2ArrayOfStr, par3); + + if (var9.length() > 32) { + throw new SyntaxErrorException("commands.scoreboard.objectives.add.displayTooLong", + new Object[] { var9, Integer.valueOf(32) }); + } + + if (var9.length() > 0) { + var8.setDisplayName(var9); + } + } + + notifyAdmins(par1ICommandSender, "commands.scoreboard.objectives.add.success", new Object[] { var4 }); + } + } + + /** + * Handler for the 'scoreboard teams add' command. + */ + protected void addTeam(ICommandSender par1ICommandSender, String[] par2ArrayOfStr, int par3) { + String var4 = par2ArrayOfStr[par3++]; + Scoreboard var5 = this.getScoreboardFromWorldServer(); + + if (var5.func_96508_e(var4) != null) { + throw new CommandException("commands.scoreboard.teams.add.alreadyExists", new Object[] { var4 }); + } else if (var4.length() > 16) { + throw new SyntaxErrorException("commands.scoreboard.teams.add.tooLong", + new Object[] { var4, Integer.valueOf(16) }); + } else { + ScorePlayerTeam var6 = var5.func_96527_f(var4); + + if (par2ArrayOfStr.length > par3) { + String var7 = func_82360_a(par1ICommandSender, par2ArrayOfStr, par3); + + if (var7.length() > 32) { + throw new SyntaxErrorException("commands.scoreboard.teams.add.displayTooLong", + new Object[] { var7, Integer.valueOf(32) }); + } + + if (var7.length() > 0) { + var6.func_96664_a(var7); + } + } + + notifyAdmins(par1ICommandSender, "commands.scoreboard.teams.add.success", new Object[] { var4 }); + } + } + + /** + * Handler for the 'scoreboard teams option' command. + */ + protected void setTeamOption(ICommandSender par1ICommandSender, String[] par2ArrayOfStr, int par3) { + ScorePlayerTeam var4 = this.getTeam(par2ArrayOfStr[par3++]); + String var5 = par2ArrayOfStr[par3++].toLowerCase(); + + if (!var5.equalsIgnoreCase("color") && !var5.equalsIgnoreCase("friendlyfire") + && !var5.equalsIgnoreCase("seeFriendlyInvisibles")) { + throw new WrongUsageException("commands.scoreboard.teams.option.usage", new Object[0]); + } else if (par2ArrayOfStr.length == 4) { + if (var5.equalsIgnoreCase("color")) { + throw new WrongUsageException("commands.scoreboard.teams.option.noValue", + new Object[] { var5, func_96333_a(EnumChatFormatting.func_96296_a(true, false)) }); + } else if (!var5.equalsIgnoreCase("friendlyfire") && !var5.equalsIgnoreCase("seeFriendlyInvisibles")) { + throw new WrongUsageException("commands.scoreboard.teams.option.usage", new Object[0]); + } else { + throw new WrongUsageException("commands.scoreboard.teams.option.noValue", + new Object[] { var5, func_96333_a(Arrays.asList(new String[] { "true", "false" })) }); + } + } else { + String var6 = par2ArrayOfStr[par3++]; + + if (var5.equalsIgnoreCase("color")) { + EnumChatFormatting var7 = EnumChatFormatting.func_96300_b(var6); + + if (var6 == null) { + throw new WrongUsageException("commands.scoreboard.teams.option.noValue", + new Object[] { var5, func_96333_a(EnumChatFormatting.func_96296_a(true, false)) }); + } + + var4.func_96666_b(var7.toString()); + var4.func_96662_c(EnumChatFormatting.RESET.toString()); + } else if (var5.equalsIgnoreCase("friendlyfire")) { + if (!var6.equalsIgnoreCase("true") && !var6.equalsIgnoreCase("false")) { + throw new WrongUsageException("commands.scoreboard.teams.option.noValue", + new Object[] { var5, func_96333_a(Arrays.asList(new String[] { "true", "false" })) }); + } + + var4.func_96660_a(var6.equalsIgnoreCase("true")); + } else if (var5.equalsIgnoreCase("seeFriendlyInvisibles")) { + if (!var6.equalsIgnoreCase("true") && !var6.equalsIgnoreCase("false")) { + throw new WrongUsageException("commands.scoreboard.teams.option.noValue", + new Object[] { var5, func_96333_a(Arrays.asList(new String[] { "true", "false" })) }); + } + + var4.func_98300_b(var6.equalsIgnoreCase("true")); + } + + notifyAdmins(par1ICommandSender, "commands.scoreboard.teams.option.success", + new Object[] { var5, var4.func_96661_b(), var6 }); + } + } + + /** + * Handler for the 'scoreboard teams remove' command. + */ + protected void removeTeam(ICommandSender par1ICommandSender, String[] par2ArrayOfStr, int par3) { + Scoreboard var4 = this.getScoreboardFromWorldServer(); + ScorePlayerTeam var5 = this.getTeam(par2ArrayOfStr[par3++]); + var4.func_96511_d(var5); + notifyAdmins(par1ICommandSender, "commands.scoreboard.teams.remove.success", + new Object[] { var5.func_96661_b() }); + } + + /** + * Handler for the 'scoreboard teams list' command. + */ + protected void getTeamList(ICommandSender par1ICommandSender, String[] par2ArrayOfStr, int par3) { + Scoreboard var4 = this.getScoreboardFromWorldServer(); + + if (par2ArrayOfStr.length > par3) { + ScorePlayerTeam var5 = this.getTeam(par2ArrayOfStr[par3++]); + Collection var6 = var5.getMembershipCollection(); + + if (var6.size() <= 0) { + throw new CommandException("commands.scoreboard.teams.list.player.empty", + new Object[] { var5.func_96661_b() }); + } + + par1ICommandSender.sendChatToPlayer(EnumChatFormatting.DARK_GREEN + + par1ICommandSender.translateString("commands.scoreboard.teams.list.player.count", + new Object[] { Integer.valueOf(var6.size()), var5.func_96661_b() })); + par1ICommandSender.sendChatToPlayer(joinNiceString(var6.toArray())); + } else { + Collection var8 = var4.func_96525_g(); + + if (var8.size() <= 0) { + throw new CommandException("commands.scoreboard.teams.list.empty", new Object[0]); + } + + par1ICommandSender.sendChatToPlayer(EnumChatFormatting.DARK_GREEN + par1ICommandSender.translateString( + "commands.scoreboard.teams.list.count", new Object[] { Integer.valueOf(var8.size()) })); + Iterator var9 = var8.iterator(); + + while (var9.hasNext()) { + ScorePlayerTeam var7 = (ScorePlayerTeam) var9.next(); + par1ICommandSender.sendChatToPlayer(par1ICommandSender + .translateString("commands.scoreboard.teams.list.entry", new Object[] { var7.func_96661_b(), + var7.func_96669_c(), Integer.valueOf(var7.getMembershipCollection().size()) })); + } + } + } + + /** + * Handler for the 'scoreboard teams join' command. + */ + protected void joinTeam(ICommandSender par1ICommandSender, String[] par2ArrayOfStr, int par3) { + Scoreboard var4 = this.getScoreboardFromWorldServer(); + ScorePlayerTeam var5 = var4.func_96508_e(par2ArrayOfStr[par3++]); + HashSet var6 = new HashSet(); + String var7; + + if (par1ICommandSender instanceof EntityPlayer && par3 == par2ArrayOfStr.length) { + var7 = getCommandSenderAsPlayer(par1ICommandSender).getEntityName(); + var4.func_96521_a(var7, var5); + var6.add(var7); + } else { + while (par3 < par2ArrayOfStr.length) { + var7 = func_96332_d(par1ICommandSender, par2ArrayOfStr[par3++]); + var4.func_96521_a(var7, var5); + var6.add(var7); + } + } + + if (!var6.isEmpty()) { + notifyAdmins(par1ICommandSender, "commands.scoreboard.teams.join.success", new Object[] { + Integer.valueOf(var6.size()), var5.func_96661_b(), joinNiceString(var6.toArray(new String[0])) }); + } + } + + /** + * Handler for the 'scoreboard teams leave' command. + */ + protected void leaveTeam(ICommandSender par1ICommandSender, String[] par2ArrayOfStr, int par3) { + Scoreboard var4 = this.getScoreboardFromWorldServer(); + HashSet var5 = new HashSet(); + HashSet var6 = new HashSet(); + String var7; + + if (par1ICommandSender instanceof EntityPlayer && par3 == par2ArrayOfStr.length) { + var7 = getCommandSenderAsPlayer(par1ICommandSender).getEntityName(); + + if (var4.func_96524_g(var7)) { + var5.add(var7); + } else { + var6.add(var7); + } + } else { + while (par3 < par2ArrayOfStr.length) { + var7 = func_96332_d(par1ICommandSender, par2ArrayOfStr[par3++]); + + if (var4.func_96524_g(var7)) { + var5.add(var7); + } else { + var6.add(var7); + } + } + } + + if (!var5.isEmpty()) { + notifyAdmins(par1ICommandSender, "commands.scoreboard.teams.leave.success", + new Object[] { Integer.valueOf(var5.size()), joinNiceString(var5.toArray(new String[0])) }); + } + + if (!var6.isEmpty()) { + throw new CommandException("commands.scoreboard.teams.leave.failure", + new Object[] { Integer.valueOf(var6.size()), joinNiceString(var6.toArray(new String[0])) }); + } + } + + /** + * Handler for the 'scoreboard teams empty' command. + */ + protected void emptyTeam(ICommandSender par1ICommandSender, String[] par2ArrayOfStr, int par3) { + Scoreboard var4 = this.getScoreboardFromWorldServer(); + ScorePlayerTeam var5 = this.getTeam(par2ArrayOfStr[par3++]); + ArrayList var6 = new ArrayList(var5.getMembershipCollection()); + + if (var6.isEmpty()) { + throw new CommandException("commands.scoreboard.teams.empty.alreadyEmpty", + new Object[] { var5.func_96661_b() }); + } else { + Iterator var7 = var6.iterator(); + + while (var7.hasNext()) { + String var8 = (String) var7.next(); + var4.removePlayerFromTeam(var8, var5); + } + + notifyAdmins(par1ICommandSender, "commands.scoreboard.teams.empty.success", + new Object[] { Integer.valueOf(var6.size()), var5.func_96661_b() }); + } + } + + /** + * Handler for the 'scoreboard objectives remove' command. + */ + protected void removeObjective(ICommandSender par1ICommandSender, String par2Str) { + Scoreboard var3 = this.getScoreboardFromWorldServer(); + ScoreObjective var4 = this.getScoreObjective(par2Str, false); + var3.func_96519_k(var4); + notifyAdmins(par1ICommandSender, "commands.scoreboard.objectives.remove.success", new Object[] { par2Str }); + } + + /** + * Handler for the 'scoreboard objectives list' command. + */ + protected void getObjectivesList(ICommandSender par1ICommandSender) { + Scoreboard var2 = this.getScoreboardFromWorldServer(); + Collection var3 = var2.getScoreObjectives(); + + if (var3.size() <= 0) { + throw new CommandException("commands.scoreboard.objectives.list.empty", new Object[0]); + } else { + par1ICommandSender.sendChatToPlayer(EnumChatFormatting.DARK_GREEN + par1ICommandSender.translateString( + "commands.scoreboard.objectives.list.count", new Object[] { Integer.valueOf(var3.size()) })); + Iterator var4 = var3.iterator(); + + while (var4.hasNext()) { + ScoreObjective var5 = (ScoreObjective) var4.next(); + par1ICommandSender.sendChatToPlayer(par1ICommandSender.translateString( + "commands.scoreboard.objectives.list.entry", + new Object[] { var5.getName(), var5.getDisplayName(), var5.getCriteria().func_96636_a() })); + } + } + } + + /** + * Handler for the 'scoreboard objectives setdisplay' command. + */ + protected void setObjectivesDisplay(ICommandSender par1ICommandSender, String[] par2ArrayOfStr, int par3) { + Scoreboard var4 = this.getScoreboardFromWorldServer(); + String var5 = par2ArrayOfStr[par3++]; + int var6 = Scoreboard.getObjectiveDisplaySlotNumber(var5); + ScoreObjective var7 = null; + + if (par2ArrayOfStr.length == 4) { + var7 = this.getScoreObjective(par2ArrayOfStr[par3++], false); + } + + if (var6 < 0) { + throw new CommandException("commands.scoreboard.objectives.setdisplay.invalidSlot", new Object[] { var5 }); + } else { + var4.func_96530_a(var6, var7); + + if (var7 != null) { + notifyAdmins(par1ICommandSender, "commands.scoreboard.objectives.setdisplay.successSet", + new Object[] { Scoreboard.getObjectiveDisplaySlot(var6), var7.getName() }); + } else { + notifyAdmins(par1ICommandSender, "commands.scoreboard.objectives.setdisplay.successCleared", + new Object[] { Scoreboard.getObjectiveDisplaySlot(var6) }); + } + } + } + + /** + * Handler for the 'scoreboard players list' command. + */ + protected void listPlayers(ICommandSender par1ICommandSender, String[] par2ArrayOfStr, int par3) { + Scoreboard var4 = this.getScoreboardFromWorldServer(); + + if (par2ArrayOfStr.length > par3) { + String var5 = func_96332_d(par1ICommandSender, par2ArrayOfStr[par3++]); + Map var6 = var4.func_96510_d(var5); + + if (var6.size() <= 0) { + throw new CommandException("commands.scoreboard.players.list.player.empty", new Object[] { var5 }); + } + + par1ICommandSender.sendChatToPlayer(EnumChatFormatting.DARK_GREEN + + par1ICommandSender.translateString("commands.scoreboard.players.list.player.count", + new Object[] { Integer.valueOf(var6.size()), var5 })); + Iterator var7 = var6.values().iterator(); + + while (var7.hasNext()) { + Score var8 = (Score) var7.next(); + par1ICommandSender.sendChatToPlayer( + par1ICommandSender.translateString("commands.scoreboard.players.list.player.entry", + new Object[] { Integer.valueOf(var8.func_96652_c()), + var8.func_96645_d().getDisplayName(), var8.func_96645_d().getName() })); + } + } else { + Collection var9 = var4.getObjectiveNames(); + + if (var9.size() <= 0) { + throw new CommandException("commands.scoreboard.players.list.empty", new Object[0]); + } + + par1ICommandSender.sendChatToPlayer(EnumChatFormatting.DARK_GREEN + par1ICommandSender.translateString( + "commands.scoreboard.players.list.count", new Object[] { Integer.valueOf(var9.size()) })); + par1ICommandSender.sendChatToPlayer(joinNiceString(var9.toArray())); + } + } + + /** + * Handler for the 'scoreboard players [add|remove|set]' commands. + */ + protected void setPlayerScore(ICommandSender par1ICommandSender, String[] par2ArrayOfStr, int par3) { + String var4 = par2ArrayOfStr[par3 - 1]; + String var5 = func_96332_d(par1ICommandSender, par2ArrayOfStr[par3++]); + ScoreObjective var6 = this.getScoreObjective(par2ArrayOfStr[par3++], true); + int var7 = var4.equalsIgnoreCase("set") ? parseInt(par1ICommandSender, par2ArrayOfStr[par3++]) + : parseIntWithMin(par1ICommandSender, par2ArrayOfStr[par3++], 1); + Scoreboard var8 = this.getScoreboardFromWorldServer(); + Score var9 = var8.func_96529_a(var5, var6); + + if (var4.equalsIgnoreCase("set")) { + var9.func_96647_c(var7); + } else if (var4.equalsIgnoreCase("add")) { + var9.func_96649_a(var7); + } else { + var9.func_96646_b(var7); + } + + notifyAdmins(par1ICommandSender, "commands.scoreboard.players.set.success", + new Object[] { var6.getName(), var5, Integer.valueOf(var9.func_96652_c()) }); + } + + /** + * Handler for the 'scoreboard players reset' command. + */ + protected void resetPlayerScore(ICommandSender par1ICommandSender, String[] par2ArrayOfStr, int par3) { + Scoreboard var4 = this.getScoreboardFromWorldServer(); + String var5 = func_96332_d(par1ICommandSender, par2ArrayOfStr[par3++]); + var4.func_96515_c(var5); + notifyAdmins(par1ICommandSender, "commands.scoreboard.players.reset.success", new Object[] { var5 }); + } + + /** + * Adds the strings available in this command to the given list of tab + * completion options. + */ + public List addTabCompletionOptions(ICommandSender par1ICommandSender, String[] par2ArrayOfStr) { + if (par2ArrayOfStr.length == 1) { + return getListOfStringsMatchingLastWord(par2ArrayOfStr, new String[] { "objectives", "players", "teams" }); + } else { + if (par2ArrayOfStr[0].equalsIgnoreCase("objectives")) { + if (par2ArrayOfStr.length == 2) { + return getListOfStringsMatchingLastWord(par2ArrayOfStr, + new String[] { "list", "add", "remove", "setdisplay" }); + } + + if (par2ArrayOfStr[1].equalsIgnoreCase("add")) { + if (par2ArrayOfStr.length == 4) { + return getListOfStringsFromIterableMatchingLastWord(par2ArrayOfStr, + ScoreObjectiveCriteria.field_96643_a.keySet()); + } + } else if (par2ArrayOfStr[1].equalsIgnoreCase("remove")) { + if (par2ArrayOfStr.length == 3) { + return getListOfStringsFromIterableMatchingLastWord(par2ArrayOfStr, + this.getScoreObjectivesList(false)); + } + } else if (par2ArrayOfStr[1].equalsIgnoreCase("setdisplay")) { + if (par2ArrayOfStr.length == 3) { + return getListOfStringsMatchingLastWord(par2ArrayOfStr, + new String[] { "list", "sidebar", "belowName" }); + } + + if (par2ArrayOfStr.length == 4) { + return getListOfStringsFromIterableMatchingLastWord(par2ArrayOfStr, + this.getScoreObjectivesList(false)); + } + } + } else if (par2ArrayOfStr[0].equalsIgnoreCase("players")) { + if (par2ArrayOfStr.length == 2) { + return getListOfStringsMatchingLastWord(par2ArrayOfStr, + new String[] { "set", "add", "remove", "reset", "list" }); + } + + if (!par2ArrayOfStr[1].equalsIgnoreCase("set") && !par2ArrayOfStr[1].equalsIgnoreCase("add") + && !par2ArrayOfStr[1].equalsIgnoreCase("remove")) { + if ((par2ArrayOfStr[1].equalsIgnoreCase("reset") || par2ArrayOfStr[1].equalsIgnoreCase("list")) + && par2ArrayOfStr.length == 3) { + return getListOfStringsFromIterableMatchingLastWord(par2ArrayOfStr, + this.getScoreboardFromWorldServer().getObjectiveNames()); + } + } else { + if (par2ArrayOfStr.length == 3) { + return getListOfStringsMatchingLastWord(par2ArrayOfStr, + MinecraftServer.getServer().getAllUsernames()); + } + + if (par2ArrayOfStr.length == 4) { + return getListOfStringsFromIterableMatchingLastWord(par2ArrayOfStr, + this.getScoreObjectivesList(true)); + } + } + } else if (par2ArrayOfStr[0].equalsIgnoreCase("teams")) { + if (par2ArrayOfStr.length == 2) { + return getListOfStringsMatchingLastWord(par2ArrayOfStr, + new String[] { "add", "remove", "join", "leave", "empty", "list", "option" }); + } + + if (par2ArrayOfStr[1].equalsIgnoreCase("join")) { + if (par2ArrayOfStr.length == 3) { + return getListOfStringsFromIterableMatchingLastWord(par2ArrayOfStr, + this.getScoreboardFromWorldServer().func_96531_f()); + } + + if (par2ArrayOfStr.length >= 4) { + return getListOfStringsMatchingLastWord(par2ArrayOfStr, + MinecraftServer.getServer().getAllUsernames()); + } + } else { + if (par2ArrayOfStr[1].equalsIgnoreCase("leave")) { + return getListOfStringsMatchingLastWord(par2ArrayOfStr, + MinecraftServer.getServer().getAllUsernames()); + } + + if (!par2ArrayOfStr[1].equalsIgnoreCase("empty") && !par2ArrayOfStr[1].equalsIgnoreCase("list") + && !par2ArrayOfStr[1].equalsIgnoreCase("remove")) { + if (par2ArrayOfStr[1].equalsIgnoreCase("option")) { + if (par2ArrayOfStr.length == 3) { + return getListOfStringsFromIterableMatchingLastWord(par2ArrayOfStr, + this.getScoreboardFromWorldServer().func_96531_f()); + } + + if (par2ArrayOfStr.length == 4) { + return getListOfStringsMatchingLastWord(par2ArrayOfStr, + new String[] { "color", "friendlyfire", "seeFriendlyInvisibles" }); + } + + if (par2ArrayOfStr.length == 5) { + if (par2ArrayOfStr[3].equalsIgnoreCase("color")) { + return getListOfStringsFromIterableMatchingLastWord(par2ArrayOfStr, + EnumChatFormatting.func_96296_a(true, false)); + } + + if (par2ArrayOfStr[3].equalsIgnoreCase("friendlyfire") + || par2ArrayOfStr[3].equalsIgnoreCase("seeFriendlyInvisibles")) { + return getListOfStringsMatchingLastWord(par2ArrayOfStr, + new String[] { "true", "false" }); + } + } + } + } else if (par2ArrayOfStr.length == 3) { + return getListOfStringsFromIterableMatchingLastWord(par2ArrayOfStr, + this.getScoreboardFromWorldServer().func_96531_f()); + } + } + } + + return null; + } + } + + /** + * If the parameter is true, does not return read-only entries. + */ + protected List getScoreObjectivesList(boolean par1) { + Collection var2 = this.getScoreboardFromWorldServer().getScoreObjectives(); + ArrayList var3 = new ArrayList(); + Iterator var4 = var2.iterator(); + + while (var4.hasNext()) { + ScoreObjective var5 = (ScoreObjective) var4.next(); + + if (!par1 || !var5.getCriteria().isReadOnly()) { + var3.add(var5.getName()); + } + } + + return var3; + } + + /** + * Return whether the specified command parameter index is a username parameter. + */ + public boolean isUsernameIndex(String[] par1ArrayOfStr, int par2) { + return par1ArrayOfStr[0].equalsIgnoreCase("players") ? par2 == 2 + : (!par1ArrayOfStr[0].equalsIgnoreCase("teams") ? false : par2 == 2 || par2 == 3); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ServerCommandTestFor.java b/sp-server/src/main/java/net/minecraft/src/ServerCommandTestFor.java new file mode 100644 index 0000000..330a8cf --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ServerCommandTestFor.java @@ -0,0 +1,31 @@ +package net.minecraft.src; + +public class ServerCommandTestFor extends CommandBase { + public String getCommandName() { + return "testfor"; + } + + /** + * Return the required permission level for this command. + */ + public int getRequiredPermissionLevel() { + return 2; + } + + public void processCommand(ICommandSender par1ICommandSender, String[] par2ArrayOfStr) { + if (par2ArrayOfStr.length != 1) { + throw new WrongUsageException("commands.testfor.usage", new Object[0]); + } else if (!(par1ICommandSender instanceof TileEntityCommandBlock)) { + throw new CommandException("commands.testfor.failed", new Object[0]); + } else { + func_82359_c(par1ICommandSender, par2ArrayOfStr[0]); + } + } + + /** + * Return whether the specified command parameter index is a username parameter. + */ + public boolean isUsernameIndex(String[] par1ArrayOfStr, int par2) { + return par2 == 0; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ServerConfigurationManager.java b/sp-server/src/main/java/net/minecraft/src/ServerConfigurationManager.java new file mode 100644 index 0000000..abda581 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ServerConfigurationManager.java @@ -0,0 +1,904 @@ +package net.minecraft.src; + +import java.io.File; +import java.net.SocketAddress; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.Map.Entry; +import net.minecraft.server.MinecraftServer; + +public abstract class ServerConfigurationManager { + private static final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd \'at\' HH:mm:ss z"); + + /** Reference to the MinecraftServer object. */ + private final MinecraftServer mcServer; + + /** A list of player entities that exist on this server. */ + public final List playerEntityList = new ArrayList(); + private final BanList bannedPlayers = new BanList(new File("banned-players.txt")); + private final BanList bannedIPs = new BanList(new File("banned-ips.txt")); + + /** A set containing the OPs. */ + private Set ops = new HashSet(); + + /** The Set of all whitelisted players. */ + private Set whiteListedPlayers = new HashSet(); + + /** Reference to the PlayerNBTManager object. */ + private IPlayerFileData playerNBTManagerObj; + + /** + * Server setting to only allow OPs and whitelisted players to join the server. + */ + private boolean whiteListEnforced; + + /** The maximum number of players that can be connected at a time. */ + protected int maxPlayers; + protected int viewDistance; + private EnumGameType gameType; + + /** True if all players are allowed to use commands (cheats). */ + private boolean commandsAllowedForAll; + + /** + * index into playerEntities of player to ping, updated every tick; currently + * hardcoded to max at 200 players + */ + private int playerPingIndex = 0; + + public ServerConfigurationManager(MinecraftServer par1MinecraftServer) { + this.mcServer = par1MinecraftServer; + this.bannedPlayers.setListActive(false); + this.bannedIPs.setListActive(false); + this.maxPlayers = 8; + } + + public void initializeConnectionToPlayer(INetworkManager par1INetworkManager, EntityPlayerMP par2EntityPlayerMP) { + NBTTagCompound var3 = this.readPlayerDataFromFile(par2EntityPlayerMP); + par2EntityPlayerMP.setWorld(this.mcServer.worldServerForDimension(par2EntityPlayerMP.dimension)); + par2EntityPlayerMP.theItemInWorldManager.setWorld((WorldServer) par2EntityPlayerMP.worldObj); + String var4 = "local"; + + if (par1INetworkManager.getRemoteAddress() != null) { + var4 = par1INetworkManager.getRemoteAddress().toString(); + } + + this.mcServer.getLogAgent() + .func_98233_a(par2EntityPlayerMP.username + "[" + var4 + "] logged in with entity id " + + par2EntityPlayerMP.entityId + " at (" + par2EntityPlayerMP.posX + ", " + + par2EntityPlayerMP.posY + ", " + par2EntityPlayerMP.posZ + ")"); + WorldServer var5 = this.mcServer.worldServerForDimension(par2EntityPlayerMP.dimension); + ChunkCoordinates var6 = var5.getSpawnPoint(); + this.func_72381_a(par2EntityPlayerMP, (EntityPlayerMP) null, var5); + NetServerHandler var7 = new NetServerHandler(this.mcServer, par1INetworkManager, par2EntityPlayerMP); + var7.sendPacket(new Packet1Login(par2EntityPlayerMP.entityId, var5.getWorldInfo().getTerrainType(), + par2EntityPlayerMP.theItemInWorldManager.getGameType(), var5.getWorldInfo().isHardcoreModeEnabled(), + var5.provider.dimensionId, var5.difficultySetting, var5.getHeight(), this.getMaxPlayers())); + var7.sendPacket(new Packet6SpawnPosition(var6.posX, var6.posY, var6.posZ)); + var7.sendPacket(new Packet202PlayerAbilities(par2EntityPlayerMP.capabilities)); + var7.sendPacket(new Packet16BlockItemSwitch(par2EntityPlayerMP.inventory.currentItem)); + this.func_96456_a((ServerScoreboard) var5.getScoreboard(), par2EntityPlayerMP); + this.updateTimeAndWeatherForPlayer(par2EntityPlayerMP, var5); + this.sendPacketToAllPlayers(new Packet3Chat(EnumChatFormatting.YELLOW + + par2EntityPlayerMP.getTranslatedEntityName() + EnumChatFormatting.YELLOW + " joined the game.")); + this.playerLoggedIn(par2EntityPlayerMP); + var7.setPlayerLocation(par2EntityPlayerMP.posX, par2EntityPlayerMP.posY, par2EntityPlayerMP.posZ, + par2EntityPlayerMP.rotationYaw, par2EntityPlayerMP.rotationPitch); + this.mcServer.getNetworkThread().addPlayer(var7); + var7.sendPacket(new Packet4UpdateTime(var5.getTotalWorldTime(), var5.getWorldTime())); + + if (this.mcServer.getTexturePack().length() > 0) { + par2EntityPlayerMP.requestTexturePackLoad(this.mcServer.getTexturePack(), this.mcServer.textureSize()); + } + + Iterator var8 = par2EntityPlayerMP.getActivePotionEffects().iterator(); + + while (var8.hasNext()) { + PotionEffect var9 = (PotionEffect) var8.next(); + var7.sendPacket(new Packet41EntityEffect(par2EntityPlayerMP.entityId, var9)); + } + + par2EntityPlayerMP.addSelfToInternalCraftingInventory(); + + if (var3 != null && var3.hasKey("Riding")) { + Entity var10 = EntityList.createEntityFromNBT(var3.getCompoundTag("Riding"), var5); + + if (var10 != null) { + var10.field_98038_p = true; + var5.spawnEntityInWorld(var10); + par2EntityPlayerMP.mountEntity(var10); + var10.field_98038_p = false; + } + } + } + + protected void func_96456_a(ServerScoreboard par1ServerScoreboard, EntityPlayerMP par2EntityPlayerMP) { + HashSet var3 = new HashSet(); + Iterator var4 = par1ServerScoreboard.func_96525_g().iterator(); + + while (var4.hasNext()) { + ScorePlayerTeam var5 = (ScorePlayerTeam) var4.next(); + par2EntityPlayerMP.playerNetServerHandler.sendPacket(new Packet209SetPlayerTeam(var5, 0)); + } + + for (int var9 = 0; var9 < 3; ++var9) { + ScoreObjective var10 = par1ServerScoreboard.func_96539_a(var9); + + if (var10 != null && !var3.contains(var10)) { + List var6 = par1ServerScoreboard.func_96550_d(var10); + Iterator var7 = var6.iterator(); + + while (var7.hasNext()) { + Packet var8 = (Packet) var7.next(); + par2EntityPlayerMP.playerNetServerHandler.sendPacket(var8); + } + + var3.add(var10); + } + } + } + + /** + * Sets the NBT manager to the one for the WorldServer given. + */ + public void setPlayerManager(WorldServer[] par1ArrayOfWorldServer) { + this.playerNBTManagerObj = par1ArrayOfWorldServer[0].getSaveHandler().getPlayerNBTManager(); + } + + public void func_72375_a(EntityPlayerMP par1EntityPlayerMP, WorldServer par2WorldServer) { + WorldServer var3 = par1EntityPlayerMP.getServerForPlayer(); + + if (par2WorldServer != null) { + par2WorldServer.getPlayerManager().removePlayer(par1EntityPlayerMP); + } + + var3.getPlayerManager().addPlayer(par1EntityPlayerMP); + var3.theChunkProviderServer.loadChunk((int) par1EntityPlayerMP.posX >> 4, (int) par1EntityPlayerMP.posZ >> 4); + } + + public int getEntityViewDistance() { + return PlayerManager.getFurthestViewableBlock(this.getViewDistance()); + } + + /** + * called during player login. reads the player information from disk. + */ + public NBTTagCompound readPlayerDataFromFile(EntityPlayerMP par1EntityPlayerMP) { + NBTTagCompound var2 = this.mcServer.worldServers[0].getWorldInfo().getPlayerNBTTagCompound(); + NBTTagCompound var3; + + if (par1EntityPlayerMP.getCommandSenderName().equals(this.mcServer.getServerOwner()) && var2 != null) { + par1EntityPlayerMP.readFromNBT(var2); + var3 = var2; + System.out.println("loading single player"); + } else { + var3 = this.playerNBTManagerObj.readPlayerData(par1EntityPlayerMP); + } + + return var3; + } + + /** + * also stores the NBTTags if this is an intergratedPlayerList + */ + protected void writePlayerData(EntityPlayerMP par1EntityPlayerMP) { + this.playerNBTManagerObj.writePlayerData(par1EntityPlayerMP); + } + + /** + * Called when a player successfully logs in. Reads player data from disk and + * inserts the player into the world. + */ + public void playerLoggedIn(EntityPlayerMP par1EntityPlayerMP) { + this.sendPacketToAllPlayers(new Packet201PlayerInfo(par1EntityPlayerMP.username, true, 1000)); + this.playerEntityList.add(par1EntityPlayerMP); + WorldServer var2 = this.mcServer.worldServerForDimension(par1EntityPlayerMP.dimension); + var2.spawnEntityInWorld(par1EntityPlayerMP); + this.func_72375_a(par1EntityPlayerMP, (WorldServer) null); + + for (int var3 = 0; var3 < this.playerEntityList.size(); ++var3) { + EntityPlayerMP var4 = (EntityPlayerMP) this.playerEntityList.get(var3); + par1EntityPlayerMP.playerNetServerHandler + .sendPacket(new Packet201PlayerInfo(var4.username, true, var4.ping)); + } + } + + /** + * using player's dimension, update their movement when in a vehicle (e.g. cart, + * boat) + */ + public void serverUpdateMountedMovingPlayer(EntityPlayerMP par1EntityPlayerMP) { + par1EntityPlayerMP.getServerForPlayer().getPlayerManager().updateMountedMovingPlayer(par1EntityPlayerMP); + } + + /** + * Called when a player disconnects from the game. Writes player data to disk + * and removes them from the world. + */ + public void playerLoggedOut(EntityPlayerMP par1EntityPlayerMP) { + this.writePlayerData(par1EntityPlayerMP); + WorldServer var2 = par1EntityPlayerMP.getServerForPlayer(); + + if (par1EntityPlayerMP.ridingEntity != null) { + var2.removeEntity(par1EntityPlayerMP.ridingEntity); + System.out.println("removing player mount"); + } + + var2.removeEntity(par1EntityPlayerMP); + var2.getPlayerManager().removePlayer(par1EntityPlayerMP); + this.playerEntityList.remove(par1EntityPlayerMP); + this.sendPacketToAllPlayers(new Packet201PlayerInfo(par1EntityPlayerMP.username, false, 9999)); + } + + /** + * checks ban-lists, then white-lists, then space for the server. Returns null + * on success, or an error message + */ + public String allowUserToConnect(SocketAddress par1SocketAddress, String par2Str) { + if (this.bannedPlayers.isBanned(par2Str)) { + BanEntry var6 = (BanEntry) this.bannedPlayers.getBannedList().get(par2Str); + String var7 = "You are banned from this server!\nReason: " + var6.getBanReason(); + + if (var6.getBanEndDate() != null) { + var7 = var7 + "\nYour ban will be removed on " + dateFormat.format(var6.getBanEndDate()); + } + + return var7; + } else if (!this.isAllowedToLogin(par2Str)) { + return "You are not white-listed on this server!"; + } else { + String var3 = par1SocketAddress.toString(); + var3 = var3.substring(var3.indexOf("/") + 1); + var3 = var3.substring(0, var3.indexOf(":")); + + if (this.bannedIPs.isBanned(var3)) { + BanEntry var4 = (BanEntry) this.bannedIPs.getBannedList().get(var3); + String var5 = "Your IP address is banned from this server!\nReason: " + var4.getBanReason(); + + if (var4.getBanEndDate() != null) { + var5 = var5 + "\nYour ban will be removed on " + dateFormat.format(var4.getBanEndDate()); + } + + return var5; + } else { + return this.playerEntityList.size() >= this.maxPlayers ? "The server is full!" : null; + } + } + } + + /** + * also checks for multiple logins + */ + public EntityPlayerMP createPlayerForUser(String par1Str) { + ArrayList var2 = new ArrayList(); + EntityPlayerMP var4; + + for (int var3 = 0; var3 < this.playerEntityList.size(); ++var3) { + var4 = (EntityPlayerMP) this.playerEntityList.get(var3); + + if (var4.username.equalsIgnoreCase(par1Str)) { + var2.add(var4); + } + } + + Iterator var5 = var2.iterator(); + + while (var5.hasNext()) { + var4 = (EntityPlayerMP) var5.next(); + var4.playerNetServerHandler.kickPlayer("You logged in from another location"); + } + + Object var6; + + if (this.mcServer.isDemo()) { + var6 = new DemoWorldManager(this.mcServer.worldServerForDimension(0)); + } else { + var6 = new ItemInWorldManager(this.mcServer.worldServerForDimension(0)); + } + + return new EntityPlayerMP(this.mcServer, this.mcServer.worldServerForDimension(0), par1Str, + (ItemInWorldManager) var6); + } + + /** + * Called on respawn + */ + public EntityPlayerMP recreatePlayerEntity(EntityPlayerMP par1EntityPlayerMP, int par2, boolean par3) { + par1EntityPlayerMP.getServerForPlayer().getEntityTracker().removePlayerFromTrackers(par1EntityPlayerMP); + par1EntityPlayerMP.getServerForPlayer().getEntityTracker().untrackEntity(par1EntityPlayerMP); + par1EntityPlayerMP.getServerForPlayer().getPlayerManager().removePlayer(par1EntityPlayerMP); + this.playerEntityList.remove(par1EntityPlayerMP); + this.mcServer.worldServerForDimension(par1EntityPlayerMP.dimension) + .removePlayerEntityDangerously(par1EntityPlayerMP); + ChunkCoordinates var4 = par1EntityPlayerMP.getBedLocation(); + boolean var5 = par1EntityPlayerMP.isSpawnForced(); + par1EntityPlayerMP.dimension = par2; + Object var6; + + if (this.mcServer.isDemo()) { + var6 = new DemoWorldManager(this.mcServer.worldServerForDimension(par1EntityPlayerMP.dimension)); + } else { + var6 = new ItemInWorldManager(this.mcServer.worldServerForDimension(par1EntityPlayerMP.dimension)); + } + + EntityPlayerMP var7 = new EntityPlayerMP(this.mcServer, + this.mcServer.worldServerForDimension(par1EntityPlayerMP.dimension), par1EntityPlayerMP.username, + (ItemInWorldManager) var6); + var7.playerNetServerHandler = par1EntityPlayerMP.playerNetServerHandler; + var7.clonePlayer(par1EntityPlayerMP, par3); + var7.entityId = par1EntityPlayerMP.entityId; + WorldServer var8 = this.mcServer.worldServerForDimension(par1EntityPlayerMP.dimension); + this.func_72381_a(var7, par1EntityPlayerMP, var8); + ChunkCoordinates var9; + + if (var4 != null) { + var9 = EntityPlayer.verifyRespawnCoordinates( + this.mcServer.worldServerForDimension(par1EntityPlayerMP.dimension), var4, var5); + + if (var9 != null) { + var7.setLocationAndAngles((double) ((float) var9.posX + 0.5F), (double) ((float) var9.posY + 0.1F), + (double) ((float) var9.posZ + 0.5F), 0.0F, 0.0F); + var7.setSpawnChunk(var4, var5); + } else { + var7.playerNetServerHandler.sendPacket(new Packet70GameEvent(0, 0)); + } + } + + var8.theChunkProviderServer.loadChunk((int) var7.posX >> 4, (int) var7.posZ >> 4); + + while (!var8.getCollidingBoundingBoxes(var7, var7.boundingBox).isEmpty()) { + var7.setPosition(var7.posX, var7.posY + 1.0D, var7.posZ); + } + + var7.playerNetServerHandler.sendPacket(new Packet9Respawn(var7.dimension, + (byte) var7.worldObj.difficultySetting, var7.worldObj.getWorldInfo().getTerrainType(), + var7.worldObj.getHeight(), var7.theItemInWorldManager.getGameType())); + var9 = var8.getSpawnPoint(); + var7.playerNetServerHandler.setPlayerLocation(var7.posX, var7.posY, var7.posZ, var7.rotationYaw, + var7.rotationPitch); + var7.playerNetServerHandler.sendPacket(new Packet6SpawnPosition(var9.posX, var9.posY, var9.posZ)); + var7.playerNetServerHandler + .sendPacket(new Packet43Experience(var7.experience, var7.experienceTotal, var7.experienceLevel)); + this.updateTimeAndWeatherForPlayer(var7, var8); + var8.getPlayerManager().addPlayer(var7); + var8.spawnEntityInWorld(var7); + this.playerEntityList.add(var7); + var7.addSelfToInternalCraftingInventory(); + var7.setEntityHealth(var7.getHealth()); + return var7; + } + + /** + * moves provided player from overworld to nether or vice versa + */ + public void transferPlayerToDimension(EntityPlayerMP par1EntityPlayerMP, int par2) { + int var3 = par1EntityPlayerMP.dimension; + WorldServer var4 = this.mcServer.worldServerForDimension(par1EntityPlayerMP.dimension); + par1EntityPlayerMP.dimension = par2; + WorldServer var5 = this.mcServer.worldServerForDimension(par1EntityPlayerMP.dimension); + par1EntityPlayerMP.playerNetServerHandler.sendPacket(new Packet9Respawn(par1EntityPlayerMP.dimension, + (byte) par1EntityPlayerMP.worldObj.difficultySetting, var5.getWorldInfo().getTerrainType(), + var5.getHeight(), par1EntityPlayerMP.theItemInWorldManager.getGameType())); + var4.removePlayerEntityDangerously(par1EntityPlayerMP); + par1EntityPlayerMP.isDead = false; + this.transferEntityToWorld(par1EntityPlayerMP, var3, var4, var5); + this.func_72375_a(par1EntityPlayerMP, var4); + par1EntityPlayerMP.playerNetServerHandler.setPlayerLocation(par1EntityPlayerMP.posX, par1EntityPlayerMP.posY, + par1EntityPlayerMP.posZ, par1EntityPlayerMP.rotationYaw, par1EntityPlayerMP.rotationPitch); + par1EntityPlayerMP.theItemInWorldManager.setWorld(var5); + this.updateTimeAndWeatherForPlayer(par1EntityPlayerMP, var5); + this.syncPlayerInventory(par1EntityPlayerMP); + Iterator var6 = par1EntityPlayerMP.getActivePotionEffects().iterator(); + + while (var6.hasNext()) { + PotionEffect var7 = (PotionEffect) var6.next(); + par1EntityPlayerMP.playerNetServerHandler + .sendPacket(new Packet41EntityEffect(par1EntityPlayerMP.entityId, var7)); + } + } + + /** + * Transfers an entity from a world to another world. + */ + public void transferEntityToWorld(Entity par1Entity, int par2, WorldServer par3WorldServer, + WorldServer par4WorldServer) { + double var5 = par1Entity.posX; + double var7 = par1Entity.posZ; + double var9 = 8.0D; + double var11 = par1Entity.posX; + double var13 = par1Entity.posY; + double var15 = par1Entity.posZ; + float var17 = par1Entity.rotationYaw; + par3WorldServer.theProfiler.startSection("moving"); + + if (par1Entity.dimension == -1) { + var5 /= var9; + var7 /= var9; + par1Entity.setLocationAndAngles(var5, par1Entity.posY, var7, par1Entity.rotationYaw, + par1Entity.rotationPitch); + + if (par1Entity.isEntityAlive()) { + par3WorldServer.updateEntityWithOptionalForce(par1Entity, false); + } + } else if (par1Entity.dimension == 0) { + var5 *= var9; + var7 *= var9; + par1Entity.setLocationAndAngles(var5, par1Entity.posY, var7, par1Entity.rotationYaw, + par1Entity.rotationPitch); + + if (par1Entity.isEntityAlive()) { + par3WorldServer.updateEntityWithOptionalForce(par1Entity, false); + } + } else { + ChunkCoordinates var18; + + if (par2 == 1) { + var18 = par4WorldServer.getSpawnPoint(); + } else { + var18 = par4WorldServer.getEntrancePortalLocation(); + } + + var5 = (double) var18.posX; + par1Entity.posY = (double) var18.posY; + var7 = (double) var18.posZ; + par1Entity.setLocationAndAngles(var5, par1Entity.posY, var7, 90.0F, 0.0F); + + if (par1Entity.isEntityAlive()) { + par3WorldServer.updateEntityWithOptionalForce(par1Entity, false); + } + } + + par3WorldServer.theProfiler.endSection(); + + if (par2 != 1) { + par3WorldServer.theProfiler.startSection("placing"); + var5 = (double) MathHelper.clamp_int((int) var5, -29999872, 29999872); + var7 = (double) MathHelper.clamp_int((int) var7, -29999872, 29999872); + + if (par1Entity.isEntityAlive()) { + par4WorldServer.spawnEntityInWorld(par1Entity); + par1Entity.setLocationAndAngles(var5, par1Entity.posY, var7, par1Entity.rotationYaw, + par1Entity.rotationPitch); + par4WorldServer.updateEntityWithOptionalForce(par1Entity, false); + par4WorldServer.getDefaultTeleporter().placeInPortal(par1Entity, var11, var13, var15, var17); + } + + par3WorldServer.theProfiler.endSection(); + } + + par1Entity.setWorld(par4WorldServer); + } + + /** + * self explanitory + */ + public void onTick() { + if (++this.playerPingIndex > 600) { + this.playerPingIndex = 0; + } + + if (this.playerPingIndex < this.playerEntityList.size()) { + EntityPlayerMP var1 = (EntityPlayerMP) this.playerEntityList.get(this.playerPingIndex); + this.sendPacketToAllPlayers(new Packet201PlayerInfo(var1.username, true, var1.ping)); + } + } + + /** + * sends a packet to all players + */ + public void sendPacketToAllPlayers(Packet par1Packet) { + for (int var2 = 0; var2 < this.playerEntityList.size(); ++var2) { + ((EntityPlayerMP) this.playerEntityList.get(var2)).playerNetServerHandler.sendPacket(par1Packet); + } + } + + /** + * Sends a packet to all players in the specified Dimension + */ + public void sendPacketToAllPlayersInDimension(Packet par1Packet, int par2) { + for (int var3 = 0; var3 < this.playerEntityList.size(); ++var3) { + EntityPlayerMP var4 = (EntityPlayerMP) this.playerEntityList.get(var3); + + if (var4.dimension == par2) { + var4.playerNetServerHandler.sendPacket(par1Packet); + } + } + } + + /** + * returns a string containing a comma-seperated list of player names + */ + public String getPlayerListAsString() { + String var1 = ""; + + for (int var2 = 0; var2 < this.playerEntityList.size(); ++var2) { + if (var2 > 0) { + var1 = var1 + ", "; + } + + var1 = var1 + ((EntityPlayerMP) this.playerEntityList.get(var2)).username; + } + + return var1; + } + + /** + * Returns an array of the usernames of all the connected players. + */ + public String[] getAllUsernames() { + String[] var1 = new String[this.playerEntityList.size()]; + + for (int var2 = 0; var2 < this.playerEntityList.size(); ++var2) { + var1[var2] = ((EntityPlayerMP) this.playerEntityList.get(var2)).username; + } + + return var1; + } + + public BanList getBannedPlayers() { + return this.bannedPlayers; + } + + public BanList getBannedIPs() { + return this.bannedIPs; + } + + /** + * This adds a username to the ops list, then saves the op list + */ + public void addOp(String par1Str) { + this.ops.add(par1Str.toLowerCase()); + } + + /** + * This removes a username from the ops list, then saves the op list + */ + public void removeOp(String par1Str) { + this.ops.remove(par1Str.toLowerCase()); + } + + /** + * Determine if the player is allowed to connect based on current server + * settings. + */ + public boolean isAllowedToLogin(String par1Str) { + par1Str = par1Str.trim().toLowerCase(); + return !this.whiteListEnforced || this.ops.contains(par1Str) || this.whiteListedPlayers.contains(par1Str); + } + + /** + * Returns true if the specific player is allowed to use commands. + */ + public boolean areCommandsAllowed(String par1Str) { + return this.ops.contains(par1Str.trim().toLowerCase()) + || this.mcServer.isSinglePlayer() && this.mcServer.worldServers[0].getWorldInfo().areCommandsAllowed() + && this.mcServer.getServerOwner().equalsIgnoreCase(par1Str) + || this.commandsAllowedForAll; + } + + /** + * gets the player entity for the player with the name specified + */ + public EntityPlayerMP getPlayerEntity(String par1Str) { + Iterator var2 = this.playerEntityList.iterator(); + EntityPlayerMP var3; + + do { + if (!var2.hasNext()) { + return null; + } + + var3 = (EntityPlayerMP) var2.next(); + } while (!var3.username.equalsIgnoreCase(par1Str)); + + return var3; + } + + /** + * Find all players in a specified range and narrowing down by other parameters + */ + public List findPlayers(ChunkCoordinates par1ChunkCoordinates, int par2, int par3, int par4, int par5, int par6, + int par7, Map par8Map, String par9Str, String par10Str) { + if (this.playerEntityList.isEmpty()) { + return null; + } else { + Object var11 = new ArrayList(); + boolean var12 = par4 < 0; + int var13 = par2 * par2; + int var14 = par3 * par3; + par4 = MathHelper.abs_int(par4); + + for (int var15 = 0; var15 < this.playerEntityList.size(); ++var15) { + EntityPlayerMP var16 = (EntityPlayerMP) this.playerEntityList.get(var15); + boolean var17; + + if (par9Str != null) { + var17 = par9Str.startsWith("!"); + + if (var17) { + par9Str = par9Str.substring(1); + } + + if (var17 == par9Str.equalsIgnoreCase(var16.getEntityName())) { + continue; + } + } + + if (par10Str != null) { + var17 = par10Str.startsWith("!"); + + if (var17) { + par10Str = par10Str.substring(1); + } + + ScorePlayerTeam var18 = var16.getTeam(); + String var19 = var18 == null ? "" : var18.func_96661_b(); + + if (var17 == par10Str.equalsIgnoreCase(var19)) { + continue; + } + } + + if (par1ChunkCoordinates != null && (par2 > 0 || par3 > 0)) { + float var20 = par1ChunkCoordinates + .getDistanceSquaredToChunkCoordinates(var16.getCommandSenderPosition()); + + if (par2 > 0 && var20 < (float) var13 || par3 > 0 && var20 > (float) var14) { + continue; + } + } + + if (this.func_96457_a(var16, par8Map) + && (par5 == EnumGameType.NOT_SET.getID() + || par5 == var16.theItemInWorldManager.getGameType().getID()) + && (par6 <= 0 || var16.experienceLevel >= par6) && var16.experienceLevel <= par7) { + ((List) var11).add(var16); + } + } + + if (par1ChunkCoordinates != null) { + Collections.sort((List) var11, new PlayerPositionComparator(par1ChunkCoordinates)); + } + + if (var12) { + Collections.reverse((List) var11); + } + + if (par4 > 0) { + var11 = ((List) var11).subList(0, Math.min(par4, ((List) var11).size())); + } + + return (List) var11; + } + } + + private boolean func_96457_a(EntityPlayer par1EntityPlayer, Map par2Map) { + if (par2Map != null && par2Map.size() != 0) { + Iterator var3 = par2Map.entrySet().iterator(); + Entry var4; + boolean var6; + int var10; + + do { + if (!var3.hasNext()) { + return true; + } + + var4 = (Entry) var3.next(); + String var5 = (String) var4.getKey(); + var6 = false; + + if (var5.endsWith("_min") && var5.length() > 4) { + var6 = true; + var5 = var5.substring(0, var5.length() - 4); + } + + Scoreboard var7 = par1EntityPlayer.getWorldScoreboard(); + ScoreObjective var8 = var7.getObjective(var5); + + if (var8 == null) { + return false; + } + + Score var9 = par1EntityPlayer.getWorldScoreboard().func_96529_a(par1EntityPlayer.getEntityName(), var8); + var10 = var9.func_96652_c(); + + if (var10 < ((Integer) var4.getValue()).intValue() && var6) { + return false; + } + } while (var10 <= ((Integer) var4.getValue()).intValue() || var6); + + return false; + } else { + return true; + } + } + + /** + * sends a packet to players within d3 of point (x,y,z) + */ + public void sendPacketToPlayersAroundPoint(double par1, double par3, double par5, double par7, int par9, + Packet par10Packet) { + this.sendToAllNearExcept((EntityPlayer) null, par1, par3, par5, par7, par9, par10Packet); + } + + /** + * params: srcPlayer,x,y,z,d,dimension. The packet is not sent to the srcPlayer, + * but all other players where dx*dx+dy*dy+dz*dz 0) { + ServerGUI.getDedicatedServer(this.mcServerGui).addPendingCommand(var2, MinecraftServer.getServer()); + } + + this.textField.setText(""); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ServerGuiFocusAdapter.java b/sp-server/src/main/java/net/minecraft/src/ServerGuiFocusAdapter.java new file mode 100644 index 0000000..65ae666 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ServerGuiFocusAdapter.java @@ -0,0 +1,16 @@ +package net.minecraft.src; + +import java.awt.event.FocusAdapter; +import java.awt.event.FocusEvent; + +class ServerGuiFocusAdapter extends FocusAdapter { + /** Reference to the ServerGui object. */ + final ServerGUI mcServerGui; + + ServerGuiFocusAdapter(ServerGUI par1ServerGUI) { + this.mcServerGui = par1ServerGUI; + } + + public void focusGained(FocusEvent par1FocusEvent) { + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ServerListenThread.java b/sp-server/src/main/java/net/minecraft/src/ServerListenThread.java new file mode 100644 index 0000000..b92684b --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ServerListenThread.java @@ -0,0 +1,104 @@ +package net.minecraft.src; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.ServerSocket; +import java.net.Socket; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; + +public class ServerListenThread extends Thread { + private final List pendingConnections = Collections.synchronizedList(new ArrayList()); + + /** + * This map stores a list of InetAddresses and the last time which they + * connected at + */ + private final HashMap recentConnections = new HashMap(); + private int connectionCounter = 0; + private final ServerSocket myServerSocket; + private NetworkListenThread myNetworkListenThread; + private final InetAddress myServerAddress; + private final int myPort; + + public ServerListenThread(NetworkListenThread par1NetworkListenThread, InetAddress par2InetAddress, int par3) + throws IOException { + super("Listen thread"); + this.myNetworkListenThread = par1NetworkListenThread; + this.myPort = par3; + this.myServerSocket = new ServerSocket(par3, 0, par2InetAddress); + this.myServerAddress = par2InetAddress == null ? this.myServerSocket.getInetAddress() : par2InetAddress; + this.myServerSocket.setPerformancePreferences(0, 2, 1); + } + + public void processPendingConnections() { + List var1 = this.pendingConnections; + + synchronized (this.pendingConnections) { + for (int var2 = 0; var2 < this.pendingConnections.size(); ++var2) { + NetLoginHandler var3 = (NetLoginHandler) this.pendingConnections.get(var2); + + try { + var3.tryLogin(); + } catch (Exception var6) { + var3.kickUser("Internal server error"); + this.myNetworkListenThread.getServer().getLogAgent().logWarningException( + "Failed to handle packet for " + var3.getUsernameAndAddress() + ": " + var6, var6); + } + + if (var3.finishedProcessing) { + this.pendingConnections.remove(var2--); + } + + var3.myTCPConnection.wakeThreads(); + } + } + } + + public void run() { + while (this.myNetworkListenThread.isListening) { + try { + Socket var1 = this.myServerSocket.accept(); + NetLoginHandler var2 = new NetLoginHandler(this.myNetworkListenThread.getServer(), var1, + "Connection #" + this.connectionCounter++); + this.addPendingConnection(var2); + } catch (IOException var3) { + var3.printStackTrace(); + } + } + + this.myNetworkListenThread.getServer().getLogAgent().func_98233_a("Closing listening thread"); + } + + private void addPendingConnection(NetLoginHandler par1NetLoginHandler) { + if (par1NetLoginHandler == null) { + throw new IllegalArgumentException("Got null pendingconnection!"); + } else { + List var2 = this.pendingConnections; + + synchronized (this.pendingConnections) { + this.pendingConnections.add(par1NetLoginHandler); + } + } + } + + public void func_71769_a(InetAddress par1InetAddress) { + if (par1InetAddress != null) { + HashMap var2 = this.recentConnections; + + synchronized (this.recentConnections) { + this.recentConnections.remove(par1InetAddress); + } + } + } + + public void func_71768_b() { + try { + this.myServerSocket.close(); + } catch (Throwable var2) { + ; + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ServerScoreboard.java b/sp-server/src/main/java/net/minecraft/src/ServerScoreboard.java new file mode 100644 index 0000000..c9d590c --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ServerScoreboard.java @@ -0,0 +1,214 @@ +package net.minecraft.src; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; +import net.minecraft.server.MinecraftServer; + +public class ServerScoreboard extends Scoreboard { + private final MinecraftServer field_96555_a; + private final Set field_96553_b = new HashSet(); + private ScoreboardSaveData field_96554_c; + + public ServerScoreboard(MinecraftServer par1MinecraftServer) { + this.field_96555_a = par1MinecraftServer; + } + + public void func_96536_a(Score par1Score) { + super.func_96536_a(par1Score); + + if (this.field_96553_b.contains(par1Score.func_96645_d())) { + this.field_96555_a.getConfigurationManager().sendPacketToAllPlayers(new Packet207SetScore(par1Score, 0)); + } + + this.func_96551_b(); + } + + public void func_96516_a(String par1Str) { + super.func_96516_a(par1Str); + this.field_96555_a.getConfigurationManager().sendPacketToAllPlayers(new Packet207SetScore(par1Str)); + this.func_96551_b(); + } + + public void func_96530_a(int par1, ScoreObjective par2ScoreObjective) { + ScoreObjective var3 = this.func_96539_a(par1); + super.func_96530_a(par1, par2ScoreObjective); + + if (var3 != par2ScoreObjective && var3 != null) { + if (this.func_96552_h(var3) > 0) { + this.field_96555_a.getConfigurationManager() + .sendPacketToAllPlayers(new Packet208SetDisplayObjective(par1, par2ScoreObjective)); + } else { + this.func_96546_g(var3); + } + } + + if (par2ScoreObjective != null) { + if (this.field_96553_b.contains(par2ScoreObjective)) { + this.field_96555_a.getConfigurationManager() + .sendPacketToAllPlayers(new Packet208SetDisplayObjective(par1, par2ScoreObjective)); + } else { + this.func_96549_e(par2ScoreObjective); + } + } + + this.func_96551_b(); + } + + public void func_96521_a(String par1Str, ScorePlayerTeam par2ScorePlayerTeam) { + super.func_96521_a(par1Str, par2ScorePlayerTeam); + this.field_96555_a.getConfigurationManager().sendPacketToAllPlayers( + new Packet209SetPlayerTeam(par2ScorePlayerTeam, Arrays.asList(new String[] { par1Str }), 3)); + this.func_96551_b(); + } + + /** + * Removes the given username from the given ScorePlayerTeam. If the player is + * not on the team then an IllegalStateException is thrown. + */ + public void removePlayerFromTeam(String par1Str, ScorePlayerTeam par2ScorePlayerTeam) { + super.removePlayerFromTeam(par1Str, par2ScorePlayerTeam); + this.field_96555_a.getConfigurationManager().sendPacketToAllPlayers( + new Packet209SetPlayerTeam(par2ScorePlayerTeam, Arrays.asList(new String[] { par1Str }), 4)); + this.func_96551_b(); + } + + public void func_96522_a(ScoreObjective par1ScoreObjective) { + super.func_96522_a(par1ScoreObjective); + this.func_96551_b(); + } + + public void func_96532_b(ScoreObjective par1ScoreObjective) { + super.func_96532_b(par1ScoreObjective); + + if (this.field_96553_b.contains(par1ScoreObjective)) { + this.field_96555_a.getConfigurationManager() + .sendPacketToAllPlayers(new Packet206SetObjective(par1ScoreObjective, 2)); + } + + this.func_96551_b(); + } + + public void func_96533_c(ScoreObjective par1ScoreObjective) { + super.func_96533_c(par1ScoreObjective); + + if (this.field_96553_b.contains(par1ScoreObjective)) { + this.func_96546_g(par1ScoreObjective); + } + + this.func_96551_b(); + } + + public void func_96523_a(ScorePlayerTeam par1ScorePlayerTeam) { + super.func_96523_a(par1ScorePlayerTeam); + this.field_96555_a.getConfigurationManager() + .sendPacketToAllPlayers(new Packet209SetPlayerTeam(par1ScorePlayerTeam, 0)); + this.func_96551_b(); + } + + public void func_96538_b(ScorePlayerTeam par1ScorePlayerTeam) { + super.func_96538_b(par1ScorePlayerTeam); + this.field_96555_a.getConfigurationManager() + .sendPacketToAllPlayers(new Packet209SetPlayerTeam(par1ScorePlayerTeam, 2)); + this.func_96551_b(); + } + + public void func_96513_c(ScorePlayerTeam par1ScorePlayerTeam) { + super.func_96513_c(par1ScorePlayerTeam); + this.field_96555_a.getConfigurationManager() + .sendPacketToAllPlayers(new Packet209SetPlayerTeam(par1ScorePlayerTeam, 1)); + this.func_96551_b(); + } + + public void func_96547_a(ScoreboardSaveData par1ScoreboardSaveData) { + this.field_96554_c = par1ScoreboardSaveData; + } + + protected void func_96551_b() { + if (this.field_96554_c != null) { + this.field_96554_c.markDirty(); + } + } + + public List func_96550_d(ScoreObjective par1ScoreObjective) { + ArrayList var2 = new ArrayList(); + var2.add(new Packet206SetObjective(par1ScoreObjective, 0)); + + for (int var3 = 0; var3 < 3; ++var3) { + if (this.func_96539_a(var3) == par1ScoreObjective) { + var2.add(new Packet208SetDisplayObjective(var3, par1ScoreObjective)); + } + } + + Iterator var5 = this.func_96534_i(par1ScoreObjective).iterator(); + + while (var5.hasNext()) { + Score var4 = (Score) var5.next(); + var2.add(new Packet207SetScore(var4, 0)); + } + + return var2; + } + + public void func_96549_e(ScoreObjective par1ScoreObjective) { + List var2 = this.func_96550_d(par1ScoreObjective); + Iterator var3 = this.field_96555_a.getConfigurationManager().playerEntityList.iterator(); + + while (var3.hasNext()) { + EntityPlayerMP var4 = (EntityPlayerMP) var3.next(); + Iterator var5 = var2.iterator(); + + while (var5.hasNext()) { + Packet var6 = (Packet) var5.next(); + var4.playerNetServerHandler.sendPacket(var6); + } + } + + this.field_96553_b.add(par1ScoreObjective); + } + + public List func_96548_f(ScoreObjective par1ScoreObjective) { + ArrayList var2 = new ArrayList(); + var2.add(new Packet206SetObjective(par1ScoreObjective, 1)); + + for (int var3 = 0; var3 < 3; ++var3) { + if (this.func_96539_a(var3) == par1ScoreObjective) { + var2.add(new Packet208SetDisplayObjective(var3, par1ScoreObjective)); + } + } + + return var2; + } + + public void func_96546_g(ScoreObjective par1ScoreObjective) { + List var2 = this.func_96548_f(par1ScoreObjective); + Iterator var3 = this.field_96555_a.getConfigurationManager().playerEntityList.iterator(); + + while (var3.hasNext()) { + EntityPlayerMP var4 = (EntityPlayerMP) var3.next(); + Iterator var5 = var2.iterator(); + + while (var5.hasNext()) { + Packet var6 = (Packet) var5.next(); + var4.playerNetServerHandler.sendPacket(var6); + } + } + + this.field_96553_b.remove(par1ScoreObjective); + } + + public int func_96552_h(ScoreObjective par1ScoreObjective) { + int var2 = 0; + + for (int var3 = 0; var3 < 3; ++var3) { + if (this.func_96539_a(var3) == par1ScoreObjective) { + ++var2; + } + } + + return var2; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ServerWindowAdapter.java b/sp-server/src/main/java/net/minecraft/src/ServerWindowAdapter.java new file mode 100644 index 0000000..9ffa02e --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ServerWindowAdapter.java @@ -0,0 +1,27 @@ +package net.minecraft.src; + +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; + +final class ServerWindowAdapter extends WindowAdapter { + /** The Minecraft instance. */ + final DedicatedServer mc; + + ServerWindowAdapter(DedicatedServer par1DedicatedServer) { + this.mc = par1DedicatedServer; + } + + public void windowClosing(WindowEvent par1WindowEvent) { + this.mc.initiateShutdown(); + + while (!this.mc.isServerStopped()) { + try { + Thread.sleep(100L); + } catch (InterruptedException var3) { + var3.printStackTrace(); + } + } + + System.exit(0); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ShapedRecipes.java b/sp-server/src/main/java/net/minecraft/src/ShapedRecipes.java new file mode 100644 index 0000000..a13d21a --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ShapedRecipes.java @@ -0,0 +1,120 @@ +package net.minecraft.src; + +public class ShapedRecipes implements IRecipe { + /** How many horizontal slots this recipe is wide. */ + private int recipeWidth; + + /** How many vertical slots this recipe uses. */ + private int recipeHeight; + + /** Is a array of ItemStack that composes the recipe. */ + private ItemStack[] recipeItems; + + /** Is the ItemStack that you get when craft the recipe. */ + private ItemStack recipeOutput; + + /** Is the itemID of the output item that you get when craft the recipe. */ + public final int recipeOutputItemID; + private boolean field_92101_f = false; + + public ShapedRecipes(int par1, int par2, ItemStack[] par3ArrayOfItemStack, ItemStack par4ItemStack) { + this.recipeOutputItemID = par4ItemStack.itemID; + this.recipeWidth = par1; + this.recipeHeight = par2; + this.recipeItems = par3ArrayOfItemStack; + this.recipeOutput = par4ItemStack; + } + + public ItemStack getRecipeOutput() { + return this.recipeOutput; + } + + /** + * Used to check if a recipe matches current crafting inventory + */ + public boolean matches(InventoryCrafting par1InventoryCrafting, World par2World) { + for (int var3 = 0; var3 <= 3 - this.recipeWidth; ++var3) { + for (int var4 = 0; var4 <= 3 - this.recipeHeight; ++var4) { + if (this.checkMatch(par1InventoryCrafting, var3, var4, true)) { + return true; + } + + if (this.checkMatch(par1InventoryCrafting, var3, var4, false)) { + return true; + } + } + } + + return false; + } + + /** + * Checks if the region of a crafting inventory is match for the recipe. + */ + private boolean checkMatch(InventoryCrafting par1InventoryCrafting, int par2, int par3, boolean par4) { + for (int var5 = 0; var5 < 3; ++var5) { + for (int var6 = 0; var6 < 3; ++var6) { + int var7 = var5 - par2; + int var8 = var6 - par3; + ItemStack var9 = null; + + if (var7 >= 0 && var8 >= 0 && var7 < this.recipeWidth && var8 < this.recipeHeight) { + if (par4) { + var9 = this.recipeItems[this.recipeWidth - var7 - 1 + var8 * this.recipeWidth]; + } else { + var9 = this.recipeItems[var7 + var8 * this.recipeWidth]; + } + } + + ItemStack var10 = par1InventoryCrafting.getStackInRowAndColumn(var5, var6); + + if (var10 != null || var9 != null) { + if (var10 == null && var9 != null || var10 != null && var9 == null) { + return false; + } + + if (var9.itemID != var10.itemID) { + return false; + } + + if (var9.getItemDamage() != 32767 && var9.getItemDamage() != var10.getItemDamage()) { + return false; + } + } + } + } + + return true; + } + + /** + * Returns an Item that is the result of this recipe + */ + public ItemStack getCraftingResult(InventoryCrafting par1InventoryCrafting) { + ItemStack var2 = this.getRecipeOutput().copy(); + + if (this.field_92101_f) { + for (int var3 = 0; var3 < par1InventoryCrafting.getSizeInventory(); ++var3) { + ItemStack var4 = par1InventoryCrafting.getStackInSlot(var3); + + if (var4 != null && var4.hasTagCompound()) { + var2.setTagCompound((NBTTagCompound) var4.stackTagCompound.copy()); + } + } + } + + return var2; + } + + /** + * Returns the size of the recipe area + */ + public int getRecipeSize() { + return this.recipeWidth * this.recipeHeight; + } + + public ShapedRecipes func_92100_c() { + this.field_92101_f = true; + return this; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ShapelessRecipes.java b/sp-server/src/main/java/net/minecraft/src/ShapelessRecipes.java new file mode 100644 index 0000000..1017f2b --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ShapelessRecipes.java @@ -0,0 +1,71 @@ +package net.minecraft.src; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +public class ShapelessRecipes implements IRecipe { + /** Is the ItemStack that you get when craft the recipe. */ + private final ItemStack recipeOutput; + + /** Is a List of ItemStack that composes the recipe. */ + private final List recipeItems; + + public ShapelessRecipes(ItemStack par1ItemStack, List par2List) { + this.recipeOutput = par1ItemStack; + this.recipeItems = par2List; + } + + public ItemStack getRecipeOutput() { + return this.recipeOutput; + } + + /** + * Used to check if a recipe matches current crafting inventory + */ + public boolean matches(InventoryCrafting par1InventoryCrafting, World par2World) { + ArrayList var3 = new ArrayList(this.recipeItems); + + for (int var4 = 0; var4 < 3; ++var4) { + for (int var5 = 0; var5 < 3; ++var5) { + ItemStack var6 = par1InventoryCrafting.getStackInRowAndColumn(var5, var4); + + if (var6 != null) { + boolean var7 = false; + Iterator var8 = var3.iterator(); + + while (var8.hasNext()) { + ItemStack var9 = (ItemStack) var8.next(); + + if (var6.itemID == var9.itemID + && (var9.getItemDamage() == 32767 || var6.getItemDamage() == var9.getItemDamage())) { + var7 = true; + var3.remove(var9); + break; + } + } + + if (!var7) { + return false; + } + } + } + } + + return var3.isEmpty(); + } + + /** + * Returns an Item that is the result of this recipe + */ + public ItemStack getCraftingResult(InventoryCrafting par1InventoryCrafting) { + return this.recipeOutput.copy(); + } + + /** + * Returns the size of the recipe area + */ + public int getRecipeSize() { + return this.recipeItems.size(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/Slot.java b/sp-server/src/main/java/net/minecraft/src/Slot.java new file mode 100644 index 0000000..fde55ca --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/Slot.java @@ -0,0 +1,126 @@ +package net.minecraft.src; + +public class Slot { + /** The index of the slot in the inventory. */ + private final int slotIndex; + + /** The inventory we want to extract a slot from. */ + public final IInventory inventory; + + /** the id of the slot(also the index in the inventory arraylist) */ + public int slotNumber; + + /** display position of the inventory slot on the screen x axis */ + public int xDisplayPosition; + + /** display position of the inventory slot on the screen y axis */ + public int yDisplayPosition; + + public Slot(IInventory par1IInventory, int par2, int par3, int par4) { + this.inventory = par1IInventory; + this.slotIndex = par2; + this.xDisplayPosition = par3; + this.yDisplayPosition = par4; + } + + /** + * if par2 has more items than par1, onCrafting(item,countIncrease) is called + */ + public void onSlotChange(ItemStack par1ItemStack, ItemStack par2ItemStack) { + if (par1ItemStack != null && par2ItemStack != null) { + if (par1ItemStack.itemID == par2ItemStack.itemID) { + int var3 = par2ItemStack.stackSize - par1ItemStack.stackSize; + + if (var3 > 0) { + this.onCrafting(par1ItemStack, var3); + } + } + } + } + + /** + * the itemStack passed in is the output - ie, iron ingots, and pickaxes, not + * ore and wood. Typically increases an internal count then calls + * onCrafting(item). + */ + protected void onCrafting(ItemStack par1ItemStack, int par2) { + } + + /** + * the itemStack passed in is the output - ie, iron ingots, and pickaxes, not + * ore and wood. + */ + protected void onCrafting(ItemStack par1ItemStack) { + } + + public void onPickupFromSlot(EntityPlayer par1EntityPlayer, ItemStack par2ItemStack) { + this.onSlotChanged(); + } + + /** + * Check if the stack is a valid item for this slot. Always true beside for the + * armor slots. + */ + public boolean isItemValid(ItemStack par1ItemStack) { + return true; + } + + /** + * Helper fnct to get the stack in the slot. + */ + public ItemStack getStack() { + return this.inventory.getStackInSlot(this.slotIndex); + } + + /** + * Returns if this slot contains a stack. + */ + public boolean getHasStack() { + return this.getStack() != null; + } + + /** + * Helper method to put a stack in the slot. + */ + public void putStack(ItemStack par1ItemStack) { + this.inventory.setInventorySlotContents(this.slotIndex, par1ItemStack); + this.onSlotChanged(); + } + + /** + * Called when the stack in a Slot changes + */ + public void onSlotChanged() { + this.inventory.onInventoryChanged(); + } + + /** + * Returns the maximum stack size for a given slot (usually the same as + * getInventoryStackLimit(), but 1 in the case of armor slots) + */ + public int getSlotStackLimit() { + return this.inventory.getInventoryStackLimit(); + } + + /** + * Decrease the size of the stack in slot (first int arg) by the amount of the + * second int arg. Returns the new stack. + */ + public ItemStack decrStackSize(int par1) { + return this.inventory.decrStackSize(this.slotIndex, par1); + } + + /** + * returns true if the slot exists in the given inventory and location + */ + public boolean isHere(IInventory par1IInventory, int par2) { + return par1IInventory == this.inventory && par2 == this.slotIndex; + } + + /** + * Return whether this slot's stack can be taken from this slot. + */ + public boolean canTakeStack(EntityPlayer par1EntityPlayer) { + return true; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/SlotArmor.java b/sp-server/src/main/java/net/minecraft/src/SlotArmor.java new file mode 100644 index 0000000..faf6b43 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/SlotArmor.java @@ -0,0 +1,43 @@ +package net.minecraft.src; + +class SlotArmor extends Slot { + /** + * The armor type that can be placed on that slot, it uses the same values of + * armorType field on ItemArmor. + */ + final int armorType; + + /** + * The parent class of this clot, ContainerPlayer, SlotArmor is a Anon inner + * class. + */ + final ContainerPlayer parent; + + SlotArmor(ContainerPlayer par1ContainerPlayer, IInventory par2IInventory, int par3, int par4, int par5, int par6) { + super(par2IInventory, par3, par4, par5); + this.parent = par1ContainerPlayer; + this.armorType = par6; + } + + /** + * Returns the maximum stack size for a given slot (usually the same as + * getInventoryStackLimit(), but 1 in the case of armor slots) + */ + public int getSlotStackLimit() { + return 1; + } + + /** + * Check if the stack is a valid item for this slot. Always true beside for the + * armor slots. + */ + public boolean isItemValid(ItemStack par1ItemStack) { + return par1ItemStack == null ? false + : (par1ItemStack + .getItem() instanceof ItemArmor + ? ((ItemArmor) par1ItemStack.getItem()).armorType == this.armorType + : (par1ItemStack.getItem().itemID != Block.pumpkin.blockID + && par1ItemStack.getItem().itemID != Item.skull.itemID ? false + : this.armorType == 0)); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/SlotBeacon.java b/sp-server/src/main/java/net/minecraft/src/SlotBeacon.java new file mode 100644 index 0000000..96c2ff2 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/SlotBeacon.java @@ -0,0 +1,30 @@ +package net.minecraft.src; + +class SlotBeacon extends Slot { + /** The beacon this slot belongs to. */ + final ContainerBeacon beacon; + + public SlotBeacon(ContainerBeacon par1ContainerBeacon, IInventory par2IInventory, int par3, int par4, int par5) { + super(par2IInventory, par3, par4, par5); + this.beacon = par1ContainerBeacon; + } + + /** + * Check if the stack is a valid item for this slot. Always true beside for the + * armor slots. + */ + public boolean isItemValid(ItemStack par1ItemStack) { + return par1ItemStack == null ? false + : par1ItemStack.itemID == Item.emerald.itemID || par1ItemStack.itemID == Item.diamond.itemID + || par1ItemStack.itemID == Item.ingotGold.itemID + || par1ItemStack.itemID == Item.ingotIron.itemID; + } + + /** + * Returns the maximum stack size for a given slot (usually the same as + * getInventoryStackLimit(), but 1 in the case of armor slots) + */ + public int getSlotStackLimit() { + return 1; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/SlotBrewingStandIngredient.java b/sp-server/src/main/java/net/minecraft/src/SlotBrewingStandIngredient.java new file mode 100644 index 0000000..9912352 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/SlotBrewingStandIngredient.java @@ -0,0 +1,28 @@ +package net.minecraft.src; + +class SlotBrewingStandIngredient extends Slot { + /** The brewing stand this slot belongs to. */ + final ContainerBrewingStand brewingStand; + + public SlotBrewingStandIngredient(ContainerBrewingStand par1ContainerBrewingStand, IInventory par2IInventory, + int par3, int par4, int par5) { + super(par2IInventory, par3, par4, par5); + this.brewingStand = par1ContainerBrewingStand; + } + + /** + * Check if the stack is a valid item for this slot. Always true beside for the + * armor slots. + */ + public boolean isItemValid(ItemStack par1ItemStack) { + return par1ItemStack != null ? Item.itemsList[par1ItemStack.itemID].isPotionIngredient() : false; + } + + /** + * Returns the maximum stack size for a given slot (usually the same as + * getInventoryStackLimit(), but 1 in the case of armor slots) + */ + public int getSlotStackLimit() { + return 64; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/SlotBrewingStandPotion.java b/sp-server/src/main/java/net/minecraft/src/SlotBrewingStandPotion.java new file mode 100644 index 0000000..4482f25 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/SlotBrewingStandPotion.java @@ -0,0 +1,44 @@ +package net.minecraft.src; + +class SlotBrewingStandPotion extends Slot { + /** The player that has this container open. */ + private EntityPlayer player; + + public SlotBrewingStandPotion(EntityPlayer par1EntityPlayer, IInventory par2IInventory, int par3, int par4, + int par5) { + super(par2IInventory, par3, par4, par5); + this.player = par1EntityPlayer; + } + + /** + * Check if the stack is a valid item for this slot. Always true beside for the + * armor slots. + */ + public boolean isItemValid(ItemStack par1ItemStack) { + return canHoldPotion(par1ItemStack); + } + + /** + * Returns the maximum stack size for a given slot (usually the same as + * getInventoryStackLimit(), but 1 in the case of armor slots) + */ + public int getSlotStackLimit() { + return 1; + } + + public void onPickupFromSlot(EntityPlayer par1EntityPlayer, ItemStack par2ItemStack) { + if (par2ItemStack.itemID == Item.potion.itemID && par2ItemStack.getItemDamage() > 0) { + this.player.addStat(AchievementList.potion, 1); + } + + super.onPickupFromSlot(par1EntityPlayer, par2ItemStack); + } + + /** + * Returns true if this itemstack can be filled with a potion + */ + public static boolean canHoldPotion(ItemStack par0ItemStack) { + return par0ItemStack != null + && (par0ItemStack.itemID == Item.potion.itemID || par0ItemStack.itemID == Item.glassBottle.itemID); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/SlotCrafting.java b/sp-server/src/main/java/net/minecraft/src/SlotCrafting.java new file mode 100644 index 0000000..3ec544a --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/SlotCrafting.java @@ -0,0 +1,108 @@ +package net.minecraft.src; + +public class SlotCrafting extends Slot { + /** The craft matrix inventory linked to this result slot. */ + private final IInventory craftMatrix; + + /** The player that is using the GUI where this slot resides. */ + private EntityPlayer thePlayer; + + /** + * The number of items that have been crafted so far. Gets passed to + * ItemStack.onCrafting before being reset. + */ + private int amountCrafted; + + public SlotCrafting(EntityPlayer par1EntityPlayer, IInventory par2IInventory, IInventory par3IInventory, int par4, + int par5, int par6) { + super(par3IInventory, par4, par5, par6); + this.thePlayer = par1EntityPlayer; + this.craftMatrix = par2IInventory; + } + + /** + * Check if the stack is a valid item for this slot. Always true beside for the + * armor slots. + */ + public boolean isItemValid(ItemStack par1ItemStack) { + return false; + } + + /** + * Decrease the size of the stack in slot (first int arg) by the amount of the + * second int arg. Returns the new stack. + */ + public ItemStack decrStackSize(int par1) { + if (this.getHasStack()) { + this.amountCrafted += Math.min(par1, this.getStack().stackSize); + } + + return super.decrStackSize(par1); + } + + /** + * the itemStack passed in is the output - ie, iron ingots, and pickaxes, not + * ore and wood. Typically increases an internal count then calls + * onCrafting(item). + */ + protected void onCrafting(ItemStack par1ItemStack, int par2) { + this.amountCrafted += par2; + this.onCrafting(par1ItemStack); + } + + /** + * the itemStack passed in is the output - ie, iron ingots, and pickaxes, not + * ore and wood. + */ + protected void onCrafting(ItemStack par1ItemStack) { + par1ItemStack.onCrafting(this.thePlayer.worldObj, this.thePlayer, this.amountCrafted); + this.amountCrafted = 0; + + if (par1ItemStack.itemID == Block.workbench.blockID) { + this.thePlayer.addStat(AchievementList.buildWorkBench, 1); + } else if (par1ItemStack.itemID == Item.pickaxeWood.itemID) { + this.thePlayer.addStat(AchievementList.buildPickaxe, 1); + } else if (par1ItemStack.itemID == Block.furnaceIdle.blockID) { + this.thePlayer.addStat(AchievementList.buildFurnace, 1); + } else if (par1ItemStack.itemID == Item.hoeWood.itemID) { + this.thePlayer.addStat(AchievementList.buildHoe, 1); + } else if (par1ItemStack.itemID == Item.bread.itemID) { + this.thePlayer.addStat(AchievementList.makeBread, 1); + } else if (par1ItemStack.itemID == Item.cake.itemID) { + this.thePlayer.addStat(AchievementList.bakeCake, 1); + } else if (par1ItemStack.itemID == Item.pickaxeStone.itemID) { + this.thePlayer.addStat(AchievementList.buildBetterPickaxe, 1); + } else if (par1ItemStack.itemID == Item.swordWood.itemID) { + this.thePlayer.addStat(AchievementList.buildSword, 1); + } else if (par1ItemStack.itemID == Block.enchantmentTable.blockID) { + this.thePlayer.addStat(AchievementList.enchantments, 1); + } else if (par1ItemStack.itemID == Block.bookShelf.blockID) { + this.thePlayer.addStat(AchievementList.bookcase, 1); + } + } + + public void onPickupFromSlot(EntityPlayer par1EntityPlayer, ItemStack par2ItemStack) { + this.onCrafting(par2ItemStack); + + for (int var3 = 0; var3 < this.craftMatrix.getSizeInventory(); ++var3) { + ItemStack var4 = this.craftMatrix.getStackInSlot(var3); + + if (var4 != null) { + this.craftMatrix.decrStackSize(var3, 1); + + if (var4.getItem().hasContainerItem()) { + ItemStack var5 = new ItemStack(var4.getItem().getContainerItem()); + + if (!var4.getItem().doesContainerItemLeaveCraftingGrid(var4) + || !this.thePlayer.inventory.addItemStackToInventory(var5)) { + if (this.craftMatrix.getStackInSlot(var3) == null) { + this.craftMatrix.setInventorySlotContents(var3, var5); + } else { + this.thePlayer.dropPlayerItem(var5); + } + } + } + } + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/SlotEnchantment.java b/sp-server/src/main/java/net/minecraft/src/SlotEnchantment.java new file mode 100644 index 0000000..9433b46 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/SlotEnchantment.java @@ -0,0 +1,20 @@ +package net.minecraft.src; + +class SlotEnchantment extends Slot { + /** The brewing stand this slot belongs to. */ + final ContainerEnchantment container; + + SlotEnchantment(ContainerEnchantment par1ContainerEnchantment, IInventory par2IInventory, int par3, int par4, + int par5) { + super(par2IInventory, par3, par4, par5); + this.container = par1ContainerEnchantment; + } + + /** + * Check if the stack is a valid item for this slot. Always true beside for the + * armor slots. + */ + public boolean isItemValid(ItemStack par1ItemStack) { + return true; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/SlotEnchantmentTable.java b/sp-server/src/main/java/net/minecraft/src/SlotEnchantmentTable.java new file mode 100644 index 0000000..fa40751 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/SlotEnchantmentTable.java @@ -0,0 +1,35 @@ +package net.minecraft.src; + +class SlotEnchantmentTable extends InventoryBasic { + /** The brewing stand this slot belongs to. */ + final ContainerEnchantment container; + + SlotEnchantmentTable(ContainerEnchantment par1ContainerEnchantment, String par2Str, boolean par3, int par4) { + super(par2Str, par3, par4); + this.container = par1ContainerEnchantment; + } + + /** + * Returns the maximum stack size for a inventory slot. Seems to always be 64, + * possibly will be extended. *Isn't this more of a set than a get?* + */ + public int getInventoryStackLimit() { + return 1; + } + + /** + * Called when an the contents of an Inventory change, usually + */ + public void onInventoryChanged() { + super.onInventoryChanged(); + this.container.onCraftMatrixChanged(this); + } + + /** + * Returns true if automation is allowed to insert the given stack (ignoring + * stack size) into the given slot. + */ + public boolean isStackValidForSlot(int par1, ItemStack par2ItemStack) { + return true; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/SlotFurnace.java b/sp-server/src/main/java/net/minecraft/src/SlotFurnace.java new file mode 100644 index 0000000..1d6a184 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/SlotFurnace.java @@ -0,0 +1,91 @@ +package net.minecraft.src; + +public class SlotFurnace extends Slot { + /** The player that is using the GUI where this slot resides. */ + private EntityPlayer thePlayer; + private int field_75228_b; + + public SlotFurnace(EntityPlayer par1EntityPlayer, IInventory par2IInventory, int par3, int par4, int par5) { + super(par2IInventory, par3, par4, par5); + this.thePlayer = par1EntityPlayer; + } + + /** + * Check if the stack is a valid item for this slot. Always true beside for the + * armor slots. + */ + public boolean isItemValid(ItemStack par1ItemStack) { + return false; + } + + /** + * Decrease the size of the stack in slot (first int arg) by the amount of the + * second int arg. Returns the new stack. + */ + public ItemStack decrStackSize(int par1) { + if (this.getHasStack()) { + this.field_75228_b += Math.min(par1, this.getStack().stackSize); + } + + return super.decrStackSize(par1); + } + + public void onPickupFromSlot(EntityPlayer par1EntityPlayer, ItemStack par2ItemStack) { + this.onCrafting(par2ItemStack); + super.onPickupFromSlot(par1EntityPlayer, par2ItemStack); + } + + /** + * the itemStack passed in is the output - ie, iron ingots, and pickaxes, not + * ore and wood. Typically increases an internal count then calls + * onCrafting(item). + */ + protected void onCrafting(ItemStack par1ItemStack, int par2) { + this.field_75228_b += par2; + this.onCrafting(par1ItemStack); + } + + /** + * the itemStack passed in is the output - ie, iron ingots, and pickaxes, not + * ore and wood. + */ + protected void onCrafting(ItemStack par1ItemStack) { + par1ItemStack.onCrafting(this.thePlayer.worldObj, this.thePlayer, this.field_75228_b); + + if (!this.thePlayer.worldObj.isRemote) { + int var2 = this.field_75228_b; + float var3 = FurnaceRecipes.smelting().getExperience(par1ItemStack.itemID); + int var4; + + if (var3 == 0.0F) { + var2 = 0; + } else if (var3 < 1.0F) { + var4 = MathHelper.floor_float((float) var2 * var3); + + if (var4 < MathHelper.ceiling_float_int((float) var2 * var3) + && (float) Math.random() < (float) var2 * var3 - (float) var4) { + ++var4; + } + + var2 = var4; + } + + while (var2 > 0) { + var4 = EntityXPOrb.getXPSplit(var2); + var2 -= var4; + this.thePlayer.worldObj.spawnEntityInWorld(new EntityXPOrb(this.thePlayer.worldObj, this.thePlayer.posX, + this.thePlayer.posY + 0.5D, this.thePlayer.posZ + 0.5D, var4)); + } + } + + this.field_75228_b = 0; + + if (par1ItemStack.itemID == Item.ingotIron.itemID) { + this.thePlayer.addStat(AchievementList.acquireIron, 1); + } + + if (par1ItemStack.itemID == Item.fishCooked.itemID) { + this.thePlayer.addStat(AchievementList.cookFish, 1); + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/SlotMerchantResult.java b/sp-server/src/main/java/net/minecraft/src/SlotMerchantResult.java new file mode 100644 index 0000000..99d2543 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/SlotMerchantResult.java @@ -0,0 +1,104 @@ +package net.minecraft.src; + +public class SlotMerchantResult extends Slot { + /** Merchant's inventory. */ + private final InventoryMerchant theMerchantInventory; + + /** The Player whos trying to buy/sell stuff. */ + private EntityPlayer thePlayer; + private int field_75231_g; + + /** "Instance" of the Merchant. */ + private final IMerchant theMerchant; + + public SlotMerchantResult(EntityPlayer par1EntityPlayer, IMerchant par2IMerchant, + InventoryMerchant par3InventoryMerchant, int par4, int par5, int par6) { + super(par3InventoryMerchant, par4, par5, par6); + this.thePlayer = par1EntityPlayer; + this.theMerchant = par2IMerchant; + this.theMerchantInventory = par3InventoryMerchant; + } + + /** + * Check if the stack is a valid item for this slot. Always true beside for the + * armor slots. + */ + public boolean isItemValid(ItemStack par1ItemStack) { + return false; + } + + /** + * Decrease the size of the stack in slot (first int arg) by the amount of the + * second int arg. Returns the new stack. + */ + public ItemStack decrStackSize(int par1) { + if (this.getHasStack()) { + this.field_75231_g += Math.min(par1, this.getStack().stackSize); + } + + return super.decrStackSize(par1); + } + + /** + * the itemStack passed in is the output - ie, iron ingots, and pickaxes, not + * ore and wood. Typically increases an internal count then calls + * onCrafting(item). + */ + protected void onCrafting(ItemStack par1ItemStack, int par2) { + this.field_75231_g += par2; + this.onCrafting(par1ItemStack); + } + + /** + * the itemStack passed in is the output - ie, iron ingots, and pickaxes, not + * ore and wood. + */ + protected void onCrafting(ItemStack par1ItemStack) { + par1ItemStack.onCrafting(this.thePlayer.worldObj, this.thePlayer, this.field_75231_g); + this.field_75231_g = 0; + } + + public void onPickupFromSlot(EntityPlayer par1EntityPlayer, ItemStack par2ItemStack) { + this.onCrafting(par2ItemStack); + MerchantRecipe var3 = this.theMerchantInventory.getCurrentRecipe(); + + if (var3 != null) { + ItemStack var4 = this.theMerchantInventory.getStackInSlot(0); + ItemStack var5 = this.theMerchantInventory.getStackInSlot(1); + + if (this.func_75230_a(var3, var4, var5) || this.func_75230_a(var3, var5, var4)) { + if (var4 != null && var4.stackSize <= 0) { + var4 = null; + } + + if (var5 != null && var5.stackSize <= 0) { + var5 = null; + } + + this.theMerchantInventory.setInventorySlotContents(0, var4); + this.theMerchantInventory.setInventorySlotContents(1, var5); + this.theMerchant.useRecipe(var3); + } + } + } + + private boolean func_75230_a(MerchantRecipe par1MerchantRecipe, ItemStack par2ItemStack, ItemStack par3ItemStack) { + ItemStack var4 = par1MerchantRecipe.getItemToBuy(); + ItemStack var5 = par1MerchantRecipe.getSecondItemToBuy(); + + if (par2ItemStack != null && par2ItemStack.itemID == var4.itemID) { + if (var5 != null && par3ItemStack != null && var5.itemID == par3ItemStack.itemID) { + par2ItemStack.stackSize -= var4.stackSize; + par3ItemStack.stackSize -= var5.stackSize; + return true; + } + + if (var5 == null && par3ItemStack == null) { + par2ItemStack.stackSize -= var4.stackSize; + return true; + } + } + + return false; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/SlotRepair.java b/sp-server/src/main/java/net/minecraft/src/SlotRepair.java new file mode 100644 index 0000000..49c5669 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/SlotRepair.java @@ -0,0 +1,83 @@ +package net.minecraft.src; + +class SlotRepair extends Slot { + final World theWorld; + + final int blockPosX; + + final int blockPosY; + + final int blockPosZ; + + /** The anvil this slot belongs to. */ + final ContainerRepair anvil; + + SlotRepair(ContainerRepair par1ContainerRepair, IInventory par2IInventory, int par3, int par4, int par5, + World par6World, int par7, int par8, int par9) { + super(par2IInventory, par3, par4, par5); + this.anvil = par1ContainerRepair; + this.theWorld = par6World; + this.blockPosX = par7; + this.blockPosY = par8; + this.blockPosZ = par9; + } + + /** + * Check if the stack is a valid item for this slot. Always true beside for the + * armor slots. + */ + public boolean isItemValid(ItemStack par1ItemStack) { + return false; + } + + /** + * Return whether this slot's stack can be taken from this slot. + */ + public boolean canTakeStack(EntityPlayer par1EntityPlayer) { + return (par1EntityPlayer.capabilities.isCreativeMode + || par1EntityPlayer.experienceLevel >= this.anvil.maximumCost) && this.anvil.maximumCost > 0 + && this.getHasStack(); + } + + public void onPickupFromSlot(EntityPlayer par1EntityPlayer, ItemStack par2ItemStack) { + if (!par1EntityPlayer.capabilities.isCreativeMode) { + par1EntityPlayer.addExperienceLevel(-this.anvil.maximumCost); + } + + ContainerRepair.getRepairInputInventory(this.anvil).setInventorySlotContents(0, (ItemStack) null); + + if (ContainerRepair.getStackSizeUsedInRepair(this.anvil) > 0) { + ItemStack var3 = ContainerRepair.getRepairInputInventory(this.anvil).getStackInSlot(1); + + if (var3 != null && var3.stackSize > ContainerRepair.getStackSizeUsedInRepair(this.anvil)) { + var3.stackSize -= ContainerRepair.getStackSizeUsedInRepair(this.anvil); + ContainerRepair.getRepairInputInventory(this.anvil).setInventorySlotContents(1, var3); + } else { + ContainerRepair.getRepairInputInventory(this.anvil).setInventorySlotContents(1, (ItemStack) null); + } + } else { + ContainerRepair.getRepairInputInventory(this.anvil).setInventorySlotContents(1, (ItemStack) null); + } + + this.anvil.maximumCost = 0; + + if (!par1EntityPlayer.capabilities.isCreativeMode && !this.theWorld.isRemote + && this.theWorld.getBlockId(this.blockPosX, this.blockPosY, this.blockPosZ) == Block.anvil.blockID + && par1EntityPlayer.getRNG().nextFloat() < 0.12F) { + int var6 = this.theWorld.getBlockMetadata(this.blockPosX, this.blockPosY, this.blockPosZ); + int var4 = var6 & 3; + int var5 = var6 >> 2; + ++var5; + + if (var5 > 2) { + this.theWorld.setBlockToAir(this.blockPosX, this.blockPosY, this.blockPosZ); + this.theWorld.playAuxSFX(1020, this.blockPosX, this.blockPosY, this.blockPosZ, 0); + } else { + this.theWorld.setBlockMetadata(this.blockPosX, this.blockPosY, this.blockPosZ, var4 | var5 << 2, 2); + this.theWorld.playAuxSFX(1021, this.blockPosX, this.blockPosY, this.blockPosZ, 0); + } + } else if (!this.theWorld.isRemote) { + this.theWorld.playAuxSFX(1021, this.blockPosX, this.blockPosY, this.blockPosZ, 0); + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/SpawnListEntry.java b/sp-server/src/main/java/net/minecraft/src/SpawnListEntry.java new file mode 100644 index 0000000..fcaf2c5 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/SpawnListEntry.java @@ -0,0 +1,15 @@ +package net.minecraft.src; + +public class SpawnListEntry extends WeightedRandomItem { + /** Holds the class of the entity to be spawned. */ + public Class entityClass; + public int minGroupCount; + public int maxGroupCount; + + public SpawnListEntry(Class par1Class, int par2, int par3, int par4) { + super(par2); + this.entityClass = par1Class; + this.minGroupCount = par3; + this.maxGroupCount = par4; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/SpawnerAnimals.java b/sp-server/src/main/java/net/minecraft/src/SpawnerAnimals.java new file mode 100644 index 0000000..a467e2d --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/SpawnerAnimals.java @@ -0,0 +1,267 @@ +package net.minecraft.src; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Random; + +public final class SpawnerAnimals { + /** The 17x17 area around the player where mobs can spawn */ + private static HashMap eligibleChunksForSpawning = new HashMap(); + + /** An array of entity classes that spawn at night. */ + protected static final Class[] nightSpawnEntities = new Class[] { EntitySpider.class, EntityZombie.class, + EntitySkeleton.class }; + + /** + * Given a chunk, find a random position in it. + */ + protected static ChunkPosition getRandomSpawningPointInChunk(World par0World, int par1, int par2) { + Chunk var3 = par0World.getChunkFromChunkCoords(par1, par2); + int var4 = par1 * 16 + par0World.rand.nextInt(16); + int var5 = par2 * 16 + par0World.rand.nextInt(16); + int var6 = par0World.rand + .nextInt(var3 == null ? par0World.getActualHeight() : var3.getTopFilledSegment() + 16 - 1); + return new ChunkPosition(var4, var6, var5); + } + + /** + * adds all chunks within the spawn radius of the players to + * eligibleChunksForSpawning. pars: the world, hostileCreatures, + * passiveCreatures. returns number of eligible chunks. + */ + public static final int findChunksForSpawning(WorldServer par0WorldServer, boolean par1, boolean par2, + boolean par3) { + if (!par1 && !par2) { + return 0; + } else { + eligibleChunksForSpawning.clear(); + int var4; + int var7; + + for (var4 = 0; var4 < par0WorldServer.playerEntities.size(); ++var4) { + EntityPlayer var5 = (EntityPlayer) par0WorldServer.playerEntities.get(var4); + int var6 = MathHelper.floor_double(var5.posX / 16.0D); + var7 = MathHelper.floor_double(var5.posZ / 16.0D); + byte var8 = 8; + + for (int var9 = -var8; var9 <= var8; ++var9) { + for (int var10 = -var8; var10 <= var8; ++var10) { + boolean var11 = var9 == -var8 || var9 == var8 || var10 == -var8 || var10 == var8; + ChunkCoordIntPair var12 = new ChunkCoordIntPair(var9 + var6, var10 + var7); + + if (!var11) { + eligibleChunksForSpawning.put(var12, Boolean.valueOf(false)); + } else if (!eligibleChunksForSpawning.containsKey(var12)) { + eligibleChunksForSpawning.put(var12, Boolean.valueOf(true)); + } + } + } + } + + var4 = 0; + ChunkCoordinates var32 = par0WorldServer.getSpawnPoint(); + EnumCreatureType[] var33 = EnumCreatureType.values(); + var7 = var33.length; + + for (int var34 = 0; var34 < var7; ++var34) { + EnumCreatureType var35 = var33[var34]; + + if ((!var35.getPeacefulCreature() || par2) && (var35.getPeacefulCreature() || par1) + && (!var35.getAnimal() || par3) + && par0WorldServer.countEntities(var35.getCreatureClass()) <= var35.getMaxNumberOfCreature() + * eligibleChunksForSpawning.size() / 256) { + Iterator var36 = eligibleChunksForSpawning.keySet().iterator(); + label110: + + while (var36.hasNext()) { + ChunkCoordIntPair var37 = (ChunkCoordIntPair) var36.next(); + + if (!((Boolean) eligibleChunksForSpawning.get(var37)).booleanValue()) { + ChunkPosition var38 = getRandomSpawningPointInChunk(par0WorldServer, var37.chunkXPos, + var37.chunkZPos); + int var13 = var38.x; + int var14 = var38.y; + int var15 = var38.z; + + if (!par0WorldServer.isBlockNormalCube(var13, var14, var15) && par0WorldServer + .getBlockMaterial(var13, var14, var15) == var35.getCreatureMaterial()) { + int var16 = 0; + int var17 = 0; + + while (var17 < 3) { + int var18 = var13; + int var19 = var14; + int var20 = var15; + byte var21 = 6; + SpawnListEntry var22 = null; + int var23 = 0; + + while (true) { + if (var23 < 4) { + label103: { + var18 += par0WorldServer.rand.nextInt(var21) + - par0WorldServer.rand.nextInt(var21); + var19 += par0WorldServer.rand.nextInt(1) + - par0WorldServer.rand.nextInt(1); + var20 += par0WorldServer.rand.nextInt(var21) + - par0WorldServer.rand.nextInt(var21); + + if (canCreatureTypeSpawnAtLocation(var35, par0WorldServer, var18, var19, + var20)) { + float var24 = (float) var18 + 0.5F; + float var25 = (float) var19; + float var26 = (float) var20 + 0.5F; + + if (par0WorldServer.getClosestPlayer((double) var24, (double) var25, + (double) var26, 24.0D) == null) { + float var27 = var24 - (float) var32.posX; + float var28 = var25 - (float) var32.posY; + float var29 = var26 - (float) var32.posZ; + float var30 = var27 * var27 + var28 * var28 + var29 * var29; + + if (var30 >= 576.0F) { + if (var22 == null) { + var22 = par0WorldServer.spawnRandomCreature(var35, + var18, var19, var20); + + if (var22 == null) { + break label103; + } + } + + EntityLiving var39; + + try { + var39 = (EntityLiving) var22.entityClass + .getConstructor(new Class[] { World.class }) + .newInstance(new Object[] { par0WorldServer }); + } catch (Exception var31) { + var31.printStackTrace(); + return var4; + } + + var39.setLocationAndAngles((double) var24, (double) var25, + (double) var26, + par0WorldServer.rand.nextFloat() * 360.0F, 0.0F); + + if (var39.getCanSpawnHere()) { + ++var16; + par0WorldServer.spawnEntityInWorld(var39); + creatureSpecificInit(var39, par0WorldServer, var24, + var25, var26); + + if (var16 >= var39.getMaxSpawnedInChunk()) { + continue label110; + } + } + + var4 += var16; + } + } + } + + ++var23; + continue; + } + } + + ++var17; + break; + } + } + } + } + } + } + } + + return var4; + } + } + + /** + * Returns whether or not the specified creature type can spawn at the specified + * location. + */ + public static boolean canCreatureTypeSpawnAtLocation(EnumCreatureType par0EnumCreatureType, World par1World, + int par2, int par3, int par4) { + if (par0EnumCreatureType.getCreatureMaterial() == Material.water) { + return par1World.getBlockMaterial(par2, par3, par4).isLiquid() + && par1World.getBlockMaterial(par2, par3 - 1, par4).isLiquid() + && !par1World.isBlockNormalCube(par2, par3 + 1, par4); + } else if (!par1World.doesBlockHaveSolidTopSurface(par2, par3 - 1, par4)) { + return false; + } else { + int var5 = par1World.getBlockId(par2, par3 - 1, par4); + return var5 != Block.bedrock.blockID && !par1World.isBlockNormalCube(par2, par3, par4) + && !par1World.getBlockMaterial(par2, par3, par4).isLiquid() + && !par1World.isBlockNormalCube(par2, par3 + 1, par4); + } + } + + /** + * determines if a skeleton spawns on a spider, and if a sheep is a different + * color + */ + private static void creatureSpecificInit(EntityLiving par0EntityLiving, World par1World, float par2, float par3, + float par4) { + par0EntityLiving.initCreature(); + } + + /** + * Called during chunk generation to spawn initial creatures. + */ + public static void performWorldGenSpawning(World par0World, BiomeGenBase par1BiomeGenBase, int par2, int par3, + int par4, int par5, Random par6Random) { + List var7 = par1BiomeGenBase.getSpawnableList(EnumCreatureType.creature); + + if (!var7.isEmpty()) { + while (par6Random.nextFloat() < par1BiomeGenBase.getSpawningChance()) { + SpawnListEntry var8 = (SpawnListEntry) WeightedRandom.getRandomItem(par0World.rand, var7); + int var9 = var8.minGroupCount + par6Random.nextInt(1 + var8.maxGroupCount - var8.minGroupCount); + int var10 = par2 + par6Random.nextInt(par4); + int var11 = par3 + par6Random.nextInt(par5); + int var12 = var10; + int var13 = var11; + + for (int var14 = 0; var14 < var9; ++var14) { + boolean var15 = false; + + for (int var16 = 0; !var15 && var16 < 4; ++var16) { + int var17 = par0World.getTopSolidOrLiquidBlock(var10, var11); + + if (canCreatureTypeSpawnAtLocation(EnumCreatureType.creature, par0World, var10, var17, var11)) { + float var18 = (float) var10 + 0.5F; + float var19 = (float) var17; + float var20 = (float) var11 + 0.5F; + EntityLiving var21; + + try { + var21 = (EntityLiving) var8.entityClass.getConstructor(new Class[] { World.class }) + .newInstance(new Object[] { par0World }); + } catch (Exception var23) { + var23.printStackTrace(); + continue; + } + + var21.setLocationAndAngles((double) var18, (double) var19, (double) var20, + par6Random.nextFloat() * 360.0F, 0.0F); + par0World.spawnEntityInWorld(var21); + creatureSpecificInit(var21, par0World, var18, var19, var20); + var15 = true; + } + + var10 += par6Random.nextInt(5) - par6Random.nextInt(5); + + for (var11 += par6Random.nextInt(5) - par6Random.nextInt(5); var10 < par2 + || var10 >= par2 + par4 || var11 < par3 || var11 >= par3 + par4; var11 = var13 + + par6Random.nextInt(5) - par6Random.nextInt(5)) { + var10 = var12 + par6Random.nextInt(5) - par6Random.nextInt(5); + } + } + } + } + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/StatBase.java b/sp-server/src/main/java/net/minecraft/src/StatBase.java new file mode 100644 index 0000000..33be609 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/StatBase.java @@ -0,0 +1,63 @@ +package net.minecraft.src; + +import java.text.DecimalFormat; +import java.text.NumberFormat; +import java.util.Locale; + +public class StatBase { + /** The Stat ID */ + public final int statId; + + /** The Stat name */ + private final String statName; + public boolean isIndependent; + + /** Holds the GUID of the stat. */ + public String statGuid; + private final IStatType type; + private static NumberFormat numberFormat = NumberFormat.getIntegerInstance(Locale.US); + public static IStatType simpleStatType = new StatTypeSimple(); + private static DecimalFormat decimalFormat = new DecimalFormat("########0.00"); + public static IStatType timeStatType = new StatTypeTime(); + public static IStatType distanceStatType = new StatTypeDistance(); + + public StatBase(int par1, String par2Str, IStatType par3IStatType) { + this.isIndependent = false; + this.statId = par1; + this.statName = par2Str; + this.type = par3IStatType; + } + + public StatBase(int par1, String par2Str) { + this(par1, par2Str, simpleStatType); + } + + /** + * Initializes the current stat as independent (i.e., lacking prerequisites for + * being updated) and returns the current instance. + */ + public StatBase initIndependentStat() { + this.isIndependent = true; + return this; + } + + /** + * Register the stat into StatList. + */ + public StatBase registerStat() { + if (StatList.oneShotStats.containsKey(Integer.valueOf(this.statId))) { + throw new RuntimeException("Duplicate stat id: \"" + + ((StatBase) StatList.oneShotStats.get(Integer.valueOf(this.statId))).statName + "\" and \"" + + this.statName + "\" at id " + this.statId); + } else { + StatList.allStats.add(this); + StatList.oneShotStats.put(Integer.valueOf(this.statId), this); + this.statGuid = AchievementMap.getGuid(this.statId); + return this; + } + } + + public String toString() { + return StatCollector.translateToLocal(this.statName); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/StatBasic.java b/sp-server/src/main/java/net/minecraft/src/StatBasic.java new file mode 100644 index 0000000..a060c5f --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/StatBasic.java @@ -0,0 +1,20 @@ +package net.minecraft.src; + +public class StatBasic extends StatBase { + public StatBasic(int par1, String par2Str, IStatType par3IStatType) { + super(par1, par2Str, par3IStatType); + } + + public StatBasic(int par1, String par2Str) { + super(par1, par2Str); + } + + /** + * Register the stat into StatList. + */ + public StatBase registerStat() { + super.registerStat(); + StatList.generalStats.add(this); + return this; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/StatCollector.java b/sp-server/src/main/java/net/minecraft/src/StatCollector.java new file mode 100644 index 0000000..0e4cc52 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/StatCollector.java @@ -0,0 +1,23 @@ +package net.minecraft.src; + +public class StatCollector { + private static StringTranslate localizedName = StringTranslate.getInstance(); + + /** + * Translates a Stat name + */ + public static String translateToLocal(String par0Str) { + return localizedName.translateKey(par0Str); + } + + /** + * Translates a Stat name with format args + */ + public static String translateToLocalFormatted(String par0Str, Object... par1ArrayOfObj) { + return localizedName.translateKeyFormat(par0Str, par1ArrayOfObj); + } + + public static boolean func_94522_b(String par0Str) { + return localizedName.isKeyTranslated(par0Str); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/StatCrafting.java b/sp-server/src/main/java/net/minecraft/src/StatCrafting.java new file mode 100644 index 0000000..a6145c3 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/StatCrafting.java @@ -0,0 +1,10 @@ +package net.minecraft.src; + +public class StatCrafting extends StatBase { + private final int itemID; + + public StatCrafting(int par1, String par2Str, int par3) { + super(par1, par2Str); + this.itemID = par3; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/StatList.java b/sp-server/src/main/java/net/minecraft/src/StatList.java new file mode 100644 index 0000000..c77339f --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/StatList.java @@ -0,0 +1,279 @@ +package net.minecraft.src; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +public class StatList { + /** Tracks one-off stats. */ + protected static Map oneShotStats = new HashMap(); + public static List allStats = new ArrayList(); + public static List generalStats = new ArrayList(); + public static List itemStats = new ArrayList(); + + /** Tracks the number of times a given block or item has been mined. */ + public static List objectMineStats = new ArrayList(); + + /** times the game has been started */ + public static StatBase startGameStat = (new StatBasic(1000, "stat.startGame")).initIndependentStat().registerStat(); + + /** times a world has been created */ + public static StatBase createWorldStat = (new StatBasic(1001, "stat.createWorld")).initIndependentStat() + .registerStat(); + + /** the number of times you have loaded a world */ + public static StatBase loadWorldStat = (new StatBasic(1002, "stat.loadWorld")).initIndependentStat().registerStat(); + + /** number of times you've joined a multiplayer world */ + public static StatBase joinMultiplayerStat = (new StatBasic(1003, "stat.joinMultiplayer")).initIndependentStat() + .registerStat(); + + /** number of times you've left a game */ + public static StatBase leaveGameStat = (new StatBasic(1004, "stat.leaveGame")).initIndependentStat().registerStat(); + + /** number of minutes you have played */ + public static StatBase minutesPlayedStat = (new StatBasic(1100, "stat.playOneMinute", StatBase.timeStatType)) + .initIndependentStat().registerStat(); + + /** distance you've walked */ + public static StatBase distanceWalkedStat = (new StatBasic(2000, "stat.walkOneCm", StatBase.distanceStatType)) + .initIndependentStat().registerStat(); + + /** distance you have swam */ + public static StatBase distanceSwumStat = (new StatBasic(2001, "stat.swimOneCm", StatBase.distanceStatType)) + .initIndependentStat().registerStat(); + + /** the distance you have fallen */ + public static StatBase distanceFallenStat = (new StatBasic(2002, "stat.fallOneCm", StatBase.distanceStatType)) + .initIndependentStat().registerStat(); + + /** the distance you've climbed */ + public static StatBase distanceClimbedStat = (new StatBasic(2003, "stat.climbOneCm", StatBase.distanceStatType)) + .initIndependentStat().registerStat(); + + /** the distance you've flown */ + public static StatBase distanceFlownStat = (new StatBasic(2004, "stat.flyOneCm", StatBase.distanceStatType)) + .initIndependentStat().registerStat(); + + /** the distance you've dived */ + public static StatBase distanceDoveStat = (new StatBasic(2005, "stat.diveOneCm", StatBase.distanceStatType)) + .initIndependentStat().registerStat(); + + /** the distance you've traveled by minecart */ + public static StatBase distanceByMinecartStat = (new StatBasic(2006, "stat.minecartOneCm", + StatBase.distanceStatType)).initIndependentStat().registerStat(); + + /** the distance you've traveled by boat */ + public static StatBase distanceByBoatStat = (new StatBasic(2007, "stat.boatOneCm", StatBase.distanceStatType)) + .initIndependentStat().registerStat(); + + /** the distance you've traveled by pig */ + public static StatBase distanceByPigStat = (new StatBasic(2008, "stat.pigOneCm", StatBase.distanceStatType)) + .initIndependentStat().registerStat(); + + /** the times you've jumped */ + public static StatBase jumpStat = (new StatBasic(2010, "stat.jump")).initIndependentStat().registerStat(); + + /** the distance you've dropped (or times you've fallen?) */ + public static StatBase dropStat = (new StatBasic(2011, "stat.drop")).initIndependentStat().registerStat(); + + /** the amount of damage you've dealt */ + public static StatBase damageDealtStat = (new StatBasic(2020, "stat.damageDealt")).registerStat(); + + /** the amount of damage you have taken */ + public static StatBase damageTakenStat = (new StatBasic(2021, "stat.damageTaken")).registerStat(); + + /** the number of times you have died */ + public static StatBase deathsStat = (new StatBasic(2022, "stat.deaths")).registerStat(); + + /** the number of mobs you have killed */ + public static StatBase mobKillsStat = (new StatBasic(2023, "stat.mobKills")).registerStat(); + + /** counts the number of times you've killed a player */ + public static StatBase playerKillsStat = (new StatBasic(2024, "stat.playerKills")).registerStat(); + public static StatBase fishCaughtStat = (new StatBasic(2025, "stat.fishCaught")).registerStat(); + public static StatBase[] mineBlockStatArray = initMinableStats("stat.mineBlock", 16777216); + + /** Tracks the number of items a given block or item has been crafted. */ + public static StatBase[] objectCraftStats; + + /** Tracks the number of times a given block or item has been used. */ + public static StatBase[] objectUseStats; + + /** Tracks the number of times a given block or item has been broken. */ + public static StatBase[] objectBreakStats; + private static boolean blockStatsInitialized; + private static boolean itemStatsInitialized; + + /** + * This method simply NOPs. It is presumably used to call the static + * constructors on server start. + */ + public static void nopInit() { + } + + /** + * Initializes statistic fields related to breakable items and blocks. + */ + public static void initBreakableStats() { + objectUseStats = initUsableStats(objectUseStats, "stat.useItem", 16908288, 0, 256); + objectBreakStats = initBreakStats(objectBreakStats, "stat.breakItem", 16973824, 0, 256); + blockStatsInitialized = true; + initCraftableStats(); + } + + public static void initStats() { + objectUseStats = initUsableStats(objectUseStats, "stat.useItem", 16908288, 256, 32000); + objectBreakStats = initBreakStats(objectBreakStats, "stat.breakItem", 16973824, 256, 32000); + itemStatsInitialized = true; + initCraftableStats(); + } + + /** + * Initializes statistics related to craftable items. Is only called after both + * block and item stats have been initialized. + */ + public static void initCraftableStats() { + if (blockStatsInitialized && itemStatsInitialized) { + HashSet var0 = new HashSet(); + Iterator var1 = CraftingManager.getInstance().getRecipeList().iterator(); + + while (var1.hasNext()) { + IRecipe var2 = (IRecipe) var1.next(); + + if (var2.getRecipeOutput() != null) { + var0.add(Integer.valueOf(var2.getRecipeOutput().itemID)); + } + } + + var1 = FurnaceRecipes.smelting().getSmeltingList().values().iterator(); + + while (var1.hasNext()) { + ItemStack var4 = (ItemStack) var1.next(); + var0.add(Integer.valueOf(var4.itemID)); + } + + objectCraftStats = new StatBase[32000]; + var1 = var0.iterator(); + + while (var1.hasNext()) { + Integer var5 = (Integer) var1.next(); + + if (Item.itemsList[var5.intValue()] != null) { + String var3 = StatCollector.translateToLocalFormatted("stat.craftItem", + new Object[] { Item.itemsList[var5.intValue()].getStatName() }); + objectCraftStats[var5 + .intValue()] = (new StatCrafting(16842752 + var5.intValue(), var3, var5.intValue())) + .registerStat(); + } + } + + replaceAllSimilarBlocks(objectCraftStats); + } + } + + /** + * Initializes statistic fields related to minable items and blocks. + */ + private static StatBase[] initMinableStats(String par0Str, int par1) { + StatBase[] var2 = new StatBase[256]; + + for (int var3 = 0; var3 < 256; ++var3) { + if (Block.blocksList[var3] != null && Block.blocksList[var3].getEnableStats()) { + String var4 = StatCollector.translateToLocalFormatted(par0Str, + new Object[] { Block.blocksList[var3].getLocalizedName() }); + var2[var3] = (new StatCrafting(par1 + var3, var4, var3)).registerStat(); + objectMineStats.add((StatCrafting) var2[var3]); + } + } + + replaceAllSimilarBlocks(var2); + return var2; + } + + /** + * Initializes statistic fields related to usable items and blocks. + */ + private static StatBase[] initUsableStats(StatBase[] par0ArrayOfStatBase, String par1Str, int par2, int par3, + int par4) { + if (par0ArrayOfStatBase == null) { + par0ArrayOfStatBase = new StatBase[32000]; + } + + for (int var5 = par3; var5 < par4; ++var5) { + if (Item.itemsList[var5] != null) { + String var6 = StatCollector.translateToLocalFormatted(par1Str, + new Object[] { Item.itemsList[var5].getStatName() }); + par0ArrayOfStatBase[var5] = (new StatCrafting(par2 + var5, var6, var5)).registerStat(); + + if (var5 >= 256) { + itemStats.add((StatCrafting) par0ArrayOfStatBase[var5]); + } + } + } + + replaceAllSimilarBlocks(par0ArrayOfStatBase); + return par0ArrayOfStatBase; + } + + private static StatBase[] initBreakStats(StatBase[] par0ArrayOfStatBase, String par1Str, int par2, int par3, + int par4) { + if (par0ArrayOfStatBase == null) { + par0ArrayOfStatBase = new StatBase[32000]; + } + + for (int var5 = par3; var5 < par4; ++var5) { + if (Item.itemsList[var5] != null && Item.itemsList[var5].isDamageable()) { + String var6 = StatCollector.translateToLocalFormatted(par1Str, + new Object[] { Item.itemsList[var5].getStatName() }); + par0ArrayOfStatBase[var5] = (new StatCrafting(par2 + var5, var6, var5)).registerStat(); + } + } + + replaceAllSimilarBlocks(par0ArrayOfStatBase); + return par0ArrayOfStatBase; + } + + /** + * Forces all dual blocks to count for each other on the stats list + */ + private static void replaceAllSimilarBlocks(StatBase[] par0ArrayOfStatBase) { + replaceSimilarBlocks(par0ArrayOfStatBase, Block.waterStill.blockID, Block.waterMoving.blockID); + replaceSimilarBlocks(par0ArrayOfStatBase, Block.lavaStill.blockID, Block.lavaStill.blockID); + replaceSimilarBlocks(par0ArrayOfStatBase, Block.pumpkinLantern.blockID, Block.pumpkin.blockID); + replaceSimilarBlocks(par0ArrayOfStatBase, Block.furnaceBurning.blockID, Block.furnaceIdle.blockID); + replaceSimilarBlocks(par0ArrayOfStatBase, Block.oreRedstoneGlowing.blockID, Block.oreRedstone.blockID); + replaceSimilarBlocks(par0ArrayOfStatBase, Block.redstoneRepeaterActive.blockID, + Block.redstoneRepeaterIdle.blockID); + replaceSimilarBlocks(par0ArrayOfStatBase, Block.torchRedstoneActive.blockID, Block.torchRedstoneIdle.blockID); + replaceSimilarBlocks(par0ArrayOfStatBase, Block.mushroomRed.blockID, Block.mushroomBrown.blockID); + replaceSimilarBlocks(par0ArrayOfStatBase, Block.stoneDoubleSlab.blockID, Block.stoneSingleSlab.blockID); + replaceSimilarBlocks(par0ArrayOfStatBase, Block.woodDoubleSlab.blockID, Block.woodSingleSlab.blockID); + replaceSimilarBlocks(par0ArrayOfStatBase, Block.grass.blockID, Block.dirt.blockID); + replaceSimilarBlocks(par0ArrayOfStatBase, Block.tilledField.blockID, Block.dirt.blockID); + } + + /** + * Forces stats for one block to add to another block, such as idle and active + * furnaces + */ + private static void replaceSimilarBlocks(StatBase[] par0ArrayOfStatBase, int par1, int par2) { + if (par0ArrayOfStatBase[par1] != null && par0ArrayOfStatBase[par2] == null) { + par0ArrayOfStatBase[par2] = par0ArrayOfStatBase[par1]; + } else { + allStats.remove(par0ArrayOfStatBase[par1]); + objectMineStats.remove(par0ArrayOfStatBase[par1]); + generalStats.remove(par0ArrayOfStatBase[par1]); + par0ArrayOfStatBase[par1] = par0ArrayOfStatBase[par2]; + } + } + + static { + AchievementList.init(); + blockStatsInitialized = false; + itemStatsInitialized = false; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/StatTypeDistance.java b/sp-server/src/main/java/net/minecraft/src/StatTypeDistance.java new file mode 100644 index 0000000..358662f --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/StatTypeDistance.java @@ -0,0 +1,4 @@ +package net.minecraft.src; + +final class StatTypeDistance implements IStatType { +} diff --git a/sp-server/src/main/java/net/minecraft/src/StatTypeSimple.java b/sp-server/src/main/java/net/minecraft/src/StatTypeSimple.java new file mode 100644 index 0000000..af05cbe --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/StatTypeSimple.java @@ -0,0 +1,4 @@ +package net.minecraft.src; + +final class StatTypeSimple implements IStatType { +} diff --git a/sp-server/src/main/java/net/minecraft/src/StatTypeTime.java b/sp-server/src/main/java/net/minecraft/src/StatTypeTime.java new file mode 100644 index 0000000..7d3c315 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/StatTypeTime.java @@ -0,0 +1,4 @@ +package net.minecraft.src; + +final class StatTypeTime implements IStatType { +} diff --git a/sp-server/src/main/java/net/minecraft/src/StepSound.java b/sp-server/src/main/java/net/minecraft/src/StepSound.java new file mode 100644 index 0000000..04de7b9 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/StepSound.java @@ -0,0 +1,42 @@ +package net.minecraft.src; + +public class StepSound { + public final String stepSoundName; + public final float stepSoundVolume; + public final float stepSoundPitch; + + public StepSound(String par1Str, float par2, float par3) { + this.stepSoundName = par1Str; + this.stepSoundVolume = par2; + this.stepSoundPitch = par3; + } + + public float getVolume() { + return this.stepSoundVolume; + } + + public float getPitch() { + return this.stepSoundPitch; + } + + /** + * Used when a block breaks, EXA: Player break, Shep eating grass, etc.. + */ + public String getBreakSound() { + return "dig." + this.stepSoundName; + } + + /** + * Used when a entity walks over, or otherwise interacts with the block. + */ + public String getStepSound() { + return "step." + this.stepSoundName; + } + + /** + * Used when a player places a block. + */ + public String getPlaceSound() { + return this.getBreakSound(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/StepSoundAnvil.java b/sp-server/src/main/java/net/minecraft/src/StepSoundAnvil.java new file mode 100644 index 0000000..21a4858 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/StepSoundAnvil.java @@ -0,0 +1,21 @@ +package net.minecraft.src; + +final class StepSoundAnvil extends StepSound { + StepSoundAnvil(String par1Str, float par2, float par3) { + super(par1Str, par2, par3); + } + + /** + * Used when a block breaks, EXA: Player break, Shep eating grass, etc.. + */ + public String getBreakSound() { + return "dig.stone"; + } + + /** + * Used when a player places a block. + */ + public String getPlaceSound() { + return "random.anvil_land"; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/StepSoundSand.java b/sp-server/src/main/java/net/minecraft/src/StepSoundSand.java new file mode 100644 index 0000000..fa7bab6 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/StepSoundSand.java @@ -0,0 +1,14 @@ +package net.minecraft.src; + +final class StepSoundSand extends StepSound { + StepSoundSand(String par1Str, float par2, float par3) { + super(par1Str, par2, par3); + } + + /** + * Used when a block breaks, EXA: Player break, Shep eating grass, etc.. + */ + public String getBreakSound() { + return "dig.wood"; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/StepSoundStone.java b/sp-server/src/main/java/net/minecraft/src/StepSoundStone.java new file mode 100644 index 0000000..cdbb8dc --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/StepSoundStone.java @@ -0,0 +1,21 @@ +package net.minecraft.src; + +final class StepSoundStone extends StepSound { + StepSoundStone(String par1Str, float par2, float par3) { + super(par1Str, par2, par3); + } + + /** + * Used when a block breaks, EXA: Player break, Shep eating grass, etc.. + */ + public String getBreakSound() { + return "random.glass"; + } + + /** + * Used when a player places a block. + */ + public String getPlaceSound() { + return "step.stone"; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/StringTranslate.java b/sp-server/src/main/java/net/minecraft/src/StringTranslate.java new file mode 100644 index 0000000..7e3996b --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/StringTranslate.java @@ -0,0 +1,166 @@ +package net.minecraft.src; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.Enumeration; +import java.util.IllegalFormatException; +import java.util.Properties; +import java.util.TreeMap; + +public class StringTranslate { + /** Is the private singleton instance of StringTranslate. */ + private static StringTranslate instance = new StringTranslate("en_US"); + + /** + * Contains all key/value pairs to be translated - is loaded from + * '/lang/en_US.lang' when the StringTranslate is created. + */ + private Properties translateTable = new Properties(); + private TreeMap languageList; + private TreeMap field_94521_d = new TreeMap(); + private String currentLanguage; + private boolean isUnicode; + + public StringTranslate(String par1Str) { + this.loadLanguageList(); + this.setLanguage(par1Str, false); + } + + /** + * Return the StringTranslate singleton instance + */ + public static StringTranslate getInstance() { + return instance; + } + + private void loadLanguageList() { + TreeMap var1 = new TreeMap(); + + try { + BufferedReader var2 = new BufferedReader( + new InputStreamReader(StringTranslate.class.getResourceAsStream("/lang/languages.txt"), "UTF-8")); + + for (String var3 = var2.readLine(); var3 != null; var3 = var2.readLine()) { + String[] var4 = var3.trim().split("="); + + if (var4 != null && var4.length == 2) { + var1.put(var4[0], var4[1]); + } + } + } catch (IOException var5) { + var5.printStackTrace(); + return; + } + + this.languageList = var1; + this.languageList.put("en_US", "English (US)"); + } + + public TreeMap getLanguageList() { + return this.languageList; + } + + private void loadLanguage(Properties par1Properties, String par2Str) throws IOException { + BufferedReader var3 = null; + + if (this.field_94521_d.containsKey(par2Str)) { + var3 = new BufferedReader(new FileReader((File) this.field_94521_d.get(par2Str))); + } else { + var3 = new BufferedReader(new InputStreamReader( + StringTranslate.class.getResourceAsStream("/lang/" + par2Str + ".lang"), "UTF-8")); + } + + for (String var4 = var3.readLine(); var4 != null; var4 = var3.readLine()) { + var4 = var4.trim(); + + if (!var4.startsWith("#")) { + String[] var5 = var4.split("="); + + if (var5 != null && var5.length == 2) { + par1Properties.setProperty(var5[0], var5[1]); + } + } + } + } + + public synchronized void setLanguage(String par1Str, boolean par2) { + if (par2 || !par1Str.equals(this.currentLanguage)) { + Properties var3 = new Properties(); + + try { + this.loadLanguage(var3, "en_US"); + } catch (IOException var9) { + ; + } + + this.isUnicode = false; + + if (!"en_US".equals(par1Str)) { + try { + this.loadLanguage(var3, par1Str); + Enumeration var4 = var3.propertyNames(); + + while (var4.hasMoreElements() && !this.isUnicode) { + Object var5 = var4.nextElement(); + Object var6 = var3.get(var5); + + if (var6 != null) { + String var7 = var6.toString(); + + for (int var8 = 0; var8 < var7.length(); ++var8) { + if (var7.charAt(var8) >= 256) { + this.isUnicode = true; + break; + } + } + } + } + } catch (IOException var10) { + var10.printStackTrace(); + return; + } + } + + this.currentLanguage = par1Str; + this.translateTable = var3; + } + } + + /** + * Translate a key to current language. + */ + public synchronized String translateKey(String par1Str) { + return this.translateTable.getProperty(par1Str, par1Str); + } + + /** + * Translate a key to current language applying String.format() + */ + public synchronized String translateKeyFormat(String par1Str, Object... par2ArrayOfObj) { + String var3 = this.translateTable.getProperty(par1Str, par1Str); + + try { + return String.format(var3, par2ArrayOfObj); + } catch (IllegalFormatException var5) { + return "Format error: " + var3; + } + } + + /** + * Returns true if the passed key is in the translation table. + */ + public synchronized boolean isKeyTranslated(String par1Str) { + return this.translateTable.containsKey(par1Str); + } + + /** + * Translate a key with a extra '.name' at end added, is used by blocks and + * items. + */ + public synchronized String translateNamedKey(String par1Str) { + return this.translateTable.getProperty(par1Str + ".name", ""); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/StringUtils.java b/sp-server/src/main/java/net/minecraft/src/StringUtils.java new file mode 100644 index 0000000..ece549e --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/StringUtils.java @@ -0,0 +1,11 @@ +package net.minecraft.src; + +import java.util.regex.Pattern; + +public class StringUtils { + private static final Pattern patternControlCode = Pattern.compile("(?i)\\u00A7[0-9A-FK-OR]"); + + public static String stripControlCodes(String par0Str) { + return patternControlCode.matcher(par0Str).replaceAll(""); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/StructureBoundingBox.java b/sp-server/src/main/java/net/minecraft/src/StructureBoundingBox.java new file mode 100644 index 0000000..bfdef33 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/StructureBoundingBox.java @@ -0,0 +1,174 @@ +package net.minecraft.src; + +public class StructureBoundingBox { + /** The first x coordinate of a bounding box. */ + public int minX; + + /** The first y coordinate of a bounding box. */ + public int minY; + + /** The first z coordinate of a bounding box. */ + public int minZ; + + /** The second x coordinate of a bounding box. */ + public int maxX; + + /** The second y coordinate of a bounding box. */ + public int maxY; + + /** The second z coordinate of a bounding box. */ + public int maxZ; + + public StructureBoundingBox() { + } + + /** + * returns a new StructureBoundingBox with MAX values + */ + public static StructureBoundingBox getNewBoundingBox() { + return new StructureBoundingBox(Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MIN_VALUE, + Integer.MIN_VALUE, Integer.MIN_VALUE); + } + + /** + * used to project a possible new component Bounding Box - to check if it would + * cut anything already spawned + */ + public static StructureBoundingBox getComponentToAddBoundingBox(int par0, int par1, int par2, int par3, int par4, + int par5, int par6, int par7, int par8, int par9) { + switch (par9) { + case 0: + return new StructureBoundingBox(par0 + par3, par1 + par4, par2 + par5, par0 + par6 - 1 + par3, + par1 + par7 - 1 + par4, par2 + par8 - 1 + par5); + + case 1: + return new StructureBoundingBox(par0 - par8 + 1 + par5, par1 + par4, par2 + par3, par0 + par5, + par1 + par7 - 1 + par4, par2 + par6 - 1 + par3); + + case 2: + return new StructureBoundingBox(par0 + par3, par1 + par4, par2 - par8 + 1 + par5, par0 + par6 - 1 + par3, + par1 + par7 - 1 + par4, par2 + par5); + + case 3: + return new StructureBoundingBox(par0 + par5, par1 + par4, par2 + par3, par0 + par8 - 1 + par5, + par1 + par7 - 1 + par4, par2 + par6 - 1 + par3); + + default: + return new StructureBoundingBox(par0 + par3, par1 + par4, par2 + par5, par0 + par6 - 1 + par3, + par1 + par7 - 1 + par4, par2 + par8 - 1 + par5); + } + } + + public StructureBoundingBox(StructureBoundingBox par1StructureBoundingBox) { + this.minX = par1StructureBoundingBox.minX; + this.minY = par1StructureBoundingBox.minY; + this.minZ = par1StructureBoundingBox.minZ; + this.maxX = par1StructureBoundingBox.maxX; + this.maxY = par1StructureBoundingBox.maxY; + this.maxZ = par1StructureBoundingBox.maxZ; + } + + public StructureBoundingBox(int par1, int par2, int par3, int par4, int par5, int par6) { + this.minX = par1; + this.minY = par2; + this.minZ = par3; + this.maxX = par4; + this.maxY = par5; + this.maxZ = par6; + } + + public StructureBoundingBox(int par1, int par2, int par3, int par4) { + this.minX = par1; + this.minZ = par2; + this.maxX = par3; + this.maxZ = par4; + this.minY = 1; + this.maxY = 512; + } + + /** + * Discover if bounding box can fit within the current bounding box object. + */ + public boolean intersectsWith(StructureBoundingBox par1StructureBoundingBox) { + return this.maxX >= par1StructureBoundingBox.minX && this.minX <= par1StructureBoundingBox.maxX + && this.maxZ >= par1StructureBoundingBox.minZ && this.minZ <= par1StructureBoundingBox.maxZ + && this.maxY >= par1StructureBoundingBox.minY && this.minY <= par1StructureBoundingBox.maxY; + } + + /** + * Discover if a coordinate is inside the bounding box area. + */ + public boolean intersectsWith(int par1, int par2, int par3, int par4) { + return this.maxX >= par1 && this.minX <= par3 && this.maxZ >= par2 && this.minZ <= par4; + } + + /** + * Expands a bounding box's dimensions to include the supplied bounding box. + */ + public void expandTo(StructureBoundingBox par1StructureBoundingBox) { + this.minX = Math.min(this.minX, par1StructureBoundingBox.minX); + this.minY = Math.min(this.minY, par1StructureBoundingBox.minY); + this.minZ = Math.min(this.minZ, par1StructureBoundingBox.minZ); + this.maxX = Math.max(this.maxX, par1StructureBoundingBox.maxX); + this.maxY = Math.max(this.maxY, par1StructureBoundingBox.maxY); + this.maxZ = Math.max(this.maxZ, par1StructureBoundingBox.maxZ); + } + + /** + * Offsets the current bounding box by the specified coordinates. Args: x, y, z + */ + public void offset(int par1, int par2, int par3) { + this.minX += par1; + this.minY += par2; + this.minZ += par3; + this.maxX += par1; + this.maxY += par2; + this.maxZ += par3; + } + + /** + * Discover if a coordinate is inside the bounding box volume. + */ + public boolean isVecInside(int par1, int par2, int par3) { + return par1 >= this.minX && par1 <= this.maxX && par3 >= this.minZ && par3 <= this.maxZ && par2 >= this.minY + && par2 <= this.maxY; + } + + /** + * Get dimension of the bounding box in the x direction. + */ + public int getXSize() { + return this.maxX - this.minX + 1; + } + + /** + * Get dimension of the bounding box in the y direction. + */ + public int getYSize() { + return this.maxY - this.minY + 1; + } + + /** + * Get dimension of the bounding box in the z direction. + */ + public int getZSize() { + return this.maxZ - this.minZ + 1; + } + + public int getCenterX() { + return this.minX + (this.maxX - this.minX + 1) / 2; + } + + public int getCenterY() { + return this.minY + (this.maxY - this.minY + 1) / 2; + } + + public int getCenterZ() { + return this.minZ + (this.maxZ - this.minZ + 1) / 2; + } + + public String toString() { + return "(" + this.minX + ", " + this.minY + ", " + this.minZ + "; " + this.maxX + ", " + this.maxY + ", " + + this.maxZ + ")"; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/StructureComponent.java b/sp-server/src/main/java/net/minecraft/src/StructureComponent.java new file mode 100644 index 0000000..246f2b0 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/StructureComponent.java @@ -0,0 +1,704 @@ +package net.minecraft.src; + +import java.util.Iterator; +import java.util.List; +import java.util.Random; + +public abstract class StructureComponent { + protected StructureBoundingBox boundingBox; + + /** switches the Coordinate System base off the Bounding Box */ + protected int coordBaseMode; + + /** The type ID of this component. */ + protected int componentType; + + protected StructureComponent(int par1) { + this.componentType = par1; + this.coordBaseMode = -1; + } + + /** + * Initiates construction of the Structure Component picked, at the current + * Location of StructGen + */ + public void buildComponent(StructureComponent par1StructureComponent, List par2List, Random par3Random) { + } + + /** + * second Part of Structure generating, this for example places Spiderwebs, Mob + * Spawners, it closes Mineshafts at the end, it adds Fences... + */ + public abstract boolean addComponentParts(World var1, Random var2, StructureBoundingBox var3); + + public StructureBoundingBox getBoundingBox() { + return this.boundingBox; + } + + /** + * Returns the component type ID of this component. + */ + public int getComponentType() { + return this.componentType; + } + + /** + * Discover if bounding box can fit within the current bounding box object. + */ + public static StructureComponent findIntersecting(List par0List, StructureBoundingBox par1StructureBoundingBox) { + Iterator var2 = par0List.iterator(); + StructureComponent var3; + + do { + if (!var2.hasNext()) { + return null; + } + + var3 = (StructureComponent) var2.next(); + } while (var3.getBoundingBox() == null || !var3.getBoundingBox().intersectsWith(par1StructureBoundingBox)); + + return var3; + } + + public ChunkPosition getCenter() { + return new ChunkPosition(this.boundingBox.getCenterX(), this.boundingBox.getCenterY(), + this.boundingBox.getCenterZ()); + } + + /** + * checks the entire StructureBoundingBox for Liquids + */ + protected boolean isLiquidInStructureBoundingBox(World par1World, StructureBoundingBox par2StructureBoundingBox) { + int var3 = Math.max(this.boundingBox.minX - 1, par2StructureBoundingBox.minX); + int var4 = Math.max(this.boundingBox.minY - 1, par2StructureBoundingBox.minY); + int var5 = Math.max(this.boundingBox.minZ - 1, par2StructureBoundingBox.minZ); + int var6 = Math.min(this.boundingBox.maxX + 1, par2StructureBoundingBox.maxX); + int var7 = Math.min(this.boundingBox.maxY + 1, par2StructureBoundingBox.maxY); + int var8 = Math.min(this.boundingBox.maxZ + 1, par2StructureBoundingBox.maxZ); + int var9; + int var10; + int var11; + + for (var9 = var3; var9 <= var6; ++var9) { + for (var10 = var5; var10 <= var8; ++var10) { + var11 = par1World.getBlockId(var9, var4, var10); + + if (var11 > 0 && Block.blocksList[var11].blockMaterial.isLiquid()) { + return true; + } + + var11 = par1World.getBlockId(var9, var7, var10); + + if (var11 > 0 && Block.blocksList[var11].blockMaterial.isLiquid()) { + return true; + } + } + } + + for (var9 = var3; var9 <= var6; ++var9) { + for (var10 = var4; var10 <= var7; ++var10) { + var11 = par1World.getBlockId(var9, var10, var5); + + if (var11 > 0 && Block.blocksList[var11].blockMaterial.isLiquid()) { + return true; + } + + var11 = par1World.getBlockId(var9, var10, var8); + + if (var11 > 0 && Block.blocksList[var11].blockMaterial.isLiquid()) { + return true; + } + } + } + + for (var9 = var5; var9 <= var8; ++var9) { + for (var10 = var4; var10 <= var7; ++var10) { + var11 = par1World.getBlockId(var3, var10, var9); + + if (var11 > 0 && Block.blocksList[var11].blockMaterial.isLiquid()) { + return true; + } + + var11 = par1World.getBlockId(var6, var10, var9); + + if (var11 > 0 && Block.blocksList[var11].blockMaterial.isLiquid()) { + return true; + } + } + } + + return false; + } + + protected int getXWithOffset(int par1, int par2) { + switch (this.coordBaseMode) { + case 0: + case 2: + return this.boundingBox.minX + par1; + + case 1: + return this.boundingBox.maxX - par2; + + case 3: + return this.boundingBox.minX + par2; + + default: + return par1; + } + } + + protected int getYWithOffset(int par1) { + return this.coordBaseMode == -1 ? par1 : par1 + this.boundingBox.minY; + } + + protected int getZWithOffset(int par1, int par2) { + switch (this.coordBaseMode) { + case 0: + return this.boundingBox.minZ + par2; + + case 1: + case 3: + return this.boundingBox.minZ + par1; + + case 2: + return this.boundingBox.maxZ - par2; + + default: + return par2; + } + } + + /** + * Returns the direction-shifted metadata for blocks that require orientation, + * e.g. doors, stairs, ladders. Parameters: block ID, original metadata + */ + protected int getMetadataWithOffset(int par1, int par2) { + if (par1 == Block.rail.blockID) { + if (this.coordBaseMode == 1 || this.coordBaseMode == 3) { + if (par2 == 1) { + return 0; + } + + return 1; + } + } else if (par1 != Block.doorWood.blockID && par1 != Block.doorIron.blockID) { + if (par1 != Block.stairsCobblestone.blockID && par1 != Block.stairsWoodOak.blockID + && par1 != Block.stairsNetherBrick.blockID && par1 != Block.stairsStoneBrick.blockID + && par1 != Block.stairsSandStone.blockID) { + if (par1 == Block.ladder.blockID) { + if (this.coordBaseMode == 0) { + if (par2 == 2) { + return 3; + } + + if (par2 == 3) { + return 2; + } + } else if (this.coordBaseMode == 1) { + if (par2 == 2) { + return 4; + } + + if (par2 == 3) { + return 5; + } + + if (par2 == 4) { + return 2; + } + + if (par2 == 5) { + return 3; + } + } else if (this.coordBaseMode == 3) { + if (par2 == 2) { + return 5; + } + + if (par2 == 3) { + return 4; + } + + if (par2 == 4) { + return 2; + } + + if (par2 == 5) { + return 3; + } + } + } else if (par1 == Block.stoneButton.blockID) { + if (this.coordBaseMode == 0) { + if (par2 == 3) { + return 4; + } + + if (par2 == 4) { + return 3; + } + } else if (this.coordBaseMode == 1) { + if (par2 == 3) { + return 1; + } + + if (par2 == 4) { + return 2; + } + + if (par2 == 2) { + return 3; + } + + if (par2 == 1) { + return 4; + } + } else if (this.coordBaseMode == 3) { + if (par2 == 3) { + return 2; + } + + if (par2 == 4) { + return 1; + } + + if (par2 == 2) { + return 3; + } + + if (par2 == 1) { + return 4; + } + } + } else if (par1 != Block.tripWireSource.blockID + && (Block.blocksList[par1] == null || !(Block.blocksList[par1] instanceof BlockDirectional))) { + if (par1 == Block.pistonBase.blockID || par1 == Block.pistonStickyBase.blockID + || par1 == Block.lever.blockID || par1 == Block.dispenser.blockID) { + if (this.coordBaseMode == 0) { + if (par2 == 2 || par2 == 3) { + return Facing.oppositeSide[par2]; + } + } else if (this.coordBaseMode == 1) { + if (par2 == 2) { + return 4; + } + + if (par2 == 3) { + return 5; + } + + if (par2 == 4) { + return 2; + } + + if (par2 == 5) { + return 3; + } + } else if (this.coordBaseMode == 3) { + if (par2 == 2) { + return 5; + } + + if (par2 == 3) { + return 4; + } + + if (par2 == 4) { + return 2; + } + + if (par2 == 5) { + return 3; + } + } + } + } else if (this.coordBaseMode == 0) { + if (par2 == 0 || par2 == 2) { + return Direction.footInvisibleFaceRemap[par2]; + } + } else if (this.coordBaseMode == 1) { + if (par2 == 2) { + return 1; + } + + if (par2 == 0) { + return 3; + } + + if (par2 == 1) { + return 2; + } + + if (par2 == 3) { + return 0; + } + } else if (this.coordBaseMode == 3) { + if (par2 == 2) { + return 3; + } + + if (par2 == 0) { + return 1; + } + + if (par2 == 1) { + return 2; + } + + if (par2 == 3) { + return 0; + } + } + } else if (this.coordBaseMode == 0) { + if (par2 == 2) { + return 3; + } + + if (par2 == 3) { + return 2; + } + } else if (this.coordBaseMode == 1) { + if (par2 == 0) { + return 2; + } + + if (par2 == 1) { + return 3; + } + + if (par2 == 2) { + return 0; + } + + if (par2 == 3) { + return 1; + } + } else if (this.coordBaseMode == 3) { + if (par2 == 0) { + return 2; + } + + if (par2 == 1) { + return 3; + } + + if (par2 == 2) { + return 1; + } + + if (par2 == 3) { + return 0; + } + } + } else if (this.coordBaseMode == 0) { + if (par2 == 0) { + return 2; + } + + if (par2 == 2) { + return 0; + } + } else { + if (this.coordBaseMode == 1) { + return par2 + 1 & 3; + } + + if (this.coordBaseMode == 3) { + return par2 + 3 & 3; + } + } + + return par2; + } + + /** + * current Position depends on currently set Coordinates mode, is computed here + */ + protected void placeBlockAtCurrentPosition(World par1World, int par2, int par3, int par4, int par5, int par6, + StructureBoundingBox par7StructureBoundingBox) { + int var8 = this.getXWithOffset(par4, par6); + int var9 = this.getYWithOffset(par5); + int var10 = this.getZWithOffset(par4, par6); + + if (par7StructureBoundingBox.isVecInside(var8, var9, var10)) { + par1World.setBlock(var8, var9, var10, par2, par3, 2); + } + } + + protected int getBlockIdAtCurrentPosition(World par1World, int par2, int par3, int par4, + StructureBoundingBox par5StructureBoundingBox) { + int var6 = this.getXWithOffset(par2, par4); + int var7 = this.getYWithOffset(par3); + int var8 = this.getZWithOffset(par2, par4); + return !par5StructureBoundingBox.isVecInside(var6, var7, var8) ? 0 : par1World.getBlockId(var6, var7, var8); + } + + /** + * arguments: (World worldObj, StructureBoundingBox structBB, int minX, int + * minY, int minZ, int maxX, int maxY, int maxZ) + */ + protected void fillWithAir(World par1World, StructureBoundingBox par2StructureBoundingBox, int par3, int par4, + int par5, int par6, int par7, int par8) { + for (int var9 = par4; var9 <= par7; ++var9) { + for (int var10 = par3; var10 <= par6; ++var10) { + for (int var11 = par5; var11 <= par8; ++var11) { + this.placeBlockAtCurrentPosition(par1World, 0, 0, var10, var9, var11, par2StructureBoundingBox); + } + } + } + } + + /** + * arguments: (World worldObj, StructureBoundingBox structBB, int minX, int + * minY, int minZ, int maxX, int maxY, int maxZ, int placeBlockId, int + * replaceBlockId, boolean alwaysreplace) + */ + protected void fillWithBlocks(World par1World, StructureBoundingBox par2StructureBoundingBox, int par3, int par4, + int par5, int par6, int par7, int par8, int par9, int par10, boolean par11) { + for (int var12 = par4; var12 <= par7; ++var12) { + for (int var13 = par3; var13 <= par6; ++var13) { + for (int var14 = par5; var14 <= par8; ++var14) { + if (!par11 || this.getBlockIdAtCurrentPosition(par1World, var13, var12, var14, + par2StructureBoundingBox) != 0) { + if (var12 != par4 && var12 != par7 && var13 != par3 && var13 != par6 && var14 != par5 + && var14 != par8) { + this.placeBlockAtCurrentPosition(par1World, par10, 0, var13, var12, var14, + par2StructureBoundingBox); + } else { + this.placeBlockAtCurrentPosition(par1World, par9, 0, var13, var12, var14, + par2StructureBoundingBox); + } + } + } + } + } + } + + /** + * arguments: (World worldObj, StructureBoundingBox structBB, int minX, int + * minY, int minZ, int maxX, int maxY, int maxZ, int placeBlockId, int + * placeBlockMetadata, int replaceBlockId, int replaceBlockMetadata, boolean + * alwaysreplace) + */ + protected void fillWithMetadataBlocks(World par1World, StructureBoundingBox par2StructureBoundingBox, int par3, + int par4, int par5, int par6, int par7, int par8, int par9, int par10, int par11, int par12, + boolean par13) { + for (int var14 = par4; var14 <= par7; ++var14) { + for (int var15 = par3; var15 <= par6; ++var15) { + for (int var16 = par5; var16 <= par8; ++var16) { + if (!par13 || this.getBlockIdAtCurrentPosition(par1World, var15, var14, var16, + par2StructureBoundingBox) != 0) { + if (var14 != par4 && var14 != par7 && var15 != par3 && var15 != par6 && var16 != par5 + && var16 != par8) { + this.placeBlockAtCurrentPosition(par1World, par11, par12, var15, var14, var16, + par2StructureBoundingBox); + } else { + this.placeBlockAtCurrentPosition(par1World, par9, par10, var15, var14, var16, + par2StructureBoundingBox); + } + } + } + } + } + } + + /** + * arguments: World worldObj, StructureBoundingBox structBB, int minX, int minY, + * int minZ, int maxX, int maxY, int maxZ, boolean alwaysreplace, Random rand, + * StructurePieceBlockSelector blockselector + */ + protected void fillWithRandomizedBlocks(World par1World, StructureBoundingBox par2StructureBoundingBox, int par3, + int par4, int par5, int par6, int par7, int par8, boolean par9, Random par10Random, + StructurePieceBlockSelector par11StructurePieceBlockSelector) { + for (int var12 = par4; var12 <= par7; ++var12) { + for (int var13 = par3; var13 <= par6; ++var13) { + for (int var14 = par5; var14 <= par8; ++var14) { + if (!par9 || this.getBlockIdAtCurrentPosition(par1World, var13, var12, var14, + par2StructureBoundingBox) != 0) { + par11StructurePieceBlockSelector.selectBlocks(par10Random, var13, var12, var14, var12 == par4 + || var12 == par7 || var13 == par3 || var13 == par6 || var14 == par5 || var14 == par8); + this.placeBlockAtCurrentPosition(par1World, + par11StructurePieceBlockSelector.getSelectedBlockId(), + par11StructurePieceBlockSelector.getSelectedBlockMetaData(), var13, var12, var14, + par2StructureBoundingBox); + } + } + } + } + } + + /** + * arguments: World worldObj, StructureBoundingBox structBB, Random rand, float + * randLimit, int minX, int minY, int minZ, int maxX, int maxY, int maxZ, int + * olaceBlockId, int replaceBlockId, boolean alwaysreplace + */ + protected void randomlyFillWithBlocks(World par1World, StructureBoundingBox par2StructureBoundingBox, + Random par3Random, float par4, int par5, int par6, int par7, int par8, int par9, int par10, int par11, + int par12, boolean par13) { + for (int var14 = par6; var14 <= par9; ++var14) { + for (int var15 = par5; var15 <= par8; ++var15) { + for (int var16 = par7; var16 <= par10; ++var16) { + if (par3Random.nextFloat() <= par4 && (!par13 || this.getBlockIdAtCurrentPosition(par1World, var15, + var14, var16, par2StructureBoundingBox) != 0)) { + if (var14 != par6 && var14 != par9 && var15 != par5 && var15 != par8 && var16 != par7 + && var16 != par10) { + this.placeBlockAtCurrentPosition(par1World, par12, 0, var15, var14, var16, + par2StructureBoundingBox); + } else { + this.placeBlockAtCurrentPosition(par1World, par11, 0, var15, var14, var16, + par2StructureBoundingBox); + } + } + } + } + } + } + + /** + * Randomly decides if placing or not. Used for Decoration such as Torches and + * Spiderwebs + */ + protected void randomlyPlaceBlock(World par1World, StructureBoundingBox par2StructureBoundingBox, Random par3Random, + float par4, int par5, int par6, int par7, int par8, int par9) { + if (par3Random.nextFloat() < par4) { + this.placeBlockAtCurrentPosition(par1World, par8, par9, par5, par6, par7, par2StructureBoundingBox); + } + } + + /** + * arguments: World worldObj, StructureBoundingBox structBB, int minX, int minY, + * int minZ, int maxX, int maxY, int maxZ, int placeBlockId, boolean + * alwaysreplace + */ + protected void randomlyRareFillWithBlocks(World par1World, StructureBoundingBox par2StructureBoundingBox, int par3, + int par4, int par5, int par6, int par7, int par8, int par9, boolean par10) { + float var11 = (float) (par6 - par3 + 1); + float var12 = (float) (par7 - par4 + 1); + float var13 = (float) (par8 - par5 + 1); + float var14 = (float) par3 + var11 / 2.0F; + float var15 = (float) par5 + var13 / 2.0F; + + for (int var16 = par4; var16 <= par7; ++var16) { + float var17 = (float) (var16 - par4) / var12; + + for (int var18 = par3; var18 <= par6; ++var18) { + float var19 = ((float) var18 - var14) / (var11 * 0.5F); + + for (int var20 = par5; var20 <= par8; ++var20) { + float var21 = ((float) var20 - var15) / (var13 * 0.5F); + + if (!par10 || this.getBlockIdAtCurrentPosition(par1World, var18, var16, var20, + par2StructureBoundingBox) != 0) { + float var22 = var19 * var19 + var17 * var17 + var21 * var21; + + if (var22 <= 1.05F) { + this.placeBlockAtCurrentPosition(par1World, par9, 0, var18, var16, var20, + par2StructureBoundingBox); + } + } + } + } + } + } + + /** + * Deletes all continuous blocks from selected position upwards. Stops at + * hitting air. + */ + protected void clearCurrentPositionBlocksUpwards(World par1World, int par2, int par3, int par4, + StructureBoundingBox par5StructureBoundingBox) { + int var6 = this.getXWithOffset(par2, par4); + int var7 = this.getYWithOffset(par3); + int var8 = this.getZWithOffset(par2, par4); + + if (par5StructureBoundingBox.isVecInside(var6, var7, var8)) { + while (!par1World.isAirBlock(var6, var7, var8) && var7 < 255) { + par1World.setBlock(var6, var7, var8, 0, 0, 2); + ++var7; + } + } + } + + /** + * Overwrites air and liquids from selected position downwards, stops at hitting + * anything else. + */ + protected void fillCurrentPositionBlocksDownwards(World par1World, int par2, int par3, int par4, int par5, int par6, + StructureBoundingBox par7StructureBoundingBox) { + int var8 = this.getXWithOffset(par4, par6); + int var9 = this.getYWithOffset(par5); + int var10 = this.getZWithOffset(par4, par6); + + if (par7StructureBoundingBox.isVecInside(var8, var9, var10)) { + while ((par1World.isAirBlock(var8, var9, var10) || par1World.getBlockMaterial(var8, var9, var10).isLiquid()) + && var9 > 1) { + par1World.setBlock(var8, var9, var10, par2, par3, 2); + --var9; + } + } + } + + /** + * Used to generate chests with items in it. ex: Temple Chests, Village + * Blacksmith Chests, Mineshaft Chests. + */ + protected boolean generateStructureChestContents(World par1World, StructureBoundingBox par2StructureBoundingBox, + Random par3Random, int par4, int par5, int par6, + WeightedRandomChestContent[] par7ArrayOfWeightedRandomChestContent, int par8) { + int var9 = this.getXWithOffset(par4, par6); + int var10 = this.getYWithOffset(par5); + int var11 = this.getZWithOffset(par4, par6); + + if (par2StructureBoundingBox.isVecInside(var9, var10, var11) + && par1World.getBlockId(var9, var10, var11) != Block.chest.blockID) { + par1World.setBlock(var9, var10, var11, Block.chest.blockID, 0, 2); + TileEntityChest var12 = (TileEntityChest) par1World.getBlockTileEntity(var9, var10, var11); + + if (var12 != null) { + WeightedRandomChestContent.generateChestContents(par3Random, par7ArrayOfWeightedRandomChestContent, + var12, par8); + } + + return true; + } else { + return false; + } + } + + /** + * Used to generate dispenser contents for structures. ex: Jungle Temples. + */ + protected boolean generateStructureDispenserContents(World par1World, StructureBoundingBox par2StructureBoundingBox, + Random par3Random, int par4, int par5, int par6, int par7, + WeightedRandomChestContent[] par8ArrayOfWeightedRandomChestContent, int par9) { + int var10 = this.getXWithOffset(par4, par6); + int var11 = this.getYWithOffset(par5); + int var12 = this.getZWithOffset(par4, par6); + + if (par2StructureBoundingBox.isVecInside(var10, var11, var12) + && par1World.getBlockId(var10, var11, var12) != Block.dispenser.blockID) { + par1World.setBlock(var10, var11, var12, Block.dispenser.blockID, + this.getMetadataWithOffset(Block.dispenser.blockID, par7), 2); + TileEntityDispenser var13 = (TileEntityDispenser) par1World.getBlockTileEntity(var10, var11, var12); + + if (var13 != null) { + WeightedRandomChestContent.generateDispenserContents(par3Random, par8ArrayOfWeightedRandomChestContent, + var13, par9); + } + + return true; + } else { + return false; + } + } + + protected void placeDoorAtCurrentPosition(World par1World, StructureBoundingBox par2StructureBoundingBox, + Random par3Random, int par4, int par5, int par6, int par7) { + int var8 = this.getXWithOffset(par4, par6); + int var9 = this.getYWithOffset(par5); + int var10 = this.getZWithOffset(par4, par6); + + if (par2StructureBoundingBox.isVecInside(var8, var9, var10)) { + ItemDoor.placeDoorBlock(par1World, var8, var9, var10, par7, Block.doorWood); + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/StructureMineshaftPieces.java b/sp-server/src/main/java/net/minecraft/src/StructureMineshaftPieces.java new file mode 100644 index 0000000..fb9e351 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/StructureMineshaftPieces.java @@ -0,0 +1,76 @@ +package net.minecraft.src; + +import java.util.List; +import java.util.Random; + +public class StructureMineshaftPieces { + /** List of contents that can generate in Mineshafts. */ + private static final WeightedRandomChestContent[] mineshaftChestContents = new WeightedRandomChestContent[] { + new WeightedRandomChestContent(Item.ingotIron.itemID, 0, 1, 5, 10), + new WeightedRandomChestContent(Item.ingotGold.itemID, 0, 1, 3, 5), + new WeightedRandomChestContent(Item.redstone.itemID, 0, 4, 9, 5), + new WeightedRandomChestContent(Item.dyePowder.itemID, 4, 4, 9, 5), + new WeightedRandomChestContent(Item.diamond.itemID, 0, 1, 2, 3), + new WeightedRandomChestContent(Item.coal.itemID, 0, 3, 8, 10), + new WeightedRandomChestContent(Item.bread.itemID, 0, 1, 3, 15), + new WeightedRandomChestContent(Item.pickaxeIron.itemID, 0, 1, 1, 1), + new WeightedRandomChestContent(Block.rail.blockID, 0, 4, 8, 1), + new WeightedRandomChestContent(Item.melonSeeds.itemID, 0, 2, 4, 10), + new WeightedRandomChestContent(Item.pumpkinSeeds.itemID, 0, 2, 4, 10) }; + + private static StructureComponent getRandomComponent(List par0List, Random par1Random, int par2, int par3, int par4, + int par5, int par6) { + int var7 = par1Random.nextInt(100); + StructureBoundingBox var8; + + if (var7 >= 80) { + var8 = ComponentMineshaftCross.findValidPlacement(par0List, par1Random, par2, par3, par4, par5); + + if (var8 != null) { + return new ComponentMineshaftCross(par6, par1Random, var8, par5); + } + } else if (var7 >= 70) { + var8 = ComponentMineshaftStairs.findValidPlacement(par0List, par1Random, par2, par3, par4, par5); + + if (var8 != null) { + return new ComponentMineshaftStairs(par6, par1Random, var8, par5); + } + } else { + var8 = ComponentMineshaftCorridor.findValidPlacement(par0List, par1Random, par2, par3, par4, par5); + + if (var8 != null) { + return new ComponentMineshaftCorridor(par6, par1Random, var8, par5); + } + } + + return null; + } + + private static StructureComponent getNextMineShaftComponent(StructureComponent par0StructureComponent, + List par1List, Random par2Random, int par3, int par4, int par5, int par6, int par7) { + if (par7 > 8) { + return null; + } else if (Math.abs(par3 - par0StructureComponent.getBoundingBox().minX) <= 80 + && Math.abs(par5 - par0StructureComponent.getBoundingBox().minZ) <= 80) { + StructureComponent var8 = getRandomComponent(par1List, par2Random, par3, par4, par5, par6, par7 + 1); + + if (var8 != null) { + par1List.add(var8); + var8.buildComponent(par0StructureComponent, par1List, par2Random); + } + + return var8; + } else { + return null; + } + } + + static StructureComponent getNextComponent(StructureComponent par0StructureComponent, List par1List, + Random par2Random, int par3, int par4, int par5, int par6, int par7) { + return getNextMineShaftComponent(par0StructureComponent, par1List, par2Random, par3, par4, par5, par6, par7); + } + + static WeightedRandomChestContent[] func_78816_a() { + return mineshaftChestContents; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/StructureMineshaftStart.java b/sp-server/src/main/java/net/minecraft/src/StructureMineshaftStart.java new file mode 100644 index 0000000..1dbd18a --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/StructureMineshaftStart.java @@ -0,0 +1,13 @@ +package net.minecraft.src; + +import java.util.Random; + +public class StructureMineshaftStart extends StructureStart { + public StructureMineshaftStart(World par1World, Random par2Random, int par3, int par4) { + ComponentMineshaftRoom var5 = new ComponentMineshaftRoom(0, par2Random, (par3 << 4) + 2, (par4 << 4) + 2); + this.components.add(var5); + var5.buildComponent(var5, this.components, par2Random); + this.updateBoundingBox(); + this.markAvailableHeight(par1World, par2Random, 10); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/StructureNetherBridgePieceWeight.java b/sp-server/src/main/java/net/minecraft/src/StructureNetherBridgePieceWeight.java new file mode 100644 index 0000000..1f541d1 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/StructureNetherBridgePieceWeight.java @@ -0,0 +1,29 @@ +package net.minecraft.src; + +class StructureNetherBridgePieceWeight { + /** The class of the StructureComponent to which this weight corresponds. */ + public Class weightClass; + public final int field_78826_b; + public int field_78827_c; + public int field_78824_d; + public boolean field_78825_e; + + public StructureNetherBridgePieceWeight(Class par1Class, int par2, int par3, boolean par4) { + this.weightClass = par1Class; + this.field_78826_b = par2; + this.field_78824_d = par3; + this.field_78825_e = par4; + } + + public StructureNetherBridgePieceWeight(Class par1Class, int par2, int par3) { + this(par1Class, par2, par3, false); + } + + public boolean func_78822_a(int par1) { + return this.field_78824_d == 0 || this.field_78827_c < this.field_78824_d; + } + + public boolean func_78823_a() { + return this.field_78824_d == 0 || this.field_78827_c < this.field_78824_d; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/StructureNetherBridgePieces.java b/sp-server/src/main/java/net/minecraft/src/StructureNetherBridgePieces.java new file mode 100644 index 0000000..48618ce --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/StructureNetherBridgePieces.java @@ -0,0 +1,85 @@ +package net.minecraft.src; + +import java.util.List; +import java.util.Random; + +public class StructureNetherBridgePieces { + private static final StructureNetherBridgePieceWeight[] primaryComponents = new StructureNetherBridgePieceWeight[] { + new StructureNetherBridgePieceWeight(ComponentNetherBridgeStraight.class, 30, 0, true), + new StructureNetherBridgePieceWeight(ComponentNetherBridgeCrossing3.class, 10, 4), + new StructureNetherBridgePieceWeight(ComponentNetherBridgeCrossing.class, 10, 4), + new StructureNetherBridgePieceWeight(ComponentNetherBridgeStairs.class, 10, 3), + new StructureNetherBridgePieceWeight(ComponentNetherBridgeThrone.class, 5, 2), + new StructureNetherBridgePieceWeight(ComponentNetherBridgeEntrance.class, 5, 1) }; + private static final StructureNetherBridgePieceWeight[] secondaryComponents = new StructureNetherBridgePieceWeight[] { + new StructureNetherBridgePieceWeight(ComponentNetherBridgeCorridor5.class, 25, 0, true), + new StructureNetherBridgePieceWeight(ComponentNetherBridgeCrossing2.class, 15, 5), + new StructureNetherBridgePieceWeight(ComponentNetherBridgeCorridor2.class, 5, 10), + new StructureNetherBridgePieceWeight(ComponentNetherBridgeCorridor.class, 5, 10), + new StructureNetherBridgePieceWeight(ComponentNetherBridgeCorridor3.class, 10, 3, true), + new StructureNetherBridgePieceWeight(ComponentNetherBridgeCorridor4.class, 7, 2), + new StructureNetherBridgePieceWeight(ComponentNetherBridgeNetherStalkRoom.class, 5, 2) }; + + private static ComponentNetherBridgePiece createNextComponentRandom( + StructureNetherBridgePieceWeight par0StructureNetherBridgePieceWeight, List par1List, Random par2Random, + int par3, int par4, int par5, int par6, int par7) { + Class var8 = par0StructureNetherBridgePieceWeight.weightClass; + Object var9 = null; + + if (var8 == ComponentNetherBridgeStraight.class) { + var9 = ComponentNetherBridgeStraight.createValidComponent(par1List, par2Random, par3, par4, par5, par6, + par7); + } else if (var8 == ComponentNetherBridgeCrossing3.class) { + var9 = ComponentNetherBridgeCrossing3.createValidComponent(par1List, par2Random, par3, par4, par5, par6, + par7); + } else if (var8 == ComponentNetherBridgeCrossing.class) { + var9 = ComponentNetherBridgeCrossing.createValidComponent(par1List, par2Random, par3, par4, par5, par6, + par7); + } else if (var8 == ComponentNetherBridgeStairs.class) { + var9 = ComponentNetherBridgeStairs.createValidComponent(par1List, par2Random, par3, par4, par5, par6, par7); + } else if (var8 == ComponentNetherBridgeThrone.class) { + var9 = ComponentNetherBridgeThrone.createValidComponent(par1List, par2Random, par3, par4, par5, par6, par7); + } else if (var8 == ComponentNetherBridgeEntrance.class) { + var9 = ComponentNetherBridgeEntrance.createValidComponent(par1List, par2Random, par3, par4, par5, par6, + par7); + } else if (var8 == ComponentNetherBridgeCorridor5.class) { + var9 = ComponentNetherBridgeCorridor5.createValidComponent(par1List, par2Random, par3, par4, par5, par6, + par7); + } else if (var8 == ComponentNetherBridgeCorridor2.class) { + var9 = ComponentNetherBridgeCorridor2.createValidComponent(par1List, par2Random, par3, par4, par5, par6, + par7); + } else if (var8 == ComponentNetherBridgeCorridor.class) { + var9 = ComponentNetherBridgeCorridor.createValidComponent(par1List, par2Random, par3, par4, par5, par6, + par7); + } else if (var8 == ComponentNetherBridgeCorridor3.class) { + var9 = ComponentNetherBridgeCorridor3.createValidComponent(par1List, par2Random, par3, par4, par5, par6, + par7); + } else if (var8 == ComponentNetherBridgeCorridor4.class) { + var9 = ComponentNetherBridgeCorridor4.createValidComponent(par1List, par2Random, par3, par4, par5, par6, + par7); + } else if (var8 == ComponentNetherBridgeCrossing2.class) { + var9 = ComponentNetherBridgeCrossing2.createValidComponent(par1List, par2Random, par3, par4, par5, par6, + par7); + } else if (var8 == ComponentNetherBridgeNetherStalkRoom.class) { + var9 = ComponentNetherBridgeNetherStalkRoom.createValidComponent(par1List, par2Random, par3, par4, par5, + par6, par7); + } + + return (ComponentNetherBridgePiece) var9; + } + + static ComponentNetherBridgePiece createNextComponent( + StructureNetherBridgePieceWeight par0StructureNetherBridgePieceWeight, List par1List, Random par2Random, + int par3, int par4, int par5, int par6, int par7) { + return createNextComponentRandom(par0StructureNetherBridgePieceWeight, par1List, par2Random, par3, par4, par5, + par6, par7); + } + + static StructureNetherBridgePieceWeight[] getPrimaryComponents() { + return primaryComponents; + } + + static StructureNetherBridgePieceWeight[] getSecondaryComponents() { + return secondaryComponents; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/StructureNetherBridgeStart.java b/sp-server/src/main/java/net/minecraft/src/StructureNetherBridgeStart.java new file mode 100644 index 0000000..f879df2 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/StructureNetherBridgeStart.java @@ -0,0 +1,23 @@ +package net.minecraft.src; + +import java.util.ArrayList; +import java.util.Random; + +class StructureNetherBridgeStart extends StructureStart { + public StructureNetherBridgeStart(World par1World, Random par2Random, int par3, int par4) { + ComponentNetherBridgeStartPiece var5 = new ComponentNetherBridgeStartPiece(par2Random, (par3 << 4) + 2, + (par4 << 4) + 2); + this.components.add(var5); + var5.buildComponent(var5, this.components, par2Random); + ArrayList var6 = var5.field_74967_d; + + while (!var6.isEmpty()) { + int var7 = par2Random.nextInt(var6.size()); + StructureComponent var8 = (StructureComponent) var6.remove(var7); + var8.buildComponent(var5, this.components, par2Random); + } + + this.updateBoundingBox(); + this.setRandomHeight(par1World, par2Random, 48, 70); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/StructurePieceBlockSelector.java b/sp-server/src/main/java/net/minecraft/src/StructurePieceBlockSelector.java new file mode 100644 index 0000000..edb6d4c --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/StructurePieceBlockSelector.java @@ -0,0 +1,21 @@ +package net.minecraft.src; + +import java.util.Random; + +public abstract class StructurePieceBlockSelector { + protected int selectedBlockId; + protected int selectedBlockMetaData; + + /** + * picks Block Ids and Metadata (Silverfish) + */ + public abstract void selectBlocks(Random var1, int var2, int var3, int var4, boolean var5); + + public int getSelectedBlockId() { + return this.selectedBlockId; + } + + public int getSelectedBlockMetaData() { + return this.selectedBlockMetaData; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/StructureScatteredFeatureStart.java b/sp-server/src/main/java/net/minecraft/src/StructureScatteredFeatureStart.java new file mode 100644 index 0000000..7ab224d --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/StructureScatteredFeatureStart.java @@ -0,0 +1,27 @@ +package net.minecraft.src; + +import java.util.Random; + +public class StructureScatteredFeatureStart extends StructureStart { + public StructureScatteredFeatureStart(World par1World, Random par2Random, int par3, int par4) { + BiomeGenBase var5 = par1World.getBiomeGenForCoords(par3 * 16 + 8, par4 * 16 + 8); + + if (var5 != BiomeGenBase.jungle && var5 != BiomeGenBase.jungleHills) { + if (var5 == BiomeGenBase.swampland) { + ComponentScatteredFeatureSwampHut var7 = new ComponentScatteredFeatureSwampHut(par2Random, par3 * 16, + par4 * 16); + this.components.add(var7); + } else { + ComponentScatteredFeatureDesertPyramid var8 = new ComponentScatteredFeatureDesertPyramid(par2Random, + par3 * 16, par4 * 16); + this.components.add(var8); + } + } else { + ComponentScatteredFeatureJunglePyramid var6 = new ComponentScatteredFeatureJunglePyramid(par2Random, + par3 * 16, par4 * 16); + this.components.add(var6); + } + + this.updateBoundingBox(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/StructureScatteredFeatureStones.java b/sp-server/src/main/java/net/minecraft/src/StructureScatteredFeatureStones.java new file mode 100644 index 0000000..f272eeb --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/StructureScatteredFeatureStones.java @@ -0,0 +1,23 @@ +package net.minecraft.src; + +import java.util.Random; + +class StructureScatteredFeatureStones extends StructurePieceBlockSelector { + private StructureScatteredFeatureStones() { + } + + /** + * picks Block Ids and Metadata (Silverfish) + */ + public void selectBlocks(Random par1Random, int par2, int par3, int par4, boolean par5) { + if (par1Random.nextFloat() < 0.4F) { + this.selectedBlockId = Block.cobblestone.blockID; + } else { + this.selectedBlockId = Block.cobblestoneMossy.blockID; + } + } + + StructureScatteredFeatureStones(ComponentScatteredFeaturePieces2 par1ComponentScatteredFeaturePieces2) { + this(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/StructureStart.java b/sp-server/src/main/java/net/minecraft/src/StructureStart.java new file mode 100644 index 0000000..727dd4a --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/StructureStart.java @@ -0,0 +1,101 @@ +package net.minecraft.src; + +import java.util.Iterator; +import java.util.LinkedList; +import java.util.Random; + +public abstract class StructureStart { + /** List of all StructureComponents that are part of this structure */ + protected LinkedList components = new LinkedList(); + protected StructureBoundingBox boundingBox; + + public StructureBoundingBox getBoundingBox() { + return this.boundingBox; + } + + public LinkedList getComponents() { + return this.components; + } + + /** + * Keeps iterating Structure Pieces and spawning them until the checks tell it + * to stop + */ + public void generateStructure(World par1World, Random par2Random, StructureBoundingBox par3StructureBoundingBox) { + Iterator var4 = this.components.iterator(); + + while (var4.hasNext()) { + StructureComponent var5 = (StructureComponent) var4.next(); + + if (var5.getBoundingBox().intersectsWith(par3StructureBoundingBox) + && !var5.addComponentParts(par1World, par2Random, par3StructureBoundingBox)) { + var4.remove(); + } + } + } + + /** + * Calculates total bounding box based on components' bounding boxes and saves + * it to boundingBox + */ + protected void updateBoundingBox() { + this.boundingBox = StructureBoundingBox.getNewBoundingBox(); + Iterator var1 = this.components.iterator(); + + while (var1.hasNext()) { + StructureComponent var2 = (StructureComponent) var1.next(); + this.boundingBox.expandTo(var2.getBoundingBox()); + } + } + + /** + * offsets the structure Bounding Boxes up to a certain height, typically 63 - + * 10 + */ + protected void markAvailableHeight(World par1World, Random par2Random, int par3) { + int var4 = 63 - par3; + int var5 = this.boundingBox.getYSize() + 1; + + if (var5 < var4) { + var5 += par2Random.nextInt(var4 - var5); + } + + int var6 = var5 - this.boundingBox.maxY; + this.boundingBox.offset(0, var6, 0); + Iterator var7 = this.components.iterator(); + + while (var7.hasNext()) { + StructureComponent var8 = (StructureComponent) var7.next(); + var8.getBoundingBox().offset(0, var6, 0); + } + } + + protected void setRandomHeight(World par1World, Random par2Random, int par3, int par4) { + int var5 = par4 - par3 + 1 - this.boundingBox.getYSize(); + boolean var6 = true; + int var10; + + if (var5 > 1) { + var10 = par3 + par2Random.nextInt(var5); + } else { + var10 = par3; + } + + int var7 = var10 - this.boundingBox.minY; + this.boundingBox.offset(0, var7, 0); + Iterator var8 = this.components.iterator(); + + while (var8.hasNext()) { + StructureComponent var9 = (StructureComponent) var8.next(); + var9.getBoundingBox().offset(0, var7, 0); + } + } + + /** + * currently only defined for Villages, returns true if Village has more than 2 + * non-road components + */ + public boolean isSizeableStructure() { + return true; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/StructureStrongholdPieceWeight.java b/sp-server/src/main/java/net/minecraft/src/StructureStrongholdPieceWeight.java new file mode 100644 index 0000000..409fdd7 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/StructureStrongholdPieceWeight.java @@ -0,0 +1,30 @@ +package net.minecraft.src; + +class StructureStrongholdPieceWeight { + public Class pieceClass; + + /** + * This basically keeps track of the 'epicness' of a structure. Epic structure + * components have a higher 'weight', and Structures may only grow up to a + * certain 'weight' before generation is stopped + */ + public final int pieceWeight; + public int instancesSpawned; + + /** How many Structure Pieces of this type may spawn in a structure */ + public int instancesLimit; + + public StructureStrongholdPieceWeight(Class par1Class, int par2, int par3) { + this.pieceClass = par1Class; + this.pieceWeight = par2; + this.instancesLimit = par3; + } + + public boolean canSpawnMoreStructuresOfType(int par1) { + return this.instancesLimit == 0 || this.instancesSpawned < this.instancesLimit; + } + + public boolean canSpawnMoreStructures() { + return this.instancesLimit == 0 || this.instancesSpawned < this.instancesLimit; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/StructureStrongholdPieceWeight2.java b/sp-server/src/main/java/net/minecraft/src/StructureStrongholdPieceWeight2.java new file mode 100644 index 0000000..f37191f --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/StructureStrongholdPieceWeight2.java @@ -0,0 +1,11 @@ +package net.minecraft.src; + +final class StructureStrongholdPieceWeight2 extends StructureStrongholdPieceWeight { + StructureStrongholdPieceWeight2(Class par1Class, int par2, int par3) { + super(par1Class, par2, par3); + } + + public boolean canSpawnMoreStructuresOfType(int par1) { + return super.canSpawnMoreStructuresOfType(par1) && par1 > 4; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/StructureStrongholdPieceWeight3.java b/sp-server/src/main/java/net/minecraft/src/StructureStrongholdPieceWeight3.java new file mode 100644 index 0000000..f245fca --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/StructureStrongholdPieceWeight3.java @@ -0,0 +1,11 @@ +package net.minecraft.src; + +final class StructureStrongholdPieceWeight3 extends StructureStrongholdPieceWeight { + StructureStrongholdPieceWeight3(Class par1Class, int par2, int par3) { + super(par1Class, par2, par3); + } + + public boolean canSpawnMoreStructuresOfType(int par1) { + return super.canSpawnMoreStructuresOfType(par1) && par1 > 5; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/StructureStrongholdPieces.java b/sp-server/src/main/java/net/minecraft/src/StructureStrongholdPieces.java new file mode 100644 index 0000000..205b78b --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/StructureStrongholdPieces.java @@ -0,0 +1,192 @@ +package net.minecraft.src; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Random; + +public class StructureStrongholdPieces { + private static final StructureStrongholdPieceWeight[] pieceWeightArray = new StructureStrongholdPieceWeight[] { + new StructureStrongholdPieceWeight(ComponentStrongholdStraight.class, 40, 0), + new StructureStrongholdPieceWeight(ComponentStrongholdPrison.class, 5, 5), + new StructureStrongholdPieceWeight(ComponentStrongholdLeftTurn.class, 20, 0), + new StructureStrongholdPieceWeight(ComponentStrongholdRightTurn.class, 20, 0), + new StructureStrongholdPieceWeight(ComponentStrongholdRoomCrossing.class, 10, 6), + new StructureStrongholdPieceWeight(ComponentStrongholdStairsStraight.class, 5, 5), + new StructureStrongholdPieceWeight(ComponentStrongholdStairs.class, 5, 5), + new StructureStrongholdPieceWeight(ComponentStrongholdCrossing.class, 5, 4), + new StructureStrongholdPieceWeight(ComponentStrongholdChestCorridor.class, 5, 4), + new StructureStrongholdPieceWeight2(ComponentStrongholdLibrary.class, 10, 2), + new StructureStrongholdPieceWeight3(ComponentStrongholdPortalRoom.class, 20, 1) }; + private static List structurePieceList; + private static Class strongComponentType; + static int totalWeight = 0; + private static final StructureStrongholdStones strongholdStones = new StructureStrongholdStones( + (StructureStrongholdPieceWeight2) null); + + /** + * sets up Arrays with the Structure pieces and their weights + */ + public static void prepareStructurePieces() { + structurePieceList = new ArrayList(); + StructureStrongholdPieceWeight[] var0 = pieceWeightArray; + int var1 = var0.length; + + for (int var2 = 0; var2 < var1; ++var2) { + StructureStrongholdPieceWeight var3 = var0[var2]; + var3.instancesSpawned = 0; + structurePieceList.add(var3); + } + + strongComponentType = null; + } + + private static boolean canAddStructurePieces() { + boolean var0 = false; + totalWeight = 0; + StructureStrongholdPieceWeight var2; + + for (Iterator var1 = structurePieceList.iterator(); var1.hasNext(); totalWeight += var2.pieceWeight) { + var2 = (StructureStrongholdPieceWeight) var1.next(); + + if (var2.instancesLimit > 0 && var2.instancesSpawned < var2.instancesLimit) { + var0 = true; + } + } + + return var0; + } + + /** + * translates the PieceWeight class to the Component class + */ + private static ComponentStronghold getStrongholdComponentFromWeightedPiece(Class par0Class, List par1List, + Random par2Random, int par3, int par4, int par5, int par6, int par7) { + Object var8 = null; + + if (par0Class == ComponentStrongholdStraight.class) { + var8 = ComponentStrongholdStraight.findValidPlacement(par1List, par2Random, par3, par4, par5, par6, par7); + } else if (par0Class == ComponentStrongholdPrison.class) { + var8 = ComponentStrongholdPrison.findValidPlacement(par1List, par2Random, par3, par4, par5, par6, par7); + } else if (par0Class == ComponentStrongholdLeftTurn.class) { + var8 = ComponentStrongholdLeftTurn.findValidPlacement(par1List, par2Random, par3, par4, par5, par6, par7); + } else if (par0Class == ComponentStrongholdRightTurn.class) { + var8 = ComponentStrongholdRightTurn.findValidPlacement(par1List, par2Random, par3, par4, par5, par6, par7); + } else if (par0Class == ComponentStrongholdRoomCrossing.class) { + var8 = ComponentStrongholdRoomCrossing.findValidPlacement(par1List, par2Random, par3, par4, par5, par6, + par7); + } else if (par0Class == ComponentStrongholdStairsStraight.class) { + var8 = ComponentStrongholdStairsStraight.findValidPlacement(par1List, par2Random, par3, par4, par5, par6, + par7); + } else if (par0Class == ComponentStrongholdStairs.class) { + var8 = ComponentStrongholdStairs.getStrongholdStairsComponent(par1List, par2Random, par3, par4, par5, par6, + par7); + } else if (par0Class == ComponentStrongholdCrossing.class) { + var8 = ComponentStrongholdCrossing.findValidPlacement(par1List, par2Random, par3, par4, par5, par6, par7); + } else if (par0Class == ComponentStrongholdChestCorridor.class) { + var8 = ComponentStrongholdChestCorridor.findValidPlacement(par1List, par2Random, par3, par4, par5, par6, + par7); + } else if (par0Class == ComponentStrongholdLibrary.class) { + var8 = ComponentStrongholdLibrary.findValidPlacement(par1List, par2Random, par3, par4, par5, par6, par7); + } else if (par0Class == ComponentStrongholdPortalRoom.class) { + var8 = ComponentStrongholdPortalRoom.findValidPlacement(par1List, par2Random, par3, par4, par5, par6, par7); + } + + return (ComponentStronghold) var8; + } + + private static ComponentStronghold getNextComponent(ComponentStrongholdStairs2 par0ComponentStrongholdStairs2, + List par1List, Random par2Random, int par3, int par4, int par5, int par6, int par7) { + if (!canAddStructurePieces()) { + return null; + } else { + if (strongComponentType != null) { + ComponentStronghold var8 = getStrongholdComponentFromWeightedPiece(strongComponentType, par1List, + par2Random, par3, par4, par5, par6, par7); + strongComponentType = null; + + if (var8 != null) { + return var8; + } + } + + int var13 = 0; + + while (var13 < 5) { + ++var13; + int var9 = par2Random.nextInt(totalWeight); + Iterator var10 = structurePieceList.iterator(); + + while (var10.hasNext()) { + StructureStrongholdPieceWeight var11 = (StructureStrongholdPieceWeight) var10.next(); + var9 -= var11.pieceWeight; + + if (var9 < 0) { + if (!var11.canSpawnMoreStructuresOfType(par7) + || var11 == par0ComponentStrongholdStairs2.strongholdPieceWeight) { + break; + } + + ComponentStronghold var12 = getStrongholdComponentFromWeightedPiece(var11.pieceClass, par1List, + par2Random, par3, par4, par5, par6, par7); + + if (var12 != null) { + ++var11.instancesSpawned; + par0ComponentStrongholdStairs2.strongholdPieceWeight = var11; + + if (!var11.canSpawnMoreStructures()) { + structurePieceList.remove(var11); + } + + return var12; + } + } + } + } + + StructureBoundingBox var14 = ComponentStrongholdCorridor.func_74992_a(par1List, par2Random, par3, par4, + par5, par6); + + if (var14 != null && var14.minY > 1) { + return new ComponentStrongholdCorridor(par7, par2Random, var14, par6); + } else { + return null; + } + } + } + + private static StructureComponent getNextValidComponent(ComponentStrongholdStairs2 par0ComponentStrongholdStairs2, + List par1List, Random par2Random, int par3, int par4, int par5, int par6, int par7) { + if (par7 > 50) { + return null; + } else if (Math.abs(par3 - par0ComponentStrongholdStairs2.getBoundingBox().minX) <= 112 + && Math.abs(par5 - par0ComponentStrongholdStairs2.getBoundingBox().minZ) <= 112) { + ComponentStronghold var8 = getNextComponent(par0ComponentStrongholdStairs2, par1List, par2Random, par3, + par4, par5, par6, par7 + 1); + + if (var8 != null) { + par1List.add(var8); + par0ComponentStrongholdStairs2.field_75026_c.add(var8); + } + + return var8; + } else { + return null; + } + } + + static StructureComponent getNextValidComponentAccess(ComponentStrongholdStairs2 par0ComponentStrongholdStairs2, + List par1List, Random par2Random, int par3, int par4, int par5, int par6, int par7) { + return getNextValidComponent(par0ComponentStrongholdStairs2, par1List, par2Random, par3, par4, par5, par6, + par7); + } + + static Class setComponentType(Class par0Class) { + strongComponentType = par0Class; + return par0Class; + } + + static StructureStrongholdStones getStrongholdStones() { + return strongholdStones; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/StructureStrongholdStart.java b/sp-server/src/main/java/net/minecraft/src/StructureStrongholdStart.java new file mode 100644 index 0000000..c5f134e --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/StructureStrongholdStart.java @@ -0,0 +1,24 @@ +package net.minecraft.src; + +import java.util.ArrayList; +import java.util.Random; + +class StructureStrongholdStart extends StructureStart { + public StructureStrongholdStart(World par1World, Random par2Random, int par3, int par4) { + StructureStrongholdPieces.prepareStructurePieces(); + ComponentStrongholdStairs2 var5 = new ComponentStrongholdStairs2(0, par2Random, (par3 << 4) + 2, + (par4 << 4) + 2); + this.components.add(var5); + var5.buildComponent(var5, this.components, par2Random); + ArrayList var6 = var5.field_75026_c; + + while (!var6.isEmpty()) { + int var7 = par2Random.nextInt(var6.size()); + StructureComponent var8 = (StructureComponent) var6.remove(var7); + var8.buildComponent(var5, this.components, par2Random); + } + + this.updateBoundingBox(); + this.markAvailableHeight(par1World, par2Random, 10); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/StructureStrongholdStones.java b/sp-server/src/main/java/net/minecraft/src/StructureStrongholdStones.java new file mode 100644 index 0000000..a0c01eb --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/StructureStrongholdStones.java @@ -0,0 +1,36 @@ +package net.minecraft.src; + +import java.util.Random; + +class StructureStrongholdStones extends StructurePieceBlockSelector { + private StructureStrongholdStones() { + } + + /** + * picks Block Ids and Metadata (Silverfish) + */ + public void selectBlocks(Random par1Random, int par2, int par3, int par4, boolean par5) { + if (par5) { + this.selectedBlockId = Block.stoneBrick.blockID; + float var6 = par1Random.nextFloat(); + + if (var6 < 0.2F) { + this.selectedBlockMetaData = 2; + } else if (var6 < 0.5F) { + this.selectedBlockMetaData = 1; + } else if (var6 < 0.55F) { + this.selectedBlockId = Block.silverfish.blockID; + this.selectedBlockMetaData = 2; + } else { + this.selectedBlockMetaData = 0; + } + } else { + this.selectedBlockId = 0; + this.selectedBlockMetaData = 0; + } + } + + StructureStrongholdStones(StructureStrongholdPieceWeight2 par1StructureStrongholdPieceWeight2) { + this(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/StructureVillagePieceWeight.java b/sp-server/src/main/java/net/minecraft/src/StructureVillagePieceWeight.java new file mode 100644 index 0000000..589bdda --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/StructureVillagePieceWeight.java @@ -0,0 +1,23 @@ +package net.minecraft.src; + +public class StructureVillagePieceWeight { + /** The Class object for the represantation of this village piece. */ + public Class villagePieceClass; + public final int villagePieceWeight; + public int villagePiecesSpawned; + public int villagePiecesLimit; + + public StructureVillagePieceWeight(Class par1Class, int par2, int par3) { + this.villagePieceClass = par1Class; + this.villagePieceWeight = par2; + this.villagePiecesLimit = par3; + } + + public boolean canSpawnMoreVillagePiecesOfType(int par1) { + return this.villagePiecesLimit == 0 || this.villagePiecesSpawned < this.villagePiecesLimit; + } + + public boolean canSpawnMoreVillagePieces() { + return this.villagePiecesLimit == 0 || this.villagePiecesSpawned < this.villagePiecesLimit; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/StructureVillagePieces.java b/sp-server/src/main/java/net/minecraft/src/StructureVillagePieces.java new file mode 100644 index 0000000..7fb1052 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/StructureVillagePieces.java @@ -0,0 +1,234 @@ +package net.minecraft.src; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Random; + +public class StructureVillagePieces { + public static ArrayList getStructureVillageWeightedPieceList(Random par0Random, int par1) { + ArrayList var2 = new ArrayList(); + var2.add(new StructureVillagePieceWeight(ComponentVillageHouse4_Garden.class, 4, + MathHelper.getRandomIntegerInRange(par0Random, 2 + par1, 4 + par1 * 2))); + var2.add(new StructureVillagePieceWeight(ComponentVillageChurch.class, 20, + MathHelper.getRandomIntegerInRange(par0Random, 0 + par1, 1 + par1))); + var2.add(new StructureVillagePieceWeight(ComponentVillageHouse1.class, 20, + MathHelper.getRandomIntegerInRange(par0Random, 0 + par1, 2 + par1))); + var2.add(new StructureVillagePieceWeight(ComponentVillageWoodHut.class, 3, + MathHelper.getRandomIntegerInRange(par0Random, 2 + par1, 5 + par1 * 3))); + var2.add(new StructureVillagePieceWeight(ComponentVillageHall.class, 15, + MathHelper.getRandomIntegerInRange(par0Random, 0 + par1, 2 + par1))); + var2.add(new StructureVillagePieceWeight(ComponentVillageField.class, 3, + MathHelper.getRandomIntegerInRange(par0Random, 1 + par1, 4 + par1))); + var2.add(new StructureVillagePieceWeight(ComponentVillageField2.class, 3, + MathHelper.getRandomIntegerInRange(par0Random, 2 + par1, 4 + par1 * 2))); + var2.add(new StructureVillagePieceWeight(ComponentVillageHouse2.class, 15, + MathHelper.getRandomIntegerInRange(par0Random, 0, 1 + par1))); + var2.add(new StructureVillagePieceWeight(ComponentVillageHouse3.class, 8, + MathHelper.getRandomIntegerInRange(par0Random, 0 + par1, 3 + par1 * 2))); + Iterator var3 = var2.iterator(); + + while (var3.hasNext()) { + if (((StructureVillagePieceWeight) var3.next()).villagePiecesLimit == 0) { + var3.remove(); + } + } + + return var2; + } + + private static int func_75079_a(List par0List) { + boolean var1 = false; + int var2 = 0; + StructureVillagePieceWeight var4; + + for (Iterator var3 = par0List.iterator(); var3.hasNext(); var2 += var4.villagePieceWeight) { + var4 = (StructureVillagePieceWeight) var3.next(); + + if (var4.villagePiecesLimit > 0 && var4.villagePiecesSpawned < var4.villagePiecesLimit) { + var1 = true; + } + } + + return var1 ? var2 : -1; + } + + private static ComponentVillage func_75083_a(ComponentVillageStartPiece par0ComponentVillageStartPiece, + StructureVillagePieceWeight par1StructureVillagePieceWeight, List par2List, Random par3Random, int par4, + int par5, int par6, int par7, int par8) { + Class var9 = par1StructureVillagePieceWeight.villagePieceClass; + Object var10 = null; + + if (var9 == ComponentVillageHouse4_Garden.class) { + var10 = ComponentVillageHouse4_Garden.func_74912_a(par0ComponentVillageStartPiece, par2List, par3Random, + par4, par5, par6, par7, par8); + } else if (var9 == ComponentVillageChurch.class) { + var10 = ComponentVillageChurch.func_74919_a(par0ComponentVillageStartPiece, par2List, par3Random, par4, + par5, par6, par7, par8); + } else if (var9 == ComponentVillageHouse1.class) { + var10 = ComponentVillageHouse1.func_74898_a(par0ComponentVillageStartPiece, par2List, par3Random, par4, + par5, par6, par7, par8); + } else if (var9 == ComponentVillageWoodHut.class) { + var10 = ComponentVillageWoodHut.func_74908_a(par0ComponentVillageStartPiece, par2List, par3Random, par4, + par5, par6, par7, par8); + } else if (var9 == ComponentVillageHall.class) { + var10 = ComponentVillageHall.func_74906_a(par0ComponentVillageStartPiece, par2List, par3Random, par4, par5, + par6, par7, par8); + } else if (var9 == ComponentVillageField.class) { + var10 = ComponentVillageField.func_74900_a(par0ComponentVillageStartPiece, par2List, par3Random, par4, par5, + par6, par7, par8); + } else if (var9 == ComponentVillageField2.class) { + var10 = ComponentVillageField2.func_74902_a(par0ComponentVillageStartPiece, par2List, par3Random, par4, + par5, par6, par7, par8); + } else if (var9 == ComponentVillageHouse2.class) { + var10 = ComponentVillageHouse2.func_74915_a(par0ComponentVillageStartPiece, par2List, par3Random, par4, + par5, par6, par7, par8); + } else if (var9 == ComponentVillageHouse3.class) { + var10 = ComponentVillageHouse3.func_74921_a(par0ComponentVillageStartPiece, par2List, par3Random, par4, + par5, par6, par7, par8); + } + + return (ComponentVillage) var10; + } + + /** + * attempts to find a next Village Component to be spawned + */ + private static ComponentVillage getNextVillageComponent(ComponentVillageStartPiece par0ComponentVillageStartPiece, + List par1List, Random par2Random, int par3, int par4, int par5, int par6, int par7) { + int var8 = func_75079_a(par0ComponentVillageStartPiece.structureVillageWeightedPieceList); + + if (var8 <= 0) { + return null; + } else { + int var9 = 0; + + while (var9 < 5) { + ++var9; + int var10 = par2Random.nextInt(var8); + Iterator var11 = par0ComponentVillageStartPiece.structureVillageWeightedPieceList.iterator(); + + while (var11.hasNext()) { + StructureVillagePieceWeight var12 = (StructureVillagePieceWeight) var11.next(); + var10 -= var12.villagePieceWeight; + + if (var10 < 0) { + if (!var12.canSpawnMoreVillagePiecesOfType(par7) + || var12 == par0ComponentVillageStartPiece.structVillagePieceWeight + && par0ComponentVillageStartPiece.structureVillageWeightedPieceList + .size() > 1) { + break; + } + + ComponentVillage var13 = func_75083_a(par0ComponentVillageStartPiece, var12, par1List, + par2Random, par3, par4, par5, par6, par7); + + if (var13 != null) { + ++var12.villagePiecesSpawned; + par0ComponentVillageStartPiece.structVillagePieceWeight = var12; + + if (!var12.canSpawnMoreVillagePieces()) { + par0ComponentVillageStartPiece.structureVillageWeightedPieceList.remove(var12); + } + + return var13; + } + } + } + } + + StructureBoundingBox var14 = ComponentVillageTorch.func_74904_a(par0ComponentVillageStartPiece, par1List, + par2Random, par3, par4, par5, par6); + + if (var14 != null) { + return new ComponentVillageTorch(par0ComponentVillageStartPiece, par7, par2Random, var14, par6); + } else { + return null; + } + } + } + + /** + * attempts to find a next Structure Component to be spawned, private Village + * function + */ + private static StructureComponent getNextVillageStructureComponent( + ComponentVillageStartPiece par0ComponentVillageStartPiece, List par1List, Random par2Random, int par3, + int par4, int par5, int par6, int par7) { + if (par7 > 50) { + return null; + } else if (Math.abs(par3 - par0ComponentVillageStartPiece.getBoundingBox().minX) <= 112 + && Math.abs(par5 - par0ComponentVillageStartPiece.getBoundingBox().minZ) <= 112) { + ComponentVillage var8 = getNextVillageComponent(par0ComponentVillageStartPiece, par1List, par2Random, par3, + par4, par5, par6, par7 + 1); + + if (var8 != null) { + int var9 = (var8.boundingBox.minX + var8.boundingBox.maxX) / 2; + int var10 = (var8.boundingBox.minZ + var8.boundingBox.maxZ) / 2; + int var11 = var8.boundingBox.maxX - var8.boundingBox.minX; + int var12 = var8.boundingBox.maxZ - var8.boundingBox.minZ; + int var13 = var11 > var12 ? var11 : var12; + + if (par0ComponentVillageStartPiece.getWorldChunkManager().areBiomesViable(var9, var10, var13 / 2 + 4, + MapGenVillage.villageSpawnBiomes)) { + par1List.add(var8); + par0ComponentVillageStartPiece.field_74932_i.add(var8); + return var8; + } + } + + return null; + } else { + return null; + } + } + + private static StructureComponent getNextComponentVillagePath( + ComponentVillageStartPiece par0ComponentVillageStartPiece, List par1List, Random par2Random, int par3, + int par4, int par5, int par6, int par7) { + if (par7 > 3 + par0ComponentVillageStartPiece.terrainType) { + return null; + } else if (Math.abs(par3 - par0ComponentVillageStartPiece.getBoundingBox().minX) <= 112 + && Math.abs(par5 - par0ComponentVillageStartPiece.getBoundingBox().minZ) <= 112) { + StructureBoundingBox var8 = ComponentVillagePathGen.func_74933_a(par0ComponentVillageStartPiece, par1List, + par2Random, par3, par4, par5, par6); + + if (var8 != null && var8.minY > 10) { + ComponentVillagePathGen var9 = new ComponentVillagePathGen(par0ComponentVillageStartPiece, par7, + par2Random, var8, par6); + int var10 = (var9.boundingBox.minX + var9.boundingBox.maxX) / 2; + int var11 = (var9.boundingBox.minZ + var9.boundingBox.maxZ) / 2; + int var12 = var9.boundingBox.maxX - var9.boundingBox.minX; + int var13 = var9.boundingBox.maxZ - var9.boundingBox.minZ; + int var14 = var12 > var13 ? var12 : var13; + + if (par0ComponentVillageStartPiece.getWorldChunkManager().areBiomesViable(var10, var11, var14 / 2 + 4, + MapGenVillage.villageSpawnBiomes)) { + par1List.add(var9); + par0ComponentVillageStartPiece.field_74930_j.add(var9); + return var9; + } + } + + return null; + } else { + return null; + } + } + + /** + * attempts to find a next Structure Component to be spawned + */ + static StructureComponent getNextStructureComponent(ComponentVillageStartPiece par0ComponentVillageStartPiece, + List par1List, Random par2Random, int par3, int par4, int par5, int par6, int par7) { + return getNextVillageStructureComponent(par0ComponentVillageStartPiece, par1List, par2Random, par3, par4, par5, + par6, par7); + } + + static StructureComponent getNextStructureComponentVillagePath( + ComponentVillageStartPiece par0ComponentVillageStartPiece, List par1List, Random par2Random, int par3, + int par4, int par5, int par6, int par7) { + return getNextComponentVillagePath(par0ComponentVillageStartPiece, par1List, par2Random, par3, par4, par5, par6, + par7); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/StructureVillageStart.java b/sp-server/src/main/java/net/minecraft/src/StructureVillageStart.java new file mode 100644 index 0000000..be42235 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/StructureVillageStart.java @@ -0,0 +1,57 @@ +package net.minecraft.src; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.Random; + +class StructureVillageStart extends StructureStart { + /** well ... thats what it does */ + private boolean hasMoreThanTwoComponents = false; + + public StructureVillageStart(World par1World, Random par2Random, int par3, int par4, int par5) { + ArrayList var6 = StructureVillagePieces.getStructureVillageWeightedPieceList(par2Random, par5); + ComponentVillageStartPiece var7 = new ComponentVillageStartPiece(par1World.getWorldChunkManager(), 0, + par2Random, (par3 << 4) + 2, (par4 << 4) + 2, var6, par5); + this.components.add(var7); + var7.buildComponent(var7, this.components, par2Random); + ArrayList var8 = var7.field_74930_j; + ArrayList var9 = var7.field_74932_i; + int var10; + + while (!var8.isEmpty() || !var9.isEmpty()) { + StructureComponent var11; + + if (var8.isEmpty()) { + var10 = par2Random.nextInt(var9.size()); + var11 = (StructureComponent) var9.remove(var10); + var11.buildComponent(var7, this.components, par2Random); + } else { + var10 = par2Random.nextInt(var8.size()); + var11 = (StructureComponent) var8.remove(var10); + var11.buildComponent(var7, this.components, par2Random); + } + } + + this.updateBoundingBox(); + var10 = 0; + Iterator var13 = this.components.iterator(); + + while (var13.hasNext()) { + StructureComponent var12 = (StructureComponent) var13.next(); + + if (!(var12 instanceof ComponentVillageRoadPiece)) { + ++var10; + } + } + + this.hasMoreThanTwoComponents = var10 > 2; + } + + /** + * currently only defined for Villages, returns true if Village has more than 2 + * non-road components + */ + public boolean isSizeableStructure() { + return this.hasMoreThanTwoComponents; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/SyntaxErrorException.java b/sp-server/src/main/java/net/minecraft/src/SyntaxErrorException.java new file mode 100644 index 0000000..49f4734 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/SyntaxErrorException.java @@ -0,0 +1,11 @@ +package net.minecraft.src; + +public class SyntaxErrorException extends CommandException { + public SyntaxErrorException() { + this("commands.generic.snytax", new Object[0]); + } + + public SyntaxErrorException(String par1Str, Object... par2ArrayOfObj) { + super(par1Str, par2ArrayOfObj); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/TcpConnection.java b/sp-server/src/main/java/net/minecraft/src/TcpConnection.java new file mode 100644 index 0000000..96efe06 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/TcpConnection.java @@ -0,0 +1,484 @@ +package net.minecraft.src; + +import java.io.BufferedOutputStream; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.Socket; +import java.net.SocketAddress; +import java.net.SocketException; +import java.security.PrivateKey; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import java.util.concurrent.atomic.AtomicInteger; +import javax.crypto.SecretKey; + +public class TcpConnection implements INetworkManager { + public static AtomicInteger field_74471_a = new AtomicInteger(); + public static AtomicInteger field_74469_b = new AtomicInteger(); + + /** The object used for synchronization on the send queue. */ + private final Object sendQueueLock = new Object(); + private final ILogAgent field_98215_i; + + /** The socket used by this network manager. */ + private Socket networkSocket; + + /** The InetSocketAddress of the remote endpoint */ + private final SocketAddress remoteSocketAddress; + + /** The input stream connected to the socket. */ + private volatile DataInputStream socketInputStream; + + /** The output stream connected to the socket. */ + private volatile DataOutputStream socketOutputStream; + + /** Whether the network is currently operational. */ + private volatile boolean isRunning = true; + + /** + * Whether this network manager is currently terminating (and should ignore + * further errors). + */ + private volatile boolean isTerminating = false; + + /** + * Linked list of packets that have been read and are awaiting processing. + */ + private List readPackets = Collections.synchronizedList(new ArrayList()); + + /** Linked list of packets awaiting sending. */ + private List dataPackets = Collections.synchronizedList(new ArrayList()); + + /** Linked list of packets with chunk data that are awaiting sending. */ + private List chunkDataPackets = Collections.synchronizedList(new ArrayList()); + + /** A reference to the NetHandler object. */ + private NetHandler theNetHandler; + + /** + * Whether this server is currently terminating. If this is a client, this is + * always false. + */ + private boolean isServerTerminating = false; + + /** The thread used for writing. */ + private Thread writeThread; + + /** The thread used for reading. */ + private Thread readThread; + + /** A String indicating why the network has shutdown. */ + private String terminationReason = ""; + private Object[] field_74480_w; + private int field_74490_x = 0; + + /** + * The length in bytes of the packets in both send queues (data and chunkData). + */ + private int sendQueueByteLength = 0; + public static int[] field_74470_c = new int[256]; + public static int[] field_74467_d = new int[256]; + public int field_74468_e = 0; + boolean isInputBeingDecrypted = false; + boolean isOutputEncrypted = false; + private SecretKey sharedKeyForEncryption = null; + private PrivateKey field_74463_A = null; + + /** + * Delay for sending pending chunk data packets (as opposed to pending non-chunk + * data packets) + */ + private int chunkDataPacketsDelay = 50; + + public TcpConnection(ILogAgent par1ILogAgent, Socket par2Socket, String par3Str, NetHandler par4NetHandler, + PrivateKey par5PrivateKey) throws IOException { + this.field_74463_A = par5PrivateKey; + this.networkSocket = par2Socket; + this.field_98215_i = par1ILogAgent; + this.remoteSocketAddress = par2Socket.getRemoteSocketAddress(); + this.theNetHandler = par4NetHandler; + + try { + par2Socket.setSoTimeout(30000); + par2Socket.setTrafficClass(24); + } catch (SocketException var7) { + System.err.println(var7.getMessage()); + } + + this.socketInputStream = new DataInputStream(par2Socket.getInputStream()); + this.socketOutputStream = new DataOutputStream(new BufferedOutputStream(par2Socket.getOutputStream(), 5120)); + this.readThread = new TcpReaderThread(this, par3Str + " read thread"); + this.writeThread = new TcpWriterThread(this, par3Str + " write thread"); + this.readThread.start(); + this.writeThread.start(); + } + + /** + * Sets the NetHandler for this NetworkManager. Server-only. + */ + public void setNetHandler(NetHandler par1NetHandler) { + this.theNetHandler = par1NetHandler; + } + + /** + * Adds the packet to the correct send queue (chunk data packets go to a + * separate queue). + */ + public void addToSendQueue(Packet par1Packet) { + if (!this.isServerTerminating) { + Object var2 = this.sendQueueLock; + + synchronized (this.sendQueueLock) { + this.sendQueueByteLength += par1Packet.getPacketSize() + 1; + this.dataPackets.add(par1Packet); + } + } + } + + /** + * Sends a data packet if there is one to send, or sends a chunk data packet if + * there is one and the counter is up, or does nothing. + */ + private boolean sendPacket() { + boolean var1 = false; + + try { + int[] var10000; + int var10001; + Packet var2; + + if (this.field_74468_e == 0 || !this.dataPackets.isEmpty() && System.currentTimeMillis() + - ((Packet) this.dataPackets.get(0)).creationTimeMillis >= (long) this.field_74468_e) { + var2 = this.func_74460_a(false); + + if (var2 != null) { + Packet.writePacket(var2, this.socketOutputStream); + + if (var2 instanceof Packet252SharedKey && !this.isOutputEncrypted) { + if (!this.theNetHandler.isServerHandler()) { + this.sharedKeyForEncryption = ((Packet252SharedKey) var2).getSharedKey(); + } + + this.encryptOuputStream(); + } + + var10000 = field_74467_d; + var10001 = var2.getPacketId(); + var10000[var10001] += var2.getPacketSize() + 1; + var1 = true; + } + } + + if (this.chunkDataPacketsDelay-- <= 0 && (this.field_74468_e == 0 + || !this.chunkDataPackets.isEmpty() && System.currentTimeMillis() - ((Packet) this.chunkDataPackets + .get(0)).creationTimeMillis >= (long) this.field_74468_e)) { + var2 = this.func_74460_a(true); + + if (var2 != null) { + Packet.writePacket(var2, this.socketOutputStream); + var10000 = field_74467_d; + var10001 = var2.getPacketId(); + var10000[var10001] += var2.getPacketSize() + 1; + this.chunkDataPacketsDelay = 0; + var1 = true; + } + } + + return var1; + } catch (Exception var3) { + if (!this.isTerminating) { + this.onNetworkError(var3); + } + + return false; + } + } + + private Packet func_74460_a(boolean par1) { + Packet var2 = null; + List var3 = par1 ? this.chunkDataPackets : this.dataPackets; + Object var4 = this.sendQueueLock; + + synchronized (this.sendQueueLock) { + while (!var3.isEmpty() && var2 == null) { + var2 = (Packet) var3.remove(0); + this.sendQueueByteLength -= var2.getPacketSize() + 1; + + if (this.func_74454_a(var2, par1)) { + var2 = null; + } + } + + return var2; + } + } + + private boolean func_74454_a(Packet par1Packet, boolean par2) { + if (!par1Packet.isRealPacket()) { + return false; + } else { + List var3 = par2 ? this.chunkDataPackets : this.dataPackets; + Iterator var4 = var3.iterator(); + Packet var5; + + do { + if (!var4.hasNext()) { + return false; + } + + var5 = (Packet) var4.next(); + } while (var5.getPacketId() != par1Packet.getPacketId()); + + return par1Packet.containsSameEntityIDAs(var5); + } + } + + /** + * Wakes reader and writer threads + */ + public void wakeThreads() { + if (this.readThread != null) { + this.readThread.interrupt(); + } + + if (this.writeThread != null) { + this.writeThread.interrupt(); + } + } + + /** + * Reads a single packet from the input stream and adds it to the read queue. If + * no packet is read, it shuts down the network. + */ + private boolean readPacket() { + boolean var1 = false; + + try { + Packet var2 = Packet.readPacket(this.field_98215_i, this.socketInputStream, + this.theNetHandler.isServerHandler(), this.networkSocket); + + if (var2 != null) { + if (var2 instanceof Packet252SharedKey && !this.isInputBeingDecrypted) { + if (this.theNetHandler.isServerHandler()) { + this.sharedKeyForEncryption = ((Packet252SharedKey) var2).getSharedKey(this.field_74463_A); + } + + this.decryptInputStream(); + } + + int[] var10000 = field_74470_c; + int var10001 = var2.getPacketId(); + var10000[var10001] += var2.getPacketSize() + 1; + + if (!this.isServerTerminating) { + if (var2.canProcessAsync() && this.theNetHandler.canProcessPacketsAsync()) { + this.field_74490_x = 0; + var2.processPacket(this.theNetHandler); + } else { + this.readPackets.add(var2); + } + } + + var1 = true; + } else { + this.networkShutdown("disconnect.endOfStream", new Object[0]); + } + + return var1; + } catch (Exception var3) { + if (!this.isTerminating) { + this.onNetworkError(var3); + } + + return false; + } + } + + /** + * Used to report network errors and causes a network shutdown. + */ + private void onNetworkError(Exception par1Exception) { + par1Exception.printStackTrace(); + this.networkShutdown("disconnect.genericReason", + new Object[] { "Internal exception: " + par1Exception.toString() }); + } + + /** + * Shuts down the network with the specified reason. Closes all streams and + * sockets, spawns NetworkMasterThread to stop reading and writing threads. + */ + public void networkShutdown(String par1Str, Object... par2ArrayOfObj) { + if (this.isRunning) { + this.isTerminating = true; + this.terminationReason = par1Str; + this.field_74480_w = par2ArrayOfObj; + this.isRunning = false; + (new TcpMasterThread(this)).start(); + + try { + this.socketInputStream.close(); + } catch (Throwable var6) { + ; + } + + try { + this.socketOutputStream.close(); + } catch (Throwable var5) { + ; + } + + try { + this.networkSocket.close(); + } catch (Throwable var4) { + ; + } + + this.socketInputStream = null; + this.socketOutputStream = null; + this.networkSocket = null; + } + } + + /** + * Checks timeouts and processes all pending read packets. + */ + public void processReadPackets() { + if (this.sendQueueByteLength > 2097152) { + this.networkShutdown("disconnect.overflow", new Object[0]); + } + + if (this.readPackets.isEmpty()) { + if (this.field_74490_x++ == 1200) { + this.networkShutdown("disconnect.timeout", new Object[0]); + } + } else { + this.field_74490_x = 0; + } + + int var1 = 1000; + + while (!this.readPackets.isEmpty() && var1-- >= 0) { + Packet var2 = (Packet) this.readPackets.remove(0); + var2.processPacket(this.theNetHandler); + } + + this.wakeThreads(); + + if (this.isTerminating && this.readPackets.isEmpty()) { + this.theNetHandler.handleErrorMessage(this.terminationReason, this.field_74480_w); + } + } + + /** + * Returns the socket address of the remote side. Server-only. + */ + public SocketAddress getRemoteAddress() { + return this.remoteSocketAddress; + } + + /** + * Shuts down the server. (Only actually used on the server) + */ + public void serverShutdown() { + if (!this.isServerTerminating) { + this.wakeThreads(); + this.isServerTerminating = true; + this.readThread.interrupt(); + (new TcpMonitorThread(this)).start(); + } + } + + private void decryptInputStream() throws IOException { + this.isInputBeingDecrypted = true; + InputStream var1 = this.networkSocket.getInputStream(); + this.socketInputStream = new DataInputStream( + CryptManager.decryptInputStream(this.sharedKeyForEncryption, var1)); + } + + /** + * flushes the stream and replaces it with an encryptedOutputStream + */ + private void encryptOuputStream() throws IOException { + this.socketOutputStream.flush(); + this.isOutputEncrypted = true; + BufferedOutputStream var1 = new BufferedOutputStream( + CryptManager.encryptOuputStream(this.sharedKeyForEncryption, this.networkSocket.getOutputStream()), + 5120); + this.socketOutputStream = new DataOutputStream(var1); + } + + /** + * Returns the number of chunk data packets waiting to be sent. + */ + public int getNumChunkDataPackets() { + return this.chunkDataPackets.size(); + } + + public Socket getSocket() { + return this.networkSocket; + } + + /** + * Whether the network is operational. + */ + static boolean isRunning(TcpConnection par0TcpConnection) { + return par0TcpConnection.isRunning; + } + + /** + * Is the server terminating? Client side aways returns false. + */ + static boolean isServerTerminating(TcpConnection par0TcpConnection) { + return par0TcpConnection.isServerTerminating; + } + + /** + * Static accessor to readPacket. + */ + static boolean readNetworkPacket(TcpConnection par0TcpConnection) { + return par0TcpConnection.readPacket(); + } + + /** + * Static accessor to sendPacket. + */ + static boolean sendNetworkPacket(TcpConnection par0TcpConnection) { + return par0TcpConnection.sendPacket(); + } + + static DataOutputStream getOutputStream(TcpConnection par0TcpConnection) { + return par0TcpConnection.socketOutputStream; + } + + /** + * Gets whether the Network manager is terminating. + */ + static boolean isTerminating(TcpConnection par0TcpConnection) { + return par0TcpConnection.isTerminating; + } + + /** + * Sends the network manager an error + */ + static void sendError(TcpConnection par0TcpConnection, Exception par1Exception) { + par0TcpConnection.onNetworkError(par1Exception); + } + + /** + * Returns the read thread. + */ + static Thread getReadThread(TcpConnection par0TcpConnection) { + return par0TcpConnection.readThread; + } + + /** + * Returns the write thread. + */ + static Thread getWriteThread(TcpConnection par0TcpConnection) { + return par0TcpConnection.writeThread; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/TcpMasterThread.java b/sp-server/src/main/java/net/minecraft/src/TcpMasterThread.java new file mode 100644 index 0000000..4ffb658 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/TcpMasterThread.java @@ -0,0 +1,34 @@ +package net.minecraft.src; + +class TcpMasterThread extends Thread { + final TcpConnection theTcpConnection; + + TcpMasterThread(TcpConnection par1TcpConnection) { + this.theTcpConnection = par1TcpConnection; + } + + @SuppressWarnings("deprecation") + public void run() { + try { + Thread.sleep(5000L); + + if (TcpConnection.getReadThread(this.theTcpConnection).isAlive()) { + try { + TcpConnection.getReadThread(this.theTcpConnection).stop(); + } catch (Throwable var3) { + ; + } + } + + if (TcpConnection.getWriteThread(this.theTcpConnection).isAlive()) { + try { + TcpConnection.getWriteThread(this.theTcpConnection).stop(); + } catch (Throwable var2) { + ; + } + } + } catch (InterruptedException var4) { + var4.printStackTrace(); + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/TcpMonitorThread.java b/sp-server/src/main/java/net/minecraft/src/TcpMonitorThread.java new file mode 100644 index 0000000..9b223a8 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/TcpMonitorThread.java @@ -0,0 +1,22 @@ +package net.minecraft.src; + +class TcpMonitorThread extends Thread { + final TcpConnection theTcpConnection; + + TcpMonitorThread(TcpConnection par1TcpConnection) { + this.theTcpConnection = par1TcpConnection; + } + + public void run() { + try { + Thread.sleep(2000L); + + if (TcpConnection.isRunning(this.theTcpConnection)) { + TcpConnection.getWriteThread(this.theTcpConnection).interrupt(); + this.theTcpConnection.networkShutdown("disconnect.closed", new Object[0]); + } + } catch (Exception var2) { + var2.printStackTrace(); + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/TcpReaderThread.java b/sp-server/src/main/java/net/minecraft/src/TcpReaderThread.java new file mode 100644 index 0000000..f65f890 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/TcpReaderThread.java @@ -0,0 +1,31 @@ +package net.minecraft.src; + +class TcpReaderThread extends Thread { + final TcpConnection theTcpConnection; + + TcpReaderThread(TcpConnection par1TcpConnection, String par2Str) { + super(par2Str); + this.theTcpConnection = par1TcpConnection; + } + + public void run() { + TcpConnection.field_74471_a.getAndIncrement(); + + try { + while (TcpConnection.isRunning(this.theTcpConnection) + && !TcpConnection.isServerTerminating(this.theTcpConnection)) { + while (true) { + if (!TcpConnection.readNetworkPacket(this.theTcpConnection)) { + try { + sleep(2L); + } catch (InterruptedException var5) { + ; + } + } + } + } + } finally { + TcpConnection.field_74471_a.getAndDecrement(); + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/TcpWriterThread.java b/sp-server/src/main/java/net/minecraft/src/TcpWriterThread.java new file mode 100644 index 0000000..c3bd28b --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/TcpWriterThread.java @@ -0,0 +1,46 @@ +package net.minecraft.src; + +import java.io.IOException; + +class TcpWriterThread extends Thread { + final TcpConnection theTcpConnection; + + TcpWriterThread(TcpConnection par1TcpConnection, String par2Str) { + super(par2Str); + this.theTcpConnection = par1TcpConnection; + } + + public void run() { + TcpConnection.field_74469_b.getAndIncrement(); + + try { + while (TcpConnection.isRunning(this.theTcpConnection)) { + boolean var1; + + for (var1 = false; TcpConnection.sendNetworkPacket(this.theTcpConnection); var1 = true) { + ; + } + + try { + if (var1 && TcpConnection.getOutputStream(this.theTcpConnection) != null) { + TcpConnection.getOutputStream(this.theTcpConnection).flush(); + } + } catch (IOException var8) { + if (!TcpConnection.isTerminating(this.theTcpConnection)) { + TcpConnection.sendError(this.theTcpConnection, var8); + } + + var8.printStackTrace(); + } + + try { + sleep(2L); + } catch (InterruptedException var7) { + ; + } + } + } finally { + TcpConnection.field_74469_b.getAndDecrement(); + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/Teleporter.java b/sp-server/src/main/java/net/minecraft/src/Teleporter.java new file mode 100644 index 0000000..aeadd1b --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/Teleporter.java @@ -0,0 +1,441 @@ +package net.minecraft.src; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Random; + +public class Teleporter { + private final WorldServer worldServerInstance; + + /** A private Random() function in Teleporter */ + private final Random random; + + /** Stores successful portal placement locations for rapid lookup. */ + private final LongHashMap destinationCoordinateCache = new LongHashMap(); + + /** + * A list of valid keys for the destinationCoordainteCache. These are based on + * the X & Z of the players initial location. + */ + private final List destinationCoordinateKeys = new ArrayList(); + + public Teleporter(WorldServer par1WorldServer) { + this.worldServerInstance = par1WorldServer; + this.random = new Random(par1WorldServer.getSeed()); + } + + /** + * Place an entity in a nearby portal, creating one if necessary. + */ + public void placeInPortal(Entity par1Entity, double par2, double par4, double par6, float par8) { + if (this.worldServerInstance.provider.dimensionId != 1) { + if (!this.placeInExistingPortal(par1Entity, par2, par4, par6, par8)) { + this.makePortal(par1Entity); + this.placeInExistingPortal(par1Entity, par2, par4, par6, par8); + } + } else { + int var9 = MathHelper.floor_double(par1Entity.posX); + int var10 = MathHelper.floor_double(par1Entity.posY) - 1; + int var11 = MathHelper.floor_double(par1Entity.posZ); + byte var12 = 1; + byte var13 = 0; + + for (int var14 = -2; var14 <= 2; ++var14) { + for (int var15 = -2; var15 <= 2; ++var15) { + for (int var16 = -1; var16 < 3; ++var16) { + int var17 = var9 + var15 * var12 + var14 * var13; + int var18 = var10 + var16; + int var19 = var11 + var15 * var13 - var14 * var12; + boolean var20 = var16 < 0; + this.worldServerInstance.setBlock(var17, var18, var19, var20 ? Block.obsidian.blockID : 0); + } + } + } + + par1Entity.setLocationAndAngles((double) var9, (double) var10, (double) var11, par1Entity.rotationYaw, + 0.0F); + par1Entity.motionX = par1Entity.motionY = par1Entity.motionZ = 0.0D; + } + } + + /** + * Place an entity in a nearby portal which already exists. + */ + public boolean placeInExistingPortal(Entity par1Entity, double par2, double par4, double par6, float par8) { + short var9 = 128; + double var10 = -1.0D; + int var12 = 0; + int var13 = 0; + int var14 = 0; + int var15 = MathHelper.floor_double(par1Entity.posX); + int var16 = MathHelper.floor_double(par1Entity.posZ); + long var17 = ChunkCoordIntPair.chunkXZ2Int(var15, var16); + boolean var19 = true; + double var27; + int var48; + + if (this.destinationCoordinateCache.containsItem(var17)) { + PortalPosition var20 = (PortalPosition) this.destinationCoordinateCache.getValueByKey(var17); + var10 = 0.0D; + var12 = var20.posX; + var13 = var20.posY; + var14 = var20.posZ; + var20.lastUpdateTime = this.worldServerInstance.getTotalWorldTime(); + var19 = false; + } else { + for (var48 = var15 - var9; var48 <= var15 + var9; ++var48) { + double var21 = (double) var48 + 0.5D - par1Entity.posX; + + for (int var23 = var16 - var9; var23 <= var16 + var9; ++var23) { + double var24 = (double) var23 + 0.5D - par1Entity.posZ; + + for (int var26 = this.worldServerInstance.getActualHeight() - 1; var26 >= 0; --var26) { + if (this.worldServerInstance.getBlockId(var48, var26, var23) == Block.portal.blockID) { + while (this.worldServerInstance.getBlockId(var48, var26 - 1, + var23) == Block.portal.blockID) { + --var26; + } + + var27 = (double) var26 + 0.5D - par1Entity.posY; + double var29 = var21 * var21 + var27 * var27 + var24 * var24; + + if (var10 < 0.0D || var29 < var10) { + var10 = var29; + var12 = var48; + var13 = var26; + var14 = var23; + } + } + } + } + } + } + + if (var10 >= 0.0D) { + if (var19) { + this.destinationCoordinateCache.add(var17, + new PortalPosition(this, var12, var13, var14, this.worldServerInstance.getTotalWorldTime())); + this.destinationCoordinateKeys.add(Long.valueOf(var17)); + } + + double var49 = (double) var12 + 0.5D; + double var25 = (double) var13 + 0.5D; + var27 = (double) var14 + 0.5D; + int var50 = -1; + + if (this.worldServerInstance.getBlockId(var12 - 1, var13, var14) == Block.portal.blockID) { + var50 = 2; + } + + if (this.worldServerInstance.getBlockId(var12 + 1, var13, var14) == Block.portal.blockID) { + var50 = 0; + } + + if (this.worldServerInstance.getBlockId(var12, var13, var14 - 1) == Block.portal.blockID) { + var50 = 3; + } + + if (this.worldServerInstance.getBlockId(var12, var13, var14 + 1) == Block.portal.blockID) { + var50 = 1; + } + + int var30 = par1Entity.getTeleportDirection(); + + if (var50 > -1) { + int var31 = Direction.rotateLeft[var50]; + int var32 = Direction.offsetX[var50]; + int var33 = Direction.offsetZ[var50]; + int var34 = Direction.offsetX[var31]; + int var35 = Direction.offsetZ[var31]; + boolean var36 = !this.worldServerInstance.isAirBlock(var12 + var32 + var34, var13, + var14 + var33 + var35) + || !this.worldServerInstance.isAirBlock(var12 + var32 + var34, var13 + 1, + var14 + var33 + var35); + boolean var37 = !this.worldServerInstance.isAirBlock(var12 + var32, var13, var14 + var33) + || !this.worldServerInstance.isAirBlock(var12 + var32, var13 + 1, var14 + var33); + + if (var36 && var37) { + var50 = Direction.footInvisibleFaceRemap[var50]; + var31 = Direction.footInvisibleFaceRemap[var31]; + var32 = Direction.offsetX[var50]; + var33 = Direction.offsetZ[var50]; + var34 = Direction.offsetX[var31]; + var35 = Direction.offsetZ[var31]; + var48 = var12 - var34; + var49 -= (double) var34; + int var22 = var14 - var35; + var27 -= (double) var35; + var36 = !this.worldServerInstance.isAirBlock(var48 + var32 + var34, var13, var22 + var33 + var35) + || !this.worldServerInstance.isAirBlock(var48 + var32 + var34, var13 + 1, + var22 + var33 + var35); + var37 = !this.worldServerInstance.isAirBlock(var48 + var32, var13, var22 + var33) + || !this.worldServerInstance.isAirBlock(var48 + var32, var13 + 1, var22 + var33); + } + + float var38 = 0.5F; + float var39 = 0.5F; + + if (!var36 && var37) { + var38 = 1.0F; + } else if (var36 && !var37) { + var38 = 0.0F; + } else if (var36 && var37) { + var39 = 0.0F; + } + + var49 += (double) ((float) var34 * var38 + var39 * (float) var32); + var27 += (double) ((float) var35 * var38 + var39 * (float) var33); + float var40 = 0.0F; + float var41 = 0.0F; + float var42 = 0.0F; + float var43 = 0.0F; + + if (var50 == var30) { + var40 = 1.0F; + var41 = 1.0F; + } else if (var50 == Direction.footInvisibleFaceRemap[var30]) { + var40 = -1.0F; + var41 = -1.0F; + } else if (var50 == Direction.enderEyeMetaToDirection[var30]) { + var42 = 1.0F; + var43 = -1.0F; + } else { + var42 = -1.0F; + var43 = 1.0F; + } + + double var44 = par1Entity.motionX; + double var46 = par1Entity.motionZ; + par1Entity.motionX = var44 * (double) var40 + var46 * (double) var43; + par1Entity.motionZ = var44 * (double) var42 + var46 * (double) var41; + par1Entity.rotationYaw = par8 - (float) (var30 * 90) + (float) (var50 * 90); + } else { + par1Entity.motionX = par1Entity.motionY = par1Entity.motionZ = 0.0D; + } + + par1Entity.setLocationAndAngles(var49, var25, var27, par1Entity.rotationYaw, par1Entity.rotationPitch); + return true; + } else { + return false; + } + } + + public boolean makePortal(Entity par1Entity) { + byte var2 = 16; + double var3 = -1.0D; + int var5 = MathHelper.floor_double(par1Entity.posX); + int var6 = MathHelper.floor_double(par1Entity.posY); + int var7 = MathHelper.floor_double(par1Entity.posZ); + int var8 = var5; + int var9 = var6; + int var10 = var7; + int var11 = 0; + int var12 = this.random.nextInt(4); + int var13; + double var14; + int var16; + double var17; + int var19; + int var20; + int var21; + int var22; + int var23; + int var24; + int var25; + int var26; + int var27; + double var31; + double var32; + + for (var13 = var5 - var2; var13 <= var5 + var2; ++var13) { + var14 = (double) var13 + 0.5D - par1Entity.posX; + + for (var16 = var7 - var2; var16 <= var7 + var2; ++var16) { + var17 = (double) var16 + 0.5D - par1Entity.posZ; + label274: + + for (var19 = this.worldServerInstance.getActualHeight() - 1; var19 >= 0; --var19) { + if (this.worldServerInstance.isAirBlock(var13, var19, var16)) { + while (var19 > 0 && this.worldServerInstance.isAirBlock(var13, var19 - 1, var16)) { + --var19; + } + + for (var20 = var12; var20 < var12 + 4; ++var20) { + var21 = var20 % 2; + var22 = 1 - var21; + + if (var20 % 4 >= 2) { + var21 = -var21; + var22 = -var22; + } + + for (var23 = 0; var23 < 3; ++var23) { + for (var24 = 0; var24 < 4; ++var24) { + for (var25 = -1; var25 < 4; ++var25) { + var26 = var13 + (var24 - 1) * var21 + var23 * var22; + var27 = var19 + var25; + int var28 = var16 + (var24 - 1) * var22 - var23 * var21; + + if (var25 < 0 + && !this.worldServerInstance.getBlockMaterial(var26, var27, var28) + .isSolid() + || var25 >= 0 + && !this.worldServerInstance.isAirBlock(var26, var27, var28)) { + continue label274; + } + } + } + } + + var31 = (double) var19 + 0.5D - par1Entity.posY; + var32 = var14 * var14 + var31 * var31 + var17 * var17; + + if (var3 < 0.0D || var32 < var3) { + var3 = var32; + var8 = var13; + var9 = var19; + var10 = var16; + var11 = var20 % 4; + } + } + } + } + } + } + + if (var3 < 0.0D) { + for (var13 = var5 - var2; var13 <= var5 + var2; ++var13) { + var14 = (double) var13 + 0.5D - par1Entity.posX; + + for (var16 = var7 - var2; var16 <= var7 + var2; ++var16) { + var17 = (double) var16 + 0.5D - par1Entity.posZ; + label222: + + for (var19 = this.worldServerInstance.getActualHeight() - 1; var19 >= 0; --var19) { + if (this.worldServerInstance.isAirBlock(var13, var19, var16)) { + while (var19 > 0 && this.worldServerInstance.isAirBlock(var13, var19 - 1, var16)) { + --var19; + } + + for (var20 = var12; var20 < var12 + 2; ++var20) { + var21 = var20 % 2; + var22 = 1 - var21; + + for (var23 = 0; var23 < 4; ++var23) { + for (var24 = -1; var24 < 4; ++var24) { + var25 = var13 + (var23 - 1) * var21; + var26 = var19 + var24; + var27 = var16 + (var23 - 1) * var22; + + if (var24 < 0 + && !this.worldServerInstance.getBlockMaterial(var25, var26, var27) + .isSolid() + || var24 >= 0 + && !this.worldServerInstance.isAirBlock(var25, var26, var27)) { + continue label222; + } + } + } + + var31 = (double) var19 + 0.5D - par1Entity.posY; + var32 = var14 * var14 + var31 * var31 + var17 * var17; + + if (var3 < 0.0D || var32 < var3) { + var3 = var32; + var8 = var13; + var9 = var19; + var10 = var16; + var11 = var20 % 2; + } + } + } + } + } + } + } + + int var29 = var8; + int var15 = var9; + var16 = var10; + int var30 = var11 % 2; + int var18 = 1 - var30; + + if (var11 % 4 >= 2) { + var30 = -var30; + var18 = -var18; + } + + boolean var33; + + if (var3 < 0.0D) { + if (var9 < 70) { + var9 = 70; + } + + if (var9 > this.worldServerInstance.getActualHeight() - 10) { + var9 = this.worldServerInstance.getActualHeight() - 10; + } + + var15 = var9; + + for (var19 = -1; var19 <= 1; ++var19) { + for (var20 = 1; var20 < 3; ++var20) { + for (var21 = -1; var21 < 3; ++var21) { + var22 = var29 + (var20 - 1) * var30 + var19 * var18; + var23 = var15 + var21; + var24 = var16 + (var20 - 1) * var18 - var19 * var30; + var33 = var21 < 0; + this.worldServerInstance.setBlock(var22, var23, var24, var33 ? Block.obsidian.blockID : 0); + } + } + } + } + + for (var19 = 0; var19 < 4; ++var19) { + for (var20 = 0; var20 < 4; ++var20) { + for (var21 = -1; var21 < 4; ++var21) { + var22 = var29 + (var20 - 1) * var30; + var23 = var15 + var21; + var24 = var16 + (var20 - 1) * var18; + var33 = var20 == 0 || var20 == 3 || var21 == -1 || var21 == 3; + this.worldServerInstance.setBlock(var22, var23, var24, + var33 ? Block.obsidian.blockID : Block.portal.blockID, 0, 2); + } + } + + for (var20 = 0; var20 < 4; ++var20) { + for (var21 = -1; var21 < 4; ++var21) { + var22 = var29 + (var20 - 1) * var30; + var23 = var15 + var21; + var24 = var16 + (var20 - 1) * var18; + this.worldServerInstance.notifyBlocksOfNeighborChange(var22, var23, var24, + this.worldServerInstance.getBlockId(var22, var23, var24)); + } + } + } + + return true; + } + + /** + * called periodically to remove out-of-date portal locations from the cache + * list. Argument par1 is a WorldServer.getTotalWorldTime() value. + */ + public void removeStalePortalLocations(long par1) { + if (par1 % 100L == 0L) { + Iterator var3 = this.destinationCoordinateKeys.iterator(); + long var4 = par1 - 600L; + + while (var3.hasNext()) { + Long var6 = (Long) var3.next(); + PortalPosition var7 = (PortalPosition) this.destinationCoordinateCache.getValueByKey(var6.longValue()); + + if (var7 == null || var7.lastUpdateTime < var4) { + var3.remove(); + this.destinationCoordinateCache.remove(var6.longValue()); + } + } + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ThreadDedicatedServer.java b/sp-server/src/main/java/net/minecraft/src/ThreadDedicatedServer.java new file mode 100644 index 0000000..147e26a --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ThreadDedicatedServer.java @@ -0,0 +1,13 @@ +package net.minecraft.src; + +public final class ThreadDedicatedServer extends Thread { + final DedicatedServer field_96244_a; + + public ThreadDedicatedServer(DedicatedServer par1) { + this.field_96244_a = par1; + } + + public void run() { + this.field_96244_a.stopServer(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ThreadLoginVerifier.java b/sp-server/src/main/java/net/minecraft/src/ThreadLoginVerifier.java new file mode 100644 index 0000000..4e06a2e --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ThreadLoginVerifier.java @@ -0,0 +1,40 @@ +package net.minecraft.src; + +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.math.BigInteger; +import java.net.URL; +import java.net.URLEncoder; + +class ThreadLoginVerifier extends Thread { + /** The login handler that spawned this thread. */ + final NetLoginHandler loginHandler; + + ThreadLoginVerifier(NetLoginHandler par1NetLoginHandler) { + this.loginHandler = par1NetLoginHandler; + } + + public void run() { + try { + String var1 = (new BigInteger(CryptManager.getServerIdHash(NetLoginHandler.getServerId(this.loginHandler), + NetLoginHandler.getLoginMinecraftServer(this.loginHandler).getKeyPair().getPublic(), + NetLoginHandler.getSharedKey(this.loginHandler)))).toString(16); + URL var2 = new URL("http://session.minecraft.net/game/checkserver.jsp?user=" + + URLEncoder.encode(NetLoginHandler.getClientUsername(this.loginHandler), "UTF-8") + "&serverId=" + + URLEncoder.encode(var1, "UTF-8")); + BufferedReader var3 = new BufferedReader(new InputStreamReader(var2.openStream())); + String var4 = var3.readLine(); + var3.close(); + + if (!"YES".equals(var4)) { + this.loginHandler.kickUser("Failed to verify username!"); + return; + } + + NetLoginHandler.func_72531_a(this.loginHandler, true); + } catch (Exception var5) { + this.loginHandler.kickUser("Failed to verify username! [internal error " + var5 + "]"); + var5.printStackTrace(); + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ThreadMinecraftServer.java b/sp-server/src/main/java/net/minecraft/src/ThreadMinecraftServer.java new file mode 100644 index 0000000..d77b48d --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ThreadMinecraftServer.java @@ -0,0 +1,17 @@ +package net.minecraft.src; + +import net.minecraft.server.MinecraftServer; + +public class ThreadMinecraftServer extends Thread { + /** Instance of MinecraftServer. */ + final MinecraftServer theServer; + + public ThreadMinecraftServer(MinecraftServer par1MinecraftServer, String par2Str) { + super(par2Str); + this.theServer = par1MinecraftServer; + } + + public void run() { + this.theServer.run(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/ThreadedFileIOBase.java b/sp-server/src/main/java/net/minecraft/src/ThreadedFileIOBase.java new file mode 100644 index 0000000..8a28186 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/ThreadedFileIOBase.java @@ -0,0 +1,75 @@ +package net.minecraft.src; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class ThreadedFileIOBase implements Runnable { + /** Instance of ThreadedFileIOBase */ + public static final ThreadedFileIOBase threadedIOInstance = new ThreadedFileIOBase(); + private List threadedIOQueue = Collections.synchronizedList(new ArrayList()); + private volatile long writeQueuedCounter = 0L; + private volatile long savedIOCounter = 0L; + private volatile boolean isThreadWaiting = false; + + private ThreadedFileIOBase() { + Thread var1 = new Thread(this, "File IO Thread"); + var1.setPriority(1); + var1.start(); + } + + public void run() { + while (true) { + this.processQueue(); + } + } + + /** + * Process the items that are in the queue + */ + private void processQueue() { + for (int var1 = 0; var1 < this.threadedIOQueue.size(); ++var1) { + IThreadedFileIO var2 = (IThreadedFileIO) this.threadedIOQueue.get(var1); + boolean var3 = var2.writeNextIO(); + + if (!var3) { + this.threadedIOQueue.remove(var1--); + ++this.savedIOCounter; + } + + try { + Thread.sleep(this.isThreadWaiting ? 0L : 10L); + } catch (InterruptedException var6) { + var6.printStackTrace(); + } + } + + if (this.threadedIOQueue.isEmpty()) { + try { + Thread.sleep(25L); + } catch (InterruptedException var5) { + var5.printStackTrace(); + } + } + } + + /** + * threaded io + */ + public void queueIO(IThreadedFileIO par1IThreadedFileIO) { + if (!this.threadedIOQueue.contains(par1IThreadedFileIO)) { + ++this.writeQueuedCounter; + this.threadedIOQueue.add(par1IThreadedFileIO); + } + } + + public void waitForFinish() throws InterruptedException { + this.isThreadWaiting = true; + + while (this.writeQueuedCounter != this.savedIOCounter) { + Thread.sleep(10L); + } + + this.isThreadWaiting = false; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/TileEntity.java b/sp-server/src/main/java/net/minecraft/src/TileEntity.java new file mode 100644 index 0000000..81d202c --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/TileEntity.java @@ -0,0 +1,241 @@ +package net.minecraft.src; + +import java.util.HashMap; +import java.util.Map; +import net.minecraft.server.MinecraftServer; + +public class TileEntity { + /** + * A HashMap storing string names of classes mapping to the actual + * java.lang.Class type. + */ + private static Map nameToClassMap = new HashMap(); + + /** + * A HashMap storing the classes and mapping to the string names (reverse of + * nameToClassMap). + */ + private static Map classToNameMap = new HashMap(); + + /** The reference to the world. */ + protected World worldObj; + + /** The x coordinate of the tile entity. */ + public int xCoord; + + /** The y coordinate of the tile entity. */ + public int yCoord; + + /** The z coordinate of the tile entity. */ + public int zCoord; + protected boolean tileEntityInvalid; + public int blockMetadata = -1; + + /** the Block type that this TileEntity is contained within */ + public Block blockType; + + /** + * Adds a new two-way mapping between the class and its string name in both + * hashmaps. + */ + private static void addMapping(Class par0Class, String par1Str) { + if (nameToClassMap.containsKey(par1Str)) { + throw new IllegalArgumentException("Duplicate id: " + par1Str); + } else { + nameToClassMap.put(par1Str, par0Class); + classToNameMap.put(par0Class, par1Str); + } + } + + /** + * Returns the worldObj for this tileEntity. + */ + public World getWorldObj() { + return this.worldObj; + } + + /** + * Sets the worldObj for this tileEntity. + */ + public void setWorldObj(World par1World) { + this.worldObj = par1World; + } + + public boolean func_70309_m() { + return this.worldObj != null; + } + + /** + * Reads a tile entity from NBT. + */ + public void readFromNBT(NBTTagCompound par1NBTTagCompound) { + this.xCoord = par1NBTTagCompound.getInteger("x"); + this.yCoord = par1NBTTagCompound.getInteger("y"); + this.zCoord = par1NBTTagCompound.getInteger("z"); + } + + /** + * Writes a tile entity to NBT. + */ + public void writeToNBT(NBTTagCompound par1NBTTagCompound) { + String var2 = (String) classToNameMap.get(this.getClass()); + + if (var2 == null) { + throw new RuntimeException(this.getClass() + " is missing a mapping! This is a bug!"); + } else { + par1NBTTagCompound.setString("id", var2); + par1NBTTagCompound.setInteger("x", this.xCoord); + par1NBTTagCompound.setInteger("y", this.yCoord); + par1NBTTagCompound.setInteger("z", this.zCoord); + } + } + + /** + * Allows the entity to update its state. Overridden in most subclasses, e.g. + * the mob spawner uses this to count ticks and creates a new spawn inside its + * implementation. + */ + public void updateEntity() { + } + + /** + * Creates a new entity and loads its data from the specified NBT. + */ + public static TileEntity createAndLoadEntity(NBTTagCompound par0NBTTagCompound) { + TileEntity var1 = null; + + try { + Class var2 = (Class) nameToClassMap.get(par0NBTTagCompound.getString("id")); + + if (var2 != null) { + var1 = (TileEntity) var2.newInstance(); + } + } catch (Exception var3) { + var3.printStackTrace(); + } + + if (var1 != null) { + var1.readFromNBT(par0NBTTagCompound); + } else { + MinecraftServer.getServer().getLogAgent() + .func_98236_b("Skipping TileEntity with id " + par0NBTTagCompound.getString("id")); + } + + return var1; + } + + /** + * Returns block data at the location of this entity (client-only). + */ + public int getBlockMetadata() { + if (this.blockMetadata == -1) { + this.blockMetadata = this.worldObj.getBlockMetadata(this.xCoord, this.yCoord, this.zCoord); + } + + return this.blockMetadata; + } + + /** + * Called when an the contents of an Inventory change, usually + */ + public void onInventoryChanged() { + if (this.worldObj != null) { + this.blockMetadata = this.worldObj.getBlockMetadata(this.xCoord, this.yCoord, this.zCoord); + this.worldObj.updateTileEntityChunkAndDoNothing(this.xCoord, this.yCoord, this.zCoord, this); + + if (this.getBlockType() != null) { + this.worldObj.func_96440_m(this.xCoord, this.yCoord, this.zCoord, this.getBlockType().blockID); + } + } + } + + /** + * Gets the block type at the location of this entity (client-only). + */ + public Block getBlockType() { + if (this.blockType == null) { + this.blockType = Block.blocksList[this.worldObj.getBlockId(this.xCoord, this.yCoord, this.zCoord)]; + } + + return this.blockType; + } + + /** + * Overriden in a sign to provide the text. + */ + public Packet getDescriptionPacket() { + return null; + } + + /** + * returns true if tile entity is invalid, false otherwise + */ + public boolean isInvalid() { + return this.tileEntityInvalid; + } + + /** + * invalidates a tile entity + */ + public void invalidate() { + this.tileEntityInvalid = true; + } + + /** + * validates a tile entity + */ + public void validate() { + this.tileEntityInvalid = false; + } + + /** + * Called when a client event is received with the event number and argument, + * see World.sendClientEvent + */ + public boolean receiveClientEvent(int par1, int par2) { + return false; + } + + /** + * Causes the TileEntity to reset all it's cached values for it's container + * block, blockID, metaData and in the case of chests, the adjcacent chest check + */ + public void updateContainingBlockInfo() { + this.blockType = null; + this.blockMetadata = -1; + } + + public void func_85027_a(CrashReportCategory par1CrashReportCategory) { + par1CrashReportCategory.addCrashSectionCallable("Name", new CallableTileEntityName(this)); + CrashReportCategory.func_85068_a(par1CrashReportCategory, this.xCoord, this.yCoord, this.zCoord, + this.getBlockType().blockID, this.getBlockMetadata()); + par1CrashReportCategory.addCrashSectionCallable("Actual block type", new CallableTileEntityID(this)); + par1CrashReportCategory.addCrashSectionCallable("Actual block data value", new CallableTileEntityData(this)); + } + + static Map getClassToNameMap() { + return classToNameMap; + } + + static { + addMapping(TileEntityFurnace.class, "Furnace"); + addMapping(TileEntityChest.class, "Chest"); + addMapping(TileEntityEnderChest.class, "EnderChest"); + addMapping(TileEntityRecordPlayer.class, "RecordPlayer"); + addMapping(TileEntityDispenser.class, "Trap"); + addMapping(TileEntityDropper.class, "Dropper"); + addMapping(TileEntitySign.class, "Sign"); + addMapping(TileEntityMobSpawner.class, "MobSpawner"); + addMapping(TileEntityNote.class, "Music"); + addMapping(TileEntityPiston.class, "Piston"); + addMapping(TileEntityBrewingStand.class, "Cauldron"); + addMapping(TileEntityEnchantmentTable.class, "EnchantTable"); + addMapping(TileEntityEndPortal.class, "Airportal"); + addMapping(TileEntityCommandBlock.class, "Control"); + addMapping(TileEntityBeacon.class, "Beacon"); + addMapping(TileEntitySkull.class, "Skull"); + addMapping(TileEntityDaylightDetector.class, "DLDetector"); + addMapping(TileEntityHopper.class, "Hopper"); + addMapping(TileEntityComparator.class, "Comparator"); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/TileEntityBeacon.java b/sp-server/src/main/java/net/minecraft/src/TileEntityBeacon.java new file mode 100644 index 0000000..09634ba --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/TileEntityBeacon.java @@ -0,0 +1,311 @@ +package net.minecraft.src; + +import java.util.Iterator; +import java.util.List; + +public class TileEntityBeacon extends TileEntity implements IInventory { + /** List of effects that Beacon can apply */ + public static final Potion[][] effectsList = new Potion[][] { { Potion.moveSpeed, Potion.digSpeed }, + { Potion.resistance, Potion.jump }, { Potion.damageBoost }, { Potion.regeneration } }; + private boolean isBeaconActive; + + /** Level of this beacon's pyramid. */ + private int levels = -1; + + /** Primary potion effect given by this beacon. */ + private int primaryEffect; + + /** Secondary potion effect given by this beacon. */ + private int secondaryEffect; + + /** Item given to this beacon as payment. */ + private ItemStack payment; + private String field_94048_i; + + /** + * Allows the entity to update its state. Overridden in most subclasses, e.g. + * the mob spawner uses this to count ticks and creates a new spawn inside its + * implementation. + */ + public void updateEntity() { + if (this.worldObj.getTotalWorldTime() % 80L == 0L) { + this.updateState(); + this.addEffectsToPlayers(); + } + } + + private void addEffectsToPlayers() { + if (this.isBeaconActive && this.levels > 0 && !this.worldObj.isRemote && this.primaryEffect > 0) { + double var1 = (double) (this.levels * 10 + 10); + byte var3 = 0; + + if (this.levels >= 4 && this.primaryEffect == this.secondaryEffect) { + var3 = 1; + } + + AxisAlignedBB var4 = AxisAlignedBB.getAABBPool() + .getAABB((double) this.xCoord, (double) this.yCoord, (double) this.zCoord, + (double) (this.xCoord + 1), (double) (this.yCoord + 1), (double) (this.zCoord + 1)) + .expand(var1, var1, var1); + var4.maxY = (double) this.worldObj.getHeight(); + List var5 = this.worldObj.getEntitiesWithinAABB(EntityPlayer.class, var4); + Iterator var6 = var5.iterator(); + EntityPlayer var7; + + while (var6.hasNext()) { + var7 = (EntityPlayer) var6.next(); + var7.addPotionEffect(new PotionEffect(this.primaryEffect, 180, var3, true)); + } + + if (this.levels >= 4 && this.primaryEffect != this.secondaryEffect && this.secondaryEffect > 0) { + var6 = var5.iterator(); + + while (var6.hasNext()) { + var7 = (EntityPlayer) var6.next(); + var7.addPotionEffect(new PotionEffect(this.secondaryEffect, 180, 0, true)); + } + } + } + } + + /** + * Checks if the Beacon has a valid pyramid underneath and direct sunlight above + */ + private void updateState() { + if (!this.worldObj.canBlockSeeTheSky(this.xCoord, this.yCoord + 1, this.zCoord)) { + this.isBeaconActive = false; + this.levels = 0; + } else { + this.isBeaconActive = true; + this.levels = 0; + + for (int var1 = 1; var1 <= 4; this.levels = var1++) { + int var2 = this.yCoord - var1; + + if (var2 < 0) { + break; + } + + boolean var3 = true; + + for (int var4 = this.xCoord - var1; var4 <= this.xCoord + var1 && var3; ++var4) { + for (int var5 = this.zCoord - var1; var5 <= this.zCoord + var1; ++var5) { + int var6 = this.worldObj.getBlockId(var4, var2, var5); + + if (var6 != Block.blockEmerald.blockID && var6 != Block.blockGold.blockID + && var6 != Block.blockDiamond.blockID && var6 != Block.blockIron.blockID) { + var3 = false; + break; + } + } + } + + if (!var3) { + break; + } + } + + if (this.levels == 0) { + this.isBeaconActive = false; + } + } + } + + /** + * Return the primary potion effect given by this beacon. + */ + public int getPrimaryEffect() { + return this.primaryEffect; + } + + /** + * Return the secondary potion effect given by this beacon. + */ + public int getSecondaryEffect() { + return this.secondaryEffect; + } + + /** + * Return the levels of this beacon's pyramid. + */ + public int getLevels() { + return this.levels; + } + + public void setPrimaryEffect(int par1) { + this.primaryEffect = 0; + + for (int var2 = 0; var2 < this.levels && var2 < 3; ++var2) { + Potion[] var3 = effectsList[var2]; + int var4 = var3.length; + + for (int var5 = 0; var5 < var4; ++var5) { + Potion var6 = var3[var5]; + + if (var6.id == par1) { + this.primaryEffect = par1; + return; + } + } + } + } + + public void setSecondaryEffect(int par1) { + this.secondaryEffect = 0; + + if (this.levels >= 4) { + for (int var2 = 0; var2 < 4; ++var2) { + Potion[] var3 = effectsList[var2]; + int var4 = var3.length; + + for (int var5 = 0; var5 < var4; ++var5) { + Potion var6 = var3[var5]; + + if (var6.id == par1) { + this.secondaryEffect = par1; + return; + } + } + } + } + } + + /** + * Overriden in a sign to provide the text. + */ + public Packet getDescriptionPacket() { + NBTTagCompound var1 = new NBTTagCompound(); + this.writeToNBT(var1); + return new Packet132TileEntityData(this.xCoord, this.yCoord, this.zCoord, 3, var1); + } + + /** + * Reads a tile entity from NBT. + */ + public void readFromNBT(NBTTagCompound par1NBTTagCompound) { + super.readFromNBT(par1NBTTagCompound); + this.primaryEffect = par1NBTTagCompound.getInteger("Primary"); + this.secondaryEffect = par1NBTTagCompound.getInteger("Secondary"); + this.levels = par1NBTTagCompound.getInteger("Levels"); + } + + /** + * Writes a tile entity to NBT. + */ + public void writeToNBT(NBTTagCompound par1NBTTagCompound) { + super.writeToNBT(par1NBTTagCompound); + par1NBTTagCompound.setInteger("Primary", this.primaryEffect); + par1NBTTagCompound.setInteger("Secondary", this.secondaryEffect); + par1NBTTagCompound.setInteger("Levels", this.levels); + } + + /** + * Returns the number of slots in the inventory. + */ + public int getSizeInventory() { + return 1; + } + + /** + * Returns the stack in slot i + */ + public ItemStack getStackInSlot(int par1) { + return par1 == 0 ? this.payment : null; + } + + /** + * Removes from an inventory slot (first arg) up to a specified number (second + * arg) of items and returns them in a new stack. + */ + public ItemStack decrStackSize(int par1, int par2) { + if (par1 == 0 && this.payment != null) { + if (par2 >= this.payment.stackSize) { + ItemStack var3 = this.payment; + this.payment = null; + return var3; + } else { + this.payment.stackSize -= par2; + return new ItemStack(this.payment.itemID, par2, this.payment.getItemDamage()); + } + } else { + return null; + } + } + + /** + * When some containers are closed they call this on each slot, then drop + * whatever it returns as an EntityItem - like when you close a workbench GUI. + */ + public ItemStack getStackInSlotOnClosing(int par1) { + if (par1 == 0 && this.payment != null) { + ItemStack var2 = this.payment; + this.payment = null; + return var2; + } else { + return null; + } + } + + /** + * Sets the given item stack to the specified slot in the inventory (can be + * crafting or armor sections). + */ + public void setInventorySlotContents(int par1, ItemStack par2ItemStack) { + if (par1 == 0) { + this.payment = par2ItemStack; + } + } + + /** + * Returns the name of the inventory. + */ + public String getInvName() { + return this.isInvNameLocalized() ? this.field_94048_i : "container.beacon"; + } + + /** + * If this returns false, the inventory name will be used as an unlocalized + * name, and translated into the player's language. Otherwise it will be used + * directly. + */ + public boolean isInvNameLocalized() { + return this.field_94048_i != null && this.field_94048_i.length() > 0; + } + + public void func_94047_a(String par1Str) { + this.field_94048_i = par1Str; + } + + /** + * Returns the maximum stack size for a inventory slot. Seems to always be 64, + * possibly will be extended. *Isn't this more of a set than a get?* + */ + public int getInventoryStackLimit() { + return 1; + } + + /** + * Do not make give this method the name canInteractWith because it clashes with + * Container + */ + public boolean isUseableByPlayer(EntityPlayer par1EntityPlayer) { + return this.worldObj.getBlockTileEntity(this.xCoord, this.yCoord, this.zCoord) != this ? false + : par1EntityPlayer.getDistanceSq((double) this.xCoord + 0.5D, (double) this.yCoord + 0.5D, + (double) this.zCoord + 0.5D) <= 64.0D; + } + + public void openChest() { + } + + public void closeChest() { + } + + /** + * Returns true if automation is allowed to insert the given stack (ignoring + * stack size) into the given slot. + */ + public boolean isStackValidForSlot(int par1, ItemStack par2ItemStack) { + return par2ItemStack.itemID == Item.emerald.itemID || par2ItemStack.itemID == Item.diamond.itemID + || par2ItemStack.itemID == Item.ingotGold.itemID || par2ItemStack.itemID == Item.ingotIron.itemID; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/TileEntityBrewingStand.java b/sp-server/src/main/java/net/minecraft/src/TileEntityBrewingStand.java new file mode 100644 index 0000000..08ffcbc --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/TileEntityBrewingStand.java @@ -0,0 +1,332 @@ +package net.minecraft.src; + +import java.util.List; + +public class TileEntityBrewingStand extends TileEntity implements ISidedInventory { + private static final int[] field_102017_a = new int[] { 3 }; + private static final int[] field_102016_b = new int[] { 0, 1, 2 }; + + /** The itemstacks currently placed in the slots of the brewing stand */ + private ItemStack[] brewingItemStacks = new ItemStack[4]; + private int brewTime; + + /** + * an integer with each bit specifying whether that slot of the stand contains a + * potion + */ + private int filledSlots; + private int ingredientID; + private String field_94132_e; + + /** + * Returns the name of the inventory. + */ + public String getInvName() { + return this.isInvNameLocalized() ? this.field_94132_e : "container.brewing"; + } + + /** + * If this returns false, the inventory name will be used as an unlocalized + * name, and translated into the player's language. Otherwise it will be used + * directly. + */ + public boolean isInvNameLocalized() { + return this.field_94132_e != null && this.field_94132_e.length() > 0; + } + + public void func_94131_a(String par1Str) { + this.field_94132_e = par1Str; + } + + /** + * Returns the number of slots in the inventory. + */ + public int getSizeInventory() { + return this.brewingItemStacks.length; + } + + /** + * Allows the entity to update its state. Overridden in most subclasses, e.g. + * the mob spawner uses this to count ticks and creates a new spawn inside its + * implementation. + */ + public void updateEntity() { + if (this.brewTime > 0) { + --this.brewTime; + + if (this.brewTime == 0) { + this.brewPotions(); + this.onInventoryChanged(); + } else if (!this.canBrew()) { + this.brewTime = 0; + this.onInventoryChanged(); + } else if (this.ingredientID != this.brewingItemStacks[3].itemID) { + this.brewTime = 0; + this.onInventoryChanged(); + } + } else if (this.canBrew()) { + this.brewTime = 400; + this.ingredientID = this.brewingItemStacks[3].itemID; + } + + int var1 = this.getFilledSlots(); + + if (var1 != this.filledSlots) { + this.filledSlots = var1; + this.worldObj.setBlockMetadata(this.xCoord, this.yCoord, this.zCoord, var1, 2); + } + + super.updateEntity(); + } + + public int getBrewTime() { + return this.brewTime; + } + + private boolean canBrew() { + if (this.brewingItemStacks[3] != null && this.brewingItemStacks[3].stackSize > 0) { + ItemStack var1 = this.brewingItemStacks[3]; + + if (!Item.itemsList[var1.itemID].isPotionIngredient()) { + return false; + } else { + boolean var2 = false; + + for (int var3 = 0; var3 < 3; ++var3) { + if (this.brewingItemStacks[var3] != null + && this.brewingItemStacks[var3].itemID == Item.potion.itemID) { + int var4 = this.brewingItemStacks[var3].getItemDamage(); + int var5 = this.getPotionResult(var4, var1); + + if (!ItemPotion.isSplash(var4) && ItemPotion.isSplash(var5)) { + var2 = true; + break; + } + + List var6 = Item.potion.getEffects(var4); + List var7 = Item.potion.getEffects(var5); + + if ((var4 <= 0 || var6 != var7) && (var6 == null || !var6.equals(var7) && var7 != null) + && var4 != var5) { + var2 = true; + break; + } + } + } + + return var2; + } + } else { + return false; + } + } + + private void brewPotions() { + if (this.canBrew()) { + ItemStack var1 = this.brewingItemStacks[3]; + + for (int var2 = 0; var2 < 3; ++var2) { + if (this.brewingItemStacks[var2] != null && this.brewingItemStacks[var2].itemID == Item.potion.itemID) { + int var3 = this.brewingItemStacks[var2].getItemDamage(); + int var4 = this.getPotionResult(var3, var1); + List var5 = Item.potion.getEffects(var3); + List var6 = Item.potion.getEffects(var4); + + if ((var3 <= 0 || var5 != var6) && (var5 == null || !var5.equals(var6) && var6 != null)) { + if (var3 != var4) { + this.brewingItemStacks[var2].setItemDamage(var4); + } + } else if (!ItemPotion.isSplash(var3) && ItemPotion.isSplash(var4)) { + this.brewingItemStacks[var2].setItemDamage(var4); + } + } + } + + if (Item.itemsList[var1.itemID].hasContainerItem()) { + this.brewingItemStacks[3] = new ItemStack(Item.itemsList[var1.itemID].getContainerItem()); + } else { + --this.brewingItemStacks[3].stackSize; + + if (this.brewingItemStacks[3].stackSize <= 0) { + this.brewingItemStacks[3] = null; + } + } + } + } + + /** + * Returns the new potion damage value after the specified item is applied as an + * ingredient to the specified potion. + */ + private int getPotionResult(int par1, ItemStack par2ItemStack) { + return par2ItemStack == null ? par1 + : (Item.itemsList[par2ItemStack.itemID].isPotionIngredient() + ? PotionHelper.applyIngredient(par1, Item.itemsList[par2ItemStack.itemID].getPotionEffect()) + : par1); + } + + /** + * Reads a tile entity from NBT. + */ + public void readFromNBT(NBTTagCompound par1NBTTagCompound) { + super.readFromNBT(par1NBTTagCompound); + NBTTagList var2 = par1NBTTagCompound.getTagList("Items"); + this.brewingItemStacks = new ItemStack[this.getSizeInventory()]; + + for (int var3 = 0; var3 < var2.tagCount(); ++var3) { + NBTTagCompound var4 = (NBTTagCompound) var2.tagAt(var3); + byte var5 = var4.getByte("Slot"); + + if (var5 >= 0 && var5 < this.brewingItemStacks.length) { + this.brewingItemStacks[var5] = ItemStack.loadItemStackFromNBT(var4); + } + } + + this.brewTime = par1NBTTagCompound.getShort("BrewTime"); + + if (par1NBTTagCompound.hasKey("CustomName")) { + this.field_94132_e = par1NBTTagCompound.getString("CustomName"); + } + } + + /** + * Writes a tile entity to NBT. + */ + public void writeToNBT(NBTTagCompound par1NBTTagCompound) { + super.writeToNBT(par1NBTTagCompound); + par1NBTTagCompound.setShort("BrewTime", (short) this.brewTime); + NBTTagList var2 = new NBTTagList(); + + for (int var3 = 0; var3 < this.brewingItemStacks.length; ++var3) { + if (this.brewingItemStacks[var3] != null) { + NBTTagCompound var4 = new NBTTagCompound(); + var4.setByte("Slot", (byte) var3); + this.brewingItemStacks[var3].writeToNBT(var4); + var2.appendTag(var4); + } + } + + par1NBTTagCompound.setTag("Items", var2); + + if (this.isInvNameLocalized()) { + par1NBTTagCompound.setString("CustomName", this.field_94132_e); + } + } + + /** + * Returns the stack in slot i + */ + public ItemStack getStackInSlot(int par1) { + return par1 >= 0 && par1 < this.brewingItemStacks.length ? this.brewingItemStacks[par1] : null; + } + + /** + * Removes from an inventory slot (first arg) up to a specified number (second + * arg) of items and returns them in a new stack. + */ + public ItemStack decrStackSize(int par1, int par2) { + if (par1 >= 0 && par1 < this.brewingItemStacks.length) { + ItemStack var3 = this.brewingItemStacks[par1]; + this.brewingItemStacks[par1] = null; + return var3; + } else { + return null; + } + } + + /** + * When some containers are closed they call this on each slot, then drop + * whatever it returns as an EntityItem - like when you close a workbench GUI. + */ + public ItemStack getStackInSlotOnClosing(int par1) { + if (par1 >= 0 && par1 < this.brewingItemStacks.length) { + ItemStack var2 = this.brewingItemStacks[par1]; + this.brewingItemStacks[par1] = null; + return var2; + } else { + return null; + } + } + + /** + * Sets the given item stack to the specified slot in the inventory (can be + * crafting or armor sections). + */ + public void setInventorySlotContents(int par1, ItemStack par2ItemStack) { + if (par1 >= 0 && par1 < this.brewingItemStacks.length) { + this.brewingItemStacks[par1] = par2ItemStack; + } + } + + /** + * Returns the maximum stack size for a inventory slot. Seems to always be 64, + * possibly will be extended. *Isn't this more of a set than a get?* + */ + public int getInventoryStackLimit() { + return 64; + } + + /** + * Do not make give this method the name canInteractWith because it clashes with + * Container + */ + public boolean isUseableByPlayer(EntityPlayer par1EntityPlayer) { + return this.worldObj.getBlockTileEntity(this.xCoord, this.yCoord, this.zCoord) != this ? false + : par1EntityPlayer.getDistanceSq((double) this.xCoord + 0.5D, (double) this.yCoord + 0.5D, + (double) this.zCoord + 0.5D) <= 64.0D; + } + + public void openChest() { + } + + public void closeChest() { + } + + /** + * Returns true if automation is allowed to insert the given stack (ignoring + * stack size) into the given slot. + */ + public boolean isStackValidForSlot(int par1, ItemStack par2ItemStack) { + return par1 == 3 ? Item.itemsList[par2ItemStack.itemID].isPotionIngredient() + : par2ItemStack.itemID == Item.potion.itemID || par2ItemStack.itemID == Item.glassBottle.itemID; + } + + /** + * returns an integer with each bit specifying wether that slot of the stand + * contains a potion + */ + public int getFilledSlots() { + int var1 = 0; + + for (int var2 = 0; var2 < 3; ++var2) { + if (this.brewingItemStacks[var2] != null) { + var1 |= 1 << var2; + } + } + + return var1; + } + + /** + * param side + */ + public int[] getSlotsForFace(int par1) { + return par1 == 1 ? field_102017_a : field_102016_b; + } + + /** + * Returns true if automation can insert the given item in the given slot from + * the given side. Args: Slot, item, side + */ + public boolean canInsertItem(int par1, ItemStack par2ItemStack, int par3) { + return this.isStackValidForSlot(par1, par2ItemStack); + } + + /** + * Returns true if automation can extract the given item in the given slot from + * the given side. Args: Slot, item, side + */ + public boolean canExtractItem(int par1, ItemStack par2ItemStack, int par3) { + return true; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/TileEntityChest.java b/sp-server/src/main/java/net/minecraft/src/TileEntityChest.java new file mode 100644 index 0000000..24af14d --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/TileEntityChest.java @@ -0,0 +1,451 @@ +package net.minecraft.src; + +import java.util.Iterator; +import java.util.List; + +public class TileEntityChest extends TileEntity implements IInventory { + private ItemStack[] chestContents = new ItemStack[36]; + + /** Determines if the check for adjacent chests has taken place. */ + public boolean adjacentChestChecked = false; + + /** Contains the chest tile located adjacent to this one (if any) */ + public TileEntityChest adjacentChestZNeg; + + /** Contains the chest tile located adjacent to this one (if any) */ + public TileEntityChest adjacentChestXPos; + + /** Contains the chest tile located adjacent to this one (if any) */ + public TileEntityChest adjacentChestXNeg; + + /** Contains the chest tile located adjacent to this one (if any) */ + public TileEntityChest adjacentChestZPosition; + + /** The current angle of the lid (between 0 and 1) */ + public float lidAngle; + + /** The angle of the lid last tick */ + public float prevLidAngle; + + /** The number of players currently using this chest */ + public int numUsingPlayers; + + /** Server sync counter (once per 20 ticks) */ + private int ticksSinceSync; + private int field_94046_i = -1; + private String field_94045_s; + + /** + * Returns the number of slots in the inventory. + */ + public int getSizeInventory() { + return 27; + } + + /** + * Returns the stack in slot i + */ + public ItemStack getStackInSlot(int par1) { + return this.chestContents[par1]; + } + + /** + * Removes from an inventory slot (first arg) up to a specified number (second + * arg) of items and returns them in a new stack. + */ + public ItemStack decrStackSize(int par1, int par2) { + if (this.chestContents[par1] != null) { + ItemStack var3; + + if (this.chestContents[par1].stackSize <= par2) { + var3 = this.chestContents[par1]; + this.chestContents[par1] = null; + this.onInventoryChanged(); + return var3; + } else { + var3 = this.chestContents[par1].splitStack(par2); + + if (this.chestContents[par1].stackSize == 0) { + this.chestContents[par1] = null; + } + + this.onInventoryChanged(); + return var3; + } + } else { + return null; + } + } + + /** + * When some containers are closed they call this on each slot, then drop + * whatever it returns as an EntityItem - like when you close a workbench GUI. + */ + public ItemStack getStackInSlotOnClosing(int par1) { + if (this.chestContents[par1] != null) { + ItemStack var2 = this.chestContents[par1]; + this.chestContents[par1] = null; + return var2; + } else { + return null; + } + } + + /** + * Sets the given item stack to the specified slot in the inventory (can be + * crafting or armor sections). + */ + public void setInventorySlotContents(int par1, ItemStack par2ItemStack) { + this.chestContents[par1] = par2ItemStack; + + if (par2ItemStack != null && par2ItemStack.stackSize > this.getInventoryStackLimit()) { + par2ItemStack.stackSize = this.getInventoryStackLimit(); + } + + this.onInventoryChanged(); + } + + /** + * Returns the name of the inventory. + */ + public String getInvName() { + return this.isInvNameLocalized() ? this.field_94045_s : "container.chest"; + } + + /** + * If this returns false, the inventory name will be used as an unlocalized + * name, and translated into the player's language. Otherwise it will be used + * directly. + */ + public boolean isInvNameLocalized() { + return this.field_94045_s != null && this.field_94045_s.length() > 0; + } + + public void func_94043_a(String par1Str) { + this.field_94045_s = par1Str; + } + + /** + * Reads a tile entity from NBT. + */ + public void readFromNBT(NBTTagCompound par1NBTTagCompound) { + super.readFromNBT(par1NBTTagCompound); + NBTTagList var2 = par1NBTTagCompound.getTagList("Items"); + this.chestContents = new ItemStack[this.getSizeInventory()]; + + if (par1NBTTagCompound.hasKey("CustomName")) { + this.field_94045_s = par1NBTTagCompound.getString("CustomName"); + } + + for (int var3 = 0; var3 < var2.tagCount(); ++var3) { + NBTTagCompound var4 = (NBTTagCompound) var2.tagAt(var3); + int var5 = var4.getByte("Slot") & 255; + + if (var5 >= 0 && var5 < this.chestContents.length) { + this.chestContents[var5] = ItemStack.loadItemStackFromNBT(var4); + } + } + } + + /** + * Writes a tile entity to NBT. + */ + public void writeToNBT(NBTTagCompound par1NBTTagCompound) { + super.writeToNBT(par1NBTTagCompound); + NBTTagList var2 = new NBTTagList(); + + for (int var3 = 0; var3 < this.chestContents.length; ++var3) { + if (this.chestContents[var3] != null) { + NBTTagCompound var4 = new NBTTagCompound(); + var4.setByte("Slot", (byte) var3); + this.chestContents[var3].writeToNBT(var4); + var2.appendTag(var4); + } + } + + par1NBTTagCompound.setTag("Items", var2); + + if (this.isInvNameLocalized()) { + par1NBTTagCompound.setString("CustomName", this.field_94045_s); + } + } + + /** + * Returns the maximum stack size for a inventory slot. Seems to always be 64, + * possibly will be extended. *Isn't this more of a set than a get?* + */ + public int getInventoryStackLimit() { + return 64; + } + + /** + * Do not make give this method the name canInteractWith because it clashes with + * Container + */ + public boolean isUseableByPlayer(EntityPlayer par1EntityPlayer) { + return this.worldObj.getBlockTileEntity(this.xCoord, this.yCoord, this.zCoord) != this ? false + : par1EntityPlayer.getDistanceSq((double) this.xCoord + 0.5D, (double) this.yCoord + 0.5D, + (double) this.zCoord + 0.5D) <= 64.0D; + } + + /** + * Causes the TileEntity to reset all it's cached values for it's container + * block, blockID, metaData and in the case of chests, the adjcacent chest check + */ + public void updateContainingBlockInfo() { + super.updateContainingBlockInfo(); + this.adjacentChestChecked = false; + } + + private void func_90009_a(TileEntityChest par1TileEntityChest, int par2) { + if (par1TileEntityChest.isInvalid()) { + this.adjacentChestChecked = false; + } else if (this.adjacentChestChecked) { + switch (par2) { + case 0: + if (this.adjacentChestZPosition != par1TileEntityChest) { + this.adjacentChestChecked = false; + } + + break; + + case 1: + if (this.adjacentChestXNeg != par1TileEntityChest) { + this.adjacentChestChecked = false; + } + + break; + + case 2: + if (this.adjacentChestZNeg != par1TileEntityChest) { + this.adjacentChestChecked = false; + } + + break; + + case 3: + if (this.adjacentChestXPos != par1TileEntityChest) { + this.adjacentChestChecked = false; + } + } + } + } + + /** + * Performs the check for adjacent chests to determine if this chest is double + * or not. + */ + public void checkForAdjacentChests() { + if (!this.adjacentChestChecked) { + this.adjacentChestChecked = true; + this.adjacentChestZNeg = null; + this.adjacentChestXPos = null; + this.adjacentChestXNeg = null; + this.adjacentChestZPosition = null; + + if (this.func_94044_a(this.xCoord - 1, this.yCoord, this.zCoord)) { + this.adjacentChestXNeg = (TileEntityChest) this.worldObj.getBlockTileEntity(this.xCoord - 1, + this.yCoord, this.zCoord); + } + + if (this.func_94044_a(this.xCoord + 1, this.yCoord, this.zCoord)) { + this.adjacentChestXPos = (TileEntityChest) this.worldObj.getBlockTileEntity(this.xCoord + 1, + this.yCoord, this.zCoord); + } + + if (this.func_94044_a(this.xCoord, this.yCoord, this.zCoord - 1)) { + this.adjacentChestZNeg = (TileEntityChest) this.worldObj.getBlockTileEntity(this.xCoord, this.yCoord, + this.zCoord - 1); + } + + if (this.func_94044_a(this.xCoord, this.yCoord, this.zCoord + 1)) { + this.adjacentChestZPosition = (TileEntityChest) this.worldObj.getBlockTileEntity(this.xCoord, + this.yCoord, this.zCoord + 1); + } + + if (this.adjacentChestZNeg != null) { + this.adjacentChestZNeg.func_90009_a(this, 0); + } + + if (this.adjacentChestZPosition != null) { + this.adjacentChestZPosition.func_90009_a(this, 2); + } + + if (this.adjacentChestXPos != null) { + this.adjacentChestXPos.func_90009_a(this, 1); + } + + if (this.adjacentChestXNeg != null) { + this.adjacentChestXNeg.func_90009_a(this, 3); + } + } + } + + private boolean func_94044_a(int par1, int par2, int par3) { + Block var4 = Block.blocksList[this.worldObj.getBlockId(par1, par2, par3)]; + return var4 != null && var4 instanceof BlockChest ? ((BlockChest) var4).isTrapped == this.func_98041_l() + : false; + } + + /** + * Allows the entity to update its state. Overridden in most subclasses, e.g. + * the mob spawner uses this to count ticks and creates a new spawn inside its + * implementation. + */ + public void updateEntity() { + super.updateEntity(); + this.checkForAdjacentChests(); + ++this.ticksSinceSync; + float var1; + + if (!this.worldObj.isRemote && this.numUsingPlayers != 0 + && (this.ticksSinceSync + this.xCoord + this.yCoord + this.zCoord) % 200 == 0) { + this.numUsingPlayers = 0; + var1 = 5.0F; + List var2 = this.worldObj.getEntitiesWithinAABB(EntityPlayer.class, + AxisAlignedBB.getAABBPool().getAABB((double) ((float) this.xCoord - var1), + (double) ((float) this.yCoord - var1), (double) ((float) this.zCoord - var1), + (double) ((float) (this.xCoord + 1) + var1), (double) ((float) (this.yCoord + 1) + var1), + (double) ((float) (this.zCoord + 1) + var1))); + Iterator var3 = var2.iterator(); + + while (var3.hasNext()) { + EntityPlayer var4 = (EntityPlayer) var3.next(); + + if (var4.openContainer instanceof ContainerChest) { + IInventory var5 = ((ContainerChest) var4.openContainer).getLowerChestInventory(); + + if (var5 == this || var5 instanceof InventoryLargeChest + && ((InventoryLargeChest) var5).isPartOfLargeChest(this)) { + ++this.numUsingPlayers; + } + } + } + } + + this.prevLidAngle = this.lidAngle; + var1 = 0.1F; + double var11; + + if (this.numUsingPlayers > 0 && this.lidAngle == 0.0F && this.adjacentChestZNeg == null + && this.adjacentChestXNeg == null) { + double var8 = (double) this.xCoord + 0.5D; + var11 = (double) this.zCoord + 0.5D; + + if (this.adjacentChestZPosition != null) { + var11 += 0.5D; + } + + if (this.adjacentChestXPos != null) { + var8 += 0.5D; + } + + this.worldObj.playSoundEffect(var8, (double) this.yCoord + 0.5D, var11, "random.chestopen", 0.5F, + this.worldObj.rand.nextFloat() * 0.1F + 0.9F); + } + + if (this.numUsingPlayers == 0 && this.lidAngle > 0.0F || this.numUsingPlayers > 0 && this.lidAngle < 1.0F) { + float var9 = this.lidAngle; + + if (this.numUsingPlayers > 0) { + this.lidAngle += var1; + } else { + this.lidAngle -= var1; + } + + if (this.lidAngle > 1.0F) { + this.lidAngle = 1.0F; + } + + float var10 = 0.5F; + + if (this.lidAngle < var10 && var9 >= var10 && this.adjacentChestZNeg == null + && this.adjacentChestXNeg == null) { + var11 = (double) this.xCoord + 0.5D; + double var6 = (double) this.zCoord + 0.5D; + + if (this.adjacentChestZPosition != null) { + var6 += 0.5D; + } + + if (this.adjacentChestXPos != null) { + var11 += 0.5D; + } + + this.worldObj.playSoundEffect(var11, (double) this.yCoord + 0.5D, var6, "random.chestclosed", 0.5F, + this.worldObj.rand.nextFloat() * 0.1F + 0.9F); + } + + if (this.lidAngle < 0.0F) { + this.lidAngle = 0.0F; + } + } + } + + /** + * Called when a client event is received with the event number and argument, + * see World.sendClientEvent + */ + public boolean receiveClientEvent(int par1, int par2) { + if (par1 == 1) { + this.numUsingPlayers = par2; + return true; + } else { + return super.receiveClientEvent(par1, par2); + } + } + + public void openChest() { + if (this.numUsingPlayers < 0) { + this.numUsingPlayers = 0; + } + + ++this.numUsingPlayers; + this.worldObj.addBlockEvent(this.xCoord, this.yCoord, this.zCoord, this.getBlockType().blockID, 1, + this.numUsingPlayers); + this.worldObj.notifyBlocksOfNeighborChange(this.xCoord, this.yCoord, this.zCoord, this.getBlockType().blockID); + this.worldObj.notifyBlocksOfNeighborChange(this.xCoord, this.yCoord - 1, this.zCoord, + this.getBlockType().blockID); + } + + public void closeChest() { + if (this.getBlockType() != null && this.getBlockType() instanceof BlockChest) { + --this.numUsingPlayers; + this.worldObj.addBlockEvent(this.xCoord, this.yCoord, this.zCoord, this.getBlockType().blockID, 1, + this.numUsingPlayers); + this.worldObj.notifyBlocksOfNeighborChange(this.xCoord, this.yCoord, this.zCoord, + this.getBlockType().blockID); + this.worldObj.notifyBlocksOfNeighborChange(this.xCoord, this.yCoord - 1, this.zCoord, + this.getBlockType().blockID); + } + } + + /** + * Returns true if automation is allowed to insert the given stack (ignoring + * stack size) into the given slot. + */ + public boolean isStackValidForSlot(int par1, ItemStack par2ItemStack) { + return true; + } + + /** + * invalidates a tile entity + */ + public void invalidate() { + super.invalidate(); + this.updateContainingBlockInfo(); + this.checkForAdjacentChests(); + } + + public int func_98041_l() { + if (this.field_94046_i == -1) { + if (this.worldObj == null || !(this.getBlockType() instanceof BlockChest)) { + return 0; + } + + this.field_94046_i = ((BlockChest) this.getBlockType()).isTrapped; + } + + return this.field_94046_i; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/TileEntityCommandBlock.java b/sp-server/src/main/java/net/minecraft/src/TileEntityCommandBlock.java new file mode 100644 index 0000000..00a56f8 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/TileEntityCommandBlock.java @@ -0,0 +1,117 @@ +package net.minecraft.src; + +import net.minecraft.server.MinecraftServer; + +public class TileEntityCommandBlock extends TileEntity implements ICommandSender { + private int succesCount = 0; + + /** The command this block will execute when powered. */ + private String command = ""; + + /** The name of command sender (usually username, but possibly "Rcon") */ + private String commandSenderName = "@"; + + /** + * Sets the command this block will execute when powered. + */ + public void setCommand(String par1Str) { + this.command = par1Str; + this.onInventoryChanged(); + } + + /** + * Execute the command, called when the command block is powered. + */ + public int executeCommandOnPowered(World par1World) { + if (par1World.isRemote) { + return 0; + } else { + MinecraftServer var2 = MinecraftServer.getServer(); + + if (var2 != null && var2.isCommandBlockEnabled()) { + ICommandManager var3 = var2.getCommandManager(); + return var3.executeCommand(this, this.command); + } else { + return 0; + } + } + } + + /** + * Gets the name of this command sender (usually username, but possibly "Rcon") + */ + public String getCommandSenderName() { + return this.commandSenderName; + } + + /** + * Sets the name of the command sender + */ + public void setCommandSenderName(String par1Str) { + this.commandSenderName = par1Str; + } + + public void sendChatToPlayer(String par1Str) { + } + + /** + * Returns true if the command sender is allowed to use the given command. + */ + public boolean canCommandSenderUseCommand(int par1, String par2Str) { + return par1 <= 2; + } + + /** + * Translates and formats the given string key with the given arguments. + */ + public String translateString(String par1Str, Object... par2ArrayOfObj) { + return par1Str; + } + + /** + * Writes a tile entity to NBT. + */ + public void writeToNBT(NBTTagCompound par1NBTTagCompound) { + super.writeToNBT(par1NBTTagCompound); + par1NBTTagCompound.setString("Command", this.command); + par1NBTTagCompound.setInteger("SuccessCount", this.succesCount); + par1NBTTagCompound.setString("CustomName", this.commandSenderName); + } + + /** + * Reads a tile entity from NBT. + */ + public void readFromNBT(NBTTagCompound par1NBTTagCompound) { + super.readFromNBT(par1NBTTagCompound); + this.command = par1NBTTagCompound.getString("Command"); + this.succesCount = par1NBTTagCompound.getInteger("SuccessCount"); + + if (par1NBTTagCompound.hasKey("CustomName")) { + this.commandSenderName = par1NBTTagCompound.getString("CustomName"); + } + } + + /** + * Return the position for this command sender. + */ + public ChunkCoordinates getCommandSenderPosition() { + return new ChunkCoordinates(this.xCoord, this.yCoord, this.zCoord); + } + + /** + * Overriden in a sign to provide the text. + */ + public Packet getDescriptionPacket() { + NBTTagCompound var1 = new NBTTagCompound(); + this.writeToNBT(var1); + return new Packet132TileEntityData(this.xCoord, this.yCoord, this.zCoord, 2, var1); + } + + public int func_96103_d() { + return this.succesCount; + } + + public void func_96102_a(int par1) { + this.succesCount = par1; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/TileEntityComparator.java b/sp-server/src/main/java/net/minecraft/src/TileEntityComparator.java new file mode 100644 index 0000000..fb02bff --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/TileEntityComparator.java @@ -0,0 +1,29 @@ +package net.minecraft.src; + +public class TileEntityComparator extends TileEntity { + private int field_96101_a = 0; + + /** + * Writes a tile entity to NBT. + */ + public void writeToNBT(NBTTagCompound par1NBTTagCompound) { + super.writeToNBT(par1NBTTagCompound); + par1NBTTagCompound.setInteger("OutputSignal", this.field_96101_a); + } + + /** + * Reads a tile entity from NBT. + */ + public void readFromNBT(NBTTagCompound par1NBTTagCompound) { + super.readFromNBT(par1NBTTagCompound); + this.field_96101_a = par1NBTTagCompound.getInteger("OutputSignal"); + } + + public int func_96100_a() { + return this.field_96101_a; + } + + public void func_96099_a(int par1) { + this.field_96101_a = par1; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/TileEntityDaylightDetector.java b/sp-server/src/main/java/net/minecraft/src/TileEntityDaylightDetector.java new file mode 100644 index 0000000..a5f06cf --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/TileEntityDaylightDetector.java @@ -0,0 +1,19 @@ +package net.minecraft.src; + +public class TileEntityDaylightDetector extends TileEntity { + /** + * Allows the entity to update its state. Overridden in most subclasses, e.g. + * the mob spawner uses this to count ticks and creates a new spawn inside its + * implementation. + */ + public void updateEntity() { + if (this.worldObj != null && !this.worldObj.isRemote && this.worldObj.getTotalWorldTime() % 20L == 0L) { + this.blockType = this.getBlockType(); + + if (this.blockType != null && this.blockType instanceof BlockDaylightDetector) { + ((BlockDaylightDetector) this.blockType).updateLightLevel(this.worldObj, this.xCoord, this.yCoord, + this.zCoord); + } + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/TileEntityDispenser.java b/sp-server/src/main/java/net/minecraft/src/TileEntityDispenser.java new file mode 100644 index 0000000..6d052a7 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/TileEntityDispenser.java @@ -0,0 +1,207 @@ +package net.minecraft.src; + +import java.util.Random; + +public class TileEntityDispenser extends TileEntity implements IInventory { + private ItemStack[] dispenserContents = new ItemStack[9]; + + /** + * random number generator for instance. Used in random item stack selection. + */ + private Random dispenserRandom = new Random(); + protected String field_94050_c; + + /** + * Returns the number of slots in the inventory. + */ + public int getSizeInventory() { + return 9; + } + + /** + * Returns the stack in slot i + */ + public ItemStack getStackInSlot(int par1) { + return this.dispenserContents[par1]; + } + + /** + * Removes from an inventory slot (first arg) up to a specified number (second + * arg) of items and returns them in a new stack. + */ + public ItemStack decrStackSize(int par1, int par2) { + if (this.dispenserContents[par1] != null) { + ItemStack var3; + + if (this.dispenserContents[par1].stackSize <= par2) { + var3 = this.dispenserContents[par1]; + this.dispenserContents[par1] = null; + this.onInventoryChanged(); + return var3; + } else { + var3 = this.dispenserContents[par1].splitStack(par2); + + if (this.dispenserContents[par1].stackSize == 0) { + this.dispenserContents[par1] = null; + } + + this.onInventoryChanged(); + return var3; + } + } else { + return null; + } + } + + /** + * When some containers are closed they call this on each slot, then drop + * whatever it returns as an EntityItem - like when you close a workbench GUI. + */ + public ItemStack getStackInSlotOnClosing(int par1) { + if (this.dispenserContents[par1] != null) { + ItemStack var2 = this.dispenserContents[par1]; + this.dispenserContents[par1] = null; + return var2; + } else { + return null; + } + } + + public int getRandomStackFromInventory() { + int var1 = -1; + int var2 = 1; + + for (int var3 = 0; var3 < this.dispenserContents.length; ++var3) { + if (this.dispenserContents[var3] != null && this.dispenserRandom.nextInt(var2++) == 0) { + var1 = var3; + } + } + + return var1; + } + + /** + * Sets the given item stack to the specified slot in the inventory (can be + * crafting or armor sections). + */ + public void setInventorySlotContents(int par1, ItemStack par2ItemStack) { + this.dispenserContents[par1] = par2ItemStack; + + if (par2ItemStack != null && par2ItemStack.stackSize > this.getInventoryStackLimit()) { + par2ItemStack.stackSize = this.getInventoryStackLimit(); + } + + this.onInventoryChanged(); + } + + /** + * Add item stack in first available inventory slot + */ + public int addItem(ItemStack par1ItemStack) { + for (int var2 = 0; var2 < this.dispenserContents.length; ++var2) { + if (this.dispenserContents[var2] == null || this.dispenserContents[var2].itemID == 0) { + this.setInventorySlotContents(var2, par1ItemStack); + return var2; + } + } + + return -1; + } + + /** + * Returns the name of the inventory. + */ + public String getInvName() { + return this.isInvNameLocalized() ? this.field_94050_c : "container.dispenser"; + } + + public void func_94049_a(String par1Str) { + this.field_94050_c = par1Str; + } + + /** + * If this returns false, the inventory name will be used as an unlocalized + * name, and translated into the player's language. Otherwise it will be used + * directly. + */ + public boolean isInvNameLocalized() { + return this.field_94050_c != null; + } + + /** + * Reads a tile entity from NBT. + */ + public void readFromNBT(NBTTagCompound par1NBTTagCompound) { + super.readFromNBT(par1NBTTagCompound); + NBTTagList var2 = par1NBTTagCompound.getTagList("Items"); + this.dispenserContents = new ItemStack[this.getSizeInventory()]; + + for (int var3 = 0; var3 < var2.tagCount(); ++var3) { + NBTTagCompound var4 = (NBTTagCompound) var2.tagAt(var3); + int var5 = var4.getByte("Slot") & 255; + + if (var5 >= 0 && var5 < this.dispenserContents.length) { + this.dispenserContents[var5] = ItemStack.loadItemStackFromNBT(var4); + } + } + + if (par1NBTTagCompound.hasKey("CustomName")) { + this.field_94050_c = par1NBTTagCompound.getString("CustomName"); + } + } + + /** + * Writes a tile entity to NBT. + */ + public void writeToNBT(NBTTagCompound par1NBTTagCompound) { + super.writeToNBT(par1NBTTagCompound); + NBTTagList var2 = new NBTTagList(); + + for (int var3 = 0; var3 < this.dispenserContents.length; ++var3) { + if (this.dispenserContents[var3] != null) { + NBTTagCompound var4 = new NBTTagCompound(); + var4.setByte("Slot", (byte) var3); + this.dispenserContents[var3].writeToNBT(var4); + var2.appendTag(var4); + } + } + + par1NBTTagCompound.setTag("Items", var2); + + if (this.isInvNameLocalized()) { + par1NBTTagCompound.setString("CustomName", this.field_94050_c); + } + } + + /** + * Returns the maximum stack size for a inventory slot. Seems to always be 64, + * possibly will be extended. *Isn't this more of a set than a get?* + */ + public int getInventoryStackLimit() { + return 64; + } + + /** + * Do not make give this method the name canInteractWith because it clashes with + * Container + */ + public boolean isUseableByPlayer(EntityPlayer par1EntityPlayer) { + return this.worldObj.getBlockTileEntity(this.xCoord, this.yCoord, this.zCoord) != this ? false + : par1EntityPlayer.getDistanceSq((double) this.xCoord + 0.5D, (double) this.yCoord + 0.5D, + (double) this.zCoord + 0.5D) <= 64.0D; + } + + public void openChest() { + } + + public void closeChest() { + } + + /** + * Returns true if automation is allowed to insert the given stack (ignoring + * stack size) into the given slot. + */ + public boolean isStackValidForSlot(int par1, ItemStack par2ItemStack) { + return true; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/TileEntityDropper.java b/sp-server/src/main/java/net/minecraft/src/TileEntityDropper.java new file mode 100644 index 0000000..7c802b2 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/TileEntityDropper.java @@ -0,0 +1,10 @@ +package net.minecraft.src; + +public class TileEntityDropper extends TileEntityDispenser { + /** + * Returns the name of the inventory. + */ + public String getInvName() { + return this.isInvNameLocalized() ? this.field_94050_c : "container.dropper"; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/TileEntityEnchantmentTable.java b/sp-server/src/main/java/net/minecraft/src/TileEntityEnchantmentTable.java new file mode 100644 index 0000000..7a33f60 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/TileEntityEnchantmentTable.java @@ -0,0 +1,144 @@ +package net.minecraft.src; + +import java.util.Random; + +public class TileEntityEnchantmentTable extends TileEntity { + /** Used by the render to make the book 'bounce' */ + public int tickCount; + + /** Value used for determining how the page flip should look. */ + public float pageFlip; + + /** The last tick's pageFlip value. */ + public float pageFlipPrev; + public float field_70373_d; + public float field_70374_e; + + /** The amount that the book is open. */ + public float bookSpread; + + /** The amount that the book was open last tick. */ + public float bookSpreadPrev; + public float bookRotation2; + public float bookRotationPrev; + public float bookRotation; + private static Random rand = new Random(); + private String field_94136_s; + + /** + * Writes a tile entity to NBT. + */ + public void writeToNBT(NBTTagCompound par1NBTTagCompound) { + super.writeToNBT(par1NBTTagCompound); + + if (this.func_94135_b()) { + par1NBTTagCompound.setString("CustomName", this.field_94136_s); + } + } + + /** + * Reads a tile entity from NBT. + */ + public void readFromNBT(NBTTagCompound par1NBTTagCompound) { + super.readFromNBT(par1NBTTagCompound); + + if (par1NBTTagCompound.hasKey("CustomName")) { + this.field_94136_s = par1NBTTagCompound.getString("CustomName"); + } + } + + /** + * Allows the entity to update its state. Overridden in most subclasses, e.g. + * the mob spawner uses this to count ticks and creates a new spawn inside its + * implementation. + */ + public void updateEntity() { + super.updateEntity(); + this.bookSpreadPrev = this.bookSpread; + this.bookRotationPrev = this.bookRotation2; + EntityPlayer var1 = this.worldObj.getClosestPlayer((double) ((float) this.xCoord + 0.5F), + (double) ((float) this.yCoord + 0.5F), (double) ((float) this.zCoord + 0.5F), 3.0D); + + if (var1 != null) { + double var2 = var1.posX - (double) ((float) this.xCoord + 0.5F); + double var4 = var1.posZ - (double) ((float) this.zCoord + 0.5F); + this.bookRotation = (float) Math.atan2(var4, var2); + this.bookSpread += 0.1F; + + if (this.bookSpread < 0.5F || rand.nextInt(40) == 0) { + float var6 = this.field_70373_d; + + do { + this.field_70373_d += (float) (rand.nextInt(4) - rand.nextInt(4)); + } while (var6 == this.field_70373_d); + } + } else { + this.bookRotation += 0.02F; + this.bookSpread -= 0.1F; + } + + while (this.bookRotation2 >= (float) Math.PI) { + this.bookRotation2 -= ((float) Math.PI * 2F); + } + + while (this.bookRotation2 < -(float) Math.PI) { + this.bookRotation2 += ((float) Math.PI * 2F); + } + + while (this.bookRotation >= (float) Math.PI) { + this.bookRotation -= ((float) Math.PI * 2F); + } + + while (this.bookRotation < -(float) Math.PI) { + this.bookRotation += ((float) Math.PI * 2F); + } + + float var7; + + for (var7 = this.bookRotation - this.bookRotation2; var7 >= (float) Math.PI; var7 -= ((float) Math.PI * 2F)) { + ; + } + + while (var7 < -(float) Math.PI) { + var7 += ((float) Math.PI * 2F); + } + + this.bookRotation2 += var7 * 0.4F; + + if (this.bookSpread < 0.0F) { + this.bookSpread = 0.0F; + } + + if (this.bookSpread > 1.0F) { + this.bookSpread = 1.0F; + } + + ++this.tickCount; + this.pageFlipPrev = this.pageFlip; + float var3 = (this.field_70373_d - this.pageFlip) * 0.4F; + float var8 = 0.2F; + + if (var3 < -var8) { + var3 = -var8; + } + + if (var3 > var8) { + var3 = var8; + } + + this.field_70374_e += (var3 - this.field_70374_e) * 0.9F; + this.pageFlip += this.field_70374_e; + } + + public String func_94133_a() { + return this.func_94135_b() ? this.field_94136_s : "container.enchant"; + } + + public boolean func_94135_b() { + return this.field_94136_s != null && this.field_94136_s.length() > 0; + } + + public void func_94134_a(String par1Str) { + this.field_94136_s = par1Str; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/TileEntityEndPortal.java b/sp-server/src/main/java/net/minecraft/src/TileEntityEndPortal.java new file mode 100644 index 0000000..64b43cc --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/TileEntityEndPortal.java @@ -0,0 +1,4 @@ +package net.minecraft.src; + +public class TileEntityEndPortal extends TileEntity { +} diff --git a/sp-server/src/main/java/net/minecraft/src/TileEntityEnderChest.java b/sp-server/src/main/java/net/minecraft/src/TileEntityEnderChest.java new file mode 100644 index 0000000..1fed3eb --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/TileEntityEnderChest.java @@ -0,0 +1,106 @@ +package net.minecraft.src; + +public class TileEntityEnderChest extends TileEntity { + /** The current angle of the chest lid (between 0 and 1) */ + public float lidAngle; + + /** The angle of the chest lid last tick */ + public float prevLidAngle; + + /** The number of players currently using this ender chest. */ + public int numUsingPlayers; + + /** Server sync counter (once per 20 ticks) */ + private int ticksSinceSync; + + /** + * Allows the entity to update its state. Overridden in most subclasses, e.g. + * the mob spawner uses this to count ticks and creates a new spawn inside its + * implementation. + */ + public void updateEntity() { + super.updateEntity(); + + if (++this.ticksSinceSync % 20 * 4 == 0) { + this.worldObj.addBlockEvent(this.xCoord, this.yCoord, this.zCoord, Block.enderChest.blockID, 1, + this.numUsingPlayers); + } + + this.prevLidAngle = this.lidAngle; + float var1 = 0.1F; + double var4; + + if (this.numUsingPlayers > 0 && this.lidAngle == 0.0F) { + double var2 = (double) this.xCoord + 0.5D; + var4 = (double) this.zCoord + 0.5D; + this.worldObj.playSoundEffect(var2, (double) this.yCoord + 0.5D, var4, "random.chestopen", 0.5F, + this.worldObj.rand.nextFloat() * 0.1F + 0.9F); + } + + if (this.numUsingPlayers == 0 && this.lidAngle > 0.0F || this.numUsingPlayers > 0 && this.lidAngle < 1.0F) { + float var8 = this.lidAngle; + + if (this.numUsingPlayers > 0) { + this.lidAngle += var1; + } else { + this.lidAngle -= var1; + } + + if (this.lidAngle > 1.0F) { + this.lidAngle = 1.0F; + } + + float var3 = 0.5F; + + if (this.lidAngle < var3 && var8 >= var3) { + var4 = (double) this.xCoord + 0.5D; + double var6 = (double) this.zCoord + 0.5D; + this.worldObj.playSoundEffect(var4, (double) this.yCoord + 0.5D, var6, "random.chestclosed", 0.5F, + this.worldObj.rand.nextFloat() * 0.1F + 0.9F); + } + + if (this.lidAngle < 0.0F) { + this.lidAngle = 0.0F; + } + } + } + + /** + * Called when a client event is received with the event number and argument, + * see World.sendClientEvent + */ + public boolean receiveClientEvent(int par1, int par2) { + if (par1 == 1) { + this.numUsingPlayers = par2; + return true; + } else { + return super.receiveClientEvent(par1, par2); + } + } + + /** + * invalidates a tile entity + */ + public void invalidate() { + this.updateContainingBlockInfo(); + super.invalidate(); + } + + public void openChest() { + ++this.numUsingPlayers; + this.worldObj.addBlockEvent(this.xCoord, this.yCoord, this.zCoord, Block.enderChest.blockID, 1, + this.numUsingPlayers); + } + + public void closeChest() { + --this.numUsingPlayers; + this.worldObj.addBlockEvent(this.xCoord, this.yCoord, this.zCoord, Block.enderChest.blockID, 1, + this.numUsingPlayers); + } + + public boolean isUseableByPlayer(EntityPlayer par1EntityPlayer) { + return this.worldObj.getBlockTileEntity(this.xCoord, this.yCoord, this.zCoord) != this ? false + : par1EntityPlayer.getDistanceSq((double) this.xCoord + 0.5D, (double) this.yCoord + 0.5D, + (double) this.zCoord + 0.5D) <= 64.0D; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/TileEntityFurnace.java b/sp-server/src/main/java/net/minecraft/src/TileEntityFurnace.java new file mode 100644 index 0000000..f8c1d08 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/TileEntityFurnace.java @@ -0,0 +1,362 @@ +package net.minecraft.src; + +public class TileEntityFurnace extends TileEntity implements ISidedInventory { + private static final int[] field_102010_d = new int[] { 0 }; + private static final int[] field_102011_e = new int[] { 2, 1 }; + private static final int[] field_102009_f = new int[] { 1 }; + + /** + * The ItemStacks that hold the items currently being used in the furnace + */ + private ItemStack[] furnaceItemStacks = new ItemStack[3]; + + /** The number of ticks that the furnace will keep burning */ + public int furnaceBurnTime = 0; + + /** + * The number of ticks that a fresh copy of the currently-burning item would + * keep the furnace burning for + */ + public int currentItemBurnTime = 0; + + /** The number of ticks that the current item has been cooking for */ + public int furnaceCookTime = 0; + private String field_94130_e; + + /** + * Returns the number of slots in the inventory. + */ + public int getSizeInventory() { + return this.furnaceItemStacks.length; + } + + /** + * Returns the stack in slot i + */ + public ItemStack getStackInSlot(int par1) { + return this.furnaceItemStacks[par1]; + } + + /** + * Removes from an inventory slot (first arg) up to a specified number (second + * arg) of items and returns them in a new stack. + */ + public ItemStack decrStackSize(int par1, int par2) { + if (this.furnaceItemStacks[par1] != null) { + ItemStack var3; + + if (this.furnaceItemStacks[par1].stackSize <= par2) { + var3 = this.furnaceItemStacks[par1]; + this.furnaceItemStacks[par1] = null; + return var3; + } else { + var3 = this.furnaceItemStacks[par1].splitStack(par2); + + if (this.furnaceItemStacks[par1].stackSize == 0) { + this.furnaceItemStacks[par1] = null; + } + + return var3; + } + } else { + return null; + } + } + + /** + * When some containers are closed they call this on each slot, then drop + * whatever it returns as an EntityItem - like when you close a workbench GUI. + */ + public ItemStack getStackInSlotOnClosing(int par1) { + if (this.furnaceItemStacks[par1] != null) { + ItemStack var2 = this.furnaceItemStacks[par1]; + this.furnaceItemStacks[par1] = null; + return var2; + } else { + return null; + } + } + + /** + * Sets the given item stack to the specified slot in the inventory (can be + * crafting or armor sections). + */ + public void setInventorySlotContents(int par1, ItemStack par2ItemStack) { + this.furnaceItemStacks[par1] = par2ItemStack; + + if (par2ItemStack != null && par2ItemStack.stackSize > this.getInventoryStackLimit()) { + par2ItemStack.stackSize = this.getInventoryStackLimit(); + } + } + + /** + * Returns the name of the inventory. + */ + public String getInvName() { + return this.isInvNameLocalized() ? this.field_94130_e : "container.furnace"; + } + + /** + * If this returns false, the inventory name will be used as an unlocalized + * name, and translated into the player's language. Otherwise it will be used + * directly. + */ + public boolean isInvNameLocalized() { + return this.field_94130_e != null && this.field_94130_e.length() > 0; + } + + public void func_94129_a(String par1Str) { + this.field_94130_e = par1Str; + } + + /** + * Reads a tile entity from NBT. + */ + public void readFromNBT(NBTTagCompound par1NBTTagCompound) { + super.readFromNBT(par1NBTTagCompound); + NBTTagList var2 = par1NBTTagCompound.getTagList("Items"); + this.furnaceItemStacks = new ItemStack[this.getSizeInventory()]; + + for (int var3 = 0; var3 < var2.tagCount(); ++var3) { + NBTTagCompound var4 = (NBTTagCompound) var2.tagAt(var3); + byte var5 = var4.getByte("Slot"); + + if (var5 >= 0 && var5 < this.furnaceItemStacks.length) { + this.furnaceItemStacks[var5] = ItemStack.loadItemStackFromNBT(var4); + } + } + + this.furnaceBurnTime = par1NBTTagCompound.getShort("BurnTime"); + this.furnaceCookTime = par1NBTTagCompound.getShort("CookTime"); + this.currentItemBurnTime = getItemBurnTime(this.furnaceItemStacks[1]); + + if (par1NBTTagCompound.hasKey("CustomName")) { + this.field_94130_e = par1NBTTagCompound.getString("CustomName"); + } + } + + /** + * Writes a tile entity to NBT. + */ + public void writeToNBT(NBTTagCompound par1NBTTagCompound) { + super.writeToNBT(par1NBTTagCompound); + par1NBTTagCompound.setShort("BurnTime", (short) this.furnaceBurnTime); + par1NBTTagCompound.setShort("CookTime", (short) this.furnaceCookTime); + NBTTagList var2 = new NBTTagList(); + + for (int var3 = 0; var3 < this.furnaceItemStacks.length; ++var3) { + if (this.furnaceItemStacks[var3] != null) { + NBTTagCompound var4 = new NBTTagCompound(); + var4.setByte("Slot", (byte) var3); + this.furnaceItemStacks[var3].writeToNBT(var4); + var2.appendTag(var4); + } + } + + par1NBTTagCompound.setTag("Items", var2); + + if (this.isInvNameLocalized()) { + par1NBTTagCompound.setString("CustomName", this.field_94130_e); + } + } + + /** + * Returns the maximum stack size for a inventory slot. Seems to always be 64, + * possibly will be extended. *Isn't this more of a set than a get?* + */ + public int getInventoryStackLimit() { + return 64; + } + + /** + * Returns true if the furnace is currently burning + */ + public boolean isBurning() { + return this.furnaceBurnTime > 0; + } + + /** + * Allows the entity to update its state. Overridden in most subclasses, e.g. + * the mob spawner uses this to count ticks and creates a new spawn inside its + * implementation. + */ + public void updateEntity() { + boolean var1 = this.furnaceBurnTime > 0; + boolean var2 = false; + + if (this.furnaceBurnTime > 0) { + --this.furnaceBurnTime; + } + + if (!this.worldObj.isRemote) { + if (this.furnaceBurnTime == 0 && this.canSmelt()) { + this.currentItemBurnTime = this.furnaceBurnTime = getItemBurnTime(this.furnaceItemStacks[1]); + + if (this.furnaceBurnTime > 0) { + var2 = true; + + if (this.furnaceItemStacks[1] != null) { + --this.furnaceItemStacks[1].stackSize; + + if (this.furnaceItemStacks[1].stackSize == 0) { + Item var3 = this.furnaceItemStacks[1].getItem().getContainerItem(); + this.furnaceItemStacks[1] = var3 != null ? new ItemStack(var3) : null; + } + } + } + } + + if (this.isBurning() && this.canSmelt()) { + ++this.furnaceCookTime; + + if (this.furnaceCookTime == 200) { + this.furnaceCookTime = 0; + this.smeltItem(); + var2 = true; + } + } else { + this.furnaceCookTime = 0; + } + + if (var1 != this.furnaceBurnTime > 0) { + var2 = true; + BlockFurnace.updateFurnaceBlockState(this.furnaceBurnTime > 0, this.worldObj, this.xCoord, this.yCoord, + this.zCoord); + } + } + + if (var2) { + this.onInventoryChanged(); + } + } + + /** + * Returns true if the furnace can smelt an item, i.e. has a source item, + * destination stack isn't full, etc. + */ + private boolean canSmelt() { + if (this.furnaceItemStacks[0] == null) { + return false; + } else { + ItemStack var1 = FurnaceRecipes.smelting().getSmeltingResult(this.furnaceItemStacks[0].getItem().itemID); + return var1 == null ? false + : (this.furnaceItemStacks[2] == null ? true + : (!this.furnaceItemStacks[2].isItemEqual(var1) ? false + : (this.furnaceItemStacks[2].stackSize < this.getInventoryStackLimit() + && this.furnaceItemStacks[2].stackSize < this.furnaceItemStacks[2] + .getMaxStackSize() ? true + : this.furnaceItemStacks[2].stackSize < var1 + .getMaxStackSize()))); + } + } + + /** + * Turn one item from the furnace source stack into the appropriate smelted item + * in the furnace result stack + */ + public void smeltItem() { + if (this.canSmelt()) { + ItemStack var1 = FurnaceRecipes.smelting().getSmeltingResult(this.furnaceItemStacks[0].getItem().itemID); + + if (this.furnaceItemStacks[2] == null) { + this.furnaceItemStacks[2] = var1.copy(); + } else if (this.furnaceItemStacks[2].itemID == var1.itemID) { + ++this.furnaceItemStacks[2].stackSize; + } + + --this.furnaceItemStacks[0].stackSize; + + if (this.furnaceItemStacks[0].stackSize <= 0) { + this.furnaceItemStacks[0] = null; + } + } + } + + /** + * Returns the number of ticks that the supplied fuel item will keep the furnace + * burning, or 0 if the item isn't fuel + */ + public static int getItemBurnTime(ItemStack par0ItemStack) { + if (par0ItemStack == null) { + return 0; + } else { + int var1 = par0ItemStack.getItem().itemID; + Item var2 = par0ItemStack.getItem(); + + if (var1 < 256 && Block.blocksList[var1] != null) { + Block var3 = Block.blocksList[var1]; + + if (var3 == Block.woodSingleSlab) { + return 150; + } + + if (var3.blockMaterial == Material.wood) { + return 300; + } + } + + return var2 instanceof ItemTool && ((ItemTool) var2).getToolMaterialName().equals("WOOD") ? 200 + : (var2 instanceof ItemSword && ((ItemSword) var2).getToolMaterialName().equals("WOOD") ? 200 + : (var2 instanceof ItemHoe && ((ItemHoe) var2).getMaterialName().equals("WOOD") ? 200 + : (var1 == Item.stick.itemID ? 100 + : (var1 == Item.coal.itemID ? 1600 + : (var1 == Item.bucketLava.itemID ? 20000 + : (var1 == Block.sapling.blockID ? 100 + : (var1 == Item.blazeRod.itemID ? 2400 : 0))))))); + } + } + + /** + * Return true if item is a fuel source (getItemBurnTime() > 0). + */ + public static boolean isItemFuel(ItemStack par0ItemStack) { + return getItemBurnTime(par0ItemStack) > 0; + } + + /** + * Do not make give this method the name canInteractWith because it clashes with + * Container + */ + public boolean isUseableByPlayer(EntityPlayer par1EntityPlayer) { + return this.worldObj.getBlockTileEntity(this.xCoord, this.yCoord, this.zCoord) != this ? false + : par1EntityPlayer.getDistanceSq((double) this.xCoord + 0.5D, (double) this.yCoord + 0.5D, + (double) this.zCoord + 0.5D) <= 64.0D; + } + + public void openChest() { + } + + public void closeChest() { + } + + /** + * Returns true if automation is allowed to insert the given stack (ignoring + * stack size) into the given slot. + */ + public boolean isStackValidForSlot(int par1, ItemStack par2ItemStack) { + return par1 == 2 ? false : (par1 == 1 ? isItemFuel(par2ItemStack) : true); + } + + /** + * param side + */ + public int[] getSlotsForFace(int par1) { + return par1 == 0 ? field_102011_e : (par1 == 1 ? field_102010_d : field_102009_f); + } + + /** + * Returns true if automation can insert the given item in the given slot from + * the given side. Args: Slot, item, side + */ + public boolean canInsertItem(int par1, ItemStack par2ItemStack, int par3) { + return this.isStackValidForSlot(par1, par2ItemStack); + } + + /** + * Returns true if automation can extract the given item in the given slot from + * the given side. Args: Slot, item, side + */ + public boolean canExtractItem(int par1, ItemStack par2ItemStack, int par3) { + return par3 != 0 || par1 != 1 || par2ItemStack.itemID == Item.bucketEmpty.itemID; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/TileEntityHopper.java b/sp-server/src/main/java/net/minecraft/src/TileEntityHopper.java new file mode 100644 index 0000000..c59607c --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/TileEntityHopper.java @@ -0,0 +1,494 @@ +package net.minecraft.src; + +import java.util.List; + +public class TileEntityHopper extends TileEntity implements Hopper { + private ItemStack[] hopperItemStacks = new ItemStack[5]; + + /** The name that is displayed if the hopper was renamed */ + private String inventoryName; + private int transferCooldown = -1; + + /** + * Reads a tile entity from NBT. + */ + public void readFromNBT(NBTTagCompound par1NBTTagCompound) { + super.readFromNBT(par1NBTTagCompound); + NBTTagList var2 = par1NBTTagCompound.getTagList("Items"); + this.hopperItemStacks = new ItemStack[this.getSizeInventory()]; + + if (par1NBTTagCompound.hasKey("CustomName")) { + this.inventoryName = par1NBTTagCompound.getString("CustomName"); + } + + this.transferCooldown = par1NBTTagCompound.getInteger("TransferCooldown"); + + for (int var3 = 0; var3 < var2.tagCount(); ++var3) { + NBTTagCompound var4 = (NBTTagCompound) var2.tagAt(var3); + byte var5 = var4.getByte("Slot"); + + if (var5 >= 0 && var5 < this.hopperItemStacks.length) { + this.hopperItemStacks[var5] = ItemStack.loadItemStackFromNBT(var4); + } + } + } + + /** + * Writes a tile entity to NBT. + */ + public void writeToNBT(NBTTagCompound par1NBTTagCompound) { + super.writeToNBT(par1NBTTagCompound); + NBTTagList var2 = new NBTTagList(); + + for (int var3 = 0; var3 < this.hopperItemStacks.length; ++var3) { + if (this.hopperItemStacks[var3] != null) { + NBTTagCompound var4 = new NBTTagCompound(); + var4.setByte("Slot", (byte) var3); + this.hopperItemStacks[var3].writeToNBT(var4); + var2.appendTag(var4); + } + } + + par1NBTTagCompound.setTag("Items", var2); + par1NBTTagCompound.setInteger("TransferCooldown", this.transferCooldown); + + if (this.isInvNameLocalized()) { + par1NBTTagCompound.setString("CustomName", this.inventoryName); + } + } + + /** + * Called when an the contents of an Inventory change, usually + */ + public void onInventoryChanged() { + super.onInventoryChanged(); + } + + /** + * Returns the number of slots in the inventory. + */ + public int getSizeInventory() { + return this.hopperItemStacks.length; + } + + /** + * Returns the stack in slot i + */ + public ItemStack getStackInSlot(int par1) { + return this.hopperItemStacks[par1]; + } + + /** + * Removes from an inventory slot (first arg) up to a specified number (second + * arg) of items and returns them in a new stack. + */ + public ItemStack decrStackSize(int par1, int par2) { + if (this.hopperItemStacks[par1] != null) { + ItemStack var3; + + if (this.hopperItemStacks[par1].stackSize <= par2) { + var3 = this.hopperItemStacks[par1]; + this.hopperItemStacks[par1] = null; + return var3; + } else { + var3 = this.hopperItemStacks[par1].splitStack(par2); + + if (this.hopperItemStacks[par1].stackSize == 0) { + this.hopperItemStacks[par1] = null; + } + + return var3; + } + } else { + return null; + } + } + + /** + * When some containers are closed they call this on each slot, then drop + * whatever it returns as an EntityItem - like when you close a workbench GUI. + */ + public ItemStack getStackInSlotOnClosing(int par1) { + if (this.hopperItemStacks[par1] != null) { + ItemStack var2 = this.hopperItemStacks[par1]; + this.hopperItemStacks[par1] = null; + return var2; + } else { + return null; + } + } + + /** + * Sets the given item stack to the specified slot in the inventory (can be + * crafting or armor sections). + */ + public void setInventorySlotContents(int par1, ItemStack par2ItemStack) { + this.hopperItemStacks[par1] = par2ItemStack; + + if (par2ItemStack != null && par2ItemStack.stackSize > this.getInventoryStackLimit()) { + par2ItemStack.stackSize = this.getInventoryStackLimit(); + } + } + + /** + * Returns the name of the inventory. + */ + public String getInvName() { + return this.isInvNameLocalized() ? this.inventoryName : "container.hopper"; + } + + /** + * If this returns false, the inventory name will be used as an unlocalized + * name, and translated into the player's language. Otherwise it will be used + * directly. + */ + public boolean isInvNameLocalized() { + return this.inventoryName != null && this.inventoryName.length() > 0; + } + + public void setInventoryName(String par1Str) { + this.inventoryName = par1Str; + } + + /** + * Returns the maximum stack size for a inventory slot. Seems to always be 64, + * possibly will be extended. *Isn't this more of a set than a get?* + */ + public int getInventoryStackLimit() { + return 64; + } + + /** + * Do not make give this method the name canInteractWith because it clashes with + * Container + */ + public boolean isUseableByPlayer(EntityPlayer par1EntityPlayer) { + return this.worldObj.getBlockTileEntity(this.xCoord, this.yCoord, this.zCoord) != this ? false + : par1EntityPlayer.getDistanceSq((double) this.xCoord + 0.5D, (double) this.yCoord + 0.5D, + (double) this.zCoord + 0.5D) <= 64.0D; + } + + public void openChest() { + } + + public void closeChest() { + } + + /** + * Returns true if automation is allowed to insert the given stack (ignoring + * stack size) into the given slot. + */ + public boolean isStackValidForSlot(int par1, ItemStack par2ItemStack) { + return true; + } + + /** + * Allows the entity to update its state. Overridden in most subclasses, e.g. + * the mob spawner uses this to count ticks and creates a new spawn inside its + * implementation. + */ + public void updateEntity() { + if (this.worldObj != null && !this.worldObj.isRemote) { + --this.transferCooldown; + + if (!this.isCoolingDown()) { + this.setTransferCooldown(0); + this.func_98045_j(); + } + } + } + + public boolean func_98045_j() { + if (this.worldObj != null && !this.worldObj.isRemote) { + if (!this.isCoolingDown() && BlockHopper.getIsBlockNotPoweredFromMetadata(this.getBlockMetadata())) { + boolean var1 = this.insertItemToInventory() | suckItemsIntoHopper(this); + + if (var1) { + this.setTransferCooldown(8); + this.onInventoryChanged(); + return true; + } + } + + return false; + } else { + return false; + } + } + + /** + * Inserts one item from the hopper into the inventory the hopper is pointing + * at. + */ + private boolean insertItemToInventory() { + IInventory var1 = this.getOutputInventory(); + + if (var1 == null) { + return false; + } else { + for (int var2 = 0; var2 < this.getSizeInventory(); ++var2) { + if (this.getStackInSlot(var2) != null) { + ItemStack var3 = this.getStackInSlot(var2).copy(); + ItemStack var4 = insertStack(var1, this.decrStackSize(var2, 1), + Facing.oppositeSide[BlockHopper.getDirectionFromMetadata(this.getBlockMetadata())]); + + if (var4 == null || var4.stackSize == 0) { + var1.onInventoryChanged(); + return true; + } + + this.setInventorySlotContents(var2, var3); + } + } + + return false; + } + } + + /** + * Sucks one item into the given hopper from an inventory or EntityItem above + * it. + */ + public static boolean suckItemsIntoHopper(Hopper par0Hopper) { + IInventory var1 = getInventoryAboveHopper(par0Hopper); + + if (var1 != null) { + byte var2 = 0; + + if (var1 instanceof ISidedInventory && var2 > -1) { + ISidedInventory var7 = (ISidedInventory) var1; + int[] var8 = var7.getSlotsForFace(var2); + + for (int var5 = 0; var5 < var8.length; ++var5) { + if (func_102012_a(par0Hopper, var1, var8[var5], var2)) { + return true; + } + } + } else { + int var3 = var1.getSizeInventory(); + + for (int var4 = 0; var4 < var3; ++var4) { + if (func_102012_a(par0Hopper, var1, var4, var2)) { + return true; + } + } + } + } else { + EntityItem var6 = func_96119_a(par0Hopper.getWorldObj(), par0Hopper.getXPos(), par0Hopper.getYPos() + 1.0D, + par0Hopper.getZPos()); + + if (var6 != null) { + return func_96114_a(par0Hopper, var6); + } + } + + return false; + } + + private static boolean func_102012_a(Hopper par0Hopper, IInventory par1IInventory, int par2, int par3) { + ItemStack var4 = par1IInventory.getStackInSlot(par2); + + if (var4 != null && canExtractItemFromInventory(par1IInventory, var4, par2, par3)) { + ItemStack var5 = var4.copy(); + ItemStack var6 = insertStack(par0Hopper, par1IInventory.decrStackSize(par2, 1), -1); + + if (var6 == null || var6.stackSize == 0) { + par1IInventory.onInventoryChanged(); + return true; + } + + par1IInventory.setInventorySlotContents(par2, var5); + } + + return false; + } + + public static boolean func_96114_a(IInventory par0IInventory, EntityItem par1EntityItem) { + boolean var2 = false; + + if (par1EntityItem == null) { + return false; + } else { + ItemStack var3 = par1EntityItem.getEntityItem().copy(); + ItemStack var4 = insertStack(par0IInventory, var3, -1); + + if (var4 != null && var4.stackSize != 0) { + par1EntityItem.setEntityItemStack(var4); + } else { + var2 = true; + par1EntityItem.setDead(); + } + + return var2; + } + } + + /** + * Inserts a stack into an inventory. Args: Inventory, stack, side. Returns + * leftover items. + */ + public static ItemStack insertStack(IInventory par1IInventory, ItemStack par2ItemStack, int par3) { + if (par1IInventory instanceof ISidedInventory && par3 > -1) { + ISidedInventory var6 = (ISidedInventory) par1IInventory; + int[] var7 = var6.getSlotsForFace(par3); + + for (int var5 = 0; var5 < var7.length && par2ItemStack != null && par2ItemStack.stackSize > 0; ++var5) { + par2ItemStack = func_102014_c(par1IInventory, par2ItemStack, var7[var5], par3); + } + } else { + int var3 = par1IInventory.getSizeInventory(); + + for (int var4 = 0; var4 < var3 && par2ItemStack != null && par2ItemStack.stackSize > 0; ++var4) { + par2ItemStack = func_102014_c(par1IInventory, par2ItemStack, var4, par3); + } + } + + if (par2ItemStack != null && par2ItemStack.stackSize == 0) { + par2ItemStack = null; + } + + return par2ItemStack; + } + + private static boolean func_102015_a(IInventory par0IInventory, ItemStack par1ItemStack, int par2, int par3) { + return !par0IInventory.isStackValidForSlot(par2, par1ItemStack) ? false + : !(par0IInventory instanceof ISidedInventory) + || ((ISidedInventory) par0IInventory).canInsertItem(par2, par1ItemStack, par3); + } + + private static boolean canExtractItemFromInventory(IInventory par0IInventory, ItemStack par1ItemStack, int par2, + int par3) { + return !(par0IInventory instanceof ISidedInventory) + || ((ISidedInventory) par0IInventory).canExtractItem(par2, par1ItemStack, par3); + } + + private static ItemStack func_102014_c(IInventory par0IInventory, ItemStack par1ItemStack, int par2, int par3) { + ItemStack var4 = par0IInventory.getStackInSlot(par2); + + if (func_102015_a(par0IInventory, par1ItemStack, par2, par3)) { + boolean var5 = false; + + if (var4 == null) { + par0IInventory.setInventorySlotContents(par2, par1ItemStack); + par1ItemStack = null; + var5 = true; + } else if (areItemStacksEqualItem(var4, par1ItemStack)) { + int var6 = par1ItemStack.getMaxStackSize() - var4.stackSize; + int var7 = Math.min(par1ItemStack.stackSize, var6); + par1ItemStack.stackSize -= var7; + var4.stackSize += var7; + var5 = var7 > 0; + } + + if (var5) { + if (par0IInventory instanceof TileEntityHopper) { + ((TileEntityHopper) par0IInventory).setTransferCooldown(8); + } + + par0IInventory.onInventoryChanged(); + } + } + + return par1ItemStack; + } + + /** + * Gets the inventory the hopper is pointing at. + */ + private IInventory getOutputInventory() { + int var1 = BlockHopper.getDirectionFromMetadata(this.getBlockMetadata()); + return getInventoryAtLocation(this.getWorldObj(), (double) (this.xCoord + Facing.offsetsXForSide[var1]), + (double) (this.yCoord + Facing.offsetsYForSide[var1]), + (double) (this.zCoord + Facing.offsetsZForSide[var1])); + } + + /** + * Looks for anything, that can hold items (like chests, furnaces, etc.) one + * block above the given hopper. + */ + public static IInventory getInventoryAboveHopper(Hopper par0Hopper) { + return getInventoryAtLocation(par0Hopper.getWorldObj(), par0Hopper.getXPos(), par0Hopper.getYPos() + 1.0D, + par0Hopper.getZPos()); + } + + public static EntityItem func_96119_a(World par0World, double par1, double par3, double par5) { + List var7 = par0World.selectEntitiesWithinAABB(EntityItem.class, + AxisAlignedBB.getAABBPool().getAABB(par1, par3, par5, par1 + 1.0D, par3 + 1.0D, par5 + 1.0D), + IEntitySelector.selectAnything); + return var7.size() > 0 ? (EntityItem) var7.get(0) : null; + } + + /** + * Gets an inventory at the given location to extract items into or take items + * from. Can find either a tile entity or regular entity implementing + * IInventory. + */ + public static IInventory getInventoryAtLocation(World par0World, double par1, double par3, double par5) { + IInventory var7 = null; + int var8 = MathHelper.floor_double(par1); + int var9 = MathHelper.floor_double(par3); + int var10 = MathHelper.floor_double(par5); + TileEntity var11 = par0World.getBlockTileEntity(var8, var9, var10); + + if (var11 != null && var11 instanceof IInventory) { + var7 = (IInventory) var11; + + if (var7 instanceof TileEntityChest) { + int var12 = par0World.getBlockId(var8, var9, var10); + Block var13 = Block.blocksList[var12]; + + if (var13 instanceof BlockChest) { + var7 = ((BlockChest) var13).getInventory(par0World, var8, var9, var10); + } + } + } + + if (var7 == null) { + List var14 = par0World.getEntitiesWithinAABBExcludingEntity((Entity) null, + AxisAlignedBB.getAABBPool().getAABB(par1, par3, par5, par1 + 1.0D, par3 + 1.0D, par5 + 1.0D), + IEntitySelector.selectInventories); + + if (var14 != null && var14.size() > 0) { + var7 = (IInventory) var14.get(par0World.rand.nextInt(var14.size())); + } + } + + return var7; + } + + private static boolean areItemStacksEqualItem(ItemStack par1ItemStack, ItemStack par2ItemStack) { + return par1ItemStack.itemID != par2ItemStack.itemID ? false + : (par1ItemStack.getItemDamage() != par2ItemStack.getItemDamage() ? false + : (par1ItemStack.stackSize > par1ItemStack.getMaxStackSize() ? false + : ItemStack.areItemStackTagsEqual(par1ItemStack, par2ItemStack))); + } + + /** + * Gets the world X position for this hopper entity. + */ + public double getXPos() { + return (double) this.xCoord; + } + + /** + * Gets the world Y position for this hopper entity. + */ + public double getYPos() { + return (double) this.yCoord; + } + + /** + * Gets the world Z position for this hopper entity. + */ + public double getZPos() { + return (double) this.zCoord; + } + + public void setTransferCooldown(int par1) { + this.transferCooldown = par1; + } + + public boolean isCoolingDown() { + return this.transferCooldown > 0; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/TileEntityMobSpawner.java b/sp-server/src/main/java/net/minecraft/src/TileEntityMobSpawner.java new file mode 100644 index 0000000..dfdf0d1 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/TileEntityMobSpawner.java @@ -0,0 +1,53 @@ +package net.minecraft.src; + +public class TileEntityMobSpawner extends TileEntity { + private final MobSpawnerBaseLogic field_98050_a = new TileEntityMobSpawnerLogic(this); + + /** + * Reads a tile entity from NBT. + */ + public void readFromNBT(NBTTagCompound par1NBTTagCompound) { + super.readFromNBT(par1NBTTagCompound); + this.field_98050_a.readFromNBT(par1NBTTagCompound); + } + + /** + * Writes a tile entity to NBT. + */ + public void writeToNBT(NBTTagCompound par1NBTTagCompound) { + super.writeToNBT(par1NBTTagCompound); + this.field_98050_a.writeToNBT(par1NBTTagCompound); + } + + /** + * Allows the entity to update its state. Overridden in most subclasses, e.g. + * the mob spawner uses this to count ticks and creates a new spawn inside its + * implementation. + */ + public void updateEntity() { + this.field_98050_a.updateSpawner(); + super.updateEntity(); + } + + /** + * Overriden in a sign to provide the text. + */ + public Packet getDescriptionPacket() { + NBTTagCompound var1 = new NBTTagCompound(); + this.writeToNBT(var1); + var1.removeTag("SpawnPotentials"); + return new Packet132TileEntityData(this.xCoord, this.yCoord, this.zCoord, 1, var1); + } + + /** + * Called when a client event is received with the event number and argument, + * see World.sendClientEvent + */ + public boolean receiveClientEvent(int par1, int par2) { + return this.field_98050_a.setDelayToMin(par1) ? true : super.receiveClientEvent(par1, par2); + } + + public MobSpawnerBaseLogic func_98049_a() { + return this.field_98050_a; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/TileEntityMobSpawnerLogic.java b/sp-server/src/main/java/net/minecraft/src/TileEntityMobSpawnerLogic.java new file mode 100644 index 0000000..7a32d1f --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/TileEntityMobSpawnerLogic.java @@ -0,0 +1,40 @@ +package net.minecraft.src; + +class TileEntityMobSpawnerLogic extends MobSpawnerBaseLogic { + /** The mob spawner we deal with */ + final TileEntityMobSpawner mobSpawnerEntity; + + TileEntityMobSpawnerLogic(TileEntityMobSpawner par1TileEntityMobSpawner) { + this.mobSpawnerEntity = par1TileEntityMobSpawner; + } + + public void func_98267_a(int par1) { + this.mobSpawnerEntity.worldObj.addBlockEvent(this.mobSpawnerEntity.xCoord, this.mobSpawnerEntity.yCoord, + this.mobSpawnerEntity.zCoord, Block.mobSpawner.blockID, par1, 0); + } + + public World getSpawnerWorld() { + return this.mobSpawnerEntity.worldObj; + } + + public int getSpawnerX() { + return this.mobSpawnerEntity.xCoord; + } + + public int getSpawnerY() { + return this.mobSpawnerEntity.yCoord; + } + + public int getSpawnerZ() { + return this.mobSpawnerEntity.zCoord; + } + + public void setRandomMinecart(WeightedRandomMinecart par1WeightedRandomMinecart) { + super.setRandomMinecart(par1WeightedRandomMinecart); + + if (this.getSpawnerWorld() != null) { + this.getSpawnerWorld().markBlockForUpdate(this.mobSpawnerEntity.xCoord, this.mobSpawnerEntity.yCoord, + this.mobSpawnerEntity.zCoord); + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/TileEntityNote.java b/sp-server/src/main/java/net/minecraft/src/TileEntityNote.java new file mode 100644 index 0000000..1e19519 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/TileEntityNote.java @@ -0,0 +1,69 @@ +package net.minecraft.src; + +public class TileEntityNote extends TileEntity { + /** Note to play */ + public byte note = 0; + + /** stores the latest redstone state */ + public boolean previousRedstoneState = false; + + /** + * Writes a tile entity to NBT. + */ + public void writeToNBT(NBTTagCompound par1NBTTagCompound) { + super.writeToNBT(par1NBTTagCompound); + par1NBTTagCompound.setByte("note", this.note); + } + + /** + * Reads a tile entity from NBT. + */ + public void readFromNBT(NBTTagCompound par1NBTTagCompound) { + super.readFromNBT(par1NBTTagCompound); + this.note = par1NBTTagCompound.getByte("note"); + + if (this.note < 0) { + this.note = 0; + } + + if (this.note > 24) { + this.note = 24; + } + } + + /** + * change pitch by -> (currentPitch + 1) % 25 + */ + public void changePitch() { + this.note = (byte) ((this.note + 1) % 25); + this.onInventoryChanged(); + } + + /** + * plays the stored note + */ + public void triggerNote(World par1World, int par2, int par3, int par4) { + if (par1World.getBlockMaterial(par2, par3 + 1, par4) == Material.air) { + Material var5 = par1World.getBlockMaterial(par2, par3 - 1, par4); + byte var6 = 0; + + if (var5 == Material.rock) { + var6 = 1; + } + + if (var5 == Material.sand) { + var6 = 2; + } + + if (var5 == Material.glass) { + var6 = 3; + } + + if (var5 == Material.wood) { + var6 = 4; + } + + par1World.addBlockEvent(par2, par3, par4, Block.music.blockID, var6, this.note); + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/TileEntityPiston.java b/sp-server/src/main/java/net/minecraft/src/TileEntityPiston.java new file mode 100644 index 0000000..5da2a73 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/TileEntityPiston.java @@ -0,0 +1,171 @@ +package net.minecraft.src; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +public class TileEntityPiston extends TileEntity { + private int storedBlockID; + private int storedMetadata; + + /** the side the front of the piston is on */ + private int storedOrientation; + + /** if this piston is extending or not */ + private boolean extending; + private boolean shouldHeadBeRendered; + private float progress; + + /** the progress in (de)extending */ + private float lastProgress; + private List pushedObjects = new ArrayList(); + + public TileEntityPiston() { + } + + public TileEntityPiston(int par1, int par2, int par3, boolean par4, boolean par5) { + this.storedBlockID = par1; + this.storedMetadata = par2; + this.storedOrientation = par3; + this.extending = par4; + this.shouldHeadBeRendered = par5; + } + + public int getStoredBlockID() { + return this.storedBlockID; + } + + /** + * Returns block data at the location of this entity (client-only). + */ + public int getBlockMetadata() { + return this.storedMetadata; + } + + /** + * Returns true if a piston is extending + */ + public boolean isExtending() { + return this.extending; + } + + /** + * Returns the orientation of the piston as an int + */ + public int getPistonOrientation() { + return this.storedOrientation; + } + + /** + * Get interpolated progress value (between lastProgress and progress) given the + * fractional time between ticks as an argument. + */ + public float getProgress(float par1) { + if (par1 > 1.0F) { + par1 = 1.0F; + } + + return this.lastProgress + (this.progress - this.lastProgress) * par1; + } + + private void updatePushedObjects(float par1, float par2) { + if (this.extending) { + par1 = 1.0F - par1; + } else { + --par1; + } + + AxisAlignedBB var3 = Block.pistonMoving.getAxisAlignedBB(this.worldObj, this.xCoord, this.yCoord, this.zCoord, + this.storedBlockID, par1, this.storedOrientation); + + if (var3 != null) { + List var4 = this.worldObj.getEntitiesWithinAABBExcludingEntity((Entity) null, var3); + + if (!var4.isEmpty()) { + this.pushedObjects.addAll(var4); + Iterator var5 = this.pushedObjects.iterator(); + + while (var5.hasNext()) { + Entity var6 = (Entity) var5.next(); + var6.moveEntity((double) (par2 * (float) Facing.offsetsXForSide[this.storedOrientation]), + (double) (par2 * (float) Facing.offsetsYForSide[this.storedOrientation]), + (double) (par2 * (float) Facing.offsetsZForSide[this.storedOrientation])); + } + + this.pushedObjects.clear(); + } + } + } + + /** + * removes a pistons tile entity (and if the piston is moving, stops it) + */ + public void clearPistonTileEntity() { + if (this.lastProgress < 1.0F && this.worldObj != null) { + this.lastProgress = this.progress = 1.0F; + this.worldObj.removeBlockTileEntity(this.xCoord, this.yCoord, this.zCoord); + this.invalidate(); + + if (this.worldObj.getBlockId(this.xCoord, this.yCoord, this.zCoord) == Block.pistonMoving.blockID) { + this.worldObj.setBlock(this.xCoord, this.yCoord, this.zCoord, this.storedBlockID, this.storedMetadata, + 3); + this.worldObj.notifyBlockOfNeighborChange(this.xCoord, this.yCoord, this.zCoord, this.storedBlockID); + } + } + } + + /** + * Allows the entity to update its state. Overridden in most subclasses, e.g. + * the mob spawner uses this to count ticks and creates a new spawn inside its + * implementation. + */ + public void updateEntity() { + this.lastProgress = this.progress; + + if (this.lastProgress >= 1.0F) { + this.updatePushedObjects(1.0F, 0.25F); + this.worldObj.removeBlockTileEntity(this.xCoord, this.yCoord, this.zCoord); + this.invalidate(); + + if (this.worldObj.getBlockId(this.xCoord, this.yCoord, this.zCoord) == Block.pistonMoving.blockID) { + this.worldObj.setBlock(this.xCoord, this.yCoord, this.zCoord, this.storedBlockID, this.storedMetadata, + 3); + this.worldObj.notifyBlockOfNeighborChange(this.xCoord, this.yCoord, this.zCoord, this.storedBlockID); + } + } else { + this.progress += 0.5F; + + if (this.progress >= 1.0F) { + this.progress = 1.0F; + } + + if (this.extending) { + this.updatePushedObjects(this.progress, this.progress - this.lastProgress + 0.0625F); + } + } + } + + /** + * Reads a tile entity from NBT. + */ + public void readFromNBT(NBTTagCompound par1NBTTagCompound) { + super.readFromNBT(par1NBTTagCompound); + this.storedBlockID = par1NBTTagCompound.getInteger("blockId"); + this.storedMetadata = par1NBTTagCompound.getInteger("blockData"); + this.storedOrientation = par1NBTTagCompound.getInteger("facing"); + this.lastProgress = this.progress = par1NBTTagCompound.getFloat("progress"); + this.extending = par1NBTTagCompound.getBoolean("extending"); + } + + /** + * Writes a tile entity to NBT. + */ + public void writeToNBT(NBTTagCompound par1NBTTagCompound) { + super.writeToNBT(par1NBTTagCompound); + par1NBTTagCompound.setInteger("blockId", this.storedBlockID); + par1NBTTagCompound.setInteger("blockData", this.storedMetadata); + par1NBTTagCompound.setInteger("facing", this.storedOrientation); + par1NBTTagCompound.setFloat("progress", this.lastProgress); + par1NBTTagCompound.setBoolean("extending", this.extending); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/TileEntityRecordPlayer.java b/sp-server/src/main/java/net/minecraft/src/TileEntityRecordPlayer.java new file mode 100644 index 0000000..dc72931 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/TileEntityRecordPlayer.java @@ -0,0 +1,40 @@ +package net.minecraft.src; + +public class TileEntityRecordPlayer extends TileEntity { + /** ID of record which is in Jukebox */ + private ItemStack record; + + /** + * Reads a tile entity from NBT. + */ + public void readFromNBT(NBTTagCompound par1NBTTagCompound) { + super.readFromNBT(par1NBTTagCompound); + + if (par1NBTTagCompound.hasKey("RecordItem")) { + this.func_96098_a(ItemStack.loadItemStackFromNBT(par1NBTTagCompound.getCompoundTag("RecordItem"))); + } else if (par1NBTTagCompound.getInteger("Record") > 0) { + this.func_96098_a(new ItemStack(par1NBTTagCompound.getInteger("Record"), 1, 0)); + } + } + + /** + * Writes a tile entity to NBT. + */ + public void writeToNBT(NBTTagCompound par1NBTTagCompound) { + super.writeToNBT(par1NBTTagCompound); + + if (this.func_96097_a() != null) { + par1NBTTagCompound.setCompoundTag("RecordItem", this.func_96097_a().writeToNBT(new NBTTagCompound())); + par1NBTTagCompound.setInteger("Record", this.func_96097_a().itemID); + } + } + + public ItemStack func_96097_a() { + return this.record; + } + + public void func_96098_a(ItemStack par1ItemStack) { + this.record = par1ItemStack; + this.onInventoryChanged(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/TileEntitySign.java b/sp-server/src/main/java/net/minecraft/src/TileEntitySign.java new file mode 100644 index 0000000..dfa3d88 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/TileEntitySign.java @@ -0,0 +1,54 @@ +package net.minecraft.src; + +public class TileEntitySign extends TileEntity { + /** An array of four strings storing the lines of text on the sign. */ + public String[] signText = new String[] { "", "", "", "" }; + + /** + * The index of the line currently being edited. Only used on client side, but + * defined on both. Note this is only really used when the > < are going to be + * visible. + */ + public int lineBeingEdited = -1; + private boolean isEditable = true; + + /** + * Writes a tile entity to NBT. + */ + public void writeToNBT(NBTTagCompound par1NBTTagCompound) { + super.writeToNBT(par1NBTTagCompound); + par1NBTTagCompound.setString("Text1", this.signText[0]); + par1NBTTagCompound.setString("Text2", this.signText[1]); + par1NBTTagCompound.setString("Text3", this.signText[2]); + par1NBTTagCompound.setString("Text4", this.signText[3]); + } + + /** + * Reads a tile entity from NBT. + */ + public void readFromNBT(NBTTagCompound par1NBTTagCompound) { + this.isEditable = false; + super.readFromNBT(par1NBTTagCompound); + + for (int var2 = 0; var2 < 4; ++var2) { + this.signText[var2] = par1NBTTagCompound.getString("Text" + (var2 + 1)); + + if (this.signText[var2].length() > 15) { + this.signText[var2] = this.signText[var2].substring(0, 15); + } + } + } + + /** + * Overriden in a sign to provide the text. + */ + public Packet getDescriptionPacket() { + String[] var1 = new String[4]; + System.arraycopy(this.signText, 0, var1, 0, 4); + return new Packet130UpdateSign(this.xCoord, this.yCoord, this.zCoord, var1); + } + + public boolean isEditable() { + return this.isEditable; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/TileEntitySkull.java b/sp-server/src/main/java/net/minecraft/src/TileEntitySkull.java new file mode 100644 index 0000000..79d33a5 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/TileEntitySkull.java @@ -0,0 +1,73 @@ +package net.minecraft.src; + +public class TileEntitySkull extends TileEntity { + /** Entity type for this skull. */ + private int skullType; + + /** The skull's rotation. */ + private int skullRotation; + + /** Extra data for this skull, used as player username by player heads */ + private String extraType = ""; + + /** + * Writes a tile entity to NBT. + */ + public void writeToNBT(NBTTagCompound par1NBTTagCompound) { + super.writeToNBT(par1NBTTagCompound); + par1NBTTagCompound.setByte("SkullType", (byte) (this.skullType & 255)); + par1NBTTagCompound.setByte("Rot", (byte) (this.skullRotation & 255)); + par1NBTTagCompound.setString("ExtraType", this.extraType); + } + + /** + * Reads a tile entity from NBT. + */ + public void readFromNBT(NBTTagCompound par1NBTTagCompound) { + super.readFromNBT(par1NBTTagCompound); + this.skullType = par1NBTTagCompound.getByte("SkullType"); + this.skullRotation = par1NBTTagCompound.getByte("Rot"); + + if (par1NBTTagCompound.hasKey("ExtraType")) { + this.extraType = par1NBTTagCompound.getString("ExtraType"); + } + } + + /** + * Overriden in a sign to provide the text. + */ + public Packet getDescriptionPacket() { + NBTTagCompound var1 = new NBTTagCompound(); + this.writeToNBT(var1); + return new Packet132TileEntityData(this.xCoord, this.yCoord, this.zCoord, 4, var1); + } + + /** + * Set the entity type for the skull + */ + public void setSkullType(int par1, String par2Str) { + this.skullType = par1; + this.extraType = par2Str; + } + + /** + * Get the entity type for the skull + */ + public int getSkullType() { + return this.skullType; + } + + /** + * Set the skull's rotation + */ + public void setSkullRotation(int par1) { + this.skullRotation = par1; + } + + /** + * Get the extra data foor this skull, used as player username by player heads + */ + public String getExtraType() { + return this.extraType; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/Tuple.java b/sp-server/src/main/java/net/minecraft/src/Tuple.java new file mode 100644 index 0000000..0cb4453 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/Tuple.java @@ -0,0 +1,28 @@ +package net.minecraft.src; + +public class Tuple { + /** First Object in the Tuple */ + private Object first; + + /** Second Object in the Tuple */ + private Object second; + + public Tuple(Object par1Obj, Object par2Obj) { + this.first = par1Obj; + this.second = par2Obj; + } + + /** + * Get the first Object in the Tuple + */ + public Object getFirst() { + return this.first; + } + + /** + * Get the second Object in the Tuple + */ + public Object getSecond() { + return this.second; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/Vec3.java b/sp-server/src/main/java/net/minecraft/src/Vec3.java new file mode 100644 index 0000000..7d7b721 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/Vec3.java @@ -0,0 +1,210 @@ +package net.minecraft.src; + +public class Vec3 { + /** + * A global Vec3Pool that always creates new vectors instead of reusing them and + * is thread-safe. + */ + public static final Vec3Pool fakePool = new Vec3Pool(-1, -1); + public final Vec3Pool myVec3LocalPool; + + /** X coordinate of Vec3D */ + public double xCoord; + + /** Y coordinate of Vec3D */ + public double yCoord; + + /** Z coordinate of Vec3D */ + public double zCoord; + + /** + * Static method for creating a new Vec3D given the three x,y,z values. This is + * only called from the other static method which creates and places it in the + * list. + */ + public static Vec3 createVectorHelper(double par0, double par2, double par4) { + return new Vec3(fakePool, par0, par2, par4); + } + + protected Vec3(Vec3Pool par1Vec3Pool, double par2, double par4, double par6) { + if (par2 == -0.0D) { + par2 = 0.0D; + } + + if (par4 == -0.0D) { + par4 = 0.0D; + } + + if (par6 == -0.0D) { + par6 = 0.0D; + } + + this.xCoord = par2; + this.yCoord = par4; + this.zCoord = par6; + this.myVec3LocalPool = par1Vec3Pool; + } + + /** + * Sets the x,y,z components of the vector as specified. + */ + protected Vec3 setComponents(double par1, double par3, double par5) { + this.xCoord = par1; + this.yCoord = par3; + this.zCoord = par5; + return this; + } + + /** + * Normalizes the vector to a length of 1 (except if it is the zero vector) + */ + public Vec3 normalize() { + double var1 = (double) MathHelper + .sqrt_double(this.xCoord * this.xCoord + this.yCoord * this.yCoord + this.zCoord * this.zCoord); + return var1 < 1.0E-4D ? this.myVec3LocalPool.getVecFromPool(0.0D, 0.0D, 0.0D) + : this.myVec3LocalPool.getVecFromPool(this.xCoord / var1, this.yCoord / var1, this.zCoord / var1); + } + + public double dotProduct(Vec3 par1Vec3) { + return this.xCoord * par1Vec3.xCoord + this.yCoord * par1Vec3.yCoord + this.zCoord * par1Vec3.zCoord; + } + + /** + * Adds the specified x,y,z vector components to this vector and returns the + * resulting vector. Does not change this vector. + */ + public Vec3 addVector(double par1, double par3, double par5) { + return this.myVec3LocalPool.getVecFromPool(this.xCoord + par1, this.yCoord + par3, this.zCoord + par5); + } + + /** + * Euclidean distance between this and the specified vector, returned as double. + */ + public double distanceTo(Vec3 par1Vec3) { + double var2 = par1Vec3.xCoord - this.xCoord; + double var4 = par1Vec3.yCoord - this.yCoord; + double var6 = par1Vec3.zCoord - this.zCoord; + return (double) MathHelper.sqrt_double(var2 * var2 + var4 * var4 + var6 * var6); + } + + /** + * The square of the Euclidean distance between this and the specified vector. + */ + public double squareDistanceTo(Vec3 par1Vec3) { + double var2 = par1Vec3.xCoord - this.xCoord; + double var4 = par1Vec3.yCoord - this.yCoord; + double var6 = par1Vec3.zCoord - this.zCoord; + return var2 * var2 + var4 * var4 + var6 * var6; + } + + /** + * The square of the Euclidean distance between this and the vector of x,y,z + * components passed in. + */ + public double squareDistanceTo(double par1, double par3, double par5) { + double var7 = par1 - this.xCoord; + double var9 = par3 - this.yCoord; + double var11 = par5 - this.zCoord; + return var7 * var7 + var9 * var9 + var11 * var11; + } + + /** + * Returns the length of the vector. + */ + public double lengthVector() { + return (double) MathHelper + .sqrt_double(this.xCoord * this.xCoord + this.yCoord * this.yCoord + this.zCoord * this.zCoord); + } + + /** + * Returns a new vector with x value equal to the second parameter, along the + * line between this vector and the passed in vector, or null if not possible. + */ + public Vec3 getIntermediateWithXValue(Vec3 par1Vec3, double par2) { + double var4 = par1Vec3.xCoord - this.xCoord; + double var6 = par1Vec3.yCoord - this.yCoord; + double var8 = par1Vec3.zCoord - this.zCoord; + + if (var4 * var4 < 1.0000000116860974E-7D) { + return null; + } else { + double var10 = (par2 - this.xCoord) / var4; + return var10 >= 0.0D && var10 <= 1.0D + ? this.myVec3LocalPool.getVecFromPool(this.xCoord + var4 * var10, this.yCoord + var6 * var10, + this.zCoord + var8 * var10) + : null; + } + } + + /** + * Returns a new vector with y value equal to the second parameter, along the + * line between this vector and the passed in vector, or null if not possible. + */ + public Vec3 getIntermediateWithYValue(Vec3 par1Vec3, double par2) { + double var4 = par1Vec3.xCoord - this.xCoord; + double var6 = par1Vec3.yCoord - this.yCoord; + double var8 = par1Vec3.zCoord - this.zCoord; + + if (var6 * var6 < 1.0000000116860974E-7D) { + return null; + } else { + double var10 = (par2 - this.yCoord) / var6; + return var10 >= 0.0D && var10 <= 1.0D + ? this.myVec3LocalPool.getVecFromPool(this.xCoord + var4 * var10, this.yCoord + var6 * var10, + this.zCoord + var8 * var10) + : null; + } + } + + /** + * Returns a new vector with z value equal to the second parameter, along the + * line between this vector and the passed in vector, or null if not possible. + */ + public Vec3 getIntermediateWithZValue(Vec3 par1Vec3, double par2) { + double var4 = par1Vec3.xCoord - this.xCoord; + double var6 = par1Vec3.yCoord - this.yCoord; + double var8 = par1Vec3.zCoord - this.zCoord; + + if (var8 * var8 < 1.0000000116860974E-7D) { + return null; + } else { + double var10 = (par2 - this.zCoord) / var8; + return var10 >= 0.0D && var10 <= 1.0D + ? this.myVec3LocalPool.getVecFromPool(this.xCoord + var4 * var10, this.yCoord + var6 * var10, + this.zCoord + var8 * var10) + : null; + } + } + + public String toString() { + return "(" + this.xCoord + ", " + this.yCoord + ", " + this.zCoord + ")"; + } + + /** + * Rotates the vector around the x axis by the specified angle. + */ + public void rotateAroundX(float par1) { + float var2 = MathHelper.cos(par1); + float var3 = MathHelper.sin(par1); + double var4 = this.xCoord; + double var6 = this.yCoord * (double) var2 + this.zCoord * (double) var3; + double var8 = this.zCoord * (double) var2 - this.yCoord * (double) var3; + this.xCoord = var4; + this.yCoord = var6; + this.zCoord = var8; + } + + /** + * Rotates the vector around the y axis by the specified angle. + */ + public void rotateAroundY(float par1) { + float var2 = MathHelper.cos(par1); + float var3 = MathHelper.sin(par1); + double var4 = this.xCoord * (double) var2 + this.zCoord * (double) var3; + double var6 = this.yCoord; + double var8 = this.zCoord * (double) var2 - this.xCoord * (double) var3; + this.xCoord = var4; + this.yCoord = var6; + this.zCoord = var8; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/Vec3Pool.java b/sp-server/src/main/java/net/minecraft/src/Vec3Pool.java new file mode 100644 index 0000000..0cb0c97 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/Vec3Pool.java @@ -0,0 +1,79 @@ +package net.minecraft.src; + +import java.util.ArrayList; +import java.util.List; + +public class Vec3Pool { + private final int truncateArrayResetThreshold; + private final int minimumSize; + + /** items at and above nextFreeSpace are assumed to be available */ + private final List vec3Cache = new ArrayList(); + private int nextFreeSpace = 0; + private int maximumSizeSinceLastTruncation = 0; + private int resetCount = 0; + + public Vec3Pool(int par1, int par2) { + this.truncateArrayResetThreshold = par1; + this.minimumSize = par2; + } + + /** + * extends the pool if all vecs are currently "out" + */ + public Vec3 getVecFromPool(double par1, double par3, double par5) { + if (this.func_82589_e()) { + return new Vec3(this, par1, par3, par5); + } else { + Vec3 var7; + + if (this.nextFreeSpace >= this.vec3Cache.size()) { + var7 = new Vec3(this, par1, par3, par5); + this.vec3Cache.add(var7); + } else { + var7 = (Vec3) this.vec3Cache.get(this.nextFreeSpace); + var7.setComponents(par1, par3, par5); + } + + ++this.nextFreeSpace; + return var7; + } + } + + /** + * Will truncate the array everyN clears to the maximum size observed since the + * last truncation. + */ + public void clear() { + if (!this.func_82589_e()) { + if (this.nextFreeSpace > this.maximumSizeSinceLastTruncation) { + this.maximumSizeSinceLastTruncation = this.nextFreeSpace; + } + + if (this.resetCount++ == this.truncateArrayResetThreshold) { + int var1 = Math.max(this.maximumSizeSinceLastTruncation, this.vec3Cache.size() - this.minimumSize); + + while (this.vec3Cache.size() > var1) { + this.vec3Cache.remove(var1); + } + + this.maximumSizeSinceLastTruncation = 0; + this.resetCount = 0; + } + + this.nextFreeSpace = 0; + } + } + + public int getPoolSize() { + return this.vec3Cache.size(); + } + + public int func_82590_d() { + return this.nextFreeSpace; + } + + private boolean func_82589_e() { + return this.minimumSize < 0 || this.truncateArrayResetThreshold < 0; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/Village.java b/sp-server/src/main/java/net/minecraft/src/Village.java new file mode 100644 index 0000000..6521897 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/Village.java @@ -0,0 +1,514 @@ +package net.minecraft.src; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.TreeMap; + +public class Village { + private World worldObj; + + /** list of VillageDoorInfo objects */ + private final List villageDoorInfoList = new ArrayList(); + + /** + * This is the sum of all door coordinates and used to calculate the actual + * village center by dividing by the number of doors. + */ + private final ChunkCoordinates centerHelper = new ChunkCoordinates(0, 0, 0); + + /** This is the actual village center. */ + private final ChunkCoordinates center = new ChunkCoordinates(0, 0, 0); + private int villageRadius = 0; + private int lastAddDoorTimestamp = 0; + private int tickCounter = 0; + private int numVillagers = 0; + + /** Timestamp of tick count when villager last bred */ + private int noBreedTicks; + + /** List of player reputations with this village */ + private TreeMap playerReputation = new TreeMap(); + private List villageAgressors = new ArrayList(); + private int numIronGolems = 0; + + public Village() { + } + + public Village(World par1World) { + this.worldObj = par1World; + } + + public void func_82691_a(World par1World) { + this.worldObj = par1World; + } + + /** + * Called periodically by VillageCollection + */ + public void tick(int par1) { + this.tickCounter = par1; + this.removeDeadAndOutOfRangeDoors(); + this.removeDeadAndOldAgressors(); + + if (par1 % 20 == 0) { + this.updateNumVillagers(); + } + + if (par1 % 30 == 0) { + this.updateNumIronGolems(); + } + + int var2 = this.numVillagers / 10; + + if (this.numIronGolems < var2 && this.villageDoorInfoList.size() > 20 + && this.worldObj.rand.nextInt(7000) == 0) { + Vec3 var3 = this.tryGetIronGolemSpawningLocation(MathHelper.floor_float((float) this.center.posX), + MathHelper.floor_float((float) this.center.posY), MathHelper.floor_float((float) this.center.posZ), + 2, 4, 2); + + if (var3 != null) { + EntityIronGolem var4 = new EntityIronGolem(this.worldObj); + var4.setPosition(var3.xCoord, var3.yCoord, var3.zCoord); + this.worldObj.spawnEntityInWorld(var4); + ++this.numIronGolems; + } + } + } + + /** + * Tries up to 10 times to get a valid spawning location before eventually + * failing and returning null. + */ + private Vec3 tryGetIronGolemSpawningLocation(int par1, int par2, int par3, int par4, int par5, int par6) { + for (int var7 = 0; var7 < 10; ++var7) { + int var8 = par1 + this.worldObj.rand.nextInt(16) - 8; + int var9 = par2 + this.worldObj.rand.nextInt(6) - 3; + int var10 = par3 + this.worldObj.rand.nextInt(16) - 8; + + if (this.isInRange(var8, var9, var10) + && this.isValidIronGolemSpawningLocation(var8, var9, var10, par4, par5, par6)) { + return this.worldObj.getWorldVec3Pool().getVecFromPool((double) var8, (double) var9, (double) var10); + } + } + + return null; + } + + private boolean isValidIronGolemSpawningLocation(int par1, int par2, int par3, int par4, int par5, int par6) { + if (!this.worldObj.doesBlockHaveSolidTopSurface(par1, par2 - 1, par3)) { + return false; + } else { + int var7 = par1 - par4 / 2; + int var8 = par3 - par6 / 2; + + for (int var9 = var7; var9 < var7 + par4; ++var9) { + for (int var10 = par2; var10 < par2 + par5; ++var10) { + for (int var11 = var8; var11 < var8 + par6; ++var11) { + if (this.worldObj.isBlockNormalCube(var9, var10, var11)) { + return false; + } + } + } + } + + return true; + } + } + + private void updateNumIronGolems() { + List var1 = this.worldObj.getEntitiesWithinAABB(EntityIronGolem.class, + AxisAlignedBB.getAABBPool().getAABB((double) (this.center.posX - this.villageRadius), + (double) (this.center.posY - 4), (double) (this.center.posZ - this.villageRadius), + (double) (this.center.posX + this.villageRadius), (double) (this.center.posY + 4), + (double) (this.center.posZ + this.villageRadius))); + this.numIronGolems = var1.size(); + } + + private void updateNumVillagers() { + List var1 = this.worldObj.getEntitiesWithinAABB(EntityVillager.class, + AxisAlignedBB.getAABBPool().getAABB((double) (this.center.posX - this.villageRadius), + (double) (this.center.posY - 4), (double) (this.center.posZ - this.villageRadius), + (double) (this.center.posX + this.villageRadius), (double) (this.center.posY + 4), + (double) (this.center.posZ + this.villageRadius))); + this.numVillagers = var1.size(); + + if (this.numVillagers == 0) { + this.playerReputation.clear(); + } + } + + public ChunkCoordinates getCenter() { + return this.center; + } + + public int getVillageRadius() { + return this.villageRadius; + } + + /** + * Actually get num village door info entries, but that boils down to number of + * doors. Called by EntityAIVillagerMate and VillageSiege + */ + public int getNumVillageDoors() { + return this.villageDoorInfoList.size(); + } + + public int getTicksSinceLastDoorAdding() { + return this.tickCounter - this.lastAddDoorTimestamp; + } + + public int getNumVillagers() { + return this.numVillagers; + } + + /** + * Returns true, if the given coordinates are within the bounding box of the + * village. + */ + public boolean isInRange(int par1, int par2, int par3) { + return this.center.getDistanceSquared(par1, par2, par3) < (float) (this.villageRadius * this.villageRadius); + } + + /** + * called only by class EntityAIMoveThroughVillage + */ + public List getVillageDoorInfoList() { + return this.villageDoorInfoList; + } + + public VillageDoorInfo findNearestDoor(int par1, int par2, int par3) { + VillageDoorInfo var4 = null; + int var5 = Integer.MAX_VALUE; + Iterator var6 = this.villageDoorInfoList.iterator(); + + while (var6.hasNext()) { + VillageDoorInfo var7 = (VillageDoorInfo) var6.next(); + int var8 = var7.getDistanceSquared(par1, par2, par3); + + if (var8 < var5) { + var4 = var7; + var5 = var8; + } + } + + return var4; + } + + /** + * Find a door suitable for shelter. If there are more doors in a distance of 16 + * blocks, then the least restricted one (i.e. the one protecting the lowest + * number of villagers) of them is chosen, else the nearest one regardless of + * restriction. + */ + public VillageDoorInfo findNearestDoorUnrestricted(int par1, int par2, int par3) { + VillageDoorInfo var4 = null; + int var5 = Integer.MAX_VALUE; + Iterator var6 = this.villageDoorInfoList.iterator(); + + while (var6.hasNext()) { + VillageDoorInfo var7 = (VillageDoorInfo) var6.next(); + int var8 = var7.getDistanceSquared(par1, par2, par3); + + if (var8 > 256) { + var8 *= 1000; + } else { + var8 = var7.getDoorOpeningRestrictionCounter(); + } + + if (var8 < var5) { + var4 = var7; + var5 = var8; + } + } + + return var4; + } + + public VillageDoorInfo getVillageDoorAt(int par1, int par2, int par3) { + if (this.center.getDistanceSquared(par1, par2, par3) > (float) (this.villageRadius * this.villageRadius)) { + return null; + } else { + Iterator var4 = this.villageDoorInfoList.iterator(); + VillageDoorInfo var5; + + do { + if (!var4.hasNext()) { + return null; + } + + var5 = (VillageDoorInfo) var4.next(); + } while (var5.posX != par1 || var5.posZ != par3 || Math.abs(var5.posY - par2) > 1); + + return var5; + } + } + + public void addVillageDoorInfo(VillageDoorInfo par1VillageDoorInfo) { + this.villageDoorInfoList.add(par1VillageDoorInfo); + this.centerHelper.posX += par1VillageDoorInfo.posX; + this.centerHelper.posY += par1VillageDoorInfo.posY; + this.centerHelper.posZ += par1VillageDoorInfo.posZ; + this.updateVillageRadiusAndCenter(); + this.lastAddDoorTimestamp = par1VillageDoorInfo.lastActivityTimestamp; + } + + /** + * Returns true, if there is not a single village door left. Called by + * VillageCollection + */ + public boolean isAnnihilated() { + return this.villageDoorInfoList.isEmpty(); + } + + public void addOrRenewAgressor(EntityLiving par1EntityLiving) { + Iterator var2 = this.villageAgressors.iterator(); + VillageAgressor var3; + + do { + if (!var2.hasNext()) { + this.villageAgressors.add(new VillageAgressor(this, par1EntityLiving, this.tickCounter)); + return; + } + + var3 = (VillageAgressor) var2.next(); + } while (var3.agressor != par1EntityLiving); + + var3.agressionTime = this.tickCounter; + } + + public EntityLiving findNearestVillageAggressor(EntityLiving par1EntityLiving) { + double var2 = Double.MAX_VALUE; + VillageAgressor var4 = null; + + for (int var5 = 0; var5 < this.villageAgressors.size(); ++var5) { + VillageAgressor var6 = (VillageAgressor) this.villageAgressors.get(var5); + double var7 = var6.agressor.getDistanceSqToEntity(par1EntityLiving); + + if (var7 <= var2) { + var4 = var6; + var2 = var7; + } + } + + return var4 != null ? var4.agressor : null; + } + + public EntityPlayer func_82685_c(EntityLiving par1EntityLiving) { + double var2 = Double.MAX_VALUE; + EntityPlayer var4 = null; + Iterator var5 = this.playerReputation.keySet().iterator(); + + while (var5.hasNext()) { + String var6 = (String) var5.next(); + + if (this.isPlayerReputationTooLow(var6)) { + EntityPlayer var7 = this.worldObj.getPlayerEntityByName(var6); + + if (var7 != null) { + double var8 = var7.getDistanceSqToEntity(par1EntityLiving); + + if (var8 <= var2) { + var4 = var7; + var2 = var8; + } + } + } + } + + return var4; + } + + private void removeDeadAndOldAgressors() { + Iterator var1 = this.villageAgressors.iterator(); + + while (var1.hasNext()) { + VillageAgressor var2 = (VillageAgressor) var1.next(); + + if (!var2.agressor.isEntityAlive() || Math.abs(this.tickCounter - var2.agressionTime) > 300) { + var1.remove(); + } + } + } + + private void removeDeadAndOutOfRangeDoors() { + boolean var1 = false; + boolean var2 = this.worldObj.rand.nextInt(50) == 0; + Iterator var3 = this.villageDoorInfoList.iterator(); + + while (var3.hasNext()) { + VillageDoorInfo var4 = (VillageDoorInfo) var3.next(); + + if (var2) { + var4.resetDoorOpeningRestrictionCounter(); + } + + if (!this.isBlockDoor(var4.posX, var4.posY, var4.posZ) + || Math.abs(this.tickCounter - var4.lastActivityTimestamp) > 1200) { + this.centerHelper.posX -= var4.posX; + this.centerHelper.posY -= var4.posY; + this.centerHelper.posZ -= var4.posZ; + var1 = true; + var4.isDetachedFromVillageFlag = true; + var3.remove(); + } + } + + if (var1) { + this.updateVillageRadiusAndCenter(); + } + } + + private boolean isBlockDoor(int par1, int par2, int par3) { + int var4 = this.worldObj.getBlockId(par1, par2, par3); + return var4 <= 0 ? false : var4 == Block.doorWood.blockID; + } + + private void updateVillageRadiusAndCenter() { + int var1 = this.villageDoorInfoList.size(); + + if (var1 == 0) { + this.center.set(0, 0, 0); + this.villageRadius = 0; + } else { + this.center.set(this.centerHelper.posX / var1, this.centerHelper.posY / var1, + this.centerHelper.posZ / var1); + int var2 = 0; + VillageDoorInfo var4; + + for (Iterator var3 = this.villageDoorInfoList.iterator(); var3.hasNext(); var2 = Math + .max(var4.getDistanceSquared(this.center.posX, this.center.posY, this.center.posZ), var2)) { + var4 = (VillageDoorInfo) var3.next(); + } + + this.villageRadius = Math.max(32, (int) Math.sqrt((double) var2) + 1); + } + } + + /** + * Return the village reputation for a player + */ + public int getReputationForPlayer(String par1Str) { + Integer var2 = (Integer) this.playerReputation.get(par1Str); + return var2 != null ? var2.intValue() : 0; + } + + /** + * Set the village reputation for a player. + */ + public int setReputationForPlayer(String par1Str, int par2) { + int var3 = this.getReputationForPlayer(par1Str); + int var4 = MathHelper.clamp_int(var3 + par2, -30, 10); + this.playerReputation.put(par1Str, Integer.valueOf(var4)); + return var4; + } + + /** + * Return whether this player has a too low reputation with this village. + */ + public boolean isPlayerReputationTooLow(String par1Str) { + return this.getReputationForPlayer(par1Str) <= -15; + } + + /** + * Read this village's data from NBT. + */ + public void readVillageDataFromNBT(NBTTagCompound par1NBTTagCompound) { + this.numVillagers = par1NBTTagCompound.getInteger("PopSize"); + this.villageRadius = par1NBTTagCompound.getInteger("Radius"); + this.numIronGolems = par1NBTTagCompound.getInteger("Golems"); + this.lastAddDoorTimestamp = par1NBTTagCompound.getInteger("Stable"); + this.tickCounter = par1NBTTagCompound.getInteger("Tick"); + this.noBreedTicks = par1NBTTagCompound.getInteger("MTick"); + this.center.posX = par1NBTTagCompound.getInteger("CX"); + this.center.posY = par1NBTTagCompound.getInteger("CY"); + this.center.posZ = par1NBTTagCompound.getInteger("CZ"); + this.centerHelper.posX = par1NBTTagCompound.getInteger("ACX"); + this.centerHelper.posY = par1NBTTagCompound.getInteger("ACY"); + this.centerHelper.posZ = par1NBTTagCompound.getInteger("ACZ"); + NBTTagList var2 = par1NBTTagCompound.getTagList("Doors"); + + for (int var3 = 0; var3 < var2.tagCount(); ++var3) { + NBTTagCompound var4 = (NBTTagCompound) var2.tagAt(var3); + VillageDoorInfo var5 = new VillageDoorInfo(var4.getInteger("X"), var4.getInteger("Y"), var4.getInteger("Z"), + var4.getInteger("IDX"), var4.getInteger("IDZ"), var4.getInteger("TS")); + this.villageDoorInfoList.add(var5); + } + + NBTTagList var6 = par1NBTTagCompound.getTagList("Players"); + + for (int var7 = 0; var7 < var6.tagCount(); ++var7) { + NBTTagCompound var8 = (NBTTagCompound) var6.tagAt(var7); + this.playerReputation.put(var8.getString("Name"), Integer.valueOf(var8.getInteger("S"))); + } + } + + /** + * Write this village's data to NBT. + */ + public void writeVillageDataToNBT(NBTTagCompound par1NBTTagCompound) { + par1NBTTagCompound.setInteger("PopSize", this.numVillagers); + par1NBTTagCompound.setInteger("Radius", this.villageRadius); + par1NBTTagCompound.setInteger("Golems", this.numIronGolems); + par1NBTTagCompound.setInteger("Stable", this.lastAddDoorTimestamp); + par1NBTTagCompound.setInteger("Tick", this.tickCounter); + par1NBTTagCompound.setInteger("MTick", this.noBreedTicks); + par1NBTTagCompound.setInteger("CX", this.center.posX); + par1NBTTagCompound.setInteger("CY", this.center.posY); + par1NBTTagCompound.setInteger("CZ", this.center.posZ); + par1NBTTagCompound.setInteger("ACX", this.centerHelper.posX); + par1NBTTagCompound.setInteger("ACY", this.centerHelper.posY); + par1NBTTagCompound.setInteger("ACZ", this.centerHelper.posZ); + NBTTagList var2 = new NBTTagList("Doors"); + Iterator var3 = this.villageDoorInfoList.iterator(); + + while (var3.hasNext()) { + VillageDoorInfo var4 = (VillageDoorInfo) var3.next(); + NBTTagCompound var5 = new NBTTagCompound("Door"); + var5.setInteger("X", var4.posX); + var5.setInteger("Y", var4.posY); + var5.setInteger("Z", var4.posZ); + var5.setInteger("IDX", var4.insideDirectionX); + var5.setInteger("IDZ", var4.insideDirectionZ); + var5.setInteger("TS", var4.lastActivityTimestamp); + var2.appendTag(var5); + } + + par1NBTTagCompound.setTag("Doors", var2); + NBTTagList var7 = new NBTTagList("Players"); + Iterator var8 = this.playerReputation.keySet().iterator(); + + while (var8.hasNext()) { + String var9 = (String) var8.next(); + NBTTagCompound var6 = new NBTTagCompound(var9); + var6.setString("Name", var9); + var6.setInteger("S", ((Integer) this.playerReputation.get(var9)).intValue()); + var7.appendTag(var6); + } + + par1NBTTagCompound.setTag("Players", var7); + } + + /** + * Prevent villager breeding for a fixed interval of time + */ + public void endMatingSeason() { + this.noBreedTicks = this.tickCounter; + } + + /** + * Return whether villagers mating refractory period has passed + */ + public boolean isMatingSeason() { + return this.noBreedTicks == 0 || this.tickCounter - this.noBreedTicks >= 3600; + } + + public void func_82683_b(int par1) { + Iterator var2 = this.playerReputation.keySet().iterator(); + + while (var2.hasNext()) { + String var3 = (String) var2.next(); + this.setReputationForPlayer(var3, par1); + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/VillageAgressor.java b/sp-server/src/main/java/net/minecraft/src/VillageAgressor.java new file mode 100644 index 0000000..20da98c --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/VillageAgressor.java @@ -0,0 +1,14 @@ +package net.minecraft.src; + +class VillageAgressor { + public EntityLiving agressor; + public int agressionTime; + + final Village villageObj; + + VillageAgressor(Village par1Village, EntityLiving par2EntityLiving, int par3) { + this.villageObj = par1Village; + this.agressor = par2EntityLiving; + this.agressionTime = par3; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/VillageCollection.java b/sp-server/src/main/java/net/minecraft/src/VillageCollection.java new file mode 100644 index 0000000..f60fe87 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/VillageCollection.java @@ -0,0 +1,309 @@ +package net.minecraft.src; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +public class VillageCollection extends WorldSavedData { + private World worldObj; + + /** + * This is a black hole. You can add data to this list through a public + * interface, but you can't query that information in any way and it's not used + * internally either. + */ + private final List villagerPositionsList = new ArrayList(); + private final List newDoors = new ArrayList(); + private final List villageList = new ArrayList(); + private int tickCounter = 0; + + public VillageCollection(String par1Str) { + super(par1Str); + } + + public VillageCollection(World par1World) { + super("villages"); + this.worldObj = par1World; + this.markDirty(); + } + + public void func_82566_a(World par1World) { + this.worldObj = par1World; + Iterator var2 = this.villageList.iterator(); + + while (var2.hasNext()) { + Village var3 = (Village) var2.next(); + var3.func_82691_a(par1World); + } + } + + /** + * This is a black hole. You can add data to this list through a public + * interface, but you can't query that information in any way and it's not used + * internally either. + */ + public void addVillagerPosition(int par1, int par2, int par3) { + if (this.villagerPositionsList.size() <= 64) { + if (!this.isVillagerPositionPresent(par1, par2, par3)) { + this.villagerPositionsList.add(new ChunkCoordinates(par1, par2, par3)); + } + } + } + + /** + * Runs a single tick for the village collection + */ + public void tick() { + ++this.tickCounter; + Iterator var1 = this.villageList.iterator(); + + while (var1.hasNext()) { + Village var2 = (Village) var1.next(); + var2.tick(this.tickCounter); + } + + this.removeAnnihilatedVillages(); + this.dropOldestVillagerPosition(); + this.addNewDoorsToVillageOrCreateVillage(); + + if (this.tickCounter % 400 == 0) { + this.markDirty(); + } + } + + private void removeAnnihilatedVillages() { + Iterator var1 = this.villageList.iterator(); + + while (var1.hasNext()) { + Village var2 = (Village) var1.next(); + + if (var2.isAnnihilated()) { + var1.remove(); + this.markDirty(); + } + } + } + + /** + * Get a list of villages. + */ + public List getVillageList() { + return this.villageList; + } + + /** + * Finds the nearest village, but only the given coordinates are withing it's + * bounding box plus the given the distance. + */ + public Village findNearestVillage(int par1, int par2, int par3, int par4) { + Village var5 = null; + float var6 = Float.MAX_VALUE; + Iterator var7 = this.villageList.iterator(); + + while (var7.hasNext()) { + Village var8 = (Village) var7.next(); + float var9 = var8.getCenter().getDistanceSquared(par1, par2, par3); + + if (var9 < var6) { + int var10 = par4 + var8.getVillageRadius(); + + if (var9 <= (float) (var10 * var10)) { + var5 = var8; + var6 = var9; + } + } + } + + return var5; + } + + private void dropOldestVillagerPosition() { + if (!this.villagerPositionsList.isEmpty()) { + this.addUnassignedWoodenDoorsAroundToNewDoorsList((ChunkCoordinates) this.villagerPositionsList.remove(0)); + } + } + + private void addNewDoorsToVillageOrCreateVillage() { + int var1 = 0; + + while (var1 < this.newDoors.size()) { + VillageDoorInfo var2 = (VillageDoorInfo) this.newDoors.get(var1); + boolean var3 = false; + Iterator var4 = this.villageList.iterator(); + + while (true) { + if (var4.hasNext()) { + Village var5 = (Village) var4.next(); + int var6 = (int) var5.getCenter().getDistanceSquared(var2.posX, var2.posY, var2.posZ); + int var7 = 32 + var5.getVillageRadius(); + + if (var6 > var7 * var7) { + continue; + } + + var5.addVillageDoorInfo(var2); + var3 = true; + } + + if (!var3) { + Village var8 = new Village(this.worldObj); + var8.addVillageDoorInfo(var2); + this.villageList.add(var8); + this.markDirty(); + } + + ++var1; + break; + } + } + + this.newDoors.clear(); + } + + private void addUnassignedWoodenDoorsAroundToNewDoorsList(ChunkCoordinates par1ChunkCoordinates) { + byte var2 = 16; + byte var3 = 4; + byte var4 = 16; + + for (int var5 = par1ChunkCoordinates.posX - var2; var5 < par1ChunkCoordinates.posX + var2; ++var5) { + for (int var6 = par1ChunkCoordinates.posY - var3; var6 < par1ChunkCoordinates.posY + var3; ++var6) { + for (int var7 = par1ChunkCoordinates.posZ - var4; var7 < par1ChunkCoordinates.posZ + var4; ++var7) { + if (this.isWoodenDoorAt(var5, var6, var7)) { + VillageDoorInfo var8 = this.getVillageDoorAt(var5, var6, var7); + + if (var8 == null) { + this.addDoorToNewListIfAppropriate(var5, var6, var7); + } else { + var8.lastActivityTimestamp = this.tickCounter; + } + } + } + } + } + } + + private VillageDoorInfo getVillageDoorAt(int par1, int par2, int par3) { + Iterator var4 = this.newDoors.iterator(); + VillageDoorInfo var5; + + do { + if (!var4.hasNext()) { + var4 = this.villageList.iterator(); + VillageDoorInfo var6; + + do { + if (!var4.hasNext()) { + return null; + } + + Village var7 = (Village) var4.next(); + var6 = var7.getVillageDoorAt(par1, par2, par3); + } while (var6 == null); + + return var6; + } + + var5 = (VillageDoorInfo) var4.next(); + } while (var5.posX != par1 || var5.posZ != par3 || Math.abs(var5.posY - par2) > 1); + + return var5; + } + + private void addDoorToNewListIfAppropriate(int par1, int par2, int par3) { + int var4 = ((BlockDoor) Block.doorWood).getDoorOrientation(this.worldObj, par1, par2, par3); + int var5; + int var6; + + if (var4 != 0 && var4 != 2) { + var5 = 0; + + for (var6 = -5; var6 < 0; ++var6) { + if (this.worldObj.canBlockSeeTheSky(par1, par2, par3 + var6)) { + --var5; + } + } + + for (var6 = 1; var6 <= 5; ++var6) { + if (this.worldObj.canBlockSeeTheSky(par1, par2, par3 + var6)) { + ++var5; + } + } + + if (var5 != 0) { + this.newDoors.add(new VillageDoorInfo(par1, par2, par3, 0, var5 > 0 ? -2 : 2, this.tickCounter)); + } + } else { + var5 = 0; + + for (var6 = -5; var6 < 0; ++var6) { + if (this.worldObj.canBlockSeeTheSky(par1 + var6, par2, par3)) { + --var5; + } + } + + for (var6 = 1; var6 <= 5; ++var6) { + if (this.worldObj.canBlockSeeTheSky(par1 + var6, par2, par3)) { + ++var5; + } + } + + if (var5 != 0) { + this.newDoors.add(new VillageDoorInfo(par1, par2, par3, var5 > 0 ? -2 : 2, 0, this.tickCounter)); + } + } + } + + private boolean isVillagerPositionPresent(int par1, int par2, int par3) { + Iterator var4 = this.villagerPositionsList.iterator(); + ChunkCoordinates var5; + + do { + if (!var4.hasNext()) { + return false; + } + + var5 = (ChunkCoordinates) var4.next(); + } while (var5.posX != par1 || var5.posY != par2 || var5.posZ != par3); + + return true; + } + + private boolean isWoodenDoorAt(int par1, int par2, int par3) { + int var4 = this.worldObj.getBlockId(par1, par2, par3); + return var4 == Block.doorWood.blockID; + } + + /** + * reads in data from the NBTTagCompound into this MapDataBase + */ + public void readFromNBT(NBTTagCompound par1NBTTagCompound) { + this.tickCounter = par1NBTTagCompound.getInteger("Tick"); + NBTTagList var2 = par1NBTTagCompound.getTagList("Villages"); + + for (int var3 = 0; var3 < var2.tagCount(); ++var3) { + NBTTagCompound var4 = (NBTTagCompound) var2.tagAt(var3); + Village var5 = new Village(); + var5.readVillageDataFromNBT(var4); + this.villageList.add(var5); + } + } + + /** + * write data to NBTTagCompound from this MapDataBase, similar to Entities and + * TileEntities + */ + public void writeToNBT(NBTTagCompound par1NBTTagCompound) { + par1NBTTagCompound.setInteger("Tick", this.tickCounter); + NBTTagList var2 = new NBTTagList("Villages"); + Iterator var3 = this.villageList.iterator(); + + while (var3.hasNext()) { + Village var4 = (Village) var3.next(); + NBTTagCompound var5 = new NBTTagCompound("Village"); + var4.writeVillageDataToNBT(var5); + var2.appendTag(var5); + } + + par1NBTTagCompound.setTag("Villages", var2); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/VillageDoorInfo.java b/sp-server/src/main/java/net/minecraft/src/VillageDoorInfo.java new file mode 100644 index 0000000..260bc82 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/VillageDoorInfo.java @@ -0,0 +1,72 @@ +package net.minecraft.src; + +public class VillageDoorInfo { + public final int posX; + public final int posY; + public final int posZ; + public final int insideDirectionX; + public final int insideDirectionZ; + public int lastActivityTimestamp; + public boolean isDetachedFromVillageFlag = false; + private int doorOpeningRestrictionCounter = 0; + + public VillageDoorInfo(int par1, int par2, int par3, int par4, int par5, int par6) { + this.posX = par1; + this.posY = par2; + this.posZ = par3; + this.insideDirectionX = par4; + this.insideDirectionZ = par5; + this.lastActivityTimestamp = par6; + } + + /** + * Returns the squared distance between this door and the given coordinate. + */ + public int getDistanceSquared(int par1, int par2, int par3) { + int var4 = par1 - this.posX; + int var5 = par2 - this.posY; + int var6 = par3 - this.posZ; + return var4 * var4 + var5 * var5 + var6 * var6; + } + + /** + * Get the square of the distance from a location 2 blocks away from the door + * considered 'inside' and the given arguments + */ + public int getInsideDistanceSquare(int par1, int par2, int par3) { + int var4 = par1 - this.posX - this.insideDirectionX; + int var5 = par2 - this.posY; + int var6 = par3 - this.posZ - this.insideDirectionZ; + return var4 * var4 + var5 * var5 + var6 * var6; + } + + public int getInsidePosX() { + return this.posX + this.insideDirectionX; + } + + public int getInsidePosY() { + return this.posY; + } + + public int getInsidePosZ() { + return this.posZ + this.insideDirectionZ; + } + + public boolean isInside(int par1, int par2) { + int var3 = par1 - this.posX; + int var4 = par2 - this.posZ; + return var3 * this.insideDirectionX + var4 * this.insideDirectionZ >= 0; + } + + public void resetDoorOpeningRestrictionCounter() { + this.doorOpeningRestrictionCounter = 0; + } + + public void incrementDoorOpeningRestrictionCounter() { + ++this.doorOpeningRestrictionCounter; + } + + public int getDoorOpeningRestrictionCounter() { + return this.doorOpeningRestrictionCounter; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/VillageSiege.java b/sp-server/src/main/java/net/minecraft/src/VillageSiege.java new file mode 100644 index 0000000..ebbd357 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/VillageSiege.java @@ -0,0 +1,184 @@ +package net.minecraft.src; + +import java.util.Iterator; +import java.util.List; + +public class VillageSiege { + private World worldObj; + private boolean field_75535_b = false; + private int field_75536_c = -1; + private int field_75533_d; + private int field_75534_e; + + /** Instance of Village. */ + private Village theVillage; + private int field_75532_g; + private int field_75538_h; + private int field_75539_i; + + public VillageSiege(World par1World) { + this.worldObj = par1World; + } + + /** + * Runs a single tick for the village siege + */ + public void tick() { + boolean var1 = false; + + if (var1) { + if (this.field_75536_c == 2) { + this.field_75533_d = 100; + return; + } + } else { + if (this.worldObj.isDaytime()) { + this.field_75536_c = 0; + return; + } + + if (this.field_75536_c == 2) { + return; + } + + if (this.field_75536_c == 0) { + float var2 = this.worldObj.getCelestialAngle(0.0F); + + if ((double) var2 < 0.5D || (double) var2 > 0.501D) { + return; + } + + this.field_75536_c = this.worldObj.rand.nextInt(10) == 0 ? 1 : 2; + this.field_75535_b = false; + + if (this.field_75536_c == 2) { + return; + } + } + } + + if (!this.field_75535_b) { + if (!this.func_75529_b()) { + return; + } + + this.field_75535_b = true; + } + + if (this.field_75534_e > 0) { + --this.field_75534_e; + } else { + this.field_75534_e = 2; + + if (this.field_75533_d > 0) { + this.spawnZombie(); + --this.field_75533_d; + } else { + this.field_75536_c = 2; + } + } + } + + private boolean func_75529_b() { + List var1 = this.worldObj.playerEntities; + Iterator var2 = var1.iterator(); + + while (var2.hasNext()) { + EntityPlayer var3 = (EntityPlayer) var2.next(); + this.theVillage = this.worldObj.villageCollectionObj.findNearestVillage((int) var3.posX, (int) var3.posY, + (int) var3.posZ, 1); + + if (this.theVillage != null && this.theVillage.getNumVillageDoors() >= 10 + && this.theVillage.getTicksSinceLastDoorAdding() >= 20 && this.theVillage.getNumVillagers() >= 20) { + ChunkCoordinates var4 = this.theVillage.getCenter(); + float var5 = (float) this.theVillage.getVillageRadius(); + boolean var6 = false; + int var7 = 0; + + while (true) { + if (var7 < 10) { + this.field_75532_g = var4.posX + (int) ((double) (MathHelper + .cos(this.worldObj.rand.nextFloat() * (float) Math.PI * 2.0F) * var5) * 0.9D); + this.field_75538_h = var4.posY; + this.field_75539_i = var4.posZ + (int) ((double) (MathHelper + .sin(this.worldObj.rand.nextFloat() * (float) Math.PI * 2.0F) * var5) * 0.9D); + var6 = false; + Iterator var8 = this.worldObj.villageCollectionObj.getVillageList().iterator(); + + while (var8.hasNext()) { + Village var9 = (Village) var8.next(); + + if (var9 != this.theVillage + && var9.isInRange(this.field_75532_g, this.field_75538_h, this.field_75539_i)) { + var6 = true; + break; + } + } + + if (var6) { + ++var7; + continue; + } + } + + if (var6) { + return false; + } + + Vec3 var10 = this.func_75527_a(this.field_75532_g, this.field_75538_h, this.field_75539_i); + + if (var10 != null) { + this.field_75534_e = 0; + this.field_75533_d = 20; + return true; + } + + break; + } + } + } + + return false; + } + + private boolean spawnZombie() { + Vec3 var1 = this.func_75527_a(this.field_75532_g, this.field_75538_h, this.field_75539_i); + + if (var1 == null) { + return false; + } else { + EntityZombie var2; + + try { + var2 = new EntityZombie(this.worldObj); + var2.initCreature(); + var2.setVillager(false); + } catch (Exception var4) { + var4.printStackTrace(); + return false; + } + + var2.setLocationAndAngles(var1.xCoord, var1.yCoord, var1.zCoord, this.worldObj.rand.nextFloat() * 360.0F, + 0.0F); + this.worldObj.spawnEntityInWorld(var2); + ChunkCoordinates var3 = this.theVillage.getCenter(); + var2.setHomeArea(var3.posX, var3.posY, var3.posZ, this.theVillage.getVillageRadius()); + return true; + } + } + + private Vec3 func_75527_a(int par1, int par2, int par3) { + for (int var4 = 0; var4 < 10; ++var4) { + int var5 = par1 + this.worldObj.rand.nextInt(16) - 8; + int var6 = par2 + this.worldObj.rand.nextInt(6) - 3; + int var7 = par3 + this.worldObj.rand.nextInt(16) - 8; + + if (this.theVillage.isInRange(var5, var6, var7) && SpawnerAnimals + .canCreatureTypeSpawnAtLocation(EnumCreatureType.monster, this.worldObj, var5, var6, var7)) { + this.worldObj.getWorldVec3Pool().getVecFromPool((double) var5, (double) var6, (double) var7); + } + } + + return null; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/WatchableObject.java b/sp-server/src/main/java/net/minecraft/src/WatchableObject.java new file mode 100644 index 0000000..d0bafe2 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/WatchableObject.java @@ -0,0 +1,48 @@ +package net.minecraft.src; + +public class WatchableObject { + private final int objectType; + + /** id of max 31 */ + private final int dataValueId; + private Object watchedObject; + private boolean watched; + + public WatchableObject(int par1, int par2, Object par3Obj) { + this.dataValueId = par2; + this.watchedObject = par3Obj; + this.objectType = par1; + this.watched = true; + } + + public int getDataValueId() { + return this.dataValueId; + } + + public void setObject(Object par1Obj) { + this.watchedObject = par1Obj; + } + + public Object getObject() { + return this.watchedObject; + } + + public int getObjectType() { + return this.objectType; + } + + public boolean isWatched() { + return this.watched; + } + + public void setWatched(boolean par1) { + this.watched = par1; + } + + /** + * Set whether the specified watchable object is being watched. + */ + static boolean setWatchableObjectWatched(WatchableObject par0WatchableObject, boolean par1) { + return par0WatchableObject.watched = par1; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/WeightedRandom.java b/sp-server/src/main/java/net/minecraft/src/WeightedRandom.java new file mode 100644 index 0000000..617ca76 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/WeightedRandom.java @@ -0,0 +1,102 @@ +package net.minecraft.src; + +import java.util.Collection; +import java.util.Iterator; +import java.util.Random; + +public class WeightedRandom { + /** + * Returns the total weight of all items in a collection. + */ + public static int getTotalWeight(Collection par0Collection) { + int var1 = 0; + WeightedRandomItem var3; + + for (Iterator var2 = par0Collection.iterator(); var2.hasNext(); var1 += var3.itemWeight) { + var3 = (WeightedRandomItem) var2.next(); + } + + return var1; + } + + /** + * Returns a random choice from the input items, with a total weight value. + */ + public static WeightedRandomItem getRandomItem(Random par0Random, Collection par1Collection, int par2) { + if (par2 <= 0) { + throw new IllegalArgumentException(); + } else { + int var3 = par0Random.nextInt(par2); + Iterator var4 = par1Collection.iterator(); + WeightedRandomItem var5; + + do { + if (!var4.hasNext()) { + return null; + } + + var5 = (WeightedRandomItem) var4.next(); + var3 -= var5.itemWeight; + } while (var3 >= 0); + + return var5; + } + } + + /** + * Returns a random choice from the input items. + */ + public static WeightedRandomItem getRandomItem(Random par0Random, Collection par1Collection) { + return getRandomItem(par0Random, par1Collection, getTotalWeight(par1Collection)); + } + + /** + * Returns the total weight of all items in a array. + */ + public static int getTotalWeight(WeightedRandomItem[] par0ArrayOfWeightedRandomItem) { + int var1 = 0; + WeightedRandomItem[] var2 = par0ArrayOfWeightedRandomItem; + int var3 = par0ArrayOfWeightedRandomItem.length; + + for (int var4 = 0; var4 < var3; ++var4) { + WeightedRandomItem var5 = var2[var4]; + var1 += var5.itemWeight; + } + + return var1; + } + + /** + * Returns a random choice from the input array of items, with a total weight + * value. + */ + public static WeightedRandomItem getRandomItem(Random par0Random, + WeightedRandomItem[] par1ArrayOfWeightedRandomItem, int par2) { + if (par2 <= 0) { + throw new IllegalArgumentException(); + } else { + int var3 = par0Random.nextInt(par2); + WeightedRandomItem[] var4 = par1ArrayOfWeightedRandomItem; + int var5 = par1ArrayOfWeightedRandomItem.length; + + for (int var6 = 0; var6 < var5; ++var6) { + WeightedRandomItem var7 = var4[var6]; + var3 -= var7.itemWeight; + + if (var3 < 0) { + return var7; + } + } + + return null; + } + } + + /** + * Returns a random choice from the input items. + */ + public static WeightedRandomItem getRandomItem(Random par0Random, + WeightedRandomItem[] par1ArrayOfWeightedRandomItem) { + return getRandomItem(par0Random, par1ArrayOfWeightedRandomItem, getTotalWeight(par1ArrayOfWeightedRandomItem)); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/WeightedRandomChestContent.java b/sp-server/src/main/java/net/minecraft/src/WeightedRandomChestContent.java new file mode 100644 index 0000000..bcf6838 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/WeightedRandomChestContent.java @@ -0,0 +1,104 @@ +package net.minecraft.src; + +import java.util.Random; + +public class WeightedRandomChestContent extends WeightedRandomItem { + /** The Item/Block ID to generate in the Chest. */ + private ItemStack theItemId = null; + + /** The minimum chance of item generating. */ + private int theMinimumChanceToGenerateItem; + + /** The maximum chance of item generating. */ + private int theMaximumChanceToGenerateItem; + + public WeightedRandomChestContent(int par1, int par2, int par3, int par4, int par5) { + super(par5); + this.theItemId = new ItemStack(par1, 1, par2); + this.theMinimumChanceToGenerateItem = par3; + this.theMaximumChanceToGenerateItem = par4; + } + + public WeightedRandomChestContent(ItemStack par1ItemStack, int par2, int par3, int par4) { + super(par4); + this.theItemId = par1ItemStack; + this.theMinimumChanceToGenerateItem = par2; + this.theMaximumChanceToGenerateItem = par3; + } + + /** + * Generates the Chest contents. + */ + public static void generateChestContents(Random par0Random, + WeightedRandomChestContent[] par1ArrayOfWeightedRandomChestContent, IInventory par2IInventory, int par3) { + for (int var4 = 0; var4 < par3; ++var4) { + WeightedRandomChestContent var5 = (WeightedRandomChestContent) WeightedRandom.getRandomItem(par0Random, + par1ArrayOfWeightedRandomChestContent); + int var6 = var5.theMinimumChanceToGenerateItem + + par0Random.nextInt(var5.theMaximumChanceToGenerateItem - var5.theMinimumChanceToGenerateItem + 1); + + if (var5.theItemId.getMaxStackSize() >= var6) { + ItemStack var7 = var5.theItemId.copy(); + var7.stackSize = var6; + par2IInventory.setInventorySlotContents(par0Random.nextInt(par2IInventory.getSizeInventory()), var7); + } else { + for (int var9 = 0; var9 < var6; ++var9) { + ItemStack var8 = var5.theItemId.copy(); + var8.stackSize = 1; + par2IInventory.setInventorySlotContents(par0Random.nextInt(par2IInventory.getSizeInventory()), + var8); + } + } + } + } + + /** + * Generates the Dispenser contents. + */ + public static void generateDispenserContents(Random par0Random, + WeightedRandomChestContent[] par1ArrayOfWeightedRandomChestContent, + TileEntityDispenser par2TileEntityDispenser, int par3) { + for (int var4 = 0; var4 < par3; ++var4) { + WeightedRandomChestContent var5 = (WeightedRandomChestContent) WeightedRandom.getRandomItem(par0Random, + par1ArrayOfWeightedRandomChestContent); + int var6 = var5.theMinimumChanceToGenerateItem + + par0Random.nextInt(var5.theMaximumChanceToGenerateItem - var5.theMinimumChanceToGenerateItem + 1); + + if (var5.theItemId.getMaxStackSize() >= var6) { + ItemStack var7 = var5.theItemId.copy(); + var7.stackSize = var6; + par2TileEntityDispenser + .setInventorySlotContents(par0Random.nextInt(par2TileEntityDispenser.getSizeInventory()), var7); + } else { + for (int var9 = 0; var9 < var6; ++var9) { + ItemStack var8 = var5.theItemId.copy(); + var8.stackSize = 1; + par2TileEntityDispenser.setInventorySlotContents( + par0Random.nextInt(par2TileEntityDispenser.getSizeInventory()), var8); + } + } + } + } + + public static WeightedRandomChestContent[] func_92080_a( + WeightedRandomChestContent[] par0ArrayOfWeightedRandomChestContent, + WeightedRandomChestContent... par1ArrayOfWeightedRandomChestContent) { + WeightedRandomChestContent[] var2 = new WeightedRandomChestContent[par0ArrayOfWeightedRandomChestContent.length + + par1ArrayOfWeightedRandomChestContent.length]; + int var3 = 0; + + for (int var4 = 0; var4 < par0ArrayOfWeightedRandomChestContent.length; ++var4) { + var2[var3++] = par0ArrayOfWeightedRandomChestContent[var4]; + } + + WeightedRandomChestContent[] var8 = par1ArrayOfWeightedRandomChestContent; + int var5 = par1ArrayOfWeightedRandomChestContent.length; + + for (int var6 = 0; var6 < var5; ++var6) { + WeightedRandomChestContent var7 = var8[var6]; + var2[var3++] = var7; + } + + return var2; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/WeightedRandomItem.java b/sp-server/src/main/java/net/minecraft/src/WeightedRandomItem.java new file mode 100644 index 0000000..d7d90ab --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/WeightedRandomItem.java @@ -0,0 +1,13 @@ +package net.minecraft.src; + +public class WeightedRandomItem { + /** + * The Weight is how often the item is chosen(higher number is higher + * chance(lower is lower)) + */ + protected int itemWeight; + + public WeightedRandomItem(int par1) { + this.itemWeight = par1; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/WeightedRandomMinecart.java b/sp-server/src/main/java/net/minecraft/src/WeightedRandomMinecart.java new file mode 100644 index 0000000..133b88e --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/WeightedRandomMinecart.java @@ -0,0 +1,73 @@ +package net.minecraft.src; + +public class WeightedRandomMinecart extends WeightedRandomItem { + public final NBTTagCompound field_98222_b; + public final String minecartName; + + final MobSpawnerBaseLogic field_98221_d; + + public WeightedRandomMinecart(MobSpawnerBaseLogic par1MobSpawnerBaseLogic, NBTTagCompound par2NBTTagCompound) { + super(par2NBTTagCompound.getInteger("Weight")); + this.field_98221_d = par1MobSpawnerBaseLogic; + NBTTagCompound var3 = par2NBTTagCompound.getCompoundTag("Properties"); + String var4 = par2NBTTagCompound.getString("Type"); + + if (var4.equals("Minecart")) { + if (var3 != null) { + switch (var3.getInteger("Type")) { + case 0: + var4 = "MinecartRideable"; + break; + + case 1: + var4 = "MinecartChest"; + break; + + case 2: + var4 = "MinecartFurnace"; + } + } else { + var4 = "MinecartRideable"; + } + } + + this.field_98222_b = var3; + this.minecartName = var4; + } + + public WeightedRandomMinecart(MobSpawnerBaseLogic par1MobSpawnerBaseLogic, NBTTagCompound par2NBTTagCompound, + String par3Str) { + super(1); + this.field_98221_d = par1MobSpawnerBaseLogic; + + if (par3Str.equals("Minecart")) { + if (par2NBTTagCompound != null) { + switch (par2NBTTagCompound.getInteger("Type")) { + case 0: + par3Str = "MinecartRideable"; + break; + + case 1: + par3Str = "MinecartChest"; + break; + + case 2: + par3Str = "MinecartFurnace"; + } + } else { + par3Str = "MinecartRideable"; + } + } + + this.field_98222_b = par2NBTTagCompound; + this.minecartName = par3Str; + } + + public NBTTagCompound func_98220_a() { + NBTTagCompound var1 = new NBTTagCompound(); + var1.setCompoundTag("Properties", this.field_98222_b); + var1.setString("Type", this.minecartName); + var1.setInteger("Weight", this.itemWeight); + return var1; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/World.java b/sp-server/src/main/java/net/minecraft/src/World.java new file mode 100644 index 0000000..f087d30 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/World.java @@ -0,0 +1,3287 @@ +package net.minecraft.src; + +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Collection; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Random; +import java.util.Set; + +public abstract class World implements IBlockAccess { + /** + * boolean; if true updates scheduled by scheduleBlockUpdate happen immediately + */ + public boolean scheduledUpdatesAreImmediate = false; + + /** A list of all Entities in all currently-loaded chunks */ + public List loadedEntityList = new ArrayList(); + protected List unloadedEntityList = new ArrayList(); + + /** A list of all TileEntities in all currently-loaded chunks */ + public List loadedTileEntityList = new ArrayList(); + private List addedTileEntityList = new ArrayList(); + + /** Entities marked for removal. */ + private List entityRemoval = new ArrayList(); + + /** Array list of players in the world. */ + public List playerEntities = new ArrayList(); + + /** a list of all the lightning entities */ + public List weatherEffects = new ArrayList(); + private long cloudColour = 16777215L; + + /** How much light is subtracted from full daylight */ + public int skylightSubtracted = 0; + + /** + * Contains the current Linear Congruential Generator seed for block updates. + * Used with an A value of 3 and a C value of 0x3c6ef35f, producing a highly + * planar series of values ill-suited for choosing random blocks in a 16x128x16 + * field. + */ + protected int updateLCG = (new Random()).nextInt(); + + /** + * magic number used to generate fast random numbers for 3d distribution within + * a chunk + */ + protected final int DIST_HASH_MAGIC = 1013904223; + protected float prevRainingStrength; + protected float rainingStrength; + protected float prevThunderingStrength; + protected float thunderingStrength; + + /** + * Set to 2 whenever a lightning bolt is generated in SSP. Decrements if > 0 in + * updateWeather(). Value appears to be unused. + */ + public int lastLightningBolt = 0; + + /** Whether monsters are enabled or not. (1 = on, 0 = off) */ + public int difficultySetting; + + /** RNG for World. */ + public Random rand = new Random(); + + /** The WorldProvider instance that World uses. */ + public final WorldProvider provider; + protected List worldAccesses = new ArrayList(); + + /** Handles chunk operations and caching */ + protected IChunkProvider chunkProvider; + protected final ISaveHandler saveHandler; + + /** + * holds information about a world (size on disk, time, spawn point, seed, ...) + */ + protected WorldInfo worldInfo; + + /** + * if set, this flag forces a request to load a chunk to load the chunk rather + * than defaulting to the world's chunkprovider's dummy if possible + */ + public boolean findingSpawnPoint; + public MapStorage mapStorage; + public final VillageCollection villageCollectionObj; + protected final VillageSiege villageSiegeObj = new VillageSiege(this); + public final Profiler theProfiler; + + /** The world-local pool of vectors */ + private final Vec3Pool vecPool = new Vec3Pool(300, 2000); + private final Calendar theCalendar = Calendar.getInstance(); + protected Scoreboard worldScoreboard = new Scoreboard(); + + /** The log agent for this world. */ + private final ILogAgent worldLogAgent; + private ArrayList collidingBoundingBoxes = new ArrayList(); + private boolean scanningTileEntities; + + /** indicates if enemies are spawned or not */ + protected boolean spawnHostileMobs = true; + + /** A flag indicating whether we should spawn peaceful mobs. */ + protected boolean spawnPeacefulMobs = true; + + /** populated by chunks that are within 9 chunks of any player */ + protected Set activeChunkSet = new HashSet(); + + /** number of ticks until the next random ambients play */ + private int ambientTickCountdown; + + /** + * is a temporary list of blocks and light values used when updating light + * levels. Holds up to 32x32x32 blocks (the maximum influence of a light + * source.) Every element is a packed bit value: + * 0000000000LLLLzzzzzzyyyyyyxxxxxx. The 4-bit L is a light level used when + * darkening blocks. 6-bit numbers x, y and z represent the block's offset from + * the original block, plus 32 (i.e. value of 31 would mean a -1 offset + */ + int[] lightUpdateBlockList; + + /** This is set to true for client worlds, and false for server worlds. */ + public boolean isRemote; + + /** + * Gets the biome for a given set of x/z coordinates + */ + public BiomeGenBase getBiomeGenForCoords(int par1, int par2) { + if (this.blockExists(par1, 0, par2)) { + Chunk var3 = this.getChunkFromBlockCoords(par1, par2); + + if (var3 != null) { + return var3.getBiomeGenForWorldCoords(par1 & 15, par2 & 15, this.provider.worldChunkMgr); + } + } + + return this.provider.worldChunkMgr.getBiomeGenAt(par1, par2); + } + + public WorldChunkManager getWorldChunkManager() { + return this.provider.worldChunkMgr; + } + + public World(ISaveHandler par1ISaveHandler, String par2Str, WorldSettings par3WorldSettings, + WorldProvider par4WorldProvider, Profiler par5Profiler, ILogAgent par6ILogAgent) { + this.ambientTickCountdown = this.rand.nextInt(12000); + this.lightUpdateBlockList = new int[32768]; + this.isRemote = false; + this.saveHandler = par1ISaveHandler; + this.theProfiler = par5Profiler; + this.mapStorage = new MapStorage(par1ISaveHandler); + this.worldLogAgent = par6ILogAgent; + this.worldInfo = par1ISaveHandler.loadWorldInfo(); + + if (par4WorldProvider != null) { + this.provider = par4WorldProvider; + } else if (this.worldInfo != null && this.worldInfo.getDimension() != 0) { + this.provider = WorldProvider.getProviderForDimension(this.worldInfo.getDimension()); + } else { + this.provider = WorldProvider.getProviderForDimension(0); + } + + if (this.worldInfo == null) { + this.worldInfo = new WorldInfo(par3WorldSettings, par2Str); + } else { + this.worldInfo.setWorldName(par2Str); + } + + this.provider.registerWorld(this); + this.chunkProvider = this.createChunkProvider(); + + if (!this.worldInfo.isInitialized()) { + try { + this.initialize(par3WorldSettings); + } catch (Throwable var11) { + CrashReport var8 = CrashReport.makeCrashReport(var11, "Exception initializing level"); + + try { + this.addWorldInfoToCrashReport(var8); + } catch (Throwable var10) { + ; + } + + throw new ReportedException(var8); + } + + this.worldInfo.setServerInitialized(true); + } + + VillageCollection var7 = (VillageCollection) this.mapStorage.loadData(VillageCollection.class, "villages"); + + if (var7 == null) { + this.villageCollectionObj = new VillageCollection(this); + this.mapStorage.setData("villages", this.villageCollectionObj); + } else { + this.villageCollectionObj = var7; + this.villageCollectionObj.func_82566_a(this); + } + + this.calculateInitialSkylight(); + this.calculateInitialWeather(); + } + + /** + * Creates the chunk provider for this world. Called in the constructor. + * Retrieves provider from worldProvider? + */ + protected abstract IChunkProvider createChunkProvider(); + + protected void initialize(WorldSettings par1WorldSettings) { + this.worldInfo.setServerInitialized(true); + } + + /** + * Returns the block ID of the first block at this (x,z) location with air above + * it, searching from sea level upwards. + */ + public int getFirstUncoveredBlock(int par1, int par2) { + int var3; + + for (var3 = 63; !this.isAirBlock(par1, var3 + 1, par2); ++var3) { + ; + } + + return this.getBlockId(par1, var3, par2); + } + + /** + * Returns the block ID at coords x,y,z + */ + public int getBlockId(int par1, int par2, int par3) { + if (par1 >= -30000000 && par3 >= -30000000 && par1 < 30000000 && par3 < 30000000) { + if (par2 < 0) { + return 0; + } else if (par2 >= 256) { + return 0; + } else { + Chunk var4 = null; + + try { + var4 = this.getChunkFromChunkCoords(par1 >> 4, par3 >> 4); + return var4.getBlockID(par1 & 15, par2, par3 & 15); + } catch (Throwable var8) { + CrashReport var6 = CrashReport.makeCrashReport(var8, "Exception getting block type in world"); + CrashReportCategory var7 = var6.makeCategory("Requested block coordinates"); + var7.addCrashSection("Found chunk", Boolean.valueOf(var4 == null)); + var7.addCrashSection("Location", CrashReportCategory.getLocationInfo(par1, par2, par3)); + throw new ReportedException(var6); + } + } + } else { + return 0; + } + } + + /** + * Returns true if the block at the specified coordinates is empty + */ + public boolean isAirBlock(int par1, int par2, int par3) { + return this.getBlockId(par1, par2, par3) == 0; + } + + /** + * Checks if a block at a given position should have a tile entity. + */ + public boolean blockHasTileEntity(int par1, int par2, int par3) { + int var4 = this.getBlockId(par1, par2, par3); + return Block.blocksList[var4] != null && Block.blocksList[var4].hasTileEntity(); + } + + /** + * Returns the render type of the block at the given coordinate. + */ + public int blockGetRenderType(int par1, int par2, int par3) { + int var4 = this.getBlockId(par1, par2, par3); + return Block.blocksList[var4] != null ? Block.blocksList[var4].getRenderType() : -1; + } + + /** + * Returns whether a block exists at world coordinates x, y, z + */ + public boolean blockExists(int par1, int par2, int par3) { + return par2 >= 0 && par2 < 256 ? this.chunkExists(par1 >> 4, par3 >> 4) : false; + } + + /** + * Checks if any of the chunks within distance (argument 4) blocks of the given + * block exist + */ + public boolean doChunksNearChunkExist(int par1, int par2, int par3, int par4) { + return this.checkChunksExist(par1 - par4, par2 - par4, par3 - par4, par1 + par4, par2 + par4, par3 + par4); + } + + /** + * Checks between a min and max all the chunks inbetween actually exist. Args: + * minX, minY, minZ, maxX, maxY, maxZ + */ + public boolean checkChunksExist(int par1, int par2, int par3, int par4, int par5, int par6) { + if (par5 >= 0 && par2 < 256) { + par1 >>= 4; + par3 >>= 4; + par4 >>= 4; + par6 >>= 4; + + for (int var7 = par1; var7 <= par4; ++var7) { + for (int var8 = par3; var8 <= par6; ++var8) { + if (!this.chunkExists(var7, var8)) { + return false; + } + } + } + + return true; + } else { + return false; + } + } + + /** + * Returns whether a chunk exists at chunk coordinates x, y + */ + protected boolean chunkExists(int par1, int par2) { + return this.chunkProvider.chunkExists(par1, par2); + } + + /** + * Returns a chunk looked up by block coordinates. Args: x, z + */ + public Chunk getChunkFromBlockCoords(int par1, int par2) { + return this.getChunkFromChunkCoords(par1 >> 4, par2 >> 4); + } + + /** + * Returns back a chunk looked up by chunk coordinates Args: x, y + */ + public Chunk getChunkFromChunkCoords(int par1, int par2) { + return this.chunkProvider.provideChunk(par1, par2); + } + + /** + * Sets the block ID and metadata at a given location. Args: X, Y, Z, new block + * ID, new metadata, flags. Flag 1 will cause a block update. Flag 2 will send + * the change to clients (you almost always want this). Flag 4 prevents the + * block from being re-rendered, if this is a client world. Flags can be added + * together. + */ + public boolean setBlock(int par1, int par2, int par3, int par4, int par5, int par6) { + if (par1 >= -30000000 && par3 >= -30000000 && par1 < 30000000 && par3 < 30000000) { + if (par2 < 0) { + return false; + } else if (par2 >= 256) { + return false; + } else { + Chunk var7 = this.getChunkFromChunkCoords(par1 >> 4, par3 >> 4); + int var8 = 0; + + if ((par6 & 1) != 0) { + var8 = var7.getBlockID(par1 & 15, par2, par3 & 15); + } + + boolean var9 = var7.setBlockIDWithMetadata(par1 & 15, par2, par3 & 15, par4, par5); + this.theProfiler.startSection("checkLight"); + this.updateAllLightTypes(par1, par2, par3); + this.theProfiler.endSection(); + + if (var9) { + if ((par6 & 2) != 0 && (!this.isRemote || (par6 & 4) == 0)) { + this.markBlockForUpdate(par1, par2, par3); + } + + if (!this.isRemote && (par6 & 1) != 0) { + this.notifyBlockChange(par1, par2, par3, var8); + Block var10 = Block.blocksList[par4]; + + if (var10 != null && var10.hasComparatorInputOverride()) { + this.func_96440_m(par1, par2, par3, par4); + } + } + } + + return var9; + } + } else { + return false; + } + } + + /** + * Returns the block's material. + */ + public Material getBlockMaterial(int par1, int par2, int par3) { + int var4 = this.getBlockId(par1, par2, par3); + return var4 == 0 ? Material.air : Block.blocksList[var4].blockMaterial; + } + + /** + * Returns the block metadata at coords x,y,z + */ + public int getBlockMetadata(int par1, int par2, int par3) { + if (par1 >= -30000000 && par3 >= -30000000 && par1 < 30000000 && par3 < 30000000) { + if (par2 < 0) { + return 0; + } else if (par2 >= 256) { + return 0; + } else { + Chunk var4 = this.getChunkFromChunkCoords(par1 >> 4, par3 >> 4); + par1 &= 15; + par3 &= 15; + return var4.getBlockMetadata(par1, par2, par3); + } + } else { + return 0; + } + } + + /** + * Sets the blocks metadata and if set will then notify blocks that this block + * changed, depending on the flag. Args: x, y, z, metadata, flag. See setBlock + * for flag description + */ + public boolean setBlockMetadata(int par1, int par2, int par3, int par4, int par5) { + if (par1 >= -30000000 && par3 >= -30000000 && par1 < 30000000 && par3 < 30000000) { + if (par2 < 0) { + return false; + } else if (par2 >= 256) { + return false; + } else { + Chunk var6 = this.getChunkFromChunkCoords(par1 >> 4, par3 >> 4); + int var7 = par1 & 15; + int var8 = par3 & 15; + boolean var9 = var6.setBlockMetadata(var7, par2, var8, par4); + + if (var9) { + int var10 = var6.getBlockID(var7, par2, var8); + + if ((par5 & 2) != 0 && (!this.isRemote || (par5 & 4) == 0)) { + this.markBlockForUpdate(par1, par2, par3); + } + + if (!this.isRemote && (par5 & 1) != 0) { + this.notifyBlockChange(par1, par2, par3, var10); + Block var11 = Block.blocksList[var10]; + + if (var11 != null && var11.hasComparatorInputOverride()) { + this.func_96440_m(par1, par2, par3, var10); + } + } + } + + return var9; + } + } else { + return false; + } + } + + /** + * Sets a block to 0 and notifies relevant systems with the block change Args: + * x, y, z + */ + public boolean setBlockToAir(int par1, int par2, int par3) { + return this.setBlock(par1, par2, par3, 0, 0, 3); + } + + /** + * Destroys a block and optionally drops items. Args: X, Y, Z, dropItems + */ + public boolean destroyBlock(int par1, int par2, int par3, boolean par4) { + int var5 = this.getBlockId(par1, par2, par3); + + if (var5 > 0) { + int var6 = this.getBlockMetadata(par1, par2, par3); + this.playAuxSFX(2001, par1, par2, par3, var5 + (var6 << 12)); + + if (par4) { + Block.blocksList[var5].dropBlockAsItem(this, par1, par2, par3, var6, 0); + } + + return this.setBlock(par1, par2, par3, 0, 0, 3); + } else { + return false; + } + } + + /** + * Sets a block and notifies relevant systems with the block change Args: x, y, + * z, blockID + */ + public boolean setBlock(int par1, int par2, int par3, int par4) { + return this.setBlock(par1, par2, par3, par4, 0, 3); + } + + /** + * On the client, re-renders the block. On the server, sends the block to the + * client (which will re-render it), including the tile entity description + * packet if applicable. Args: x, y, z + */ + public void markBlockForUpdate(int par1, int par2, int par3) { + for (int var4 = 0; var4 < this.worldAccesses.size(); ++var4) { + ((IWorldAccess) this.worldAccesses.get(var4)).markBlockForUpdate(par1, par2, par3); + } + } + + /** + * The block type change and need to notify other systems Args: x, y, z, blockID + */ + public void notifyBlockChange(int par1, int par2, int par3, int par4) { + this.notifyBlocksOfNeighborChange(par1, par2, par3, par4); + } + + /** + * marks a vertical line of blocks as dirty + */ + public void markBlocksDirtyVertical(int par1, int par2, int par3, int par4) { + int var5; + + if (par3 > par4) { + var5 = par4; + par4 = par3; + par3 = var5; + } + + if (!this.provider.hasNoSky) { + for (var5 = par3; var5 <= par4; ++var5) { + this.updateLightByType(EnumSkyBlock.Sky, par1, var5, par2); + } + } + + this.markBlockRangeForRenderUpdate(par1, par3, par2, par1, par4, par2); + } + + /** + * On the client, re-renders all blocks in this range, inclusive. On the server, + * does nothing. Args: min x, min y, min z, max x, max y, max z + */ + public void markBlockRangeForRenderUpdate(int par1, int par2, int par3, int par4, int par5, int par6) { + for (int var7 = 0; var7 < this.worldAccesses.size(); ++var7) { + ((IWorldAccess) this.worldAccesses.get(var7)).markBlockRangeForRenderUpdate(par1, par2, par3, par4, par5, + par6); + } + } + + /** + * Notifies neighboring blocks that this specified block changed Args: x, y, z, + * blockID + */ + public void notifyBlocksOfNeighborChange(int par1, int par2, int par3, int par4) { + this.notifyBlockOfNeighborChange(par1 - 1, par2, par3, par4); + this.notifyBlockOfNeighborChange(par1 + 1, par2, par3, par4); + this.notifyBlockOfNeighborChange(par1, par2 - 1, par3, par4); + this.notifyBlockOfNeighborChange(par1, par2 + 1, par3, par4); + this.notifyBlockOfNeighborChange(par1, par2, par3 - 1, par4); + this.notifyBlockOfNeighborChange(par1, par2, par3 + 1, par4); + } + + /** + * Calls notifyBlockOfNeighborChange on adjacent blocks, except the one on the + * given side. Args: X, Y, Z, changingBlockID, side + */ + public void notifyBlocksOfNeighborChange(int par1, int par2, int par3, int par4, int par5) { + if (par5 != 4) { + this.notifyBlockOfNeighborChange(par1 - 1, par2, par3, par4); + } + + if (par5 != 5) { + this.notifyBlockOfNeighborChange(par1 + 1, par2, par3, par4); + } + + if (par5 != 0) { + this.notifyBlockOfNeighborChange(par1, par2 - 1, par3, par4); + } + + if (par5 != 1) { + this.notifyBlockOfNeighborChange(par1, par2 + 1, par3, par4); + } + + if (par5 != 2) { + this.notifyBlockOfNeighborChange(par1, par2, par3 - 1, par4); + } + + if (par5 != 3) { + this.notifyBlockOfNeighborChange(par1, par2, par3 + 1, par4); + } + } + + /** + * Notifies a block that one of its neighbor change to the specified type Args: + * x, y, z, blockID + */ + public void notifyBlockOfNeighborChange(int par1, int par2, int par3, int par4) { + if (!this.isRemote) { + int var5 = this.getBlockId(par1, par2, par3); + Block var6 = Block.blocksList[var5]; + + if (var6 != null) { + try { + var6.onNeighborBlockChange(this, par1, par2, par3, par4); + } catch (Throwable var13) { + CrashReport var8 = CrashReport.makeCrashReport(var13, "Exception while updating neighbours"); + CrashReportCategory var9 = var8.makeCategory("Block being updated"); + int var10; + + try { + var10 = this.getBlockMetadata(par1, par2, par3); + } catch (Throwable var12) { + var10 = -1; + } + + var9.addCrashSectionCallable("Source block type", new CallableLvl1(this, par4)); + CrashReportCategory.func_85068_a(var9, par1, par2, par3, var5, var10); + throw new ReportedException(var8); + } + } + } + } + + /** + * Returns true if the given block will receive a scheduled tick in the future. + * Args: X, Y, Z, blockID + */ + public boolean isBlockTickScheduled(int par1, int par2, int par3, int par4) { + return false; + } + + /** + * Checks if the specified block is able to see the sky + */ + public boolean canBlockSeeTheSky(int par1, int par2, int par3) { + return this.getChunkFromChunkCoords(par1 >> 4, par3 >> 4).canBlockSeeTheSky(par1 & 15, par2, par3 & 15); + } + + /** + * gets the block's light value - without the _do function's checks. + */ + public int getFullBlockLightValue(int par1, int par2, int par3) { + if (par2 < 0) { + return 0; + } else { + if (par2 >= 256) { + par2 = 255; + } + + return this.getChunkFromChunkCoords(par1 >> 4, par3 >> 4).getBlockLightValue(par1 & 15, par2, par3 & 15, 0); + } + } + + /** + * Gets the light value of a block location + */ + public int getBlockLightValue(int par1, int par2, int par3) { + return this.getBlockLightValue_do(par1, par2, par3, true); + } + + /** + * Gets the light value of a block location. This is the actual function that + * gets the value and has a bool flag that indicates if its a half step block to + * get the maximum light value of a direct neighboring block (left, right, + * forward, back, and up) + */ + public int getBlockLightValue_do(int par1, int par2, int par3, boolean par4) { + if (par1 >= -30000000 && par3 >= -30000000 && par1 < 30000000 && par3 < 30000000) { + if (par4) { + int var5 = this.getBlockId(par1, par2, par3); + + if (Block.useNeighborBrightness[var5]) { + int var6 = this.getBlockLightValue_do(par1, par2 + 1, par3, false); + int var7 = this.getBlockLightValue_do(par1 + 1, par2, par3, false); + int var8 = this.getBlockLightValue_do(par1 - 1, par2, par3, false); + int var9 = this.getBlockLightValue_do(par1, par2, par3 + 1, false); + int var10 = this.getBlockLightValue_do(par1, par2, par3 - 1, false); + + if (var7 > var6) { + var6 = var7; + } + + if (var8 > var6) { + var6 = var8; + } + + if (var9 > var6) { + var6 = var9; + } + + if (var10 > var6) { + var6 = var10; + } + + return var6; + } + } + + if (par2 < 0) { + return 0; + } else { + if (par2 >= 256) { + par2 = 255; + } + + Chunk var11 = this.getChunkFromChunkCoords(par1 >> 4, par3 >> 4); + par1 &= 15; + par3 &= 15; + return var11.getBlockLightValue(par1, par2, par3, this.skylightSubtracted); + } + } else { + return 15; + } + } + + /** + * Returns the y coordinate with a block in it at this x, z coordinate + */ + public int getHeightValue(int par1, int par2) { + if (par1 >= -30000000 && par2 >= -30000000 && par1 < 30000000 && par2 < 30000000) { + if (!this.chunkExists(par1 >> 4, par2 >> 4)) { + return 0; + } else { + Chunk var3 = this.getChunkFromChunkCoords(par1 >> 4, par2 >> 4); + return var3.getHeightValue(par1 & 15, par2 & 15); + } + } else { + return 0; + } + } + + /** + * Gets the heightMapMinimum field of the given chunk, or 0 if the chunk is not + * loaded. Coords are in blocks. Args: X, Z + */ + public int getChunkHeightMapMinimum(int par1, int par2) { + if (par1 >= -30000000 && par2 >= -30000000 && par1 < 30000000 && par2 < 30000000) { + if (!this.chunkExists(par1 >> 4, par2 >> 4)) { + return 0; + } else { + Chunk var3 = this.getChunkFromChunkCoords(par1 >> 4, par2 >> 4); + return var3.heightMapMinimum; + } + } else { + return 0; + } + } + + /** + * Returns saved light value without taking into account the time of day. Either + * looks in the sky light map or block light map based on the enumSkyBlock arg. + */ + public int getSavedLightValue(EnumSkyBlock par1EnumSkyBlock, int par2, int par3, int par4) { + if (par3 < 0) { + par3 = 0; + } + + if (par3 >= 256) { + par3 = 255; + } + + if (par2 >= -30000000 && par4 >= -30000000 && par2 < 30000000 && par4 < 30000000) { + int var5 = par2 >> 4; + int var6 = par4 >> 4; + + if (!this.chunkExists(var5, var6)) { + return par1EnumSkyBlock.defaultLightValue; + } else { + Chunk var7 = this.getChunkFromChunkCoords(var5, var6); + return var7.getSavedLightValue(par1EnumSkyBlock, par2 & 15, par3, par4 & 15); + } + } else { + return par1EnumSkyBlock.defaultLightValue; + } + } + + /** + * Sets the light value either into the sky map or block map depending on if + * enumSkyBlock is set to sky or block. Args: enumSkyBlock, x, y, z, lightValue + */ + public void setLightValue(EnumSkyBlock par1EnumSkyBlock, int par2, int par3, int par4, int par5) { + if (par2 >= -30000000 && par4 >= -30000000 && par2 < 30000000 && par4 < 30000000) { + if (par3 >= 0) { + if (par3 < 256) { + if (this.chunkExists(par2 >> 4, par4 >> 4)) { + Chunk var6 = this.getChunkFromChunkCoords(par2 >> 4, par4 >> 4); + var6.setLightValue(par1EnumSkyBlock, par2 & 15, par3, par4 & 15, par5); + + for (int var7 = 0; var7 < this.worldAccesses.size(); ++var7) { + ((IWorldAccess) this.worldAccesses.get(var7)).markBlockForRenderUpdate(par2, par3, par4); + } + } + } + } + } + } + + /** + * On the client, re-renders this block. On the server, does nothing. Used for + * lighting updates. + */ + public void markBlockForRenderUpdate(int par1, int par2, int par3) { + for (int var4 = 0; var4 < this.worldAccesses.size(); ++var4) { + ((IWorldAccess) this.worldAccesses.get(var4)).markBlockForRenderUpdate(par1, par2, par3); + } + } + + /** + * Returns how bright the block is shown as which is the block's light value + * looked up in a lookup table (light values aren't linear for brightness). + * Args: x, y, z + */ + public float getLightBrightness(int par1, int par2, int par3) { + return this.provider.lightBrightnessTable[this.getBlockLightValue(par1, par2, par3)]; + } + + /** + * Checks whether its daytime by seeing if the light subtracted from the + * skylight is less than 4 + */ + public boolean isDaytime() { + return this.skylightSubtracted < 4; + } + + /** + * ray traces all blocks, including non-collideable ones + */ + public MovingObjectPosition rayTraceBlocks(Vec3 par1Vec3, Vec3 par2Vec3) { + return this.rayTraceBlocks_do_do(par1Vec3, par2Vec3, false, false); + } + + public MovingObjectPosition rayTraceBlocks_do(Vec3 par1Vec3, Vec3 par2Vec3, boolean par3) { + return this.rayTraceBlocks_do_do(par1Vec3, par2Vec3, par3, false); + } + + public MovingObjectPosition rayTraceBlocks_do_do(Vec3 par1Vec3, Vec3 par2Vec3, boolean par3, boolean par4) { + if (!Double.isNaN(par1Vec3.xCoord) && !Double.isNaN(par1Vec3.yCoord) && !Double.isNaN(par1Vec3.zCoord)) { + if (!Double.isNaN(par2Vec3.xCoord) && !Double.isNaN(par2Vec3.yCoord) && !Double.isNaN(par2Vec3.zCoord)) { + int var5 = MathHelper.floor_double(par2Vec3.xCoord); + int var6 = MathHelper.floor_double(par2Vec3.yCoord); + int var7 = MathHelper.floor_double(par2Vec3.zCoord); + int var8 = MathHelper.floor_double(par1Vec3.xCoord); + int var9 = MathHelper.floor_double(par1Vec3.yCoord); + int var10 = MathHelper.floor_double(par1Vec3.zCoord); + int var11 = this.getBlockId(var8, var9, var10); + int var12 = this.getBlockMetadata(var8, var9, var10); + Block var13 = Block.blocksList[var11]; + + if ((!par4 || var13 == null || var13.getCollisionBoundingBoxFromPool(this, var8, var9, var10) != null) + && var11 > 0 && var13.canCollideCheck(var12, par3)) { + MovingObjectPosition var14 = var13.collisionRayTrace(this, var8, var9, var10, par1Vec3, par2Vec3); + + if (var14 != null) { + return var14; + } + } + + var11 = 200; + + while (var11-- >= 0) { + if (Double.isNaN(par1Vec3.xCoord) || Double.isNaN(par1Vec3.yCoord) + || Double.isNaN(par1Vec3.zCoord)) { + return null; + } + + if (var8 == var5 && var9 == var6 && var10 == var7) { + return null; + } + + boolean var39 = true; + boolean var40 = true; + boolean var41 = true; + double var15 = 999.0D; + double var17 = 999.0D; + double var19 = 999.0D; + + if (var5 > var8) { + var15 = (double) var8 + 1.0D; + } else if (var5 < var8) { + var15 = (double) var8 + 0.0D; + } else { + var39 = false; + } + + if (var6 > var9) { + var17 = (double) var9 + 1.0D; + } else if (var6 < var9) { + var17 = (double) var9 + 0.0D; + } else { + var40 = false; + } + + if (var7 > var10) { + var19 = (double) var10 + 1.0D; + } else if (var7 < var10) { + var19 = (double) var10 + 0.0D; + } else { + var41 = false; + } + + double var21 = 999.0D; + double var23 = 999.0D; + double var25 = 999.0D; + double var27 = par2Vec3.xCoord - par1Vec3.xCoord; + double var29 = par2Vec3.yCoord - par1Vec3.yCoord; + double var31 = par2Vec3.zCoord - par1Vec3.zCoord; + + if (var39) { + var21 = (var15 - par1Vec3.xCoord) / var27; + } + + if (var40) { + var23 = (var17 - par1Vec3.yCoord) / var29; + } + + if (var41) { + var25 = (var19 - par1Vec3.zCoord) / var31; + } + + boolean var33 = false; + byte var42; + + if (var21 < var23 && var21 < var25) { + if (var5 > var8) { + var42 = 4; + } else { + var42 = 5; + } + + par1Vec3.xCoord = var15; + par1Vec3.yCoord += var29 * var21; + par1Vec3.zCoord += var31 * var21; + } else if (var23 < var25) { + if (var6 > var9) { + var42 = 0; + } else { + var42 = 1; + } + + par1Vec3.xCoord += var27 * var23; + par1Vec3.yCoord = var17; + par1Vec3.zCoord += var31 * var23; + } else { + if (var7 > var10) { + var42 = 2; + } else { + var42 = 3; + } + + par1Vec3.xCoord += var27 * var25; + par1Vec3.yCoord += var29 * var25; + par1Vec3.zCoord = var19; + } + + Vec3 var34 = this.getWorldVec3Pool().getVecFromPool(par1Vec3.xCoord, par1Vec3.yCoord, + par1Vec3.zCoord); + var8 = (int) (var34.xCoord = (double) MathHelper.floor_double(par1Vec3.xCoord)); + + if (var42 == 5) { + --var8; + ++var34.xCoord; + } + + var9 = (int) (var34.yCoord = (double) MathHelper.floor_double(par1Vec3.yCoord)); + + if (var42 == 1) { + --var9; + ++var34.yCoord; + } + + var10 = (int) (var34.zCoord = (double) MathHelper.floor_double(par1Vec3.zCoord)); + + if (var42 == 3) { + --var10; + ++var34.zCoord; + } + + int var35 = this.getBlockId(var8, var9, var10); + int var36 = this.getBlockMetadata(var8, var9, var10); + Block var37 = Block.blocksList[var35]; + + if ((!par4 || var37 == null + || var37.getCollisionBoundingBoxFromPool(this, var8, var9, var10) != null) && var35 > 0 + && var37.canCollideCheck(var36, par3)) { + MovingObjectPosition var38 = var37.collisionRayTrace(this, var8, var9, var10, par1Vec3, + par2Vec3); + + if (var38 != null) { + return var38; + } + } + } + + return null; + } else { + return null; + } + } else { + return null; + } + } + + /** + * Plays a sound at the entity's position. Args: entity, sound, volume (relative + * to 1.0), and frequency (or pitch, also relative to 1.0). + */ + public void playSoundAtEntity(Entity par1Entity, String par2Str, float par3, float par4) { + if (par1Entity != null && par2Str != null) { + for (int var5 = 0; var5 < this.worldAccesses.size(); ++var5) { + ((IWorldAccess) this.worldAccesses.get(var5)).playSound(par2Str, par1Entity.posX, + par1Entity.posY - (double) par1Entity.yOffset, par1Entity.posZ, par3, par4); + } + } + } + + /** + * Plays sound to all near players except the player reference given + */ + public void playSoundToNearExcept(EntityPlayer par1EntityPlayer, String par2Str, float par3, float par4) { + if (par1EntityPlayer != null && par2Str != null) { + for (int var5 = 0; var5 < this.worldAccesses.size(); ++var5) { + ((IWorldAccess) this.worldAccesses.get(var5)).playSoundToNearExcept(par1EntityPlayer, par2Str, + par1EntityPlayer.posX, par1EntityPlayer.posY - (double) par1EntityPlayer.yOffset, + par1EntityPlayer.posZ, par3, par4); + } + } + } + + /** + * Play a sound effect. Many many parameters for this function. Not sure what + * they do, but a classic call is : (double)i + 0.5D, (double)j + 0.5D, + * (double)k + 0.5D, 'random.door_open', 1.0F, world.rand.nextFloat() * 0.1F + + * 0.9F with i,j,k position of the block. + */ + public void playSoundEffect(double par1, double par3, double par5, String par7Str, float par8, float par9) { + if (par7Str != null) { + for (int var10 = 0; var10 < this.worldAccesses.size(); ++var10) { + ((IWorldAccess) this.worldAccesses.get(var10)).playSound(par7Str, par1, par3, par5, par8, par9); + } + } + } + + /** + * par8 is loudness, all pars passed to minecraftInstance.sndManager.playSound + */ + public void playSound(double par1, double par3, double par5, String par7Str, float par8, float par9, + boolean par10) { + } + + /** + * Plays a record at the specified coordinates of the specified name. Args: + * recordName, x, y, z + */ + public void playRecord(String par1Str, int par2, int par3, int par4) { + for (int var5 = 0; var5 < this.worldAccesses.size(); ++var5) { + ((IWorldAccess) this.worldAccesses.get(var5)).playRecord(par1Str, par2, par3, par4); + } + } + + /** + * Spawns a particle. Args particleName, x, y, z, velX, velY, velZ + */ + public void spawnParticle(String par1Str, double par2, double par4, double par6, double par8, double par10, + double par12) { + for (int var14 = 0; var14 < this.worldAccesses.size(); ++var14) { + ((IWorldAccess) this.worldAccesses.get(var14)).spawnParticle(par1Str, par2, par4, par6, par8, par10, par12); + } + } + + /** + * adds a lightning bolt to the list of lightning bolts in this world. + */ + public boolean addWeatherEffect(Entity par1Entity) { + this.weatherEffects.add(par1Entity); + return true; + } + + /** + * Called when an entity is spawned in the world. This includes players. + */ + public boolean spawnEntityInWorld(Entity par1Entity) { + int var2 = MathHelper.floor_double(par1Entity.posX / 16.0D); + int var3 = MathHelper.floor_double(par1Entity.posZ / 16.0D); + boolean var4 = par1Entity.field_98038_p; + + if (par1Entity instanceof EntityPlayer) { + var4 = true; + } + + if (!var4 && !this.chunkExists(var2, var3)) { + return false; + } else { + if (par1Entity instanceof EntityPlayer) { + EntityPlayer var5 = (EntityPlayer) par1Entity; + this.playerEntities.add(var5); + this.updateAllPlayersSleepingFlag(); + } + + this.getChunkFromChunkCoords(var2, var3).addEntity(par1Entity); + this.loadedEntityList.add(par1Entity); + this.obtainEntitySkin(par1Entity); + return true; + } + } + + /** + * Start the skin for this entity downloading, if necessary, and increment its + * reference counter + */ + protected void obtainEntitySkin(Entity par1Entity) { + for (int var2 = 0; var2 < this.worldAccesses.size(); ++var2) { + ((IWorldAccess) this.worldAccesses.get(var2)).onEntityCreate(par1Entity); + } + } + + /** + * Decrement the reference counter for this entity's skin image data + */ + protected void releaseEntitySkin(Entity par1Entity) { + for (int var2 = 0; var2 < this.worldAccesses.size(); ++var2) { + ((IWorldAccess) this.worldAccesses.get(var2)).onEntityDestroy(par1Entity); + } + } + + /** + * Schedule the entity for removal during the next tick. Marks the entity dead + * in anticipation. + */ + public void removeEntity(Entity par1Entity) { + if (par1Entity.riddenByEntity != null) { + par1Entity.riddenByEntity.mountEntity((Entity) null); + } + + if (par1Entity.ridingEntity != null) { + par1Entity.mountEntity((Entity) null); + } + + par1Entity.setDead(); + + if (par1Entity instanceof EntityPlayer) { + this.playerEntities.remove(par1Entity); + this.updateAllPlayersSleepingFlag(); + } + } + + /** + * Do NOT use this method to remove normal entities- use normal removeEntity + */ + public void removePlayerEntityDangerously(Entity par1Entity) { + par1Entity.setDead(); + + if (par1Entity instanceof EntityPlayer) { + this.playerEntities.remove(par1Entity); + this.updateAllPlayersSleepingFlag(); + } + + int var2 = par1Entity.chunkCoordX; + int var3 = par1Entity.chunkCoordZ; + + if (par1Entity.addedToChunk && this.chunkExists(var2, var3)) { + this.getChunkFromChunkCoords(var2, var3).removeEntity(par1Entity); + } + + this.loadedEntityList.remove(par1Entity); + this.releaseEntitySkin(par1Entity); + } + + /** + * Adds a IWorldAccess to the list of worldAccesses + */ + public void addWorldAccess(IWorldAccess par1IWorldAccess) { + this.worldAccesses.add(par1IWorldAccess); + } + + /** + * Returns a list of bounding boxes that collide with aabb excluding the passed + * in entity's collision. Args: entity, aabb + */ + public List getCollidingBoundingBoxes(Entity par1Entity, AxisAlignedBB par2AxisAlignedBB) { + this.collidingBoundingBoxes.clear(); + int var3 = MathHelper.floor_double(par2AxisAlignedBB.minX); + int var4 = MathHelper.floor_double(par2AxisAlignedBB.maxX + 1.0D); + int var5 = MathHelper.floor_double(par2AxisAlignedBB.minY); + int var6 = MathHelper.floor_double(par2AxisAlignedBB.maxY + 1.0D); + int var7 = MathHelper.floor_double(par2AxisAlignedBB.minZ); + int var8 = MathHelper.floor_double(par2AxisAlignedBB.maxZ + 1.0D); + + for (int var9 = var3; var9 < var4; ++var9) { + for (int var10 = var7; var10 < var8; ++var10) { + if (this.blockExists(var9, 64, var10)) { + for (int var11 = var5 - 1; var11 < var6; ++var11) { + Block var12 = Block.blocksList[this.getBlockId(var9, var11, var10)]; + + if (var12 != null) { + var12.addCollisionBoxesToList(this, var9, var11, var10, par2AxisAlignedBB, + this.collidingBoundingBoxes, par1Entity); + } + } + } + } + } + + double var14 = 0.25D; + List var15 = this.getEntitiesWithinAABBExcludingEntity(par1Entity, + par2AxisAlignedBB.expand(var14, var14, var14)); + + for (int var16 = 0; var16 < var15.size(); ++var16) { + AxisAlignedBB var13 = ((Entity) var15.get(var16)).getBoundingBox(); + + if (var13 != null && var13.intersectsWith(par2AxisAlignedBB)) { + this.collidingBoundingBoxes.add(var13); + } + + var13 = par1Entity.getCollisionBox((Entity) var15.get(var16)); + + if (var13 != null && var13.intersectsWith(par2AxisAlignedBB)) { + this.collidingBoundingBoxes.add(var13); + } + } + + return this.collidingBoundingBoxes; + } + + /** + * calculates and returns a list of colliding bounding boxes within a given AABB + */ + public List getCollidingBlockBounds(AxisAlignedBB par1AxisAlignedBB) { + this.collidingBoundingBoxes.clear(); + int var2 = MathHelper.floor_double(par1AxisAlignedBB.minX); + int var3 = MathHelper.floor_double(par1AxisAlignedBB.maxX + 1.0D); + int var4 = MathHelper.floor_double(par1AxisAlignedBB.minY); + int var5 = MathHelper.floor_double(par1AxisAlignedBB.maxY + 1.0D); + int var6 = MathHelper.floor_double(par1AxisAlignedBB.minZ); + int var7 = MathHelper.floor_double(par1AxisAlignedBB.maxZ + 1.0D); + + for (int var8 = var2; var8 < var3; ++var8) { + for (int var9 = var6; var9 < var7; ++var9) { + if (this.blockExists(var8, 64, var9)) { + for (int var10 = var4 - 1; var10 < var5; ++var10) { + Block var11 = Block.blocksList[this.getBlockId(var8, var10, var9)]; + + if (var11 != null) { + var11.addCollisionBoxesToList(this, var8, var10, var9, par1AxisAlignedBB, + this.collidingBoundingBoxes, (Entity) null); + } + } + } + } + } + + return this.collidingBoundingBoxes; + } + + /** + * Returns the amount of skylight subtracted for the current time + */ + public int calculateSkylightSubtracted(float par1) { + float var2 = this.getCelestialAngle(par1); + float var3 = 1.0F - (MathHelper.cos(var2 * (float) Math.PI * 2.0F) * 2.0F + 0.5F); + + if (var3 < 0.0F) { + var3 = 0.0F; + } + + if (var3 > 1.0F) { + var3 = 1.0F; + } + + var3 = 1.0F - var3; + var3 = (float) ((double) var3 * (1.0D - (double) (this.getRainStrength(par1) * 5.0F) / 16.0D)); + var3 = (float) ((double) var3 * (1.0D - (double) (this.getWeightedThunderStrength(par1) * 5.0F) / 16.0D)); + var3 = 1.0F - var3; + return (int) (var3 * 11.0F); + } + + /** + * calls calculateCelestialAngle + */ + public float getCelestialAngle(float par1) { + return this.provider.calculateCelestialAngle(this.worldInfo.getWorldTime(), par1); + } + + public int getMoonPhase() { + return this.provider.func_76559_b(this.worldInfo.getWorldTime()); + } + + /** + * Return getCelestialAngle()*2*PI + */ + public float getCelestialAngleRadians(float par1) { + float var2 = this.getCelestialAngle(par1); + return var2 * (float) Math.PI * 2.0F; + } + + /** + * Gets the height to which rain/snow will fall. Calculates it if not already + * stored. + */ + public int getPrecipitationHeight(int par1, int par2) { + return this.getChunkFromBlockCoords(par1, par2).getPrecipitationHeight(par1 & 15, par2 & 15); + } + + /** + * Finds the highest block on the x, z coordinate that is solid and returns its + * y coord. Args x, z + */ + public int getTopSolidOrLiquidBlock(int par1, int par2) { + Chunk var3 = this.getChunkFromBlockCoords(par1, par2); + int var4 = var3.getTopFilledSegment() + 15; + par1 &= 15; + + for (par2 &= 15; var4 > 0; --var4) { + int var5 = var3.getBlockID(par1, var4, par2); + + if (var5 != 0 && Block.blocksList[var5].blockMaterial.blocksMovement() + && Block.blocksList[var5].blockMaterial != Material.leaves) { + return var4 + 1; + } + } + + return -1; + } + + /** + * Used to schedule a call to the updateTick method on the specified block. + */ + public void scheduleBlockUpdate(int par1, int par2, int par3, int par4, int par5) { + } + + public void func_82740_a(int par1, int par2, int par3, int par4, int par5, int par6) { + } + + /** + * Schedules a block update from the saved information in a chunk. Called when + * the chunk is loaded. + */ + public void scheduleBlockUpdateFromLoad(int par1, int par2, int par3, int par4, int par5, int par6) { + } + + /** + * Updates (and cleans up) entities and tile entities + */ + public void updateEntities() { + this.theProfiler.startSection("entities"); + this.theProfiler.startSection("global"); + int var1; + Entity var2; + CrashReport var4; + CrashReportCategory var5; + + for (var1 = 0; var1 < this.weatherEffects.size(); ++var1) { + var2 = (Entity) this.weatherEffects.get(var1); + + try { + ++var2.ticksExisted; + var2.onUpdate(); + } catch (Throwable var8) { + var4 = CrashReport.makeCrashReport(var8, "Ticking entity"); + var5 = var4.makeCategory("Entity being ticked"); + + if (var2 == null) { + var5.addCrashSection("Entity", "~~NULL~~"); + } else { + var2.func_85029_a(var5); + } + + throw new ReportedException(var4); + } + + if (var2.isDead) { + this.weatherEffects.remove(var1--); + } + } + + this.theProfiler.endStartSection("remove"); + this.loadedEntityList.removeAll(this.unloadedEntityList); + int var3; + int var13; + + for (var1 = 0; var1 < this.unloadedEntityList.size(); ++var1) { + var2 = (Entity) this.unloadedEntityList.get(var1); + var3 = var2.chunkCoordX; + var13 = var2.chunkCoordZ; + + if (var2.addedToChunk && this.chunkExists(var3, var13)) { + this.getChunkFromChunkCoords(var3, var13).removeEntity(var2); + } + } + + for (var1 = 0; var1 < this.unloadedEntityList.size(); ++var1) { + this.releaseEntitySkin((Entity) this.unloadedEntityList.get(var1)); + } + + this.unloadedEntityList.clear(); + this.theProfiler.endStartSection("regular"); + + for (var1 = 0; var1 < this.loadedEntityList.size(); ++var1) { + var2 = (Entity) this.loadedEntityList.get(var1); + + if (var2.ridingEntity != null) { + if (!var2.ridingEntity.isDead && var2.ridingEntity.riddenByEntity == var2) { + continue; + } + + var2.ridingEntity.riddenByEntity = null; + var2.ridingEntity = null; + } + + this.theProfiler.startSection("tick"); + + if (!var2.isDead) { + try { + this.updateEntity(var2); + } catch (Throwable var7) { + var4 = CrashReport.makeCrashReport(var7, "Ticking entity"); + var5 = var4.makeCategory("Entity being ticked"); + var2.func_85029_a(var5); + throw new ReportedException(var4); + } + } + + this.theProfiler.endSection(); + this.theProfiler.startSection("remove"); + + if (var2.isDead) { + var3 = var2.chunkCoordX; + var13 = var2.chunkCoordZ; + + if (var2.addedToChunk && this.chunkExists(var3, var13)) { + this.getChunkFromChunkCoords(var3, var13).removeEntity(var2); + } + + this.loadedEntityList.remove(var1--); + this.releaseEntitySkin(var2); + } + + this.theProfiler.endSection(); + } + + this.theProfiler.endStartSection("tileEntities"); + this.scanningTileEntities = true; + Iterator var14 = this.loadedTileEntityList.iterator(); + + while (var14.hasNext()) { + TileEntity var9 = (TileEntity) var14.next(); + + if (!var9.isInvalid() && var9.func_70309_m() && this.blockExists(var9.xCoord, var9.yCoord, var9.zCoord)) { + try { + var9.updateEntity(); + } catch (Throwable var6) { + var4 = CrashReport.makeCrashReport(var6, "Ticking tile entity"); + var5 = var4.makeCategory("Tile entity being ticked"); + var9.func_85027_a(var5); + throw new ReportedException(var4); + } + } + + if (var9.isInvalid()) { + var14.remove(); + + if (this.chunkExists(var9.xCoord >> 4, var9.zCoord >> 4)) { + Chunk var11 = this.getChunkFromChunkCoords(var9.xCoord >> 4, var9.zCoord >> 4); + + if (var11 != null) { + var11.removeChunkBlockTileEntity(var9.xCoord & 15, var9.yCoord, var9.zCoord & 15); + } + } + } + } + + this.scanningTileEntities = false; + + if (!this.entityRemoval.isEmpty()) { + this.loadedTileEntityList.removeAll(this.entityRemoval); + this.entityRemoval.clear(); + } + + this.theProfiler.endStartSection("pendingTileEntities"); + + if (!this.addedTileEntityList.isEmpty()) { + for (int var10 = 0; var10 < this.addedTileEntityList.size(); ++var10) { + TileEntity var12 = (TileEntity) this.addedTileEntityList.get(var10); + + if (!var12.isInvalid()) { + if (!this.loadedTileEntityList.contains(var12)) { + this.loadedTileEntityList.add(var12); + } + + if (this.chunkExists(var12.xCoord >> 4, var12.zCoord >> 4)) { + Chunk var15 = this.getChunkFromChunkCoords(var12.xCoord >> 4, var12.zCoord >> 4); + + if (var15 != null) { + var15.setChunkBlockTileEntity(var12.xCoord & 15, var12.yCoord, var12.zCoord & 15, var12); + } + } + + this.markBlockForUpdate(var12.xCoord, var12.yCoord, var12.zCoord); + } + } + + this.addedTileEntityList.clear(); + } + + this.theProfiler.endSection(); + this.theProfiler.endSection(); + } + + public void addTileEntity(Collection par1Collection) { + if (this.scanningTileEntities) { + this.addedTileEntityList.addAll(par1Collection); + } else { + this.loadedTileEntityList.addAll(par1Collection); + } + } + + /** + * Will update the entity in the world if the chunk the entity is in is + * currently loaded. Args: entity + */ + public void updateEntity(Entity par1Entity) { + this.updateEntityWithOptionalForce(par1Entity, true); + } + + /** + * Will update the entity in the world if the chunk the entity is in is + * currently loaded or its forced to update. Args: entity, forceUpdate + */ + public void updateEntityWithOptionalForce(Entity par1Entity, boolean par2) { + int var3 = MathHelper.floor_double(par1Entity.posX); + int var4 = MathHelper.floor_double(par1Entity.posZ); + byte var5 = 32; + + if (!par2 || this.checkChunksExist(var3 - var5, 0, var4 - var5, var3 + var5, 0, var4 + var5)) { + par1Entity.lastTickPosX = par1Entity.posX; + par1Entity.lastTickPosY = par1Entity.posY; + par1Entity.lastTickPosZ = par1Entity.posZ; + par1Entity.prevRotationYaw = par1Entity.rotationYaw; + par1Entity.prevRotationPitch = par1Entity.rotationPitch; + + if (par2 && par1Entity.addedToChunk) { + if (par1Entity.ridingEntity != null) { + par1Entity.updateRidden(); + } else { + ++par1Entity.ticksExisted; + par1Entity.onUpdate(); + } + } + + this.theProfiler.startSection("chunkCheck"); + + if (Double.isNaN(par1Entity.posX) || Double.isInfinite(par1Entity.posX)) { + par1Entity.posX = par1Entity.lastTickPosX; + } + + if (Double.isNaN(par1Entity.posY) || Double.isInfinite(par1Entity.posY)) { + par1Entity.posY = par1Entity.lastTickPosY; + } + + if (Double.isNaN(par1Entity.posZ) || Double.isInfinite(par1Entity.posZ)) { + par1Entity.posZ = par1Entity.lastTickPosZ; + } + + if (Double.isNaN((double) par1Entity.rotationPitch) + || Double.isInfinite((double) par1Entity.rotationPitch)) { + par1Entity.rotationPitch = par1Entity.prevRotationPitch; + } + + if (Double.isNaN((double) par1Entity.rotationYaw) || Double.isInfinite((double) par1Entity.rotationYaw)) { + par1Entity.rotationYaw = par1Entity.prevRotationYaw; + } + + int var6 = MathHelper.floor_double(par1Entity.posX / 16.0D); + int var7 = MathHelper.floor_double(par1Entity.posY / 16.0D); + int var8 = MathHelper.floor_double(par1Entity.posZ / 16.0D); + + if (!par1Entity.addedToChunk || par1Entity.chunkCoordX != var6 || par1Entity.chunkCoordY != var7 + || par1Entity.chunkCoordZ != var8) { + if (par1Entity.addedToChunk && this.chunkExists(par1Entity.chunkCoordX, par1Entity.chunkCoordZ)) { + this.getChunkFromChunkCoords(par1Entity.chunkCoordX, par1Entity.chunkCoordZ) + .removeEntityAtIndex(par1Entity, par1Entity.chunkCoordY); + } + + if (this.chunkExists(var6, var8)) { + par1Entity.addedToChunk = true; + this.getChunkFromChunkCoords(var6, var8).addEntity(par1Entity); + } else { + par1Entity.addedToChunk = false; + } + } + + this.theProfiler.endSection(); + + if (par2 && par1Entity.addedToChunk && par1Entity.riddenByEntity != null) { + if (!par1Entity.riddenByEntity.isDead && par1Entity.riddenByEntity.ridingEntity == par1Entity) { + this.updateEntity(par1Entity.riddenByEntity); + } else { + par1Entity.riddenByEntity.ridingEntity = null; + par1Entity.riddenByEntity = null; + } + } + } + } + + /** + * Returns true if there are no solid, live entities in the specified + * AxisAlignedBB + */ + public boolean checkNoEntityCollision(AxisAlignedBB par1AxisAlignedBB) { + return this.checkNoEntityCollision(par1AxisAlignedBB, (Entity) null); + } + + /** + * Returns true if there are no solid, live entities in the specified + * AxisAlignedBB, excluding the given entity + */ + public boolean checkNoEntityCollision(AxisAlignedBB par1AxisAlignedBB, Entity par2Entity) { + List var3 = this.getEntitiesWithinAABBExcludingEntity((Entity) null, par1AxisAlignedBB); + + for (int var4 = 0; var4 < var3.size(); ++var4) { + Entity var5 = (Entity) var3.get(var4); + + if (!var5.isDead && var5.preventEntitySpawning && var5 != par2Entity) { + return false; + } + } + + return true; + } + + /** + * Returns true if there are any blocks in the region constrained by an + * AxisAlignedBB + */ + public boolean checkBlockCollision(AxisAlignedBB par1AxisAlignedBB) { + int var2 = MathHelper.floor_double(par1AxisAlignedBB.minX); + int var3 = MathHelper.floor_double(par1AxisAlignedBB.maxX + 1.0D); + int var4 = MathHelper.floor_double(par1AxisAlignedBB.minY); + int var5 = MathHelper.floor_double(par1AxisAlignedBB.maxY + 1.0D); + int var6 = MathHelper.floor_double(par1AxisAlignedBB.minZ); + int var7 = MathHelper.floor_double(par1AxisAlignedBB.maxZ + 1.0D); + + if (par1AxisAlignedBB.minX < 0.0D) { + --var2; + } + + if (par1AxisAlignedBB.minY < 0.0D) { + --var4; + } + + if (par1AxisAlignedBB.minZ < 0.0D) { + --var6; + } + + for (int var8 = var2; var8 < var3; ++var8) { + for (int var9 = var4; var9 < var5; ++var9) { + for (int var10 = var6; var10 < var7; ++var10) { + Block var11 = Block.blocksList[this.getBlockId(var8, var9, var10)]; + + if (var11 != null) { + return true; + } + } + } + } + + return false; + } + + /** + * Returns if any of the blocks within the aabb are liquids. Args: aabb + */ + public boolean isAnyLiquid(AxisAlignedBB par1AxisAlignedBB) { + int var2 = MathHelper.floor_double(par1AxisAlignedBB.minX); + int var3 = MathHelper.floor_double(par1AxisAlignedBB.maxX + 1.0D); + int var4 = MathHelper.floor_double(par1AxisAlignedBB.minY); + int var5 = MathHelper.floor_double(par1AxisAlignedBB.maxY + 1.0D); + int var6 = MathHelper.floor_double(par1AxisAlignedBB.minZ); + int var7 = MathHelper.floor_double(par1AxisAlignedBB.maxZ + 1.0D); + + if (par1AxisAlignedBB.minX < 0.0D) { + --var2; + } + + if (par1AxisAlignedBB.minY < 0.0D) { + --var4; + } + + if (par1AxisAlignedBB.minZ < 0.0D) { + --var6; + } + + for (int var8 = var2; var8 < var3; ++var8) { + for (int var9 = var4; var9 < var5; ++var9) { + for (int var10 = var6; var10 < var7; ++var10) { + Block var11 = Block.blocksList[this.getBlockId(var8, var9, var10)]; + + if (var11 != null && var11.blockMaterial.isLiquid()) { + return true; + } + } + } + } + + return false; + } + + /** + * Returns whether or not the given bounding box is on fire or not + */ + public boolean isBoundingBoxBurning(AxisAlignedBB par1AxisAlignedBB) { + int var2 = MathHelper.floor_double(par1AxisAlignedBB.minX); + int var3 = MathHelper.floor_double(par1AxisAlignedBB.maxX + 1.0D); + int var4 = MathHelper.floor_double(par1AxisAlignedBB.minY); + int var5 = MathHelper.floor_double(par1AxisAlignedBB.maxY + 1.0D); + int var6 = MathHelper.floor_double(par1AxisAlignedBB.minZ); + int var7 = MathHelper.floor_double(par1AxisAlignedBB.maxZ + 1.0D); + + if (this.checkChunksExist(var2, var4, var6, var3, var5, var7)) { + for (int var8 = var2; var8 < var3; ++var8) { + for (int var9 = var4; var9 < var5; ++var9) { + for (int var10 = var6; var10 < var7; ++var10) { + int var11 = this.getBlockId(var8, var9, var10); + + if (var11 == Block.fire.blockID || var11 == Block.lavaMoving.blockID + || var11 == Block.lavaStill.blockID) { + return true; + } + } + } + } + } + + return false; + } + + /** + * handles the acceleration of an object whilst in water. Not sure if it is used + * elsewhere. + */ + public boolean handleMaterialAcceleration(AxisAlignedBB par1AxisAlignedBB, Material par2Material, + Entity par3Entity) { + int var4 = MathHelper.floor_double(par1AxisAlignedBB.minX); + int var5 = MathHelper.floor_double(par1AxisAlignedBB.maxX + 1.0D); + int var6 = MathHelper.floor_double(par1AxisAlignedBB.minY); + int var7 = MathHelper.floor_double(par1AxisAlignedBB.maxY + 1.0D); + int var8 = MathHelper.floor_double(par1AxisAlignedBB.minZ); + int var9 = MathHelper.floor_double(par1AxisAlignedBB.maxZ + 1.0D); + + if (!this.checkChunksExist(var4, var6, var8, var5, var7, var9)) { + return false; + } else { + boolean var10 = false; + Vec3 var11 = this.getWorldVec3Pool().getVecFromPool(0.0D, 0.0D, 0.0D); + + for (int var12 = var4; var12 < var5; ++var12) { + for (int var13 = var6; var13 < var7; ++var13) { + for (int var14 = var8; var14 < var9; ++var14) { + Block var15 = Block.blocksList[this.getBlockId(var12, var13, var14)]; + + if (var15 != null && var15.blockMaterial == par2Material) { + double var16 = (double) ((float) (var13 + 1) + - BlockFluid.getFluidHeightPercent(this.getBlockMetadata(var12, var13, var14))); + + if ((double) var7 >= var16) { + var10 = true; + var15.velocityToAddToEntity(this, var12, var13, var14, par3Entity, var11); + } + } + } + } + } + + if (var11.lengthVector() > 0.0D && par3Entity.func_96092_aw()) { + var11 = var11.normalize(); + double var18 = 0.014D; + par3Entity.motionX += var11.xCoord * var18; + par3Entity.motionY += var11.yCoord * var18; + par3Entity.motionZ += var11.zCoord * var18; + } + + return var10; + } + } + + /** + * Returns true if the given bounding box contains the given material + */ + public boolean isMaterialInBB(AxisAlignedBB par1AxisAlignedBB, Material par2Material) { + int var3 = MathHelper.floor_double(par1AxisAlignedBB.minX); + int var4 = MathHelper.floor_double(par1AxisAlignedBB.maxX + 1.0D); + int var5 = MathHelper.floor_double(par1AxisAlignedBB.minY); + int var6 = MathHelper.floor_double(par1AxisAlignedBB.maxY + 1.0D); + int var7 = MathHelper.floor_double(par1AxisAlignedBB.minZ); + int var8 = MathHelper.floor_double(par1AxisAlignedBB.maxZ + 1.0D); + + for (int var9 = var3; var9 < var4; ++var9) { + for (int var10 = var5; var10 < var6; ++var10) { + for (int var11 = var7; var11 < var8; ++var11) { + Block var12 = Block.blocksList[this.getBlockId(var9, var10, var11)]; + + if (var12 != null && var12.blockMaterial == par2Material) { + return true; + } + } + } + } + + return false; + } + + /** + * checks if the given AABB is in the material given. Used while swimming. + */ + public boolean isAABBInMaterial(AxisAlignedBB par1AxisAlignedBB, Material par2Material) { + int var3 = MathHelper.floor_double(par1AxisAlignedBB.minX); + int var4 = MathHelper.floor_double(par1AxisAlignedBB.maxX + 1.0D); + int var5 = MathHelper.floor_double(par1AxisAlignedBB.minY); + int var6 = MathHelper.floor_double(par1AxisAlignedBB.maxY + 1.0D); + int var7 = MathHelper.floor_double(par1AxisAlignedBB.minZ); + int var8 = MathHelper.floor_double(par1AxisAlignedBB.maxZ + 1.0D); + + for (int var9 = var3; var9 < var4; ++var9) { + for (int var10 = var5; var10 < var6; ++var10) { + for (int var11 = var7; var11 < var8; ++var11) { + Block var12 = Block.blocksList[this.getBlockId(var9, var10, var11)]; + + if (var12 != null && var12.blockMaterial == par2Material) { + int var13 = this.getBlockMetadata(var9, var10, var11); + double var14 = (double) (var10 + 1); + + if (var13 < 8) { + var14 = (double) (var10 + 1) - (double) var13 / 8.0D; + } + + if (var14 >= par1AxisAlignedBB.minY) { + return true; + } + } + } + } + } + + return false; + } + + /** + * Creates an explosion. Args: entity, x, y, z, strength + */ + public Explosion createExplosion(Entity par1Entity, double par2, double par4, double par6, float par8, + boolean par9) { + return this.newExplosion(par1Entity, par2, par4, par6, par8, false, par9); + } + + /** + * returns a new explosion. Does initiation (at time of writing Explosion is not + * finished) + */ + public Explosion newExplosion(Entity par1Entity, double par2, double par4, double par6, float par8, boolean par9, + boolean par10) { + Explosion var11 = new Explosion(this, par1Entity, par2, par4, par6, par8); + var11.isFlaming = par9; + var11.isSmoking = par10; + var11.doExplosionA(); + var11.doExplosionB(true); + return var11; + } + + /** + * Gets the percentage of real blocks within within a bounding box, along a + * specified vector. + */ + public float getBlockDensity(Vec3 par1Vec3, AxisAlignedBB par2AxisAlignedBB) { + double var3 = 1.0D / ((par2AxisAlignedBB.maxX - par2AxisAlignedBB.minX) * 2.0D + 1.0D); + double var5 = 1.0D / ((par2AxisAlignedBB.maxY - par2AxisAlignedBB.minY) * 2.0D + 1.0D); + double var7 = 1.0D / ((par2AxisAlignedBB.maxZ - par2AxisAlignedBB.minZ) * 2.0D + 1.0D); + int var9 = 0; + int var10 = 0; + + for (float var11 = 0.0F; var11 <= 1.0F; var11 = (float) ((double) var11 + var3)) { + for (float var12 = 0.0F; var12 <= 1.0F; var12 = (float) ((double) var12 + var5)) { + for (float var13 = 0.0F; var13 <= 1.0F; var13 = (float) ((double) var13 + var7)) { + double var14 = par2AxisAlignedBB.minX + + (par2AxisAlignedBB.maxX - par2AxisAlignedBB.minX) * (double) var11; + double var16 = par2AxisAlignedBB.minY + + (par2AxisAlignedBB.maxY - par2AxisAlignedBB.minY) * (double) var12; + double var18 = par2AxisAlignedBB.minZ + + (par2AxisAlignedBB.maxZ - par2AxisAlignedBB.minZ) * (double) var13; + + if (this.rayTraceBlocks(this.getWorldVec3Pool().getVecFromPool(var14, var16, var18), + par1Vec3) == null) { + ++var9; + } + + ++var10; + } + } + } + + return (float) var9 / (float) var10; + } + + /** + * If the block in the given direction of the given coordinate is fire, + * extinguish it. Args: Player, X,Y,Z, blockDirection + */ + public boolean extinguishFire(EntityPlayer par1EntityPlayer, int par2, int par3, int par4, int par5) { + if (par5 == 0) { + --par3; + } + + if (par5 == 1) { + ++par3; + } + + if (par5 == 2) { + --par4; + } + + if (par5 == 3) { + ++par4; + } + + if (par5 == 4) { + --par2; + } + + if (par5 == 5) { + ++par2; + } + + if (this.getBlockId(par2, par3, par4) == Block.fire.blockID) { + this.playAuxSFXAtEntity(par1EntityPlayer, 1004, par2, par3, par4, 0); + this.setBlockToAir(par2, par3, par4); + return true; + } else { + return false; + } + } + + /** + * Returns the TileEntity associated with a given block in X,Y,Z coordinates, or + * null if no TileEntity exists + */ + public TileEntity getBlockTileEntity(int par1, int par2, int par3) { + if (par2 >= 0 && par2 < 256) { + TileEntity var4 = null; + int var5; + TileEntity var6; + + if (this.scanningTileEntities) { + for (var5 = 0; var5 < this.addedTileEntityList.size(); ++var5) { + var6 = (TileEntity) this.addedTileEntityList.get(var5); + + if (!var6.isInvalid() && var6.xCoord == par1 && var6.yCoord == par2 && var6.zCoord == par3) { + var4 = var6; + break; + } + } + } + + if (var4 == null) { + Chunk var7 = this.getChunkFromChunkCoords(par1 >> 4, par3 >> 4); + + if (var7 != null) { + var4 = var7.getChunkBlockTileEntity(par1 & 15, par2, par3 & 15); + } + } + + if (var4 == null) { + for (var5 = 0; var5 < this.addedTileEntityList.size(); ++var5) { + var6 = (TileEntity) this.addedTileEntityList.get(var5); + + if (!var6.isInvalid() && var6.xCoord == par1 && var6.yCoord == par2 && var6.zCoord == par3) { + var4 = var6; + break; + } + } + } + + return var4; + } else { + return null; + } + } + + /** + * Sets the TileEntity for a given block in X, Y, Z coordinates + */ + public void setBlockTileEntity(int par1, int par2, int par3, TileEntity par4TileEntity) { + if (par4TileEntity != null && !par4TileEntity.isInvalid()) { + if (this.scanningTileEntities) { + par4TileEntity.xCoord = par1; + par4TileEntity.yCoord = par2; + par4TileEntity.zCoord = par3; + Iterator var5 = this.addedTileEntityList.iterator(); + + while (var5.hasNext()) { + TileEntity var6 = (TileEntity) var5.next(); + + if (var6.xCoord == par1 && var6.yCoord == par2 && var6.zCoord == par3) { + var6.invalidate(); + var5.remove(); + } + } + + this.addedTileEntityList.add(par4TileEntity); + } else { + this.loadedTileEntityList.add(par4TileEntity); + Chunk var7 = this.getChunkFromChunkCoords(par1 >> 4, par3 >> 4); + + if (var7 != null) { + var7.setChunkBlockTileEntity(par1 & 15, par2, par3 & 15, par4TileEntity); + } + } + } + } + + /** + * Removes the TileEntity for a given block in X,Y,Z coordinates + */ + public void removeBlockTileEntity(int par1, int par2, int par3) { + TileEntity var4 = this.getBlockTileEntity(par1, par2, par3); + + if (var4 != null && this.scanningTileEntities) { + var4.invalidate(); + this.addedTileEntityList.remove(var4); + } else { + if (var4 != null) { + this.addedTileEntityList.remove(var4); + this.loadedTileEntityList.remove(var4); + } + + Chunk var5 = this.getChunkFromChunkCoords(par1 >> 4, par3 >> 4); + + if (var5 != null) { + var5.removeChunkBlockTileEntity(par1 & 15, par2, par3 & 15); + } + } + } + + /** + * Adds TileEntity to despawn list + */ + public void markTileEntityForDespawn(TileEntity par1TileEntity) { + this.entityRemoval.add(par1TileEntity); + } + + /** + * Returns true if the block at the specified coordinates is an opaque cube. + * Args: x, y, z + */ + public boolean isBlockOpaqueCube(int par1, int par2, int par3) { + Block var4 = Block.blocksList[this.getBlockId(par1, par2, par3)]; + return var4 == null ? false : var4.isOpaqueCube(); + } + + /** + * Returns true if the block at the specified coordinates is an opaque cube. + * Args: x, y, z + */ + public boolean isBlockNormalCube(int par1, int par2, int par3) { + return Block.isNormalCube(this.getBlockId(par1, par2, par3)); + } + + public boolean func_85174_u(int par1, int par2, int par3) { + int var4 = this.getBlockId(par1, par2, par3); + + if (var4 != 0 && Block.blocksList[var4] != null) { + AxisAlignedBB var5 = Block.blocksList[var4].getCollisionBoundingBoxFromPool(this, par1, par2, par3); + return var5 != null && var5.getAverageEdgeLength() >= 1.0D; + } else { + return false; + } + } + + /** + * Returns true if the block at the given coordinate has a solid (buildable) top + * surface. + */ + public boolean doesBlockHaveSolidTopSurface(int par1, int par2, int par3) { + Block var4 = Block.blocksList[this.getBlockId(par1, par2, par3)]; + return this.isBlockTopFacingSurfaceSolid(var4, this.getBlockMetadata(par1, par2, par3)); + } + + /** + * Performs check to see if the block is a normal, solid block, or if the + * metadata of the block indicates that its facing puts its solid side upwards. + * (inverted stairs, for example) + */ + public boolean isBlockTopFacingSurfaceSolid(Block par1Block, int par2) { + return par1Block == null ? false + : (par1Block.blockMaterial.isOpaque() && par1Block.renderAsNormalBlock() ? true + : (par1Block instanceof BlockStairs ? (par2 & 4) == 4 + : (par1Block instanceof BlockHalfSlab ? (par2 & 8) == 8 + : (par1Block instanceof BlockHopper ? true + : (par1Block instanceof BlockSnow ? (par2 & 7) == 7 : false))))); + } + + /** + * Checks if the block is a solid, normal cube. If the chunk does not exist, or + * is not loaded, it returns the boolean parameter. + */ + public boolean isBlockNormalCubeDefault(int par1, int par2, int par3, boolean par4) { + if (par1 >= -30000000 && par3 >= -30000000 && par1 < 30000000 && par3 < 30000000) { + Chunk var5 = this.chunkProvider.provideChunk(par1 >> 4, par3 >> 4); + + if (var5 != null && !var5.isEmpty()) { + Block var6 = Block.blocksList[this.getBlockId(par1, par2, par3)]; + return var6 == null ? false : var6.blockMaterial.isOpaque() && var6.renderAsNormalBlock(); + } else { + return par4; + } + } else { + return par4; + } + } + + /** + * Called on construction of the World class to setup the initial skylight + * values + */ + public void calculateInitialSkylight() { + int var1 = this.calculateSkylightSubtracted(1.0F); + + if (var1 != this.skylightSubtracted) { + this.skylightSubtracted = var1; + } + } + + /** + * first boolean for hostile mobs and second for peaceful mobs + */ + public void setAllowedSpawnTypes(boolean par1, boolean par2) { + this.spawnHostileMobs = par1; + this.spawnPeacefulMobs = par2; + } + + /** + * Runs a single tick for the world + */ + public void tick() { + this.updateWeather(); + } + + /** + * Called from World constructor to set rainingStrength and thunderingStrength + */ + private void calculateInitialWeather() { + if (this.worldInfo.isRaining()) { + this.rainingStrength = 1.0F; + + if (this.worldInfo.isThundering()) { + this.thunderingStrength = 1.0F; + } + } + } + + /** + * Updates all weather states. + */ + protected void updateWeather() { + if (!this.provider.hasNoSky) { + int var1 = this.worldInfo.getThunderTime(); + + if (var1 <= 0) { + if (this.worldInfo.isThundering()) { + this.worldInfo.setThunderTime(this.rand.nextInt(12000) + 3600); + } else { + this.worldInfo.setThunderTime(this.rand.nextInt(168000) + 12000); + } + } else { + --var1; + this.worldInfo.setThunderTime(var1); + + if (var1 <= 0) { + this.worldInfo.setThundering(!this.worldInfo.isThundering()); + } + } + + int var2 = this.worldInfo.getRainTime(); + + if (var2 <= 0) { + if (this.worldInfo.isRaining()) { + this.worldInfo.setRainTime(this.rand.nextInt(12000) + 12000); + } else { + this.worldInfo.setRainTime(this.rand.nextInt(168000) + 12000); + } + } else { + --var2; + this.worldInfo.setRainTime(var2); + + if (var2 <= 0) { + this.worldInfo.setRaining(!this.worldInfo.isRaining()); + } + } + + this.prevRainingStrength = this.rainingStrength; + + if (this.worldInfo.isRaining()) { + this.rainingStrength = (float) ((double) this.rainingStrength + 0.01D); + } else { + this.rainingStrength = (float) ((double) this.rainingStrength - 0.01D); + } + + if (this.rainingStrength < 0.0F) { + this.rainingStrength = 0.0F; + } + + if (this.rainingStrength > 1.0F) { + this.rainingStrength = 1.0F; + } + + this.prevThunderingStrength = this.thunderingStrength; + + if (this.worldInfo.isThundering()) { + this.thunderingStrength = (float) ((double) this.thunderingStrength + 0.01D); + } else { + this.thunderingStrength = (float) ((double) this.thunderingStrength - 0.01D); + } + + if (this.thunderingStrength < 0.0F) { + this.thunderingStrength = 0.0F; + } + + if (this.thunderingStrength > 1.0F) { + this.thunderingStrength = 1.0F; + } + } + } + + /** + * start precipitation in this world (2 ticks after command posted) + */ + public void commandToggleDownfall() { + this.worldInfo.setRainTime(1); + } + + protected void setActivePlayerChunksAndCheckLight() { + this.activeChunkSet.clear(); + this.theProfiler.startSection("buildList"); + int var1; + EntityPlayer var2; + int var3; + int var4; + + for (var1 = 0; var1 < this.playerEntities.size(); ++var1) { + var2 = (EntityPlayer) this.playerEntities.get(var1); + var3 = MathHelper.floor_double(var2.posX / 16.0D); + var4 = MathHelper.floor_double(var2.posZ / 16.0D); + byte var5 = 7; + + for (int var6 = -var5; var6 <= var5; ++var6) { + for (int var7 = -var5; var7 <= var5; ++var7) { + this.activeChunkSet.add(new ChunkCoordIntPair(var6 + var3, var7 + var4)); + } + } + } + + this.theProfiler.endSection(); + + if (this.ambientTickCountdown > 0) { + --this.ambientTickCountdown; + } + + this.theProfiler.startSection("playerCheckLight"); + + if (!this.playerEntities.isEmpty()) { + var1 = this.rand.nextInt(this.playerEntities.size()); + var2 = (EntityPlayer) this.playerEntities.get(var1); + var3 = MathHelper.floor_double(var2.posX) + this.rand.nextInt(11) - 5; + var4 = MathHelper.floor_double(var2.posY) + this.rand.nextInt(11) - 5; + int var8 = MathHelper.floor_double(var2.posZ) + this.rand.nextInt(11) - 5; + this.updateAllLightTypes(var3, var4, var8); + } + + this.theProfiler.endSection(); + } + + protected void moodSoundAndLightCheck(int par1, int par2, Chunk par3Chunk) { + this.theProfiler.endStartSection("moodSound"); + + if (this.ambientTickCountdown == 0 && !this.isRemote) { + this.updateLCG = this.updateLCG * 3 + 1013904223; + int var4 = this.updateLCG >> 2; + int var5 = var4 & 15; + int var6 = var4 >> 8 & 15; + int var7 = var4 >> 16 & 127; + int var8 = par3Chunk.getBlockID(var5, var7, var6); + var5 += par1; + var6 += par2; + + if (var8 == 0 && this.getFullBlockLightValue(var5, var7, var6) <= this.rand.nextInt(8) + && this.getSavedLightValue(EnumSkyBlock.Sky, var5, var7, var6) <= 0) { + EntityPlayer var9 = this.getClosestPlayer((double) var5 + 0.5D, (double) var7 + 0.5D, + (double) var6 + 0.5D, 8.0D); + + if (var9 != null && var9.getDistanceSq((double) var5 + 0.5D, (double) var7 + 0.5D, + (double) var6 + 0.5D) > 4.0D) { + this.playSoundEffect((double) var5 + 0.5D, (double) var7 + 0.5D, (double) var6 + 0.5D, + "ambient.cave.cave", 0.7F, 0.8F + this.rand.nextFloat() * 0.2F); + this.ambientTickCountdown = this.rand.nextInt(12000) + 6000; + } + } + } + + this.theProfiler.endStartSection("checkLight"); + par3Chunk.enqueueRelightChecks(); + } + + /** + * plays random cave ambient sounds and runs updateTick on random blocks within + * each chunk in the vacinity of a player + */ + protected void tickBlocksAndAmbiance() { + this.setActivePlayerChunksAndCheckLight(); + } + + /** + * checks to see if a given block is both water and is cold enough to freeze + */ + public boolean isBlockFreezable(int par1, int par2, int par3) { + return this.canBlockFreeze(par1, par2, par3, false); + } + + /** + * checks to see if a given block is both water and has at least one immediately + * adjacent non-water block + */ + public boolean isBlockFreezableNaturally(int par1, int par2, int par3) { + return this.canBlockFreeze(par1, par2, par3, true); + } + + /** + * checks to see if a given block is both water, and cold enough to freeze - if + * the par4 boolean is set, this will only return true if there is a non-water + * block immediately adjacent to the specified block + */ + public boolean canBlockFreeze(int par1, int par2, int par3, boolean par4) { + BiomeGenBase var5 = this.getBiomeGenForCoords(par1, par3); + float var6 = var5.getFloatTemperature(); + + if (var6 > 0.15F) { + return false; + } else { + if (par2 >= 0 && par2 < 256 && this.getSavedLightValue(EnumSkyBlock.Block, par1, par2, par3) < 10) { + int var7 = this.getBlockId(par1, par2, par3); + + if ((var7 == Block.waterStill.blockID || var7 == Block.waterMoving.blockID) + && this.getBlockMetadata(par1, par2, par3) == 0) { + if (!par4) { + return true; + } + + boolean var8 = true; + + if (var8 && this.getBlockMaterial(par1 - 1, par2, par3) != Material.water) { + var8 = false; + } + + if (var8 && this.getBlockMaterial(par1 + 1, par2, par3) != Material.water) { + var8 = false; + } + + if (var8 && this.getBlockMaterial(par1, par2, par3 - 1) != Material.water) { + var8 = false; + } + + if (var8 && this.getBlockMaterial(par1, par2, par3 + 1) != Material.water) { + var8 = false; + } + + if (!var8) { + return true; + } + } + } + + return false; + } + } + + /** + * Tests whether or not snow can be placed at a given location + */ + public boolean canSnowAt(int par1, int par2, int par3) { + BiomeGenBase var4 = this.getBiomeGenForCoords(par1, par3); + float var5 = var4.getFloatTemperature(); + + if (var5 > 0.15F) { + return false; + } else { + if (par2 >= 0 && par2 < 256 && this.getSavedLightValue(EnumSkyBlock.Block, par1, par2, par3) < 10) { + int var6 = this.getBlockId(par1, par2 - 1, par3); + int var7 = this.getBlockId(par1, par2, par3); + + if (var7 == 0 && Block.snow.canPlaceBlockAt(this, par1, par2, par3) && var6 != 0 + && var6 != Block.ice.blockID && Block.blocksList[var6].blockMaterial.blocksMovement()) { + return true; + } + } + + return false; + } + } + + public void updateAllLightTypes(int par1, int par2, int par3) { + if (!this.provider.hasNoSky) { + this.updateLightByType(EnumSkyBlock.Sky, par1, par2, par3); + } + + this.updateLightByType(EnumSkyBlock.Block, par1, par2, par3); + } + + private int computeLightValue(int par1, int par2, int par3, EnumSkyBlock par4EnumSkyBlock) { + if (par4EnumSkyBlock == EnumSkyBlock.Sky && this.canBlockSeeTheSky(par1, par2, par3)) { + return 15; + } else { + int var5 = this.getBlockId(par1, par2, par3); + int var6 = par4EnumSkyBlock == EnumSkyBlock.Sky ? 0 : Block.lightValue[var5]; + int var7 = Block.lightOpacity[var5]; + + if (var7 >= 15 && Block.lightValue[var5] > 0) { + var7 = 1; + } + + if (var7 < 1) { + var7 = 1; + } + + if (var7 >= 15) { + return 0; + } else if (var6 >= 14) { + return var6; + } else { + for (int var8 = 0; var8 < 6; ++var8) { + int var9 = par1 + Facing.offsetsXForSide[var8]; + int var10 = par2 + Facing.offsetsYForSide[var8]; + int var11 = par3 + Facing.offsetsZForSide[var8]; + int var12 = this.getSavedLightValue(par4EnumSkyBlock, var9, var10, var11) - var7; + + if (var12 > var6) { + var6 = var12; + } + + if (var6 >= 14) { + return var6; + } + } + + return var6; + } + } + } + + public void updateLightByType(EnumSkyBlock par1EnumSkyBlock, int par2, int par3, int par4) { + if (this.doChunksNearChunkExist(par2, par3, par4, 17)) { + int var5 = 0; + int var6 = 0; + this.theProfiler.startSection("getBrightness"); + int var7 = this.getSavedLightValue(par1EnumSkyBlock, par2, par3, par4); + int var8 = this.computeLightValue(par2, par3, par4, par1EnumSkyBlock); + int var9; + int var10; + int var11; + int var12; + int var13; + int var14; + int var15; + int var16; + int var17; + + if (var8 > var7) { + this.lightUpdateBlockList[var6++] = 133152; + } else if (var8 < var7) { + this.lightUpdateBlockList[var6++] = 133152 | var7 << 18; + + while (var5 < var6) { + var9 = this.lightUpdateBlockList[var5++]; + var10 = (var9 & 63) - 32 + par2; + var11 = (var9 >> 6 & 63) - 32 + par3; + var12 = (var9 >> 12 & 63) - 32 + par4; + var13 = var9 >> 18 & 15; + var14 = this.getSavedLightValue(par1EnumSkyBlock, var10, var11, var12); + + if (var14 == var13) { + this.setLightValue(par1EnumSkyBlock, var10, var11, var12, 0); + + if (var13 > 0) { + var15 = MathHelper.abs_int(var10 - par2); + var16 = MathHelper.abs_int(var11 - par3); + var17 = MathHelper.abs_int(var12 - par4); + + if (var15 + var16 + var17 < 17) { + for (int var18 = 0; var18 < 6; ++var18) { + int var19 = var10 + Facing.offsetsXForSide[var18]; + int var20 = var11 + Facing.offsetsYForSide[var18]; + int var21 = var12 + Facing.offsetsZForSide[var18]; + int var22 = Math.max(1, Block.lightOpacity[this.getBlockId(var19, var20, var21)]); + var14 = this.getSavedLightValue(par1EnumSkyBlock, var19, var20, var21); + + if (var14 == var13 - var22 && var6 < this.lightUpdateBlockList.length) { + this.lightUpdateBlockList[var6++] = var19 - par2 + 32 | var20 - par3 + 32 << 6 + | var21 - par4 + 32 << 12 | var13 - var22 << 18; + } + } + } + } + } + } + + var5 = 0; + } + + this.theProfiler.endSection(); + this.theProfiler.startSection("checkedPosition < toCheckCount"); + + while (var5 < var6) { + var9 = this.lightUpdateBlockList[var5++]; + var10 = (var9 & 63) - 32 + par2; + var11 = (var9 >> 6 & 63) - 32 + par3; + var12 = (var9 >> 12 & 63) - 32 + par4; + var13 = this.getSavedLightValue(par1EnumSkyBlock, var10, var11, var12); + var14 = this.computeLightValue(var10, var11, var12, par1EnumSkyBlock); + + if (var14 != var13) { + this.setLightValue(par1EnumSkyBlock, var10, var11, var12, var14); + + if (var14 > var13) { + var15 = Math.abs(var10 - par2); + var16 = Math.abs(var11 - par3); + var17 = Math.abs(var12 - par4); + boolean var23 = var6 < this.lightUpdateBlockList.length - 6; + + if (var15 + var16 + var17 < 17 && var23) { + if (this.getSavedLightValue(par1EnumSkyBlock, var10 - 1, var11, var12) < var14) { + this.lightUpdateBlockList[var6++] = var10 - 1 - par2 + 32 + (var11 - par3 + 32 << 6) + + (var12 - par4 + 32 << 12); + } + + if (this.getSavedLightValue(par1EnumSkyBlock, var10 + 1, var11, var12) < var14) { + this.lightUpdateBlockList[var6++] = var10 + 1 - par2 + 32 + (var11 - par3 + 32 << 6) + + (var12 - par4 + 32 << 12); + } + + if (this.getSavedLightValue(par1EnumSkyBlock, var10, var11 - 1, var12) < var14) { + this.lightUpdateBlockList[var6++] = var10 - par2 + 32 + (var11 - 1 - par3 + 32 << 6) + + (var12 - par4 + 32 << 12); + } + + if (this.getSavedLightValue(par1EnumSkyBlock, var10, var11 + 1, var12) < var14) { + this.lightUpdateBlockList[var6++] = var10 - par2 + 32 + (var11 + 1 - par3 + 32 << 6) + + (var12 - par4 + 32 << 12); + } + + if (this.getSavedLightValue(par1EnumSkyBlock, var10, var11, var12 - 1) < var14) { + this.lightUpdateBlockList[var6++] = var10 - par2 + 32 + (var11 - par3 + 32 << 6) + + (var12 - 1 - par4 + 32 << 12); + } + + if (this.getSavedLightValue(par1EnumSkyBlock, var10, var11, var12 + 1) < var14) { + this.lightUpdateBlockList[var6++] = var10 - par2 + 32 + (var11 - par3 + 32 << 6) + + (var12 + 1 - par4 + 32 << 12); + } + } + } + } + } + + this.theProfiler.endSection(); + } + } + + /** + * Runs through the list of updates to run and ticks them + */ + public boolean tickUpdates(boolean par1) { + return false; + } + + public List getPendingBlockUpdates(Chunk par1Chunk, boolean par2) { + return null; + } + + /** + * Will get all entities within the specified AABB excluding the one passed into + * it. Args: entityToExclude, aabb + */ + public List getEntitiesWithinAABBExcludingEntity(Entity par1Entity, AxisAlignedBB par2AxisAlignedBB) { + return this.getEntitiesWithinAABBExcludingEntity(par1Entity, par2AxisAlignedBB, (IEntitySelector) null); + } + + public List getEntitiesWithinAABBExcludingEntity(Entity par1Entity, AxisAlignedBB par2AxisAlignedBB, + IEntitySelector par3IEntitySelector) { + ArrayList var4 = new ArrayList(); + int var5 = MathHelper.floor_double((par2AxisAlignedBB.minX - 2.0D) / 16.0D); + int var6 = MathHelper.floor_double((par2AxisAlignedBB.maxX + 2.0D) / 16.0D); + int var7 = MathHelper.floor_double((par2AxisAlignedBB.minZ - 2.0D) / 16.0D); + int var8 = MathHelper.floor_double((par2AxisAlignedBB.maxZ + 2.0D) / 16.0D); + + for (int var9 = var5; var9 <= var6; ++var9) { + for (int var10 = var7; var10 <= var8; ++var10) { + if (this.chunkExists(var9, var10)) { + this.getChunkFromChunkCoords(var9, var10).getEntitiesWithinAABBForEntity(par1Entity, + par2AxisAlignedBB, var4, par3IEntitySelector); + } + } + } + + return var4; + } + + /** + * Returns all entities of the specified class type which intersect with the + * AABB. Args: entityClass, aabb + */ + public List getEntitiesWithinAABB(Class par1Class, AxisAlignedBB par2AxisAlignedBB) { + return this.selectEntitiesWithinAABB(par1Class, par2AxisAlignedBB, (IEntitySelector) null); + } + + public List selectEntitiesWithinAABB(Class par1Class, AxisAlignedBB par2AxisAlignedBB, + IEntitySelector par3IEntitySelector) { + int var4 = MathHelper.floor_double((par2AxisAlignedBB.minX - 2.0D) / 16.0D); + int var5 = MathHelper.floor_double((par2AxisAlignedBB.maxX + 2.0D) / 16.0D); + int var6 = MathHelper.floor_double((par2AxisAlignedBB.minZ - 2.0D) / 16.0D); + int var7 = MathHelper.floor_double((par2AxisAlignedBB.maxZ + 2.0D) / 16.0D); + ArrayList var8 = new ArrayList(); + + for (int var9 = var4; var9 <= var5; ++var9) { + for (int var10 = var6; var10 <= var7; ++var10) { + if (this.chunkExists(var9, var10)) { + this.getChunkFromChunkCoords(var9, var10).getEntitiesOfTypeWithinAAAB(par1Class, par2AxisAlignedBB, + var8, par3IEntitySelector); + } + } + } + + return var8; + } + + public Entity findNearestEntityWithinAABB(Class par1Class, AxisAlignedBB par2AxisAlignedBB, Entity par3Entity) { + List var4 = this.getEntitiesWithinAABB(par1Class, par2AxisAlignedBB); + Entity var5 = null; + double var6 = Double.MAX_VALUE; + + for (int var8 = 0; var8 < var4.size(); ++var8) { + Entity var9 = (Entity) var4.get(var8); + + if (var9 != par3Entity) { + double var10 = par3Entity.getDistanceSqToEntity(var9); + + if (var10 <= var6) { + var5 = var9; + var6 = var10; + } + } + } + + return var5; + } + + /** + * Returns the Entity with the given ID, or null if it doesn't exist in this + * World. + */ + public abstract Entity getEntityByID(int var1); + + /** + * marks the chunk that contains this tilentity as modified and then calls + * worldAccesses.doNothingWithTileEntity + */ + public void updateTileEntityChunkAndDoNothing(int par1, int par2, int par3, TileEntity par4TileEntity) { + if (this.blockExists(par1, par2, par3)) { + this.getChunkFromBlockCoords(par1, par3).setChunkModified(); + } + } + + /** + * Counts how many entities of an entity class exist in the world. Args: + * entityClass + */ + public int countEntities(Class par1Class) { + int var2 = 0; + + for (int var3 = 0; var3 < this.loadedEntityList.size(); ++var3) { + Entity var4 = (Entity) this.loadedEntityList.get(var3); + + if ((!(var4 instanceof EntityLiving) || !((EntityLiving) var4).func_104002_bU()) + && par1Class.isAssignableFrom(var4.getClass())) { + ++var2; + } + } + + return var2; + } + + /** + * adds entities to the loaded entities list, and loads thier skins. + */ + public void addLoadedEntities(List par1List) { + this.loadedEntityList.addAll(par1List); + + for (int var2 = 0; var2 < par1List.size(); ++var2) { + this.obtainEntitySkin((Entity) par1List.get(var2)); + } + } + + /** + * adds entities to the list of unloaded entities + */ + public void unloadEntities(List par1List) { + this.unloadedEntityList.addAll(par1List); + } + + /** + * Returns true if the given Entity can be placed on the given side of the given + * block position. + */ + public boolean canPlaceEntityOnSide(int par1, int par2, int par3, int par4, boolean par5, int par6, + Entity par7Entity, ItemStack par8ItemStack) { + int var9 = this.getBlockId(par2, par3, par4); + Block var10 = Block.blocksList[var9]; + Block var11 = Block.blocksList[par1]; + AxisAlignedBB var12 = var11.getCollisionBoundingBoxFromPool(this, par2, par3, par4); + + if (par5) { + var12 = null; + } + + if (var12 != null && !this.checkNoEntityCollision(var12, par7Entity)) { + return false; + } else { + if (var10 != null && (var10 == Block.waterMoving || var10 == Block.waterStill || var10 == Block.lavaMoving + || var10 == Block.lavaStill || var10 == Block.fire || var10.blockMaterial.isReplaceable())) { + var10 = null; + } + + return var10 != null && var10.blockMaterial == Material.circuits && var11 == Block.anvil ? true + : par1 > 0 && var10 == null + && var11.canPlaceBlockOnSide(this, par2, par3, par4, par6, par8ItemStack); + } + } + + public PathEntity getPathEntityToEntity(Entity par1Entity, Entity par2Entity, float par3, boolean par4, + boolean par5, boolean par6, boolean par7) { + this.theProfiler.startSection("pathfind"); + int var8 = MathHelper.floor_double(par1Entity.posX); + int var9 = MathHelper.floor_double(par1Entity.posY + 1.0D); + int var10 = MathHelper.floor_double(par1Entity.posZ); + int var11 = (int) (par3 + 16.0F); + int var12 = var8 - var11; + int var13 = var9 - var11; + int var14 = var10 - var11; + int var15 = var8 + var11; + int var16 = var9 + var11; + int var17 = var10 + var11; + ChunkCache var18 = new ChunkCache(this, var12, var13, var14, var15, var16, var17, 0); + PathEntity var19 = (new PathFinder(var18, par4, par5, par6, par7)).createEntityPathTo(par1Entity, par2Entity, + par3); + this.theProfiler.endSection(); + return var19; + } + + public PathEntity getEntityPathToXYZ(Entity par1Entity, int par2, int par3, int par4, float par5, boolean par6, + boolean par7, boolean par8, boolean par9) { + this.theProfiler.startSection("pathfind"); + int var10 = MathHelper.floor_double(par1Entity.posX); + int var11 = MathHelper.floor_double(par1Entity.posY); + int var12 = MathHelper.floor_double(par1Entity.posZ); + int var13 = (int) (par5 + 8.0F); + int var14 = var10 - var13; + int var15 = var11 - var13; + int var16 = var12 - var13; + int var17 = var10 + var13; + int var18 = var11 + var13; + int var19 = var12 + var13; + ChunkCache var20 = new ChunkCache(this, var14, var15, var16, var17, var18, var19, 0); + PathEntity var21 = (new PathFinder(var20, par6, par7, par8, par9)).createEntityPathTo(par1Entity, par2, par3, + par4, par5); + this.theProfiler.endSection(); + return var21; + } + + /** + * Is this block powering in the specified direction Args: x, y, z, direction + */ + public int isBlockProvidingPowerTo(int par1, int par2, int par3, int par4) { + int var5 = this.getBlockId(par1, par2, par3); + return var5 == 0 ? 0 : Block.blocksList[var5].isProvidingStrongPower(this, par1, par2, par3, par4); + } + + /** + * Returns the highest redstone signal strength powering the given block. Args: + * X, Y, Z. + */ + public int getBlockPowerInput(int par1, int par2, int par3) { + byte var4 = 0; + int var5 = Math.max(var4, this.isBlockProvidingPowerTo(par1, par2 - 1, par3, 0)); + + if (var5 >= 15) { + return var5; + } else { + var5 = Math.max(var5, this.isBlockProvidingPowerTo(par1, par2 + 1, par3, 1)); + + if (var5 >= 15) { + return var5; + } else { + var5 = Math.max(var5, this.isBlockProvidingPowerTo(par1, par2, par3 - 1, 2)); + + if (var5 >= 15) { + return var5; + } else { + var5 = Math.max(var5, this.isBlockProvidingPowerTo(par1, par2, par3 + 1, 3)); + + if (var5 >= 15) { + return var5; + } else { + var5 = Math.max(var5, this.isBlockProvidingPowerTo(par1 - 1, par2, par3, 4)); + + if (var5 >= 15) { + return var5; + } else { + var5 = Math.max(var5, this.isBlockProvidingPowerTo(par1 + 1, par2, par3, 5)); + return var5 >= 15 ? var5 : var5; + } + } + } + } + } + } + + /** + * Returns the indirect signal strength being outputted by the given block in + * the *opposite* of the given direction. Args: X, Y, Z, direction + */ + public boolean getIndirectPowerOutput(int par1, int par2, int par3, int par4) { + return this.getIndirectPowerLevelTo(par1, par2, par3, par4) > 0; + } + + /** + * Gets the power level from a certain block face. Args: x, y, z, direction + */ + public int getIndirectPowerLevelTo(int par1, int par2, int par3, int par4) { + if (this.isBlockNormalCube(par1, par2, par3)) { + return this.getBlockPowerInput(par1, par2, par3); + } else { + int var5 = this.getBlockId(par1, par2, par3); + return var5 == 0 ? 0 : Block.blocksList[var5].isProvidingWeakPower(this, par1, par2, par3, par4); + } + } + + /** + * Used to see if one of the blocks next to you or your block is getting power + * from a neighboring block. Used by items like TNT or Doors so they don't have + * redstone going straight into them. Args: x, y, z + */ + public boolean isBlockIndirectlyGettingPowered(int par1, int par2, int par3) { + return this.getIndirectPowerLevelTo(par1, par2 - 1, par3, 0) > 0 ? true + : (this.getIndirectPowerLevelTo(par1, par2 + 1, par3, 1) > 0 ? true + : (this.getIndirectPowerLevelTo(par1, par2, par3 - 1, 2) > 0 ? true + : (this.getIndirectPowerLevelTo(par1, par2, par3 + 1, 3) > 0 ? true + : (this.getIndirectPowerLevelTo(par1 - 1, par2, par3, 4) > 0 ? true + : this.getIndirectPowerLevelTo(par1 + 1, par2, par3, 5) > 0)))); + } + + public int getStrongestIndirectPower(int par1, int par2, int par3) { + int var4 = 0; + + for (int var5 = 0; var5 < 6; ++var5) { + int var6 = this.getIndirectPowerLevelTo(par1 + Facing.offsetsXForSide[var5], + par2 + Facing.offsetsYForSide[var5], par3 + Facing.offsetsZForSide[var5], var5); + + if (var6 >= 15) { + return 15; + } + + if (var6 > var4) { + var4 = var6; + } + } + + return var4; + } + + /** + * Gets the closest player to the entity within the specified distance (if + * distance is less than 0 then ignored). Args: entity, dist + */ + public EntityPlayer getClosestPlayerToEntity(Entity par1Entity, double par2) { + return this.getClosestPlayer(par1Entity.posX, par1Entity.posY, par1Entity.posZ, par2); + } + + /** + * Gets the closest player to the point within the specified distance (distance + * can be set to less than 0 to not limit the distance). Args: x, y, z, dist + */ + public EntityPlayer getClosestPlayer(double par1, double par3, double par5, double par7) { + double var9 = -1.0D; + EntityPlayer var11 = null; + + for (int var12 = 0; var12 < this.playerEntities.size(); ++var12) { + EntityPlayer var13 = (EntityPlayer) this.playerEntities.get(var12); + double var14 = var13.getDistanceSq(par1, par3, par5); + + if ((par7 < 0.0D || var14 < par7 * par7) && (var9 == -1.0D || var14 < var9)) { + var9 = var14; + var11 = var13; + } + } + + return var11; + } + + /** + * Returns the closest vulnerable player to this entity within the given radius, + * or null if none is found + */ + public EntityPlayer getClosestVulnerablePlayerToEntity(Entity par1Entity, double par2) { + return this.getClosestVulnerablePlayer(par1Entity.posX, par1Entity.posY, par1Entity.posZ, par2); + } + + /** + * Returns the closest vulnerable player within the given radius, or null if + * none is found. + */ + public EntityPlayer getClosestVulnerablePlayer(double par1, double par3, double par5, double par7) { + double var9 = -1.0D; + EntityPlayer var11 = null; + + for (int var12 = 0; var12 < this.playerEntities.size(); ++var12) { + EntityPlayer var13 = (EntityPlayer) this.playerEntities.get(var12); + + if (!var13.capabilities.disableDamage && var13.isEntityAlive()) { + double var14 = var13.getDistanceSq(par1, par3, par5); + double var16 = par7; + + if (var13.isSneaking()) { + var16 = par7 * 0.800000011920929D; + } + + if (var13.isInvisible()) { + float var18 = var13.func_82243_bO(); + + if (var18 < 0.1F) { + var18 = 0.1F; + } + + var16 *= (double) (0.7F * var18); + } + + if ((par7 < 0.0D || var14 < var16 * var16) && (var9 == -1.0D || var14 < var9)) { + var9 = var14; + var11 = var13; + } + } + } + + return var11; + } + + /** + * Find a player by name in this world. + */ + public EntityPlayer getPlayerEntityByName(String par1Str) { + for (int var2 = 0; var2 < this.playerEntities.size(); ++var2) { + if (par1Str.equals(((EntityPlayer) this.playerEntities.get(var2)).username)) { + return (EntityPlayer) this.playerEntities.get(var2); + } + } + + return null; + } + + /** + * Checks whether the session lock file was modified by another process + */ + public void checkSessionLock() throws MinecraftException { + this.saveHandler.checkSessionLock(); + } + + /** + * gets the random world seed + */ + public long getSeed() { + return this.worldInfo.getSeed(); + } + + public long getTotalWorldTime() { + return this.worldInfo.getWorldTotalTime(); + } + + public long getWorldTime() { + return this.worldInfo.getWorldTime(); + } + + /** + * Sets the world time. + */ + public void setWorldTime(long par1) { + this.worldInfo.setWorldTime(par1); + } + + /** + * Returns the coordinates of the spawn point + */ + public ChunkCoordinates getSpawnPoint() { + return new ChunkCoordinates(this.worldInfo.getSpawnX(), this.worldInfo.getSpawnY(), this.worldInfo.getSpawnZ()); + } + + /** + * Called when checking if a certain block can be mined or not. The 'spawn safe + * zone' check is located here. + */ + public boolean canMineBlock(EntityPlayer par1EntityPlayer, int par2, int par3, int par4) { + return true; + } + + /** + * sends a Packet 38 (Entity Status) to all tracked players of that entity + */ + public void setEntityState(Entity par1Entity, byte par2) { + } + + /** + * gets the world's chunk provider + */ + public IChunkProvider getChunkProvider() { + return this.chunkProvider; + } + + /** + * Adds a block event with the given Args to the blockEventCache. During the + * next tick(), the block specified will have its onBlockEvent handler called + * with the given parameters. Args: X,Y,Z, BlockID, EventID, EventParameter + */ + public void addBlockEvent(int par1, int par2, int par3, int par4, int par5, int par6) { + if (par4 > 0) { + Block.blocksList[par4].onBlockEventReceived(this, par1, par2, par3, par5, par6); + } + } + + /** + * Returns this world's current save handler + */ + public ISaveHandler getSaveHandler() { + return this.saveHandler; + } + + /** + * Returns the world's WorldInfo object + */ + public WorldInfo getWorldInfo() { + return this.worldInfo; + } + + /** + * Gets the GameRules instance. + */ + public GameRules getGameRules() { + return this.worldInfo.getGameRulesInstance(); + } + + /** + * Updates the flag that indicates whether or not all players in the world are + * sleeping. + */ + public void updateAllPlayersSleepingFlag() { + } + + public float getWeightedThunderStrength(float par1) { + return (this.prevThunderingStrength + (this.thunderingStrength - this.prevThunderingStrength) * par1) + * this.getRainStrength(par1); + } + + /** + * Not sure about this actually. Reverting this one myself. + */ + public float getRainStrength(float par1) { + return this.prevRainingStrength + (this.rainingStrength - this.prevRainingStrength) * par1; + } + + /** + * Returns true if the current thunder strength (weighted with the rain + * strength) is greater than 0.9 + */ + public boolean isThundering() { + return (double) this.getWeightedThunderStrength(1.0F) > 0.9D; + } + + /** + * Returns true if the current rain strength is greater than 0.2 + */ + public boolean isRaining() { + return (double) this.getRainStrength(1.0F) > 0.2D; + } + + public boolean canLightningStrikeAt(int par1, int par2, int par3) { + if (!this.isRaining()) { + return false; + } else if (!this.canBlockSeeTheSky(par1, par2, par3)) { + return false; + } else if (this.getPrecipitationHeight(par1, par3) > par2) { + return false; + } else { + BiomeGenBase var4 = this.getBiomeGenForCoords(par1, par3); + return var4.getEnableSnow() ? false : var4.canSpawnLightningBolt(); + } + } + + /** + * Checks to see if the biome rainfall values for a given x,y,z coordinate set + * are extremely high + */ + public boolean isBlockHighHumidity(int par1, int par2, int par3) { + BiomeGenBase var4 = this.getBiomeGenForCoords(par1, par3); + return var4.isHighHumidity(); + } + + /** + * Assigns the given String id to the given MapDataBase using the MapStorage, + * removing any existing ones of the same id. + */ + public void setItemData(String par1Str, WorldSavedData par2WorldSavedData) { + this.mapStorage.setData(par1Str, par2WorldSavedData); + } + + /** + * Loads an existing MapDataBase corresponding to the given String id from disk + * using the MapStorage, instantiating the given Class, or returns null if none + * such file exists. args: Class to instantiate, String dataid + */ + public WorldSavedData loadItemData(Class par1Class, String par2Str) { + return this.mapStorage.loadData(par1Class, par2Str); + } + + /** + * Returns an unique new data id from the MapStorage for the given prefix and + * saves the idCounts map to the 'idcounts' file. + */ + public int getUniqueDataId(String par1Str) { + return this.mapStorage.getUniqueDataId(par1Str); + } + + public void func_82739_e(int par1, int par2, int par3, int par4, int par5) { + for (int var6 = 0; var6 < this.worldAccesses.size(); ++var6) { + ((IWorldAccess) this.worldAccesses.get(var6)).broadcastSound(par1, par2, par3, par4, par5); + } + } + + /** + * Plays a sound or particle effect. Parameters: Effect ID, X, Y, Z, Data. For a + * list of ids and data, see http://wiki.vg/Protocol#Effects + */ + public void playAuxSFX(int par1, int par2, int par3, int par4, int par5) { + this.playAuxSFXAtEntity((EntityPlayer) null, par1, par2, par3, par4, par5); + } + + /** + * See description for playAuxSFX. + */ + public void playAuxSFXAtEntity(EntityPlayer par1EntityPlayer, int par2, int par3, int par4, int par5, int par6) { + try { + for (int var7 = 0; var7 < this.worldAccesses.size(); ++var7) { + ((IWorldAccess) this.worldAccesses.get(var7)).playAuxSFX(par1EntityPlayer, par2, par3, par4, par5, + par6); + } + } catch (Throwable var10) { + CrashReport var8 = CrashReport.makeCrashReport(var10, "Playing level event"); + CrashReportCategory var9 = var8.makeCategory("Level event being played"); + var9.addCrashSection("Block coordinates", CrashReportCategory.getLocationInfo(par3, par4, par5)); + var9.addCrashSection("Event source", par1EntityPlayer); + var9.addCrashSection("Event type", Integer.valueOf(par2)); + var9.addCrashSection("Event data", Integer.valueOf(par6)); + throw new ReportedException(var8); + } + } + + /** + * Returns maximum world height. + */ + public int getHeight() { + return 256; + } + + /** + * Returns current world height. + */ + public int getActualHeight() { + return this.provider.hasNoSky ? 128 : 256; + } + + public IUpdatePlayerListBox func_82735_a(EntityMinecart par1EntityMinecart) { + return null; + } + + /** + * puts the World Random seed to a specific state dependant on the inputs + */ + public Random setRandomSeed(int par1, int par2, int par3) { + long var4 = (long) par1 * 341873128712L + (long) par2 * 132897987541L + this.getWorldInfo().getSeed() + + (long) par3; + this.rand.setSeed(var4); + return this.rand; + } + + /** + * Returns the location of the closest structure of the specified type. If not + * found returns null. + */ + public ChunkPosition findClosestStructure(String par1Str, int par2, int par3, int par4) { + return this.getChunkProvider().findClosestStructure(this, par1Str, par2, par3, par4); + } + + /** + * Adds some basic stats of the world to the given crash report. + */ + public CrashReportCategory addWorldInfoToCrashReport(CrashReport par1CrashReport) { + CrashReportCategory var2 = par1CrashReport.makeCategoryDepth("Affected level", 1); + var2.addCrashSection("Level name", this.worldInfo == null ? "????" : this.worldInfo.getWorldName()); + var2.addCrashSectionCallable("All players", new CallableLvl2(this)); + var2.addCrashSectionCallable("Chunk stats", new CallableLvl3(this)); + + try { + this.worldInfo.addToCrashReport(var2); + } catch (Throwable var4) { + var2.addCrashSectionThrowable("Level Data Unobtainable", var4); + } + + return var2; + } + + /** + * Starts (or continues) destroying a block with given ID at the given + * coordinates for the given partially destroyed value + */ + public void destroyBlockInWorldPartially(int par1, int par2, int par3, int par4, int par5) { + for (int var6 = 0; var6 < this.worldAccesses.size(); ++var6) { + IWorldAccess var7 = (IWorldAccess) this.worldAccesses.get(var6); + var7.destroyBlockPartially(par1, par2, par3, par4, par5); + } + } + + /** + * Return the Vec3Pool object for this world. + */ + public Vec3Pool getWorldVec3Pool() { + return this.vecPool; + } + + /** + * returns a calendar object containing the current date + */ + public Calendar getCurrentDate() { + if (this.getTotalWorldTime() % 600L == 0L) { + this.theCalendar.setTimeInMillis(System.currentTimeMillis()); + } + + return this.theCalendar; + } + + public Scoreboard getScoreboard() { + return this.worldScoreboard; + } + + public void func_96440_m(int par1, int par2, int par3, int par4) { + for (int var5 = 0; var5 < 4; ++var5) { + int var6 = par1 + Direction.offsetX[var5]; + int var7 = par3 + Direction.offsetZ[var5]; + int var8 = this.getBlockId(var6, par2, var7); + + if (var8 != 0) { + Block var9 = Block.blocksList[var8]; + + if (Block.redstoneComparatorIdle.func_94487_f(var8)) { + var9.onNeighborBlockChange(this, var6, par2, var7, par4); + } else if (Block.isNormalCube(var8)) { + var6 += Direction.offsetX[var5]; + var7 += Direction.offsetZ[var5]; + var8 = this.getBlockId(var6, par2, var7); + var9 = Block.blocksList[var8]; + + if (Block.redstoneComparatorIdle.func_94487_f(var8)) { + var9.onNeighborBlockChange(this, var6, par2, var7, par4); + } + } + } + } + } + + public ILogAgent getWorldLogAgent() { + return this.worldLogAgent; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/WorldChunkManager.java b/sp-server/src/main/java/net/minecraft/src/WorldChunkManager.java new file mode 100644 index 0000000..223000e --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/WorldChunkManager.java @@ -0,0 +1,225 @@ +package net.minecraft.src; + +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +public class WorldChunkManager { + private GenLayer genBiomes; + + /** A GenLayer containing the indices into BiomeGenBase.biomeList[] */ + private GenLayer biomeIndexLayer; + + /** The biome list. */ + private BiomeCache biomeCache; + + /** A list of biomes that the player can spawn in. */ + private List biomesToSpawnIn; + + protected WorldChunkManager() { + this.biomeCache = new BiomeCache(this); + this.biomesToSpawnIn = new ArrayList(); + this.biomesToSpawnIn.add(BiomeGenBase.forest); + this.biomesToSpawnIn.add(BiomeGenBase.plains); + this.biomesToSpawnIn.add(BiomeGenBase.taiga); + this.biomesToSpawnIn.add(BiomeGenBase.taigaHills); + this.biomesToSpawnIn.add(BiomeGenBase.forestHills); + this.biomesToSpawnIn.add(BiomeGenBase.jungle); + this.biomesToSpawnIn.add(BiomeGenBase.jungleHills); + } + + public WorldChunkManager(long par1, WorldType par3WorldType) { + this(); + GenLayer[] var4 = GenLayer.initializeAllBiomeGenerators(par1, par3WorldType); + this.genBiomes = var4[0]; + this.biomeIndexLayer = var4[1]; + } + + public WorldChunkManager(World par1World) { + this(par1World.getSeed(), par1World.getWorldInfo().getTerrainType()); + } + + /** + * Gets the list of valid biomes for the player to spawn in. + */ + public List getBiomesToSpawnIn() { + return this.biomesToSpawnIn; + } + + /** + * Returns the BiomeGenBase related to the x, z position on the world. + */ + public BiomeGenBase getBiomeGenAt(int par1, int par2) { + return this.biomeCache.getBiomeGenAt(par1, par2); + } + + /** + * Returns a list of rainfall values for the specified blocks. Args: + * listToReuse, x, z, width, length. + */ + public float[] getRainfall(float[] par1ArrayOfFloat, int par2, int par3, int par4, int par5) { + IntCache.resetIntCache(); + + if (par1ArrayOfFloat == null || par1ArrayOfFloat.length < par4 * par5) { + par1ArrayOfFloat = new float[par4 * par5]; + } + + int[] var6 = this.biomeIndexLayer.getInts(par2, par3, par4, par5); + + for (int var7 = 0; var7 < par4 * par5; ++var7) { + float var8 = (float) BiomeGenBase.biomeList[var6[var7]].getIntRainfall() / 65536.0F; + + if (var8 > 1.0F) { + var8 = 1.0F; + } + + par1ArrayOfFloat[var7] = var8; + } + + return par1ArrayOfFloat; + } + + /** + * Returns a list of temperatures to use for the specified blocks. Args: + * listToReuse, x, y, width, length + */ + public float[] getTemperatures(float[] par1ArrayOfFloat, int par2, int par3, int par4, int par5) { + IntCache.resetIntCache(); + + if (par1ArrayOfFloat == null || par1ArrayOfFloat.length < par4 * par5) { + par1ArrayOfFloat = new float[par4 * par5]; + } + + int[] var6 = this.biomeIndexLayer.getInts(par2, par3, par4, par5); + + for (int var7 = 0; var7 < par4 * par5; ++var7) { + float var8 = (float) BiomeGenBase.biomeList[var6[var7]].getIntTemperature() / 65536.0F; + + if (var8 > 1.0F) { + var8 = 1.0F; + } + + par1ArrayOfFloat[var7] = var8; + } + + return par1ArrayOfFloat; + } + + /** + * Returns an array of biomes for the location input. + */ + public BiomeGenBase[] getBiomesForGeneration(BiomeGenBase[] par1ArrayOfBiomeGenBase, int par2, int par3, int par4, + int par5) { + IntCache.resetIntCache(); + + if (par1ArrayOfBiomeGenBase == null || par1ArrayOfBiomeGenBase.length < par4 * par5) { + par1ArrayOfBiomeGenBase = new BiomeGenBase[par4 * par5]; + } + + int[] var6 = this.genBiomes.getInts(par2, par3, par4, par5); + + for (int var7 = 0; var7 < par4 * par5; ++var7) { + par1ArrayOfBiomeGenBase[var7] = BiomeGenBase.biomeList[var6[var7]]; + } + + return par1ArrayOfBiomeGenBase; + } + + /** + * Returns biomes to use for the blocks and loads the other data like + * temperature and humidity onto the WorldChunkManager Args: oldBiomeList, x, z, + * width, depth + */ + public BiomeGenBase[] loadBlockGeneratorData(BiomeGenBase[] par1ArrayOfBiomeGenBase, int par2, int par3, int par4, + int par5) { + return this.getBiomeGenAt(par1ArrayOfBiomeGenBase, par2, par3, par4, par5, true); + } + + /** + * Return a list of biomes for the specified blocks. Args: listToReuse, x, y, + * width, length, cacheFlag (if false, don't check biomeCache to avoid infinite + * loop in BiomeCacheBlock) + */ + public BiomeGenBase[] getBiomeGenAt(BiomeGenBase[] par1ArrayOfBiomeGenBase, int par2, int par3, int par4, int par5, + boolean par6) { + IntCache.resetIntCache(); + + if (par1ArrayOfBiomeGenBase == null || par1ArrayOfBiomeGenBase.length < par4 * par5) { + par1ArrayOfBiomeGenBase = new BiomeGenBase[par4 * par5]; + } + + if (par6 && par4 == 16 && par5 == 16 && (par2 & 15) == 0 && (par3 & 15) == 0) { + BiomeGenBase[] var9 = this.biomeCache.getCachedBiomes(par2, par3); + System.arraycopy(var9, 0, par1ArrayOfBiomeGenBase, 0, par4 * par5); + return par1ArrayOfBiomeGenBase; + } else { + int[] var7 = this.biomeIndexLayer.getInts(par2, par3, par4, par5); + + for (int var8 = 0; var8 < par4 * par5; ++var8) { + par1ArrayOfBiomeGenBase[var8] = BiomeGenBase.biomeList[var7[var8]]; + } + + return par1ArrayOfBiomeGenBase; + } + } + + /** + * checks given Chunk's Biomes against List of allowed ones + */ + public boolean areBiomesViable(int par1, int par2, int par3, List par4List) { + IntCache.resetIntCache(); + int var5 = par1 - par3 >> 2; + int var6 = par2 - par3 >> 2; + int var7 = par1 + par3 >> 2; + int var8 = par2 + par3 >> 2; + int var9 = var7 - var5 + 1; + int var10 = var8 - var6 + 1; + int[] var11 = this.genBiomes.getInts(var5, var6, var9, var10); + + for (int var12 = 0; var12 < var9 * var10; ++var12) { + BiomeGenBase var13 = BiomeGenBase.biomeList[var11[var12]]; + + if (!par4List.contains(var13)) { + return false; + } + } + + return true; + } + + /** + * Finds a valid position within a range, that is once of the listed biomes. + */ + public ChunkPosition findBiomePosition(int par1, int par2, int par3, List par4List, Random par5Random) { + IntCache.resetIntCache(); + int var6 = par1 - par3 >> 2; + int var7 = par2 - par3 >> 2; + int var8 = par1 + par3 >> 2; + int var9 = par2 + par3 >> 2; + int var10 = var8 - var6 + 1; + int var11 = var9 - var7 + 1; + int[] var12 = this.genBiomes.getInts(var6, var7, var10, var11); + ChunkPosition var13 = null; + int var14 = 0; + + for (int var15 = 0; var15 < var10 * var11; ++var15) { + int var16 = var6 + var15 % var10 << 2; + int var17 = var7 + var15 / var10 << 2; + BiomeGenBase var18 = BiomeGenBase.biomeList[var12[var15]]; + + if (par4List.contains(var18) && (var13 == null || par5Random.nextInt(var14 + 1) == 0)) { + var13 = new ChunkPosition(var16, 0, var17); + ++var14; + } + } + + return var13; + } + + /** + * Calls the WorldChunkManager's biomeCache.cleanupCache() + */ + public void cleanupCache() { + this.biomeCache.cleanupCache(); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/WorldChunkManagerHell.java b/sp-server/src/main/java/net/minecraft/src/WorldChunkManagerHell.java new file mode 100644 index 0000000..d25b072 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/WorldChunkManagerHell.java @@ -0,0 +1,108 @@ +package net.minecraft.src; + +import java.util.Arrays; +import java.util.List; +import java.util.Random; + +public class WorldChunkManagerHell extends WorldChunkManager { + /** The biome generator object. */ + private BiomeGenBase biomeGenerator; + private float hellTemperature; + + /** The rainfall in the world */ + private float rainfall; + + public WorldChunkManagerHell(BiomeGenBase par1BiomeGenBase, float par2, float par3) { + this.biomeGenerator = par1BiomeGenBase; + this.hellTemperature = par2; + this.rainfall = par3; + } + + /** + * Returns the BiomeGenBase related to the x, z position on the world. + */ + public BiomeGenBase getBiomeGenAt(int par1, int par2) { + return this.biomeGenerator; + } + + /** + * Returns an array of biomes for the location input. + */ + public BiomeGenBase[] getBiomesForGeneration(BiomeGenBase[] par1ArrayOfBiomeGenBase, int par2, int par3, int par4, + int par5) { + if (par1ArrayOfBiomeGenBase == null || par1ArrayOfBiomeGenBase.length < par4 * par5) { + par1ArrayOfBiomeGenBase = new BiomeGenBase[par4 * par5]; + } + + Arrays.fill(par1ArrayOfBiomeGenBase, 0, par4 * par5, this.biomeGenerator); + return par1ArrayOfBiomeGenBase; + } + + /** + * Returns a list of temperatures to use for the specified blocks. Args: + * listToReuse, x, y, width, length + */ + public float[] getTemperatures(float[] par1ArrayOfFloat, int par2, int par3, int par4, int par5) { + if (par1ArrayOfFloat == null || par1ArrayOfFloat.length < par4 * par5) { + par1ArrayOfFloat = new float[par4 * par5]; + } + + Arrays.fill(par1ArrayOfFloat, 0, par4 * par5, this.hellTemperature); + return par1ArrayOfFloat; + } + + /** + * Returns a list of rainfall values for the specified blocks. Args: + * listToReuse, x, z, width, length. + */ + public float[] getRainfall(float[] par1ArrayOfFloat, int par2, int par3, int par4, int par5) { + if (par1ArrayOfFloat == null || par1ArrayOfFloat.length < par4 * par5) { + par1ArrayOfFloat = new float[par4 * par5]; + } + + Arrays.fill(par1ArrayOfFloat, 0, par4 * par5, this.rainfall); + return par1ArrayOfFloat; + } + + /** + * Returns biomes to use for the blocks and loads the other data like + * temperature and humidity onto the WorldChunkManager Args: oldBiomeList, x, z, + * width, depth + */ + public BiomeGenBase[] loadBlockGeneratorData(BiomeGenBase[] par1ArrayOfBiomeGenBase, int par2, int par3, int par4, + int par5) { + if (par1ArrayOfBiomeGenBase == null || par1ArrayOfBiomeGenBase.length < par4 * par5) { + par1ArrayOfBiomeGenBase = new BiomeGenBase[par4 * par5]; + } + + Arrays.fill(par1ArrayOfBiomeGenBase, 0, par4 * par5, this.biomeGenerator); + return par1ArrayOfBiomeGenBase; + } + + /** + * Return a list of biomes for the specified blocks. Args: listToReuse, x, y, + * width, length, cacheFlag (if false, don't check biomeCache to avoid infinite + * loop in BiomeCacheBlock) + */ + public BiomeGenBase[] getBiomeGenAt(BiomeGenBase[] par1ArrayOfBiomeGenBase, int par2, int par3, int par4, int par5, + boolean par6) { + return this.loadBlockGeneratorData(par1ArrayOfBiomeGenBase, par2, par3, par4, par5); + } + + /** + * Finds a valid position within a range, that is once of the listed biomes. + */ + public ChunkPosition findBiomePosition(int par1, int par2, int par3, List par4List, Random par5Random) { + return par4List.contains(this.biomeGenerator) + ? new ChunkPosition(par1 - par3 + par5Random.nextInt(par3 * 2 + 1), 0, + par2 - par3 + par5Random.nextInt(par3 * 2 + 1)) + : null; + } + + /** + * checks given Chunk's Biomes against List of allowed ones + */ + public boolean areBiomesViable(int par1, int par2, int par3, List par4List) { + return par4List.contains(this.biomeGenerator); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/WorldGenBigMushroom.java b/sp-server/src/main/java/net/minecraft/src/WorldGenBigMushroom.java new file mode 100644 index 0000000..b47b97e --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/WorldGenBigMushroom.java @@ -0,0 +1,169 @@ +package net.minecraft.src; + +import java.util.Random; + +public class WorldGenBigMushroom extends WorldGenerator { + /** The mushroom type. 0 for brown, 1 for red. */ + private int mushroomType = -1; + + public WorldGenBigMushroom(int par1) { + super(true); + this.mushroomType = par1; + } + + public WorldGenBigMushroom() { + super(false); + } + + public boolean generate(World par1World, Random par2Random, int par3, int par4, int par5) { + int var6 = par2Random.nextInt(2); + + if (this.mushroomType >= 0) { + var6 = this.mushroomType; + } + + int var7 = par2Random.nextInt(3) + 4; + boolean var8 = true; + + if (par4 >= 1 && par4 + var7 + 1 < 256) { + int var9; + int var11; + int var12; + int var13; + + for (var9 = par4; var9 <= par4 + 1 + var7; ++var9) { + byte var10 = 3; + + if (var9 <= par4 + 3) { + var10 = 0; + } + + for (var11 = par3 - var10; var11 <= par3 + var10 && var8; ++var11) { + for (var12 = par5 - var10; var12 <= par5 + var10 && var8; ++var12) { + if (var9 >= 0 && var9 < 256) { + var13 = par1World.getBlockId(var11, var9, var12); + + if (var13 != 0 && var13 != Block.leaves.blockID) { + var8 = false; + } + } else { + var8 = false; + } + } + } + } + + if (!var8) { + return false; + } else { + var9 = par1World.getBlockId(par3, par4 - 1, par5); + + if (var9 != Block.dirt.blockID && var9 != Block.grass.blockID && var9 != Block.mycelium.blockID) { + return false; + } else { + int var16 = par4 + var7; + + if (var6 == 1) { + var16 = par4 + var7 - 3; + } + + for (var11 = var16; var11 <= par4 + var7; ++var11) { + var12 = 1; + + if (var11 < par4 + var7) { + ++var12; + } + + if (var6 == 0) { + var12 = 3; + } + + for (var13 = par3 - var12; var13 <= par3 + var12; ++var13) { + for (int var14 = par5 - var12; var14 <= par5 + var12; ++var14) { + int var15 = 5; + + if (var13 == par3 - var12) { + --var15; + } + + if (var13 == par3 + var12) { + ++var15; + } + + if (var14 == par5 - var12) { + var15 -= 3; + } + + if (var14 == par5 + var12) { + var15 += 3; + } + + if (var6 == 0 || var11 < par4 + var7) { + if ((var13 == par3 - var12 || var13 == par3 + var12) + && (var14 == par5 - var12 || var14 == par5 + var12)) { + continue; + } + + if (var13 == par3 - (var12 - 1) && var14 == par5 - var12) { + var15 = 1; + } + + if (var13 == par3 - var12 && var14 == par5 - (var12 - 1)) { + var15 = 1; + } + + if (var13 == par3 + (var12 - 1) && var14 == par5 - var12) { + var15 = 3; + } + + if (var13 == par3 + var12 && var14 == par5 - (var12 - 1)) { + var15 = 3; + } + + if (var13 == par3 - (var12 - 1) && var14 == par5 + var12) { + var15 = 7; + } + + if (var13 == par3 - var12 && var14 == par5 + (var12 - 1)) { + var15 = 7; + } + + if (var13 == par3 + (var12 - 1) && var14 == par5 + var12) { + var15 = 9; + } + + if (var13 == par3 + var12 && var14 == par5 + (var12 - 1)) { + var15 = 9; + } + } + + if (var15 == 5 && var11 < par4 + var7) { + var15 = 0; + } + + if ((var15 != 0 || par4 >= par4 + var7 - 1) + && !Block.opaqueCubeLookup[par1World.getBlockId(var13, var11, var14)]) { + this.setBlockAndMetadata(par1World, var13, var11, var14, + Block.mushroomCapBrown.blockID + var6, var15); + } + } + } + } + + for (var11 = 0; var11 < var7; ++var11) { + var12 = par1World.getBlockId(par3, par4 + var11, par5); + + if (!Block.opaqueCubeLookup[var12]) { + this.setBlockAndMetadata(par1World, par3, par4 + var11, par5, + Block.mushroomCapBrown.blockID + var6, 10); + } + } + + return true; + } + } + } else { + return false; + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/WorldGenBigTree.java b/sp-server/src/main/java/net/minecraft/src/WorldGenBigTree.java new file mode 100644 index 0000000..4238e26 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/WorldGenBigTree.java @@ -0,0 +1,440 @@ +package net.minecraft.src; + +import java.util.Random; + +public class WorldGenBigTree extends WorldGenerator { + /** + * Contains three sets of two values that provide complimentary indices for a + * given 'major' index - 1 and 2 for 0, 0 and 2 for 1, and 0 and 1 for 2. + */ + static final byte[] otherCoordPairs = new byte[] { (byte) 2, (byte) 0, (byte) 0, (byte) 1, (byte) 2, (byte) 1 }; + + /** random seed for GenBigTree */ + Random rand = new Random(); + + /** Reference to the World object. */ + World worldObj; + int[] basePos = new int[] { 0, 0, 0 }; + int heightLimit = 0; + int height; + double heightAttenuation = 0.618D; + double branchDensity = 1.0D; + double branchSlope = 0.381D; + double scaleWidth = 1.0D; + double leafDensity = 1.0D; + + /** + * Currently always 1, can be set to 2 in the class constructor to generate a + * double-sized tree trunk for big trees. + */ + int trunkSize = 1; + + /** + * Sets the limit of the random value used to initialize the height limit. + */ + int heightLimitLimit = 12; + + /** + * Sets the distance limit for how far away the generator will populate leaves + * from the base leaf node. + */ + int leafDistanceLimit = 4; + + /** Contains a list of a points at which to generate groups of leaves. */ + int[][] leafNodes; + + public WorldGenBigTree(boolean par1) { + super(par1); + } + + /** + * Generates a list of leaf nodes for the tree, to be populated by + * generateLeaves. + */ + void generateLeafNodeList() { + this.height = (int) ((double) this.heightLimit * this.heightAttenuation); + + if (this.height >= this.heightLimit) { + this.height = this.heightLimit - 1; + } + + int var1 = (int) (1.382D + Math.pow(this.leafDensity * (double) this.heightLimit / 13.0D, 2.0D)); + + if (var1 < 1) { + var1 = 1; + } + + int[][] var2 = new int[var1 * this.heightLimit][4]; + int var3 = this.basePos[1] + this.heightLimit - this.leafDistanceLimit; + int var4 = 1; + int var5 = this.basePos[1] + this.height; + int var6 = var3 - this.basePos[1]; + var2[0][0] = this.basePos[0]; + var2[0][1] = var3; + var2[0][2] = this.basePos[2]; + var2[0][3] = var5; + --var3; + + while (var6 >= 0) { + int var7 = 0; + float var8 = this.layerSize(var6); + + if (var8 < 0.0F) { + --var3; + --var6; + } else { + for (double var9 = 0.5D; var7 < var1; ++var7) { + double var11 = this.scaleWidth * (double) var8 * ((double) this.rand.nextFloat() + 0.328D); + double var13 = (double) this.rand.nextFloat() * 2.0D * Math.PI; + int var15 = MathHelper.floor_double(var11 * Math.sin(var13) + (double) this.basePos[0] + var9); + int var16 = MathHelper.floor_double(var11 * Math.cos(var13) + (double) this.basePos[2] + var9); + int[] var17 = new int[] { var15, var3, var16 }; + int[] var18 = new int[] { var15, var3 + this.leafDistanceLimit, var16 }; + + if (this.checkBlockLine(var17, var18) == -1) { + int[] var19 = new int[] { this.basePos[0], this.basePos[1], this.basePos[2] }; + double var20 = Math.sqrt(Math.pow((double) Math.abs(this.basePos[0] - var17[0]), 2.0D) + + Math.pow((double) Math.abs(this.basePos[2] - var17[2]), 2.0D)); + double var22 = var20 * this.branchSlope; + + if ((double) var17[1] - var22 > (double) var5) { + var19[1] = var5; + } else { + var19[1] = (int) ((double) var17[1] - var22); + } + + if (this.checkBlockLine(var19, var17) == -1) { + var2[var4][0] = var15; + var2[var4][1] = var3; + var2[var4][2] = var16; + var2[var4][3] = var19[1]; + ++var4; + } + } + } + + --var3; + --var6; + } + } + + this.leafNodes = new int[var4][4]; + System.arraycopy(var2, 0, this.leafNodes, 0, var4); + } + + void genTreeLayer(int par1, int par2, int par3, float par4, byte par5, int par6) { + int var7 = (int) ((double) par4 + 0.618D); + byte var8 = otherCoordPairs[par5]; + byte var9 = otherCoordPairs[par5 + 3]; + int[] var10 = new int[] { par1, par2, par3 }; + int[] var11 = new int[] { 0, 0, 0 }; + int var12 = -var7; + int var13 = -var7; + + for (var11[par5] = var10[par5]; var12 <= var7; ++var12) { + var11[var8] = var10[var8] + var12; + var13 = -var7; + + while (var13 <= var7) { + double var15 = Math.pow((double) Math.abs(var12) + 0.5D, 2.0D) + + Math.pow((double) Math.abs(var13) + 0.5D, 2.0D); + + if (var15 > (double) (par4 * par4)) { + ++var13; + } else { + var11[var9] = var10[var9] + var13; + int var14 = this.worldObj.getBlockId(var11[0], var11[1], var11[2]); + + if (var14 != 0 && var14 != Block.leaves.blockID) { + ++var13; + } else { + this.setBlockAndMetadata(this.worldObj, var11[0], var11[1], var11[2], par6, 0); + ++var13; + } + } + } + } + } + + /** + * Gets the rough size of a layer of the tree. + */ + float layerSize(int par1) { + if ((double) par1 < (double) ((float) this.heightLimit) * 0.3D) { + return -1.618F; + } else { + float var2 = (float) this.heightLimit / 2.0F; + float var3 = (float) this.heightLimit / 2.0F - (float) par1; + float var4; + + if (var3 == 0.0F) { + var4 = var2; + } else if (Math.abs(var3) >= var2) { + var4 = 0.0F; + } else { + var4 = (float) Math + .sqrt(Math.pow((double) Math.abs(var2), 2.0D) - Math.pow((double) Math.abs(var3), 2.0D)); + } + + var4 *= 0.5F; + return var4; + } + } + + float leafSize(int par1) { + return par1 >= 0 && par1 < this.leafDistanceLimit + ? (par1 != 0 && par1 != this.leafDistanceLimit - 1 ? 3.0F : 2.0F) + : -1.0F; + } + + /** + * Generates the leaves surrounding an individual entry in the leafNodes list. + */ + void generateLeafNode(int par1, int par2, int par3) { + int var4 = par2; + + for (int var5 = par2 + this.leafDistanceLimit; var4 < var5; ++var4) { + float var6 = this.leafSize(var4 - par2); + this.genTreeLayer(par1, var4, par3, var6, (byte) 1, Block.leaves.blockID); + } + } + + /** + * Places a line of the specified block ID into the world from the first + * coordinate triplet to the second. + */ + void placeBlockLine(int[] par1ArrayOfInteger, int[] par2ArrayOfInteger, int par3) { + int[] var4 = new int[] { 0, 0, 0 }; + byte var5 = 0; + byte var6; + + for (var6 = 0; var5 < 3; ++var5) { + var4[var5] = par2ArrayOfInteger[var5] - par1ArrayOfInteger[var5]; + + if (Math.abs(var4[var5]) > Math.abs(var4[var6])) { + var6 = var5; + } + } + + if (var4[var6] != 0) { + byte var7 = otherCoordPairs[var6]; + byte var8 = otherCoordPairs[var6 + 3]; + byte var9; + + if (var4[var6] > 0) { + var9 = 1; + } else { + var9 = -1; + } + + double var10 = (double) var4[var7] / (double) var4[var6]; + double var12 = (double) var4[var8] / (double) var4[var6]; + int[] var14 = new int[] { 0, 0, 0 }; + int var15 = 0; + + for (int var16 = var4[var6] + var9; var15 != var16; var15 += var9) { + var14[var6] = MathHelper.floor_double((double) (par1ArrayOfInteger[var6] + var15) + 0.5D); + var14[var7] = MathHelper + .floor_double((double) par1ArrayOfInteger[var7] + (double) var15 * var10 + 0.5D); + var14[var8] = MathHelper + .floor_double((double) par1ArrayOfInteger[var8] + (double) var15 * var12 + 0.5D); + byte var17 = 0; + int var18 = Math.abs(var14[0] - par1ArrayOfInteger[0]); + int var19 = Math.abs(var14[2] - par1ArrayOfInteger[2]); + int var20 = Math.max(var18, var19); + + if (var20 > 0) { + if (var18 == var20) { + var17 = 4; + } else if (var19 == var20) { + var17 = 8; + } + } + + this.setBlockAndMetadata(this.worldObj, var14[0], var14[1], var14[2], par3, var17); + } + } + } + + /** + * Generates the leaf portion of the tree as specified by the leafNodes list. + */ + void generateLeaves() { + int var1 = 0; + + for (int var2 = this.leafNodes.length; var1 < var2; ++var1) { + int var3 = this.leafNodes[var1][0]; + int var4 = this.leafNodes[var1][1]; + int var5 = this.leafNodes[var1][2]; + this.generateLeafNode(var3, var4, var5); + } + } + + /** + * Indicates whether or not a leaf node requires additional wood to be added to + * preserve integrity. + */ + boolean leafNodeNeedsBase(int par1) { + return (double) par1 >= (double) this.heightLimit * 0.2D; + } + + /** + * Places the trunk for the big tree that is being generated. Able to generate + * double-sized trunks by changing a field that is always 1 to 2. + */ + void generateTrunk() { + int var1 = this.basePos[0]; + int var2 = this.basePos[1]; + int var3 = this.basePos[1] + this.height; + int var4 = this.basePos[2]; + int[] var5 = new int[] { var1, var2, var4 }; + int[] var6 = new int[] { var1, var3, var4 }; + this.placeBlockLine(var5, var6, Block.wood.blockID); + + if (this.trunkSize == 2) { + ++var5[0]; + ++var6[0]; + this.placeBlockLine(var5, var6, Block.wood.blockID); + ++var5[2]; + ++var6[2]; + this.placeBlockLine(var5, var6, Block.wood.blockID); + var5[0] += -1; + var6[0] += -1; + this.placeBlockLine(var5, var6, Block.wood.blockID); + } + } + + /** + * Generates additional wood blocks to fill out the bases of different leaf + * nodes that would otherwise degrade. + */ + void generateLeafNodeBases() { + int var1 = 0; + int var2 = this.leafNodes.length; + + for (int[] var3 = new int[] { this.basePos[0], this.basePos[1], this.basePos[2] }; var1 < var2; ++var1) { + int[] var4 = this.leafNodes[var1]; + int[] var5 = new int[] { var4[0], var4[1], var4[2] }; + var3[1] = var4[3]; + int var6 = var3[1] - this.basePos[1]; + + if (this.leafNodeNeedsBase(var6)) { + this.placeBlockLine(var3, var5, (byte) Block.wood.blockID); + } + } + } + + /** + * Checks a line of blocks in the world from the first coordinate to triplet to + * the second, returning the distance (in blocks) before a non-air, non-leaf + * block is encountered and/or the end is encountered. + */ + int checkBlockLine(int[] par1ArrayOfInteger, int[] par2ArrayOfInteger) { + int[] var3 = new int[] { 0, 0, 0 }; + byte var4 = 0; + byte var5; + + for (var5 = 0; var4 < 3; ++var4) { + var3[var4] = par2ArrayOfInteger[var4] - par1ArrayOfInteger[var4]; + + if (Math.abs(var3[var4]) > Math.abs(var3[var5])) { + var5 = var4; + } + } + + if (var3[var5] == 0) { + return -1; + } else { + byte var6 = otherCoordPairs[var5]; + byte var7 = otherCoordPairs[var5 + 3]; + byte var8; + + if (var3[var5] > 0) { + var8 = 1; + } else { + var8 = -1; + } + + double var9 = (double) var3[var6] / (double) var3[var5]; + double var11 = (double) var3[var7] / (double) var3[var5]; + int[] var13 = new int[] { 0, 0, 0 }; + int var14 = 0; + int var15; + + for (var15 = var3[var5] + var8; var14 != var15; var14 += var8) { + var13[var5] = par1ArrayOfInteger[var5] + var14; + var13[var6] = MathHelper.floor_double((double) par1ArrayOfInteger[var6] + (double) var14 * var9); + var13[var7] = MathHelper.floor_double((double) par1ArrayOfInteger[var7] + (double) var14 * var11); + int var16 = this.worldObj.getBlockId(var13[0], var13[1], var13[2]); + + if (var16 != 0 && var16 != Block.leaves.blockID) { + break; + } + } + + return var14 == var15 ? -1 : Math.abs(var14); + } + } + + /** + * Returns a boolean indicating whether or not the current location for the + * tree, spanning basePos to to the height limit, is valid. + */ + boolean validTreeLocation() { + int[] var1 = new int[] { this.basePos[0], this.basePos[1], this.basePos[2] }; + int[] var2 = new int[] { this.basePos[0], this.basePos[1] + this.heightLimit - 1, this.basePos[2] }; + int var3 = this.worldObj.getBlockId(this.basePos[0], this.basePos[1] - 1, this.basePos[2]); + + if (var3 != 2 && var3 != 3) { + return false; + } else { + int var4 = this.checkBlockLine(var1, var2); + + if (var4 == -1) { + return true; + } else if (var4 < 6) { + return false; + } else { + this.heightLimit = var4; + return true; + } + } + } + + /** + * Rescales the generator settings, only used in WorldGenBigTree + */ + public void setScale(double par1, double par3, double par5) { + this.heightLimitLimit = (int) (par1 * 12.0D); + + if (par1 > 0.5D) { + this.leafDistanceLimit = 5; + } + + this.scaleWidth = par3; + this.leafDensity = par5; + } + + public boolean generate(World par1World, Random par2Random, int par3, int par4, int par5) { + this.worldObj = par1World; + long var6 = par2Random.nextLong(); + this.rand.setSeed(var6); + this.basePos[0] = par3; + this.basePos[1] = par4; + this.basePos[2] = par5; + + if (this.heightLimit == 0) { + this.heightLimit = 5 + this.rand.nextInt(this.heightLimitLimit); + } + + if (!this.validTreeLocation()) { + return false; + } else { + this.generateLeafNodeList(); + this.generateLeaves(); + this.generateTrunk(); + this.generateLeafNodeBases(); + return true; + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/WorldGenCactus.java b/sp-server/src/main/java/net/minecraft/src/WorldGenCactus.java new file mode 100644 index 0000000..8cd0663 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/WorldGenCactus.java @@ -0,0 +1,25 @@ +package net.minecraft.src; + +import java.util.Random; + +public class WorldGenCactus extends WorldGenerator { + public boolean generate(World par1World, Random par2Random, int par3, int par4, int par5) { + for (int var6 = 0; var6 < 10; ++var6) { + int var7 = par3 + par2Random.nextInt(8) - par2Random.nextInt(8); + int var8 = par4 + par2Random.nextInt(4) - par2Random.nextInt(4); + int var9 = par5 + par2Random.nextInt(8) - par2Random.nextInt(8); + + if (par1World.isAirBlock(var7, var8, var9)) { + int var10 = 1 + par2Random.nextInt(par2Random.nextInt(3) + 1); + + for (int var11 = 0; var11 < var10; ++var11) { + if (Block.cactus.canBlockStay(par1World, var7, var8 + var11, var9)) { + par1World.setBlock(var7, var8 + var11, var9, Block.cactus.blockID, 0, 2); + } + } + } + } + + return true; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/WorldGenClay.java b/sp-server/src/main/java/net/minecraft/src/WorldGenClay.java new file mode 100644 index 0000000..5479146 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/WorldGenClay.java @@ -0,0 +1,44 @@ +package net.minecraft.src; + +import java.util.Random; + +public class WorldGenClay extends WorldGenerator { + /** The block ID for clay. */ + private int clayBlockId; + + /** The number of blocks to generate. */ + private int numberOfBlocks; + + public WorldGenClay(int par1) { + this.clayBlockId = Block.blockClay.blockID; + this.numberOfBlocks = par1; + } + + public boolean generate(World par1World, Random par2Random, int par3, int par4, int par5) { + if (par1World.getBlockMaterial(par3, par4, par5) != Material.water) { + return false; + } else { + int var6 = par2Random.nextInt(this.numberOfBlocks - 2) + 2; + byte var7 = 1; + + for (int var8 = par3 - var6; var8 <= par3 + var6; ++var8) { + for (int var9 = par5 - var6; var9 <= par5 + var6; ++var9) { + int var10 = var8 - par3; + int var11 = var9 - par5; + + if (var10 * var10 + var11 * var11 <= var6 * var6) { + for (int var12 = par4 - var7; var12 <= par4 + var7; ++var12) { + int var13 = par1World.getBlockId(var8, var12, var9); + + if (var13 == Block.dirt.blockID || var13 == Block.blockClay.blockID) { + par1World.setBlock(var8, var12, var9, this.clayBlockId, 0, 2); + } + } + } + } + } + + return true; + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/WorldGenDeadBush.java b/sp-server/src/main/java/net/minecraft/src/WorldGenDeadBush.java new file mode 100644 index 0000000..3e06a25 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/WorldGenDeadBush.java @@ -0,0 +1,34 @@ +package net.minecraft.src; + +import java.util.Random; + +public class WorldGenDeadBush extends WorldGenerator { + /** stores the ID for WorldGenDeadBush */ + private int deadBushID; + + public WorldGenDeadBush(int par1) { + this.deadBushID = par1; + } + + public boolean generate(World par1World, Random par2Random, int par3, int par4, int par5) { + int var11; + + for (boolean var6 = false; ((var11 = par1World.getBlockId(par3, par4, par5)) == 0 + || var11 == Block.leaves.blockID) && par4 > 0; --par4) { + ; + } + + for (int var7 = 0; var7 < 4; ++var7) { + int var8 = par3 + par2Random.nextInt(8) - par2Random.nextInt(8); + int var9 = par4 + par2Random.nextInt(4) - par2Random.nextInt(4); + int var10 = par5 + par2Random.nextInt(8) - par2Random.nextInt(8); + + if (par1World.isAirBlock(var8, var9, var10) + && Block.blocksList[this.deadBushID].canBlockStay(par1World, var8, var9, var10)) { + par1World.setBlock(var8, var9, var10, this.deadBushID, 0, 2); + } + } + + return true; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/WorldGenDesertWells.java b/sp-server/src/main/java/net/minecraft/src/WorldGenDesertWells.java new file mode 100644 index 0000000..cd7f9bf --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/WorldGenDesertWells.java @@ -0,0 +1,75 @@ +package net.minecraft.src; + +import java.util.Random; + +public class WorldGenDesertWells extends WorldGenerator { + public boolean generate(World par1World, Random par2Random, int par3, int par4, int par5) { + while (par1World.isAirBlock(par3, par4, par5) && par4 > 2) { + --par4; + } + + int var6 = par1World.getBlockId(par3, par4, par5); + + if (var6 != Block.sand.blockID) { + return false; + } else { + int var7; + int var8; + + for (var7 = -2; var7 <= 2; ++var7) { + for (var8 = -2; var8 <= 2; ++var8) { + if (par1World.isAirBlock(par3 + var7, par4 - 1, par5 + var8) + && par1World.isAirBlock(par3 + var7, par4 - 2, par5 + var8)) { + return false; + } + } + } + + for (var7 = -1; var7 <= 0; ++var7) { + for (var8 = -2; var8 <= 2; ++var8) { + for (int var9 = -2; var9 <= 2; ++var9) { + par1World.setBlock(par3 + var8, par4 + var7, par5 + var9, Block.sandStone.blockID, 0, 2); + } + } + } + + par1World.setBlock(par3, par4, par5, Block.waterMoving.blockID, 0, 2); + par1World.setBlock(par3 - 1, par4, par5, Block.waterMoving.blockID, 0, 2); + par1World.setBlock(par3 + 1, par4, par5, Block.waterMoving.blockID, 0, 2); + par1World.setBlock(par3, par4, par5 - 1, Block.waterMoving.blockID, 0, 2); + par1World.setBlock(par3, par4, par5 + 1, Block.waterMoving.blockID, 0, 2); + + for (var7 = -2; var7 <= 2; ++var7) { + for (var8 = -2; var8 <= 2; ++var8) { + if (var7 == -2 || var7 == 2 || var8 == -2 || var8 == 2) { + par1World.setBlock(par3 + var7, par4 + 1, par5 + var8, Block.sandStone.blockID, 0, 2); + } + } + } + + par1World.setBlock(par3 + 2, par4 + 1, par5, Block.stoneSingleSlab.blockID, 1, 2); + par1World.setBlock(par3 - 2, par4 + 1, par5, Block.stoneSingleSlab.blockID, 1, 2); + par1World.setBlock(par3, par4 + 1, par5 + 2, Block.stoneSingleSlab.blockID, 1, 2); + par1World.setBlock(par3, par4 + 1, par5 - 2, Block.stoneSingleSlab.blockID, 1, 2); + + for (var7 = -1; var7 <= 1; ++var7) { + for (var8 = -1; var8 <= 1; ++var8) { + if (var7 == 0 && var8 == 0) { + par1World.setBlock(par3 + var7, par4 + 4, par5 + var8, Block.sandStone.blockID, 0, 2); + } else { + par1World.setBlock(par3 + var7, par4 + 4, par5 + var8, Block.stoneSingleSlab.blockID, 1, 2); + } + } + } + + for (var7 = 1; var7 <= 3; ++var7) { + par1World.setBlock(par3 - 1, par4 + var7, par5 - 1, Block.sandStone.blockID, 0, 2); + par1World.setBlock(par3 - 1, par4 + var7, par5 + 1, Block.sandStone.blockID, 0, 2); + par1World.setBlock(par3 + 1, par4 + var7, par5 - 1, Block.sandStone.blockID, 0, 2); + par1World.setBlock(par3 + 1, par4 + var7, par5 + 1, Block.sandStone.blockID, 0, 2); + } + + return true; + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/WorldGenDungeons.java b/sp-server/src/main/java/net/minecraft/src/WorldGenDungeons.java new file mode 100644 index 0000000..a38a7fc --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/WorldGenDungeons.java @@ -0,0 +1,173 @@ +package net.minecraft.src; + +import java.util.Random; + +public class WorldGenDungeons extends WorldGenerator { + public boolean generate(World par1World, Random par2Random, int par3, int par4, int par5) { + byte var6 = 3; + int var7 = par2Random.nextInt(2) + 2; + int var8 = par2Random.nextInt(2) + 2; + int var9 = 0; + int var10; + int var11; + int var12; + + for (var10 = par3 - var7 - 1; var10 <= par3 + var7 + 1; ++var10) { + for (var11 = par4 - 1; var11 <= par4 + var6 + 1; ++var11) { + for (var12 = par5 - var8 - 1; var12 <= par5 + var8 + 1; ++var12) { + Material var13 = par1World.getBlockMaterial(var10, var11, var12); + + if (var11 == par4 - 1 && !var13.isSolid()) { + return false; + } + + if (var11 == par4 + var6 + 1 && !var13.isSolid()) { + return false; + } + + if ((var10 == par3 - var7 - 1 || var10 == par3 + var7 + 1 || var12 == par5 - var8 - 1 + || var12 == par5 + var8 + 1) && var11 == par4 && par1World.isAirBlock(var10, var11, var12) + && par1World.isAirBlock(var10, var11 + 1, var12)) { + ++var9; + } + } + } + } + + if (var9 >= 1 && var9 <= 5) { + for (var10 = par3 - var7 - 1; var10 <= par3 + var7 + 1; ++var10) { + for (var11 = par4 + var6; var11 >= par4 - 1; --var11) { + for (var12 = par5 - var8 - 1; var12 <= par5 + var8 + 1; ++var12) { + if (var10 != par3 - var7 - 1 && var11 != par4 - 1 && var12 != par5 - var8 - 1 + && var10 != par3 + var7 + 1 && var11 != par4 + var6 + 1 && var12 != par5 + var8 + 1) { + par1World.setBlockToAir(var10, var11, var12); + } else if (var11 >= 0 && !par1World.getBlockMaterial(var10, var11 - 1, var12).isSolid()) { + par1World.setBlockToAir(var10, var11, var12); + } else if (par1World.getBlockMaterial(var10, var11, var12).isSolid()) { + if (var11 == par4 - 1 && par2Random.nextInt(4) != 0) { + par1World.setBlock(var10, var11, var12, Block.cobblestoneMossy.blockID, 0, 2); + } else { + par1World.setBlock(var10, var11, var12, Block.cobblestone.blockID, 0, 2); + } + } + } + } + } + + var10 = 0; + + while (var10 < 2) { + var11 = 0; + + while (true) { + if (var11 < 3) { + label113: { + var12 = par3 + par2Random.nextInt(var7 * 2 + 1) - var7; + int var14 = par5 + par2Random.nextInt(var8 * 2 + 1) - var8; + + if (par1World.isAirBlock(var12, par4, var14)) { + int var15 = 0; + + if (par1World.getBlockMaterial(var12 - 1, par4, var14).isSolid()) { + ++var15; + } + + if (par1World.getBlockMaterial(var12 + 1, par4, var14).isSolid()) { + ++var15; + } + + if (par1World.getBlockMaterial(var12, par4, var14 - 1).isSolid()) { + ++var15; + } + + if (par1World.getBlockMaterial(var12, par4, var14 + 1).isSolid()) { + ++var15; + } + + if (var15 == 1) { + par1World.setBlock(var12, par4, var14, Block.chest.blockID, 0, 2); + TileEntityChest var16 = (TileEntityChest) par1World.getBlockTileEntity(var12, par4, + var14); + + if (var16 != null) { + for (int var17 = 0; var17 < 8; ++var17) { + ItemStack var18 = this.pickCheckLootItem(par2Random); + + if (var18 != null) { + var16.setInventorySlotContents( + par2Random.nextInt(var16.getSizeInventory()), var18); + } + } + } + + break label113; + } + } + + ++var11; + continue; + } + } + + ++var10; + break; + } + } + + par1World.setBlock(par3, par4, par5, Block.mobSpawner.blockID, 0, 2); + TileEntityMobSpawner var19 = (TileEntityMobSpawner) par1World.getBlockTileEntity(par3, par4, par5); + + if (var19 != null) { + var19.func_98049_a().setMobID(this.pickMobSpawner(par2Random)); + } else { + System.err.println("Failed to fetch mob spawner entity at (" + par3 + ", " + par4 + ", " + par5 + ")"); + } + + return true; + } else { + return false; + } + } + + /** + * Picks potentially a random item to add to a dungeon chest. + */ + private ItemStack pickCheckLootItem(Random par1Random) { + int var2 = par1Random.nextInt(12); + return var2 == 0 ? new ItemStack(Item.saddle) + : (var2 == 1 ? new ItemStack(Item.ingotIron, par1Random.nextInt(4) + 1) + : (var2 == 2 ? new ItemStack(Item.bread) + : (var2 == 3 ? new ItemStack(Item.wheat, par1Random.nextInt(4) + 1) + : (var2 == 4 ? new ItemStack(Item.gunpowder, par1Random.nextInt(4) + 1) + : (var2 == 5 ? new ItemStack(Item.silk, par1Random.nextInt(4) + 1) + : (var2 == 6 ? new ItemStack(Item.bucketEmpty) + : (var2 == 7 && par1Random.nextInt(100) == 0 + ? new ItemStack(Item.appleGold) + : (var2 == 8 && par1Random.nextInt(2) == 0 + ? new ItemStack(Item.redstone, + par1Random.nextInt(4) + 1) + : (var2 == 9 && par1Random.nextInt( + 10) == 0 ? new ItemStack( + Item.itemsList[Item.record13.itemID + + par1Random + .nextInt( + 2)]) + : (var2 == 10 + ? new ItemStack( + Item.dyePowder, + 1, 3) + : (var2 == 11 + ? Item.enchantedBook + .func_92109_a( + par1Random) + : null))))))))))); + } + + /** + * Randomly decides which spawner to use in a dungeon + */ + private String pickMobSpawner(Random par1Random) { + int var2 = par1Random.nextInt(4); + return var2 == 0 ? "Skeleton" : (var2 == 1 ? "Zombie" : (var2 == 2 ? "Zombie" : (var2 == 3 ? "Spider" : ""))); + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/WorldGenFire.java b/sp-server/src/main/java/net/minecraft/src/WorldGenFire.java new file mode 100644 index 0000000..659691b --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/WorldGenFire.java @@ -0,0 +1,20 @@ +package net.minecraft.src; + +import java.util.Random; + +public class WorldGenFire extends WorldGenerator { + public boolean generate(World par1World, Random par2Random, int par3, int par4, int par5) { + for (int var6 = 0; var6 < 64; ++var6) { + int var7 = par3 + par2Random.nextInt(8) - par2Random.nextInt(8); + int var8 = par4 + par2Random.nextInt(4) - par2Random.nextInt(4); + int var9 = par5 + par2Random.nextInt(8) - par2Random.nextInt(8); + + if (par1World.isAirBlock(var7, var8, var9) + && par1World.getBlockId(var7, var8 - 1, var9) == Block.netherrack.blockID) { + par1World.setBlock(var7, var8, var9, Block.fire.blockID, 0, 2); + } + } + + return true; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/WorldGenFlowers.java b/sp-server/src/main/java/net/minecraft/src/WorldGenFlowers.java new file mode 100644 index 0000000..3359758 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/WorldGenFlowers.java @@ -0,0 +1,27 @@ +package net.minecraft.src; + +import java.util.Random; + +public class WorldGenFlowers extends WorldGenerator { + /** The ID of the plant block used in this plant generator. */ + private int plantBlockId; + + public WorldGenFlowers(int par1) { + this.plantBlockId = par1; + } + + public boolean generate(World par1World, Random par2Random, int par3, int par4, int par5) { + for (int var6 = 0; var6 < 64; ++var6) { + int var7 = par3 + par2Random.nextInt(8) - par2Random.nextInt(8); + int var8 = par4 + par2Random.nextInt(4) - par2Random.nextInt(4); + int var9 = par5 + par2Random.nextInt(8) - par2Random.nextInt(8); + + if (par1World.isAirBlock(var7, var8, var9) && (!par1World.provider.hasNoSky || var8 < 127) + && Block.blocksList[this.plantBlockId].canBlockStay(par1World, var7, var8, var9)) { + par1World.setBlock(var7, var8, var9, this.plantBlockId, 0, 2); + } + } + + return true; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/WorldGenForest.java b/sp-server/src/main/java/net/minecraft/src/WorldGenForest.java new file mode 100644 index 0000000..8f9ebcc --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/WorldGenForest.java @@ -0,0 +1,95 @@ +package net.minecraft.src; + +import java.util.Random; + +public class WorldGenForest extends WorldGenerator { + public WorldGenForest(boolean par1) { + super(par1); + } + + public boolean generate(World par1World, Random par2Random, int par3, int par4, int par5) { + int var6 = par2Random.nextInt(3) + 5; + boolean var7 = true; + + if (par4 >= 1 && par4 + var6 + 1 <= 256) { + int var8; + int var10; + int var11; + int var12; + + for (var8 = par4; var8 <= par4 + 1 + var6; ++var8) { + byte var9 = 1; + + if (var8 == par4) { + var9 = 0; + } + + if (var8 >= par4 + 1 + var6 - 2) { + var9 = 2; + } + + for (var10 = par3 - var9; var10 <= par3 + var9 && var7; ++var10) { + for (var11 = par5 - var9; var11 <= par5 + var9 && var7; ++var11) { + if (var8 >= 0 && var8 < 256) { + var12 = par1World.getBlockId(var10, var8, var11); + + if (var12 != 0 && var12 != Block.leaves.blockID) { + var7 = false; + } + } else { + var7 = false; + } + } + } + } + + if (!var7) { + return false; + } else { + var8 = par1World.getBlockId(par3, par4 - 1, par5); + + if ((var8 == Block.grass.blockID || var8 == Block.dirt.blockID) && par4 < 256 - var6 - 1) { + this.setBlock(par1World, par3, par4 - 1, par5, Block.dirt.blockID); + int var17; + + for (var17 = par4 - 3 + var6; var17 <= par4 + var6; ++var17) { + var10 = var17 - (par4 + var6); + var11 = 1 - var10 / 2; + + for (var12 = par3 - var11; var12 <= par3 + var11; ++var12) { + int var13 = var12 - par3; + + for (int var14 = par5 - var11; var14 <= par5 + var11; ++var14) { + int var15 = var14 - par5; + + if (Math.abs(var13) != var11 || Math.abs(var15) != var11 + || par2Random.nextInt(2) != 0 && var10 != 0) { + int var16 = par1World.getBlockId(var12, var17, var14); + + if (var16 == 0 || var16 == Block.leaves.blockID) { + this.setBlockAndMetadata(par1World, var12, var17, var14, Block.leaves.blockID, + 2); + } + } + } + } + } + + for (var17 = 0; var17 < var6; ++var17) { + var10 = par1World.getBlockId(par3, par4 + var17, par5); + + if (var10 == 0 || var10 == Block.leaves.blockID) { + this.setBlockAndMetadata(par1World, par3, par4 + var17, par5, Block.wood.blockID, 2); + } + } + + return true; + } else { + return false; + } + } + } else { + return false; + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/WorldGenGlowStone1.java b/sp-server/src/main/java/net/minecraft/src/WorldGenGlowStone1.java new file mode 100644 index 0000000..ba07b07 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/WorldGenGlowStone1.java @@ -0,0 +1,63 @@ +package net.minecraft.src; + +import java.util.Random; + +public class WorldGenGlowStone1 extends WorldGenerator { + public boolean generate(World par1World, Random par2Random, int par3, int par4, int par5) { + if (!par1World.isAirBlock(par3, par4, par5)) { + return false; + } else if (par1World.getBlockId(par3, par4 + 1, par5) != Block.netherrack.blockID) { + return false; + } else { + par1World.setBlock(par3, par4, par5, Block.glowStone.blockID, 0, 2); + + for (int var6 = 0; var6 < 1500; ++var6) { + int var7 = par3 + par2Random.nextInt(8) - par2Random.nextInt(8); + int var8 = par4 - par2Random.nextInt(12); + int var9 = par5 + par2Random.nextInt(8) - par2Random.nextInt(8); + + if (par1World.getBlockId(var7, var8, var9) == 0) { + int var10 = 0; + + for (int var11 = 0; var11 < 6; ++var11) { + int var12 = 0; + + if (var11 == 0) { + var12 = par1World.getBlockId(var7 - 1, var8, var9); + } + + if (var11 == 1) { + var12 = par1World.getBlockId(var7 + 1, var8, var9); + } + + if (var11 == 2) { + var12 = par1World.getBlockId(var7, var8 - 1, var9); + } + + if (var11 == 3) { + var12 = par1World.getBlockId(var7, var8 + 1, var9); + } + + if (var11 == 4) { + var12 = par1World.getBlockId(var7, var8, var9 - 1); + } + + if (var11 == 5) { + var12 = par1World.getBlockId(var7, var8, var9 + 1); + } + + if (var12 == Block.glowStone.blockID) { + ++var10; + } + } + + if (var10 == 1) { + par1World.setBlock(var7, var8, var9, Block.glowStone.blockID, 0, 2); + } + } + } + + return true; + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/WorldGenGlowStone2.java b/sp-server/src/main/java/net/minecraft/src/WorldGenGlowStone2.java new file mode 100644 index 0000000..ff7a183 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/WorldGenGlowStone2.java @@ -0,0 +1,63 @@ +package net.minecraft.src; + +import java.util.Random; + +public class WorldGenGlowStone2 extends WorldGenerator { + public boolean generate(World par1World, Random par2Random, int par3, int par4, int par5) { + if (!par1World.isAirBlock(par3, par4, par5)) { + return false; + } else if (par1World.getBlockId(par3, par4 + 1, par5) != Block.netherrack.blockID) { + return false; + } else { + par1World.setBlock(par3, par4, par5, Block.glowStone.blockID, 0, 2); + + for (int var6 = 0; var6 < 1500; ++var6) { + int var7 = par3 + par2Random.nextInt(8) - par2Random.nextInt(8); + int var8 = par4 - par2Random.nextInt(12); + int var9 = par5 + par2Random.nextInt(8) - par2Random.nextInt(8); + + if (par1World.getBlockId(var7, var8, var9) == 0) { + int var10 = 0; + + for (int var11 = 0; var11 < 6; ++var11) { + int var12 = 0; + + if (var11 == 0) { + var12 = par1World.getBlockId(var7 - 1, var8, var9); + } + + if (var11 == 1) { + var12 = par1World.getBlockId(var7 + 1, var8, var9); + } + + if (var11 == 2) { + var12 = par1World.getBlockId(var7, var8 - 1, var9); + } + + if (var11 == 3) { + var12 = par1World.getBlockId(var7, var8 + 1, var9); + } + + if (var11 == 4) { + var12 = par1World.getBlockId(var7, var8, var9 - 1); + } + + if (var11 == 5) { + var12 = par1World.getBlockId(var7, var8, var9 + 1); + } + + if (var12 == Block.glowStone.blockID) { + ++var10; + } + } + + if (var10 == 1) { + par1World.setBlock(var7, var8, var9, Block.glowStone.blockID, 0, 2); + } + } + } + + return true; + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/WorldGenHellLava.java b/sp-server/src/main/java/net/minecraft/src/WorldGenHellLava.java new file mode 100644 index 0000000..9c5d37f --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/WorldGenHellLava.java @@ -0,0 +1,76 @@ +package net.minecraft.src; + +import java.util.Random; + +public class WorldGenHellLava extends WorldGenerator { + /** Stores the ID for WorldGenHellLava */ + private int hellLavaID; + private boolean field_94524_b = false; + + public WorldGenHellLava(int par1, boolean par2) { + this.hellLavaID = par1; + this.field_94524_b = par2; + } + + public boolean generate(World par1World, Random par2Random, int par3, int par4, int par5) { + if (par1World.getBlockId(par3, par4 + 1, par5) != Block.netherrack.blockID) { + return false; + } else if (par1World.getBlockId(par3, par4, par5) != 0 + && par1World.getBlockId(par3, par4, par5) != Block.netherrack.blockID) { + return false; + } else { + int var6 = 0; + + if (par1World.getBlockId(par3 - 1, par4, par5) == Block.netherrack.blockID) { + ++var6; + } + + if (par1World.getBlockId(par3 + 1, par4, par5) == Block.netherrack.blockID) { + ++var6; + } + + if (par1World.getBlockId(par3, par4, par5 - 1) == Block.netherrack.blockID) { + ++var6; + } + + if (par1World.getBlockId(par3, par4, par5 + 1) == Block.netherrack.blockID) { + ++var6; + } + + if (par1World.getBlockId(par3, par4 - 1, par5) == Block.netherrack.blockID) { + ++var6; + } + + int var7 = 0; + + if (par1World.isAirBlock(par3 - 1, par4, par5)) { + ++var7; + } + + if (par1World.isAirBlock(par3 + 1, par4, par5)) { + ++var7; + } + + if (par1World.isAirBlock(par3, par4, par5 - 1)) { + ++var7; + } + + if (par1World.isAirBlock(par3, par4, par5 + 1)) { + ++var7; + } + + if (par1World.isAirBlock(par3, par4 - 1, par5)) { + ++var7; + } + + if (!this.field_94524_b && var6 == 4 && var7 == 1 || var6 == 5) { + par1World.setBlock(par3, par4, par5, this.hellLavaID, 0, 2); + par1World.scheduledUpdatesAreImmediate = true; + Block.blocksList[this.hellLavaID].updateTick(par1World, par3, par4, par5, par2Random); + par1World.scheduledUpdatesAreImmediate = false; + } + + return true; + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/WorldGenHugeTrees.java b/sp-server/src/main/java/net/minecraft/src/WorldGenHugeTrees.java new file mode 100644 index 0000000..31447b3 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/WorldGenHugeTrees.java @@ -0,0 +1,211 @@ +package net.minecraft.src; + +import java.util.Random; + +public class WorldGenHugeTrees extends WorldGenerator { + /** The base height of the tree */ + private final int baseHeight; + + /** Sets the metadata for the wood blocks used */ + private final int woodMetadata; + + /** Sets the metadata for the leaves used in huge trees */ + private final int leavesMetadata; + + public WorldGenHugeTrees(boolean par1, int par2, int par3, int par4) { + super(par1); + this.baseHeight = par2; + this.woodMetadata = par3; + this.leavesMetadata = par4; + } + + public boolean generate(World par1World, Random par2Random, int par3, int par4, int par5) { + int var6 = par2Random.nextInt(3) + this.baseHeight; + boolean var7 = true; + + if (par4 >= 1 && par4 + var6 + 1 <= 256) { + int var8; + int var10; + int var11; + int var12; + + for (var8 = par4; var8 <= par4 + 1 + var6; ++var8) { + byte var9 = 2; + + if (var8 == par4) { + var9 = 1; + } + + if (var8 >= par4 + 1 + var6 - 2) { + var9 = 2; + } + + for (var10 = par3 - var9; var10 <= par3 + var9 && var7; ++var10) { + for (var11 = par5 - var9; var11 <= par5 + var9 && var7; ++var11) { + if (var8 >= 0 && var8 < 256) { + var12 = par1World.getBlockId(var10, var8, var11); + + if (var12 != 0 && var12 != Block.leaves.blockID && var12 != Block.grass.blockID + && var12 != Block.dirt.blockID && var12 != Block.wood.blockID + && var12 != Block.sapling.blockID) { + var7 = false; + } + } else { + var7 = false; + } + } + } + } + + if (!var7) { + return false; + } else { + var8 = par1World.getBlockId(par3, par4 - 1, par5); + + if ((var8 == Block.grass.blockID || var8 == Block.dirt.blockID) && par4 < 256 - var6 - 1) { + par1World.setBlock(par3, par4 - 1, par5, Block.dirt.blockID, 0, 2); + par1World.setBlock(par3 + 1, par4 - 1, par5, Block.dirt.blockID, 0, 2); + par1World.setBlock(par3, par4 - 1, par5 + 1, Block.dirt.blockID, 0, 2); + par1World.setBlock(par3 + 1, par4 - 1, par5 + 1, Block.dirt.blockID, 0, 2); + this.growLeaves(par1World, par3, par5, par4 + var6, 2, par2Random); + + for (int var14 = par4 + var6 - 2 - par2Random.nextInt(4); var14 > par4 + var6 / 2; var14 -= 2 + + par2Random.nextInt(4)) { + float var15 = par2Random.nextFloat() * (float) Math.PI * 2.0F; + var11 = par3 + (int) (0.5F + MathHelper.cos(var15) * 4.0F); + var12 = par5 + (int) (0.5F + MathHelper.sin(var15) * 4.0F); + this.growLeaves(par1World, var11, var12, var14, 0, par2Random); + + for (int var13 = 0; var13 < 5; ++var13) { + var11 = par3 + (int) (1.5F + MathHelper.cos(var15) * (float) var13); + var12 = par5 + (int) (1.5F + MathHelper.sin(var15) * (float) var13); + this.setBlockAndMetadata(par1World, var11, var14 - 3 + var13 / 2, var12, Block.wood.blockID, + this.woodMetadata); + } + } + + for (var10 = 0; var10 < var6; ++var10) { + var11 = par1World.getBlockId(par3, par4 + var10, par5); + + if (var11 == 0 || var11 == Block.leaves.blockID) { + this.setBlockAndMetadata(par1World, par3, par4 + var10, par5, Block.wood.blockID, + this.woodMetadata); + + if (var10 > 0) { + if (par2Random.nextInt(3) > 0 && par1World.isAirBlock(par3 - 1, par4 + var10, par5)) { + this.setBlockAndMetadata(par1World, par3 - 1, par4 + var10, par5, + Block.vine.blockID, 8); + } + + if (par2Random.nextInt(3) > 0 && par1World.isAirBlock(par3, par4 + var10, par5 - 1)) { + this.setBlockAndMetadata(par1World, par3, par4 + var10, par5 - 1, + Block.vine.blockID, 1); + } + } + } + + if (var10 < var6 - 1) { + var11 = par1World.getBlockId(par3 + 1, par4 + var10, par5); + + if (var11 == 0 || var11 == Block.leaves.blockID) { + this.setBlockAndMetadata(par1World, par3 + 1, par4 + var10, par5, Block.wood.blockID, + this.woodMetadata); + + if (var10 > 0) { + if (par2Random.nextInt(3) > 0 + && par1World.isAirBlock(par3 + 2, par4 + var10, par5)) { + this.setBlockAndMetadata(par1World, par3 + 2, par4 + var10, par5, + Block.vine.blockID, 2); + } + + if (par2Random.nextInt(3) > 0 + && par1World.isAirBlock(par3 + 1, par4 + var10, par5 - 1)) { + this.setBlockAndMetadata(par1World, par3 + 1, par4 + var10, par5 - 1, + Block.vine.blockID, 1); + } + } + } + + var11 = par1World.getBlockId(par3 + 1, par4 + var10, par5 + 1); + + if (var11 == 0 || var11 == Block.leaves.blockID) { + this.setBlockAndMetadata(par1World, par3 + 1, par4 + var10, par5 + 1, + Block.wood.blockID, this.woodMetadata); + + if (var10 > 0) { + if (par2Random.nextInt(3) > 0 + && par1World.isAirBlock(par3 + 2, par4 + var10, par5 + 1)) { + this.setBlockAndMetadata(par1World, par3 + 2, par4 + var10, par5 + 1, + Block.vine.blockID, 2); + } + + if (par2Random.nextInt(3) > 0 + && par1World.isAirBlock(par3 + 1, par4 + var10, par5 + 2)) { + this.setBlockAndMetadata(par1World, par3 + 1, par4 + var10, par5 + 2, + Block.vine.blockID, 4); + } + } + } + + var11 = par1World.getBlockId(par3, par4 + var10, par5 + 1); + + if (var11 == 0 || var11 == Block.leaves.blockID) { + this.setBlockAndMetadata(par1World, par3, par4 + var10, par5 + 1, Block.wood.blockID, + this.woodMetadata); + + if (var10 > 0) { + if (par2Random.nextInt(3) > 0 + && par1World.isAirBlock(par3 - 1, par4 + var10, par5 + 1)) { + this.setBlockAndMetadata(par1World, par3 - 1, par4 + var10, par5 + 1, + Block.vine.blockID, 8); + } + + if (par2Random.nextInt(3) > 0 + && par1World.isAirBlock(par3, par4 + var10, par5 + 2)) { + this.setBlockAndMetadata(par1World, par3, par4 + var10, par5 + 2, + Block.vine.blockID, 4); + } + } + } + } + } + + return true; + } else { + return false; + } + } + } else { + return false; + } + } + + private void growLeaves(World par1World, int par2, int par3, int par4, int par5, Random par6Random) { + byte var7 = 2; + + for (int var8 = par4 - var7; var8 <= par4; ++var8) { + int var9 = var8 - par4; + int var10 = par5 + 1 - var9; + + for (int var11 = par2 - var10; var11 <= par2 + var10 + 1; ++var11) { + int var12 = var11 - par2; + + for (int var13 = par3 - var10; var13 <= par3 + var10 + 1; ++var13) { + int var14 = var13 - par3; + + if ((var12 >= 0 || var14 >= 0 || var12 * var12 + var14 * var14 <= var10 * var10) + && (var12 <= 0 && var14 <= 0 || var12 * var12 + var14 * var14 <= (var10 + 1) * (var10 + 1)) + && (par6Random.nextInt(4) != 0 + || var12 * var12 + var14 * var14 <= (var10 - 1) * (var10 - 1))) { + int var15 = par1World.getBlockId(var11, var8, var13); + + if (var15 == 0 || var15 == Block.leaves.blockID) { + this.setBlockAndMetadata(par1World, var11, var8, var13, Block.leaves.blockID, + this.leavesMetadata); + } + } + } + } + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/WorldGenLakes.java b/sp-server/src/main/java/net/minecraft/src/WorldGenLakes.java new file mode 100644 index 0000000..31130e2 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/WorldGenLakes.java @@ -0,0 +1,151 @@ +package net.minecraft.src; + +import java.util.Random; + +public class WorldGenLakes extends WorldGenerator { + private int blockIndex; + + public WorldGenLakes(int par1) { + this.blockIndex = par1; + } + + public boolean generate(World par1World, Random par2Random, int par3, int par4, int par5) { + par3 -= 8; + + for (par5 -= 8; par4 > 5 && par1World.isAirBlock(par3, par4, par5); --par4) { + ; + } + + if (par4 <= 4) { + return false; + } else { + par4 -= 4; + boolean[] var6 = new boolean[2048]; + int var7 = par2Random.nextInt(4) + 4; + int var8; + + for (var8 = 0; var8 < var7; ++var8) { + double var9 = par2Random.nextDouble() * 6.0D + 3.0D; + double var11 = par2Random.nextDouble() * 4.0D + 2.0D; + double var13 = par2Random.nextDouble() * 6.0D + 3.0D; + double var15 = par2Random.nextDouble() * (16.0D - var9 - 2.0D) + 1.0D + var9 / 2.0D; + double var17 = par2Random.nextDouble() * (8.0D - var11 - 4.0D) + 2.0D + var11 / 2.0D; + double var19 = par2Random.nextDouble() * (16.0D - var13 - 2.0D) + 1.0D + var13 / 2.0D; + + for (int var21 = 1; var21 < 15; ++var21) { + for (int var22 = 1; var22 < 15; ++var22) { + for (int var23 = 1; var23 < 7; ++var23) { + double var24 = ((double) var21 - var15) / (var9 / 2.0D); + double var26 = ((double) var23 - var17) / (var11 / 2.0D); + double var28 = ((double) var22 - var19) / (var13 / 2.0D); + double var30 = var24 * var24 + var26 * var26 + var28 * var28; + + if (var30 < 1.0D) { + var6[(var21 * 16 + var22) * 8 + var23] = true; + } + } + } + } + } + + int var10; + int var32; + boolean var33; + + for (var8 = 0; var8 < 16; ++var8) { + for (var32 = 0; var32 < 16; ++var32) { + for (var10 = 0; var10 < 8; ++var10) { + var33 = !var6[(var8 * 16 + var32) * 8 + var10] + && (var8 < 15 && var6[((var8 + 1) * 16 + var32) * 8 + var10] + || var8 > 0 && var6[((var8 - 1) * 16 + var32) * 8 + var10] + || var32 < 15 && var6[(var8 * 16 + var32 + 1) * 8 + var10] + || var32 > 0 && var6[(var8 * 16 + (var32 - 1)) * 8 + var10] + || var10 < 7 && var6[(var8 * 16 + var32) * 8 + var10 + 1] + || var10 > 0 && var6[(var8 * 16 + var32) * 8 + (var10 - 1)]); + + if (var33) { + Material var12 = par1World.getBlockMaterial(par3 + var8, par4 + var10, par5 + var32); + + if (var10 >= 4 && var12.isLiquid()) { + return false; + } + + if (var10 < 4 && !var12.isSolid() && par1World.getBlockId(par3 + var8, par4 + var10, + par5 + var32) != this.blockIndex) { + return false; + } + } + } + } + } + + for (var8 = 0; var8 < 16; ++var8) { + for (var32 = 0; var32 < 16; ++var32) { + for (var10 = 0; var10 < 8; ++var10) { + if (var6[(var8 * 16 + var32) * 8 + var10]) { + par1World.setBlock(par3 + var8, par4 + var10, par5 + var32, + var10 >= 4 ? 0 : this.blockIndex, 0, 2); + } + } + } + } + + for (var8 = 0; var8 < 16; ++var8) { + for (var32 = 0; var32 < 16; ++var32) { + for (var10 = 4; var10 < 8; ++var10) { + if (var6[(var8 * 16 + var32) * 8 + var10] + && par1World.getBlockId(par3 + var8, par4 + var10 - 1, + par5 + var32) == Block.dirt.blockID + && par1World.getSavedLightValue(EnumSkyBlock.Sky, par3 + var8, par4 + var10, + par5 + var32) > 0) { + BiomeGenBase var34 = par1World.getBiomeGenForCoords(par3 + var8, par5 + var32); + + if (var34.topBlock == Block.mycelium.blockID) { + par1World.setBlock(par3 + var8, par4 + var10 - 1, par5 + var32, Block.mycelium.blockID, + 0, 2); + } else { + par1World.setBlock(par3 + var8, par4 + var10 - 1, par5 + var32, Block.grass.blockID, 0, + 2); + } + } + } + } + } + + if (Block.blocksList[this.blockIndex].blockMaterial == Material.lava) { + for (var8 = 0; var8 < 16; ++var8) { + for (var32 = 0; var32 < 16; ++var32) { + for (var10 = 0; var10 < 8; ++var10) { + var33 = !var6[(var8 * 16 + var32) * 8 + var10] + && (var8 < 15 && var6[((var8 + 1) * 16 + var32) * 8 + var10] + || var8 > 0 && var6[((var8 - 1) * 16 + var32) * 8 + var10] + || var32 < 15 && var6[(var8 * 16 + var32 + 1) * 8 + var10] + || var32 > 0 && var6[(var8 * 16 + (var32 - 1)) * 8 + var10] + || var10 < 7 && var6[(var8 * 16 + var32) * 8 + var10 + 1] + || var10 > 0 && var6[(var8 * 16 + var32) * 8 + (var10 - 1)]); + + if (var33 && (var10 < 4 || par2Random.nextInt(2) != 0) + && par1World.getBlockMaterial(par3 + var8, par4 + var10, par5 + var32).isSolid()) { + par1World.setBlock(par3 + var8, par4 + var10, par5 + var32, Block.stone.blockID, 0, 2); + } + } + } + } + } + + if (Block.blocksList[this.blockIndex].blockMaterial == Material.water) { + for (var8 = 0; var8 < 16; ++var8) { + for (var32 = 0; var32 < 16; ++var32) { + byte var35 = 4; + + if (par1World.isBlockFreezable(par3 + var8, par4 + var35, par5 + var32)) { + par1World.setBlock(par3 + var8, par4 + var35, par5 + var32, Block.ice.blockID, 0, 2); + } + } + } + } + + return true; + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/WorldGenLiquids.java b/sp-server/src/main/java/net/minecraft/src/WorldGenLiquids.java new file mode 100644 index 0000000..c23411f --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/WorldGenLiquids.java @@ -0,0 +1,68 @@ +package net.minecraft.src; + +import java.util.Random; + +public class WorldGenLiquids extends WorldGenerator { + /** The ID of the liquid block used in this liquid generator. */ + private int liquidBlockId; + + public WorldGenLiquids(int par1) { + this.liquidBlockId = par1; + } + + public boolean generate(World par1World, Random par2Random, int par3, int par4, int par5) { + if (par1World.getBlockId(par3, par4 + 1, par5) != Block.stone.blockID) { + return false; + } else if (par1World.getBlockId(par3, par4 - 1, par5) != Block.stone.blockID) { + return false; + } else if (par1World.getBlockId(par3, par4, par5) != 0 + && par1World.getBlockId(par3, par4, par5) != Block.stone.blockID) { + return false; + } else { + int var6 = 0; + + if (par1World.getBlockId(par3 - 1, par4, par5) == Block.stone.blockID) { + ++var6; + } + + if (par1World.getBlockId(par3 + 1, par4, par5) == Block.stone.blockID) { + ++var6; + } + + if (par1World.getBlockId(par3, par4, par5 - 1) == Block.stone.blockID) { + ++var6; + } + + if (par1World.getBlockId(par3, par4, par5 + 1) == Block.stone.blockID) { + ++var6; + } + + int var7 = 0; + + if (par1World.isAirBlock(par3 - 1, par4, par5)) { + ++var7; + } + + if (par1World.isAirBlock(par3 + 1, par4, par5)) { + ++var7; + } + + if (par1World.isAirBlock(par3, par4, par5 - 1)) { + ++var7; + } + + if (par1World.isAirBlock(par3, par4, par5 + 1)) { + ++var7; + } + + if (var6 == 3 && var7 == 1) { + par1World.setBlock(par3, par4, par5, this.liquidBlockId, 0, 2); + par1World.scheduledUpdatesAreImmediate = true; + Block.blocksList[this.liquidBlockId].updateTick(par1World, par3, par4, par5, par2Random); + par1World.scheduledUpdatesAreImmediate = false; + } + + return true; + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/WorldGenMinable.java b/sp-server/src/main/java/net/minecraft/src/WorldGenMinable.java new file mode 100644 index 0000000..01e7742 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/WorldGenMinable.java @@ -0,0 +1,72 @@ +package net.minecraft.src; + +import java.util.Random; + +public class WorldGenMinable extends WorldGenerator { + /** The block ID of the ore to be placed using this generator. */ + private int minableBlockId; + + /** The number of blocks to generate. */ + private int numberOfBlocks; + private int field_94523_c; + + public WorldGenMinable(int par1, int par2) { + this(par1, par2, Block.stone.blockID); + } + + public WorldGenMinable(int par1, int par2, int par3) { + this.minableBlockId = par1; + this.numberOfBlocks = par2; + this.field_94523_c = par3; + } + + public boolean generate(World par1World, Random par2Random, int par3, int par4, int par5) { + float var6 = par2Random.nextFloat() * (float) Math.PI; + double var7 = (double) ((float) (par3 + 8) + MathHelper.sin(var6) * (float) this.numberOfBlocks / 8.0F); + double var9 = (double) ((float) (par3 + 8) - MathHelper.sin(var6) * (float) this.numberOfBlocks / 8.0F); + double var11 = (double) ((float) (par5 + 8) + MathHelper.cos(var6) * (float) this.numberOfBlocks / 8.0F); + double var13 = (double) ((float) (par5 + 8) - MathHelper.cos(var6) * (float) this.numberOfBlocks / 8.0F); + double var15 = (double) (par4 + par2Random.nextInt(3) - 2); + double var17 = (double) (par4 + par2Random.nextInt(3) - 2); + + for (int var19 = 0; var19 <= this.numberOfBlocks; ++var19) { + double var20 = var7 + (var9 - var7) * (double) var19 / (double) this.numberOfBlocks; + double var22 = var15 + (var17 - var15) * (double) var19 / (double) this.numberOfBlocks; + double var24 = var11 + (var13 - var11) * (double) var19 / (double) this.numberOfBlocks; + double var26 = par2Random.nextDouble() * (double) this.numberOfBlocks / 16.0D; + double var28 = (double) (MathHelper.sin((float) var19 * (float) Math.PI / (float) this.numberOfBlocks) + + 1.0F) * var26 + 1.0D; + double var30 = (double) (MathHelper.sin((float) var19 * (float) Math.PI / (float) this.numberOfBlocks) + + 1.0F) * var26 + 1.0D; + int var32 = MathHelper.floor_double(var20 - var28 / 2.0D); + int var33 = MathHelper.floor_double(var22 - var30 / 2.0D); + int var34 = MathHelper.floor_double(var24 - var28 / 2.0D); + int var35 = MathHelper.floor_double(var20 + var28 / 2.0D); + int var36 = MathHelper.floor_double(var22 + var30 / 2.0D); + int var37 = MathHelper.floor_double(var24 + var28 / 2.0D); + + for (int var38 = var32; var38 <= var35; ++var38) { + double var39 = ((double) var38 + 0.5D - var20) / (var28 / 2.0D); + + if (var39 * var39 < 1.0D) { + for (int var41 = var33; var41 <= var36; ++var41) { + double var42 = ((double) var41 + 0.5D - var22) / (var30 / 2.0D); + + if (var39 * var39 + var42 * var42 < 1.0D) { + for (int var44 = var34; var44 <= var37; ++var44) { + double var45 = ((double) var44 + 0.5D - var24) / (var28 / 2.0D); + + if (var39 * var39 + var42 * var42 + var45 * var45 < 1.0D + && par1World.getBlockId(var38, var41, var44) == this.field_94523_c) { + par1World.setBlock(var38, var41, var44, this.minableBlockId, 0, 2); + } + } + } + } + } + } + } + + return true; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/WorldGenPumpkin.java b/sp-server/src/main/java/net/minecraft/src/WorldGenPumpkin.java new file mode 100644 index 0000000..82fb7c5 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/WorldGenPumpkin.java @@ -0,0 +1,21 @@ +package net.minecraft.src; + +import java.util.Random; + +public class WorldGenPumpkin extends WorldGenerator { + public boolean generate(World par1World, Random par2Random, int par3, int par4, int par5) { + for (int var6 = 0; var6 < 64; ++var6) { + int var7 = par3 + par2Random.nextInt(8) - par2Random.nextInt(8); + int var8 = par4 + par2Random.nextInt(4) - par2Random.nextInt(4); + int var9 = par5 + par2Random.nextInt(8) - par2Random.nextInt(8); + + if (par1World.isAirBlock(var7, var8, var9) + && par1World.getBlockId(var7, var8 - 1, var9) == Block.grass.blockID + && Block.pumpkin.canPlaceBlockAt(par1World, var7, var8, var9)) { + par1World.setBlock(var7, var8, var9, Block.pumpkin.blockID, par2Random.nextInt(4), 2); + } + } + + return true; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/WorldGenReed.java b/sp-server/src/main/java/net/minecraft/src/WorldGenReed.java new file mode 100644 index 0000000..5a68d5a --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/WorldGenReed.java @@ -0,0 +1,29 @@ +package net.minecraft.src; + +import java.util.Random; + +public class WorldGenReed extends WorldGenerator { + public boolean generate(World par1World, Random par2Random, int par3, int par4, int par5) { + for (int var6 = 0; var6 < 20; ++var6) { + int var7 = par3 + par2Random.nextInt(4) - par2Random.nextInt(4); + int var8 = par4; + int var9 = par5 + par2Random.nextInt(4) - par2Random.nextInt(4); + + if (par1World.isAirBlock(var7, par4, var9) + && (par1World.getBlockMaterial(var7 - 1, par4 - 1, var9) == Material.water + || par1World.getBlockMaterial(var7 + 1, par4 - 1, var9) == Material.water + || par1World.getBlockMaterial(var7, par4 - 1, var9 - 1) == Material.water + || par1World.getBlockMaterial(var7, par4 - 1, var9 + 1) == Material.water)) { + int var10 = 2 + par2Random.nextInt(par2Random.nextInt(3) + 1); + + for (int var11 = 0; var11 < var10; ++var11) { + if (Block.reed.canBlockStay(par1World, var7, var8 + var11, var9)) { + par1World.setBlock(var7, var8 + var11, var9, Block.reed.blockID, 0, 2); + } + } + } + } + + return true; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/WorldGenSand.java b/sp-server/src/main/java/net/minecraft/src/WorldGenSand.java new file mode 100644 index 0000000..4651223 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/WorldGenSand.java @@ -0,0 +1,44 @@ +package net.minecraft.src; + +import java.util.Random; + +public class WorldGenSand extends WorldGenerator { + /** Stores ID for WorldGenSand */ + private int sandID; + + /** The maximum radius used when generating a patch of blocks. */ + private int radius; + + public WorldGenSand(int par1, int par2) { + this.sandID = par2; + this.radius = par1; + } + + public boolean generate(World par1World, Random par2Random, int par3, int par4, int par5) { + if (par1World.getBlockMaterial(par3, par4, par5) != Material.water) { + return false; + } else { + int var6 = par2Random.nextInt(this.radius - 2) + 2; + byte var7 = 2; + + for (int var8 = par3 - var6; var8 <= par3 + var6; ++var8) { + for (int var9 = par5 - var6; var9 <= par5 + var6; ++var9) { + int var10 = var8 - par3; + int var11 = var9 - par5; + + if (var10 * var10 + var11 * var11 <= var6 * var6) { + for (int var12 = par4 - var7; var12 <= par4 + var7; ++var12) { + int var13 = par1World.getBlockId(var8, var12, var9); + + if (var13 == Block.dirt.blockID || var13 == Block.grass.blockID) { + par1World.setBlock(var8, var12, var9, this.sandID, 0, 2); + } + } + } + } + } + + return true; + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/WorldGenShrub.java b/sp-server/src/main/java/net/minecraft/src/WorldGenShrub.java new file mode 100644 index 0000000..a221be5 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/WorldGenShrub.java @@ -0,0 +1,50 @@ +package net.minecraft.src; + +import java.util.Random; + +public class WorldGenShrub extends WorldGenerator { + private int field_76527_a; + private int field_76526_b; + + public WorldGenShrub(int par1, int par2) { + this.field_76526_b = par1; + this.field_76527_a = par2; + } + + public boolean generate(World par1World, Random par2Random, int par3, int par4, int par5) { + int var15; + + for (boolean var6 = false; ((var15 = par1World.getBlockId(par3, par4, par5)) == 0 + || var15 == Block.leaves.blockID) && par4 > 0; --par4) { + ; + } + + int var7 = par1World.getBlockId(par3, par4, par5); + + if (var7 == Block.dirt.blockID || var7 == Block.grass.blockID) { + ++par4; + this.setBlockAndMetadata(par1World, par3, par4, par5, Block.wood.blockID, this.field_76526_b); + + for (int var8 = par4; var8 <= par4 + 2; ++var8) { + int var9 = var8 - par4; + int var10 = 2 - var9; + + for (int var11 = par3 - var10; var11 <= par3 + var10; ++var11) { + int var12 = var11 - par3; + + for (int var13 = par5 - var10; var13 <= par5 + var10; ++var13) { + int var14 = var13 - par5; + + if ((Math.abs(var12) != var10 || Math.abs(var14) != var10 || par2Random.nextInt(2) != 0) + && !Block.opaqueCubeLookup[par1World.getBlockId(var11, var8, var13)]) { + this.setBlockAndMetadata(par1World, var11, var8, var13, Block.leaves.blockID, + this.field_76527_a); + } + } + } + } + } + + return true; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/WorldGenSpikes.java b/sp-server/src/main/java/net/minecraft/src/WorldGenSpikes.java new file mode 100644 index 0000000..d04dc82 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/WorldGenSpikes.java @@ -0,0 +1,60 @@ +package net.minecraft.src; + +import java.util.Random; + +public class WorldGenSpikes extends WorldGenerator { + /** + * The Block ID that the generator is allowed to replace while generating the + * terrain. + */ + private int replaceID; + + public WorldGenSpikes(int par1) { + this.replaceID = par1; + } + + public boolean generate(World par1World, Random par2Random, int par3, int par4, int par5) { + if (par1World.isAirBlock(par3, par4, par5) && par1World.getBlockId(par3, par4 - 1, par5) == this.replaceID) { + int var6 = par2Random.nextInt(32) + 6; + int var7 = par2Random.nextInt(4) + 1; + int var8; + int var9; + int var10; + int var11; + + for (var8 = par3 - var7; var8 <= par3 + var7; ++var8) { + for (var9 = par5 - var7; var9 <= par5 + var7; ++var9) { + var10 = var8 - par3; + var11 = var9 - par5; + + if (var10 * var10 + var11 * var11 <= var7 * var7 + 1 + && par1World.getBlockId(var8, par4 - 1, var9) != this.replaceID) { + return false; + } + } + } + + for (var8 = par4; var8 < par4 + var6 && var8 < 128; ++var8) { + for (var9 = par3 - var7; var9 <= par3 + var7; ++var9) { + for (var10 = par5 - var7; var10 <= par5 + var7; ++var10) { + var11 = var9 - par3; + int var12 = var10 - par5; + + if (var11 * var11 + var12 * var12 <= var7 * var7 + 1) { + par1World.setBlock(var9, var8, var10, Block.obsidian.blockID, 0, 2); + } + } + } + } + + EntityEnderCrystal var13 = new EntityEnderCrystal(par1World); + var13.setLocationAndAngles((double) ((float) par3 + 0.5F), (double) (par4 + var6), + (double) ((float) par5 + 0.5F), par2Random.nextFloat() * 360.0F, 0.0F); + par1World.spawnEntityInWorld(var13); + par1World.setBlock(par3, par4 + var6, par5, Block.bedrock.blockID, 0, 2); + return true; + } else { + return false; + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/WorldGenSwamp.java b/sp-server/src/main/java/net/minecraft/src/WorldGenSwamp.java new file mode 100644 index 0000000..9c5b85f --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/WorldGenSwamp.java @@ -0,0 +1,149 @@ +package net.minecraft.src; + +import java.util.Random; + +public class WorldGenSwamp extends WorldGenerator { + public boolean generate(World par1World, Random par2Random, int par3, int par4, int par5) { + int var6; + + for (var6 = par2Random.nextInt(4) + 5; par1World.getBlockMaterial(par3, par4 - 1, + par5) == Material.water; --par4) { + ; + } + + boolean var7 = true; + + if (par4 >= 1 && par4 + var6 + 1 <= 128) { + int var8; + int var10; + int var11; + int var12; + + for (var8 = par4; var8 <= par4 + 1 + var6; ++var8) { + byte var9 = 1; + + if (var8 == par4) { + var9 = 0; + } + + if (var8 >= par4 + 1 + var6 - 2) { + var9 = 3; + } + + for (var10 = par3 - var9; var10 <= par3 + var9 && var7; ++var10) { + for (var11 = par5 - var9; var11 <= par5 + var9 && var7; ++var11) { + if (var8 >= 0 && var8 < 128) { + var12 = par1World.getBlockId(var10, var8, var11); + + if (var12 != 0 && var12 != Block.leaves.blockID) { + if (var12 != Block.waterStill.blockID && var12 != Block.waterMoving.blockID) { + var7 = false; + } else if (var8 > par4) { + var7 = false; + } + } + } else { + var7 = false; + } + } + } + } + + if (!var7) { + return false; + } else { + var8 = par1World.getBlockId(par3, par4 - 1, par5); + + if ((var8 == Block.grass.blockID || var8 == Block.dirt.blockID) && par4 < 128 - var6 - 1) { + this.setBlock(par1World, par3, par4 - 1, par5, Block.dirt.blockID); + int var13; + int var16; + + for (var16 = par4 - 3 + var6; var16 <= par4 + var6; ++var16) { + var10 = var16 - (par4 + var6); + var11 = 2 - var10 / 2; + + for (var12 = par3 - var11; var12 <= par3 + var11; ++var12) { + var13 = var12 - par3; + + for (int var14 = par5 - var11; var14 <= par5 + var11; ++var14) { + int var15 = var14 - par5; + + if ((Math.abs(var13) != var11 || Math.abs(var15) != var11 + || par2Random.nextInt(2) != 0 && var10 != 0) + && !Block.opaqueCubeLookup[par1World.getBlockId(var12, var16, var14)]) { + this.setBlock(par1World, var12, var16, var14, Block.leaves.blockID); + } + } + } + } + + for (var16 = 0; var16 < var6; ++var16) { + var10 = par1World.getBlockId(par3, par4 + var16, par5); + + if (var10 == 0 || var10 == Block.leaves.blockID || var10 == Block.waterMoving.blockID + || var10 == Block.waterStill.blockID) { + this.setBlock(par1World, par3, par4 + var16, par5, Block.wood.blockID); + } + } + + for (var16 = par4 - 3 + var6; var16 <= par4 + var6; ++var16) { + var10 = var16 - (par4 + var6); + var11 = 2 - var10 / 2; + + for (var12 = par3 - var11; var12 <= par3 + var11; ++var12) { + for (var13 = par5 - var11; var13 <= par5 + var11; ++var13) { + if (par1World.getBlockId(var12, var16, var13) == Block.leaves.blockID) { + if (par2Random.nextInt(4) == 0 + && par1World.getBlockId(var12 - 1, var16, var13) == 0) { + this.generateVines(par1World, var12 - 1, var16, var13, 8); + } + + if (par2Random.nextInt(4) == 0 + && par1World.getBlockId(var12 + 1, var16, var13) == 0) { + this.generateVines(par1World, var12 + 1, var16, var13, 2); + } + + if (par2Random.nextInt(4) == 0 + && par1World.getBlockId(var12, var16, var13 - 1) == 0) { + this.generateVines(par1World, var12, var16, var13 - 1, 1); + } + + if (par2Random.nextInt(4) == 0 + && par1World.getBlockId(var12, var16, var13 + 1) == 0) { + this.generateVines(par1World, var12, var16, var13 + 1, 4); + } + } + } + } + } + + return true; + } else { + return false; + } + } + } else { + return false; + } + } + + /** + * Generates vines at the given position until it hits a block. + */ + private void generateVines(World par1World, int par2, int par3, int par4, int par5) { + this.setBlockAndMetadata(par1World, par2, par3, par4, Block.vine.blockID, par5); + int var6 = 4; + + while (true) { + --par3; + + if (par1World.getBlockId(par2, par3, par4) != 0 || var6 <= 0) { + return; + } + + this.setBlockAndMetadata(par1World, par2, par3, par4, Block.vine.blockID, par5); + --var6; + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/WorldGenTaiga1.java b/sp-server/src/main/java/net/minecraft/src/WorldGenTaiga1.java new file mode 100644 index 0000000..f7e9ae5 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/WorldGenTaiga1.java @@ -0,0 +1,91 @@ +package net.minecraft.src; + +import java.util.Random; + +public class WorldGenTaiga1 extends WorldGenerator { + public boolean generate(World par1World, Random par2Random, int par3, int par4, int par5) { + int var6 = par2Random.nextInt(5) + 7; + int var7 = var6 - par2Random.nextInt(2) - 3; + int var8 = var6 - var7; + int var9 = 1 + par2Random.nextInt(var8 + 1); + boolean var10 = true; + + if (par4 >= 1 && par4 + var6 + 1 <= 128) { + int var11; + int var13; + int var14; + int var15; + int var18; + + for (var11 = par4; var11 <= par4 + 1 + var6 && var10; ++var11) { + boolean var12 = true; + + if (var11 - par4 < var7) { + var18 = 0; + } else { + var18 = var9; + } + + for (var13 = par3 - var18; var13 <= par3 + var18 && var10; ++var13) { + for (var14 = par5 - var18; var14 <= par5 + var18 && var10; ++var14) { + if (var11 >= 0 && var11 < 128) { + var15 = par1World.getBlockId(var13, var11, var14); + + if (var15 != 0 && var15 != Block.leaves.blockID) { + var10 = false; + } + } else { + var10 = false; + } + } + } + } + + if (!var10) { + return false; + } else { + var11 = par1World.getBlockId(par3, par4 - 1, par5); + + if ((var11 == Block.grass.blockID || var11 == Block.dirt.blockID) && par4 < 128 - var6 - 1) { + this.setBlock(par1World, par3, par4 - 1, par5, Block.dirt.blockID); + var18 = 0; + + for (var13 = par4 + var6; var13 >= par4 + var7; --var13) { + for (var14 = par3 - var18; var14 <= par3 + var18; ++var14) { + var15 = var14 - par3; + + for (int var16 = par5 - var18; var16 <= par5 + var18; ++var16) { + int var17 = var16 - par5; + + if ((Math.abs(var15) != var18 || Math.abs(var17) != var18 || var18 <= 0) + && !Block.opaqueCubeLookup[par1World.getBlockId(var14, var13, var16)]) { + this.setBlockAndMetadata(par1World, var14, var13, var16, Block.leaves.blockID, 1); + } + } + } + + if (var18 >= 1 && var13 == par4 + var7 + 1) { + --var18; + } else if (var18 < var9) { + ++var18; + } + } + + for (var13 = 0; var13 < var6 - 1; ++var13) { + var14 = par1World.getBlockId(par3, par4 + var13, par5); + + if (var14 == 0 || var14 == Block.leaves.blockID) { + this.setBlockAndMetadata(par1World, par3, par4 + var13, par5, Block.wood.blockID, 1); + } + } + + return true; + } else { + return false; + } + } + } else { + return false; + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/WorldGenTaiga2.java b/sp-server/src/main/java/net/minecraft/src/WorldGenTaiga2.java new file mode 100644 index 0000000..1fc4991 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/WorldGenTaiga2.java @@ -0,0 +1,108 @@ +package net.minecraft.src; + +import java.util.Random; + +public class WorldGenTaiga2 extends WorldGenerator { + public WorldGenTaiga2(boolean par1) { + super(par1); + } + + public boolean generate(World par1World, Random par2Random, int par3, int par4, int par5) { + int var6 = par2Random.nextInt(4) + 6; + int var7 = 1 + par2Random.nextInt(2); + int var8 = var6 - var7; + int var9 = 2 + par2Random.nextInt(2); + boolean var10 = true; + + if (par4 >= 1 && par4 + var6 + 1 <= 256) { + int var11; + int var13; + int var15; + int var21; + + for (var11 = par4; var11 <= par4 + 1 + var6 && var10; ++var11) { + boolean var12 = true; + + if (var11 - par4 < var7) { + var21 = 0; + } else { + var21 = var9; + } + + for (var13 = par3 - var21; var13 <= par3 + var21 && var10; ++var13) { + for (int var14 = par5 - var21; var14 <= par5 + var21 && var10; ++var14) { + if (var11 >= 0 && var11 < 256) { + var15 = par1World.getBlockId(var13, var11, var14); + + if (var15 != 0 && var15 != Block.leaves.blockID) { + var10 = false; + } + } else { + var10 = false; + } + } + } + } + + if (!var10) { + return false; + } else { + var11 = par1World.getBlockId(par3, par4 - 1, par5); + + if ((var11 == Block.grass.blockID || var11 == Block.dirt.blockID) && par4 < 256 - var6 - 1) { + this.setBlock(par1World, par3, par4 - 1, par5, Block.dirt.blockID); + var21 = par2Random.nextInt(2); + var13 = 1; + byte var22 = 0; + int var16; + int var17; + + for (var15 = 0; var15 <= var8; ++var15) { + var16 = par4 + var6 - var15; + + for (var17 = par3 - var21; var17 <= par3 + var21; ++var17) { + int var18 = var17 - par3; + + for (int var19 = par5 - var21; var19 <= par5 + var21; ++var19) { + int var20 = var19 - par5; + + if ((Math.abs(var18) != var21 || Math.abs(var20) != var21 || var21 <= 0) + && !Block.opaqueCubeLookup[par1World.getBlockId(var17, var16, var19)]) { + this.setBlockAndMetadata(par1World, var17, var16, var19, Block.leaves.blockID, 1); + } + } + } + + if (var21 >= var13) { + var21 = var22; + var22 = 1; + ++var13; + + if (var13 > var9) { + var13 = var9; + } + } else { + ++var21; + } + } + + var15 = par2Random.nextInt(3); + + for (var16 = 0; var16 < var6 - var15; ++var16) { + var17 = par1World.getBlockId(par3, par4 + var16, par5); + + if (var17 == 0 || var17 == Block.leaves.blockID) { + this.setBlockAndMetadata(par1World, par3, par4 + var16, par5, Block.wood.blockID, 1); + } + } + + return true; + } else { + return false; + } + } + } else { + return false; + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/WorldGenTallGrass.java b/sp-server/src/main/java/net/minecraft/src/WorldGenTallGrass.java new file mode 100644 index 0000000..793090b --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/WorldGenTallGrass.java @@ -0,0 +1,36 @@ +package net.minecraft.src; + +import java.util.Random; + +public class WorldGenTallGrass extends WorldGenerator { + /** Stores ID for WorldGenTallGrass */ + private int tallGrassID; + private int tallGrassMetadata; + + public WorldGenTallGrass(int par1, int par2) { + this.tallGrassID = par1; + this.tallGrassMetadata = par2; + } + + public boolean generate(World par1World, Random par2Random, int par3, int par4, int par5) { + int var11; + + for (boolean var6 = false; ((var11 = par1World.getBlockId(par3, par4, par5)) == 0 + || var11 == Block.leaves.blockID) && par4 > 0; --par4) { + ; + } + + for (int var7 = 0; var7 < 128; ++var7) { + int var8 = par3 + par2Random.nextInt(8) - par2Random.nextInt(8); + int var9 = par4 + par2Random.nextInt(4) - par2Random.nextInt(4); + int var10 = par5 + par2Random.nextInt(8) - par2Random.nextInt(8); + + if (par1World.isAirBlock(var8, var9, var10) + && Block.blocksList[this.tallGrassID].canBlockStay(par1World, var8, var9, var10)) { + par1World.setBlock(var8, var9, var10, this.tallGrassID, this.tallGrassMetadata, 2); + } + } + + return true; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/WorldGenTrees.java b/sp-server/src/main/java/net/minecraft/src/WorldGenTrees.java new file mode 100644 index 0000000..915bb05 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/WorldGenTrees.java @@ -0,0 +1,211 @@ +package net.minecraft.src; + +import java.util.Random; + +public class WorldGenTrees extends WorldGenerator { + /** The minimum height of a generated tree. */ + private final int minTreeHeight; + + /** True if this tree should grow Vines. */ + private final boolean vinesGrow; + + /** The metadata value of the wood to use in tree generation. */ + private final int metaWood; + + /** The metadata value of the leaves to use in tree generation. */ + private final int metaLeaves; + + public WorldGenTrees(boolean par1) { + this(par1, 4, 0, 0, false); + } + + public WorldGenTrees(boolean par1, int par2, int par3, int par4, boolean par5) { + super(par1); + this.minTreeHeight = par2; + this.metaWood = par3; + this.metaLeaves = par4; + this.vinesGrow = par5; + } + + public boolean generate(World par1World, Random par2Random, int par3, int par4, int par5) { + int var6 = par2Random.nextInt(3) + this.minTreeHeight; + boolean var7 = true; + + if (par4 >= 1 && par4 + var6 + 1 <= 256) { + int var8; + byte var9; + int var11; + int var12; + + for (var8 = par4; var8 <= par4 + 1 + var6; ++var8) { + var9 = 1; + + if (var8 == par4) { + var9 = 0; + } + + if (var8 >= par4 + 1 + var6 - 2) { + var9 = 2; + } + + for (int var10 = par3 - var9; var10 <= par3 + var9 && var7; ++var10) { + for (var11 = par5 - var9; var11 <= par5 + var9 && var7; ++var11) { + if (var8 >= 0 && var8 < 256) { + var12 = par1World.getBlockId(var10, var8, var11); + + if (var12 != 0 && var12 != Block.leaves.blockID && var12 != Block.grass.blockID + && var12 != Block.dirt.blockID && var12 != Block.wood.blockID) { + var7 = false; + } + } else { + var7 = false; + } + } + } + } + + if (!var7) { + return false; + } else { + var8 = par1World.getBlockId(par3, par4 - 1, par5); + + if ((var8 == Block.grass.blockID || var8 == Block.dirt.blockID) && par4 < 256 - var6 - 1) { + this.setBlock(par1World, par3, par4 - 1, par5, Block.dirt.blockID); + var9 = 3; + byte var19 = 0; + int var13; + int var14; + int var15; + + for (var11 = par4 - var9 + var6; var11 <= par4 + var6; ++var11) { + var12 = var11 - (par4 + var6); + var13 = var19 + 1 - var12 / 2; + + for (var14 = par3 - var13; var14 <= par3 + var13; ++var14) { + var15 = var14 - par3; + + for (int var16 = par5 - var13; var16 <= par5 + var13; ++var16) { + int var17 = var16 - par5; + + if (Math.abs(var15) != var13 || Math.abs(var17) != var13 + || par2Random.nextInt(2) != 0 && var12 != 0) { + int var18 = par1World.getBlockId(var14, var11, var16); + + if (var18 == 0 || var18 == Block.leaves.blockID) { + this.setBlockAndMetadata(par1World, var14, var11, var16, Block.leaves.blockID, + this.metaLeaves); + } + } + } + } + } + + for (var11 = 0; var11 < var6; ++var11) { + var12 = par1World.getBlockId(par3, par4 + var11, par5); + + if (var12 == 0 || var12 == Block.leaves.blockID) { + this.setBlockAndMetadata(par1World, par3, par4 + var11, par5, Block.wood.blockID, + this.metaWood); + + if (this.vinesGrow && var11 > 0) { + if (par2Random.nextInt(3) > 0 && par1World.isAirBlock(par3 - 1, par4 + var11, par5)) { + this.setBlockAndMetadata(par1World, par3 - 1, par4 + var11, par5, + Block.vine.blockID, 8); + } + + if (par2Random.nextInt(3) > 0 && par1World.isAirBlock(par3 + 1, par4 + var11, par5)) { + this.setBlockAndMetadata(par1World, par3 + 1, par4 + var11, par5, + Block.vine.blockID, 2); + } + + if (par2Random.nextInt(3) > 0 && par1World.isAirBlock(par3, par4 + var11, par5 - 1)) { + this.setBlockAndMetadata(par1World, par3, par4 + var11, par5 - 1, + Block.vine.blockID, 1); + } + + if (par2Random.nextInt(3) > 0 && par1World.isAirBlock(par3, par4 + var11, par5 + 1)) { + this.setBlockAndMetadata(par1World, par3, par4 + var11, par5 + 1, + Block.vine.blockID, 4); + } + } + } + } + + if (this.vinesGrow) { + for (var11 = par4 - 3 + var6; var11 <= par4 + var6; ++var11) { + var12 = var11 - (par4 + var6); + var13 = 2 - var12 / 2; + + for (var14 = par3 - var13; var14 <= par3 + var13; ++var14) { + for (var15 = par5 - var13; var15 <= par5 + var13; ++var15) { + if (par1World.getBlockId(var14, var11, var15) == Block.leaves.blockID) { + if (par2Random.nextInt(4) == 0 + && par1World.getBlockId(var14 - 1, var11, var15) == 0) { + this.growVines(par1World, var14 - 1, var11, var15, 8); + } + + if (par2Random.nextInt(4) == 0 + && par1World.getBlockId(var14 + 1, var11, var15) == 0) { + this.growVines(par1World, var14 + 1, var11, var15, 2); + } + + if (par2Random.nextInt(4) == 0 + && par1World.getBlockId(var14, var11, var15 - 1) == 0) { + this.growVines(par1World, var14, var11, var15 - 1, 1); + } + + if (par2Random.nextInt(4) == 0 + && par1World.getBlockId(var14, var11, var15 + 1) == 0) { + this.growVines(par1World, var14, var11, var15 + 1, 4); + } + } + } + } + } + + if (par2Random.nextInt(5) == 0 && var6 > 5) { + for (var11 = 0; var11 < 2; ++var11) { + for (var12 = 0; var12 < 4; ++var12) { + if (par2Random.nextInt(4 - var11) == 0) { + var13 = par2Random.nextInt(3); + this.setBlockAndMetadata(par1World, + par3 + Direction.offsetX[Direction.footInvisibleFaceRemap[var12]], + par4 + var6 - 5 + var11, + par5 + Direction.offsetZ[Direction.footInvisibleFaceRemap[var12]], + Block.cocoaPlant.blockID, var13 << 2 | var12); + } + } + } + } + } + + return true; + } else { + return false; + } + } + } else { + return false; + } + } + + /** + * Grows vines downward from the given block for a given length. Args: World, x, + * starty, z, vine-length + */ + private void growVines(World par1World, int par2, int par3, int par4, int par5) { + this.setBlockAndMetadata(par1World, par2, par3, par4, Block.vine.blockID, par5); + int var6 = 4; + + while (true) { + --par3; + + if (par1World.getBlockId(par2, par3, par4) != 0 || var6 <= 0) { + return; + } + + this.setBlockAndMetadata(par1World, par2, par3, par4, Block.vine.blockID, par5); + --var6; + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/WorldGenVines.java b/sp-server/src/main/java/net/minecraft/src/WorldGenVines.java new file mode 100644 index 0000000..c3dc0b1 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/WorldGenVines.java @@ -0,0 +1,26 @@ +package net.minecraft.src; + +import java.util.Random; + +public class WorldGenVines extends WorldGenerator { + public boolean generate(World par1World, Random par2Random, int par3, int par4, int par5) { + int var6 = par3; + + for (int var7 = par5; par4 < 128; ++par4) { + if (par1World.isAirBlock(par3, par4, par5)) { + for (int var8 = 2; var8 <= 5; ++var8) { + if (Block.vine.canPlaceBlockOnSide(par1World, par3, par4, par5, var8)) { + par1World.setBlock(par3, par4, par5, Block.vine.blockID, + 1 << Direction.facingToDirection[Facing.oppositeSide[var8]], 2); + break; + } + } + } else { + par3 = var6 + par2Random.nextInt(4) - par2Random.nextInt(4); + par5 = var7 + par2Random.nextInt(4) - par2Random.nextInt(4); + } + } + + return true; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/WorldGenWaterlily.java b/sp-server/src/main/java/net/minecraft/src/WorldGenWaterlily.java new file mode 100644 index 0000000..22dd3c3 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/WorldGenWaterlily.java @@ -0,0 +1,20 @@ +package net.minecraft.src; + +import java.util.Random; + +public class WorldGenWaterlily extends WorldGenerator { + public boolean generate(World par1World, Random par2Random, int par3, int par4, int par5) { + for (int var6 = 0; var6 < 10; ++var6) { + int var7 = par3 + par2Random.nextInt(8) - par2Random.nextInt(8); + int var8 = par4 + par2Random.nextInt(4) - par2Random.nextInt(4); + int var9 = par5 + par2Random.nextInt(8) - par2Random.nextInt(8); + + if (par1World.isAirBlock(var7, var8, var9) + && Block.waterlily.canPlaceBlockAt(par1World, var7, var8, var9)) { + par1World.setBlock(var7, var8, var9, Block.waterlily.blockID, 0, 2); + } + } + + return true; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/WorldGenerator.java b/sp-server/src/main/java/net/minecraft/src/WorldGenerator.java new file mode 100644 index 0000000..22f6e94 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/WorldGenerator.java @@ -0,0 +1,46 @@ +package net.minecraft.src; + +import java.util.Random; + +public abstract class WorldGenerator { + /** + * Sets wither or not the generator should notify blocks of blocks it changes. + * When the world is first generated, this is false, when saplings grow, this is + * true. + */ + private final boolean doBlockNotify; + + public WorldGenerator() { + this.doBlockNotify = false; + } + + public WorldGenerator(boolean par1) { + this.doBlockNotify = par1; + } + + public abstract boolean generate(World var1, Random var2, int var3, int var4, int var5); + + /** + * Rescales the generator settings, only used in WorldGenBigTree + */ + public void setScale(double par1, double par3, double par5) { + } + + /** + * Sets the block without metadata in the world, notifying neighbors if enabled. + */ + protected void setBlock(World par1World, int par2, int par3, int par4, int par5) { + this.setBlockAndMetadata(par1World, par2, par3, par4, par5, 0); + } + + /** + * Sets the block in the world, notifying neighbors if enabled. + */ + protected void setBlockAndMetadata(World par1World, int par2, int par3, int par4, int par5, int par6) { + if (this.doBlockNotify) { + par1World.setBlock(par2, par3, par4, par5, par6, 3); + } else { + par1World.setBlock(par2, par3, par4, par5, par6, 2); + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/WorldGeneratorBonusChest.java b/sp-server/src/main/java/net/minecraft/src/WorldGeneratorBonusChest.java new file mode 100644 index 0000000..7018f65 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/WorldGeneratorBonusChest.java @@ -0,0 +1,78 @@ +package net.minecraft.src; + +import java.util.Random; + +public class WorldGeneratorBonusChest extends WorldGenerator { + /** + * Instance of WeightedRandomChestContent what will randomly generate items into + * the Bonus Chest. + */ + private final WeightedRandomChestContent[] theBonusChestGenerator; + + /** + * Value of this int will determine how much items gonna generate in Bonus + * Chest. + */ + private final int itemsToGenerateInBonusChest; + + public WorldGeneratorBonusChest(WeightedRandomChestContent[] par1ArrayOfWeightedRandomChestContent, int par2) { + this.theBonusChestGenerator = par1ArrayOfWeightedRandomChestContent; + this.itemsToGenerateInBonusChest = par2; + } + + public boolean generate(World par1World, Random par2Random, int par3, int par4, int par5) { + int var12; + + for (boolean var6 = false; ((var12 = par1World.getBlockId(par3, par4, par5)) == 0 + || var12 == Block.leaves.blockID) && par4 > 1; --par4) { + ; + } + + if (par4 < 1) { + return false; + } else { + ++par4; + + for (int var7 = 0; var7 < 4; ++var7) { + int var8 = par3 + par2Random.nextInt(4) - par2Random.nextInt(4); + int var9 = par4 + par2Random.nextInt(3) - par2Random.nextInt(3); + int var10 = par5 + par2Random.nextInt(4) - par2Random.nextInt(4); + + if (par1World.isAirBlock(var8, var9, var10) + && par1World.doesBlockHaveSolidTopSurface(var8, var9 - 1, var10)) { + par1World.setBlock(var8, var9, var10, Block.chest.blockID, 0, 2); + TileEntityChest var11 = (TileEntityChest) par1World.getBlockTileEntity(var8, var9, var10); + + if (var11 != null && var11 != null) { + WeightedRandomChestContent.generateChestContents(par2Random, this.theBonusChestGenerator, var11, + this.itemsToGenerateInBonusChest); + } + + if (par1World.isAirBlock(var8 - 1, var9, var10) + && par1World.doesBlockHaveSolidTopSurface(var8 - 1, var9 - 1, var10)) { + par1World.setBlock(var8 - 1, var9, var10, Block.torchWood.blockID, 0, 2); + } + + if (par1World.isAirBlock(var8 + 1, var9, var10) + && par1World.doesBlockHaveSolidTopSurface(var8 - 1, var9 - 1, var10)) { + par1World.setBlock(var8 + 1, var9, var10, Block.torchWood.blockID, 0, 2); + } + + if (par1World.isAirBlock(var8, var9, var10 - 1) + && par1World.doesBlockHaveSolidTopSurface(var8 - 1, var9 - 1, var10)) { + par1World.setBlock(var8, var9, var10 - 1, Block.torchWood.blockID, 0, 2); + } + + if (par1World.isAirBlock(var8, var9, var10 + 1) + && par1World.doesBlockHaveSolidTopSurface(var8 - 1, var9 - 1, var10)) { + par1World.setBlock(var8, var9, var10 + 1, Block.torchWood.blockID, 0, 2); + } + + return true; + } + } + + return false; + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/WorldInfo.java b/sp-server/src/main/java/net/minecraft/src/WorldInfo.java new file mode 100644 index 0000000..ededa12 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/WorldInfo.java @@ -0,0 +1,558 @@ +package net.minecraft.src; + +public class WorldInfo { + /** Holds the seed of the currently world. */ + private long randomSeed; + private WorldType terrainType; + private String generatorOptions; + + /** The spawn zone position X coordinate. */ + private int spawnX; + + /** The spawn zone position Y coordinate. */ + private int spawnY; + + /** The spawn zone position Z coordinate. */ + private int spawnZ; + + /** Total time for this world. */ + private long totalTime; + + /** The current world time in ticks, ranging from 0 to 23999. */ + private long worldTime; + + /** The last time the player was in this world. */ + private long lastTimePlayed; + + /** The size of entire save of current world on the disk, isn't exactly. */ + private long sizeOnDisk; + private NBTTagCompound playerTag; + private int dimension; + + /** The name of the save defined at world creation. */ + private String levelName; + + /** Introduced in beta 1.3, is the save version for future control. */ + private int saveVersion; + + /** True if it's raining, false otherwise. */ + private boolean raining; + + /** Number of ticks until next rain. */ + private int rainTime; + + /** Is thunderbolts failing now? */ + private boolean thundering; + + /** Number of ticks untils next thunderbolt. */ + private int thunderTime; + + /** The Game Type. */ + private EnumGameType theGameType; + + /** + * Whether the map features (e.g. strongholds) generation is enabled or + * disabled. + */ + private boolean mapFeaturesEnabled; + + /** Hardcore mode flag */ + private boolean hardcore; + private boolean allowCommands; + private boolean initialized; + private GameRules theGameRules; + + protected WorldInfo() { + this.terrainType = WorldType.DEFAULT; + this.generatorOptions = ""; + this.theGameRules = new GameRules(); + } + + public WorldInfo(NBTTagCompound par1NBTTagCompound) { + this.terrainType = WorldType.DEFAULT; + this.generatorOptions = ""; + this.theGameRules = new GameRules(); + this.randomSeed = par1NBTTagCompound.getLong("RandomSeed"); + + if (par1NBTTagCompound.hasKey("generatorName")) { + String var2 = par1NBTTagCompound.getString("generatorName"); + this.terrainType = WorldType.parseWorldType(var2); + + if (this.terrainType == null) { + this.terrainType = WorldType.DEFAULT; + } else if (this.terrainType.isVersioned()) { + int var3 = 0; + + if (par1NBTTagCompound.hasKey("generatorVersion")) { + var3 = par1NBTTagCompound.getInteger("generatorVersion"); + } + + this.terrainType = this.terrainType.getWorldTypeForGeneratorVersion(var3); + } + + if (par1NBTTagCompound.hasKey("generatorOptions")) { + this.generatorOptions = par1NBTTagCompound.getString("generatorOptions"); + } + } + + this.theGameType = EnumGameType.getByID(par1NBTTagCompound.getInteger("GameType")); + + if (par1NBTTagCompound.hasKey("MapFeatures")) { + this.mapFeaturesEnabled = par1NBTTagCompound.getBoolean("MapFeatures"); + } else { + this.mapFeaturesEnabled = true; + } + + this.spawnX = par1NBTTagCompound.getInteger("SpawnX"); + this.spawnY = par1NBTTagCompound.getInteger("SpawnY"); + this.spawnZ = par1NBTTagCompound.getInteger("SpawnZ"); + this.totalTime = par1NBTTagCompound.getLong("Time"); + + if (par1NBTTagCompound.hasKey("DayTime")) { + this.worldTime = par1NBTTagCompound.getLong("DayTime"); + } else { + this.worldTime = this.totalTime; + } + + this.lastTimePlayed = par1NBTTagCompound.getLong("LastPlayed"); + this.sizeOnDisk = par1NBTTagCompound.getLong("SizeOnDisk"); + this.levelName = par1NBTTagCompound.getString("LevelName"); + this.saveVersion = par1NBTTagCompound.getInteger("version"); + this.rainTime = par1NBTTagCompound.getInteger("rainTime"); + this.raining = par1NBTTagCompound.getBoolean("raining"); + this.thunderTime = par1NBTTagCompound.getInteger("thunderTime"); + this.thundering = par1NBTTagCompound.getBoolean("thundering"); + this.hardcore = par1NBTTagCompound.getBoolean("hardcore"); + + if (par1NBTTagCompound.hasKey("initialized")) { + this.initialized = par1NBTTagCompound.getBoolean("initialized"); + } else { + this.initialized = true; + } + + if (par1NBTTagCompound.hasKey("allowCommands")) { + this.allowCommands = par1NBTTagCompound.getBoolean("allowCommands"); + } else { + this.allowCommands = this.theGameType == EnumGameType.CREATIVE; + } + + if (par1NBTTagCompound.hasKey("Player")) { + this.playerTag = par1NBTTagCompound.getCompoundTag("Player"); + this.dimension = this.playerTag.getInteger("Dimension"); + } + + if (par1NBTTagCompound.hasKey("GameRules")) { + this.theGameRules.readGameRulesFromNBT(par1NBTTagCompound.getCompoundTag("GameRules")); + } + } + + public WorldInfo(WorldSettings par1WorldSettings, String par2Str) { + this.terrainType = WorldType.DEFAULT; + this.generatorOptions = ""; + this.theGameRules = new GameRules(); + this.randomSeed = par1WorldSettings.getSeed(); + this.theGameType = par1WorldSettings.getGameType(); + this.mapFeaturesEnabled = par1WorldSettings.isMapFeaturesEnabled(); + this.levelName = par2Str; + this.hardcore = par1WorldSettings.getHardcoreEnabled(); + this.terrainType = par1WorldSettings.getTerrainType(); + this.generatorOptions = par1WorldSettings.func_82749_j(); + this.allowCommands = par1WorldSettings.areCommandsAllowed(); + this.initialized = false; + } + + public WorldInfo(WorldInfo par1WorldInfo) { + this.terrainType = WorldType.DEFAULT; + this.generatorOptions = ""; + this.theGameRules = new GameRules(); + this.randomSeed = par1WorldInfo.randomSeed; + this.terrainType = par1WorldInfo.terrainType; + this.generatorOptions = par1WorldInfo.generatorOptions; + this.theGameType = par1WorldInfo.theGameType; + this.mapFeaturesEnabled = par1WorldInfo.mapFeaturesEnabled; + this.spawnX = par1WorldInfo.spawnX; + this.spawnY = par1WorldInfo.spawnY; + this.spawnZ = par1WorldInfo.spawnZ; + this.totalTime = par1WorldInfo.totalTime; + this.worldTime = par1WorldInfo.worldTime; + this.lastTimePlayed = par1WorldInfo.lastTimePlayed; + this.sizeOnDisk = par1WorldInfo.sizeOnDisk; + this.playerTag = par1WorldInfo.playerTag; + this.dimension = par1WorldInfo.dimension; + this.levelName = par1WorldInfo.levelName; + this.saveVersion = par1WorldInfo.saveVersion; + this.rainTime = par1WorldInfo.rainTime; + this.raining = par1WorldInfo.raining; + this.thunderTime = par1WorldInfo.thunderTime; + this.thundering = par1WorldInfo.thundering; + this.hardcore = par1WorldInfo.hardcore; + this.allowCommands = par1WorldInfo.allowCommands; + this.initialized = par1WorldInfo.initialized; + this.theGameRules = par1WorldInfo.theGameRules; + } + + /** + * Gets the NBTTagCompound for the worldInfo + */ + public NBTTagCompound getNBTTagCompound() { + NBTTagCompound var1 = new NBTTagCompound(); + this.updateTagCompound(var1, this.playerTag); + return var1; + } + + /** + * Creates a new NBTTagCompound for the world, with the given NBTTag as the + * "Player" + */ + public NBTTagCompound cloneNBTCompound(NBTTagCompound par1NBTTagCompound) { + NBTTagCompound var2 = new NBTTagCompound(); + this.updateTagCompound(var2, par1NBTTagCompound); + return var2; + } + + private void updateTagCompound(NBTTagCompound par1NBTTagCompound, NBTTagCompound par2NBTTagCompound) { + par1NBTTagCompound.setLong("RandomSeed", this.randomSeed); + par1NBTTagCompound.setString("generatorName", this.terrainType.getWorldTypeName()); + par1NBTTagCompound.setInteger("generatorVersion", this.terrainType.getGeneratorVersion()); + par1NBTTagCompound.setString("generatorOptions", this.generatorOptions); + par1NBTTagCompound.setInteger("GameType", this.theGameType.getID()); + par1NBTTagCompound.setBoolean("MapFeatures", this.mapFeaturesEnabled); + par1NBTTagCompound.setInteger("SpawnX", this.spawnX); + par1NBTTagCompound.setInteger("SpawnY", this.spawnY); + par1NBTTagCompound.setInteger("SpawnZ", this.spawnZ); + par1NBTTagCompound.setLong("Time", this.totalTime); + par1NBTTagCompound.setLong("DayTime", this.worldTime); + par1NBTTagCompound.setLong("SizeOnDisk", this.sizeOnDisk); + par1NBTTagCompound.setLong("LastPlayed", System.currentTimeMillis()); + par1NBTTagCompound.setString("LevelName", this.levelName); + par1NBTTagCompound.setInteger("version", this.saveVersion); + par1NBTTagCompound.setInteger("rainTime", this.rainTime); + par1NBTTagCompound.setBoolean("raining", this.raining); + par1NBTTagCompound.setInteger("thunderTime", this.thunderTime); + par1NBTTagCompound.setBoolean("thundering", this.thundering); + par1NBTTagCompound.setBoolean("hardcore", this.hardcore); + par1NBTTagCompound.setBoolean("allowCommands", this.allowCommands); + par1NBTTagCompound.setBoolean("initialized", this.initialized); + par1NBTTagCompound.setCompoundTag("GameRules", this.theGameRules.writeGameRulesToNBT()); + + if (par2NBTTagCompound != null) { + par1NBTTagCompound.setCompoundTag("Player", par2NBTTagCompound); + } + } + + /** + * Returns the seed of current world. + */ + public long getSeed() { + return this.randomSeed; + } + + /** + * Returns the x spawn position + */ + public int getSpawnX() { + return this.spawnX; + } + + /** + * Return the Y axis spawning point of the player. + */ + public int getSpawnY() { + return this.spawnY; + } + + /** + * Returns the z spawn position + */ + public int getSpawnZ() { + return this.spawnZ; + } + + public long getWorldTotalTime() { + return this.totalTime; + } + + /** + * Get current world time + */ + public long getWorldTime() { + return this.worldTime; + } + + /** + * Returns the player's NBTTagCompound to be loaded + */ + public NBTTagCompound getPlayerNBTTagCompound() { + return this.playerTag; + } + + public int getDimension() { + return this.dimension; + } + + public void incrementTotalWorldTime(long par1) { + this.totalTime = par1; + } + + /** + * Set current world time + */ + public void setWorldTime(long par1) { + this.worldTime = par1; + } + + /** + * Sets the spawn zone position. Args: x, y, z + */ + public void setSpawnPosition(int par1, int par2, int par3) { + this.spawnX = par1; + this.spawnY = par2; + this.spawnZ = par3; + } + + /** + * Get current world name + */ + public String getWorldName() { + return this.levelName; + } + + public void setWorldName(String par1Str) { + this.levelName = par1Str; + } + + /** + * Returns the save version of this world + */ + public int getSaveVersion() { + return this.saveVersion; + } + + /** + * Sets the save version of the world + */ + public void setSaveVersion(int par1) { + this.saveVersion = par1; + } + + /** + * Returns true if it is thundering, false otherwise. + */ + public boolean isThundering() { + return this.thundering; + } + + /** + * Sets whether it is thundering or not. + */ + public void setThundering(boolean par1) { + this.thundering = par1; + } + + /** + * Returns the number of ticks until next thunderbolt. + */ + public int getThunderTime() { + return this.thunderTime; + } + + /** + * Defines the number of ticks until next thunderbolt. + */ + public void setThunderTime(int par1) { + this.thunderTime = par1; + } + + /** + * Returns true if it is raining, false otherwise. + */ + public boolean isRaining() { + return this.raining; + } + + /** + * Sets whether it is raining or not. + */ + public void setRaining(boolean par1) { + this.raining = par1; + } + + /** + * Return the number of ticks until rain. + */ + public int getRainTime() { + return this.rainTime; + } + + /** + * Sets the number of ticks until rain. + */ + public void setRainTime(int par1) { + this.rainTime = par1; + } + + /** + * Gets the GameType. + */ + public EnumGameType getGameType() { + return this.theGameType; + } + + /** + * Get whether the map features (e.g. strongholds) generation is enabled or + * disabled. + */ + public boolean isMapFeaturesEnabled() { + return this.mapFeaturesEnabled; + } + + /** + * Sets the GameType. + */ + public void setGameType(EnumGameType par1EnumGameType) { + this.theGameType = par1EnumGameType; + } + + /** + * Returns true if hardcore mode is enabled, otherwise false + */ + public boolean isHardcoreModeEnabled() { + return this.hardcore; + } + + public WorldType getTerrainType() { + return this.terrainType; + } + + public void setTerrainType(WorldType par1WorldType) { + this.terrainType = par1WorldType; + } + + public String getGeneratorOptions() { + return this.generatorOptions; + } + + /** + * Returns true if commands are allowed on this World. + */ + public boolean areCommandsAllowed() { + return this.allowCommands; + } + + /** + * Returns true if the World is initialized. + */ + public boolean isInitialized() { + return this.initialized; + } + + /** + * Sets the initialization status of the World. + */ + public void setServerInitialized(boolean par1) { + this.initialized = par1; + } + + /** + * Gets the GameRules class Instance. + */ + public GameRules getGameRulesInstance() { + return this.theGameRules; + } + + /** + * Adds this WorldInfo instance to the crash report. + */ + public void addToCrashReport(CrashReportCategory par1CrashReportCategory) { + par1CrashReportCategory.addCrashSectionCallable("Level seed", new CallableLevelSeed(this)); + par1CrashReportCategory.addCrashSectionCallable("Level generator", new CallableLevelGenerator(this)); + par1CrashReportCategory.addCrashSectionCallable("Level generator options", + new CallableLevelGeneratorOptions(this)); + par1CrashReportCategory.addCrashSectionCallable("Level spawn location", new CallableLevelSpawnLocation(this)); + par1CrashReportCategory.addCrashSectionCallable("Level time", new CallableLevelTime(this)); + par1CrashReportCategory.addCrashSectionCallable("Level dimension", new CallableLevelDimension(this)); + par1CrashReportCategory.addCrashSectionCallable("Level storage version", new CallableLevelStorageVersion(this)); + par1CrashReportCategory.addCrashSectionCallable("Level weather", new CallableLevelWeather(this)); + par1CrashReportCategory.addCrashSectionCallable("Level game mode", new CallableLevelGamemode(this)); + } + + /** + * Return the terrain type of a world + */ + static WorldType getTerrainTypeOfWorld(WorldInfo par0WorldInfo) { + return par0WorldInfo.terrainType; + } + + /** + * Return the map feautures enabled of a world + */ + static boolean getMapFeaturesEnabled(WorldInfo par0WorldInfo) { + return par0WorldInfo.mapFeaturesEnabled; + } + + static String getWorldGeneratorOptions(WorldInfo par0WorldInfo) { + return par0WorldInfo.generatorOptions; + } + + static int getSpawnXCoordinate(WorldInfo par0WorldInfo) { + return par0WorldInfo.spawnX; + } + + static int getSpawnYCoordinate(WorldInfo par0WorldInfo) { + return par0WorldInfo.spawnY; + } + + static int getSpawnZCoordinate(WorldInfo par0WorldInfo) { + return par0WorldInfo.spawnZ; + } + + static long func_85126_g(WorldInfo par0WorldInfo) { + return par0WorldInfo.totalTime; + } + + static long getWorldTime(WorldInfo par0WorldInfo) { + return par0WorldInfo.worldTime; + } + + static int func_85122_i(WorldInfo par0WorldInfo) { + return par0WorldInfo.dimension; + } + + static int getSaveVersion(WorldInfo par0WorldInfo) { + return par0WorldInfo.saveVersion; + } + + static int getRainTime(WorldInfo par0WorldInfo) { + return par0WorldInfo.rainTime; + } + + /** + * Returns wether it's raining or not. + */ + static boolean getRaining(WorldInfo par0WorldInfo) { + return par0WorldInfo.raining; + } + + static int getThunderTime(WorldInfo par0WorldInfo) { + return par0WorldInfo.thunderTime; + } + + /** + * Returns wether it's thundering or not. + */ + static boolean getThundering(WorldInfo par0WorldInfo) { + return par0WorldInfo.thundering; + } + + static EnumGameType getGameType(WorldInfo par0WorldInfo) { + return par0WorldInfo.theGameType; + } + + static boolean func_85117_p(WorldInfo par0WorldInfo) { + return par0WorldInfo.hardcore; + } + + static boolean func_85131_q(WorldInfo par0WorldInfo) { + return par0WorldInfo.allowCommands; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/WorldManager.java b/sp-server/src/main/java/net/minecraft/src/WorldManager.java new file mode 100644 index 0000000..45dc9a8 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/WorldManager.java @@ -0,0 +1,127 @@ +package net.minecraft.src; + +import java.util.Iterator; +import net.minecraft.server.MinecraftServer; + +public class WorldManager implements IWorldAccess { + /** Reference to the MinecraftServer object. */ + private MinecraftServer mcServer; + + /** The WorldServer object. */ + private WorldServer theWorldServer; + + public WorldManager(MinecraftServer par1MinecraftServer, WorldServer par2WorldServer) { + this.mcServer = par1MinecraftServer; + this.theWorldServer = par2WorldServer; + } + + /** + * Spawns a particle. Arg: particleType, x, y, z, velX, velY, velZ + */ + public void spawnParticle(String par1Str, double par2, double par4, double par6, double par8, double par10, + double par12) { + } + + /** + * Called on all IWorldAccesses when an entity is created or loaded. On client + * worlds, starts downloading any necessary textures. On server worlds, adds the + * entity to the entity tracker. + */ + public void onEntityCreate(Entity par1Entity) { + this.theWorldServer.getEntityTracker().trackEntity(par1Entity); + } + + /** + * Called on all IWorldAccesses when an entity is unloaded or destroyed. On + * client worlds, releases any downloaded textures. On server worlds, removes + * the entity from the entity tracker. + */ + public void onEntityDestroy(Entity par1Entity) { + this.theWorldServer.getEntityTracker().untrackEntity(par1Entity); + } + + /** + * Plays the specified sound. Arg: soundName, x, y, z, volume, pitch + */ + public void playSound(String par1Str, double par2, double par4, double par6, float par8, float par9) { + this.mcServer.getConfigurationManager().sendPacketToPlayersAroundPoint(par2, par4, par6, + par8 > 1.0F ? (double) (16.0F * par8) : 16.0D, this.theWorldServer.provider.dimensionId, + new Packet62LevelSound(par1Str, par2, par4, par6, par8, par9)); + } + + /** + * Plays sound to all near players except the player reference given + */ + public void playSoundToNearExcept(EntityPlayer par1EntityPlayer, String par2Str, double par3, double par5, + double par7, float par9, float par10) { + this.mcServer.getConfigurationManager().sendToAllNearExcept(par1EntityPlayer, par3, par5, par7, + par9 > 1.0F ? (double) (16.0F * par9) : 16.0D, this.theWorldServer.provider.dimensionId, + new Packet62LevelSound(par2Str, par3, par5, par7, par9, par10)); + } + + /** + * On the client, re-renders all blocks in this range, inclusive. On the server, + * does nothing. Args: min x, min y, min z, max x, max y, max z + */ + public void markBlockRangeForRenderUpdate(int par1, int par2, int par3, int par4, int par5, int par6) { + } + + /** + * On the client, re-renders the block. On the server, sends the block to the + * client (which will re-render it), including the tile entity description + * packet if applicable. Args: x, y, z + */ + public void markBlockForUpdate(int par1, int par2, int par3) { + this.theWorldServer.getPlayerManager().markBlockNeedsUpdate(par1, par2, par3); + } + + /** + * On the client, re-renders this block. On the server, does nothing. Used for + * lighting updates. + */ + public void markBlockForRenderUpdate(int par1, int par2, int par3) { + } + + /** + * Plays the specified record. Arg: recordName, x, y, z + */ + public void playRecord(String par1Str, int par2, int par3, int par4) { + } + + /** + * Plays a pre-canned sound effect along with potentially auxiliary data-driven + * one-shot behaviour (particles, etc). + */ + public void playAuxSFX(EntityPlayer par1EntityPlayer, int par2, int par3, int par4, int par5, int par6) { + this.mcServer.getConfigurationManager().sendToAllNearExcept(par1EntityPlayer, (double) par3, (double) par4, + (double) par5, 64.0D, this.theWorldServer.provider.dimensionId, + new Packet61DoorChange(par2, par3, par4, par5, par6, false)); + } + + public void broadcastSound(int par1, int par2, int par3, int par4, int par5) { + this.mcServer.getConfigurationManager() + .sendPacketToAllPlayers(new Packet61DoorChange(par1, par2, par3, par4, par5, true)); + } + + /** + * Starts (or continues) destroying a block with given ID at the given + * coordinates for the given partially destroyed value + */ + public void destroyBlockPartially(int par1, int par2, int par3, int par4, int par5) { + Iterator var6 = this.mcServer.getConfigurationManager().playerEntityList.iterator(); + + while (var6.hasNext()) { + EntityPlayerMP var7 = (EntityPlayerMP) var6.next(); + + if (var7 != null && var7.worldObj == this.theWorldServer && var7.entityId != par1) { + double var8 = (double) par2 - var7.posX; + double var10 = (double) par3 - var7.posY; + double var12 = (double) par4 - var7.posZ; + + if (var8 * var8 + var10 * var10 + var12 * var12 < 1024.0D) { + var7.playerNetServerHandler.sendPacket(new Packet55BlockDestroy(par1, par2, par3, par4, par5)); + } + } + } + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/WorldProvider.java b/sp-server/src/main/java/net/minecraft/src/WorldProvider.java new file mode 100644 index 0000000..36ffe29 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/WorldProvider.java @@ -0,0 +1,152 @@ +package net.minecraft.src; + +public abstract class WorldProvider { + /** world object being used */ + public World worldObj; + public WorldType terrainType; + public String field_82913_c; + + /** World chunk manager being used to generate chunks */ + public WorldChunkManager worldChunkMgr; + + /** + * States whether the Hell world provider is used(true) or if the normal world + * provider is used(false) + */ + public boolean isHellWorld = false; + + /** + * A boolean that tells if a world does not have a sky. Used in calculating + * weather and skylight + */ + public boolean hasNoSky = false; + + /** Light to brightness conversion table */ + public float[] lightBrightnessTable = new float[16]; + + /** The id for the dimension (ex. -1: Nether, 0: Overworld, 1: The End) */ + public int dimensionId = 0; + + /** Array for sunrise/sunset colors (RGBA) */ + private float[] colorsSunriseSunset = new float[4]; + + /** + * associate an existing world with a World provider, and setup its + * lightbrightness table + */ + public final void registerWorld(World par1World) { + this.worldObj = par1World; + this.terrainType = par1World.getWorldInfo().getTerrainType(); + this.field_82913_c = par1World.getWorldInfo().getGeneratorOptions(); + this.registerWorldChunkManager(); + this.generateLightBrightnessTable(); + } + + /** + * Creates the light to brightness table + */ + protected void generateLightBrightnessTable() { + float var1 = 0.0F; + + for (int var2 = 0; var2 <= 15; ++var2) { + float var3 = 1.0F - (float) var2 / 15.0F; + this.lightBrightnessTable[var2] = (1.0F - var3) / (var3 * 3.0F + 1.0F) * (1.0F - var1) + var1; + } + } + + /** + * creates a new world chunk manager for WorldProvider + */ + protected void registerWorldChunkManager() { + if (this.worldObj.getWorldInfo().getTerrainType() == WorldType.FLAT) { + FlatGeneratorInfo var1 = FlatGeneratorInfo + .createFlatGeneratorFromString(this.worldObj.getWorldInfo().getGeneratorOptions()); + this.worldChunkMgr = new WorldChunkManagerHell(BiomeGenBase.biomeList[var1.getBiome()], 0.5F, 0.5F); + } else { + this.worldChunkMgr = new WorldChunkManager(this.worldObj); + } + } + + /** + * Returns a new chunk provider which generates chunks for this world + */ + public IChunkProvider createChunkGenerator() { + return (IChunkProvider) (this.terrainType == WorldType.FLAT + ? new ChunkProviderFlat(this.worldObj, this.worldObj.getSeed(), + this.worldObj.getWorldInfo().isMapFeaturesEnabled(), this.field_82913_c) + : new ChunkProviderGenerate(this.worldObj, this.worldObj.getSeed(), + this.worldObj.getWorldInfo().isMapFeaturesEnabled())); + } + + /** + * Will check if the x, z position specified is alright to be set as the map + * spawn point + */ + public boolean canCoordinateBeSpawn(int par1, int par2) { + int var3 = this.worldObj.getFirstUncoveredBlock(par1, par2); + return var3 == Block.grass.blockID; + } + + /** + * Calculates the angle of sun and moon in the sky relative to a specified time + * (usually worldTime) + */ + public float calculateCelestialAngle(long par1, float par3) { + int var4 = (int) (par1 % 24000L); + float var5 = ((float) var4 + par3) / 24000.0F - 0.25F; + + if (var5 < 0.0F) { + ++var5; + } + + if (var5 > 1.0F) { + --var5; + } + + float var6 = var5; + var5 = 1.0F - (float) ((Math.cos((double) var5 * Math.PI) + 1.0D) / 2.0D); + var5 = var6 + (var5 - var6) / 3.0F; + return var5; + } + + public int func_76559_b(long par1) { + return (int) (par1 / 24000L) % 8; + } + + /** + * Returns 'true' if in the "main surface world", but 'false' if in the Nether + * or End dimensions. + */ + public boolean isSurfaceWorld() { + return true; + } + + /** + * True if the player can respawn in this dimension (true = overworld, false = + * nether). + */ + public boolean canRespawnHere() { + return true; + } + + public static WorldProvider getProviderForDimension(int par0) { + return (WorldProvider) (par0 == -1 ? new WorldProviderHell() + : (par0 == 0 ? new WorldProviderSurface() : (par0 == 1 ? new WorldProviderEnd() : null))); + } + + /** + * Gets the hard-coded portal location to use when entering this dimension. + */ + public ChunkCoordinates getEntrancePortalLocation() { + return null; + } + + public int getAverageGroundLevel() { + return this.terrainType == WorldType.FLAT ? 4 : 64; + } + + /** + * Returns the dimension's name, e.g. "The End", "Nether", or "Overworld". + */ + public abstract String getDimensionName(); +} diff --git a/sp-server/src/main/java/net/minecraft/src/WorldProviderEnd.java b/sp-server/src/main/java/net/minecraft/src/WorldProviderEnd.java new file mode 100644 index 0000000..5d79a3b --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/WorldProviderEnd.java @@ -0,0 +1,70 @@ +package net.minecraft.src; + +public class WorldProviderEnd extends WorldProvider { + /** + * creates a new world chunk manager for WorldProvider + */ + public void registerWorldChunkManager() { + this.worldChunkMgr = new WorldChunkManagerHell(BiomeGenBase.sky, 0.5F, 0.0F); + this.dimensionId = 1; + this.hasNoSky = true; + } + + /** + * Returns a new chunk provider which generates chunks for this world + */ + public IChunkProvider createChunkGenerator() { + return new ChunkProviderEnd(this.worldObj, this.worldObj.getSeed()); + } + + /** + * Calculates the angle of sun and moon in the sky relative to a specified time + * (usually worldTime) + */ + public float calculateCelestialAngle(long par1, float par3) { + return 0.0F; + } + + /** + * True if the player can respawn in this dimension (true = overworld, false = + * nether). + */ + public boolean canRespawnHere() { + return false; + } + + /** + * Returns 'true' if in the "main surface world", but 'false' if in the Nether + * or End dimensions. + */ + public boolean isSurfaceWorld() { + return false; + } + + /** + * Will check if the x, z position specified is alright to be set as the map + * spawn point + */ + public boolean canCoordinateBeSpawn(int par1, int par2) { + int var3 = this.worldObj.getFirstUncoveredBlock(par1, par2); + return var3 == 0 ? false : Block.blocksList[var3].blockMaterial.blocksMovement(); + } + + /** + * Gets the hard-coded portal location to use when entering this dimension. + */ + public ChunkCoordinates getEntrancePortalLocation() { + return new ChunkCoordinates(100, 50, 0); + } + + public int getAverageGroundLevel() { + return 50; + } + + /** + * Returns the dimension's name, e.g. "The End", "Nether", or "Overworld". + */ + public String getDimensionName() { + return "The End"; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/WorldProviderHell.java b/sp-server/src/main/java/net/minecraft/src/WorldProviderHell.java new file mode 100644 index 0000000..f6a9d5c --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/WorldProviderHell.java @@ -0,0 +1,71 @@ +package net.minecraft.src; + +public class WorldProviderHell extends WorldProvider { + /** + * creates a new world chunk manager for WorldProvider + */ + public void registerWorldChunkManager() { + this.worldChunkMgr = new WorldChunkManagerHell(BiomeGenBase.hell, 1.0F, 0.0F); + this.isHellWorld = true; + this.hasNoSky = true; + this.dimensionId = -1; + } + + /** + * Creates the light to brightness table + */ + protected void generateLightBrightnessTable() { + float var1 = 0.1F; + + for (int var2 = 0; var2 <= 15; ++var2) { + float var3 = 1.0F - (float) var2 / 15.0F; + this.lightBrightnessTable[var2] = (1.0F - var3) / (var3 * 3.0F + 1.0F) * (1.0F - var1) + var1; + } + } + + /** + * Returns a new chunk provider which generates chunks for this world + */ + public IChunkProvider createChunkGenerator() { + return new ChunkProviderHell(this.worldObj, this.worldObj.getSeed()); + } + + /** + * Returns 'true' if in the "main surface world", but 'false' if in the Nether + * or End dimensions. + */ + public boolean isSurfaceWorld() { + return false; + } + + /** + * Will check if the x, z position specified is alright to be set as the map + * spawn point + */ + public boolean canCoordinateBeSpawn(int par1, int par2) { + return false; + } + + /** + * Calculates the angle of sun and moon in the sky relative to a specified time + * (usually worldTime) + */ + public float calculateCelestialAngle(long par1, float par3) { + return 0.5F; + } + + /** + * True if the player can respawn in this dimension (true = overworld, false = + * nether). + */ + public boolean canRespawnHere() { + return false; + } + + /** + * Returns the dimension's name, e.g. "The End", "Nether", or "Overworld". + */ + public String getDimensionName() { + return "Nether"; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/WorldProviderSurface.java b/sp-server/src/main/java/net/minecraft/src/WorldProviderSurface.java new file mode 100644 index 0000000..cac7078 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/WorldProviderSurface.java @@ -0,0 +1,10 @@ +package net.minecraft.src; + +public class WorldProviderSurface extends WorldProvider { + /** + * Returns the dimension's name, e.g. "The End", "Nether", or "Overworld". + */ + public String getDimensionName() { + return "Overworld"; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/WorldSavedData.java b/sp-server/src/main/java/net/minecraft/src/WorldSavedData.java new file mode 100644 index 0000000..fbe0a5d --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/WorldSavedData.java @@ -0,0 +1,45 @@ +package net.minecraft.src; + +public abstract class WorldSavedData { + /** The name of the map data nbt */ + public final String mapName; + + /** Whether this MapDataBase needs saving to disk. */ + private boolean dirty; + + public WorldSavedData(String par1Str) { + this.mapName = par1Str; + } + + /** + * reads in data from the NBTTagCompound into this MapDataBase + */ + public abstract void readFromNBT(NBTTagCompound var1); + + /** + * write data to NBTTagCompound from this MapDataBase, similar to Entities and + * TileEntities + */ + public abstract void writeToNBT(NBTTagCompound var1); + + /** + * Marks this MapDataBase dirty, to be saved to disk when the level next saves. + */ + public void markDirty() { + this.setDirty(true); + } + + /** + * Sets the dirty state of this MapDataBase, whether it needs saving to disk. + */ + public void setDirty(boolean par1) { + this.dirty = par1; + } + + /** + * Whether this MapDataBase needs saving to disk. + */ + public boolean isDirty() { + return this.dirty; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/WorldServer.java b/sp-server/src/main/java/net/minecraft/src/WorldServer.java new file mode 100644 index 0000000..a5daa71 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/WorldServer.java @@ -0,0 +1,887 @@ +package net.minecraft.src; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Random; +import java.util.Set; +import java.util.TreeSet; +import net.minecraft.server.MinecraftServer; + +public class WorldServer extends World { + private final MinecraftServer mcServer; + private final EntityTracker theEntityTracker; + private final PlayerManager thePlayerManager; + private Set field_73064_N; + + /** All work to do in future ticks. */ + private TreeSet pendingTickListEntries; + public ChunkProviderServer theChunkProviderServer; + + /** Whether or not level saving is enabled */ + public boolean levelSaving; + + /** is false if there are no players */ + private boolean allPlayersSleeping; + private int updateEntityTick = 0; + private final Teleporter field_85177_Q; + + /** + * Double buffer of ServerBlockEventList[] for holding pending BlockEventData's + */ + private ServerBlockEventList[] blockEventCache = new ServerBlockEventList[] { + new ServerBlockEventList((ServerBlockEvent) null), new ServerBlockEventList((ServerBlockEvent) null) }; + + /** + * The index into the blockEventCache; either 0, or 1, toggled in + * sendBlockEventPackets where all BlockEvent are applied locally and send to + * clients. + */ + private int blockEventCacheIndex = 0; + private static final WeightedRandomChestContent[] bonusChestContent = new WeightedRandomChestContent[] { + new WeightedRandomChestContent(Item.stick.itemID, 0, 1, 3, 10), + new WeightedRandomChestContent(Block.planks.blockID, 0, 1, 3, 10), + new WeightedRandomChestContent(Block.wood.blockID, 0, 1, 3, 10), + new WeightedRandomChestContent(Item.axeStone.itemID, 0, 1, 1, 3), + new WeightedRandomChestContent(Item.axeWood.itemID, 0, 1, 1, 5), + new WeightedRandomChestContent(Item.pickaxeStone.itemID, 0, 1, 1, 3), + new WeightedRandomChestContent(Item.pickaxeWood.itemID, 0, 1, 1, 5), + new WeightedRandomChestContent(Item.appleRed.itemID, 0, 2, 3, 5), + new WeightedRandomChestContent(Item.bread.itemID, 0, 2, 3, 3) }; + private ArrayList field_94579_S = new ArrayList(); + + /** An IntHashMap of entity IDs (integers) to their Entity objects. */ + private IntHashMap entityIdMap; + + public WorldServer(MinecraftServer par1MinecraftServer, ISaveHandler par2ISaveHandler, String par3Str, int par4, + WorldSettings par5WorldSettings, Profiler par6Profiler, ILogAgent par7ILogAgent) { + super(par2ISaveHandler, par3Str, par5WorldSettings, WorldProvider.getProviderForDimension(par4), par6Profiler, + par7ILogAgent); + this.mcServer = par1MinecraftServer; + this.theEntityTracker = new EntityTracker(this); + this.thePlayerManager = new PlayerManager(this, + par1MinecraftServer.getConfigurationManager().getViewDistance()); + + if (this.entityIdMap == null) { + this.entityIdMap = new IntHashMap(); + } + + if (this.field_73064_N == null) { + this.field_73064_N = new HashSet(); + } + + if (this.pendingTickListEntries == null) { + this.pendingTickListEntries = new TreeSet(); + } + + this.field_85177_Q = new Teleporter(this); + this.worldScoreboard = new ServerScoreboard(par1MinecraftServer); + ScoreboardSaveData var8 = (ScoreboardSaveData) this.mapStorage.loadData(ScoreboardSaveData.class, "scoreboard"); + + if (var8 == null) { + var8 = new ScoreboardSaveData(); + this.mapStorage.setData("scoreboard", var8); + } + + var8.func_96499_a(this.worldScoreboard); + ((ServerScoreboard) this.worldScoreboard).func_96547_a(var8); + } + + /** + * Runs a single tick for the world + */ + public void tick() { + super.tick(); + + if (this.getWorldInfo().isHardcoreModeEnabled() && this.difficultySetting < 3) { + this.difficultySetting = 3; + } + + this.provider.worldChunkMgr.cleanupCache(); + + if (this.areAllPlayersAsleep()) { + boolean var1 = false; + + if (this.spawnHostileMobs && this.difficultySetting >= 1) { + ; + } + + if (!var1) { + long var2 = this.worldInfo.getWorldTime() + 24000L; + this.worldInfo.setWorldTime(var2 - var2 % 24000L); + this.wakeAllPlayers(); + } + } + + this.theProfiler.startSection("mobSpawner"); + + if (this.getGameRules().getGameRuleBooleanValue("doMobSpawning")) { + SpawnerAnimals.findChunksForSpawning(this, this.spawnHostileMobs, this.spawnPeacefulMobs, + this.worldInfo.getWorldTotalTime() % 400L == 0L); + } + + this.theProfiler.endStartSection("chunkSource"); + this.chunkProvider.unloadQueuedChunks(); + int var4 = this.calculateSkylightSubtracted(1.0F); + + if (var4 != this.skylightSubtracted) { + this.skylightSubtracted = var4; + } + + this.worldInfo.incrementTotalWorldTime(this.worldInfo.getWorldTotalTime() + 1L); + this.worldInfo.setWorldTime(this.worldInfo.getWorldTime() + 1L); + this.theProfiler.endStartSection("tickPending"); + this.tickUpdates(false); + this.theProfiler.endStartSection("tickTiles"); + this.tickBlocksAndAmbiance(); + this.theProfiler.endStartSection("chunkMap"); + this.thePlayerManager.updatePlayerInstances(); + this.theProfiler.endStartSection("village"); + this.villageCollectionObj.tick(); + this.villageSiegeObj.tick(); + this.theProfiler.endStartSection("portalForcer"); + this.field_85177_Q.removeStalePortalLocations(this.getTotalWorldTime()); + this.theProfiler.endSection(); + this.sendAndApplyBlockEvents(); + } + + /** + * only spawns creatures allowed by the chunkProvider + */ + public SpawnListEntry spawnRandomCreature(EnumCreatureType par1EnumCreatureType, int par2, int par3, int par4) { + List var5 = this.getChunkProvider().getPossibleCreatures(par1EnumCreatureType, par2, par3, par4); + return var5 != null && !var5.isEmpty() ? (SpawnListEntry) WeightedRandom.getRandomItem(this.rand, var5) : null; + } + + /** + * Updates the flag that indicates whether or not all players in the world are + * sleeping. + */ + public void updateAllPlayersSleepingFlag() { + this.allPlayersSleeping = !this.playerEntities.isEmpty(); + Iterator var1 = this.playerEntities.iterator(); + + while (var1.hasNext()) { + EntityPlayer var2 = (EntityPlayer) var1.next(); + + if (!var2.isPlayerSleeping()) { + this.allPlayersSleeping = false; + break; + } + } + } + + protected void wakeAllPlayers() { + this.allPlayersSleeping = false; + Iterator var1 = this.playerEntities.iterator(); + + while (var1.hasNext()) { + EntityPlayer var2 = (EntityPlayer) var1.next(); + + if (var2.isPlayerSleeping()) { + var2.wakeUpPlayer(false, false, true); + } + } + + this.resetRainAndThunder(); + } + + private void resetRainAndThunder() { + this.worldInfo.setRainTime(0); + this.worldInfo.setRaining(false); + this.worldInfo.setThunderTime(0); + this.worldInfo.setThundering(false); + } + + public boolean areAllPlayersAsleep() { + if (this.allPlayersSleeping && !this.isRemote) { + Iterator var1 = this.playerEntities.iterator(); + EntityPlayer var2; + + do { + if (!var1.hasNext()) { + return true; + } + + var2 = (EntityPlayer) var1.next(); + } while (var2.isPlayerFullyAsleep()); + + return false; + } else { + return false; + } + } + + /** + * plays random cave ambient sounds and runs updateTick on random blocks within + * each chunk in the vacinity of a player + */ + protected void tickBlocksAndAmbiance() { + super.tickBlocksAndAmbiance(); + int var1 = 0; + int var2 = 0; + Iterator var3 = this.activeChunkSet.iterator(); + + while (var3.hasNext()) { + ChunkCoordIntPair var4 = (ChunkCoordIntPair) var3.next(); + int var5 = var4.chunkXPos * 16; + int var6 = var4.chunkZPos * 16; + this.theProfiler.startSection("getChunk"); + Chunk var7 = this.getChunkFromChunkCoords(var4.chunkXPos, var4.chunkZPos); + this.moodSoundAndLightCheck(var5, var6, var7); + this.theProfiler.endStartSection("tickChunk"); + var7.updateSkylight(); + this.theProfiler.endStartSection("thunder"); + int var8; + int var9; + int var10; + int var11; + + if (this.rand.nextInt(100000) == 0 && this.isRaining() && this.isThundering()) { + this.updateLCG = this.updateLCG * 3 + 1013904223; + var8 = this.updateLCG >> 2; + var9 = var5 + (var8 & 15); + var10 = var6 + (var8 >> 8 & 15); + var11 = this.getPrecipitationHeight(var9, var10); + + if (this.canLightningStrikeAt(var9, var11, var10)) { + this.addWeatherEffect(new EntityLightningBolt(this, (double) var9, (double) var11, (double) var10)); + } + } + + this.theProfiler.endStartSection("iceandsnow"); + int var13; + + if (this.rand.nextInt(16) == 0) { + this.updateLCG = this.updateLCG * 3 + 1013904223; + var8 = this.updateLCG >> 2; + var9 = var8 & 15; + var10 = var8 >> 8 & 15; + var11 = this.getPrecipitationHeight(var9 + var5, var10 + var6); + + if (this.isBlockFreezableNaturally(var9 + var5, var11 - 1, var10 + var6)) { + this.setBlock(var9 + var5, var11 - 1, var10 + var6, Block.ice.blockID); + } + + if (this.isRaining() && this.canSnowAt(var9 + var5, var11, var10 + var6)) { + this.setBlock(var9 + var5, var11, var10 + var6, Block.snow.blockID); + } + + if (this.isRaining()) { + BiomeGenBase var12 = this.getBiomeGenForCoords(var9 + var5, var10 + var6); + + if (var12.canSpawnLightningBolt()) { + var13 = this.getBlockId(var9 + var5, var11 - 1, var10 + var6); + + if (var13 != 0) { + Block.blocksList[var13].fillWithRain(this, var9 + var5, var11 - 1, var10 + var6); + } + } + } + } + + this.theProfiler.endStartSection("tickTiles"); + ExtendedBlockStorage[] var19 = var7.getBlockStorageArray(); + var9 = var19.length; + + for (var10 = 0; var10 < var9; ++var10) { + ExtendedBlockStorage var20 = var19[var10]; + + if (var20 != null && var20.getNeedsRandomTick()) { + for (int var21 = 0; var21 < 3; ++var21) { + this.updateLCG = this.updateLCG * 3 + 1013904223; + var13 = this.updateLCG >> 2; + int var14 = var13 & 15; + int var15 = var13 >> 8 & 15; + int var16 = var13 >> 16 & 15; + int var17 = var20.getExtBlockID(var14, var16, var15); + ++var2; + Block var18 = Block.blocksList[var17]; + + if (var18 != null && var18.getTickRandomly()) { + ++var1; + var18.updateTick(this, var14 + var5, var16 + var20.getYLocation(), var15 + var6, this.rand); + } + } + } + } + + this.theProfiler.endSection(); + } + } + + /** + * Returns true if the given block will receive a scheduled tick in the future. + * Args: X, Y, Z, blockID + */ + public boolean isBlockTickScheduled(int par1, int par2, int par3, int par4) { + NextTickListEntry var5 = new NextTickListEntry(par1, par2, par3, par4); + return this.field_94579_S.contains(var5); + } + + /** + * Used to schedule a call to the updateTick method on the specified block. + */ + public void scheduleBlockUpdate(int par1, int par2, int par3, int par4, int par5) { + this.func_82740_a(par1, par2, par3, par4, par5, 0); + } + + public void func_82740_a(int par1, int par2, int par3, int par4, int par5, int par6) { + NextTickListEntry var7 = new NextTickListEntry(par1, par2, par3, par4); + byte var8 = 0; + + if (this.scheduledUpdatesAreImmediate && par4 > 0) { + if (Block.blocksList[par4].func_82506_l()) { + if (this.checkChunksExist(var7.xCoord - var8, var7.yCoord - var8, var7.zCoord - var8, + var7.xCoord + var8, var7.yCoord + var8, var7.zCoord + var8)) { + int var9 = this.getBlockId(var7.xCoord, var7.yCoord, var7.zCoord); + + if (var9 == var7.blockID && var9 > 0) { + Block.blocksList[var9].updateTick(this, var7.xCoord, var7.yCoord, var7.zCoord, this.rand); + } + } + + return; + } + + par5 = 1; + } + + if (this.checkChunksExist(par1 - var8, par2 - var8, par3 - var8, par1 + var8, par2 + var8, par3 + var8)) { + if (par4 > 0) { + var7.setScheduledTime((long) par5 + this.worldInfo.getWorldTotalTime()); + var7.func_82753_a(par6); + } + + if (!this.field_73064_N.contains(var7)) { + this.field_73064_N.add(var7); + this.pendingTickListEntries.add(var7); + } + } + } + + /** + * Schedules a block update from the saved information in a chunk. Called when + * the chunk is loaded. + */ + public void scheduleBlockUpdateFromLoad(int par1, int par2, int par3, int par4, int par5, int par6) { + NextTickListEntry var7 = new NextTickListEntry(par1, par2, par3, par4); + var7.func_82753_a(par6); + + if (par4 > 0) { + var7.setScheduledTime((long) par5 + this.worldInfo.getWorldTotalTime()); + } + + if (!this.field_73064_N.contains(var7)) { + this.field_73064_N.add(var7); + this.pendingTickListEntries.add(var7); + } + } + + /** + * Updates (and cleans up) entities and tile entities + */ + public void updateEntities() { + if (this.playerEntities.isEmpty()) { + if (this.updateEntityTick++ >= 1200) { + return; + } + } else { + this.resetUpdateEntityTick(); + } + + super.updateEntities(); + } + + /** + * Resets the updateEntityTick field to 0 + */ + public void resetUpdateEntityTick() { + this.updateEntityTick = 0; + } + + /** + * Runs through the list of updates to run and ticks them + */ + public boolean tickUpdates(boolean par1) { + int var2 = this.pendingTickListEntries.size(); + + if (var2 != this.field_73064_N.size()) { + throw new IllegalStateException("TickNextTick list out of synch"); + } else { + if (var2 > 1000) { + var2 = 1000; + } + + this.theProfiler.startSection("cleaning"); + NextTickListEntry var4; + + for (int var3 = 0; var3 < var2; ++var3) { + var4 = (NextTickListEntry) this.pendingTickListEntries.first(); + + if (!par1 && var4.scheduledTime > this.worldInfo.getWorldTotalTime()) { + break; + } + + this.pendingTickListEntries.remove(var4); + this.field_73064_N.remove(var4); + this.field_94579_S.add(var4); + } + + this.theProfiler.endSection(); + this.theProfiler.startSection("ticking"); + Iterator var14 = this.field_94579_S.iterator(); + + while (var14.hasNext()) { + var4 = (NextTickListEntry) var14.next(); + var14.remove(); + byte var5 = 0; + + if (this.checkChunksExist(var4.xCoord - var5, var4.yCoord - var5, var4.zCoord - var5, + var4.xCoord + var5, var4.yCoord + var5, var4.zCoord + var5)) { + int var6 = this.getBlockId(var4.xCoord, var4.yCoord, var4.zCoord); + + if (var6 > 0 && Block.isAssociatedBlockID(var6, var4.blockID)) { + try { + Block.blocksList[var6].updateTick(this, var4.xCoord, var4.yCoord, var4.zCoord, this.rand); + } catch (Throwable var13) { + CrashReport var8 = CrashReport.makeCrashReport(var13, "Exception while ticking a block"); + CrashReportCategory var9 = var8.makeCategory("Block being ticked"); + int var10; + + try { + var10 = this.getBlockMetadata(var4.xCoord, var4.yCoord, var4.zCoord); + } catch (Throwable var12) { + var10 = -1; + } + + CrashReportCategory.func_85068_a(var9, var4.xCoord, var4.yCoord, var4.zCoord, var6, var10); + throw new ReportedException(var8); + } + } + } else { + this.scheduleBlockUpdate(var4.xCoord, var4.yCoord, var4.zCoord, var4.blockID, 0); + } + } + + this.theProfiler.endSection(); + this.field_94579_S.clear(); + return !this.pendingTickListEntries.isEmpty(); + } + } + + public List getPendingBlockUpdates(Chunk par1Chunk, boolean par2) { + ArrayList var3 = null; + ChunkCoordIntPair var4 = par1Chunk.getChunkCoordIntPair(); + int var5 = (var4.chunkXPos << 4) - 2; + int var6 = var5 + 16 + 2; + int var7 = (var4.chunkZPos << 4) - 2; + int var8 = var7 + 16 + 2; + + for (int var9 = 0; var9 < 2; ++var9) { + Iterator var10; + + if (var9 == 0) { + var10 = this.pendingTickListEntries.iterator(); + } else { + var10 = this.field_94579_S.iterator(); + + if (!this.field_94579_S.isEmpty()) { + System.out.println(this.field_94579_S.size()); + } + } + + while (var10.hasNext()) { + NextTickListEntry var11 = (NextTickListEntry) var10.next(); + + if (var11.xCoord >= var5 && var11.xCoord < var6 && var11.zCoord >= var7 && var11.zCoord < var8) { + if (par2) { + this.field_73064_N.remove(var11); + var10.remove(); + } + + if (var3 == null) { + var3 = new ArrayList(); + } + + var3.add(var11); + } + } + } + + return var3; + } + + /** + * Will update the entity in the world if the chunk the entity is in is + * currently loaded or its forced to update. Args: entity, forceUpdate + */ + public void updateEntityWithOptionalForce(Entity par1Entity, boolean par2) { + if (!this.mcServer.getCanSpawnAnimals() + && (par1Entity instanceof EntityAnimal || par1Entity instanceof EntityWaterMob)) { + par1Entity.setDead(); + } + + if (!this.mcServer.getCanSpawnNPCs() && par1Entity instanceof INpc) { + par1Entity.setDead(); + } + + if (!(par1Entity.riddenByEntity instanceof EntityPlayer)) { + super.updateEntityWithOptionalForce(par1Entity, par2); + } + } + + /** + * direct call to super.updateEntityWithOptionalForce + */ + public void uncheckedUpdateEntity(Entity par1Entity, boolean par2) { + super.updateEntityWithOptionalForce(par1Entity, par2); + } + + /** + * Creates the chunk provider for this world. Called in the constructor. + * Retrieves provider from worldProvider? + */ + protected IChunkProvider createChunkProvider() { + IChunkLoader var1 = this.saveHandler.getChunkLoader(this.provider); + this.theChunkProviderServer = new ChunkProviderServer(this, var1, this.provider.createChunkGenerator()); + return this.theChunkProviderServer; + } + + /** + * get a list of tileEntity's + */ + public List getTileEntityList(int par1, int par2, int par3, int par4, int par5, int par6) { + ArrayList var7 = new ArrayList(); + + for (int var8 = 0; var8 < this.loadedTileEntityList.size(); ++var8) { + TileEntity var9 = (TileEntity) this.loadedTileEntityList.get(var8); + + if (var9.xCoord >= par1 && var9.yCoord >= par2 && var9.zCoord >= par3 && var9.xCoord < par4 + && var9.yCoord < par5 && var9.zCoord < par6) { + var7.add(var9); + } + } + + return var7; + } + + /** + * Called when checking if a certain block can be mined or not. The 'spawn safe + * zone' check is located here. + */ + public boolean canMineBlock(EntityPlayer par1EntityPlayer, int par2, int par3, int par4) { + return !this.mcServer.func_96290_a(this, par2, par3, par4, par1EntityPlayer); + } + + protected void initialize(WorldSettings par1WorldSettings) { + if (this.entityIdMap == null) { + this.entityIdMap = new IntHashMap(); + } + + if (this.field_73064_N == null) { + this.field_73064_N = new HashSet(); + } + + if (this.pendingTickListEntries == null) { + this.pendingTickListEntries = new TreeSet(); + } + + this.createSpawnPosition(par1WorldSettings); + super.initialize(par1WorldSettings); + } + + /** + * creates a spawn position at random within 256 blocks of 0,0 + */ + protected void createSpawnPosition(WorldSettings par1WorldSettings) { + if (!this.provider.canRespawnHere()) { + this.worldInfo.setSpawnPosition(0, this.provider.getAverageGroundLevel(), 0); + } else { + this.findingSpawnPoint = true; + WorldChunkManager var2 = this.provider.worldChunkMgr; + List var3 = var2.getBiomesToSpawnIn(); + Random var4 = new Random(this.getSeed()); + ChunkPosition var5 = var2.findBiomePosition(0, 0, 256, var3, var4); + int var6 = 0; + int var7 = this.provider.getAverageGroundLevel(); + int var8 = 0; + + if (var5 != null) { + var6 = var5.x; + var8 = var5.z; + } else { + this.getWorldLogAgent().func_98236_b("Unable to find spawn biome"); + } + + int var9 = 0; + + while (!this.provider.canCoordinateBeSpawn(var6, var8)) { + var6 += var4.nextInt(64) - var4.nextInt(64); + var8 += var4.nextInt(64) - var4.nextInt(64); + ++var9; + + if (var9 == 1000) { + break; + } + } + + this.worldInfo.setSpawnPosition(var6, var7, var8); + this.findingSpawnPoint = false; + + if (par1WorldSettings.isBonusChestEnabled()) { + this.createBonusChest(); + } + } + } + + /** + * Creates the bonus chest in the world. + */ + protected void createBonusChest() { + WorldGeneratorBonusChest var1 = new WorldGeneratorBonusChest(bonusChestContent, 10); + + for (int var2 = 0; var2 < 10; ++var2) { + int var3 = this.worldInfo.getSpawnX() + this.rand.nextInt(6) - this.rand.nextInt(6); + int var4 = this.worldInfo.getSpawnZ() + this.rand.nextInt(6) - this.rand.nextInt(6); + int var5 = this.getTopSolidOrLiquidBlock(var3, var4) + 1; + + if (var1.generate(this, this.rand, var3, var5, var4)) { + break; + } + } + } + + /** + * Gets the hard-coded portal location to use when entering this dimension. + */ + public ChunkCoordinates getEntrancePortalLocation() { + return this.provider.getEntrancePortalLocation(); + } + + /** + * Saves all chunks to disk while updating progress bar. + */ + public void saveAllChunks(boolean par1, IProgressUpdate par2IProgressUpdate) throws MinecraftException { + if (this.chunkProvider.canSave()) { + if (par2IProgressUpdate != null) { + par2IProgressUpdate.displaySavingString("Saving level"); + } + + this.saveLevel(); + + if (par2IProgressUpdate != null) { + par2IProgressUpdate.displayLoadingString("Saving chunks"); + } + + this.chunkProvider.saveChunks(par1, par2IProgressUpdate); + } + } + + public void func_104140_m() { + if (this.chunkProvider.canSave()) { + this.chunkProvider.func_104112_b(); + } + } + + /** + * Saves the chunks to disk. + */ + protected void saveLevel() throws MinecraftException { + this.checkSessionLock(); + this.saveHandler.saveWorldInfoWithPlayer(this.worldInfo, + this.mcServer.getConfigurationManager().getHostPlayerData()); + this.mapStorage.saveAllData(); + } + + /** + * Start the skin for this entity downloading, if necessary, and increment its + * reference counter + */ + protected void obtainEntitySkin(Entity par1Entity) { + super.obtainEntitySkin(par1Entity); + this.entityIdMap.addKey(par1Entity.entityId, par1Entity); + Entity[] var2 = par1Entity.getParts(); + + if (var2 != null) { + for (int var3 = 0; var3 < var2.length; ++var3) { + this.entityIdMap.addKey(var2[var3].entityId, var2[var3]); + } + } + } + + /** + * Decrement the reference counter for this entity's skin image data + */ + protected void releaseEntitySkin(Entity par1Entity) { + super.releaseEntitySkin(par1Entity); + this.entityIdMap.removeObject(par1Entity.entityId); + Entity[] var2 = par1Entity.getParts(); + + if (var2 != null) { + for (int var3 = 0; var3 < var2.length; ++var3) { + this.entityIdMap.removeObject(var2[var3].entityId); + } + } + } + + /** + * Returns the Entity with the given ID, or null if it doesn't exist in this + * World. + */ + public Entity getEntityByID(int par1) { + return (Entity) this.entityIdMap.lookup(par1); + } + + /** + * adds a lightning bolt to the list of lightning bolts in this world. + */ + public boolean addWeatherEffect(Entity par1Entity) { + if (super.addWeatherEffect(par1Entity)) { + this.mcServer.getConfigurationManager().sendPacketToPlayersAroundPoint(par1Entity.posX, par1Entity.posY, + par1Entity.posZ, 512.0D, this.provider.dimensionId, new Packet71Weather(par1Entity)); + return true; + } else { + return false; + } + } + + /** + * sends a Packet 38 (Entity Status) to all tracked players of that entity + */ + public void setEntityState(Entity par1Entity, byte par2) { + Packet38EntityStatus var3 = new Packet38EntityStatus(par1Entity.entityId, par2); + this.getEntityTracker().sendPacketToTrackedPlayersAndTrackedEntity(par1Entity, var3); + } + + /** + * returns a new explosion. Does initiation (at time of writing Explosion is not + * finished) + */ + public Explosion newExplosion(Entity par1Entity, double par2, double par4, double par6, float par8, boolean par9, + boolean par10) { + Explosion var11 = new Explosion(this, par1Entity, par2, par4, par6, par8); + var11.isFlaming = par9; + var11.isSmoking = par10; + var11.doExplosionA(); + var11.doExplosionB(false); + + if (!par10) { + var11.affectedBlockPositions.clear(); + } + + Iterator var12 = this.playerEntities.iterator(); + + while (var12.hasNext()) { + EntityPlayer var13 = (EntityPlayer) var12.next(); + + if (var13.getDistanceSq(par2, par4, par6) < 4096.0D) { + ((EntityPlayerMP) var13).playerNetServerHandler.sendPacket(new Packet60Explosion(par2, par4, par6, par8, + var11.affectedBlockPositions, (Vec3) var11.func_77277_b().get(var13))); + } + } + + return var11; + } + + /** + * Adds a block event with the given Args to the blockEventCache. During the + * next tick(), the block specified will have its onBlockEvent handler called + * with the given parameters. Args: X,Y,Z, BlockID, EventID, EventParameter + */ + public void addBlockEvent(int par1, int par2, int par3, int par4, int par5, int par6) { + BlockEventData var7 = new BlockEventData(par1, par2, par3, par4, par5, par6); + Iterator var8 = this.blockEventCache[this.blockEventCacheIndex].iterator(); + BlockEventData var9; + + do { + if (!var8.hasNext()) { + this.blockEventCache[this.blockEventCacheIndex].add(var7); + return; + } + + var9 = (BlockEventData) var8.next(); + } while (!var9.equals(var7)); + } + + /** + * Send and apply locally all pending BlockEvents to each player with 64m radius + * of the event. + */ + private void sendAndApplyBlockEvents() { + while (!this.blockEventCache[this.blockEventCacheIndex].isEmpty()) { + int var1 = this.blockEventCacheIndex; + this.blockEventCacheIndex ^= 1; + Iterator var2 = this.blockEventCache[var1].iterator(); + + while (var2.hasNext()) { + BlockEventData var3 = (BlockEventData) var2.next(); + + if (this.onBlockEventReceived(var3)) { + this.mcServer.getConfigurationManager().sendPacketToPlayersAroundPoint((double) var3.getX(), + (double) var3.getY(), (double) var3.getZ(), 64.0D, this.provider.dimensionId, + new Packet54PlayNoteBlock(var3.getX(), var3.getY(), var3.getZ(), var3.getBlockID(), + var3.getEventID(), var3.getEventParameter())); + } + } + + this.blockEventCache[var1].clear(); + } + } + + /** + * Called to apply a pending BlockEvent to apply to the current world. + */ + private boolean onBlockEventReceived(BlockEventData par1BlockEventData) { + int var2 = this.getBlockId(par1BlockEventData.getX(), par1BlockEventData.getY(), par1BlockEventData.getZ()); + return var2 == par1BlockEventData.getBlockID() ? Block.blocksList[var2].onBlockEventReceived(this, + par1BlockEventData.getX(), par1BlockEventData.getY(), par1BlockEventData.getZ(), + par1BlockEventData.getEventID(), par1BlockEventData.getEventParameter()) : false; + } + + /** + * Syncs all changes to disk and wait for completion. + */ + public void flush() { + this.saveHandler.flush(); + } + + /** + * Updates all weather states. + */ + protected void updateWeather() { + boolean var1 = this.isRaining(); + super.updateWeather(); + + if (var1 != this.isRaining()) { + if (var1) { + this.mcServer.getConfigurationManager().sendPacketToAllPlayers(new Packet70GameEvent(2, 0)); + } else { + this.mcServer.getConfigurationManager().sendPacketToAllPlayers(new Packet70GameEvent(1, 0)); + } + } + } + + /** + * Gets the MinecraftServer. + */ + public MinecraftServer getMinecraftServer() { + return this.mcServer; + } + + /** + * Gets the EntityTracker + */ + public EntityTracker getEntityTracker() { + return this.theEntityTracker; + } + + public PlayerManager getPlayerManager() { + return this.thePlayerManager; + } + + public Teleporter getDefaultTeleporter() { + return this.field_85177_Q; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/WorldServerMulti.java b/sp-server/src/main/java/net/minecraft/src/WorldServerMulti.java new file mode 100644 index 0000000..673b2c0 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/WorldServerMulti.java @@ -0,0 +1,20 @@ +package net.minecraft.src; + +import net.minecraft.server.MinecraftServer; + +public class WorldServerMulti extends WorldServer { + public WorldServerMulti(MinecraftServer par1MinecraftServer, ISaveHandler par2ISaveHandler, String par3Str, + int par4, WorldSettings par5WorldSettings, WorldServer par6WorldServer, Profiler par7Profiler, + ILogAgent par8ILogAgent) { + super(par1MinecraftServer, par2ISaveHandler, par3Str, par4, par5WorldSettings, par7Profiler, par8ILogAgent); + this.mapStorage = par6WorldServer.mapStorage; + this.worldScoreboard = par6WorldServer.getScoreboard(); + this.worldInfo = new DerivedWorldInfo(par6WorldServer.getWorldInfo()); + } + + /** + * Saves the chunks to disk. + */ + protected void saveLevel() throws MinecraftException { + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/WorldSettings.java b/sp-server/src/main/java/net/minecraft/src/WorldSettings.java new file mode 100644 index 0000000..c57e2cc --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/WorldSettings.java @@ -0,0 +1,111 @@ +package net.minecraft.src; + +public final class WorldSettings { + /** The seed for the map. */ + private final long seed; + + /** The EnumGameType. */ + private final EnumGameType theGameType; + + /** + * Switch for the map features. 'true' for enabled, 'false' for disabled. + */ + private final boolean mapFeaturesEnabled; + + /** True if hardcore mode is enabled */ + private final boolean hardcoreEnabled; + private final WorldType terrainType; + + /** True if Commands (cheats) are allowed. */ + private boolean commandsAllowed; + + /** True if the Bonus Chest is enabled. */ + private boolean bonusChestEnabled; + private String field_82751_h; + + public WorldSettings(long par1, EnumGameType par3EnumGameType, boolean par4, boolean par5, + WorldType par6WorldType) { + this.field_82751_h = ""; + this.seed = par1; + this.theGameType = par3EnumGameType; + this.mapFeaturesEnabled = par4; + this.hardcoreEnabled = par5; + this.terrainType = par6WorldType; + } + + public WorldSettings(WorldInfo par1WorldInfo) { + this(par1WorldInfo.getSeed(), par1WorldInfo.getGameType(), par1WorldInfo.isMapFeaturesEnabled(), + par1WorldInfo.isHardcoreModeEnabled(), par1WorldInfo.getTerrainType()); + } + + /** + * Enables the bonus chest. + */ + public WorldSettings enableBonusChest() { + this.bonusChestEnabled = true; + return this; + } + + public WorldSettings func_82750_a(String par1Str) { + this.field_82751_h = par1Str; + return this; + } + + /** + * Returns true if the Bonus Chest is enabled. + */ + public boolean isBonusChestEnabled() { + return this.bonusChestEnabled; + } + + /** + * Returns the seed for the world. + */ + public long getSeed() { + return this.seed; + } + + /** + * Gets the game type. + */ + public EnumGameType getGameType() { + return this.theGameType; + } + + /** + * Returns true if hardcore mode is enabled, otherwise false + */ + public boolean getHardcoreEnabled() { + return this.hardcoreEnabled; + } + + /** + * Get whether the map features (e.g. strongholds) generation is enabled or + * disabled. + */ + public boolean isMapFeaturesEnabled() { + return this.mapFeaturesEnabled; + } + + public WorldType getTerrainType() { + return this.terrainType; + } + + /** + * Returns true if Commands (cheats) are allowed. + */ + public boolean areCommandsAllowed() { + return this.commandsAllowed; + } + + /** + * Gets the GameType by ID + */ + public static EnumGameType getGameTypeById(int par0) { + return EnumGameType.getByID(par0); + } + + public String func_82749_j() { + return this.field_82751_h; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/WorldType.java b/sp-server/src/main/java/net/minecraft/src/WorldType.java new file mode 100644 index 0000000..af12217 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/WorldType.java @@ -0,0 +1,98 @@ +package net.minecraft.src; + +public class WorldType { + /** List of world types. */ + public static final WorldType[] worldTypes = new WorldType[16]; + + /** Default world type. */ + public static final WorldType DEFAULT = (new WorldType(0, "default", 1)).setVersioned(); + + /** Flat world type. */ + public static final WorldType FLAT = new WorldType(1, "flat"); + + /** Large Biome world Type. */ + public static final WorldType LARGE_BIOMES = new WorldType(2, "largeBiomes"); + + /** Default (1.1) world type. */ + public static final WorldType DEFAULT_1_1 = (new WorldType(8, "default_1_1", 0)).setCanBeCreated(false); + + /** ID for this world type. */ + private final int worldTypeId; + private final String worldType; + + /** The int version of the ChunkProvider that generated this world. */ + private final int generatorVersion; + + /** + * Whether this world type can be generated. Normally true; set to false for + * out-of-date generator versions. + */ + private boolean canBeCreated; + + /** Whether this WorldType has a version or not. */ + private boolean isWorldTypeVersioned; + + private WorldType(int par1, String par2Str) { + this(par1, par2Str, 0); + } + + private WorldType(int par1, String par2Str, int par3) { + this.worldType = par2Str; + this.generatorVersion = par3; + this.canBeCreated = true; + this.worldTypeId = par1; + worldTypes[par1] = this; + } + + public String getWorldTypeName() { + return this.worldType; + } + + /** + * Returns generatorVersion. + */ + public int getGeneratorVersion() { + return this.generatorVersion; + } + + public WorldType getWorldTypeForGeneratorVersion(int par1) { + return this == DEFAULT && par1 == 0 ? DEFAULT_1_1 : this; + } + + /** + * Sets canBeCreated to the provided value, and returns this. + */ + private WorldType setCanBeCreated(boolean par1) { + this.canBeCreated = par1; + return this; + } + + /** + * Flags this world type as having an associated version. + */ + private WorldType setVersioned() { + this.isWorldTypeVersioned = true; + return this; + } + + /** + * Returns true if this world Type has a version associated with it. + */ + public boolean isVersioned() { + return this.isWorldTypeVersioned; + } + + public static WorldType parseWorldType(String par0Str) { + for (int var1 = 0; var1 < worldTypes.length; ++var1) { + if (worldTypes[var1] != null && worldTypes[var1].worldType.equalsIgnoreCase(par0Str)) { + return worldTypes[var1]; + } + } + + return null; + } + + public int getWorldTypeID() { + return this.worldTypeId; + } +} diff --git a/sp-server/src/main/java/net/minecraft/src/WrongUsageException.java b/sp-server/src/main/java/net/minecraft/src/WrongUsageException.java new file mode 100644 index 0000000..fa83809 --- /dev/null +++ b/sp-server/src/main/java/net/minecraft/src/WrongUsageException.java @@ -0,0 +1,7 @@ +package net.minecraft.src; + +public class WrongUsageException extends SyntaxErrorException { + public WrongUsageException(String par1Str, Object... par2ArrayOfObj) { + super(par1Str, par2ArrayOfObj); + } +} diff --git a/sp-server/src/main/java/org/bouncycastle/asn1/ASN1Encodable.java b/sp-server/src/main/java/org/bouncycastle/asn1/ASN1Encodable.java new file mode 100644 index 0000000..9e61164 --- /dev/null +++ b/sp-server/src/main/java/org/bouncycastle/asn1/ASN1Encodable.java @@ -0,0 +1,5 @@ +package org.bouncycastle.asn1; + +public interface ASN1Encodable { + ASN1Primitive toASN1Primitive(); +} diff --git a/sp-server/src/main/java/org/bouncycastle/asn1/ASN1Object.java b/sp-server/src/main/java/org/bouncycastle/asn1/ASN1Object.java new file mode 100644 index 0000000..e91b5c7 --- /dev/null +++ b/sp-server/src/main/java/org/bouncycastle/asn1/ASN1Object.java @@ -0,0 +1,20 @@ +package org.bouncycastle.asn1; + +public abstract class ASN1Object implements ASN1Encodable { + public int hashCode() { + return this.toASN1Primitive().hashCode(); + } + + public boolean equals(Object par1Obj) { + if (this == par1Obj) { + return true; + } else if (!(par1Obj instanceof ASN1Encodable)) { + return false; + } else { + ASN1Encodable var2 = (ASN1Encodable) par1Obj; + return this.toASN1Primitive().equals(var2.toASN1Primitive()); + } + } + + public abstract ASN1Primitive toASN1Primitive(); +} diff --git a/sp-server/src/main/java/org/bouncycastle/asn1/ASN1ObjectIdentifier.java b/sp-server/src/main/java/org/bouncycastle/asn1/ASN1ObjectIdentifier.java new file mode 100644 index 0000000..bde75a4 --- /dev/null +++ b/sp-server/src/main/java/org/bouncycastle/asn1/ASN1ObjectIdentifier.java @@ -0,0 +1,11 @@ +package org.bouncycastle.asn1; + +public class ASN1ObjectIdentifier extends DERObjectIdentifier { + public ASN1ObjectIdentifier(String par1Str) { + super(par1Str); + } + + public ASN1ObjectIdentifier branch(String par1Str) { + return new ASN1ObjectIdentifier(this.getId() + "." + par1Str); + } +} diff --git a/sp-server/src/main/java/org/bouncycastle/asn1/ASN1Primitive.java b/sp-server/src/main/java/org/bouncycastle/asn1/ASN1Primitive.java new file mode 100644 index 0000000..c565be3 --- /dev/null +++ b/sp-server/src/main/java/org/bouncycastle/asn1/ASN1Primitive.java @@ -0,0 +1,16 @@ +package org.bouncycastle.asn1; + +public abstract class ASN1Primitive extends ASN1Object { + public final boolean equals(Object par1Obj) { + return this == par1Obj ? true + : par1Obj instanceof ASN1Encodable && this.asn1Equals(((ASN1Encodable) par1Obj).toASN1Primitive()); + } + + public ASN1Primitive toASN1Primitive() { + return this; + } + + public abstract int hashCode(); + + abstract boolean asn1Equals(ASN1Primitive var1); +} diff --git a/sp-server/src/main/java/org/bouncycastle/asn1/DERObjectIdentifier.java b/sp-server/src/main/java/org/bouncycastle/asn1/DERObjectIdentifier.java new file mode 100644 index 0000000..bcc5778 --- /dev/null +++ b/sp-server/src/main/java/org/bouncycastle/asn1/DERObjectIdentifier.java @@ -0,0 +1,65 @@ +package org.bouncycastle.asn1; + +public class DERObjectIdentifier extends ASN1Primitive { + String identifier; + private static ASN1ObjectIdentifier[][] cache = new ASN1ObjectIdentifier[255][]; + + public DERObjectIdentifier(String par1Str) { + if (!isValidIdentifier(par1Str)) { + throw new IllegalArgumentException("string " + par1Str + " not an OID"); + } else { + this.identifier = par1Str; + } + } + + public String getId() { + return this.identifier; + } + + public int hashCode() { + return this.identifier.hashCode(); + } + + boolean asn1Equals(ASN1Primitive par1ASN1Primitive) { + return !(par1ASN1Primitive instanceof DERObjectIdentifier) ? false + : this.identifier.equals(((DERObjectIdentifier) par1ASN1Primitive).identifier); + } + + public String toString() { + return this.getId(); + } + + private static boolean isValidIdentifier(String par0Str) { + if (par0Str.length() >= 3 && par0Str.charAt(1) == 46) { + char var1 = par0Str.charAt(0); + + if (var1 >= 48 && var1 <= 50) { + boolean var2 = false; + + for (int var3 = par0Str.length() - 1; var3 >= 2; --var3) { + char var4 = par0Str.charAt(var3); + + if (48 <= var4 && var4 <= 57) { + var2 = true; + } else { + if (var4 != 46) { + return false; + } + + if (!var2) { + return false; + } + + var2 = false; + } + } + + return var2; + } else { + return false; + } + } else { + return false; + } + } +} diff --git a/sp-server/src/main/java/org/bouncycastle/asn1/bc/BCObjectIdentifiers.java b/sp-server/src/main/java/org/bouncycastle/asn1/bc/BCObjectIdentifiers.java new file mode 100644 index 0000000..db102a6 --- /dev/null +++ b/sp-server/src/main/java/org/bouncycastle/asn1/bc/BCObjectIdentifiers.java @@ -0,0 +1,26 @@ +package org.bouncycastle.asn1.bc; + +import org.bouncycastle.asn1.ASN1ObjectIdentifier; + +public interface BCObjectIdentifiers { + ASN1ObjectIdentifier bc = new ASN1ObjectIdentifier("1.3.6.1.4.1.22554"); + ASN1ObjectIdentifier bc_pbe = new ASN1ObjectIdentifier(bc.getId() + ".1"); + ASN1ObjectIdentifier bc_pbe_sha1 = new ASN1ObjectIdentifier(bc_pbe.getId() + ".1"); + ASN1ObjectIdentifier bc_pbe_sha256 = new ASN1ObjectIdentifier(bc_pbe.getId() + ".2.1"); + ASN1ObjectIdentifier bc_pbe_sha384 = new ASN1ObjectIdentifier(bc_pbe.getId() + ".2.2"); + ASN1ObjectIdentifier bc_pbe_sha512 = new ASN1ObjectIdentifier(bc_pbe.getId() + ".2.3"); + ASN1ObjectIdentifier bc_pbe_sha224 = new ASN1ObjectIdentifier(bc_pbe.getId() + ".2.4"); + ASN1ObjectIdentifier bc_pbe_sha1_pkcs5 = new ASN1ObjectIdentifier(bc_pbe_sha1.getId() + ".1"); + ASN1ObjectIdentifier bc_pbe_sha1_pkcs12 = new ASN1ObjectIdentifier(bc_pbe_sha1.getId() + ".2"); + ASN1ObjectIdentifier bc_pbe_sha256_pkcs5 = new ASN1ObjectIdentifier(bc_pbe_sha256.getId() + ".1"); + ASN1ObjectIdentifier bc_pbe_sha256_pkcs12 = new ASN1ObjectIdentifier(bc_pbe_sha256.getId() + ".2"); + ASN1ObjectIdentifier bc_pbe_sha1_pkcs12_aes128_cbc = new ASN1ObjectIdentifier(bc_pbe_sha1_pkcs12.getId() + ".1.2"); + ASN1ObjectIdentifier bc_pbe_sha1_pkcs12_aes192_cbc = new ASN1ObjectIdentifier(bc_pbe_sha1_pkcs12.getId() + ".1.22"); + ASN1ObjectIdentifier bc_pbe_sha1_pkcs12_aes256_cbc = new ASN1ObjectIdentifier(bc_pbe_sha1_pkcs12.getId() + ".1.42"); + ASN1ObjectIdentifier bc_pbe_sha256_pkcs12_aes128_cbc = new ASN1ObjectIdentifier( + bc_pbe_sha256_pkcs12.getId() + ".1.2"); + ASN1ObjectIdentifier bc_pbe_sha256_pkcs12_aes192_cbc = new ASN1ObjectIdentifier( + bc_pbe_sha256_pkcs12.getId() + ".1.22"); + ASN1ObjectIdentifier bc_pbe_sha256_pkcs12_aes256_cbc = new ASN1ObjectIdentifier( + bc_pbe_sha256_pkcs12.getId() + ".1.42"); +} diff --git a/sp-server/src/main/java/org/bouncycastle/asn1/pkcs/PKCSObjectIdentifiers.java b/sp-server/src/main/java/org/bouncycastle/asn1/pkcs/PKCSObjectIdentifiers.java new file mode 100644 index 0000000..9242ef5 --- /dev/null +++ b/sp-server/src/main/java/org/bouncycastle/asn1/pkcs/PKCSObjectIdentifiers.java @@ -0,0 +1,135 @@ +package org.bouncycastle.asn1.pkcs; + +import org.bouncycastle.asn1.ASN1ObjectIdentifier; + +public interface PKCSObjectIdentifiers { + ASN1ObjectIdentifier pkcs_1 = new ASN1ObjectIdentifier("1.2.840.113549.1.1"); + ASN1ObjectIdentifier rsaEncryption = pkcs_1.branch("1"); + ASN1ObjectIdentifier md2WithRSAEncryption = pkcs_1.branch("2"); + ASN1ObjectIdentifier md4WithRSAEncryption = pkcs_1.branch("3"); + ASN1ObjectIdentifier md5WithRSAEncryption = pkcs_1.branch("4"); + ASN1ObjectIdentifier sha1WithRSAEncryption = pkcs_1.branch("5"); + ASN1ObjectIdentifier srsaOAEPEncryptionSET = pkcs_1.branch("6"); + ASN1ObjectIdentifier id_RSAES_OAEP = pkcs_1.branch("7"); + ASN1ObjectIdentifier id_mgf1 = pkcs_1.branch("8"); + ASN1ObjectIdentifier id_pSpecified = pkcs_1.branch("9"); + ASN1ObjectIdentifier id_RSASSA_PSS = pkcs_1.branch("10"); + ASN1ObjectIdentifier sha256WithRSAEncryption = pkcs_1.branch("11"); + ASN1ObjectIdentifier sha384WithRSAEncryption = pkcs_1.branch("12"); + ASN1ObjectIdentifier sha512WithRSAEncryption = pkcs_1.branch("13"); + ASN1ObjectIdentifier sha224WithRSAEncryption = pkcs_1.branch("14"); + ASN1ObjectIdentifier pkcs_3 = new ASN1ObjectIdentifier("1.2.840.113549.1.3"); + ASN1ObjectIdentifier dhKeyAgreement = pkcs_3.branch("1"); + ASN1ObjectIdentifier pkcs_5 = new ASN1ObjectIdentifier("1.2.840.113549.1.5"); + ASN1ObjectIdentifier pbeWithMD2AndDES_CBC = pkcs_5.branch("1"); + ASN1ObjectIdentifier pbeWithMD2AndRC2_CBC = pkcs_5.branch("4"); + ASN1ObjectIdentifier pbeWithMD5AndDES_CBC = pkcs_5.branch("3"); + ASN1ObjectIdentifier pbeWithMD5AndRC2_CBC = pkcs_5.branch("6"); + ASN1ObjectIdentifier pbeWithSHA1AndDES_CBC = pkcs_5.branch("10"); + ASN1ObjectIdentifier pbeWithSHA1AndRC2_CBC = pkcs_5.branch("11"); + ASN1ObjectIdentifier id_PBES2 = pkcs_5.branch("13"); + ASN1ObjectIdentifier id_PBKDF2 = pkcs_5.branch("12"); + ASN1ObjectIdentifier encryptionAlgorithm = new ASN1ObjectIdentifier("1.2.840.113549.3"); + ASN1ObjectIdentifier des_EDE3_CBC = encryptionAlgorithm.branch("7"); + ASN1ObjectIdentifier RC2_CBC = encryptionAlgorithm.branch("2"); + ASN1ObjectIdentifier digestAlgorithm = new ASN1ObjectIdentifier("1.2.840.113549.2"); + ASN1ObjectIdentifier md2 = digestAlgorithm.branch("2"); + ASN1ObjectIdentifier md4 = digestAlgorithm.branch("4"); + ASN1ObjectIdentifier md5 = digestAlgorithm.branch("5"); + ASN1ObjectIdentifier id_hmacWithSHA1 = digestAlgorithm.branch("7"); + ASN1ObjectIdentifier id_hmacWithSHA224 = digestAlgorithm.branch("8"); + ASN1ObjectIdentifier id_hmacWithSHA256 = digestAlgorithm.branch("9"); + ASN1ObjectIdentifier id_hmacWithSHA384 = digestAlgorithm.branch("10"); + ASN1ObjectIdentifier id_hmacWithSHA512 = digestAlgorithm.branch("11"); + ASN1ObjectIdentifier data = new ASN1ObjectIdentifier("1.2.840.113549.1.7.1"); + ASN1ObjectIdentifier signedData = new ASN1ObjectIdentifier("1.2.840.113549.1.7.2"); + ASN1ObjectIdentifier envelopedData = new ASN1ObjectIdentifier("1.2.840.113549.1.7.3"); + ASN1ObjectIdentifier signedAndEnvelopedData = new ASN1ObjectIdentifier("1.2.840.113549.1.7.4"); + ASN1ObjectIdentifier digestedData = new ASN1ObjectIdentifier("1.2.840.113549.1.7.5"); + ASN1ObjectIdentifier encryptedData = new ASN1ObjectIdentifier("1.2.840.113549.1.7.6"); + ASN1ObjectIdentifier pkcs_9 = new ASN1ObjectIdentifier("1.2.840.113549.1.9"); + ASN1ObjectIdentifier pkcs_9_at_emailAddress = pkcs_9.branch("1"); + ASN1ObjectIdentifier pkcs_9_at_unstructuredName = pkcs_9.branch("2"); + ASN1ObjectIdentifier pkcs_9_at_contentType = pkcs_9.branch("3"); + ASN1ObjectIdentifier pkcs_9_at_messageDigest = pkcs_9.branch("4"); + ASN1ObjectIdentifier pkcs_9_at_signingTime = pkcs_9.branch("5"); + ASN1ObjectIdentifier pkcs_9_at_counterSignature = pkcs_9.branch("6"); + ASN1ObjectIdentifier pkcs_9_at_challengePassword = pkcs_9.branch("7"); + ASN1ObjectIdentifier pkcs_9_at_unstructuredAddress = pkcs_9.branch("8"); + ASN1ObjectIdentifier pkcs_9_at_extendedCertificateAttributes = pkcs_9.branch("9"); + ASN1ObjectIdentifier pkcs_9_at_signingDescription = pkcs_9.branch("13"); + ASN1ObjectIdentifier pkcs_9_at_extensionRequest = pkcs_9.branch("14"); + ASN1ObjectIdentifier pkcs_9_at_smimeCapabilities = pkcs_9.branch("15"); + ASN1ObjectIdentifier pkcs_9_at_friendlyName = pkcs_9.branch("20"); + ASN1ObjectIdentifier pkcs_9_at_localKeyId = pkcs_9.branch("21"); + ASN1ObjectIdentifier x509certType = pkcs_9.branch("22.1"); + ASN1ObjectIdentifier certTypes = pkcs_9.branch("22"); + ASN1ObjectIdentifier x509Certificate = certTypes.branch("1"); + ASN1ObjectIdentifier sdsiCertificate = certTypes.branch("2"); + ASN1ObjectIdentifier crlTypes = pkcs_9.branch("23"); + ASN1ObjectIdentifier x509Crl = crlTypes.branch("1"); + ASN1ObjectIdentifier id_alg_PWRI_KEK = pkcs_9.branch("16.3.9"); + ASN1ObjectIdentifier preferSignedData = pkcs_9.branch("15.1"); + ASN1ObjectIdentifier canNotDecryptAny = pkcs_9.branch("15.2"); + ASN1ObjectIdentifier sMIMECapabilitiesVersions = pkcs_9.branch("15.3"); + ASN1ObjectIdentifier id_ct = new ASN1ObjectIdentifier("1.2.840.113549.1.9.16.1"); + ASN1ObjectIdentifier id_ct_authData = id_ct.branch("2"); + ASN1ObjectIdentifier id_ct_TSTInfo = id_ct.branch("4"); + ASN1ObjectIdentifier id_ct_compressedData = id_ct.branch("9"); + ASN1ObjectIdentifier id_ct_authEnvelopedData = id_ct.branch("23"); + ASN1ObjectIdentifier id_ct_timestampedData = id_ct.branch("31"); + ASN1ObjectIdentifier id_cti = new ASN1ObjectIdentifier("1.2.840.113549.1.9.16.6"); + ASN1ObjectIdentifier id_cti_ets_proofOfOrigin = id_cti.branch("1"); + ASN1ObjectIdentifier id_cti_ets_proofOfReceipt = id_cti.branch("2"); + ASN1ObjectIdentifier id_cti_ets_proofOfDelivery = id_cti.branch("3"); + ASN1ObjectIdentifier id_cti_ets_proofOfSender = id_cti.branch("4"); + ASN1ObjectIdentifier id_cti_ets_proofOfApproval = id_cti.branch("5"); + ASN1ObjectIdentifier id_cti_ets_proofOfCreation = id_cti.branch("6"); + ASN1ObjectIdentifier id_aa = new ASN1ObjectIdentifier("1.2.840.113549.1.9.16.2"); + ASN1ObjectIdentifier id_aa_receiptRequest = id_aa.branch("1"); + ASN1ObjectIdentifier id_aa_contentHint = id_aa.branch("4"); + ASN1ObjectIdentifier id_aa_msgSigDigest = id_aa.branch("5"); + ASN1ObjectIdentifier id_aa_contentReference = id_aa.branch("10"); + ASN1ObjectIdentifier id_aa_encrypKeyPref = id_aa.branch("11"); + ASN1ObjectIdentifier id_aa_signingCertificate = id_aa.branch("12"); + ASN1ObjectIdentifier id_aa_signingCertificateV2 = id_aa.branch("47"); + ASN1ObjectIdentifier id_aa_contentIdentifier = id_aa.branch("7"); + ASN1ObjectIdentifier id_aa_signatureTimeStampToken = id_aa.branch("14"); + ASN1ObjectIdentifier id_aa_ets_sigPolicyId = id_aa.branch("15"); + ASN1ObjectIdentifier id_aa_ets_commitmentType = id_aa.branch("16"); + ASN1ObjectIdentifier id_aa_ets_signerLocation = id_aa.branch("17"); + ASN1ObjectIdentifier id_aa_ets_signerAttr = id_aa.branch("18"); + ASN1ObjectIdentifier id_aa_ets_otherSigCert = id_aa.branch("19"); + ASN1ObjectIdentifier id_aa_ets_contentTimestamp = id_aa.branch("20"); + ASN1ObjectIdentifier id_aa_ets_certificateRefs = id_aa.branch("21"); + ASN1ObjectIdentifier id_aa_ets_revocationRefs = id_aa.branch("22"); + ASN1ObjectIdentifier id_aa_ets_certValues = id_aa.branch("23"); + ASN1ObjectIdentifier id_aa_ets_revocationValues = id_aa.branch("24"); + ASN1ObjectIdentifier id_aa_ets_escTimeStamp = id_aa.branch("25"); + ASN1ObjectIdentifier id_aa_ets_certCRLTimestamp = id_aa.branch("26"); + ASN1ObjectIdentifier id_aa_ets_archiveTimestamp = id_aa.branch("27"); + ASN1ObjectIdentifier id_aa_sigPolicyId = id_aa_ets_sigPolicyId; + ASN1ObjectIdentifier id_aa_commitmentType = id_aa_ets_commitmentType; + ASN1ObjectIdentifier id_aa_signerLocation = id_aa_ets_signerLocation; + ASN1ObjectIdentifier id_aa_otherSigCert = id_aa_ets_otherSigCert; + ASN1ObjectIdentifier id_spq_ets_uri = new ASN1ObjectIdentifier("1.2.840.113549.1.9.16.5.1"); + ASN1ObjectIdentifier id_spq_ets_unotice = new ASN1ObjectIdentifier("1.2.840.113549.1.9.16.5.2"); + ASN1ObjectIdentifier pkcs_12 = new ASN1ObjectIdentifier("1.2.840.113549.1.12"); + ASN1ObjectIdentifier bagtypes = pkcs_12.branch("10.1"); + ASN1ObjectIdentifier keyBag = bagtypes.branch("1"); + ASN1ObjectIdentifier pkcs8ShroudedKeyBag = bagtypes.branch("2"); + ASN1ObjectIdentifier certBag = bagtypes.branch("3"); + ASN1ObjectIdentifier crlBag = bagtypes.branch("4"); + ASN1ObjectIdentifier secretBag = bagtypes.branch("5"); + ASN1ObjectIdentifier safeContentsBag = bagtypes.branch("6"); + ASN1ObjectIdentifier pkcs_12PbeIds = pkcs_12.branch("1"); + ASN1ObjectIdentifier pbeWithSHAAnd128BitRC4 = pkcs_12PbeIds.branch("1"); + ASN1ObjectIdentifier pbeWithSHAAnd40BitRC4 = pkcs_12PbeIds.branch("2"); + ASN1ObjectIdentifier pbeWithSHAAnd3_KeyTripleDES_CBC = pkcs_12PbeIds.branch("3"); + ASN1ObjectIdentifier pbeWithSHAAnd2_KeyTripleDES_CBC = pkcs_12PbeIds.branch("4"); + ASN1ObjectIdentifier pbeWithSHAAnd128BitRC2_CBC = pkcs_12PbeIds.branch("5"); + ASN1ObjectIdentifier pbeWithSHAAnd40BitRC2_CBC = pkcs_12PbeIds.branch("6"); + ASN1ObjectIdentifier pbewithSHAAnd40BitRC2_CBC = pkcs_12PbeIds.branch("6"); + ASN1ObjectIdentifier id_alg_CMS3DESwrap = new ASN1ObjectIdentifier("1.2.840.113549.1.9.16.3.6"); + ASN1ObjectIdentifier id_alg_CMSRC2wrap = new ASN1ObjectIdentifier("1.2.840.113549.1.9.16.3.7"); +} diff --git a/sp-server/src/main/java/org/bouncycastle/crypto/BlockCipher.java b/sp-server/src/main/java/org/bouncycastle/crypto/BlockCipher.java new file mode 100644 index 0000000..470e87b --- /dev/null +++ b/sp-server/src/main/java/org/bouncycastle/crypto/BlockCipher.java @@ -0,0 +1,19 @@ +package org.bouncycastle.crypto; + +public interface BlockCipher { + void init(boolean var1, CipherParameters var2) throws IllegalArgumentException; + + /** + * Return the name of the algorithm the cipher implements. + */ + String getAlgorithmName(); + + /** + * Return the block size for this cipher (in bytes). + */ + int getBlockSize(); + + int processBlock(byte[] var1, int var2, byte[] var3, int var4) throws DataLengthException, IllegalStateException; + + void reset(); +} diff --git a/sp-server/src/main/java/org/bouncycastle/crypto/BufferedBlockCipher.java b/sp-server/src/main/java/org/bouncycastle/crypto/BufferedBlockCipher.java new file mode 100644 index 0000000..829285a --- /dev/null +++ b/sp-server/src/main/java/org/bouncycastle/crypto/BufferedBlockCipher.java @@ -0,0 +1,134 @@ +package org.bouncycastle.crypto; + +public class BufferedBlockCipher { + protected byte[] buf; + protected int bufOff; + protected boolean forEncryption; + protected BlockCipher cipher; + protected boolean partialBlockOkay; + protected boolean pgpCFB; + + protected BufferedBlockCipher() { + } + + public BufferedBlockCipher(BlockCipher par1BlockCipher) { + this.cipher = par1BlockCipher; + this.buf = new byte[par1BlockCipher.getBlockSize()]; + this.bufOff = 0; + String var2 = par1BlockCipher.getAlgorithmName(); + int var3 = var2.indexOf(47) + 1; + this.pgpCFB = var3 > 0 && var2.startsWith("PGP", var3); + + if (this.pgpCFB) { + this.partialBlockOkay = true; + } else { + this.partialBlockOkay = var3 > 0 + && (var2.startsWith("CFB", var3) || var2.startsWith("OFB", var3) || var2.startsWith("OpenPGP", var3) + || var2.startsWith("SIC", var3) || var2.startsWith("GCTR", var3)); + } + } + + public void init(boolean par1, CipherParameters par2CipherParameters) throws IllegalArgumentException { + this.forEncryption = par1; + this.reset(); + this.cipher.init(par1, par2CipherParameters); + } + + public int getBlockSize() { + return this.cipher.getBlockSize(); + } + + public int getUpdateOutputSize(int par1) { + int var2 = par1 + this.bufOff; + int var3; + + if (this.pgpCFB) { + var3 = var2 % this.buf.length - (this.cipher.getBlockSize() + 2); + } else { + var3 = var2 % this.buf.length; + } + + return var2 - var3; + } + + public int getOutputSize(int par1) { + return par1 + this.bufOff; + } + + public int processByte(byte[] par1ArrayOfByte, int par2, int par3, byte[] par4ArrayOfByte, int par5) + throws DataLengthException, IllegalStateException { + if (par3 < 0) { + throw new IllegalArgumentException("Can\'t have a negative input length!"); + } else { + int var6 = this.getBlockSize(); + int var7 = this.getUpdateOutputSize(par3); + + if (var7 > 0 && par5 + var7 > par4ArrayOfByte.length) { + throw new DataLengthException("output buffer too short"); + } else { + int var8 = 0; + int var9 = this.buf.length - this.bufOff; + + if (par3 > var9) { + System.arraycopy(par1ArrayOfByte, par2, this.buf, this.bufOff, var9); + var8 += this.cipher.processBlock(this.buf, 0, par4ArrayOfByte, par5); + this.bufOff = 0; + par3 -= var9; + + for (par2 += var9; par3 > this.buf.length; par2 += var6) { + var8 += this.cipher.processBlock(par1ArrayOfByte, par2, par4ArrayOfByte, par5 + var8); + par3 -= var6; + } + } + + System.arraycopy(par1ArrayOfByte, par2, this.buf, this.bufOff, par3); + this.bufOff += par3; + + if (this.bufOff == this.buf.length) { + var8 += this.cipher.processBlock(this.buf, 0, par4ArrayOfByte, par5 + var8); + this.bufOff = 0; + } + + return var8; + } + } + } + + public int doFinal(byte[] par1ArrayOfByte, int par2) throws DataLengthException, IllegalStateException { + int var4; + + try { + int var3 = 0; + + if (par2 + this.bufOff > par1ArrayOfByte.length) { + throw new DataLengthException("output buffer too short for doFinal()"); + } + + if (this.bufOff != 0) { + if (!this.partialBlockOkay) { + throw new DataLengthException("data not block size aligned"); + } + + this.cipher.processBlock(this.buf, 0, this.buf, 0); + var3 = this.bufOff; + this.bufOff = 0; + System.arraycopy(this.buf, 0, par1ArrayOfByte, par2, var3); + } + + var4 = var3; + } finally { + this.reset(); + } + + return var4; + } + + public void reset() { + for (int var1 = 0; var1 < this.buf.length; ++var1) { + this.buf[var1] = 0; + } + + this.bufOff = 0; + this.cipher.reset(); + } +} diff --git a/sp-server/src/main/java/org/bouncycastle/crypto/CipherParameters.java b/sp-server/src/main/java/org/bouncycastle/crypto/CipherParameters.java new file mode 100644 index 0000000..bd8313a --- /dev/null +++ b/sp-server/src/main/java/org/bouncycastle/crypto/CipherParameters.java @@ -0,0 +1,4 @@ +package org.bouncycastle.crypto; + +public interface CipherParameters { +} diff --git a/sp-server/src/main/java/org/bouncycastle/crypto/DataLengthException.java b/sp-server/src/main/java/org/bouncycastle/crypto/DataLengthException.java new file mode 100644 index 0000000..abf0ec6 --- /dev/null +++ b/sp-server/src/main/java/org/bouncycastle/crypto/DataLengthException.java @@ -0,0 +1,10 @@ +package org.bouncycastle.crypto; + +public class DataLengthException extends RuntimeCryptoException { + public DataLengthException() { + } + + public DataLengthException(String par1Str) { + super(par1Str); + } +} diff --git a/sp-server/src/main/java/org/bouncycastle/crypto/RuntimeCryptoException.java b/sp-server/src/main/java/org/bouncycastle/crypto/RuntimeCryptoException.java new file mode 100644 index 0000000..5d140d6 --- /dev/null +++ b/sp-server/src/main/java/org/bouncycastle/crypto/RuntimeCryptoException.java @@ -0,0 +1,10 @@ +package org.bouncycastle.crypto; + +public class RuntimeCryptoException extends RuntimeException { + public RuntimeCryptoException() { + } + + public RuntimeCryptoException(String par1Str) { + super(par1Str); + } +} diff --git a/sp-server/src/main/java/org/bouncycastle/crypto/StreamCipher.java b/sp-server/src/main/java/org/bouncycastle/crypto/StreamCipher.java new file mode 100644 index 0000000..29f85bb --- /dev/null +++ b/sp-server/src/main/java/org/bouncycastle/crypto/StreamCipher.java @@ -0,0 +1,10 @@ +package org.bouncycastle.crypto; + +public interface StreamCipher { + /** + * Encrypt/decrypt a single byte, returning the result. + */ + byte returnByte(byte var1); + + void processBytes(byte[] var1, int var2, int var3, byte[] var4, int var5) throws DataLengthException; +} diff --git a/sp-server/src/main/java/org/bouncycastle/crypto/engines/AESFastEngine.java b/sp-server/src/main/java/org/bouncycastle/crypto/engines/AESFastEngine.java new file mode 100644 index 0000000..8ae9380 --- /dev/null +++ b/sp-server/src/main/java/org/bouncycastle/crypto/engines/AESFastEngine.java @@ -0,0 +1,565 @@ +package org.bouncycastle.crypto.engines; + +import org.bouncycastle.crypto.BlockCipher; +import org.bouncycastle.crypto.CipherParameters; +import org.bouncycastle.crypto.DataLengthException; +import org.bouncycastle.crypto.params.KeyParameter; + +public class AESFastEngine implements BlockCipher { + private static final byte[] S = new byte[] { (byte) 99, (byte) 124, (byte) 119, (byte) 123, (byte) -14, (byte) 107, + (byte) 111, (byte) -59, (byte) 48, (byte) 1, (byte) 103, (byte) 43, (byte) -2, (byte) -41, (byte) -85, + (byte) 118, (byte) -54, (byte) -126, (byte) -55, (byte) 125, (byte) -6, (byte) 89, (byte) 71, (byte) -16, + (byte) -83, (byte) -44, (byte) -94, (byte) -81, (byte) -100, (byte) -92, (byte) 114, (byte) -64, (byte) -73, + (byte) -3, (byte) -109, (byte) 38, (byte) 54, (byte) 63, (byte) -9, (byte) -52, (byte) 52, (byte) -91, + (byte) -27, (byte) -15, (byte) 113, (byte) -40, (byte) 49, (byte) 21, (byte) 4, (byte) -57, (byte) 35, + (byte) -61, (byte) 24, (byte) -106, (byte) 5, (byte) -102, (byte) 7, (byte) 18, (byte) -128, (byte) -30, + (byte) -21, (byte) 39, (byte) -78, (byte) 117, (byte) 9, (byte) -125, (byte) 44, (byte) 26, (byte) 27, + (byte) 110, (byte) 90, (byte) -96, (byte) 82, (byte) 59, (byte) -42, (byte) -77, (byte) 41, (byte) -29, + (byte) 47, (byte) -124, (byte) 83, (byte) -47, (byte) 0, (byte) -19, (byte) 32, (byte) -4, (byte) -79, + (byte) 91, (byte) 106, (byte) -53, (byte) -66, (byte) 57, (byte) 74, (byte) 76, (byte) 88, (byte) -49, + (byte) -48, (byte) -17, (byte) -86, (byte) -5, (byte) 67, (byte) 77, (byte) 51, (byte) -123, (byte) 69, + (byte) -7, (byte) 2, (byte) 127, (byte) 80, (byte) 60, (byte) -97, (byte) -88, (byte) 81, (byte) -93, + (byte) 64, (byte) -113, (byte) -110, (byte) -99, (byte) 56, (byte) -11, (byte) -68, (byte) -74, (byte) -38, + (byte) 33, (byte) 16, (byte) -1, (byte) -13, (byte) -46, (byte) -51, (byte) 12, (byte) 19, (byte) -20, + (byte) 95, (byte) -105, (byte) 68, (byte) 23, (byte) -60, (byte) -89, (byte) 126, (byte) 61, (byte) 100, + (byte) 93, (byte) 25, (byte) 115, (byte) 96, (byte) -127, (byte) 79, (byte) -36, (byte) 34, (byte) 42, + (byte) -112, (byte) -120, (byte) 70, (byte) -18, (byte) -72, (byte) 20, (byte) -34, (byte) 94, (byte) 11, + (byte) -37, (byte) -32, (byte) 50, (byte) 58, (byte) 10, (byte) 73, (byte) 6, (byte) 36, (byte) 92, + (byte) -62, (byte) -45, (byte) -84, (byte) 98, (byte) -111, (byte) -107, (byte) -28, (byte) 121, (byte) -25, + (byte) -56, (byte) 55, (byte) 109, (byte) -115, (byte) -43, (byte) 78, (byte) -87, (byte) 108, (byte) 86, + (byte) -12, (byte) -22, (byte) 101, (byte) 122, (byte) -82, (byte) 8, (byte) -70, (byte) 120, (byte) 37, + (byte) 46, (byte) 28, (byte) -90, (byte) -76, (byte) -58, (byte) -24, (byte) -35, (byte) 116, (byte) 31, + (byte) 75, (byte) -67, (byte) -117, (byte) -118, (byte) 112, (byte) 62, (byte) -75, (byte) 102, (byte) 72, + (byte) 3, (byte) -10, (byte) 14, (byte) 97, (byte) 53, (byte) 87, (byte) -71, (byte) -122, (byte) -63, + (byte) 29, (byte) -98, (byte) -31, (byte) -8, (byte) -104, (byte) 17, (byte) 105, (byte) -39, (byte) -114, + (byte) -108, (byte) -101, (byte) 30, (byte) -121, (byte) -23, (byte) -50, (byte) 85, (byte) 40, (byte) -33, + (byte) -116, (byte) -95, (byte) -119, (byte) 13, (byte) -65, (byte) -26, (byte) 66, (byte) 104, (byte) 65, + (byte) -103, (byte) 45, (byte) 15, (byte) -80, (byte) 84, (byte) -69, (byte) 22 }; + private static final byte[] Si = new byte[] { (byte) 82, (byte) 9, (byte) 106, (byte) -43, (byte) 48, (byte) 54, + (byte) -91, (byte) 56, (byte) -65, (byte) 64, (byte) -93, (byte) -98, (byte) -127, (byte) -13, (byte) -41, + (byte) -5, (byte) 124, (byte) -29, (byte) 57, (byte) -126, (byte) -101, (byte) 47, (byte) -1, (byte) -121, + (byte) 52, (byte) -114, (byte) 67, (byte) 68, (byte) -60, (byte) -34, (byte) -23, (byte) -53, (byte) 84, + (byte) 123, (byte) -108, (byte) 50, (byte) -90, (byte) -62, (byte) 35, (byte) 61, (byte) -18, (byte) 76, + (byte) -107, (byte) 11, (byte) 66, (byte) -6, (byte) -61, (byte) 78, (byte) 8, (byte) 46, (byte) -95, + (byte) 102, (byte) 40, (byte) -39, (byte) 36, (byte) -78, (byte) 118, (byte) 91, (byte) -94, (byte) 73, + (byte) 109, (byte) -117, (byte) -47, (byte) 37, (byte) 114, (byte) -8, (byte) -10, (byte) 100, (byte) -122, + (byte) 104, (byte) -104, (byte) 22, (byte) -44, (byte) -92, (byte) 92, (byte) -52, (byte) 93, (byte) 101, + (byte) -74, (byte) -110, (byte) 108, (byte) 112, (byte) 72, (byte) 80, (byte) -3, (byte) -19, (byte) -71, + (byte) -38, (byte) 94, (byte) 21, (byte) 70, (byte) 87, (byte) -89, (byte) -115, (byte) -99, (byte) -124, + (byte) -112, (byte) -40, (byte) -85, (byte) 0, (byte) -116, (byte) -68, (byte) -45, (byte) 10, (byte) -9, + (byte) -28, (byte) 88, (byte) 5, (byte) -72, (byte) -77, (byte) 69, (byte) 6, (byte) -48, (byte) 44, + (byte) 30, (byte) -113, (byte) -54, (byte) 63, (byte) 15, (byte) 2, (byte) -63, (byte) -81, (byte) -67, + (byte) 3, (byte) 1, (byte) 19, (byte) -118, (byte) 107, (byte) 58, (byte) -111, (byte) 17, (byte) 65, + (byte) 79, (byte) 103, (byte) -36, (byte) -22, (byte) -105, (byte) -14, (byte) -49, (byte) -50, (byte) -16, + (byte) -76, (byte) -26, (byte) 115, (byte) -106, (byte) -84, (byte) 116, (byte) 34, (byte) -25, (byte) -83, + (byte) 53, (byte) -123, (byte) -30, (byte) -7, (byte) 55, (byte) -24, (byte) 28, (byte) 117, (byte) -33, + (byte) 110, (byte) 71, (byte) -15, (byte) 26, (byte) 113, (byte) 29, (byte) 41, (byte) -59, (byte) -119, + (byte) 111, (byte) -73, (byte) 98, (byte) 14, (byte) -86, (byte) 24, (byte) -66, (byte) 27, (byte) -4, + (byte) 86, (byte) 62, (byte) 75, (byte) -58, (byte) -46, (byte) 121, (byte) 32, (byte) -102, (byte) -37, + (byte) -64, (byte) -2, (byte) 120, (byte) -51, (byte) 90, (byte) -12, (byte) 31, (byte) -35, (byte) -88, + (byte) 51, (byte) -120, (byte) 7, (byte) -57, (byte) 49, (byte) -79, (byte) 18, (byte) 16, (byte) 89, + (byte) 39, (byte) -128, (byte) -20, (byte) 95, (byte) 96, (byte) 81, (byte) 127, (byte) -87, (byte) 25, + (byte) -75, (byte) 74, (byte) 13, (byte) 45, (byte) -27, (byte) 122, (byte) -97, (byte) -109, (byte) -55, + (byte) -100, (byte) -17, (byte) -96, (byte) -32, (byte) 59, (byte) 77, (byte) -82, (byte) 42, (byte) -11, + (byte) -80, (byte) -56, (byte) -21, (byte) -69, (byte) 60, (byte) -125, (byte) 83, (byte) -103, (byte) 97, + (byte) 23, (byte) 43, (byte) 4, (byte) 126, (byte) -70, (byte) 119, (byte) -42, (byte) 38, (byte) -31, + (byte) 105, (byte) 20, (byte) 99, (byte) 85, (byte) 33, (byte) 12, (byte) 125 }; + private static final int[] rcon = new int[] { 1, 2, 4, 8, 16, 32, 64, 128, 27, 54, 108, 216, 171, 77, 154, 47, 94, + 188, 99, 198, 151, 53, 106, 212, 179, 125, 250, 239, 197, 145 }; + private static final int[] T0 = new int[] { -1520213050, -2072216328, -1720223762, -1921287178, 234025727, + -1117033514, -1318096930, 1422247313, 1345335392, 50397442, -1452841010, 2099981142, 436141799, 1658312629, + -424957107, -1703512340, 1170918031, -1652391393, 1086966153, -2021818886, 368769775, -346465870, + -918075506, 200339707, -324162239, 1742001331, -39673249, -357585083, -1080255453, -140204973, -1770884380, + 1539358875, -1028147339, 486407649, -1366060227, 1780885068, 1513502316, 1094664062, 49805301, 1338821763, + 1546925160, -190470831, 887481809, 150073849, -1821281822, 1943591083, 1395732834, 1058346282, 201589768, + 1388824469, 1696801606, 1589887901, 672667696, -1583966665, 251987210, -1248159185, 151455502, 907153956, + -1686077413, 1038279391, 652995533, 1764173646, -843926913, -1619692054, 453576978, -1635548387, 1949051992, + 773462580, 756751158, -1301385508, -296068428, -73359269, -162377052, 1295727478, 1641469623, -827083907, + 2066295122, 1055122397, 1898917726, -1752923117, -179088474, 1758581177, 0, 753790401, 1612718144, + 536673507, -927878791, -312779850, -1100322092, 1187761037, -641810841, 1262041458, -565556588, -733197160, + -396863312, 1255133061, 1808847035, 720367557, -441800113, 385612781, -985447546, -682799718, 1429418854, + -1803188975, -817543798, 284817897, 100794884, -2122350594, -263171936, 1144798328, -1163944155, -475486133, + -212774494, -22830243, -1069531008, -1970303227, -1382903233, -1130521311, 1211644016, 83228145, -541279133, + -1044990345, 1977277103, 1663115586, 806359072, 452984805, 250868733, 1842533055, 1288555905, 336333848, + 890442534, 804056259, -513843266, -1567123659, -867941240, 957814574, 1472513171, -223893675, -2105639172, + 1195195770, -1402706744, -413311558, 723065138, -1787595802, -1604296512, -1736343271, -783331426, + 2145180835, 1713513028, 2116692564, -1416589253, -2088204277, -901364084, 703524551, -742868885, 1007948840, + 2044649127, -497131844, 487262998, 1994120109, 1004593371, 1446130276, 1312438900, 503974420, -615954030, + 168166924, 1814307912, -463709000, 1573044895, 1859376061, -273896381, -1503501628, -1466855111, + -1533700815, 937747667, -1954973198, 854058965, 1137232011, 1496790894, -1217565222, -1936880383, + 1691735473, -766620004, -525751991, -1267962664, -95005012, 133494003, 636152527, -1352309302, -1904575756, + -374428089, 403179536, -709182865, -2005370640, 1864705354, 1915629148, 605822008, -240736681, -944458637, + 1371981463, 602466507, 2094914977, -1670089496, 555687742, -582268010, -591544991, -2037675251, -2054518257, + -1871679264, 1111375484, -994724495, -1436129588, -666351472, 84083462, 32962295, 302911004, -1553899070, + 1597322602, -111716434, -793134743, -1853454825, 1489093017, 656219450, -1180787161, 954327513, 335083755, + -1281845205, 856756514, -1150719534, 1893325225, -1987146233, -1483434957, -1231316179, 572399164, + -1836611819, 552200649, 1238290055, -11184726, 2015897680, 2061492133, -1886614525, -123625127, -2138470135, + 386731290, -624967835, 837215959, -968736124, -1201116976, -1019133566, -1332111063, 1999449434, 286199582, + -877612933, -61582168, -692339859, 974525996 }; + private static final int[] T1 = new int[] { 1667483301, 2088564868, 2004348569, 2071721613, -218956019, 1802229437, + 1869602481, -976907948, 808476752, 16843267, 1734856361, 724260477, -16849127, -673729182, -1414836762, + 1987505306, -892694715, -2105401443, -909539008, 2105408135, -84218091, 1499050731, 1195871945, -252642549, + -1381154324, -724257945, -1566416899, -1347467798, -1667488833, -1532734473, 1920132246, -1061119141, + -1212713534, -33693412, -1819066962, 640044138, 909536346, 1061125697, -134744830, -859012273, 875849820, + -1515892236, -437923532, -235800312, 1903288979, -656888973, 825320019, 353708607, 67373068, -943221422, + 589514341, -1010590370, 404238376, -1768540255, 84216335, -1701171275, 117902857, 303178806, -2139087973, + -488448195, -336868058, 656887401, -1296924723, 1970662047, 151589403, -2088559202, 741103732, 437924910, + 454768173, 1852759218, 1515893998, -1600103429, 1381147894, 993752653, -690571423, -1280082482, 690573947, + -471605954, 791633521, -2071719017, 1397991157, -774784664, 0, -303185620, 538984544, -50535649, + -1313769016, 1532737261, 1785386174, -875852474, -1094817831, 960066123, 1246401758, 1280088276, 1482207464, + -808483510, -791626901, -269499094, -1431679003, -67375850, 1128498885, 1296931543, 859006549, -2054876780, + 1162185423, -101062384, 33686534, 2139094657, 1347461360, 1010595908, -1616960070, -1465365533, 1364304627, + -1549574658, 1077969088, -1886452342, -1835909203, -1650646596, 943222856, -168431356, -1128504353, + -1229555775, -623202443, 555827811, 269492272, -6886, -202113778, -757940371, -842170036, 202119188, + 320022069, -320027857, 1600110305, -1751698014, 1145342156, 387395129, -993750185, -1482205710, 2122251394, + 1027439175, 1684326572, 1566423783, 421081643, 1936975509, 1616953504, -2122245736, 1330618065, -589520001, + 572671078, 707417214, -1869595733, -2004350077, 1179028682, -286341335, -1195873325, 336865340, -555833479, + 1583267042, 185275933, -606360202, -522134725, 842163286, 976909390, 168432670, 1229558491, 101059594, + 606357612, 1549580516, -1027432611, -741098130, -1397996561, 1650640038, -1852753496, -1785384540, + -454765769, 2038035083, -404237006, -926381245, 926379609, 1835915959, -1920138868, -707415708, 1313774802, + -1448523296, 1819072692, 1448520954, -185273593, -353710299, 1701169839, 2054878350, -1364310039, 134746136, + -1162186795, 2021191816, 623200879, 774790258, 471611428, -1499047951, -1263242297, -960063663, -387396829, + -572677764, 1953818780, 522141217, 1263245021, -1111662116, -1953821306, -1970663547, 1886445712, + 1044282434, -1246400060, 1718013098, 1212715224, 50529797, -151587071, 235805714, 1633796771, 892693087, + 1465364217, -1179031088, -2038032495, -1044276904, 488454695, -1633802311, -505292488, -117904621, + -1734857805, 286335539, 1768542907, -640046736, -1903294583, -1802226777, -1684329034, 505297954, + -2021190254, -370554592, -825325751, 1431677695, 673730680, -538991238, -1936981105, -1583261192, + -1987507840, 218962455, -1077975590, -421079247, 1111655622, 1751699640, 1094812355, -1718015568, 757946999, + 252648977, -1330611253, 1414834428, -1145344554, 370551866 }; + private static final int[] T2 = new int[] { 1673962851, 2096661628, 2012125559, 2079755643, -218165774, 1809235307, + 1876865391, -980331323, 811618352, 16909057, 1741597031, 727088427, -18408962, -675978537, -1420958037, + 1995217526, -896580150, -2111857278, -913751863, 2113570685, -84994566, 1504897881, 1200539975, -251982864, + -1388188499, -726439980, -1570767454, -1354372433, -1675378788, -1538000988, 1927583346, -1063560256, + -1217019209, -35578627, -1824674157, 642542118, 913070646, 1065238847, -134937865, -863809588, 879254580, + -1521355611, -439274267, -235337487, 1910674289, -659852328, 828527409, 355090197, 67636228, -946515257, + 591815971, -1013096765, 405809176, -1774739050, 84545285, -1708149350, 118360327, 304363026, -2145674368, + -488686110, -338876693, 659450151, -1300247118, 1978310517, 152181513, -2095210877, 743994412, 439627290, + 456535323, 1859957358, 1521806938, -1604584544, 1386542674, 997608763, -692624938, -1283600717, 693271337, + -472039709, 794718511, -2079090812, 1403450707, -776378159, 0, -306107155, 541089824, -52224004, + -1317418831, 1538714971, 1792327274, -879933749, -1100490306, 963791673, 1251270218, 1285084236, 1487988824, + -813348145, -793023536, -272291089, -1437604438, -68348165, 1132905795, 1301993293, 862344499, -2062445435, + 1166724933, -102166279, 33818114, 2147385727, 1352724560, 1014514748, -1624917345, -1471421528, 1369633617, + -1554121053, 1082179648, -1895462257, -1841320558, -1658733411, 946882616, -168753931, -1134305348, + -1233665610, -626035238, 557998881, 270544912, -1762561, -201519373, -759206446, -847164211, 202904588, + 321271059, -322752532, 1606345055, -1758092649, 1149815876, 388905239, -996976700, -1487539545, 2130477694, + 1031423805, 1690872932, 1572530013, 422718233, 1944491379, 1623236704, -2129028991, 1335808335, -593264676, + 574907938, 710180394, -1875137648, -2012511352, 1183631942, -288937490, -1200893000, 338181140, -559449634, + 1589437022, 185998603, -609388837, -522503200, 845436466, 980700730, 169090570, 1234361161, 101452294, + 608726052, 1555620956, -1029743166, -742560045, -1404833876, 1657054818, -1858492271, -1791908715, + -455919644, 2045938553, -405458201, -930397240, 929978679, 1843050349, -1929278323, -709794603, 1318900302, + -1454776151, 1826141292, 1454176854, -185399308, -355523094, 1707781989, 2062847610, -1371018834, 135272456, + -1167075910, 2029029496, 625635109, 777810478, 473441308, -1504185946, -1267480652, -963161658, -389340184, + -576619299, 1961401460, 524165407, 1268178251, -1117659971, -1962047861, -1978694262, 1893765232, + 1048330814, -1250835275, 1724688998, 1217452104, 50726147, -151584266, 236720654, 1640145761, 896163637, + 1471084887, -1184247623, -2045275770, -1046914879, 490350365, -1641563746, -505857823, -118811656, + -1741966440, 287453969, 1775418217, -643206951, -1912108658, -1808554092, -1691502949, 507257374, + -2028629369, -372694807, -829994546, 1437269845, 676362280, -542803233, -1945923700, -1587939167, + -1995865975, 219813645, -1083843905, -422104602, 1115997762, 1758509160, 1099088705, -1725321063, 760903469, + 253628687, -1334064208, 1420360788, -1150429509, 371997206 }; + private static final int[] T3 = new int[] { -962239645, -125535108, -291932297, -158499973, -15863054, -692229269, + -558796945, -1856715323, 1615867952, 33751297, -827758745, 1451043627, -417726722, -1251813417, 1306962859, + -325421450, -1891251510, 530416258, -1992242743, -91783811, -283772166, -1293199015, -1899411641, -83103504, + 1106029997, -1285040940, 1610457762, 1173008303, 599760028, 1408738468, -459902350, -1688485696, 1975695287, + -518193667, 1034851219, 1282024998, 1817851446, 2118205247, -184354825, -2091922228, 1750873140, 1374987685, + -785062427, -116854287, -493653647, -1418471208, 1649619249, 708777237, 135005188, -1789737017, 1181033251, + -1654733885, 807933976, 933336726, 168756485, 800430746, 235472647, 607523346, 463175808, -549592350, + -853087253, 1315514151, 2144187058, -358648459, 303761673, 496927619, 1484008492, 875436570, 908925723, + -592286098, -1259447718, 1543217312, -1527360942, 1984772923, -1218324778, 2110698419, 1383803177, + -583080989, 1584475951, 328696964, -1493871789, -1184312879, 0, -1054020115, 1080041504, -484442884, + 2043195825, -1225958565, -725718422, -1924740149, 1742323390, 1917532473, -1797371318, -1730917300, + -1326950312, -2058694705, -1150562096, -987041809, 1340451498, -317260805, -2033892541, -1697166003, + 1716859699, 294946181, -1966127803, -384763399, 67502594, -25067649, -1594863536, 2017737788, 632987551, + 1273211048, -1561112239, 1576969123, -2134884288, 92966799, 1068339858, 566009245, 1883781176, -251333131, + 1675607228, 2009183926, -1351230758, 1113792801, 540020752, -451215361, -49351693, -1083321646, -2125673011, + 403966988, 641012499, -1020269332, -1092526241, 899848087, -1999879100, 775493399, -1822964540, 1441965991, + -58556802, 2051489085, -928226204, -1159242403, 841685273, -426413197, -1063231392, 429425025, -1630449841, + -1551901476, 1147544098, 1417554474, 1001099408, 193169544, -1932900794, -953553170, 1809037496, 675025940, + -1485185314, -1126015394, 371002123, -1384719397, -616832800, 1683370546, 1951283770, 337512970, + -1831122615, 201983494, 1215046692, -1192993700, -1621245246, -1116810285, 1139780780, -995728798, + 967348625, 832869781, -751311644, -225740423, -718084121, -1958491960, 1851340599, -625513107, 25988493, + -1318791723, -1663938994, 1239460265, -659264404, -1392880042, -217582348, -819598614, -894474907, + -191989126, 1206496942, 270010376, 1876277946, -259491720, 1248797989, 1550986798, 941890588, 1475454630, + 1942467764, -1756248378, -886839064, -1585652259, -392399756, 1042358047, -1763882165, 1641856445, + 226921355, 260409994, -527404944, 2084716094, 1908716981, -861247898, -1864873912, 100991747, -150866186, + 470945294, -1029480095, 1784624437, -1359390889, 1775286713, 395413126, -1722236479, 975641885, 666476190, + -650583583, -351012616, 733190296, 573772049, -759469719, -1452221991, 126455438, 866620564, 766942107, + 1008868894, 361924487, -920589847, -2025206066, -1426107051, 1350051880, -1518673953, 59739276, 1509466529, + 159418761, 437718285, 1708834751, -684595482, -2067381694, -793221016, -2101132991, 699439513, 1517759789, + 504434447, 2076946608, -1459858348, 1842789307, 742004246 }; + private static final int[] Tinv0 = new int[] { 1353184337, 1399144830, -1012656358, -1772214470, -882136261, + -247096033, -1420232020, -1828461749, 1442459680, -160598355, -1854485368, 625738485, -52959921, -674551099, + -2143013594, -1885117771, 1230680542, 1729870373, -1743852987, -507445667, 41234371, 317738113, -1550367091, + -956705941, -413167869, -1784901099, -344298049, -631680363, 763608788, -752782248, 694804553, 1154009486, + 1787413109, 2021232372, 1799248025, -579749593, -1236278850, 397248752, 1722556617, -1271214467, 407560035, + -2110711067, 1613975959, 1165972322, -529046351, -2068943941, 480281086, -1809118983, 1483229296, 436028815, + -2022908268, -1208452270, 601060267, -503166094, 1468997603, 715871590, 120122290, 63092015, -1703164538, + -1526188077, -226023376, -1297760477, -1167457534, 1552029421, 723308426, -1833666137, -252573709, + -1578997426, -839591323, -708967162, 526529745, -1963022652, -1655493068, -1604979806, 853641733, + 1978398372, 971801355, -1427152832, 111112542, 1360031421, -108388034, 1023860118, -1375387939, 1186850381, + -1249028975, 90031217, 1876166148, -15380384, 620468249, -1746289194, -868007799, 2006899047, -1119688528, + -2004121337, 945494503, -605108103, 1191869601, -384875908, -920746760, 0, -2088337399, 1223502642, + -1401941730, 1316117100, -67170563, 1446544655, 517320253, 658058550, 1691946762, 564550760, -783000677, + 976107044, -1318647284, 266819475, -761860428, -1634624741, 1338359936, -1574904735, 1766553434, 370807324, + 179999714, -450191168, 1138762300, 488053522, 185403662, -1379431438, -1180125651, -928440812, -2061897385, + 1275557295, -1143105042, -44007517, -1624899081, -1124765092, -985962940, 880737115, 1982415755, -590994485, + 1761406390, 1676797112, -891538985, 277177154, 1076008723, 538035844, 2099530373, -130171950, 288553390, + 1839278535, 1261411869, -214912292, -330136051, -790380169, 1813426987, -1715900247, -95906799, 577038663, + -997393240, 440397984, -668172970, -275762398, -951170681, -1043253031, -22885748, 906744984, -813566554, + 685669029, 646887386, -1530942145, -459458004, 227702864, -1681105046, 1648787028, -1038905866, -390539120, + 1593260334, -173030526, -1098883681, 2090061929, -1456614033, -1290656305, 999926984, -1484974064, + 1852021992, 2075868123, 158869197, -199730834, 28809964, -1466282109, 1701746150, 2129067946, 147831841, + -420997649, -644094022, -835293366, -737566742, -696471511, -1347247055, 824393514, 815048134, -1067015627, + 935087732, -1496677636, -1328508704, 366520115, 1251476721, -136647615, 240176511, 804688151, -1915335306, + 1303441219, 1414376140, -553347356, -474623586, 461924940, -1205916479, 2136040774, 82468509, 1563790337, + 1937016826, 776014843, 1511876531, 1389550482, 861278441, 323475053, -1939744870, 2047648055, -1911228327, + -1992551445, -299390514, 902390199, -303751967, 1018251130, 1507840668, 1064563285, 2043548696, -1086863501, + -355600557, 1537932639, 342834655, -2032450440, -2114736182, 1053059257, 741614648, 1598071746, 1925389590, + 203809468, -1958134744, 1100287487, 1895934009, -558691320, -1662733096, -1866377628, 1636092795, + 1890988757, 1952214088, 1113045200 }; + private static final int[] Tinv1 = new int[] { -1477160624, 1698790995, -1541989693, 1579629206, 1806384075, + 1167925233, 1492823211, 65227667, -97509291, 1836494326, 1993115793, 1275262245, -672837636, -886389289, + 1144333952, -1553812081, 1521606217, 465184103, 250234264, -1057071647, 1966064386, -263421678, -1756983901, + -103584826, 1603208167, -1668147819, 2054012907, 1498584538, -2084645843, 561273043, 1776306473, -926314940, + -1983744662, 2039411832, 1045993835, 1907959773, 1340194486, -1383534569, -1407137434, 986611124, + 1256153880, 823846274, 860985184, 2136171077, 2003087840, -1368671356, -1602093540, 722008468, 1749577816, + -45773031, 1826526343, -126135625, -747394269, 38499042, -1893735593, -1420466646, 686535175, -1028313341, + 2076542618, 137876389, -2027409166, -1514200142, 1778582202, -2112426660, 483363371, -1267095662, + -234359824, -496415071, -187013683, -1106966827, 1647628575, -22625142, 1395537053, 1442030240, -511048398, + -336157579, -326956231, -278904662, -1619960314, 275692881, -1977532679, 115185213, 88006062, -1108980410, + -1923837515, 1573155077, -737803153, 357589247, -73918172, -373434729, 1128303052, -1629919369, 1122545853, + -1953953912, 1528424248, -288851493, 175939911, 256015593, 512030921, 0, -2038429309, -315936184, + 1880170156, 1918528590, -15794693, 948244310, -710001378, 959264295, -653325724, -1503893471, 1415289809, + 775300154, 1728711857, -413691121, -1762741038, -1852105826, -977239985, 551313826, 1266113129, 437394454, + -1164713462, 715178213, -534627261, 387650077, 218697227, -947129683, -1464455751, -1457646392, 435246981, + 125153100, -577114437, 1618977789, 637663135, -177054532, 996558021, 2130402100, 692292470, -970732580, + -51530136, -236668829, -600713270, -2057092592, 580326208, 298222624, 608863613, 1035719416, 855223825, + -1591097491, 798891339, 817028339, 1384517100, -473860144, 380840812, -1183798887, 1217663482, 1693009698, + -1929598780, 1072734234, 746411736, -1875696913, 1313441735, -784803391, -1563783938, 198481974, + -2114607409, -562387672, -1900553690, -1079165020, -1657131804, -1837608947, -866162021, 1182684258, + 328070850, -1193766680, -147247522, -1346141451, -2141347906, -1815058052, 768962473, 304467891, + -1716729797, 2098729127, 1671227502, -1153705093, 2015808777, 408514292, -1214583807, -1706064984, + 1855317605, -419452290, -809754360, -401215514, -1679312167, 913263310, 161475284, 2091919830, -1297862225, + 591342129, -1801075152, 1721906624, -1135709129, -897385306, -795811664, -660131051, -1744506550, + -622050825, 1355644686, -158263505, -699566451, -1326496947, 1303039060, 76997855, -1244553501, -2006299621, + 523026872, 1365591679, -362898172, 898367837, 1955068531, 1091304238, 493335386, -757362094, 1443948851, + 1205234963, 1641519756, 211892090, 351820174, 1007938441, 665439982, -916342987, -451091987, -1320715716, + -539845543, 1945261375, -837543815, 935818175, -839429142, -1426235557, 1866325780, -616269690, -206583167, + -999769794, 874788908, 1084473951, -1021503886, 635616268, 1228679307, -1794244799, 27801969, -1291056930, + -457910116, -1051302768, -2067039391, -1238182544, 1550600308, 1471729730 }; + private static final int[] Tinv2 = new int[] { -195997529, 1098797925, 387629988, 658151006, -1422144661, + -1658851003, -89347240, -481586429, 807425530, 1991112301, -863465098, 49620300, -447742761, 717608907, + 891715652, 1656065955, -1310832294, -1171953893, -364537842, -27401792, 801309301, 1283527408, 1183687575, + -747911431, -1895569569, -1844079204, 1841294202, 1385552473, -1093390973, 1951978273, -532076183, + -913423160, -1032492407, -1896580999, 1486449470, -1188569743, -507595185, -1997531219, 550069932, + -830622662, -547153846, 451248689, 1368875059, 1398949247, 1689378935, 1807451310, -2114052960, 150574123, + 1215322216, 1167006205, -560691348, 2069018616, 1940595667, 1265820162, 534992783, 1432758955, -340654296, + -1255210046, -981034373, 936617224, 674296455, -1088179547, 50510442, 384654466, -813028580, 2041025204, + 133427442, 1766760930, -630862348, 84334014, 886120290, -1497068802, 775200083, -207445931, -1979370783, + -156994069, -2096416276, 1614850799, 1901987487, 1857900816, 557775242, -577356538, 1054715397, -431143235, + 1418835341, -999226019, 100954068, 1348534037, -1743182597, -1110009879, 1082772547, -647530594, -391070398, + -1995994997, 434583643, -931537938, 2090944266, 1115482383, -2064070370, 0, -2146860154, 724715757, + 287222896, 1517047410, 251526143, -2062592456, -1371726123, 758523705, 252339417, 1550328230, 1536938324, + 908343854, 168604007, 1469255655, -290139498, -1692688751, -1065332795, -597581280, 2002413899, 303830554, + -1813902662, -1597971158, 574374880, 454171927, 151915277, -1947030073, -1238517336, 504678569, -245922535, + 1974422535, -1712407587, 2141453664, 33005350, 1918680309, 1715782971, -77908866, 1133213225, 600562886, + -306812676, -457677839, 836225756, 1665273989, -1760346078, -964419567, 1250262308, -1143801795, -106032846, + 700935585, -1642247377, -1294142672, -2045907886, -1049112349, -1288999914, 1890163129, -1810761144, + -381214108, -56048500, -257942977, 2102843436, 857927568, 1233635150, 953795025, -896729438, -728222197, + -173617279, 2057644254, -1210440050, -1388337985, 976020637, 2018512274, 1600822220, 2119459398, + -1913208301, -661591880, 959340279, -1014827601, 1570750080, -798393197, -714102483, 634368786, -1396163687, + 403744637, -1662488989, 1004239803, 650971512, 1500443672, -1695809097, 1334028442, -1780062866, -5603610, + -1138685745, 368043752, -407184997, 1867173430, -1612000247, -1339435396, -1540247630, 1059729699, + -1513738092, -1573535642, 1316239292, -2097371446, -1864322864, -1489824296, 82922136, -331221030, + -847311280, -1860751370, 1299615190, -280801872, -1429449651, -1763385596, -778116171, 1783372680, + 750893087, 1699118929, 1587348714, -1946067659, -2013629580, 201010753, 1739807261, -611167534, 283718486, + -697494713, -677737375, -1590199796, -128348652, 334203196, -1446056409, 1639396809, 484568549, 1199193265, + -761505313, -229294221, 337148366, -948715721, -145495347, -44082262, 1038029935, 1148749531, -1345682957, + 1756970692, 607661108, -1547542720, 488010435, -490992603, 1009290057, 234832277, -1472630527, 201907891, + -1260872476, 1449431233, -881106556, 852848822, 1816687708, -1194311081 }; + private static final int[] Tinv3 = new int[] { 1364240372, 2119394625, 449029143, 982933031, 1003187115, 535905693, + -1398056710, 1267925987, 542505520, -1376359050, -2003732788, -182105086, 1341970405, -975713494, 645940277, + -1248877726, -565617999, 627514298, 1167593194, 1575076094, -1023249105, -2129465268, -1918658746, + 1808202195, 65494927, 362126482, -1075086739, -1780852398, -735214658, 1490231668, 1227450848, -1908094775, + 1969916354, -193431154, -1721024936, 668823993, -1095348255, -266883704, -916018144, 2108963534, 1662536415, + -444452582, -1755303087, 1648721747, -1310689436, -1148932501, -31678335, -107730168, 1884842056, + -1894122171, -1803064098, 1387788411, -1423715469, 1927414347, -480800993, 1714072405, -1308153621, + 788775605, -2036696123, -744159177, 821200680, 598910399, 45771267, -312704490, -1976886065, -1483557767, + -202313209, 1319232105, 1707996378, 114671109, -786472396, -997523802, 882725678, -1566550541, 87220618, + -1535775754, 188345475, 1084944224, 1577492337, -1118760850, 1056541217, -1774385443, -575797954, + 1296481766, -1850372780, 1896177092, 74437638, 1627329872, 421854104, -694687299, -1983102144, 1735892697, + -1329773848, 126389129, -415737063, 2044456648, -1589179780, 2095648578, -121037180, 0, 159614592, + 843640107, 514617361, 1817080410, -33816818, 257308805, 1025430958, 908540205, 174381327, 1747035740, + -1680780197, 607792694, 212952842, -1827674281, -1261267218, 463376795, -2142255680, 1638015196, 1516850039, + 471210514, -502613357, -1058723168, 1011081250, 303896347, 235605257, -223492213, 767142070, 348694814, + 1468340721, -1353971851, -289677927, -1543675777, -140564991, 1555887474, 1153776486, 1530167035, + -1955190461, -874723805, -1234633491, -1201409564, -674571215, 1108378979, 322970263, -2078273082, + -2055396278, -755483205, -1374604551, -949116631, 491466654, -588042062, 233591430, 2010178497, 728503987, + -1449543312, 301615252, 1193436393, -1463513860, -1608892432, 1457007741, 586125363, -2016981431, + -641609416, -1929469238, -1741288492, -1496350219, -1524048262, -635007305, 1067761581, 753179962, + 1343066744, 1788595295, 1415726718, -155053171, -1863796520, 777975609, -2097827901, -1614905251, + 1769771984, 1873358293, -810347995, -935618132, 279411992, -395418724, -612648133, -855017434, 1861490777, + -335431782, -2086102449, -429560171, -1434523905, 554225596, -270079979, -1160143897, 1255028335, + -355202657, 701922480, 833598116, 707863359, -969894747, 901801634, 1949809742, -56178046, -525283184, + 857069735, -246769660, 1106762476, 2131644621, 389019281, 1989006925, 1129165039, -866890326, -455146346, + -1629243951, 1276872810, -1044898004, 1182749029, -1660622242, 22885772, -93096825, -80854773, -1285939865, + -1840065829, -382511600, 1829980118, -1702075945, 930745505, 1502483704, -343327725, -823253079, + -1221211807, -504503012, 2050797895, -1671831598, 1430221810, 410635796, 1941911495, 1407897079, 1599843069, + -552308931, 2022103876, -897453137, -1187068824, 942421028, -1033944925, 376619805, -1140054558, 680216892, + -12479219, 963707304, 148812556, -660806476, 1687208278, 2069988555, -714033614, 1215585388, -800958536 }; + private int ROUNDS; + private int[][] WorkingKey = (int[][]) null; + private int C0; + private int C1; + private int C2; + private int C3; + private boolean forEncryption; + + private int shift(int par1, int par2) { + return par1 >>> par2 | par1 << -par2; + } + + private int FFmulX(int par1) { + return (par1 & 2139062143) << 1 ^ ((par1 & -2139062144) >>> 7) * 27; + } + + private int inv_mcol(int par1) { + int var2 = this.FFmulX(par1); + int var3 = this.FFmulX(var2); + int var4 = this.FFmulX(var3); + int var5 = par1 ^ var4; + return var2 ^ var3 ^ var4 ^ this.shift(var2 ^ var5, 8) ^ this.shift(var3 ^ var5, 16) ^ this.shift(var5, 24); + } + + private int subWord(int par1) { + return S[par1 & 255] & 255 | (S[par1 >> 8 & 255] & 255) << 8 | (S[par1 >> 16 & 255] & 255) << 16 + | S[par1 >> 24 & 255] << 24; + } + + private int[][] generateWorkingKey(byte[] par1ArrayOfByte, boolean par2) { + int var3 = par1ArrayOfByte.length / 4; + + if ((var3 == 4 || var3 == 6 || var3 == 8) && var3 * 4 == par1ArrayOfByte.length) { + this.ROUNDS = var3 + 6; + int[][] var5 = new int[this.ROUNDS + 1][4]; + int var4 = 0; + int var6; + + for (var6 = 0; var6 < par1ArrayOfByte.length; ++var4) { + var5[var4 >> 2][var4 & 3] = par1ArrayOfByte[var6] & 255 | (par1ArrayOfByte[var6 + 1] & 255) << 8 + | (par1ArrayOfByte[var6 + 2] & 255) << 16 | par1ArrayOfByte[var6 + 3] << 24; + var6 += 4; + } + + int var7 = this.ROUNDS + 1 << 2; + int var8; + + for (var6 = var3; var6 < var7; ++var6) { + var8 = var5[var6 - 1 >> 2][var6 - 1 & 3]; + + if (var6 % var3 == 0) { + var8 = this.subWord(this.shift(var8, 8)) ^ rcon[var6 / var3 - 1]; + } else if (var3 > 6 && var6 % var3 == 4) { + var8 = this.subWord(var8); + } + + var5[var6 >> 2][var6 & 3] = var5[var6 - var3 >> 2][var6 - var3 & 3] ^ var8; + } + + if (!par2) { + for (var8 = 1; var8 < this.ROUNDS; ++var8) { + for (var6 = 0; var6 < 4; ++var6) { + var5[var8][var6] = this.inv_mcol(var5[var8][var6]); + } + } + } + + return var5; + } else { + throw new IllegalArgumentException("Key length not 128/192/256 bits."); + } + } + + public void init(boolean par1, CipherParameters par2CipherParameters) throws IllegalArgumentException { + if (par2CipherParameters instanceof KeyParameter) { + this.WorkingKey = this.generateWorkingKey(((KeyParameter) par2CipherParameters).getKey(), par1); + this.forEncryption = par1; + } else { + throw new IllegalArgumentException( + "invalid parameter passed to AES init - " + par2CipherParameters.getClass().getName()); + } + } + + /** + * Return the name of the algorithm the cipher implements. + */ + public String getAlgorithmName() { + return "AES"; + } + + /** + * Return the block size for this cipher (in bytes). + */ + public int getBlockSize() { + return 16; + } + + public int processBlock(byte[] par1ArrayOfByte, int par2, byte[] par3ArrayOfByte, int par4) + throws DataLengthException, IllegalStateException { + if (this.WorkingKey == null) { + throw new IllegalStateException("AES engine not initialised"); + } else if (par2 + 16 > par1ArrayOfByte.length) { + throw new DataLengthException("input buffer too short"); + } else if (par4 + 16 > par3ArrayOfByte.length) { + throw new DataLengthException("output buffer too short"); + } else { + if (this.forEncryption) { + this.unpackBlock(par1ArrayOfByte, par2); + this.encryptBlock(this.WorkingKey); + this.packBlock(par3ArrayOfByte, par4); + } else { + this.unpackBlock(par1ArrayOfByte, par2); + this.decryptBlock(this.WorkingKey); + this.packBlock(par3ArrayOfByte, par4); + } + + return 16; + } + } + + public void reset() { + } + + private void unpackBlock(byte[] par1ArrayOfByte, int par2) { + int var3 = par2 + 1; + this.C0 = par1ArrayOfByte[par2] & 255; + this.C0 |= (par1ArrayOfByte[var3++] & 255) << 8; + this.C0 |= (par1ArrayOfByte[var3++] & 255) << 16; + this.C0 |= par1ArrayOfByte[var3++] << 24; + this.C1 = par1ArrayOfByte[var3++] & 255; + this.C1 |= (par1ArrayOfByte[var3++] & 255) << 8; + this.C1 |= (par1ArrayOfByte[var3++] & 255) << 16; + this.C1 |= par1ArrayOfByte[var3++] << 24; + this.C2 = par1ArrayOfByte[var3++] & 255; + this.C2 |= (par1ArrayOfByte[var3++] & 255) << 8; + this.C2 |= (par1ArrayOfByte[var3++] & 255) << 16; + this.C2 |= par1ArrayOfByte[var3++] << 24; + this.C3 = par1ArrayOfByte[var3++] & 255; + this.C3 |= (par1ArrayOfByte[var3++] & 255) << 8; + this.C3 |= (par1ArrayOfByte[var3++] & 255) << 16; + this.C3 |= par1ArrayOfByte[var3++] << 24; + } + + private void packBlock(byte[] par1ArrayOfByte, int par2) { + int var3 = par2 + 1; + par1ArrayOfByte[par2] = (byte) this.C0; + par1ArrayOfByte[var3++] = (byte) (this.C0 >> 8); + par1ArrayOfByte[var3++] = (byte) (this.C0 >> 16); + par1ArrayOfByte[var3++] = (byte) (this.C0 >> 24); + par1ArrayOfByte[var3++] = (byte) this.C1; + par1ArrayOfByte[var3++] = (byte) (this.C1 >> 8); + par1ArrayOfByte[var3++] = (byte) (this.C1 >> 16); + par1ArrayOfByte[var3++] = (byte) (this.C1 >> 24); + par1ArrayOfByte[var3++] = (byte) this.C2; + par1ArrayOfByte[var3++] = (byte) (this.C2 >> 8); + par1ArrayOfByte[var3++] = (byte) (this.C2 >> 16); + par1ArrayOfByte[var3++] = (byte) (this.C2 >> 24); + par1ArrayOfByte[var3++] = (byte) this.C3; + par1ArrayOfByte[var3++] = (byte) (this.C3 >> 8); + par1ArrayOfByte[var3++] = (byte) (this.C3 >> 16); + par1ArrayOfByte[var3++] = (byte) (this.C3 >> 24); + } + + private void encryptBlock(int[][] par1ArrayOfInteger) { + this.C0 ^= par1ArrayOfInteger[0][0]; + this.C1 ^= par1ArrayOfInteger[0][1]; + this.C2 ^= par1ArrayOfInteger[0][2]; + this.C3 ^= par1ArrayOfInteger[0][3]; + int var2; + int var3; + int var4; + int var5; + int var6; + + for (var2 = 1; var2 < this.ROUNDS - 1; this.C3 = T0[var6 & 255] ^ T1[var3 >> 8 & 255] ^ T2[var4 >> 16 & 255] + ^ T3[var5 >> 24 & 255] ^ par1ArrayOfInteger[var2++][3]) { + var3 = T0[this.C0 & 255] ^ T1[this.C1 >> 8 & 255] ^ T2[this.C2 >> 16 & 255] ^ T3[this.C3 >> 24 & 255] + ^ par1ArrayOfInteger[var2][0]; + var4 = T0[this.C1 & 255] ^ T1[this.C2 >> 8 & 255] ^ T2[this.C3 >> 16 & 255] ^ T3[this.C0 >> 24 & 255] + ^ par1ArrayOfInteger[var2][1]; + var5 = T0[this.C2 & 255] ^ T1[this.C3 >> 8 & 255] ^ T2[this.C0 >> 16 & 255] ^ T3[this.C1 >> 24 & 255] + ^ par1ArrayOfInteger[var2][2]; + var6 = T0[this.C3 & 255] ^ T1[this.C0 >> 8 & 255] ^ T2[this.C1 >> 16 & 255] ^ T3[this.C2 >> 24 & 255] + ^ par1ArrayOfInteger[var2++][3]; + this.C0 = T0[var3 & 255] ^ T1[var4 >> 8 & 255] ^ T2[var5 >> 16 & 255] ^ T3[var6 >> 24 & 255] + ^ par1ArrayOfInteger[var2][0]; + this.C1 = T0[var4 & 255] ^ T1[var5 >> 8 & 255] ^ T2[var6 >> 16 & 255] ^ T3[var3 >> 24 & 255] + ^ par1ArrayOfInteger[var2][1]; + this.C2 = T0[var5 & 255] ^ T1[var6 >> 8 & 255] ^ T2[var3 >> 16 & 255] ^ T3[var4 >> 24 & 255] + ^ par1ArrayOfInteger[var2][2]; + } + + var3 = T0[this.C0 & 255] ^ T1[this.C1 >> 8 & 255] ^ T2[this.C2 >> 16 & 255] ^ T3[this.C3 >> 24 & 255] + ^ par1ArrayOfInteger[var2][0]; + var4 = T0[this.C1 & 255] ^ T1[this.C2 >> 8 & 255] ^ T2[this.C3 >> 16 & 255] ^ T3[this.C0 >> 24 & 255] + ^ par1ArrayOfInteger[var2][1]; + var5 = T0[this.C2 & 255] ^ T1[this.C3 >> 8 & 255] ^ T2[this.C0 >> 16 & 255] ^ T3[this.C1 >> 24 & 255] + ^ par1ArrayOfInteger[var2][2]; + var6 = T0[this.C3 & 255] ^ T1[this.C0 >> 8 & 255] ^ T2[this.C1 >> 16 & 255] ^ T3[this.C2 >> 24 & 255] + ^ par1ArrayOfInteger[var2++][3]; + this.C0 = S[var3 & 255] & 255 ^ (S[var4 >> 8 & 255] & 255) << 8 ^ (S[var5 >> 16 & 255] & 255) << 16 + ^ S[var6 >> 24 & 255] << 24 ^ par1ArrayOfInteger[var2][0]; + this.C1 = S[var4 & 255] & 255 ^ (S[var5 >> 8 & 255] & 255) << 8 ^ (S[var6 >> 16 & 255] & 255) << 16 + ^ S[var3 >> 24 & 255] << 24 ^ par1ArrayOfInteger[var2][1]; + this.C2 = S[var5 & 255] & 255 ^ (S[var6 >> 8 & 255] & 255) << 8 ^ (S[var3 >> 16 & 255] & 255) << 16 + ^ S[var4 >> 24 & 255] << 24 ^ par1ArrayOfInteger[var2][2]; + this.C3 = S[var6 & 255] & 255 ^ (S[var3 >> 8 & 255] & 255) << 8 ^ (S[var4 >> 16 & 255] & 255) << 16 + ^ S[var5 >> 24 & 255] << 24 ^ par1ArrayOfInteger[var2][3]; + } + + private void decryptBlock(int[][] par1ArrayOfInteger) { + this.C0 ^= par1ArrayOfInteger[this.ROUNDS][0]; + this.C1 ^= par1ArrayOfInteger[this.ROUNDS][1]; + this.C2 ^= par1ArrayOfInteger[this.ROUNDS][2]; + this.C3 ^= par1ArrayOfInteger[this.ROUNDS][3]; + int var2; + int var3; + int var4; + int var5; + int var6; + + for (var6 = this.ROUNDS - 1; var6 > 1; this.C3 = Tinv0[var5 & 255] ^ Tinv1[var4 >> 8 & 255] + ^ Tinv2[var3 >> 16 & 255] ^ Tinv3[var2 >> 24 & 255] ^ par1ArrayOfInteger[var6--][3]) { + var2 = Tinv0[this.C0 & 255] ^ Tinv1[this.C3 >> 8 & 255] ^ Tinv2[this.C2 >> 16 & 255] + ^ Tinv3[this.C1 >> 24 & 255] ^ par1ArrayOfInteger[var6][0]; + var3 = Tinv0[this.C1 & 255] ^ Tinv1[this.C0 >> 8 & 255] ^ Tinv2[this.C3 >> 16 & 255] + ^ Tinv3[this.C2 >> 24 & 255] ^ par1ArrayOfInteger[var6][1]; + var4 = Tinv0[this.C2 & 255] ^ Tinv1[this.C1 >> 8 & 255] ^ Tinv2[this.C0 >> 16 & 255] + ^ Tinv3[this.C3 >> 24 & 255] ^ par1ArrayOfInteger[var6][2]; + var5 = Tinv0[this.C3 & 255] ^ Tinv1[this.C2 >> 8 & 255] ^ Tinv2[this.C1 >> 16 & 255] + ^ Tinv3[this.C0 >> 24 & 255] ^ par1ArrayOfInteger[var6--][3]; + this.C0 = Tinv0[var2 & 255] ^ Tinv1[var5 >> 8 & 255] ^ Tinv2[var4 >> 16 & 255] ^ Tinv3[var3 >> 24 & 255] + ^ par1ArrayOfInteger[var6][0]; + this.C1 = Tinv0[var3 & 255] ^ Tinv1[var2 >> 8 & 255] ^ Tinv2[var5 >> 16 & 255] ^ Tinv3[var4 >> 24 & 255] + ^ par1ArrayOfInteger[var6][1]; + this.C2 = Tinv0[var4 & 255] ^ Tinv1[var3 >> 8 & 255] ^ Tinv2[var2 >> 16 & 255] ^ Tinv3[var5 >> 24 & 255] + ^ par1ArrayOfInteger[var6][2]; + } + + var2 = Tinv0[this.C0 & 255] ^ Tinv1[this.C3 >> 8 & 255] ^ Tinv2[this.C2 >> 16 & 255] + ^ Tinv3[this.C1 >> 24 & 255] ^ par1ArrayOfInteger[var6][0]; + var3 = Tinv0[this.C1 & 255] ^ Tinv1[this.C0 >> 8 & 255] ^ Tinv2[this.C3 >> 16 & 255] + ^ Tinv3[this.C2 >> 24 & 255] ^ par1ArrayOfInteger[var6][1]; + var4 = Tinv0[this.C2 & 255] ^ Tinv1[this.C1 >> 8 & 255] ^ Tinv2[this.C0 >> 16 & 255] + ^ Tinv3[this.C3 >> 24 & 255] ^ par1ArrayOfInteger[var6][2]; + var5 = Tinv0[this.C3 & 255] ^ Tinv1[this.C2 >> 8 & 255] ^ Tinv2[this.C1 >> 16 & 255] + ^ Tinv3[this.C0 >> 24 & 255] ^ par1ArrayOfInteger[var6][3]; + this.C0 = Si[var2 & 255] & 255 ^ (Si[var5 >> 8 & 255] & 255) << 8 ^ (Si[var4 >> 16 & 255] & 255) << 16 + ^ Si[var3 >> 24 & 255] << 24 ^ par1ArrayOfInteger[0][0]; + this.C1 = Si[var3 & 255] & 255 ^ (Si[var2 >> 8 & 255] & 255) << 8 ^ (Si[var5 >> 16 & 255] & 255) << 16 + ^ Si[var4 >> 24 & 255] << 24 ^ par1ArrayOfInteger[0][1]; + this.C2 = Si[var4 & 255] & 255 ^ (Si[var3 >> 8 & 255] & 255) << 8 ^ (Si[var2 >> 16 & 255] & 255) << 16 + ^ Si[var5 >> 24 & 255] << 24 ^ par1ArrayOfInteger[0][2]; + this.C3 = Si[var5 & 255] & 255 ^ (Si[var4 >> 8 & 255] & 255) << 8 ^ (Si[var3 >> 16 & 255] & 255) << 16 + ^ Si[var2 >> 24 & 255] << 24 ^ par1ArrayOfInteger[0][3]; + } +} diff --git a/sp-server/src/main/java/org/bouncycastle/crypto/io/CipherInputStream.java b/sp-server/src/main/java/org/bouncycastle/crypto/io/CipherInputStream.java new file mode 100644 index 0000000..cd9c634 --- /dev/null +++ b/sp-server/src/main/java/org/bouncycastle/crypto/io/CipherInputStream.java @@ -0,0 +1,134 @@ +package org.bouncycastle.crypto.io; + +import java.io.FilterInputStream; +import java.io.IOException; +import java.io.InputStream; +import org.bouncycastle.crypto.BufferedBlockCipher; +import org.bouncycastle.crypto.StreamCipher; + +public class CipherInputStream extends FilterInputStream { + private BufferedBlockCipher theBufferedBlockCipher; + private StreamCipher theStreamCipher; + private byte[] buf; + private byte[] inBuf; + private int bufOff; + private int maxBuf; + private boolean finalized; + + public CipherInputStream(InputStream par1InputStream, BufferedBlockCipher par2BufferedBlockCipher) { + super(par1InputStream); + this.theBufferedBlockCipher = par2BufferedBlockCipher; + this.buf = new byte[par2BufferedBlockCipher.getOutputSize(2048)]; + this.inBuf = new byte[2048]; + } + + private int nextChunk() throws IOException { + int var1 = super.available(); + + if (var1 <= 0) { + var1 = 1; + } + + if (var1 > this.inBuf.length) { + var1 = super.read(this.inBuf, 0, this.inBuf.length); + } else { + var1 = super.read(this.inBuf, 0, var1); + } + + if (var1 < 0) { + if (this.finalized) { + return -1; + } + + try { + if (this.theBufferedBlockCipher != null) { + this.maxBuf = this.theBufferedBlockCipher.doFinal(this.buf, 0); + } else { + this.maxBuf = 0; + } + } catch (Exception var4) { + throw new IOException("error processing stream: " + var4.toString()); + } + + this.bufOff = 0; + this.finalized = true; + + if (this.bufOff == this.maxBuf) { + return -1; + } + } else { + this.bufOff = 0; + + try { + if (this.theBufferedBlockCipher != null) { + this.maxBuf = this.theBufferedBlockCipher.processByte(this.inBuf, 0, var1, this.buf, 0); + } else { + this.theStreamCipher.processBytes(this.inBuf, 0, var1, this.buf, 0); + this.maxBuf = var1; + } + } catch (Exception var3) { + throw new IOException("error processing stream: " + var3.toString()); + } + + if (this.maxBuf == 0) { + return this.nextChunk(); + } + } + + return this.maxBuf; + } + + public int read() throws IOException { + return this.bufOff == this.maxBuf && this.nextChunk() < 0 ? -1 : this.buf[this.bufOff++] & 255; + } + + public int read(byte[] par1ArrayOfByte) throws IOException { + return this.read(par1ArrayOfByte, 0, par1ArrayOfByte.length); + } + + public int read(byte[] par1ArrayOfByte, int par2, int par3) throws IOException { + if (this.bufOff == this.maxBuf && this.nextChunk() < 0) { + return -1; + } else { + int var4 = this.maxBuf - this.bufOff; + + if (par3 > var4) { + System.arraycopy(this.buf, this.bufOff, par1ArrayOfByte, par2, var4); + this.bufOff = this.maxBuf; + return var4; + } else { + System.arraycopy(this.buf, this.bufOff, par1ArrayOfByte, par2, par3); + this.bufOff += par3; + return par3; + } + } + } + + public long skip(long par1) throws IOException { + if (par1 <= 0L) { + return 0L; + } else { + int var3 = this.maxBuf - this.bufOff; + + if (par1 > (long) var3) { + this.bufOff = this.maxBuf; + return (long) var3; + } else { + this.bufOff += (int) par1; + return (long) ((int) par1); + } + } + } + + public int available() throws IOException { + return this.maxBuf - this.bufOff; + } + + public void close() throws IOException { + super.close(); + } + + public boolean markSupported() { + return false; + } +} diff --git a/sp-server/src/main/java/org/bouncycastle/crypto/io/CipherOutputStream.java b/sp-server/src/main/java/org/bouncycastle/crypto/io/CipherOutputStream.java new file mode 100644 index 0000000..46df809 --- /dev/null +++ b/sp-server/src/main/java/org/bouncycastle/crypto/io/CipherOutputStream.java @@ -0,0 +1,77 @@ +package org.bouncycastle.crypto.io; + +import java.io.FilterOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import org.bouncycastle.crypto.BufferedBlockCipher; +import org.bouncycastle.crypto.StreamCipher; + +public class CipherOutputStream extends FilterOutputStream { + private BufferedBlockCipher theBufferedBlockCipher; + private StreamCipher theStreamCipher; + private byte[] oneByte = new byte[1]; + private byte[] buf; + + public CipherOutputStream(OutputStream par1OutputStream, BufferedBlockCipher par2BufferedBlockCipher) { + super(par1OutputStream); + this.theBufferedBlockCipher = par2BufferedBlockCipher; + this.buf = new byte[par2BufferedBlockCipher.getBlockSize()]; + } + + public void write(int par1) throws IOException { + this.oneByte[0] = (byte) par1; + + if (this.theBufferedBlockCipher != null) { + int var2 = this.theBufferedBlockCipher.processByte(this.oneByte, 0, 1, this.buf, 0); + + if (var2 != 0) { + this.out.write(this.buf, 0, var2); + } + } else { + this.out.write(this.theStreamCipher.returnByte((byte) par1)); + } + } + + public void write(byte[] par1) throws IOException { + this.write(par1, 0, par1.length); + } + + public void write(byte[] par1, int par2, int par3) throws IOException { + byte[] var4; + + if (this.theBufferedBlockCipher != null) { + var4 = new byte[this.theBufferedBlockCipher.getOutputSize(par3)]; + int var5 = this.theBufferedBlockCipher.processByte(par1, par2, par3, var4, 0); + + if (var5 != 0) { + this.out.write(var4, 0, var5); + } + } else { + var4 = new byte[par3]; + this.theStreamCipher.processBytes(par1, par2, par3, var4, 0); + this.out.write(var4, 0, par3); + } + } + + public void flush() throws IOException { + super.flush(); + } + + public void close() throws IOException { + try { + if (this.theBufferedBlockCipher != null) { + byte[] var1 = new byte[this.theBufferedBlockCipher.getOutputSize(0)]; + int var2 = this.theBufferedBlockCipher.doFinal(var1, 0); + + if (var2 != 0) { + this.out.write(var1, 0, var2); + } + } + } catch (Exception var3) { + throw new IOException("Error closing stream: " + var3.toString()); + } + + this.flush(); + super.close(); + } +} diff --git a/sp-server/src/main/java/org/bouncycastle/crypto/modes/CFBBlockCipher.java b/sp-server/src/main/java/org/bouncycastle/crypto/modes/CFBBlockCipher.java new file mode 100644 index 0000000..5d83844 --- /dev/null +++ b/sp-server/src/main/java/org/bouncycastle/crypto/modes/CFBBlockCipher.java @@ -0,0 +1,114 @@ +package org.bouncycastle.crypto.modes; + +import org.bouncycastle.crypto.BlockCipher; +import org.bouncycastle.crypto.CipherParameters; +import org.bouncycastle.crypto.DataLengthException; +import org.bouncycastle.crypto.params.ParametersWithIV; + +public class CFBBlockCipher implements BlockCipher { + private byte[] IV; + private byte[] cfbV; + private byte[] cfbOutV; + private int blockSize; + private BlockCipher cipher = null; + private boolean encrypting; + + public CFBBlockCipher(BlockCipher par1BlockCipher, int par2) { + this.cipher = par1BlockCipher; + this.blockSize = par2 / 8; + this.IV = new byte[par1BlockCipher.getBlockSize()]; + this.cfbV = new byte[par1BlockCipher.getBlockSize()]; + this.cfbOutV = new byte[par1BlockCipher.getBlockSize()]; + } + + public void init(boolean par1, CipherParameters par2CipherParameters) throws IllegalArgumentException { + this.encrypting = par1; + + if (par2CipherParameters instanceof ParametersWithIV) { + ParametersWithIV var3 = (ParametersWithIV) par2CipherParameters; + byte[] var4 = var3.getIV(); + + if (var4.length < this.IV.length) { + System.arraycopy(var4, 0, this.IV, this.IV.length - var4.length, var4.length); + + for (int var5 = 0; var5 < this.IV.length - var4.length; ++var5) { + this.IV[var5] = 0; + } + } else { + System.arraycopy(var4, 0, this.IV, 0, this.IV.length); + } + + this.reset(); + + if (var3.getParameters() != null) { + this.cipher.init(true, var3.getParameters()); + } + } else { + this.reset(); + this.cipher.init(true, par2CipherParameters); + } + } + + /** + * Return the name of the algorithm the cipher implements. + */ + public String getAlgorithmName() { + return this.cipher.getAlgorithmName() + "/CFB" + this.blockSize * 8; + } + + /** + * Return the block size for this cipher (in bytes). + */ + public int getBlockSize() { + return this.blockSize; + } + + public int processBlock(byte[] par1ArrayOfByte, int par2, byte[] par3ArrayOfByte, int par4) + throws DataLengthException, IllegalStateException { + return this.encrypting ? this.encryptBlock(par1ArrayOfByte, par2, par3ArrayOfByte, par4) + : this.decryptBlock(par1ArrayOfByte, par2, par3ArrayOfByte, par4); + } + + public int encryptBlock(byte[] par1ArrayOfByte, int par2, byte[] par3ArrayOfByte, int par4) + throws DataLengthException, IllegalStateException { + if (par2 + this.blockSize > par1ArrayOfByte.length) { + throw new DataLengthException("input buffer too short"); + } else if (par4 + this.blockSize > par3ArrayOfByte.length) { + throw new DataLengthException("output buffer too short"); + } else { + this.cipher.processBlock(this.cfbV, 0, this.cfbOutV, 0); + + for (int var5 = 0; var5 < this.blockSize; ++var5) { + par3ArrayOfByte[par4 + var5] = (byte) (this.cfbOutV[var5] ^ par1ArrayOfByte[par2 + var5]); + } + + System.arraycopy(this.cfbV, this.blockSize, this.cfbV, 0, this.cfbV.length - this.blockSize); + System.arraycopy(par3ArrayOfByte, par4, this.cfbV, this.cfbV.length - this.blockSize, this.blockSize); + return this.blockSize; + } + } + + public int decryptBlock(byte[] par1ArrayOfByte, int par2, byte[] par3ArrayOfByte, int par4) + throws DataLengthException, IllegalStateException { + if (par2 + this.blockSize > par1ArrayOfByte.length) { + throw new DataLengthException("input buffer too short"); + } else if (par4 + this.blockSize > par3ArrayOfByte.length) { + throw new DataLengthException("output buffer too short"); + } else { + this.cipher.processBlock(this.cfbV, 0, this.cfbOutV, 0); + System.arraycopy(this.cfbV, this.blockSize, this.cfbV, 0, this.cfbV.length - this.blockSize); + System.arraycopy(par1ArrayOfByte, par2, this.cfbV, this.cfbV.length - this.blockSize, this.blockSize); + + for (int var5 = 0; var5 < this.blockSize; ++var5) { + par3ArrayOfByte[par4 + var5] = (byte) (this.cfbOutV[var5] ^ par1ArrayOfByte[par2 + var5]); + } + + return this.blockSize; + } + } + + public void reset() { + System.arraycopy(this.IV, 0, this.cfbV, 0, this.IV.length); + this.cipher.reset(); + } +} diff --git a/sp-server/src/main/java/org/bouncycastle/crypto/params/KeyParameter.java b/sp-server/src/main/java/org/bouncycastle/crypto/params/KeyParameter.java new file mode 100644 index 0000000..215e4a9 --- /dev/null +++ b/sp-server/src/main/java/org/bouncycastle/crypto/params/KeyParameter.java @@ -0,0 +1,20 @@ +package org.bouncycastle.crypto.params; + +import org.bouncycastle.crypto.CipherParameters; + +public class KeyParameter implements CipherParameters { + private byte[] key; + + public KeyParameter(byte[] par1ArrayOfByte) { + this(par1ArrayOfByte, 0, par1ArrayOfByte.length); + } + + public KeyParameter(byte[] par1ArrayOfByte, int par2, int par3) { + this.key = new byte[par3]; + System.arraycopy(par1ArrayOfByte, par2, this.key, 0, par3); + } + + public byte[] getKey() { + return this.key; + } +} diff --git a/sp-server/src/main/java/org/bouncycastle/crypto/params/ParametersWithIV.java b/sp-server/src/main/java/org/bouncycastle/crypto/params/ParametersWithIV.java new file mode 100644 index 0000000..2ae9a9e --- /dev/null +++ b/sp-server/src/main/java/org/bouncycastle/crypto/params/ParametersWithIV.java @@ -0,0 +1,22 @@ +package org.bouncycastle.crypto.params; + +import org.bouncycastle.crypto.CipherParameters; + +public class ParametersWithIV implements CipherParameters { + private byte[] iv; + private CipherParameters parameters; + + public ParametersWithIV(CipherParameters par1CipherParameters, byte[] par2ArrayOfByte, int par3, int par4) { + this.iv = new byte[par4]; + this.parameters = par1CipherParameters; + System.arraycopy(par2ArrayOfByte, par3, this.iv, 0, par4); + } + + public byte[] getIV() { + return this.iv; + } + + public CipherParameters getParameters() { + return this.parameters; + } +} diff --git a/sp-server/src/main/java/org/bouncycastle/jcajce/provider/config/ConfigurableProvider.java b/sp-server/src/main/java/org/bouncycastle/jcajce/provider/config/ConfigurableProvider.java new file mode 100644 index 0000000..4ae5547 --- /dev/null +++ b/sp-server/src/main/java/org/bouncycastle/jcajce/provider/config/ConfigurableProvider.java @@ -0,0 +1,4 @@ +package org.bouncycastle.jcajce.provider.config; + +public interface ConfigurableProvider { +} diff --git a/sp-server/src/main/java/org/bouncycastle/jcajce/provider/config/ProviderConfiguration.java b/sp-server/src/main/java/org/bouncycastle/jcajce/provider/config/ProviderConfiguration.java new file mode 100644 index 0000000..8dc104b --- /dev/null +++ b/sp-server/src/main/java/org/bouncycastle/jcajce/provider/config/ProviderConfiguration.java @@ -0,0 +1,4 @@ +package org.bouncycastle.jcajce.provider.config; + +public interface ProviderConfiguration { +} diff --git a/sp-server/src/main/java/org/bouncycastle/jcajce/provider/config/ProviderConfigurationPermission.java b/sp-server/src/main/java/org/bouncycastle/jcajce/provider/config/ProviderConfigurationPermission.java new file mode 100644 index 0000000..99eaa1c --- /dev/null +++ b/sp-server/src/main/java/org/bouncycastle/jcajce/provider/config/ProviderConfigurationPermission.java @@ -0,0 +1,74 @@ +package org.bouncycastle.jcajce.provider.config; + +import java.security.BasicPermission; +import java.security.Permission; +import java.util.StringTokenizer; +import org.bouncycastle.util.Strings; + +public class ProviderConfigurationPermission extends BasicPermission { + private final String actions; + private final int permissionMask; + + public ProviderConfigurationPermission(String par1Str, String par2Str) { + super(par1Str, par2Str); + this.actions = par2Str; + this.permissionMask = this.calculateMask(par2Str); + } + + private int calculateMask(String par1Str) { + StringTokenizer var2 = new StringTokenizer(Strings.toLowerCase(par1Str), " ,"); + int var3 = 0; + + while (var2.hasMoreTokens()) { + String var4 = var2.nextToken(); + + if (var4.equals("threadlocalecimplicitlyca")) { + var3 |= 1; + } else if (var4.equals("ecimplicitlyca")) { + var3 |= 2; + } else if (var4.equals("threadlocaldhdefaultparams")) { + var3 |= 4; + } else if (var4.equals("dhdefaultparams")) { + var3 |= 8; + } else if (var4.equals("all")) { + var3 |= 15; + } + } + + if (var3 == 0) { + throw new IllegalArgumentException("unknown permissions passed to mask"); + } else { + return var3; + } + } + + public String getActions() { + return this.actions; + } + + public boolean implies(Permission par1Permission) { + if (!(par1Permission instanceof ProviderConfigurationPermission)) { + return false; + } else if (!this.getName().equals(par1Permission.getName())) { + return false; + } else { + ProviderConfigurationPermission var2 = (ProviderConfigurationPermission) par1Permission; + return (this.permissionMask & var2.permissionMask) == var2.permissionMask; + } + } + + public boolean equals(Object par1Obj) { + if (par1Obj == this) { + return true; + } else if (!(par1Obj instanceof ProviderConfigurationPermission)) { + return false; + } else { + ProviderConfigurationPermission var2 = (ProviderConfigurationPermission) par1Obj; + return this.permissionMask == var2.permissionMask && this.getName().equals(var2.getName()); + } + } + + public int hashCode() { + return this.getName().hashCode() + this.permissionMask; + } +} diff --git a/sp-server/src/main/java/org/bouncycastle/jcajce/provider/util/AlgorithmProvider.java b/sp-server/src/main/java/org/bouncycastle/jcajce/provider/util/AlgorithmProvider.java new file mode 100644 index 0000000..a0b7949 --- /dev/null +++ b/sp-server/src/main/java/org/bouncycastle/jcajce/provider/util/AlgorithmProvider.java @@ -0,0 +1,7 @@ +package org.bouncycastle.jcajce.provider.util; + +import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; + +public abstract class AlgorithmProvider { + public abstract void configure(ConfigurableProvider var1); +} diff --git a/sp-server/src/main/java/org/bouncycastle/jce/provider/BouncyCastleProvider.java b/sp-server/src/main/java/org/bouncycastle/jce/provider/BouncyCastleProvider.java new file mode 100644 index 0000000..0109c3a --- /dev/null +++ b/sp-server/src/main/java/org/bouncycastle/jce/provider/BouncyCastleProvider.java @@ -0,0 +1,365 @@ +package org.bouncycastle.jce.provider; + +import java.security.AccessController; +import java.security.Provider; +import java.util.HashMap; +import java.util.Map; +import org.bouncycastle.asn1.bc.BCObjectIdentifiers; +import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; +import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; +import org.bouncycastle.jcajce.provider.config.ProviderConfiguration; +import org.bouncycastle.jcajce.provider.util.AlgorithmProvider; + +public final class BouncyCastleProvider extends Provider implements ConfigurableProvider { + private static String info = "BouncyCastle Security Provider v1.47"; + public static String PROVIDER_NAME = "BC"; + public static final ProviderConfiguration CONFIGURATION = new BouncyCastleProviderConfiguration(); + private static final Map keyInfoConverters = new HashMap(); + private static final String[] SYMMETRIC_CIPHERS = new String[] { "AES", "ARC4", "Blowfish", "Camellia", "CAST5", + "CAST6", "DES", "DESede", "GOST28147", "Grainv1", "Grain128", "HC128", "HC256", "IDEA", "Noekeon", "RC2", + "RC5", "RC6", "Rijndael", "Salsa20", "SEED", "Serpent", "Skipjack", "TEA", "Twofish", "VMPC", "VMPCKSA3", + "XTEA" }; + private static final String[] ASYMMETRIC_GENERIC = new String[] { "X509" }; + private static final String[] ASYMMETRIC_CIPHERS = new String[] { "DSA", "DH", "EC", "RSA", "GOST", "ECGOST", + "ElGamal" }; + private static final String[] DIGESTS = new String[] { "GOST3411", "MD2", "MD4", "MD5", "SHA1", "RIPEMD128", + "RIPEMD160", "RIPEMD256", "RIPEMD320", "SHA224", "SHA256", "SHA384", "SHA512", "Tiger", "Whirlpool" }; + + public BouncyCastleProvider() { + super(PROVIDER_NAME, 1.47D, info); + AccessController.doPrivileged(new BouncyCastleProviderAction(this)); + } + + private void setup() { + this.loadAlgorithms("org.bouncycastle.jcajce.provider.digest.", DIGESTS); + this.loadAlgorithms("org.bouncycastle.jcajce.provider.symmetric.", SYMMETRIC_CIPHERS); + this.loadAlgorithms("org.bouncycastle.jcajce.provider.asymmetric.", ASYMMETRIC_GENERIC); + this.loadAlgorithms("org.bouncycastle.jcajce.provider.asymmetric.", ASYMMETRIC_CIPHERS); + this.put("X509Store.CERTIFICATE/COLLECTION", "org.bouncycastle.jce.provider.X509StoreCertCollection"); + this.put("X509Store.ATTRIBUTECERTIFICATE/COLLECTION", + "org.bouncycastle.jce.provider.X509StoreAttrCertCollection"); + this.put("X509Store.CRL/COLLECTION", "org.bouncycastle.jce.provider.X509StoreCRLCollection"); + this.put("X509Store.CERTIFICATEPAIR/COLLECTION", "org.bouncycastle.jce.provider.X509StoreCertPairCollection"); + this.put("X509Store.CERTIFICATE/LDAP", "org.bouncycastle.jce.provider.X509StoreLDAPCerts"); + this.put("X509Store.CRL/LDAP", "org.bouncycastle.jce.provider.X509StoreLDAPCRLs"); + this.put("X509Store.ATTRIBUTECERTIFICATE/LDAP", "org.bouncycastle.jce.provider.X509StoreLDAPAttrCerts"); + this.put("X509Store.CERTIFICATEPAIR/LDAP", "org.bouncycastle.jce.provider.X509StoreLDAPCertPairs"); + this.put("X509StreamParser.CERTIFICATE", "org.bouncycastle.jce.provider.X509CertParser"); + this.put("X509StreamParser.ATTRIBUTECERTIFICATE", "org.bouncycastle.jce.provider.X509AttrCertParser"); + this.put("X509StreamParser.CRL", "org.bouncycastle.jce.provider.X509CRLParser"); + this.put("X509StreamParser.CERTIFICATEPAIR", "org.bouncycastle.jce.provider.X509CertPairParser"); + this.put("KeyStore.BKS", "org.bouncycastle.jce.provider.JDKKeyStore"); + this.put("KeyStore.BouncyCastle", "org.bouncycastle.jce.provider.JDKKeyStore$BouncyCastleStore"); + this.put("KeyStore.PKCS12", "org.bouncycastle.jce.provider.JDKPKCS12KeyStore$BCPKCS12KeyStore"); + this.put("KeyStore.BCPKCS12", "org.bouncycastle.jce.provider.JDKPKCS12KeyStore$BCPKCS12KeyStore"); + this.put("KeyStore.PKCS12-DEF", "org.bouncycastle.jce.provider.JDKPKCS12KeyStore$DefPKCS12KeyStore"); + this.put("KeyStore.PKCS12-3DES-40RC2", "org.bouncycastle.jce.provider.JDKPKCS12KeyStore$BCPKCS12KeyStore"); + this.put("KeyStore.PKCS12-3DES-3DES", "org.bouncycastle.jce.provider.JDKPKCS12KeyStore$BCPKCS12KeyStore3DES"); + this.put("KeyStore.PKCS12-DEF-3DES-40RC2", "org.bouncycastle.jce.provider.JDKPKCS12KeyStore$DefPKCS12KeyStore"); + this.put("KeyStore.PKCS12-DEF-3DES-3DES", + "org.bouncycastle.jce.provider.JDKPKCS12KeyStore$DefPKCS12KeyStore3DES"); + this.put("Alg.Alias.KeyStore.UBER", "BouncyCastle"); + this.put("Alg.Alias.KeyStore.BOUNCYCASTLE", "BouncyCastle"); + this.put("Alg.Alias.KeyStore.bouncycastle", "BouncyCastle"); + this.put("AlgorithmParameters.IES", "org.bouncycastle.jce.provider.JDKAlgorithmParameters$IES"); + this.put("AlgorithmParameters.PKCS12PBE", "org.bouncycastle.jce.provider.JDKAlgorithmParameters$PKCS12PBE"); + this.put("AlgorithmParameters." + PKCSObjectIdentifiers.id_PBKDF2, + "org.bouncycastle.jce.provider.JDKAlgorithmParameters$PBKDF2"); + this.put("Alg.Alias.AlgorithmParameters.PBEWITHSHA1ANDRC2", "PKCS12PBE"); + this.put("Alg.Alias.AlgorithmParameters.PBEWITHSHAAND3-KEYTRIPLEDES", "PKCS12PBE"); + this.put("Alg.Alias.AlgorithmParameters.PBEWITHSHAAND2-KEYTRIPLEDES", "PKCS12PBE"); + this.put("Alg.Alias.AlgorithmParameters.PBEWITHSHAANDRC2", "PKCS12PBE"); + this.put("Alg.Alias.AlgorithmParameters.PBEWITHSHAANDRC4", "PKCS12PBE"); + this.put("Alg.Alias.AlgorithmParameters.PBEWITHSHAANDTWOFISH", "PKCS12PBE"); + this.put("Alg.Alias.AlgorithmParameters.PBEWITHSHA1ANDRC2-CBC", "PKCS12PBE"); + this.put("Alg.Alias.AlgorithmParameters.PBEWITHSHAAND3-KEYTRIPLEDES-CBC", "PKCS12PBE"); + this.put("Alg.Alias.AlgorithmParameters.PBEWITHSHAAND2-KEYTRIPLEDES-CBC", "PKCS12PBE"); + this.put("Alg.Alias.AlgorithmParameters.PBEWITHSHAANDDES3KEY-CBC", "PKCS12PBE"); + this.put("Alg.Alias.AlgorithmParameters.PBEWITHSHAANDDES2KEY-CBC", "PKCS12PBE"); + this.put("Alg.Alias.AlgorithmParameters.PBEWITHSHAAND40BITRC2-CBC", "PKCS12PBE"); + this.put("Alg.Alias.AlgorithmParameters.PBEWITHSHAAND40BITRC4", "PKCS12PBE"); + this.put("Alg.Alias.AlgorithmParameters.PBEWITHSHAAND128BITRC2-CBC", "PKCS12PBE"); + this.put("Alg.Alias.AlgorithmParameters.PBEWITHSHAAND128BITRC4", "PKCS12PBE"); + this.put("Alg.Alias.AlgorithmParameters.PBEWITHSHAANDTWOFISH", "PKCS12PBE"); + this.put("Alg.Alias.AlgorithmParameters.PBEWITHSHAANDTWOFISH-CBC", "PKCS12PBE"); + this.put("Alg.Alias.AlgorithmParameters.1.2.840.113549.1.12.1.1", "PKCS12PBE"); + this.put("Alg.Alias.AlgorithmParameters.1.2.840.113549.1.12.1.2", "PKCS12PBE"); + this.put("Alg.Alias.AlgorithmParameters.1.2.840.113549.1.12.1.3", "PKCS12PBE"); + this.put("Alg.Alias.AlgorithmParameters.1.2.840.113549.1.12.1.4", "PKCS12PBE"); + this.put("Alg.Alias.AlgorithmParameters.1.2.840.113549.1.12.1.5", "PKCS12PBE"); + this.put("Alg.Alias.AlgorithmParameters.1.2.840.113549.1.12.1.6", "PKCS12PBE"); + this.put("Alg.Alias.AlgorithmParameters.PBEWithSHAAnd3KeyTripleDES", "PKCS12PBE"); + this.put("Alg.Alias.AlgorithmParameters." + BCObjectIdentifiers.bc_pbe_sha1_pkcs12_aes128_cbc.getId(), + "PKCS12PBE"); + this.put("Alg.Alias.AlgorithmParameters." + BCObjectIdentifiers.bc_pbe_sha1_pkcs12_aes192_cbc.getId(), + "PKCS12PBE"); + this.put("Alg.Alias.AlgorithmParameters." + BCObjectIdentifiers.bc_pbe_sha1_pkcs12_aes256_cbc.getId(), + "PKCS12PBE"); + this.put("Alg.Alias.AlgorithmParameters." + BCObjectIdentifiers.bc_pbe_sha256_pkcs12_aes128_cbc.getId(), + "PKCS12PBE"); + this.put("Alg.Alias.AlgorithmParameters." + BCObjectIdentifiers.bc_pbe_sha256_pkcs12_aes192_cbc.getId(), + "PKCS12PBE"); + this.put("Alg.Alias.AlgorithmParameters." + BCObjectIdentifiers.bc_pbe_sha256_pkcs12_aes256_cbc.getId(), + "PKCS12PBE"); + this.put("Alg.Alias.AlgorithmParameters.PBEWITHSHAAND128BITAES-CBC-BC", "PKCS12PBE"); + this.put("Alg.Alias.AlgorithmParameters.PBEWITHSHAAND192BITAES-CBC-BC", "PKCS12PBE"); + this.put("Alg.Alias.AlgorithmParameters.PBEWITHSHAAND256BITAES-CBC-BC", "PKCS12PBE"); + this.put("Alg.Alias.AlgorithmParameters.PBEWITHSHA256AND128BITAES-CBC-BC", "PKCS12PBE"); + this.put("Alg.Alias.AlgorithmParameters.PBEWITHSHA256AND192BITAES-CBC-BC", "PKCS12PBE"); + this.put("Alg.Alias.AlgorithmParameters.PBEWITHSHA256AND256BITAES-CBC-BC", "PKCS12PBE"); + this.put("Alg.Alias.AlgorithmParameters.PBEWITHSHA1AND128BITAES-CBC-BC", "PKCS12PBE"); + this.put("Alg.Alias.AlgorithmParameters.PBEWITHSHA1AND192BITAES-CBC-BC", "PKCS12PBE"); + this.put("Alg.Alias.AlgorithmParameters.PBEWITHSHA1AND256BITAES-CBC-BC", "PKCS12PBE"); + this.put("Alg.Alias.AlgorithmParameters.PBEWITHSHA-1AND128BITAES-CBC-BC", "PKCS12PBE"); + this.put("Alg.Alias.AlgorithmParameters.PBEWITHSHA-1AND192BITAES-CBC-BC", "PKCS12PBE"); + this.put("Alg.Alias.AlgorithmParameters.PBEWITHSHA-1AND256BITAES-CBC-BC", "PKCS12PBE"); + this.put("Alg.Alias.AlgorithmParameters.PBEWITHSHA-256AND128BITAES-CBC-BC", "PKCS12PBE"); + this.put("Alg.Alias.AlgorithmParameters.PBEWITHSHA-256AND192BITAES-CBC-BC", "PKCS12PBE"); + this.put("Alg.Alias.AlgorithmParameters.PBEWITHSHA-256AND256BITAES-CBC-BC", "PKCS12PBE"); + this.put("AlgorithmParameters.SHA1WITHECDSA", + "org.bouncycastle.jce.provider.JDKECDSAAlgParameters$SigAlgParameters"); + this.put("AlgorithmParameters.SHA224WITHECDSA", + "org.bouncycastle.jce.provider.JDKECDSAAlgParameters$SigAlgParameters"); + this.put("AlgorithmParameters.SHA256WITHECDSA", + "org.bouncycastle.jce.provider.JDKECDSAAlgParameters$SigAlgParameters"); + this.put("AlgorithmParameters.SHA384WITHECDSA", + "org.bouncycastle.jce.provider.JDKECDSAAlgParameters$SigAlgParameters"); + this.put("AlgorithmParameters.SHA512WITHECDSA", + "org.bouncycastle.jce.provider.JDKECDSAAlgParameters$SigAlgParameters"); + this.put("Alg.Alias.Cipher.PBEWithSHAAnd3KeyTripleDES", "PBEWITHSHAAND3-KEYTRIPLEDES-CBC"); + this.put("Cipher.ECIES", "org.bouncycastle.jce.provider.JCEIESCipher$ECIES"); + this.put("Cipher.BrokenECIES", "org.bouncycastle.jce.provider.JCEIESCipher$BrokenECIES"); + this.put("Cipher.IES", "org.bouncycastle.jce.provider.JCEIESCipher$IES"); + this.put("Cipher.BrokenIES", "org.bouncycastle.jce.provider.JCEIESCipher$BrokenIES"); + this.put("Cipher.PBEWITHMD5ANDDES", "org.bouncycastle.jce.provider.JCEBlockCipher$PBEWithMD5AndDES"); + this.put("Cipher.BROKENPBEWITHMD5ANDDES", + "org.bouncycastle.jce.provider.BrokenJCEBlockCipher$BrokePBEWithMD5AndDES"); + this.put("Cipher.PBEWITHMD5ANDRC2", "org.bouncycastle.jce.provider.JCEBlockCipher$PBEWithMD5AndRC2"); + this.put("Cipher.PBEWITHSHA1ANDDES", "org.bouncycastle.jce.provider.JCEBlockCipher$PBEWithSHA1AndDES"); + this.put("Cipher.BROKENPBEWITHSHA1ANDDES", + "org.bouncycastle.jce.provider.BrokenJCEBlockCipher$BrokePBEWithSHA1AndDES"); + this.put("Cipher.PBEWITHSHA1ANDRC2", "org.bouncycastle.jce.provider.JCEBlockCipher$PBEWithSHA1AndRC2"); + this.put("Cipher.PBEWITHSHAAND128BITRC2-CBC", + "org.bouncycastle.jce.provider.JCEBlockCipher$PBEWithSHAAnd128BitRC2"); + this.put("Cipher.PBEWITHSHAAND40BITRC2-CBC", + "org.bouncycastle.jce.provider.JCEBlockCipher$PBEWithSHAAnd40BitRC2"); + this.put("Cipher.PBEWITHSHAAND128BITRC4", + "org.bouncycastle.jce.provider.JCEStreamCipher$PBEWithSHAAnd128BitRC4"); + this.put("Cipher.PBEWITHSHAAND40BITRC4", "org.bouncycastle.jce.provider.JCEStreamCipher$PBEWithSHAAnd40BitRC4"); + this.put("Alg.Alias.Cipher.PBEWITHSHA1AND128BITRC2-CBC", "PBEWITHSHAAND128BITRC2-CBC"); + this.put("Alg.Alias.Cipher.PBEWITHSHA1AND40BITRC2-CBC", "PBEWITHSHAAND40BITRC2-CBC"); + this.put("Alg.Alias.Cipher.PBEWITHSHA1AND128BITRC4", "PBEWITHSHAAND128BITRC4"); + this.put("Alg.Alias.Cipher.PBEWITHSHA1AND40BITRC4", "PBEWITHSHAAND40BITRC4"); + this.put("Alg.Alias.Cipher." + BCObjectIdentifiers.bc_pbe_sha1_pkcs12_aes128_cbc.getId(), + "PBEWITHSHAAND128BITAES-CBC-BC"); + this.put("Alg.Alias.Cipher." + BCObjectIdentifiers.bc_pbe_sha1_pkcs12_aes192_cbc.getId(), + "PBEWITHSHAAND192BITAES-CBC-BC"); + this.put("Alg.Alias.Cipher." + BCObjectIdentifiers.bc_pbe_sha1_pkcs12_aes256_cbc.getId(), + "PBEWITHSHAAND256BITAES-CBC-BC"); + this.put("Alg.Alias.Cipher." + BCObjectIdentifiers.bc_pbe_sha256_pkcs12_aes128_cbc.getId(), + "PBEWITHSHA256AND128BITAES-CBC-BC"); + this.put("Alg.Alias.Cipher." + BCObjectIdentifiers.bc_pbe_sha256_pkcs12_aes192_cbc.getId(), + "PBEWITHSHA256AND192BITAES-CBC-BC"); + this.put("Alg.Alias.Cipher." + BCObjectIdentifiers.bc_pbe_sha256_pkcs12_aes256_cbc.getId(), + "PBEWITHSHA256AND256BITAES-CBC-BC"); + this.put("Cipher.PBEWITHSHAAND128BITAES-CBC-BC", "org.bouncycastle.jce.provider.JCEBlockCipher$PBEWithAESCBC"); + this.put("Cipher.PBEWITHSHAAND192BITAES-CBC-BC", "org.bouncycastle.jce.provider.JCEBlockCipher$PBEWithAESCBC"); + this.put("Cipher.PBEWITHSHAAND256BITAES-CBC-BC", "org.bouncycastle.jce.provider.JCEBlockCipher$PBEWithAESCBC"); + this.put("Cipher.PBEWITHSHA256AND128BITAES-CBC-BC", + "org.bouncycastle.jce.provider.JCEBlockCipher$PBEWithAESCBC"); + this.put("Cipher.PBEWITHSHA256AND192BITAES-CBC-BC", + "org.bouncycastle.jce.provider.JCEBlockCipher$PBEWithAESCBC"); + this.put("Cipher.PBEWITHSHA256AND256BITAES-CBC-BC", + "org.bouncycastle.jce.provider.JCEBlockCipher$PBEWithAESCBC"); + this.put("Alg.Alias.Cipher.PBEWITHSHA1AND128BITAES-CBC-BC", "PBEWITHSHAAND128BITAES-CBC-BC"); + this.put("Alg.Alias.Cipher.PBEWITHSHA1AND192BITAES-CBC-BC", "PBEWITHSHAAND192BITAES-CBC-BC"); + this.put("Alg.Alias.Cipher.PBEWITHSHA1AND256BITAES-CBC-BC", "PBEWITHSHAAND256BITAES-CBC-BC"); + this.put("Alg.Alias.Cipher.PBEWITHSHA-1AND128BITAES-CBC-BC", "PBEWITHSHAAND128BITAES-CBC-BC"); + this.put("Alg.Alias.Cipher.PBEWITHSHA-1AND192BITAES-CBC-BC", "PBEWITHSHAAND192BITAES-CBC-BC"); + this.put("Alg.Alias.Cipher.PBEWITHSHA-1AND256BITAES-CBC-BC", "PBEWITHSHAAND256BITAES-CBC-BC"); + this.put("Alg.Alias.Cipher.PBEWITHSHA-256AND128BITAES-CBC-BC", "PBEWITHSHA256AND128BITAES-CBC-BC"); + this.put("Alg.Alias.Cipher.PBEWITHSHA-256AND192BITAES-CBC-BC", "PBEWITHSHA256AND192BITAES-CBC-BC"); + this.put("Alg.Alias.Cipher.PBEWITHSHA-256AND256BITAES-CBC-BC", "PBEWITHSHA256AND256BITAES-CBC-BC"); + this.put("Cipher.PBEWITHMD5AND128BITAES-CBC-OPENSSL", + "org.bouncycastle.jce.provider.JCEBlockCipher$PBEWithAESCBC"); + this.put("Cipher.PBEWITHMD5AND192BITAES-CBC-OPENSSL", + "org.bouncycastle.jce.provider.JCEBlockCipher$PBEWithAESCBC"); + this.put("Cipher.PBEWITHMD5AND256BITAES-CBC-OPENSSL", + "org.bouncycastle.jce.provider.JCEBlockCipher$PBEWithAESCBC"); + this.put("Cipher.PBEWITHSHAANDTWOFISH-CBC", + "org.bouncycastle.jce.provider.JCEBlockCipher$PBEWithSHAAndTwofish"); + this.put("Cipher.OLDPBEWITHSHAANDTWOFISH-CBC", + "org.bouncycastle.jce.provider.BrokenJCEBlockCipher$OldPBEWithSHAAndTwofish"); + this.put("Alg.Alias.Cipher." + PKCSObjectIdentifiers.pbeWithMD2AndDES_CBC, "PBEWITHMD2ANDDES"); + this.put("Alg.Alias.Cipher." + PKCSObjectIdentifiers.pbeWithMD2AndRC2_CBC, "PBEWITHMD2ANDRC2"); + this.put("Alg.Alias.Cipher." + PKCSObjectIdentifiers.pbeWithMD5AndDES_CBC, "PBEWITHMD5ANDDES"); + this.put("Alg.Alias.Cipher." + PKCSObjectIdentifiers.pbeWithMD5AndRC2_CBC, "PBEWITHMD5ANDDES"); + this.put("Alg.Alias.Cipher." + PKCSObjectIdentifiers.pbeWithSHA1AndDES_CBC, "PBEWITHSHA1ANDDES"); + this.put("Alg.Alias.Cipher." + PKCSObjectIdentifiers.pbeWithSHA1AndRC2_CBC, "PBEWITHSHA1ANDRC2"); + this.put("Alg.Alias.Cipher.1.2.840.113549.1.12.1.1", "PBEWITHSHAAND128BITRC4"); + this.put("Alg.Alias.Cipher.1.2.840.113549.1.12.1.2", "PBEWITHSHAAND40BITRC4"); + this.put("Alg.Alias.Cipher.1.2.840.113549.1.12.1.5", "PBEWITHSHAAND128BITRC2-CBC"); + this.put("Alg.Alias.Cipher.1.2.840.113549.1.12.1.6", "PBEWITHSHAAND40BITRC2-CBC"); + this.put("SecretKeyFactory.PBEWITHMD2ANDDES", + "org.bouncycastle.jce.provider.JCESecretKeyFactory$PBEWithMD2AndDES"); + this.put("Alg.Alias.SecretKeyFactory." + PKCSObjectIdentifiers.pbeWithMD2AndDES_CBC, "PBEWITHMD2ANDDES"); + this.put("Alg.Alias.SecretKeyFactory." + PKCSObjectIdentifiers.pbeWithMD2AndRC2_CBC, "PBEWITHMD2ANDRC2"); + this.put("Alg.Alias.SecretKeyFactory." + PKCSObjectIdentifiers.pbeWithMD5AndDES_CBC, "PBEWITHMD5ANDDES"); + this.put("Alg.Alias.SecretKeyFactory." + PKCSObjectIdentifiers.pbeWithMD5AndRC2_CBC, "PBEWITHMD5ANDDES"); + this.put("Alg.Alias.SecretKeyFactory." + PKCSObjectIdentifiers.pbeWithSHA1AndDES_CBC, "PBEWITHSHA1ANDDES"); + this.put("Alg.Alias.SecretKeyFactory." + PKCSObjectIdentifiers.pbeWithSHA1AndRC2_CBC, "PBEWITHSHA1ANDRC2"); + this.put("SecretKeyFactory.PBEWITHMD2ANDRC2", + "org.bouncycastle.jce.provider.JCESecretKeyFactory$PBEWithMD2AndRC2"); + this.put("SecretKeyFactory.PBEWITHMD5ANDDES", + "org.bouncycastle.jce.provider.JCESecretKeyFactory$PBEWithMD5AndDES"); + this.put("SecretKeyFactory.PBEWITHMD5ANDRC2", + "org.bouncycastle.jce.provider.JCESecretKeyFactory$PBEWithMD5AndRC2"); + this.put("SecretKeyFactory.PBEWITHSHA1ANDDES", + "org.bouncycastle.jce.provider.JCESecretKeyFactory$PBEWithSHA1AndDES"); + this.put("SecretKeyFactory.PBEWITHSHA1ANDRC2", + "org.bouncycastle.jce.provider.JCESecretKeyFactory$PBEWithSHA1AndRC2"); + this.put("SecretKeyFactory.PBEWITHSHAAND3-KEYTRIPLEDES-CBC", + "org.bouncycastle.jce.provider.JCESecretKeyFactory$PBEWithSHAAndDES3Key"); + this.put("SecretKeyFactory.PBEWITHSHAAND2-KEYTRIPLEDES-CBC", + "org.bouncycastle.jce.provider.JCESecretKeyFactory$PBEWithSHAAndDES2Key"); + this.put("SecretKeyFactory.PBEWITHSHAAND128BITRC4", + "org.bouncycastle.jce.provider.JCESecretKeyFactory$PBEWithSHAAnd128BitRC4"); + this.put("SecretKeyFactory.PBEWITHSHAAND40BITRC4", + "org.bouncycastle.jce.provider.JCESecretKeyFactory$PBEWithSHAAnd40BitRC4"); + this.put("SecretKeyFactory.PBEWITHSHAAND128BITRC2-CBC", + "org.bouncycastle.jce.provider.JCESecretKeyFactory$PBEWithSHAAnd128BitRC2"); + this.put("SecretKeyFactory.PBEWITHSHAAND40BITRC2-CBC", + "org.bouncycastle.jce.provider.JCESecretKeyFactory$PBEWithSHAAnd40BitRC2"); + this.put("SecretKeyFactory.PBEWITHSHAANDTWOFISH-CBC", + "org.bouncycastle.jce.provider.JCESecretKeyFactory$PBEWithSHAAndTwofish"); + this.put("SecretKeyFactory.PBEWITHHMACRIPEMD160", + "org.bouncycastle.jce.provider.JCESecretKeyFactory$PBEWithRIPEMD160"); + this.put("SecretKeyFactory.PBEWITHHMACSHA1", "org.bouncycastle.jce.provider.JCESecretKeyFactory$PBEWithSHA"); + this.put("SecretKeyFactory.PBEWITHHMACTIGER", "org.bouncycastle.jce.provider.JCESecretKeyFactory$PBEWithTiger"); + this.put("SecretKeyFactory.PBEWITHMD5AND128BITAES-CBC-OPENSSL", + "org.bouncycastle.jce.provider.JCESecretKeyFactory$PBEWithMD5And128BitAESCBCOpenSSL"); + this.put("SecretKeyFactory.PBEWITHMD5AND192BITAES-CBC-OPENSSL", + "org.bouncycastle.jce.provider.JCESecretKeyFactory$PBEWithMD5And192BitAESCBCOpenSSL"); + this.put("SecretKeyFactory.PBEWITHMD5AND256BITAES-CBC-OPENSSL", + "org.bouncycastle.jce.provider.JCESecretKeyFactory$PBEWithMD5And256BitAESCBCOpenSSL"); + this.put("Alg.Alias.SecretKeyFactory.PBE", "PBE/PKCS5"); + this.put("Alg.Alias.SecretKeyFactory.BROKENPBEWITHMD5ANDDES", "PBE/PKCS5"); + this.put("Alg.Alias.SecretKeyFactory.BROKENPBEWITHSHA1ANDDES", "PBE/PKCS5"); + this.put("Alg.Alias.SecretKeyFactory.OLDPBEWITHSHAAND3-KEYTRIPLEDES-CBC", "PBE/PKCS12"); + this.put("Alg.Alias.SecretKeyFactory.BROKENPBEWITHSHAAND3-KEYTRIPLEDES-CBC", "PBE/PKCS12"); + this.put("Alg.Alias.SecretKeyFactory.BROKENPBEWITHSHAAND2-KEYTRIPLEDES-CBC", "PBE/PKCS12"); + this.put("Alg.Alias.SecretKeyFactory.OLDPBEWITHSHAANDTWOFISH-CBC", "PBE/PKCS12"); + this.put("Alg.Alias.SecretKeyFactory.PBEWITHMD2ANDDES-CBC", "PBEWITHMD2ANDDES"); + this.put("Alg.Alias.SecretKeyFactory.PBEWITHMD2ANDRC2-CBC", "PBEWITHMD2ANDRC2"); + this.put("Alg.Alias.SecretKeyFactory.PBEWITHMD5ANDDES-CBC", "PBEWITHMD5ANDDES"); + this.put("Alg.Alias.SecretKeyFactory.PBEWITHMD5ANDRC2-CBC", "PBEWITHMD5ANDRC2"); + this.put("Alg.Alias.SecretKeyFactory.PBEWITHSHA1ANDDES-CBC", "PBEWITHSHA1ANDDES"); + this.put("Alg.Alias.SecretKeyFactory.PBEWITHSHA1ANDRC2-CBC", "PBEWITHSHA1ANDRC2"); + this.put("Alg.Alias.SecretKeyFactory." + PKCSObjectIdentifiers.pbeWithMD2AndDES_CBC, "PBEWITHMD2ANDDES"); + this.put("Alg.Alias.SecretKeyFactory." + PKCSObjectIdentifiers.pbeWithMD2AndRC2_CBC, "PBEWITHMD2ANDRC2"); + this.put("Alg.Alias.SecretKeyFactory." + PKCSObjectIdentifiers.pbeWithMD5AndDES_CBC, "PBEWITHMD5ANDDES"); + this.put("Alg.Alias.SecretKeyFactory." + PKCSObjectIdentifiers.pbeWithMD5AndRC2_CBC, "PBEWITHMD5ANDRC2"); + this.put("Alg.Alias.SecretKeyFactory." + PKCSObjectIdentifiers.pbeWithSHA1AndDES_CBC, "PBEWITHSHA1ANDDES"); + this.put("Alg.Alias.SecretKeyFactory." + PKCSObjectIdentifiers.pbeWithSHA1AndRC2_CBC, "PBEWITHSHA1ANDRC2"); + this.put("Alg.Alias.SecretKeyFactory.1.2.840.113549.1.12.1.1", "PBEWITHSHAAND128BITRC4"); + this.put("Alg.Alias.SecretKeyFactory.1.2.840.113549.1.12.1.2", "PBEWITHSHAAND40BITRC4"); + this.put("Alg.Alias.SecretKeyFactory.1.2.840.113549.1.12.1.3", "PBEWITHSHAAND3-KEYTRIPLEDES-CBC"); + this.put("Alg.Alias.SecretKeyFactory.1.2.840.113549.1.12.1.4", "PBEWITHSHAAND2-KEYTRIPLEDES-CBC"); + this.put("Alg.Alias.SecretKeyFactory.1.2.840.113549.1.12.1.5", "PBEWITHSHAAND128BITRC2-CBC"); + this.put("Alg.Alias.SecretKeyFactory.1.2.840.113549.1.12.1.6", "PBEWITHSHAAND40BITRC2-CBC"); + this.put("Alg.Alias.SecretKeyFactory.PBEWITHHMACSHA", "PBEWITHHMACSHA1"); + this.put("Alg.Alias.SecretKeyFactory.1.3.14.3.2.26", "PBEWITHHMACSHA1"); + this.put("Alg.Alias.SecretKeyFactory.PBEWithSHAAnd3KeyTripleDES", "PBEWITHSHAAND3-KEYTRIPLEDES-CBC"); + this.put("SecretKeyFactory.PBEWITHSHAAND128BITAES-CBC-BC", + "org.bouncycastle.jce.provider.JCESecretKeyFactory$PBEWithSHAAnd128BitAESBC"); + this.put("SecretKeyFactory.PBEWITHSHAAND192BITAES-CBC-BC", + "org.bouncycastle.jce.provider.JCESecretKeyFactory$PBEWithSHAAnd192BitAESBC"); + this.put("SecretKeyFactory.PBEWITHSHAAND256BITAES-CBC-BC", + "org.bouncycastle.jce.provider.JCESecretKeyFactory$PBEWithSHAAnd256BitAESBC"); + this.put("SecretKeyFactory.PBEWITHSHA256AND128BITAES-CBC-BC", + "org.bouncycastle.jce.provider.JCESecretKeyFactory$PBEWithSHA256And128BitAESBC"); + this.put("SecretKeyFactory.PBEWITHSHA256AND192BITAES-CBC-BC", + "org.bouncycastle.jce.provider.JCESecretKeyFactory$PBEWithSHA256And192BitAESBC"); + this.put("SecretKeyFactory.PBEWITHSHA256AND256BITAES-CBC-BC", + "org.bouncycastle.jce.provider.JCESecretKeyFactory$PBEWithSHA256And256BitAESBC"); + this.put("Alg.Alias.SecretKeyFactory.PBEWITHSHA1AND128BITAES-CBC-BC", "PBEWITHSHAAND128BITAES-CBC-BC"); + this.put("Alg.Alias.SecretKeyFactory.PBEWITHSHA1AND192BITAES-CBC-BC", "PBEWITHSHAAND192BITAES-CBC-BC"); + this.put("Alg.Alias.SecretKeyFactory.PBEWITHSHA1AND256BITAES-CBC-BC", "PBEWITHSHAAND256BITAES-CBC-BC"); + this.put("Alg.Alias.SecretKeyFactory.PBEWITHSHA-1AND128BITAES-CBC-BC", "PBEWITHSHAAND128BITAES-CBC-BC"); + this.put("Alg.Alias.SecretKeyFactory.PBEWITHSHA-1AND192BITAES-CBC-BC", "PBEWITHSHAAND192BITAES-CBC-BC"); + this.put("Alg.Alias.SecretKeyFactory.PBEWITHSHA-1AND256BITAES-CBC-BC", "PBEWITHSHAAND256BITAES-CBC-BC"); + this.put("Alg.Alias.SecretKeyFactory.PBEWITHSHA-256AND128BITAES-CBC-BC", "PBEWITHSHA256AND128BITAES-CBC-BC"); + this.put("Alg.Alias.SecretKeyFactory.PBEWITHSHA-256AND192BITAES-CBC-BC", "PBEWITHSHA256AND192BITAES-CBC-BC"); + this.put("Alg.Alias.SecretKeyFactory.PBEWITHSHA-256AND256BITAES-CBC-BC", "PBEWITHSHA256AND256BITAES-CBC-BC"); + this.put("Alg.Alias.SecretKeyFactory." + BCObjectIdentifiers.bc_pbe_sha1_pkcs12_aes128_cbc.getId(), + "PBEWITHSHAAND128BITAES-CBC-BC"); + this.put("Alg.Alias.SecretKeyFactory." + BCObjectIdentifiers.bc_pbe_sha1_pkcs12_aes192_cbc.getId(), + "PBEWITHSHAAND192BITAES-CBC-BC"); + this.put("Alg.Alias.SecretKeyFactory." + BCObjectIdentifiers.bc_pbe_sha1_pkcs12_aes256_cbc.getId(), + "PBEWITHSHAAND256BITAES-CBC-BC"); + this.put("Alg.Alias.SecretKeyFactory." + BCObjectIdentifiers.bc_pbe_sha256_pkcs12_aes128_cbc.getId(), + "PBEWITHSHA256AND128BITAES-CBC-BC"); + this.put("Alg.Alias.SecretKeyFactory." + BCObjectIdentifiers.bc_pbe_sha256_pkcs12_aes192_cbc.getId(), + "PBEWITHSHA256AND192BITAES-CBC-BC"); + this.put("Alg.Alias.SecretKeyFactory." + BCObjectIdentifiers.bc_pbe_sha256_pkcs12_aes256_cbc.getId(), + "PBEWITHSHA256AND256BITAES-CBC-BC"); + this.addMacAlgorithms(); + this.put("CertPathValidator.RFC3281", "org.bouncycastle.jce.provider.PKIXAttrCertPathValidatorSpi"); + this.put("CertPathBuilder.RFC3281", "org.bouncycastle.jce.provider.PKIXAttrCertPathBuilderSpi"); + this.put("CertPathValidator.RFC3280", "org.bouncycastle.jce.provider.PKIXCertPathValidatorSpi"); + this.put("CertPathBuilder.RFC3280", "org.bouncycastle.jce.provider.PKIXCertPathBuilderSpi"); + this.put("CertPathValidator.PKIX", "org.bouncycastle.jce.provider.PKIXCertPathValidatorSpi"); + this.put("CertPathBuilder.PKIX", "org.bouncycastle.jce.provider.PKIXCertPathBuilderSpi"); + this.put("CertStore.Collection", "org.bouncycastle.jce.provider.CertStoreCollectionSpi"); + this.put("CertStore.LDAP", "org.bouncycastle.jce.provider.X509LDAPCertStoreSpi"); + this.put("CertStore.Multi", "org.bouncycastle.jce.provider.MultiCertStoreSpi"); + this.put("Alg.Alias.CertStore.X509LDAP", "LDAP"); + } + + private void loadAlgorithms(String par1Str, String[] par2ArrayOfStr) { + for (int var3 = 0; var3 != par2ArrayOfStr.length; ++var3) { + Class var4 = null; + + try { + ClassLoader var5 = this.getClass().getClassLoader(); + + if (var5 != null) { + var4 = var5.loadClass(par1Str + par2ArrayOfStr[var3] + "$Mappings"); + } else { + var4 = Class.forName(par1Str + par2ArrayOfStr[var3] + "$Mappings"); + } + } catch (ClassNotFoundException var7) { + ; + } + + if (var4 != null) { + try { + ((AlgorithmProvider) var4.newInstance()).configure(this); + } catch (Exception var6) { + var6.printStackTrace(); + throw new InternalError( + "cannot create instance of " + par1Str + par2ArrayOfStr[var3] + "$Mappings : " + var6); + } + } + } + } + + private void addMacAlgorithms() { + this.put("Mac.DESWITHISO9797", "org.bouncycastle.jce.provider.JCEMac$DES9797Alg3"); + this.put("Alg.Alias.Mac.DESISO9797MAC", "DESWITHISO9797"); + this.put("Mac.ISO9797ALG3MAC", "org.bouncycastle.jce.provider.JCEMac$DES9797Alg3"); + this.put("Alg.Alias.Mac.ISO9797ALG3", "ISO9797ALG3MAC"); + this.put("Mac.ISO9797ALG3WITHISO7816-4PADDING", "org.bouncycastle.jce.provider.JCEMac$DES9797Alg3with7816d4"); + this.put("Alg.Alias.Mac.ISO9797ALG3MACWITHISO7816-4PADDING", "ISO9797ALG3WITHISO7816-4PADDING"); + this.put("Mac.OLDHMACSHA384", "org.bouncycastle.jce.provider.JCEMac$OldSHA384"); + this.put("Mac.OLDHMACSHA512", "org.bouncycastle.jce.provider.JCEMac$OldSHA512"); + this.put("Mac.PBEWITHHMACSHA", "org.bouncycastle.jce.provider.JCEMac$PBEWithSHA"); + this.put("Mac.PBEWITHHMACSHA1", "org.bouncycastle.jce.provider.JCEMac$PBEWithSHA"); + this.put("Mac.PBEWITHHMACRIPEMD160", "org.bouncycastle.jce.provider.JCEMac$PBEWithRIPEMD160"); + this.put("Alg.Alias.Mac.1.3.14.3.2.26", "PBEWITHHMACSHA"); + } + + static void doSetup(BouncyCastleProvider par0BouncyCastleProvider) { + par0BouncyCastleProvider.setup(); + } +} diff --git a/sp-server/src/main/java/org/bouncycastle/jce/provider/BouncyCastleProviderAction.java b/sp-server/src/main/java/org/bouncycastle/jce/provider/BouncyCastleProviderAction.java new file mode 100644 index 0000000..bf31892 --- /dev/null +++ b/sp-server/src/main/java/org/bouncycastle/jce/provider/BouncyCastleProviderAction.java @@ -0,0 +1,16 @@ +package org.bouncycastle.jce.provider; + +import java.security.PrivilegedAction; + +class BouncyCastleProviderAction implements PrivilegedAction { + final BouncyCastleProvider theBouncyCastleProvider; + + BouncyCastleProviderAction(BouncyCastleProvider par1BouncyCastleProvider) { + this.theBouncyCastleProvider = par1BouncyCastleProvider; + } + + public Object run() { + BouncyCastleProvider.doSetup(this.theBouncyCastleProvider); + return null; + } +} diff --git a/sp-server/src/main/java/org/bouncycastle/jce/provider/BouncyCastleProviderConfiguration.java b/sp-server/src/main/java/org/bouncycastle/jce/provider/BouncyCastleProviderConfiguration.java new file mode 100644 index 0000000..75c3af3 --- /dev/null +++ b/sp-server/src/main/java/org/bouncycastle/jce/provider/BouncyCastleProviderConfiguration.java @@ -0,0 +1,18 @@ +package org.bouncycastle.jce.provider; + +import java.security.Permission; +import org.bouncycastle.jcajce.provider.config.ProviderConfiguration; +import org.bouncycastle.jcajce.provider.config.ProviderConfigurationPermission; + +class BouncyCastleProviderConfiguration implements ProviderConfiguration { + private static Permission BC_EC_LOCAL_PERMISSION = new ProviderConfigurationPermission( + BouncyCastleProvider.PROVIDER_NAME, "threadLocalEcImplicitlyCa"); + private static Permission BC_EC_PERMISSION = new ProviderConfigurationPermission(BouncyCastleProvider.PROVIDER_NAME, + "ecImplicitlyCa"); + private static Permission BC_DH_LOCAL_PERMISSION = new ProviderConfigurationPermission( + BouncyCastleProvider.PROVIDER_NAME, "threadLocalDhDefaultParams"); + private static Permission BC_DH_PERMISSION = new ProviderConfigurationPermission(BouncyCastleProvider.PROVIDER_NAME, + "DhDefaultParams"); + private ThreadLocal ecThreadSpec = new ThreadLocal(); + private ThreadLocal dhThreadSpec = new ThreadLocal(); +} diff --git a/sp-server/src/main/java/org/bouncycastle/util/Strings.java b/sp-server/src/main/java/org/bouncycastle/util/Strings.java new file mode 100644 index 0000000..f7b89e4 --- /dev/null +++ b/sp-server/src/main/java/org/bouncycastle/util/Strings.java @@ -0,0 +1,27 @@ +package org.bouncycastle.util; + +public final class Strings { + /** + * A locale independent version of toLowerCase that returns a US ASCII lowercase + * String. + */ + public static String toLowerCase(String par0Str) { + boolean var1 = false; + char[] var2 = par0Str.toCharArray(); + + for (int var3 = 0; var3 != var2.length; ++var3) { + char var4 = var2[var3]; + + if (65 <= var4 && 90 >= var4) { + var1 = true; + var2[var3] = (char) (var4 - 65 + 97); + } + } + + if (var1) { + return new String(var2); + } else { + return par0Str; + } + } +}