mirror of
https://github.com/GTNewHorizons/CodeChickenCore.git
synced 2026-10-26 22:33:58 +00:00
Merge pull request #7 from GTNewHorizons/buildscript
Update buildscript & apply spotless
This commit is contained in:
114 files changed
+4080
-4539
No files matched your search
@@ -0,0 +1,44 @@
|
||||
* text eol=lf
|
||||
|
||||
*.[jJ][aA][rR] binary
|
||||
|
||||
*.[pP][nN][gG] binary
|
||||
*.[jJ][pP][gG] binary
|
||||
*.[jJ][pP][eE][gG] binary
|
||||
*.[gG][iI][fF] binary
|
||||
*.[tT][iI][fF] binary
|
||||
*.[tT][iI][fF][fF] binary
|
||||
*.[iI][cC][oO] binary
|
||||
*.[sS][vV][gG] text
|
||||
*.[eE][pP][sS] binary
|
||||
*.[xX][cC][fF] binary
|
||||
|
||||
*.[kK][aA][rR] binary
|
||||
*.[mM]4[aA] binary
|
||||
*.[mM][iI][dD] binary
|
||||
*.[mM][iI][dD][iI] binary
|
||||
*.[mM][pP]3 binary
|
||||
*.[oO][gG][gG] binary
|
||||
*.[rR][aA] binary
|
||||
|
||||
*.7[zZ] binary
|
||||
*.[gG][zZ] binary
|
||||
*.[tT][aA][rR] binary
|
||||
*.[tT][gG][zZ] binary
|
||||
*.[zZ][iI][pP] binary
|
||||
|
||||
*.[tT][cC][nN] binary
|
||||
*.[sS][oO] binary
|
||||
*.[dD][lL][lL] binary
|
||||
*.[dD][yY][lL][iI][bB] binary
|
||||
*.[pP][sS][dD] binary
|
||||
*.[tT][tT][fF] binary
|
||||
*.[oO][tT][fF] binary
|
||||
|
||||
*.[pP][aA][tT][cC][hH] -text
|
||||
|
||||
*.[bB][aA][tT] text eol=crlf
|
||||
*.[cC][mM][dD] text eol=crlf
|
||||
*.[pP][sS]1 text eol=crlf
|
||||
|
||||
*[aA][uU][tT][oO][gG][eE][nN][eE][rR][aA][tT][eE][dD]* binary
|
||||
+608
-187
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,10 @@
|
||||
plugins {
|
||||
id 'com.diffplug.blowdryerSetup' version '1.6.0'
|
||||
}
|
||||
|
||||
apply plugin: 'com.diffplug.blowdryerSetup'
|
||||
|
||||
blowdryerSetup {
|
||||
github('GTNewHorizons/ExampleMod1.7.10', 'tag', '0.1.5')
|
||||
//devLocal '.' // Use this when testing config updates locally
|
||||
}
|
||||
@@ -1,20 +1,18 @@
|
||||
package codechicken.lib.asm;
|
||||
|
||||
import static org.objectweb.asm.tree.AbstractInsnNode.*;
|
||||
|
||||
import com.google.common.collect.BiMap;
|
||||
import com.google.common.collect.HashBiMap;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
import org.objectweb.asm.tree.AbstractInsnNode;
|
||||
import org.objectweb.asm.tree.InsnList;
|
||||
import org.objectweb.asm.tree.JumpInsnNode;
|
||||
import org.objectweb.asm.tree.LabelNode;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import static org.objectweb.asm.tree.AbstractInsnNode.*;
|
||||
|
||||
public class ASMBlock
|
||||
{
|
||||
public class ASMBlock {
|
||||
public InsnListSection list;
|
||||
private BiMap<String, LabelNode> labels;
|
||||
|
||||
@@ -37,8 +35,7 @@ public class ASMBlock
|
||||
|
||||
public LabelNode getOrAdd(String s) {
|
||||
LabelNode l = get(s);
|
||||
if (l == null)
|
||||
labels.put(s, l = new LabelNode());
|
||||
if (l == null) labels.put(s, l = new LabelNode());
|
||||
return l;
|
||||
}
|
||||
|
||||
@@ -51,8 +48,8 @@ public class ASMBlock
|
||||
switch (insn.getType()) {
|
||||
case LABEL:
|
||||
AbstractInsnNode insn2 = insn.clone(labelMap);
|
||||
if (insn2 == insn)//identity mapping
|
||||
continue;
|
||||
if (insn2 == insn) // identity mapping
|
||||
continue;
|
||||
if (usedLabels.contains(insn2))
|
||||
throw new IllegalStateException("LabelNode cannot be a part of two InsnLists");
|
||||
list.replace(insn, insn2);
|
||||
@@ -64,10 +61,9 @@ public class ASMBlock
|
||||
list.replace(insn, insn.clone(labelMap));
|
||||
}
|
||||
|
||||
for(Entry<LabelNode, LabelNode> entry : labelMap.entrySet()) {
|
||||
for (Entry<LabelNode, LabelNode> entry : labelMap.entrySet()) {
|
||||
String key = labels.inverse().get(entry.getKey());
|
||||
if(key != null)
|
||||
labels.put(key, entry.getValue());
|
||||
if (key != null) labels.put(key, entry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,8 +73,7 @@ public class ASMBlock
|
||||
|
||||
public void replaceLabel(String s, LabelNode l) {
|
||||
LabelNode old = get(s);
|
||||
if (old != null)
|
||||
replaceLabels(ImmutableMap.of(old, l));
|
||||
if (old != null) replaceLabels(ImmutableMap.of(old, l));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -86,20 +81,17 @@ public class ASMBlock
|
||||
* @return this
|
||||
*/
|
||||
public ASMBlock mergeLabels(ASMBlock other) {
|
||||
if(labels.isEmpty() || other.labels.isEmpty())
|
||||
return this;
|
||||
if (labels.isEmpty() || other.labels.isEmpty()) return this;
|
||||
|
||||
//common labels, give them our nodes
|
||||
// common labels, give them our nodes
|
||||
HashMap<LabelNode, LabelNode> labelMap = list.identityLabelMap();
|
||||
for(Entry<String, LabelNode> entry : other.labels.entrySet()) {
|
||||
for (Entry<String, LabelNode> entry : other.labels.entrySet()) {
|
||||
LabelNode old = labels.get(entry.getKey());
|
||||
if(old != null)
|
||||
labelMap.put(old, entry.getValue());
|
||||
if (old != null) labelMap.put(old, entry.getValue());
|
||||
}
|
||||
HashSet<LabelNode> usedLabels = new HashSet<LabelNode>();
|
||||
for (AbstractInsnNode insn = other.list.list.getFirst(); insn != null; insn = insn.getNext())
|
||||
if(insn.getType() == LABEL)
|
||||
usedLabels.add((LabelNode) insn);
|
||||
if (insn.getType() == LABEL) usedLabels.add((LabelNode) insn);
|
||||
|
||||
replaceLabels(labelMap, usedLabels);
|
||||
return this;
|
||||
@@ -118,15 +110,14 @@ public class ASMBlock
|
||||
BiMap<String, LabelNode> labels = HashBiMap.create();
|
||||
Map<LabelNode, LabelNode> labelMap = list.cloneLabels();
|
||||
|
||||
for(Entry<String, LabelNode> entry : this.labels.entrySet())
|
||||
for (Entry<String, LabelNode> entry : this.labels.entrySet())
|
||||
labels.put(entry.getKey(), labelMap.get(entry.getValue()));
|
||||
|
||||
return new ASMBlock(list.copy(labelMap), labels);
|
||||
}
|
||||
|
||||
public ASMBlock applyLabels(InsnListSection list2) {
|
||||
if(labels.isEmpty())
|
||||
return new ASMBlock(list2);
|
||||
if (labels.isEmpty()) return new ASMBlock(list2);
|
||||
|
||||
Set<LabelNode> cFlowLabels1 = labels.values();
|
||||
Set<LabelNode> cFlowLabels2 = InsnComparator.getControlFlowLabels(list2);
|
||||
@@ -134,23 +125,23 @@ public class ASMBlock
|
||||
|
||||
HashMap<LabelNode, LabelNode> labelMap = new HashMap<LabelNode, LabelNode>();
|
||||
|
||||
for(int i = 0, k = 0; i < list.size() && k < list2.size(); ) {
|
||||
for (int i = 0, k = 0; i < list.size() && k < list2.size(); ) {
|
||||
AbstractInsnNode insn1 = list.get(i);
|
||||
if(!InsnComparator.insnImportant(insn1, cFlowLabels1)) {
|
||||
if (!InsnComparator.insnImportant(insn1, cFlowLabels1)) {
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
|
||||
AbstractInsnNode insn2 = list2.get(k);
|
||||
if(!InsnComparator.insnImportant(insn2, cFlowLabels2)) {
|
||||
if (!InsnComparator.insnImportant(insn2, cFlowLabels2)) {
|
||||
k++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(insn1.getOpcode() != insn2.getOpcode())
|
||||
throw new IllegalArgumentException("Lists do not match:\n"+list+"\n\n"+list2);
|
||||
if (insn1.getOpcode() != insn2.getOpcode())
|
||||
throw new IllegalArgumentException("Lists do not match:\n" + list + "\n\n" + list2);
|
||||
|
||||
switch(insn1.getType()) {
|
||||
switch (insn1.getType()) {
|
||||
case LABEL:
|
||||
labelMap.put((LabelNode) insn1, (LabelNode) insn2);
|
||||
break;
|
||||
@@ -158,10 +149,11 @@ public class ASMBlock
|
||||
labelMap.put(((JumpInsnNode) insn1).label, ((JumpInsnNode) insn2).label);
|
||||
break;
|
||||
}
|
||||
i++; k++;
|
||||
i++;
|
||||
k++;
|
||||
}
|
||||
|
||||
for(Entry<String, LabelNode> entry : labels.entrySet())
|
||||
for (Entry<String, LabelNode> entry : labels.entrySet())
|
||||
block.labels.put(entry.getKey(), labelMap.get(entry.getValue()));
|
||||
|
||||
return block;
|
||||
@@ -170,4 +162,4 @@ public class ASMBlock
|
||||
public InsnList rawListCopy() {
|
||||
return list.copy().list;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,13 @@ package codechicken.lib.asm;
|
||||
|
||||
import codechicken.lib.config.ConfigFile;
|
||||
import codechicken.lib.config.DefaultingConfigFile;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.objectweb.asm.ClassReader;
|
||||
@@ -12,48 +19,35 @@ import org.objectweb.asm.util.ASMifier;
|
||||
import org.objectweb.asm.util.Textifier;
|
||||
import org.objectweb.asm.util.TraceClassVisitor;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class ASMHelper
|
||||
{
|
||||
public class ASMHelper {
|
||||
public static ConfigFile config = loadConfig();
|
||||
public static Logger logger = LogManager.getLogger("CCL ASM");
|
||||
|
||||
private static ConfigFile loadConfig() {
|
||||
try {//weak reference for environments without FML
|
||||
File mcDir = (File)((Object[])Class.forName("cpw.mods.fml.relauncher.FMLInjectionData").getMethod("data").invoke(null))[6];
|
||||
try { // weak reference for environments without FML
|
||||
File mcDir = (File) ((Object[]) Class.forName("cpw.mods.fml.relauncher.FMLInjectionData")
|
||||
.getMethod("data")
|
||||
.invoke(null))
|
||||
[6];
|
||||
File file = new File(mcDir, "config/CodeChickenLib.cfg");
|
||||
if(ObfMapping.obfuscated)
|
||||
return new DefaultingConfigFile(file);
|
||||
else
|
||||
return new ConfigFile(file).setComment("CodeChickenLib development configuration file.");
|
||||
if (ObfMapping.obfuscated) return new DefaultingConfigFile(file);
|
||||
else return new ConfigFile(file).setComment("CodeChickenLib development configuration file.");
|
||||
} catch (Exception ignored) {
|
||||
return null;//no config for these systems
|
||||
return null; // no config for these systems
|
||||
}
|
||||
}
|
||||
|
||||
public static interface Acceptor
|
||||
{
|
||||
public static interface Acceptor {
|
||||
public void accept(ClassVisitor cv) throws IOException;
|
||||
}
|
||||
|
||||
public static MethodNode findMethod(ObfMapping methodmap, ClassNode cnode) {
|
||||
for (MethodNode mnode : cnode.methods)
|
||||
if (methodmap.matches(mnode))
|
||||
return mnode;
|
||||
for (MethodNode mnode : cnode.methods) if (methodmap.matches(mnode)) return mnode;
|
||||
return null;
|
||||
}
|
||||
|
||||
public static FieldNode findField(ObfMapping fieldmap, ClassNode cnode) {
|
||||
for (FieldNode fnode : cnode.fields)
|
||||
if (fieldmap.matches(fnode))
|
||||
return fnode;
|
||||
for (FieldNode fnode : cnode.fields) if (fieldmap.matches(fnode)) return fnode;
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -86,23 +80,24 @@ public class ASMHelper
|
||||
return new InsnListSection(list).copy(labelMap).list;
|
||||
}
|
||||
|
||||
public static List<TryCatchBlockNode> cloneTryCatchBlocks(Map<LabelNode, LabelNode> labelMap, List<TryCatchBlockNode> tcblocks) {
|
||||
public static List<TryCatchBlockNode> cloneTryCatchBlocks(
|
||||
Map<LabelNode, LabelNode> labelMap, List<TryCatchBlockNode> tcblocks) {
|
||||
ArrayList<TryCatchBlockNode> clone = new ArrayList<TryCatchBlockNode>();
|
||||
for (TryCatchBlockNode node : tcblocks)
|
||||
clone.add(new TryCatchBlockNode(
|
||||
labelMap.get(node.start),
|
||||
labelMap.get(node.end),
|
||||
labelMap.get(node.handler),
|
||||
node.type));
|
||||
labelMap.get(node.start), labelMap.get(node.end), labelMap.get(node.handler), node.type));
|
||||
|
||||
return clone;
|
||||
}
|
||||
|
||||
public static List<LocalVariableNode> cloneLocals(Map<LabelNode, LabelNode> labelMap, List<LocalVariableNode> locals) {
|
||||
public static List<LocalVariableNode> cloneLocals(
|
||||
Map<LabelNode, LabelNode> labelMap, List<LocalVariableNode> locals) {
|
||||
ArrayList<LocalVariableNode> clone = new ArrayList<LocalVariableNode>(locals.size());
|
||||
for (LocalVariableNode node : locals)
|
||||
clone.add(new LocalVariableNode(
|
||||
node.name, node.desc, node.signature,
|
||||
node.name,
|
||||
node.desc,
|
||||
node.signature,
|
||||
labelMap.get(node.start),
|
||||
labelMap.get(node.end),
|
||||
node.index));
|
||||
@@ -114,8 +109,7 @@ public class ASMHelper
|
||||
Map<LabelNode, LabelNode> labelMap = cloneLabels(src.instructions);
|
||||
dst.instructions = cloneInsnList(labelMap, src.instructions);
|
||||
dst.tryCatchBlocks = cloneTryCatchBlocks(labelMap, src.tryCatchBlocks);
|
||||
if (src.localVariables != null)
|
||||
dst.localVariables = cloneLocals(labelMap, src.localVariables);
|
||||
if (src.localVariables != null) dst.localVariables = cloneLocals(labelMap, src.localVariables);
|
||||
dst.visibleAnnotations = src.visibleAnnotations;
|
||||
dst.invisibleAnnotations = src.invisibleAnnotations;
|
||||
dst.visitMaxs(src.maxStack, src.maxLocals);
|
||||
@@ -130,7 +124,8 @@ public class ASMHelper
|
||||
for (LocalVariableNode node : list) {
|
||||
if (node.name.equals(name)) {
|
||||
if (found >= 0)
|
||||
throw new RuntimeException("Duplicate local variable: " + name + " not coded to handle this scenario.");
|
||||
throw new RuntimeException(
|
||||
"Duplicate local variable: " + name + " not coded to handle this scenario.");
|
||||
|
||||
found = node.index;
|
||||
}
|
||||
@@ -140,24 +135,21 @@ public class ASMHelper
|
||||
|
||||
public static void replaceMethod(MethodNode original, MethodNode replacement) {
|
||||
original.instructions.clear();
|
||||
if (original.localVariables != null)
|
||||
original.localVariables.clear();
|
||||
if (original.tryCatchBlocks != null)
|
||||
original.tryCatchBlocks.clear();
|
||||
if (original.localVariables != null) original.localVariables.clear();
|
||||
if (original.tryCatchBlocks != null) original.tryCatchBlocks.clear();
|
||||
replacement.accept(original);
|
||||
}
|
||||
|
||||
public static void dump(Acceptor acceptor, File file, boolean filterImportant, boolean sortLocals, boolean textify) {
|
||||
public static void dump(
|
||||
Acceptor acceptor, File file, boolean filterImportant, boolean sortLocals, boolean textify) {
|
||||
try {
|
||||
if(!file.getParentFile().exists())
|
||||
file.getParentFile().mkdirs();
|
||||
if(!file.exists())
|
||||
file.createNewFile();
|
||||
if (!file.getParentFile().exists()) file.getParentFile().mkdirs();
|
||||
if (!file.exists()) file.createNewFile();
|
||||
|
||||
PrintWriter pout = new PrintWriter(file);
|
||||
ClassVisitor cv = new TraceClassVisitor(null, textify ? new Textifier() : new ASMifier(), pout);
|
||||
if(filterImportant) cv = new ImportantInsnVisitor(cv);
|
||||
if(sortLocals) cv = new LocalVariablesSorterVisitor(cv);
|
||||
if (filterImportant) cv = new ImportantInsnVisitor(cv);
|
||||
if (sortLocals) cv = new LocalVariablesSorterVisitor(cv);
|
||||
acceptor.accept(cv);
|
||||
pout.close();
|
||||
} catch (IOException e) {
|
||||
@@ -166,36 +158,50 @@ public class ASMHelper
|
||||
}
|
||||
|
||||
public static void dump(Acceptor acceptor, File file, boolean filterImportant, boolean sortLocals) {
|
||||
dump(acceptor, file, filterImportant, sortLocals, config.getTag("textify").getBooleanValue(true));
|
||||
dump(
|
||||
acceptor,
|
||||
file,
|
||||
filterImportant,
|
||||
sortLocals,
|
||||
config.getTag("textify").getBooleanValue(true));
|
||||
}
|
||||
|
||||
public static void dump(final byte[] bytes, File file, boolean filterImportant, boolean sortLocals) {
|
||||
dump(new Acceptor()
|
||||
{
|
||||
@Override
|
||||
public void accept(ClassVisitor cv) {
|
||||
new ClassReader(bytes).accept(cv, ClassReader.EXPAND_FRAMES);
|
||||
}
|
||||
}, file, filterImportant, sortLocals);
|
||||
dump(
|
||||
new Acceptor() {
|
||||
@Override
|
||||
public void accept(ClassVisitor cv) {
|
||||
new ClassReader(bytes).accept(cv, ClassReader.EXPAND_FRAMES);
|
||||
}
|
||||
},
|
||||
file,
|
||||
filterImportant,
|
||||
sortLocals);
|
||||
}
|
||||
|
||||
public static void dump(final InputStream is, File file, boolean filterImportant, boolean sortLocals) {
|
||||
dump(new Acceptor()
|
||||
{
|
||||
@Override
|
||||
public void accept(ClassVisitor cv) throws IOException {
|
||||
new ClassReader(is).accept(cv, ClassReader.EXPAND_FRAMES);
|
||||
}
|
||||
}, file, filterImportant, sortLocals);
|
||||
dump(
|
||||
new Acceptor() {
|
||||
@Override
|
||||
public void accept(ClassVisitor cv) throws IOException {
|
||||
new ClassReader(is).accept(cv, ClassReader.EXPAND_FRAMES);
|
||||
}
|
||||
},
|
||||
file,
|
||||
filterImportant,
|
||||
sortLocals);
|
||||
}
|
||||
|
||||
public static void dump(final ClassNode cnode, File file, boolean filterImportant, boolean sortLocals) {
|
||||
dump(new Acceptor()
|
||||
{
|
||||
@Override
|
||||
public void accept(ClassVisitor cv) {
|
||||
cnode.accept(cv);
|
||||
}
|
||||
}, file, filterImportant, sortLocals);
|
||||
dump(
|
||||
new Acceptor() {
|
||||
@Override
|
||||
public void accept(ClassVisitor cv) {
|
||||
cnode.accept(cv);
|
||||
}
|
||||
},
|
||||
file,
|
||||
filterImportant,
|
||||
sortLocals);
|
||||
}
|
||||
}
|
||||
@@ -5,11 +5,11 @@ import net.minecraft.launchwrapper.Launch;
|
||||
/**
|
||||
* Initialisation class for using this package. Call this on coremod load
|
||||
*/
|
||||
public class ASMInit
|
||||
{
|
||||
public class ASMInit {
|
||||
private static boolean initialised = false;
|
||||
|
||||
public static void init() {
|
||||
if(!initialised) {
|
||||
if (!initialised) {
|
||||
Launch.classLoader.addTransformerExclusion("codechicken.lib.asm");
|
||||
Launch.classLoader.addTransformerExclusion("codechicken.lib.config");
|
||||
initialised = true;
|
||||
|
||||
@@ -1,18 +1,16 @@
|
||||
package codechicken.lib.asm;
|
||||
|
||||
import org.objectweb.asm.tree.*;
|
||||
import static org.objectweb.asm.Opcodes.*;
|
||||
import static org.objectweb.asm.tree.AbstractInsnNode.*;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.*;
|
||||
import org.objectweb.asm.tree.*;
|
||||
|
||||
import static org.objectweb.asm.Opcodes.*;
|
||||
import static org.objectweb.asm.tree.AbstractInsnNode.*;
|
||||
|
||||
public class ASMReader
|
||||
{
|
||||
public class ASMReader {
|
||||
public static Map<String, Integer> opCodes = new HashMap<String, Integer>();
|
||||
public static byte[] TYPE;
|
||||
|
||||
@@ -175,14 +173,13 @@ public class ASMReader
|
||||
opCodes.put("IFNULL", IFNULL);
|
||||
opCodes.put("IFNONNULL", IFNONNULL);
|
||||
|
||||
//derived from classWriter, mapped to AbstractInsnNode
|
||||
// derived from classWriter, mapped to AbstractInsnNode
|
||||
TYPE = new byte[200];
|
||||
String s = "AAAAAAAAAAAAAAAABBJ__CCCCC____________________AAAAAAAACC"
|
||||
+ "CCC____________________AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
|
||||
+ "AAAAAAAAAAAAAAAAAKAAAAAAAAAAAAAAAAAAAAHHHHHHHHHHHHHHHHCLMAA"
|
||||
+ "AAAAEEEEFFFFGDBDAADDAA_NHH";
|
||||
for (int i = 0; i < s.length(); i++)
|
||||
TYPE[i] = (byte) (s.charAt(i) - 'A');
|
||||
for (int i = 0; i < s.length(); i++) TYPE[i] = (byte) (s.charAt(i) - 'A');
|
||||
}
|
||||
|
||||
public static Map<String, ASMBlock> loadResource(String res) {
|
||||
@@ -217,10 +214,8 @@ public class ASMReader
|
||||
if (i_opcode == null) {
|
||||
if (split[0].equals("LINENUMBER"))
|
||||
insn = new LineNumberNode(Integer.parseInt(split[1]), block.getOrAdd(split[2]));
|
||||
else if (split[0].startsWith("L"))
|
||||
insn = block.getOrAdd(split[0]);
|
||||
else
|
||||
throw new Exception("Unknown opcode " + split[0]);
|
||||
else if (split[0].startsWith("L")) insn = block.getOrAdd(split[0]);
|
||||
else throw new Exception("Unknown opcode " + split[0]);
|
||||
} else {
|
||||
int opcode = i_opcode;
|
||||
switch (TYPE[opcode]) {
|
||||
@@ -239,9 +234,10 @@ public class ASMReader
|
||||
case FIELD_INSN:
|
||||
case METHOD_INSN:
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 1; i < split.length; i++)
|
||||
sb.append(split[i]);
|
||||
insn = ObfMapping.fromDesc(sb.toString()).toClassloading().toInsn(opcode);
|
||||
for (int i = 1; i < split.length; i++) sb.append(split[i]);
|
||||
insn = ObfMapping.fromDesc(sb.toString())
|
||||
.toClassloading()
|
||||
.toInsn(opcode);
|
||||
break;
|
||||
case INVOKE_DYNAMIC_INSN:
|
||||
throw new Exception("Found INVOKEDYNAMIC while reading");
|
||||
@@ -250,20 +246,16 @@ public class ASMReader
|
||||
break;
|
||||
case LDC_INSN:
|
||||
String cst = split[1];
|
||||
if(cst.equals("*"))
|
||||
insn = new LdcInsnNode(null);
|
||||
else if (cst.endsWith("\""))
|
||||
insn = new LdcInsnNode(cst.substring(1, cst.length() - 1));
|
||||
if (cst.equals("*")) insn = new LdcInsnNode(null);
|
||||
else if (cst.endsWith("\"")) insn = new LdcInsnNode(cst.substring(1, cst.length() - 1));
|
||||
else if (cst.endsWith("L"))
|
||||
insn = new LdcInsnNode(Long.valueOf(cst.substring(0, cst.length() - 1)));
|
||||
else if (cst.endsWith("F"))
|
||||
insn = new LdcInsnNode(Float.valueOf(cst.substring(0, cst.length() - 1)));
|
||||
else if (cst.endsWith("D"))
|
||||
insn = new LdcInsnNode(Double.valueOf(cst.substring(0, cst.length() - 1)));
|
||||
else if (cst.contains("."))
|
||||
insn = new LdcInsnNode(Double.valueOf(cst));
|
||||
else
|
||||
insn = new LdcInsnNode(Integer.valueOf(cst));
|
||||
else if (cst.contains(".")) insn = new LdcInsnNode(Double.valueOf(cst));
|
||||
else insn = new LdcInsnNode(Integer.valueOf(cst));
|
||||
break;
|
||||
case IINC_INSN:
|
||||
insn = new IincInsnNode(opcode, Integer.parseInt(split[1]));
|
||||
@@ -281,11 +273,9 @@ public class ASMReader
|
||||
}
|
||||
}
|
||||
|
||||
if (insn != null)
|
||||
block.list.add(insn);
|
||||
if (insn != null) block.list.add(insn);
|
||||
} catch (Exception e) {
|
||||
System.err.println("Error while reading ASM Block " +
|
||||
current + " from " + res + ", line: " + line);
|
||||
System.err.println("Error while reading ASM Block " + current + " from " + res + ", line: " + line);
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,36 +2,27 @@ package codechicken.lib.asm;
|
||||
|
||||
import org.objectweb.asm.ClassWriter;
|
||||
|
||||
|
||||
public class CC_ClassWriter extends ClassWriter
|
||||
{
|
||||
public class CC_ClassWriter extends ClassWriter {
|
||||
private final boolean runtime;
|
||||
|
||||
public CC_ClassWriter(int flags)
|
||||
{
|
||||
|
||||
public CC_ClassWriter(int flags) {
|
||||
this(flags, false);
|
||||
}
|
||||
|
||||
public CC_ClassWriter(int flags, boolean runtime)
|
||||
{
|
||||
|
||||
public CC_ClassWriter(int flags, boolean runtime) {
|
||||
super(flags);
|
||||
this.runtime = runtime;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected String getCommonSuperClass(String type1, String type2)
|
||||
{
|
||||
protected String getCommonSuperClass(String type1, String type2) {
|
||||
String c = type1.replace('/', '.');
|
||||
String d = type2.replace('/', '.');
|
||||
if(ClassHeirachyManager.classExtends(d, c))
|
||||
return type1;
|
||||
if(ClassHeirachyManager.classExtends(c, d))
|
||||
return type2;
|
||||
do
|
||||
{
|
||||
if (ClassHeirachyManager.classExtends(d, c)) return type1;
|
||||
if (ClassHeirachyManager.classExtends(c, d)) return type2;
|
||||
do {
|
||||
c = ClassHeirachyManager.getSuperClass(c, runtime);
|
||||
}
|
||||
while(!ClassHeirachyManager.classExtends(d, c));
|
||||
} while (!ClassHeirachyManager.classExtends(d, c));
|
||||
return c.replace('.', '/');
|
||||
}
|
||||
}
|
||||
@@ -1,26 +1,23 @@
|
||||
package codechicken.lib.asm;
|
||||
|
||||
import cpw.mods.fml.common.asm.transformers.deobf.FMLDeobfuscatingRemapper;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import net.minecraft.launchwrapper.IClassTransformer;
|
||||
import net.minecraft.launchwrapper.Launch;
|
||||
import net.minecraft.launchwrapper.LaunchClassLoader;
|
||||
import org.objectweb.asm.tree.ClassNode;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
|
||||
/**
|
||||
* This is added as a class transformer if CodeChickenCore is installed. Adding it as a class transformer will speed evaluation up slightly by automatically caching superclasses when they are first loaded.
|
||||
*/
|
||||
public class ClassHeirachyManager implements IClassTransformer
|
||||
{
|
||||
public class ClassHeirachyManager implements IClassTransformer {
|
||||
static {
|
||||
ASMInit.init();
|
||||
}
|
||||
|
||||
public static class SuperCache
|
||||
{
|
||||
public static class SuperCache {
|
||||
String superclass;
|
||||
public HashSet<String> parents = new HashSet<String>();
|
||||
private boolean flattened;
|
||||
@@ -30,8 +27,7 @@ public class ClassHeirachyManager implements IClassTransformer
|
||||
}
|
||||
|
||||
public void flatten() {
|
||||
if (flattened)
|
||||
return;
|
||||
if (flattened) return;
|
||||
|
||||
for (String s : new ArrayList<String>(parents)) {
|
||||
SuperCache c = declareClass(s);
|
||||
@@ -55,7 +51,9 @@ public class ClassHeirachyManager implements IClassTransformer
|
||||
|
||||
public static String unKey(String name) {
|
||||
if (ObfMapping.obfuscated)
|
||||
name = FMLDeobfuscatingRemapper.INSTANCE.unmap(name.replace('.', '/')).replace('/', '.');
|
||||
name = FMLDeobfuscatingRemapper.INSTANCE
|
||||
.unmap(name.replace('.', '/'))
|
||||
.replace('/', '.');
|
||||
return name;
|
||||
}
|
||||
|
||||
@@ -68,12 +66,11 @@ public class ClassHeirachyManager implements IClassTransformer
|
||||
name = toKey(name);
|
||||
superclass = toKey(superclass);
|
||||
|
||||
if (name.equals(superclass))
|
||||
return true;
|
||||
if (name.equals(superclass)) return true;
|
||||
|
||||
SuperCache cache = declareClass(name);
|
||||
if (cache == null)//just can't handle this
|
||||
return false;
|
||||
if (cache == null) // just can't handle this
|
||||
return false;
|
||||
|
||||
cache.flatten();
|
||||
return cache.parents.contains(superclass);
|
||||
@@ -83,19 +80,15 @@ public class ClassHeirachyManager implements IClassTransformer
|
||||
name = toKey(name);
|
||||
SuperCache cache = superclasses.get(name);
|
||||
|
||||
if (cache != null)
|
||||
return cache;
|
||||
if (cache != null) return cache;
|
||||
|
||||
try {
|
||||
byte[] bytes = cl.getClassBytes(unKey(name));
|
||||
if (bytes != null)
|
||||
cache = declareASM(bytes);
|
||||
if (bytes != null) cache = declareASM(bytes);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
|
||||
if (cache != null)
|
||||
return cache;
|
||||
|
||||
if (cache != null) return cache;
|
||||
|
||||
try {
|
||||
cache = declareReflection(name);
|
||||
@@ -109,16 +102,12 @@ public class ClassHeirachyManager implements IClassTransformer
|
||||
Class<?> aclass = Class.forName(name);
|
||||
|
||||
SuperCache cache = getOrCreateCache(name);
|
||||
if (aclass.isInterface())
|
||||
cache.superclass = "java.lang.Object";
|
||||
else if (name.equals("java.lang.Object"))
|
||||
return cache;
|
||||
else
|
||||
cache.superclass = toKey(aclass.getSuperclass().getName());
|
||||
if (aclass.isInterface()) cache.superclass = "java.lang.Object";
|
||||
else if (name.equals("java.lang.Object")) return cache;
|
||||
else cache.superclass = toKey(aclass.getSuperclass().getName());
|
||||
|
||||
cache.add(cache.superclass);
|
||||
for (Class<?> iclass : aclass.getInterfaces())
|
||||
cache.add(toKey(iclass.getName()));
|
||||
for (Class<?> iclass : aclass.getInterfaces()) cache.add(toKey(iclass.getName()));
|
||||
|
||||
return cache;
|
||||
}
|
||||
@@ -130,40 +119,34 @@ public class ClassHeirachyManager implements IClassTransformer
|
||||
SuperCache cache = getOrCreateCache(name);
|
||||
cache.superclass = toKey(node.superName.replace('/', '.'));
|
||||
cache.add(cache.superclass);
|
||||
for (String iclass : node.interfaces)
|
||||
cache.add(toKey(iclass.replace('/', '.')));
|
||||
for (String iclass : node.interfaces) cache.add(toKey(iclass.replace('/', '.')));
|
||||
|
||||
return cache;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] transform(String name, String tname, byte[] bytes) {
|
||||
if (bytes == null)
|
||||
return null;
|
||||
if (bytes == null) return null;
|
||||
|
||||
if (!superclasses.containsKey(tname))
|
||||
declareASM(bytes);
|
||||
if (!superclasses.containsKey(tname)) declareASM(bytes);
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
public static SuperCache getOrCreateCache(String name) {
|
||||
SuperCache cache = superclasses.get(name);
|
||||
if (cache == null)
|
||||
superclasses.put(name, cache = new SuperCache());
|
||||
if (cache == null) superclasses.put(name, cache = new SuperCache());
|
||||
return cache;
|
||||
}
|
||||
|
||||
public static String getSuperClass(String name, boolean runtime) {
|
||||
name = toKey(name);
|
||||
SuperCache cache = declareClass(name);
|
||||
if (cache == null)
|
||||
return "java.lang.Object";
|
||||
if (cache == null) return "java.lang.Object";
|
||||
|
||||
cache.flatten();
|
||||
String s = cache.superclass;
|
||||
if (!runtime)
|
||||
s = FMLDeobfuscatingRemapper.INSTANCE.unmap(s);
|
||||
if (!runtime) s = FMLDeobfuscatingRemapper.INSTANCE.unmap(s);
|
||||
return s;
|
||||
}
|
||||
}
|
||||
@@ -5,10 +5,8 @@ import org.objectweb.asm.MethodVisitor;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
import org.objectweb.asm.tree.MethodNode;
|
||||
|
||||
public class ImportantInsnVisitor extends ClassVisitor
|
||||
{
|
||||
public class ImportantInsnMethodVisitor extends MethodVisitor
|
||||
{
|
||||
public class ImportantInsnVisitor extends ClassVisitor {
|
||||
public class ImportantInsnMethodVisitor extends MethodVisitor {
|
||||
MethodVisitor delegate;
|
||||
|
||||
public ImportantInsnMethodVisitor(int access, String name, String desc, String signature, String[] exceptions) {
|
||||
@@ -19,7 +17,7 @@ public class ImportantInsnVisitor extends ClassVisitor
|
||||
@Override
|
||||
public void visitEnd() {
|
||||
super.visitEnd();
|
||||
MethodNode mnode = (MethodNode)mv;
|
||||
MethodNode mnode = (MethodNode) mv;
|
||||
mnode.instructions = InsnComparator.getImportantList(mnode.instructions);
|
||||
mnode.accept(delegate);
|
||||
}
|
||||
|
||||
@@ -1,15 +1,13 @@
|
||||
package codechicken.lib.asm;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.Maps;
|
||||
import org.objectweb.asm.tree.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static org.objectweb.asm.tree.AbstractInsnNode.*;
|
||||
|
||||
public class InsnComparator
|
||||
{
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.Maps;
|
||||
import java.util.*;
|
||||
import org.objectweb.asm.tree.*;
|
||||
|
||||
public class InsnComparator {
|
||||
public static boolean varInsnEqual(VarInsnNode insn1, VarInsnNode insn2) {
|
||||
return insn1.var == -1 || insn2.var == -1 || insn1.var == insn2.var;
|
||||
}
|
||||
@@ -39,8 +37,7 @@ public class InsnComparator
|
||||
}
|
||||
|
||||
public static boolean insnEqual(AbstractInsnNode node1, AbstractInsnNode node2) {
|
||||
if (node1.getOpcode() != node2.getOpcode())
|
||||
return false;
|
||||
if (node1.getOpcode() != node2.getOpcode()) return false;
|
||||
|
||||
switch (node2.getType()) {
|
||||
case VAR_INSN:
|
||||
@@ -63,7 +60,7 @@ public class InsnComparator
|
||||
}
|
||||
|
||||
public static boolean insnImportant(AbstractInsnNode insn, Set<LabelNode> controlFlowLabels) {
|
||||
switch(insn.getType()) {
|
||||
switch (insn.getType()) {
|
||||
case LINE:
|
||||
case FRAME:
|
||||
return false;
|
||||
@@ -89,14 +86,12 @@ public class InsnComparator
|
||||
case TABLESWITCH_INSN:
|
||||
TableSwitchInsnNode tsinsn = (TableSwitchInsnNode) insn;
|
||||
controlFlowLabels.add(tsinsn.dflt);
|
||||
for (LabelNode label : tsinsn.labels)
|
||||
controlFlowLabels.add(label);
|
||||
for (LabelNode label : tsinsn.labels) controlFlowLabels.add(label);
|
||||
break;
|
||||
case LOOKUPSWITCH_INSN:
|
||||
LookupSwitchInsnNode lsinsn = (LookupSwitchInsnNode) insn;
|
||||
controlFlowLabels.add(lsinsn.dflt);
|
||||
for (LabelNode label : lsinsn.labels)
|
||||
controlFlowLabels.add(label);
|
||||
for (LabelNode label : lsinsn.labels) controlFlowLabels.add(label);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -108,12 +103,10 @@ public class InsnComparator
|
||||
}
|
||||
|
||||
public static InsnListSection getImportantList(InsnListSection list) {
|
||||
if (list.size() == 0)
|
||||
return list;
|
||||
if (list.size() == 0) return list;
|
||||
|
||||
Set<LabelNode> controlFlowLabels = getControlFlowLabels(list);
|
||||
Map<LabelNode, LabelNode> labelMap = Maps.asMap(controlFlowLabels, new Function<LabelNode, LabelNode>()
|
||||
{
|
||||
Map<LabelNode, LabelNode> labelMap = Maps.asMap(controlFlowLabels, new Function<LabelNode, LabelNode>() {
|
||||
@Override
|
||||
public LabelNode apply(LabelNode input) {
|
||||
return input;
|
||||
@@ -121,9 +114,8 @@ public class InsnComparator
|
||||
});
|
||||
|
||||
InsnListSection importantNodeList = new InsnListSection();
|
||||
for(AbstractInsnNode insn : list)
|
||||
if (insnImportant(insn, controlFlowLabels))
|
||||
importantNodeList.add(insn.clone(labelMap));
|
||||
for (AbstractInsnNode insn : list)
|
||||
if (insnImportant(insn, controlFlowLabels)) importantNodeList.add(insn.clone(labelMap));
|
||||
|
||||
return importantNodeList;
|
||||
}
|
||||
@@ -135,7 +127,7 @@ public class InsnComparator
|
||||
InsnListSection section = matches(haystack.drop(start), needle, controlFlowLabels);
|
||||
if (section != null) {
|
||||
list.add(section);
|
||||
start = section.end-1;
|
||||
start = section.end - 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -146,27 +138,26 @@ public class InsnComparator
|
||||
return find(new InsnListSection(haystack), needle);
|
||||
}
|
||||
|
||||
public static InsnListSection matches(InsnListSection haystack, InsnListSection needle, Set<LabelNode> controlFlowLabels) {
|
||||
public static InsnListSection matches(
|
||||
InsnListSection haystack, InsnListSection needle, Set<LabelNode> controlFlowLabels) {
|
||||
int h = 0, n = 0;
|
||||
for (; h < haystack.size() && n < needle.size(); h++) {
|
||||
AbstractInsnNode insn = haystack.get(h);
|
||||
if(!insnImportant(insn, controlFlowLabels))
|
||||
continue;
|
||||
if (!insnImportant(insn, controlFlowLabels)) continue;
|
||||
|
||||
if (!insnEqual(haystack.get(h), needle.get(n)))
|
||||
return null;
|
||||
if (!insnEqual(haystack.get(h), needle.get(n))) return null;
|
||||
n++;
|
||||
}
|
||||
if (n != needle.size())
|
||||
return null;
|
||||
if (n != needle.size()) return null;
|
||||
|
||||
return haystack.take(h);
|
||||
}
|
||||
|
||||
public static InsnListSection findOnce(InsnListSection haystack, InsnListSection needle) {
|
||||
List<InsnListSection> list = find(haystack, needle);
|
||||
if(list.size() != 1)
|
||||
throw new RuntimeException("Needle found " + list.size() + " times in Haystack:\n" + haystack + "\n\n" + needle);
|
||||
if (list.size() != 1)
|
||||
throw new RuntimeException(
|
||||
"Needle found " + list.size() + " times in Haystack:\n" + haystack + "\n\n" + needle);
|
||||
|
||||
return list.get(0);
|
||||
}
|
||||
@@ -177,8 +168,7 @@ public class InsnComparator
|
||||
|
||||
public static List<InsnListSection> findN(InsnListSection haystack, InsnListSection needle) {
|
||||
List<InsnListSection> list = find(haystack, needle);
|
||||
if(list.isEmpty())
|
||||
throw new RuntimeException("Needle not found in Haystack:\n" + haystack + "\n\n" + needle);
|
||||
if (list.isEmpty()) throw new RuntimeException("Needle not found in Haystack:\n" + haystack + "\n\n" + needle);
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
package codechicken.lib.asm;
|
||||
|
||||
import org.objectweb.asm.MethodVisitor;
|
||||
import org.objectweb.asm.tree.*;
|
||||
import org.objectweb.asm.util.Textifier;
|
||||
import org.objectweb.asm.util.TraceMethodVisitor;
|
||||
import static org.objectweb.asm.tree.AbstractInsnNode.*;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
@@ -12,16 +9,16 @@ import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.objectweb.asm.tree.AbstractInsnNode.*;
|
||||
import org.objectweb.asm.MethodVisitor;
|
||||
import org.objectweb.asm.tree.*;
|
||||
import org.objectweb.asm.util.Textifier;
|
||||
import org.objectweb.asm.util.TraceMethodVisitor;
|
||||
|
||||
/**
|
||||
* A section of an InsnList, may become invalid if the insn list is modified
|
||||
*/
|
||||
public class InsnListSection implements Iterable<AbstractInsnNode>
|
||||
{
|
||||
private class InsnListSectionIterator implements Iterator<AbstractInsnNode>
|
||||
{
|
||||
public class InsnListSection implements Iterable<AbstractInsnNode> {
|
||||
private class InsnListSectionIterator implements Iterator<AbstractInsnNode> {
|
||||
int i = 0;
|
||||
|
||||
@Override
|
||||
@@ -51,7 +48,7 @@ public class InsnListSection implements Iterable<AbstractInsnNode>
|
||||
}
|
||||
|
||||
public InsnListSection(InsnList list, AbstractInsnNode first, AbstractInsnNode last) {
|
||||
this(list, list.indexOf(first), list.indexOf(last)+1);
|
||||
this(list, list.indexOf(first), list.indexOf(last) + 1);
|
||||
}
|
||||
|
||||
public InsnListSection(InsnList list) {
|
||||
@@ -63,8 +60,7 @@ public class InsnListSection implements Iterable<AbstractInsnNode>
|
||||
}
|
||||
|
||||
public void accept(MethodVisitor mv) {
|
||||
for(AbstractInsnNode insn : this)
|
||||
insn.accept(mv);
|
||||
for (AbstractInsnNode insn : this) insn.accept(mv);
|
||||
}
|
||||
|
||||
public AbstractInsnNode getFirst() {
|
||||
@@ -103,35 +99,30 @@ public class InsnListSection implements Iterable<AbstractInsnNode>
|
||||
|
||||
public void insertBefore(InsnList insns) {
|
||||
int s = insns.size();
|
||||
if(this.list.size() == 0)
|
||||
list.insert(insns);
|
||||
else
|
||||
list.insertBefore(list.get(start), insns);
|
||||
start+=s;
|
||||
end+=s;
|
||||
if (this.list.size() == 0) list.insert(insns);
|
||||
else list.insertBefore(list.get(start), insns);
|
||||
start += s;
|
||||
end += s;
|
||||
}
|
||||
|
||||
public void insert(InsnList insns) {
|
||||
if(end == 0)
|
||||
list.insert(insns);
|
||||
else
|
||||
list.insert(list.get(end-1), insns);
|
||||
if (end == 0) list.insert(insns);
|
||||
else list.insert(list.get(end - 1), insns);
|
||||
}
|
||||
|
||||
public void replace(InsnList insns) {
|
||||
int s = insns.size();
|
||||
remove();
|
||||
insert(insns);
|
||||
end = start+s;
|
||||
end = start + s;
|
||||
}
|
||||
|
||||
public void remove() {
|
||||
while(end != start)
|
||||
remove(0);
|
||||
while (end != start) remove(0);
|
||||
}
|
||||
|
||||
public void setLast(AbstractInsnNode last) {
|
||||
end = list.indexOf(last)+1;
|
||||
end = list.indexOf(last) + 1;
|
||||
}
|
||||
|
||||
public void setFirst(AbstractInsnNode first) {
|
||||
@@ -147,7 +138,7 @@ public class InsnListSection implements Iterable<AbstractInsnNode>
|
||||
}
|
||||
|
||||
public InsnListSection slice(int start, int end) {
|
||||
return new InsnListSection(list, this.start+start, this.start+end);
|
||||
return new InsnListSection(list, this.start + start, this.start + end);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -155,11 +146,9 @@ public class InsnListSection implements Iterable<AbstractInsnNode>
|
||||
* @return this
|
||||
*/
|
||||
public InsnListSection trim(Set<LabelNode> controlFlowLabels) {
|
||||
while(start < end && !InsnComparator.insnImportant(getFirst(), controlFlowLabels))
|
||||
start++;
|
||||
while (start < end && !InsnComparator.insnImportant(getFirst(), controlFlowLabels)) start++;
|
||||
|
||||
while(start < end && !InsnComparator.insnImportant(getLast(), controlFlowLabels))
|
||||
end--;
|
||||
while (start < end && !InsnComparator.insnImportant(getLast(), controlFlowLabels)) end--;
|
||||
|
||||
return this;
|
||||
}
|
||||
@@ -176,38 +165,34 @@ public class InsnListSection implements Iterable<AbstractInsnNode>
|
||||
System.out.println(toString());
|
||||
}
|
||||
|
||||
public HashMap<LabelNode,LabelNode> identityLabelMap() {
|
||||
public HashMap<LabelNode, LabelNode> identityLabelMap() {
|
||||
HashMap<LabelNode, LabelNode> labelMap = new HashMap<LabelNode, LabelNode>();
|
||||
for (AbstractInsnNode insn : this)
|
||||
switch(insn.getType()) {
|
||||
switch (insn.getType()) {
|
||||
case LABEL:
|
||||
labelMap.put((LabelNode) insn, (LabelNode) insn);
|
||||
break;
|
||||
case JUMP_INSN:
|
||||
labelMap.put(((JumpInsnNode)insn).label, ((JumpInsnNode)insn).label);
|
||||
labelMap.put(((JumpInsnNode) insn).label, ((JumpInsnNode) insn).label);
|
||||
break;
|
||||
case LOOKUPSWITCH_INSN:
|
||||
LookupSwitchInsnNode linsn = (LookupSwitchInsnNode)insn;
|
||||
LookupSwitchInsnNode linsn = (LookupSwitchInsnNode) insn;
|
||||
labelMap.put(linsn.dflt, linsn.dflt);
|
||||
for(LabelNode label : linsn.labels)
|
||||
labelMap.put(label, label);
|
||||
for (LabelNode label : linsn.labels) labelMap.put(label, label);
|
||||
break;
|
||||
case TABLESWITCH_INSN:
|
||||
TableSwitchInsnNode tinsn = (TableSwitchInsnNode)insn;
|
||||
TableSwitchInsnNode tinsn = (TableSwitchInsnNode) insn;
|
||||
labelMap.put(tinsn.dflt, tinsn.dflt);
|
||||
for(LabelNode label : tinsn.labels)
|
||||
labelMap.put(label, label);
|
||||
for (LabelNode label : tinsn.labels) labelMap.put(label, label);
|
||||
break;
|
||||
case FRAME:
|
||||
FrameNode fnode = (FrameNode)insn;
|
||||
if(fnode.local != null)
|
||||
for(Object o : fnode.local)
|
||||
if(o instanceof LabelNode)
|
||||
labelMap.put((LabelNode) o, (LabelNode) o);
|
||||
if(fnode.stack != null)
|
||||
for(Object o : fnode.stack)
|
||||
if(o instanceof LabelNode)
|
||||
labelMap.put((LabelNode) o, (LabelNode) o);
|
||||
FrameNode fnode = (FrameNode) insn;
|
||||
if (fnode.local != null)
|
||||
for (Object o : fnode.local)
|
||||
if (o instanceof LabelNode) labelMap.put((LabelNode) o, (LabelNode) o);
|
||||
if (fnode.stack != null)
|
||||
for (Object o : fnode.stack)
|
||||
if (o instanceof LabelNode) labelMap.put((LabelNode) o, (LabelNode) o);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -216,8 +201,7 @@ public class InsnListSection implements Iterable<AbstractInsnNode>
|
||||
|
||||
public Map<LabelNode, LabelNode> cloneLabels() {
|
||||
Map<LabelNode, LabelNode> labelMap = identityLabelMap();
|
||||
for(Entry<LabelNode, LabelNode> entry : labelMap.entrySet())
|
||||
entry.setValue(new LabelNode());
|
||||
for (Entry<LabelNode, LabelNode> entry : labelMap.entrySet()) entry.setValue(new LabelNode());
|
||||
|
||||
return labelMap;
|
||||
}
|
||||
@@ -228,8 +212,7 @@ public class InsnListSection implements Iterable<AbstractInsnNode>
|
||||
|
||||
public InsnListSection copy(Map<LabelNode, LabelNode> labelMap) {
|
||||
InsnListSection copy = new InsnListSection();
|
||||
for(AbstractInsnNode insn : this)
|
||||
copy.add(insn.clone(labelMap));
|
||||
for (AbstractInsnNode insn : this) copy.add(insn.clone(labelMap));
|
||||
|
||||
return copy;
|
||||
}
|
||||
@@ -238,4 +221,4 @@ public class InsnListSection implements Iterable<AbstractInsnNode>
|
||||
public Iterator<AbstractInsnNode> iterator() {
|
||||
return new InsnListSectionIterator();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,37 +1,35 @@
|
||||
package codechicken.lib.asm;
|
||||
|
||||
import java.util.Set;
|
||||
import org.objectweb.asm.ClassVisitor;
|
||||
import org.objectweb.asm.MethodVisitor;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
import org.objectweb.asm.commons.LocalVariablesSorter;
|
||||
|
||||
import java.util.Set;
|
||||
public class LocalVariablesSorterVisitor extends ClassVisitor {
|
||||
public Set<ObfMapping> methods;
|
||||
public String owner;
|
||||
|
||||
public class LocalVariablesSorterVisitor extends ClassVisitor
|
||||
{
|
||||
public Set<ObfMapping> methods;
|
||||
public String owner;
|
||||
|
||||
public LocalVariablesSorterVisitor(Set<ObfMapping> methods, ClassVisitor cv) {
|
||||
super(Opcodes.ASM4, cv);
|
||||
this.methods = methods;
|
||||
}
|
||||
|
||||
public LocalVariablesSorterVisitor(ClassVisitor cv) {
|
||||
this(null, cv);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
|
||||
super.visit(version, access, name, signature, superName, interfaces);
|
||||
owner = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
|
||||
MethodVisitor mv = cv.visitMethod(access, name, desc, signature, exceptions);
|
||||
return methods == null || methods.contains(new ObfMapping(owner, name, desc)) ? new LocalVariablesSorter(access, desc, mv) : mv;
|
||||
}
|
||||
public LocalVariablesSorterVisitor(Set<ObfMapping> methods, ClassVisitor cv) {
|
||||
super(Opcodes.ASM4, cv);
|
||||
this.methods = methods;
|
||||
}
|
||||
|
||||
|
||||
public LocalVariablesSorterVisitor(ClassVisitor cv) {
|
||||
this(null, cv);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
|
||||
super.visit(version, access, name, signature, superName, interfaces);
|
||||
owner = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
|
||||
MethodVisitor mv = cv.visitMethod(access, name, desc, signature, exceptions);
|
||||
return methods == null || methods.contains(new ObfMapping(owner, name, desc))
|
||||
? new LocalVariablesSorter(access, desc, mv)
|
||||
: mv;
|
||||
}
|
||||
}
|
||||
@@ -1,19 +1,16 @@
|
||||
package codechicken.lib.asm;
|
||||
|
||||
import static codechicken.lib.asm.ASMHelper.*;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.*;
|
||||
import org.objectweb.asm.*;
|
||||
import org.objectweb.asm.tree.ClassNode;
|
||||
import org.objectweb.asm.tree.InsnList;
|
||||
import org.objectweb.asm.tree.MethodNode;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.*;
|
||||
|
||||
import static codechicken.lib.asm.ASMHelper.*;
|
||||
|
||||
public class ModularASMTransformer
|
||||
{
|
||||
public static class ClassNodeTransformerList
|
||||
{
|
||||
public class ModularASMTransformer {
|
||||
public static class ClassNodeTransformerList {
|
||||
List<ClassNodeTransformer> transformers = new LinkedList<ClassNodeTransformer>();
|
||||
HashSet<ObfMapping> methodsToSort = new HashSet<ObfMapping>();
|
||||
|
||||
@@ -26,31 +23,30 @@ public class ModularASMTransformer
|
||||
ClassNode cnode = new ClassNode();
|
||||
ClassReader reader = new ClassReader(bytes);
|
||||
ClassVisitor cv = cnode;
|
||||
if(!methodsToSort.isEmpty())
|
||||
cv = new LocalVariablesSorterVisitor(methodsToSort, cv);
|
||||
if (!methodsToSort.isEmpty()) cv = new LocalVariablesSorterVisitor(methodsToSort, cv);
|
||||
reader.accept(cv, ClassReader.EXPAND_FRAMES);
|
||||
|
||||
try {
|
||||
int writeFlags = 0;
|
||||
for(ClassNodeTransformer t : transformers) {
|
||||
for (ClassNodeTransformer t : transformers) {
|
||||
t.transform(cnode);
|
||||
writeFlags|=t.writeFlags;
|
||||
writeFlags |= t.writeFlags;
|
||||
}
|
||||
|
||||
bytes = createBytes(cnode, writeFlags);
|
||||
if(config.getTag("dump_asm").getBooleanValue(false))
|
||||
dump(bytes, new File("asm/ccl_modular/"+cnode.name.replace('/', '#')+".txt"), false, false);
|
||||
if (config.getTag("dump_asm").getBooleanValue(false))
|
||||
dump(bytes, new File("asm/ccl_modular/" + cnode.name.replace('/', '#') + ".txt"), false, false);
|
||||
return bytes;
|
||||
} catch (RuntimeException e) {
|
||||
dump(bytes, new File("asm/ccl_modular/"+cnode.name.replace('/', '#')+".txt"), false, false);
|
||||
dump(bytes, new File("asm/ccl_modular/" + cnode.name.replace('/', '#') + ".txt"), false, false);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static abstract class ClassNodeTransformer
|
||||
{
|
||||
public abstract static class ClassNodeTransformer {
|
||||
public int writeFlags;
|
||||
|
||||
public ClassNodeTransformer(int writeFlags) {
|
||||
this.writeFlags = writeFlags;
|
||||
}
|
||||
@@ -60,13 +56,13 @@ public class ModularASMTransformer
|
||||
}
|
||||
|
||||
public abstract String className();
|
||||
|
||||
public abstract void transform(ClassNode cnode);
|
||||
|
||||
public void addMethodsToSort(Set<ObfMapping> set) {}
|
||||
}
|
||||
|
||||
public static abstract class MethodTransformer extends ClassNodeTransformer
|
||||
{
|
||||
public abstract static class MethodTransformer extends ClassNodeTransformer {
|
||||
public final ObfMapping method;
|
||||
|
||||
public MethodTransformer(ObfMapping method) {
|
||||
@@ -81,28 +77,26 @@ public class ModularASMTransformer
|
||||
@Override
|
||||
public void transform(ClassNode cnode) {
|
||||
MethodNode mv = findMethod(method, cnode);
|
||||
if (mv == null)
|
||||
throw new RuntimeException("Method not found: " + method);
|
||||
if (mv == null) throw new RuntimeException("Method not found: " + method);
|
||||
|
||||
try {
|
||||
transform(mv);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Error transforming method: "+method, e);
|
||||
throw new RuntimeException("Error transforming method: " + method, e);
|
||||
}
|
||||
}
|
||||
|
||||
public abstract void transform(MethodNode mv);
|
||||
}
|
||||
|
||||
public static class MethodWriter extends ClassNodeTransformer
|
||||
{
|
||||
public static class MethodWriter extends ClassNodeTransformer {
|
||||
public final int access;
|
||||
public final ObfMapping method;
|
||||
public final String[] exceptions;
|
||||
public InsnList list;
|
||||
|
||||
public MethodWriter(int access, ObfMapping method) {
|
||||
this(access, method, null, (InsnList)null);
|
||||
this(access, method, null, (InsnList) null);
|
||||
}
|
||||
|
||||
public MethodWriter(int access, ObfMapping method, InsnList list) {
|
||||
@@ -114,7 +108,7 @@ public class ModularASMTransformer
|
||||
}
|
||||
|
||||
public MethodWriter(int access, ObfMapping method, String[] exceptions) {
|
||||
this(access, method, exceptions, (InsnList)null);
|
||||
this(access, method, exceptions, (InsnList) null);
|
||||
}
|
||||
|
||||
public MethodWriter(int access, ObfMapping method, String[] exceptions, InsnList list) {
|
||||
@@ -136,28 +130,24 @@ public class ModularASMTransformer
|
||||
@Override
|
||||
public void transform(ClassNode cnode) {
|
||||
MethodNode mv = findMethod(method, cnode);
|
||||
if(mv == null)
|
||||
mv = (MethodNode) method.visitMethod(cnode, access, exceptions);
|
||||
if (mv == null) mv = (MethodNode) method.visitMethod(cnode, access, exceptions);
|
||||
else {
|
||||
mv.access = access;
|
||||
mv.instructions.clear();
|
||||
if (mv.localVariables != null)
|
||||
mv.localVariables.clear();
|
||||
if (mv.tryCatchBlocks != null)
|
||||
mv.tryCatchBlocks.clear();
|
||||
if (mv.localVariables != null) mv.localVariables.clear();
|
||||
if (mv.tryCatchBlocks != null) mv.tryCatchBlocks.clear();
|
||||
}
|
||||
|
||||
write(mv);
|
||||
}
|
||||
|
||||
public void write(MethodNode mv) {
|
||||
logger.debug("Writing method "+method);
|
||||
logger.debug("Writing method " + method);
|
||||
list.accept(mv);
|
||||
}
|
||||
}
|
||||
|
||||
public static class MethodInjector extends MethodTransformer
|
||||
{
|
||||
public static class MethodInjector extends MethodTransformer {
|
||||
public ASMBlock needle;
|
||||
public ASMBlock injection;
|
||||
public boolean before;
|
||||
@@ -188,29 +178,24 @@ public class ModularASMTransformer
|
||||
|
||||
@Override
|
||||
public void transform(MethodNode mv) {
|
||||
if(needle == null) {
|
||||
logger.debug("Injecting "+(before ? "before" : "after")+" method "+method);
|
||||
if (before)
|
||||
mv.instructions.insert(injection.rawListCopy());
|
||||
else
|
||||
mv.instructions.add(injection.rawListCopy());
|
||||
}
|
||||
else {
|
||||
if (needle == null) {
|
||||
logger.debug("Injecting " + (before ? "before" : "after") + " method " + method);
|
||||
if (before) mv.instructions.insert(injection.rawListCopy());
|
||||
else mv.instructions.add(injection.rawListCopy());
|
||||
} else {
|
||||
for (InsnListSection key : InsnComparator.findN(mv.instructions, needle.list)) {
|
||||
logger.debug("Injecting "+(before ? "before" : "after")+" method "+method+" @ "+key.start+" - "+key.end);
|
||||
logger.debug("Injecting " + (before ? "before" : "after") + " method " + method + " @ " + key.start
|
||||
+ " - " + key.end);
|
||||
ASMBlock injectBlock = injection.copy().mergeLabels(needle.applyLabels(key));
|
||||
|
||||
if (before)
|
||||
key.insertBefore(injectBlock.list.list);
|
||||
else
|
||||
key.insert(injectBlock.list.list);
|
||||
if (before) key.insertBefore(injectBlock.list.list);
|
||||
else key.insert(injectBlock.list.list);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class MethodReplacer extends MethodTransformer
|
||||
{
|
||||
public static class MethodReplacer extends MethodTransformer {
|
||||
public ASMBlock needle;
|
||||
public ASMBlock replacement;
|
||||
|
||||
@@ -232,15 +217,14 @@ public class ModularASMTransformer
|
||||
@Override
|
||||
public void transform(MethodNode mv) {
|
||||
for (InsnListSection key : InsnComparator.findN(mv.instructions, needle.list)) {
|
||||
logger.debug("Replacing method "+method+" @ "+key.start+" - "+key.end);
|
||||
logger.debug("Replacing method " + method + " @ " + key.start + " - " + key.end);
|
||||
ASMBlock replaceBlock = replacement.copy().pullLabels(needle.applyLabels(key));
|
||||
key.insert(replaceBlock.list.list);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class FieldWriter extends ClassNodeTransformer
|
||||
{
|
||||
public static class FieldWriter extends ClassNodeTransformer {
|
||||
public final ObfMapping field;
|
||||
public final int access;
|
||||
public final Object value;
|
||||
@@ -270,14 +254,12 @@ public class ModularASMTransformer
|
||||
|
||||
public void add(ClassNodeTransformer t) {
|
||||
ClassNodeTransformerList list = transformers.get(t.className());
|
||||
if(list == null)
|
||||
transformers.put(t.className(), list = new ClassNodeTransformerList());
|
||||
if (list == null) transformers.put(t.className(), list = new ClassNodeTransformerList());
|
||||
list.add(t);
|
||||
}
|
||||
|
||||
public byte[] transform(String name, byte[] bytes) {
|
||||
if(bytes == null)
|
||||
return null;
|
||||
if (bytes == null) return null;
|
||||
|
||||
ClassNodeTransformerList list = transformers.get(name);
|
||||
return list == null ? bytes : list.transform(bytes);
|
||||
|
||||
@@ -7,6 +7,13 @@ import com.google.common.io.LineProcessor;
|
||||
import com.google.common.io.Resources;
|
||||
import cpw.mods.fml.common.asm.transformers.deobf.FMLDeobfuscatingRemapper;
|
||||
import cpw.mods.fml.relauncher.FMLInjectionData;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import javax.swing.*;
|
||||
import net.minecraft.launchwrapper.Launch;
|
||||
import net.minecraftforge.common.ForgeVersion;
|
||||
import org.objectweb.asm.ClassVisitor;
|
||||
@@ -15,18 +22,8 @@ import org.objectweb.asm.MethodVisitor;
|
||||
import org.objectweb.asm.commons.Remapper;
|
||||
import org.objectweb.asm.tree.*;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
public class ObfMapping
|
||||
{
|
||||
public static class ObfRemapper extends Remapper
|
||||
{
|
||||
public class ObfMapping {
|
||||
public static class ObfRemapper extends Remapper {
|
||||
private HashMap<String, String> fields = new HashMap<String, String>();
|
||||
private HashMap<String, String> funcs = new HashMap<String, String>();
|
||||
|
||||
@@ -36,20 +33,27 @@ public class ObfMapping
|
||||
Field rawMethodMapsField = FMLDeobfuscatingRemapper.class.getDeclaredField("rawMethodMaps");
|
||||
rawFieldMapsField.setAccessible(true);
|
||||
rawMethodMapsField.setAccessible(true);
|
||||
Map<String, Map<String, String>> rawFieldMaps = (Map<String, Map<String, String>>) rawFieldMapsField.get(FMLDeobfuscatingRemapper.INSTANCE);
|
||||
Map<String, Map<String, String>> rawMethodMaps = (Map<String, Map<String, String>>) rawMethodMapsField.get(FMLDeobfuscatingRemapper.INSTANCE);
|
||||
Map<String, Map<String, String>> rawFieldMaps =
|
||||
(Map<String, Map<String, String>>) rawFieldMapsField.get(FMLDeobfuscatingRemapper.INSTANCE);
|
||||
Map<String, Map<String, String>> rawMethodMaps =
|
||||
(Map<String, Map<String, String>>) rawMethodMapsField.get(FMLDeobfuscatingRemapper.INSTANCE);
|
||||
|
||||
if (rawFieldMaps == null)
|
||||
throw new IllegalStateException("codechicken.lib.asm.ObfMapping loaded too early. Make sure all references are in or after the asm transformer load stage");
|
||||
throw new IllegalStateException(
|
||||
"codechicken.lib.asm.ObfMapping loaded too early. Make sure all references are in or after the asm transformer load stage");
|
||||
|
||||
for (Map<String, String> map : rawFieldMaps.values())
|
||||
for (Entry<String, String> entry : map.entrySet())
|
||||
if (entry.getValue().startsWith("field"))
|
||||
fields.put(entry.getValue(), entry.getKey().substring(0, entry.getKey().indexOf(':')));
|
||||
fields.put(
|
||||
entry.getValue(),
|
||||
entry.getKey().substring(0, entry.getKey().indexOf(':')));
|
||||
for (Map<String, String> map : rawMethodMaps.values())
|
||||
for (Entry<String, String> entry : map.entrySet())
|
||||
if (entry.getValue().startsWith("func"))
|
||||
funcs.put(entry.getValue(), entry.getKey().substring(0, entry.getKey().indexOf('(')));
|
||||
funcs.put(
|
||||
entry.getValue(),
|
||||
entry.getKey().substring(0, entry.getKey().indexOf('(')));
|
||||
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
@@ -82,21 +86,20 @@ public class ObfMapping
|
||||
}
|
||||
}
|
||||
|
||||
public static class MCPRemapper extends Remapper implements LineProcessor<Void>
|
||||
{
|
||||
public static class MCPRemapper extends Remapper implements LineProcessor<Void> {
|
||||
public static File[] getConfFiles() {
|
||||
ConfigTag tag = ASMHelper.config.getTag("mappingDir").setComment("Path to directory holding packaged.srg, fields.csv and methods.csv for mcp remapping");
|
||||
for (int i = 0; i < DIR_GUESSES+DIR_ASKS; i++) {
|
||||
ConfigTag tag = ASMHelper.config
|
||||
.getTag("mappingDir")
|
||||
.setComment("Path to directory holding packaged.srg, fields.csv and methods.csv for mcp remapping");
|
||||
for (int i = 0; i < DIR_GUESSES + DIR_ASKS; i++) {
|
||||
File dir = confDirectoryGuess(i, tag);
|
||||
if (dir == null || dir.isFile())
|
||||
continue;
|
||||
if (dir == null || dir.isFile()) continue;
|
||||
|
||||
File[] mappings;
|
||||
try {
|
||||
mappings = parseConfDir(dir);
|
||||
} catch (Exception e) {
|
||||
if (i >= DIR_GUESSES)
|
||||
e.printStackTrace();
|
||||
if (i >= DIR_GUESSES) e.printStackTrace();
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -109,6 +112,7 @@ public class ObfMapping
|
||||
|
||||
private static final int DIR_GUESSES = 5;
|
||||
private static final int DIR_ASKS = 3;
|
||||
|
||||
public static File confDirectoryGuess(int i, ConfigTag tag) {
|
||||
File mcDir = (File) FMLInjectionData.data()[6];
|
||||
switch (i) {
|
||||
@@ -119,11 +123,15 @@ public class ObfMapping
|
||||
case 2:
|
||||
return new File(mcDir, "../build/unpacked/conf");
|
||||
case 3:
|
||||
return new File(System.getProperty("user.home"), ".gradle/caches/minecraft/net/minecraftforge/forge/"+
|
||||
FMLInjectionData.data()[4]+"-"+ ForgeVersion.getVersion()+"/unpacked/conf");
|
||||
return new File(
|
||||
System.getProperty("user.home"),
|
||||
".gradle/caches/minecraft/net/minecraftforge/forge/" + FMLInjectionData.data()[4] + "-"
|
||||
+ ForgeVersion.getVersion() + "/unpacked/conf");
|
||||
case 4:
|
||||
return new File(System.getProperty("user.home"), ".gradle/caches/minecraft/net/minecraftforge/forge/"+
|
||||
FMLInjectionData.data()[4]+"-"+ ForgeVersion.getVersion()+"-"+FMLInjectionData.data()[4]+"/unpacked/conf");
|
||||
return new File(
|
||||
System.getProperty("user.home"),
|
||||
".gradle/caches/minecraft/net/minecraftforge/forge/" + FMLInjectionData.data()[4] + "-"
|
||||
+ ForgeVersion.getVersion() + "-" + FMLInjectionData.data()[4] + "/unpacked/conf");
|
||||
default:
|
||||
JFileChooser fc = new JFileChooser(mcDir);
|
||||
fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
|
||||
@@ -135,27 +143,21 @@ public class ObfMapping
|
||||
|
||||
public static File[] parseConfDir(File confDir) {
|
||||
File srgDir = new File(confDir, "conf");
|
||||
if (!srgDir.exists())
|
||||
srgDir = confDir;
|
||||
if (!srgDir.exists()) srgDir = confDir;
|
||||
|
||||
File srgs = new File(srgDir, "packaged.srg");
|
||||
if (!srgs.exists())
|
||||
srgs = new File(srgDir, "joined.srg");
|
||||
if (!srgs.exists())
|
||||
throw new RuntimeException("Could not find packaged.srg or joined.srg");
|
||||
if (!srgs.exists()) srgs = new File(srgDir, "joined.srg");
|
||||
if (!srgs.exists()) throw new RuntimeException("Could not find packaged.srg or joined.srg");
|
||||
|
||||
File mapDir = new File(confDir, "mappings");
|
||||
if (!mapDir.exists())
|
||||
mapDir = confDir;
|
||||
if (!mapDir.exists()) mapDir = confDir;
|
||||
|
||||
File methods = new File(mapDir, "methods.csv");
|
||||
if (!methods.exists())
|
||||
throw new RuntimeException("Could not find methods.csv");
|
||||
if (!methods.exists()) throw new RuntimeException("Could not find methods.csv");
|
||||
File fields = new File(mapDir, "fields.csv");
|
||||
if (!fields.exists())
|
||||
throw new RuntimeException("Could not find fields.csv");
|
||||
if (!fields.exists()) throw new RuntimeException("Could not find fields.csv");
|
||||
|
||||
return new File[]{srgs, methods, fields};
|
||||
return new File[] {srgs, methods, fields};
|
||||
}
|
||||
|
||||
private HashMap<String, String> fields = new HashMap<String, String>();
|
||||
@@ -204,8 +206,7 @@ public class ObfMapping
|
||||
public static Remapper mcpMapper = null;
|
||||
|
||||
public static void loadMCPRemapper() {
|
||||
if (mcpMapper == null)
|
||||
mcpMapper = new MCPRemapper();
|
||||
if (mcpMapper == null) mcpMapper = new MCPRemapper();
|
||||
}
|
||||
|
||||
public static final boolean obfuscated;
|
||||
@@ -214,10 +215,10 @@ public class ObfMapping
|
||||
boolean obf = true;
|
||||
try {
|
||||
obf = Launch.classLoader.getClassBytes("net.minecraft.world.World") == null;
|
||||
} catch (IOException ignored) {}
|
||||
} catch (IOException ignored) {
|
||||
}
|
||||
obfuscated = obf;
|
||||
if (!obf)
|
||||
loadMCPRemapper();
|
||||
if (!obf) loadMCPRemapper();
|
||||
}
|
||||
|
||||
public String s_owner;
|
||||
@@ -233,8 +234,7 @@ public class ObfMapping
|
||||
this.s_name = name;
|
||||
this.s_desc = desc;
|
||||
|
||||
if (s_owner.contains("."))
|
||||
throw new IllegalArgumentException(s_owner);
|
||||
if (s_owner.contains(".")) throw new IllegalArgumentException(s_owner);
|
||||
}
|
||||
|
||||
public ObfMapping(ObfMapping descmap, String subclass) {
|
||||
@@ -243,20 +243,18 @@ public class ObfMapping
|
||||
|
||||
public static ObfMapping fromDesc(String s) {
|
||||
int lastDot = s.lastIndexOf('.');
|
||||
if (lastDot < 0)
|
||||
return new ObfMapping(s, "", "");
|
||||
int sep = s.indexOf('(');//methods
|
||||
if (lastDot < 0) return new ObfMapping(s, "", "");
|
||||
int sep = s.indexOf('('); // methods
|
||||
int sep_end = sep;
|
||||
if (sep < 0) {
|
||||
sep = s.indexOf(' ');//some stuffs
|
||||
sep = s.indexOf(' '); // some stuffs
|
||||
sep_end = sep + 1;
|
||||
}
|
||||
if (sep < 0) {
|
||||
sep = s.indexOf(':');//fields
|
||||
sep = s.indexOf(':'); // fields
|
||||
sep_end = sep + 1;
|
||||
}
|
||||
if (sep < 0)
|
||||
return new ObfMapping(s.substring(0, lastDot), s.substring(lastDot + 1), "");
|
||||
if (sep < 0) return new ObfMapping(s.substring(0, lastDot), s.substring(lastDot + 1), "");
|
||||
|
||||
return new ObfMapping(s.substring(0, lastDot), s.substring(lastDot + 1, sep), s.substring(sep_end));
|
||||
}
|
||||
@@ -274,12 +272,9 @@ public class ObfMapping
|
||||
}
|
||||
|
||||
public AbstractInsnNode toInsn(int opcode) {
|
||||
if (isClass())
|
||||
return new TypeInsnNode(opcode, s_owner);
|
||||
else if (isMethod())
|
||||
return new MethodInsnNode(opcode, s_owner, s_name, s_desc);
|
||||
else
|
||||
return new FieldInsnNode(opcode, s_owner, s_name, s_desc);
|
||||
if (isClass()) return new TypeInsnNode(opcode, s_owner);
|
||||
else if (isMethod()) return new MethodInsnNode(opcode, s_owner, s_name, s_desc);
|
||||
else return new FieldInsnNode(opcode, s_owner, s_name, s_desc);
|
||||
}
|
||||
|
||||
public void visitTypeInsn(MethodVisitor mv, int opcode) {
|
||||
@@ -324,8 +319,7 @@ public class ObfMapping
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (!(obj instanceof ObfMapping))
|
||||
return false;
|
||||
if (!(obj instanceof ObfMapping)) return false;
|
||||
|
||||
ObfMapping desc = (ObfMapping) obj;
|
||||
return s_owner.equals(desc.s_owner) && s_name.equals(desc.s_name) && s_desc.equals(desc.s_desc);
|
||||
@@ -338,10 +332,8 @@ public class ObfMapping
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
if (s_name.length() == 0)
|
||||
return "[" + s_owner + "]";
|
||||
if (s_desc.length() == 0)
|
||||
return "[" + s_owner + "." + s_name + "]";
|
||||
if (s_name.length() == 0) return "[" + s_owner + "]";
|
||||
if (s_desc.length() == 0) return "[" + s_owner + "." + s_name + "]";
|
||||
return "[" + (isMethod() ? methodDesc() : fieldDesc()) + "]";
|
||||
}
|
||||
|
||||
@@ -366,20 +358,15 @@ public class ObfMapping
|
||||
}
|
||||
|
||||
public ObfMapping map(Remapper mapper) {
|
||||
if (mapper == null)
|
||||
return this;
|
||||
if (mapper == null) return this;
|
||||
|
||||
if (isMethod())
|
||||
s_name = mapper.mapMethodName(s_owner, s_name, s_desc);
|
||||
else if (isField())
|
||||
s_name = mapper.mapFieldName(s_owner, s_name, s_desc);
|
||||
if (isMethod()) s_name = mapper.mapMethodName(s_owner, s_name, s_desc);
|
||||
else if (isField()) s_name = mapper.mapFieldName(s_owner, s_name, s_desc);
|
||||
|
||||
s_owner = mapper.mapType(s_owner);
|
||||
|
||||
if (isMethod())
|
||||
s_desc = mapper.mapMethodDesc(s_desc);
|
||||
else if (s_desc.length() > 0)
|
||||
s_desc = mapper.mapDesc(s_desc);
|
||||
if (isMethod()) s_desc = mapper.mapMethodDesc(s_desc);
|
||||
else if (s_desc.length() > 0) s_desc = mapper.mapDesc(s_desc);
|
||||
|
||||
return this;
|
||||
}
|
||||
@@ -390,10 +377,8 @@ public class ObfMapping
|
||||
}
|
||||
|
||||
public ObfMapping toClassloading() {
|
||||
if(!obfuscated)
|
||||
map(mcpMapper);
|
||||
else if(obfMapper.isObf(s_owner))
|
||||
map(obfMapper);
|
||||
if (!obfuscated) map(mcpMapper);
|
||||
else if (obfMapper.isObf(s_owner)) map(obfMapper);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,28 +5,25 @@ import codechicken.lib.math.MathHelper;
|
||||
import codechicken.lib.util.Copyable;
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
public abstract class Colour implements Copyable<Colour>
|
||||
{
|
||||
public static IConfigType<Colour> configRGB = new IConfigType<Colour>()
|
||||
{
|
||||
public abstract class Colour implements Copyable<Colour> {
|
||||
public static IConfigType<Colour> configRGB = new IConfigType<Colour>() {
|
||||
@Override
|
||||
public String configValue(Colour entry) {
|
||||
String s = Long.toString(((long) entry.rgb()) << 32 >>> 32, 16);
|
||||
while (s.length() < 6)
|
||||
s = "0" + s;
|
||||
while (s.length() < 6) s = "0" + s;
|
||||
return "0x" + s.toUpperCase();
|
||||
}
|
||||
|
||||
private final Pattern patternRGB = Pattern.compile("(\\d+),(\\d+),(\\d+)");
|
||||
|
||||
@Override
|
||||
public Colour valueOf(String text) throws Exception {
|
||||
Matcher matcherRGB = patternRGB.matcher(text.replaceAll("\\s", ""));
|
||||
if(matcherRGB.matches())
|
||||
if (matcherRGB.matches())
|
||||
return new ColourRGBA(
|
||||
Integer.parseInt(matcherRGB.group(1)),
|
||||
Integer.parseInt(matcherRGB.group(2)),
|
||||
@@ -34,7 +31,7 @@ public abstract class Colour implements Copyable<Colour>
|
||||
0xFF);
|
||||
|
||||
int hex = (int) Long.parseLong(text.replace("0x", ""), 16);
|
||||
return new ColourRGBA(hex<<8|0xFF);
|
||||
return new ColourRGBA(hex << 8 | 0xFF);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -43,16 +40,14 @@ public abstract class Colour implements Copyable<Colour>
|
||||
public byte b;
|
||||
public byte a;
|
||||
|
||||
public Colour(int r, int g, int b, int a)
|
||||
{
|
||||
public Colour(int r, int g, int b, int a) {
|
||||
this.r = (byte) r;
|
||||
this.g = (byte) g;
|
||||
this.b = (byte) b;
|
||||
this.a = (byte) a;
|
||||
}
|
||||
|
||||
public Colour(Colour colour)
|
||||
{
|
||||
public Colour(Colour colour) {
|
||||
r = colour.r;
|
||||
g = colour.g;
|
||||
b = colour.b;
|
||||
@@ -60,27 +55,23 @@ public abstract class Colour implements Copyable<Colour>
|
||||
}
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
public void glColour()
|
||||
{
|
||||
public void glColour() {
|
||||
GL11.glColor4ub(r, g, b, a);
|
||||
}
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
public void glColour(int a)
|
||||
{
|
||||
public void glColour(int a) {
|
||||
GL11.glColor4ub(r, g, b, (byte) a);
|
||||
}
|
||||
|
||||
|
||||
public abstract int pack();
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
public String toString() {
|
||||
return getClass().getSimpleName() + "[0x" + Integer.toHexString(pack()).toUpperCase() + "]";
|
||||
}
|
||||
|
||||
public Colour add(Colour colour2)
|
||||
{
|
||||
public Colour add(Colour colour2) {
|
||||
a += colour2.a;
|
||||
r += colour2.r;
|
||||
g += colour2.g;
|
||||
@@ -88,8 +79,7 @@ public abstract class Colour implements Copyable<Colour>
|
||||
return this;
|
||||
}
|
||||
|
||||
public Colour sub(Colour colour2)
|
||||
{
|
||||
public Colour sub(Colour colour2) {
|
||||
int ia = (a & 0xFF) - (colour2.a & 0xFF);
|
||||
int ir = (r & 0xFF) - (colour2.r & 0xFF);
|
||||
int ig = (g & 0xFF) - (colour2.g & 0xFF);
|
||||
@@ -101,8 +91,7 @@ public abstract class Colour implements Copyable<Colour>
|
||||
return this;
|
||||
}
|
||||
|
||||
public Colour invert()
|
||||
{
|
||||
public Colour invert() {
|
||||
a = (byte) (0xFF - (a & 0xFF));
|
||||
r = (byte) (0xFF - (r & 0xFF));
|
||||
g = (byte) (0xFF - (g & 0xFF));
|
||||
@@ -110,8 +99,7 @@ public abstract class Colour implements Copyable<Colour>
|
||||
return this;
|
||||
}
|
||||
|
||||
public Colour multiply(Colour colour2)
|
||||
{
|
||||
public Colour multiply(Colour colour2) {
|
||||
a = (byte) ((a & 0xFF) * ((colour2.a & 0xFF) / 255D));
|
||||
r = (byte) ((r & 0xFF) * ((colour2.r & 0xFF) / 255D));
|
||||
g = (byte) ((g & 0xFF) * ((colour2.g & 0xFF) / 255D));
|
||||
@@ -119,8 +107,7 @@ public abstract class Colour implements Copyable<Colour>
|
||||
return this;
|
||||
}
|
||||
|
||||
public Colour scale(double d)
|
||||
{
|
||||
public Colour scale(double d) {
|
||||
a = (byte) ((a & 0xFF) * d);
|
||||
r = (byte) ((r & 0xFF) * d);
|
||||
g = (byte) ((g & 0xFF) * d);
|
||||
@@ -128,13 +115,11 @@ public abstract class Colour implements Copyable<Colour>
|
||||
return this;
|
||||
}
|
||||
|
||||
public Colour interpolate(Colour colour2, double d)
|
||||
{
|
||||
public Colour interpolate(Colour colour2, double d) {
|
||||
return this.add(colour2.copy().sub(this).scale(d));
|
||||
}
|
||||
|
||||
public Colour multiplyC(double d)
|
||||
{
|
||||
public Colour multiplyC(double d) {
|
||||
r = (byte) MathHelper.clip((r & 0xFF) * d, 0, 255);
|
||||
g = (byte) MathHelper.clip((g & 0xFF) * d, 0, 255);
|
||||
b = (byte) MathHelper.clip((b & 0xFF) * d, 0, 255);
|
||||
@@ -144,23 +129,19 @@ public abstract class Colour implements Copyable<Colour>
|
||||
|
||||
public abstract Colour copy();
|
||||
|
||||
public int rgb()
|
||||
{
|
||||
public int rgb() {
|
||||
return (r & 0xFF) << 16 | (g & 0xFF) << 8 | (b & 0xFF);
|
||||
}
|
||||
|
||||
public int argb()
|
||||
{
|
||||
public int argb() {
|
||||
return (a & 0xFF) << 24 | (r & 0xFF) << 16 | (g & 0xFF) << 8 | (b & 0xFF);
|
||||
}
|
||||
|
||||
public int rgba()
|
||||
{
|
||||
public int rgba() {
|
||||
return (r & 0xFF) << 24 | (g & 0xFF) << 16 | (b & 0xFF) << 8 | (a & 0xFF);
|
||||
}
|
||||
|
||||
public Colour set(Colour colour)
|
||||
{
|
||||
public Colour set(Colour colour) {
|
||||
r = colour.r;
|
||||
g = colour.g;
|
||||
b = colour.b;
|
||||
@@ -168,8 +149,7 @@ public abstract class Colour implements Copyable<Colour>
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean equals(Colour colour)
|
||||
{
|
||||
public boolean equals(Colour colour) {
|
||||
return colour != null && rgba() == colour.rgba();
|
||||
}
|
||||
}
|
||||
@@ -1,34 +1,27 @@
|
||||
package codechicken.lib.colour;
|
||||
|
||||
public class ColourARGB extends Colour
|
||||
{
|
||||
public ColourARGB(int colour)
|
||||
{
|
||||
public class ColourARGB extends Colour {
|
||||
public ColourARGB(int colour) {
|
||||
super((colour >> 16) & 0xFF, (colour >> 8) & 0xFF, colour & 0xFF, (colour >> 24) & 0xFF);
|
||||
}
|
||||
|
||||
public ColourARGB(int a, int r, int g, int b)
|
||||
{
|
||||
|
||||
public ColourARGB(int a, int r, int g, int b) {
|
||||
super(r, g, b, a);
|
||||
}
|
||||
|
||||
public ColourARGB(ColourARGB colour)
|
||||
{
|
||||
public ColourARGB(ColourARGB colour) {
|
||||
super(colour);
|
||||
}
|
||||
|
||||
public ColourARGB copy()
|
||||
{
|
||||
public ColourARGB copy() {
|
||||
return new ColourARGB(this);
|
||||
}
|
||||
|
||||
public int pack()
|
||||
{
|
||||
public int pack() {
|
||||
return pack(this);
|
||||
}
|
||||
|
||||
public static int pack(Colour colour)
|
||||
{
|
||||
return (colour.a&0xFF) << 24 | (colour.r&0xFF) << 16 | (colour.g&0xFF) << 8 | (colour.b&0xFF);
|
||||
public static int pack(Colour colour) {
|
||||
return (colour.a & 0xFF) << 24 | (colour.r & 0xFF) << 16 | (colour.g & 0xFF) << 8 | (colour.b & 0xFF);
|
||||
}
|
||||
}
|
||||
@@ -31,19 +31,19 @@ public class ColourRGBA extends Colour {
|
||||
}
|
||||
|
||||
public static int multiply(int c1, int c2) {
|
||||
if(c1 == -1) return c2;
|
||||
if(c2 == -1) return c1;
|
||||
if (c1 == -1) return c2;
|
||||
if (c2 == -1) return c1;
|
||||
int r = (((c1 >>> 24) * (c2 >>> 24)) & 0xFF00) << 16;
|
||||
int g = (((c1 >> 16 & 0xFF) * (c2 >> 16 & 0xFF)) & 0xFF00) << 8;
|
||||
int b = ((c1 >> 8 & 0xFF) * (c2 >> 8 & 0xFF)) & 0xFF00;
|
||||
int a = ((c1 & 0xFF) * (c2 & 0xFF)) >> 8;
|
||||
return r|g|b|a;
|
||||
return r | g | b | a;
|
||||
}
|
||||
|
||||
public static int multiplyC(int c, float f) {
|
||||
int r = (int) ((c >>> 24) * f);
|
||||
int g = (int) ((c >> 16 & 0xFF) * f);
|
||||
int b = (int) ((c >> 8 & 0xFF) * f);
|
||||
return r<<24 | g<<16 | b<<8 | c&0xFF;
|
||||
return r << 24 | g << 16 | b << 8 | c & 0xFF;
|
||||
}
|
||||
}
|
||||
@@ -2,35 +2,28 @@ package codechicken.lib.colour;
|
||||
|
||||
import codechicken.lib.math.MathHelper;
|
||||
import codechicken.lib.render.TextureUtils;
|
||||
import java.awt.image.BufferedImage;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
|
||||
public class CustomGradient
|
||||
{
|
||||
public class CustomGradient {
|
||||
public int[] gradient;
|
||||
|
||||
public CustomGradient(ResourceLocation textureFile)
|
||||
{
|
||||
|
||||
public CustomGradient(ResourceLocation textureFile) {
|
||||
BufferedImage img = TextureUtils.loadBufferedImage(textureFile);
|
||||
if(img == null)
|
||||
throw new RuntimeException("File not found: "+textureFile.toString());
|
||||
if (img == null) throw new RuntimeException("File not found: " + textureFile.toString());
|
||||
|
||||
int[] data = new int[img.getWidth()];
|
||||
img.getRGB(0, 0, img.getWidth(), 1, data, 0, img.getWidth());
|
||||
gradient = new int[img.getWidth()];
|
||||
for(int i = 0; i < data.length; i++)
|
||||
gradient[i] = (data[i]<<8)|(((data[i])>>24)&0xFF);
|
||||
for (int i = 0; i < data.length; i++) gradient[i] = (data[i] << 8) | (((data[i]) >> 24) & 0xFF);
|
||||
}
|
||||
|
||||
public ColourRGBA getColour(double position)
|
||||
{
|
||||
|
||||
public ColourRGBA getColour(double position) {
|
||||
return new ColourRGBA(getColourI(position));
|
||||
}
|
||||
|
||||
public int getColourI(double position)
|
||||
{
|
||||
int off = (int)MathHelper.clip(gradient.length*position, 0, gradient.length-1);
|
||||
|
||||
public int getColourI(double position) {
|
||||
int off = (int) MathHelper.clip(gradient.length * position, 0, gradient.length - 1);
|
||||
return gradient[off];
|
||||
}
|
||||
}
|
||||
@@ -2,9 +2,8 @@ package codechicken.lib.config;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
public class ConfigFile extends ConfigTagParent
|
||||
{
|
||||
public static final byte[] crlf = new byte[]{0xD, 0xA};
|
||||
public class ConfigFile extends ConfigTagParent {
|
||||
public static final byte[] crlf = new byte[] {0xD, 0xA};
|
||||
|
||||
public File file;
|
||||
private boolean loading;
|
||||
@@ -18,10 +17,8 @@ public class ConfigFile extends ConfigTagParent
|
||||
|
||||
protected void load(File file) {
|
||||
try {
|
||||
if(!file.getParentFile().exists())
|
||||
file.getParentFile().mkdirs();
|
||||
if (!file.exists())
|
||||
file.createNewFile();
|
||||
if (!file.getParentFile().exists()) file.getParentFile().mkdirs();
|
||||
if (!file.exists()) file.createNewFile();
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
@@ -39,10 +36,8 @@ public class ConfigFile extends ConfigTagParent
|
||||
reader.mark(2000);
|
||||
String line = reader.readLine();
|
||||
if (line != null && line.startsWith("#")) {
|
||||
if (comment == null || comment.equals(""))
|
||||
comment = line.substring(1);
|
||||
else
|
||||
comment = comment + "\n" + line.substring(1);
|
||||
if (comment == null || comment.equals("")) comment = line.substring(1);
|
||||
else comment = comment + "\n" + line.substring(1);
|
||||
} else {
|
||||
reader.reset();
|
||||
break;
|
||||
@@ -81,15 +76,13 @@ public class ConfigFile extends ConfigTagParent
|
||||
}
|
||||
|
||||
public static void writeLine(PrintWriter writer, String line, int tabs) {
|
||||
for (int i = 0; i < tabs; i++)
|
||||
writer.print('\t');
|
||||
for (int i = 0; i < tabs; i++) writer.print('\t');
|
||||
|
||||
writer.println(line);
|
||||
}
|
||||
|
||||
public void saveConfig() {
|
||||
if (loading)
|
||||
return;
|
||||
if (loading) return;
|
||||
|
||||
PrintWriter writer;
|
||||
try {
|
||||
|
||||
@@ -2,10 +2,8 @@ package codechicken.lib.config;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
|
||||
public class ConfigTag extends ConfigTagParent
|
||||
{
|
||||
public interface IConfigType<T>
|
||||
{
|
||||
public class ConfigTag extends ConfigTagParent {
|
||||
public interface IConfigType<T> {
|
||||
public String configValue(T entry);
|
||||
|
||||
public T valueOf(String text) throws Exception;
|
||||
@@ -81,9 +79,9 @@ public class ConfigTag extends ConfigTagParent
|
||||
|
||||
public int getIntValue(int defaultValue) {
|
||||
try {
|
||||
if (value != null)
|
||||
return getIntValue();
|
||||
} catch (NumberFormatException ignored) {}
|
||||
if (value != null) return getIntValue();
|
||||
} catch (NumberFormatException ignored) {
|
||||
}
|
||||
|
||||
setIntValue(defaultValue);
|
||||
return defaultValue;
|
||||
@@ -91,19 +89,17 @@ public class ConfigTag extends ConfigTagParent
|
||||
|
||||
public boolean getBooleanValue() {
|
||||
String value = getValue();
|
||||
if (value != null && (value.equalsIgnoreCase("true") || value.equalsIgnoreCase("yes")))
|
||||
return true;
|
||||
else if (value != null && (value.equalsIgnoreCase("false") || value.equalsIgnoreCase("no")))
|
||||
return false;
|
||||
if (value != null && (value.equalsIgnoreCase("true") || value.equalsIgnoreCase("yes"))) return true;
|
||||
else if (value != null && (value.equalsIgnoreCase("false") || value.equalsIgnoreCase("no"))) return false;
|
||||
|
||||
throw new NumberFormatException(qualifiedname + ".value=" + value);
|
||||
}
|
||||
|
||||
public boolean getBooleanValue(boolean defaultValue) {
|
||||
try {
|
||||
if (value != null)
|
||||
return getBooleanValue();
|
||||
} catch (NumberFormatException ignored) {}
|
||||
if (value != null) return getBooleanValue();
|
||||
} catch (NumberFormatException ignored) {
|
||||
}
|
||||
|
||||
setBooleanValue(defaultValue);
|
||||
return defaultValue;
|
||||
@@ -115,9 +111,9 @@ public class ConfigTag extends ConfigTagParent
|
||||
|
||||
public int getHexValue(int defaultValue) {
|
||||
try {
|
||||
if (value != null)
|
||||
return getHexValue();
|
||||
} catch (NumberFormatException ignored) {}
|
||||
if (value != null) return getHexValue();
|
||||
} catch (NumberFormatException ignored) {
|
||||
}
|
||||
|
||||
setHexValue(defaultValue);
|
||||
return defaultValue;
|
||||
@@ -133,9 +129,9 @@ public class ConfigTag extends ConfigTagParent
|
||||
|
||||
public <T> T get(IConfigType<T> type, T defaultValue) {
|
||||
try {
|
||||
if (value != null)
|
||||
return get(type);
|
||||
} catch (Exception ignored) {}
|
||||
if (value != null) return get(type);
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
|
||||
set(type, defaultValue);
|
||||
return defaultValue;
|
||||
@@ -145,22 +141,17 @@ public class ConfigTag extends ConfigTagParent
|
||||
String vname;
|
||||
if (qualifiedname.contains(".") && bracequalifier.length() > 0)
|
||||
vname = qualifiedname.substring(bracequalifier.length() + 1);
|
||||
else
|
||||
vname = qualifiedname;
|
||||
else vname = qualifiedname;
|
||||
|
||||
if (newline && !first)
|
||||
ConfigFile.writeLine(writer, "", tabs);
|
||||
if (newline && !first) ConfigFile.writeLine(writer, "", tabs);
|
||||
|
||||
writeComment(writer, tabs);
|
||||
if (value != null)
|
||||
ConfigFile.writeLine(writer, vname + "=" + value, tabs);
|
||||
if (value != null) ConfigFile.writeLine(writer, vname + "=" + value, tabs);
|
||||
|
||||
if (!hasChildTags())
|
||||
return;
|
||||
if (!hasChildTags()) return;
|
||||
|
||||
if (brace) {
|
||||
if (value == null)
|
||||
ConfigFile.writeLine(writer, vname, tabs);
|
||||
if (value == null) ConfigFile.writeLine(writer, vname, tabs);
|
||||
ConfigFile.writeLine(writer, "{", tabs);
|
||||
saveTagTree(writer, tabs + 1, qualifiedname);
|
||||
ConfigFile.writeLine(writer, "}", tabs);
|
||||
@@ -189,8 +180,7 @@ public class ConfigTag extends ConfigTagParent
|
||||
|
||||
public ConfigTag useBraces() {
|
||||
brace = true;
|
||||
if (parent.newlinemode == 1)
|
||||
newline = true;
|
||||
if (parent.newlinemode == 1) newline = true;
|
||||
|
||||
saveConfig();
|
||||
return this;
|
||||
|
||||
@@ -6,10 +6,8 @@ import java.io.PrintWriter;
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
public abstract class ConfigTagParent
|
||||
{
|
||||
public static class TagOrderComparator implements Comparator<ConfigTag>
|
||||
{
|
||||
public abstract class ConfigTagParent {
|
||||
public static class TagOrderComparator implements Comparator<ConfigTag> {
|
||||
int sortMode;
|
||||
|
||||
public TagOrderComparator(int sortMode) {
|
||||
@@ -17,18 +15,13 @@ public abstract class ConfigTagParent
|
||||
}
|
||||
|
||||
public int compare(ConfigTag o1, ConfigTag o2) {
|
||||
if (o1.position != o2.position)
|
||||
return compareInt(o1.position, o2.position);
|
||||
if (o1.brace != o2.brace)
|
||||
return o1.brace ? 1 : -1;//braced one goes after
|
||||
if (o1.position != o2.position) return compareInt(o1.position, o2.position);
|
||||
if (o1.brace != o2.brace) return o1.brace ? 1 : -1; // braced one goes after
|
||||
switch (sortMode) {
|
||||
case 1:
|
||||
if (o1.value == o2.value)
|
||||
return 0;
|
||||
if (o1.value == null)
|
||||
return 1;
|
||||
if (o2.value == null)
|
||||
return -1;
|
||||
if (o1.value == o2.value) return 0;
|
||||
if (o1.value == null) return 1;
|
||||
if (o2.value == null) return -1;
|
||||
return o1.value.compareTo(o2.value);
|
||||
default:
|
||||
return o1.name.compareTo(o2.name);
|
||||
@@ -72,12 +65,9 @@ public abstract class ConfigTagParent
|
||||
newlinemode = mode;
|
||||
for (Entry<String, ConfigTag> entry : childtags.entrySet()) {
|
||||
ConfigTag tag = entry.getValue();
|
||||
if (newlinemode == 0)
|
||||
tag.newline = false;
|
||||
else if (newlinemode == 1)
|
||||
tag.newline = tag.brace;
|
||||
else if (newlinemode == 2)
|
||||
tag.newline = true;
|
||||
if (newlinemode == 0) tag.newline = false;
|
||||
else if (newlinemode == 1) tag.newline = tag.brace;
|
||||
else if (newlinemode == 2) tag.newline = true;
|
||||
}
|
||||
saveConfig();
|
||||
return this;
|
||||
@@ -104,14 +94,12 @@ public abstract class ConfigTagParent
|
||||
String basetagname = dotpos == -1 ? tagname : tagname.substring(0, dotpos);
|
||||
ConfigTag basetag = childtags.get(basetagname);
|
||||
if (basetag == null) {
|
||||
if (!create)
|
||||
return null;
|
||||
if (!create) return null;
|
||||
|
||||
basetag = getNewTag(basetagname);
|
||||
saveConfig();
|
||||
}
|
||||
if (dotpos == -1)
|
||||
return basetag;
|
||||
if (dotpos == -1) return basetag;
|
||||
|
||||
return basetag.getTag(tagname.substring(dotpos + 1), create);
|
||||
}
|
||||
@@ -122,15 +110,13 @@ public abstract class ConfigTagParent
|
||||
|
||||
public boolean removeTag(String tagname) {
|
||||
ConfigTag tag = getTag(tagname, false);
|
||||
if (tag == null)
|
||||
return false;
|
||||
if (tag == null) return false;
|
||||
|
||||
int dotpos = tagname.lastIndexOf(".");
|
||||
String lastpart = dotpos == -1 ? tagname : tagname.substring(dotpos + 1, tagname.length());
|
||||
if (tag.parent != null) {
|
||||
boolean ret = tag.parent.childtags.remove(lastpart) != null;
|
||||
if (ret)
|
||||
saveConfig();
|
||||
if (ret) saveConfig();
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -143,8 +129,7 @@ public abstract class ConfigTagParent
|
||||
|
||||
public <T extends ConfigTag> ArrayList<T> getSortedTagList() {
|
||||
ArrayList<T> taglist = new ArrayList<T>(childtags.size());
|
||||
for (Entry<String, ConfigTag> tag : childtags.entrySet())
|
||||
taglist.add((T) tag.getValue());
|
||||
for (Entry<String, ConfigTag> tag : childtags.entrySet()) taglist.add((T) tag.getValue());
|
||||
|
||||
Collections.sort(taglist, new TagOrderComparator(sortMode));
|
||||
return taglist;
|
||||
@@ -156,13 +141,10 @@ public abstract class ConfigTagParent
|
||||
try {
|
||||
while (true) {
|
||||
String line = ConfigFile.readLine(reader);
|
||||
if (line == null)
|
||||
break;
|
||||
if (line == null) break;
|
||||
if (line.startsWith("#")) {
|
||||
if (comment.equals(""))
|
||||
comment = line.substring(1);
|
||||
else
|
||||
comment = comment + "\n" + line.substring(1);
|
||||
if (comment.equals("")) comment = line.substring(1);
|
||||
else comment = comment + "\n" + line.substring(1);
|
||||
} else if (line.contains("=")) {
|
||||
String qualifiedname = line.substring(0, line.indexOf("="));
|
||||
getTag(qualifiedname)
|
||||
@@ -197,8 +179,7 @@ public abstract class ConfigTagParent
|
||||
public void writeComment(PrintWriter writer, int tabs) {
|
||||
if (comment != null && !comment.equals("")) {
|
||||
String[] comments = comment.split("\n");
|
||||
for (int i = 0; i < comments.length; i++)
|
||||
ConfigFile.writeLine(writer, "#" + comments[i], tabs);
|
||||
for (int i = 0; i < comments.length; i++) ConfigFile.writeLine(writer, "#" + comments[i], tabs);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,17 +2,14 @@ package codechicken.lib.config;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class DefaultingConfigFile extends ConfigFile
|
||||
{
|
||||
public class DefaultingConfigFile extends ConfigFile {
|
||||
public DefaultingConfigFile(File file) {
|
||||
super();
|
||||
if(file.exists())
|
||||
load(file);
|
||||
if (file.exists()) load(file);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveConfig() {
|
||||
if(file != null)
|
||||
super.saveConfig();
|
||||
if (file != null) super.saveConfig();
|
||||
}
|
||||
}
|
||||
@@ -5,142 +5,116 @@ import java.nio.charset.Charset;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
public class SimpleProperties
|
||||
{
|
||||
public class SimpleProperties {
|
||||
public HashMap<String, String> propertyMap = new HashMap<String, String>();
|
||||
public File propertyFile;
|
||||
public boolean saveOnChange = false;
|
||||
public String encoding;
|
||||
|
||||
|
||||
private boolean loading = false;
|
||||
|
||||
public SimpleProperties(File file, boolean saveOnChange, String encoding)
|
||||
{
|
||||
|
||||
public SimpleProperties(File file, boolean saveOnChange, String encoding) {
|
||||
propertyFile = file;
|
||||
this.saveOnChange = saveOnChange;
|
||||
this.encoding = encoding;
|
||||
}
|
||||
|
||||
public SimpleProperties(File file, boolean saveOnChange)
|
||||
{
|
||||
|
||||
public SimpleProperties(File file, boolean saveOnChange) {
|
||||
this(file, saveOnChange, Charset.defaultCharset().name());
|
||||
}
|
||||
|
||||
public SimpleProperties(File file)
|
||||
{
|
||||
|
||||
public SimpleProperties(File file) {
|
||||
this(file, true);
|
||||
}
|
||||
|
||||
public void load()
|
||||
{
|
||||
|
||||
public void load() {
|
||||
clear();
|
||||
loading = true;
|
||||
|
||||
try
|
||||
{
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(propertyFile), encoding));
|
||||
while(true)
|
||||
{
|
||||
|
||||
try {
|
||||
BufferedReader reader =
|
||||
new BufferedReader(new InputStreamReader(new FileInputStream(propertyFile), encoding));
|
||||
while (true) {
|
||||
String read = reader.readLine();
|
||||
if(read == null)
|
||||
break;
|
||||
if (read == null) break;
|
||||
|
||||
int equalIndex = read.indexOf('=');
|
||||
if(equalIndex == -1)
|
||||
continue;
|
||||
|
||||
setProperty(read.substring(0, equalIndex), read.substring(equalIndex+1));
|
||||
if (equalIndex == -1) continue;
|
||||
|
||||
setProperty(read.substring(0, equalIndex), read.substring(equalIndex + 1));
|
||||
}
|
||||
reader.close();
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
loading = false;
|
||||
}
|
||||
|
||||
public void save()
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
public void save() {
|
||||
try {
|
||||
PrintStream writer = new PrintStream(propertyFile);
|
||||
|
||||
for(Entry<String, String> entry : propertyMap.entrySet())
|
||||
{
|
||||
writer.println(entry.getKey()+"="+entry.getValue());
|
||||
|
||||
for (Entry<String, String> entry : propertyMap.entrySet()) {
|
||||
writer.println(entry.getKey() + "=" + entry.getValue());
|
||||
}
|
||||
|
||||
|
||||
writer.close();
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void clear()
|
||||
{
|
||||
|
||||
public void clear() {
|
||||
propertyMap.clear();
|
||||
}
|
||||
|
||||
public boolean hasProperty(String key)
|
||||
{
|
||||
|
||||
public boolean hasProperty(String key) {
|
||||
return propertyMap.containsKey(key);
|
||||
}
|
||||
|
||||
public void removeProperty(String key)
|
||||
{
|
||||
if(propertyMap.remove(key) != null && saveOnChange && !loading)
|
||||
save();
|
||||
|
||||
public void removeProperty(String key) {
|
||||
if (propertyMap.remove(key) != null && saveOnChange && !loading) save();
|
||||
}
|
||||
|
||||
public void setProperty(String key, int value)
|
||||
{
|
||||
|
||||
public void setProperty(String key, int value) {
|
||||
setProperty(key, Integer.toString(value));
|
||||
}
|
||||
|
||||
public void setProperty(String key, boolean value)
|
||||
{
|
||||
|
||||
public void setProperty(String key, boolean value) {
|
||||
setProperty(key, Boolean.toString(value));
|
||||
}
|
||||
|
||||
public void setProperty(String key, String value)
|
||||
{
|
||||
|
||||
public void setProperty(String key, String value) {
|
||||
propertyMap.put(key, value);
|
||||
if(saveOnChange && !loading)
|
||||
save();
|
||||
if (saveOnChange && !loading) save();
|
||||
}
|
||||
|
||||
public int getProperty(String property, int defaultvalue)
|
||||
{
|
||||
|
||||
public int getProperty(String property, int defaultvalue) {
|
||||
try {
|
||||
return Integer.parseInt(getProperty(property, Integer.toString(defaultvalue)));
|
||||
} catch(NumberFormatException nfe)
|
||||
{return defaultvalue;}
|
||||
} catch (NumberFormatException nfe) {
|
||||
return defaultvalue;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean getProperty(String property, boolean defaultvalue)
|
||||
{
|
||||
|
||||
public boolean getProperty(String property, boolean defaultvalue) {
|
||||
try {
|
||||
return Boolean.parseBoolean(getProperty(property, Boolean.toString(defaultvalue)));
|
||||
} catch(NumberFormatException nfe)
|
||||
{return defaultvalue;}
|
||||
} catch (NumberFormatException nfe) {
|
||||
return defaultvalue;
|
||||
}
|
||||
}
|
||||
|
||||
public String getProperty(String property, String defaultvalue)
|
||||
{
|
||||
|
||||
public String getProperty(String property, String defaultvalue) {
|
||||
String value = propertyMap.get(property);
|
||||
if(value == null)
|
||||
{
|
||||
if (value == null) {
|
||||
setProperty(property, defaultvalue);
|
||||
return defaultvalue;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
public String getProperty(String property)
|
||||
{
|
||||
|
||||
public String getProperty(String property) {
|
||||
return propertyMap.get(property);
|
||||
}
|
||||
}
|
||||
@@ -5,24 +5,40 @@ import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraftforge.fluids.FluidStack;
|
||||
|
||||
public interface MCDataInput
|
||||
{
|
||||
public interface MCDataInput {
|
||||
public long readLong();
|
||||
|
||||
public int readInt();
|
||||
|
||||
public short readShort();
|
||||
|
||||
public int readUShort();
|
||||
|
||||
public byte readByte();
|
||||
|
||||
public short readUByte();
|
||||
|
||||
public double readDouble();
|
||||
|
||||
public float readFloat();
|
||||
|
||||
public boolean readBoolean();
|
||||
|
||||
public char readChar();
|
||||
|
||||
public int readVarShort();
|
||||
|
||||
public int readVarInt();
|
||||
|
||||
public byte[] readByteArray(int length);
|
||||
|
||||
public String readString();
|
||||
|
||||
public BlockCoord readCoord();
|
||||
|
||||
public NBTTagCompound readNBTTagCompound();
|
||||
|
||||
public ItemStack readItemStack();
|
||||
|
||||
public FluidStack readFluidStack();
|
||||
}
|
||||
@@ -2,18 +2,15 @@ package codechicken.lib.data;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
public class MCDataInputStream extends InputStream
|
||||
{
|
||||
public class MCDataInputStream extends InputStream {
|
||||
private MCDataInput in;
|
||||
|
||||
public MCDataInputStream(MCDataInput in)
|
||||
{
|
||||
|
||||
public MCDataInputStream(MCDataInput in) {
|
||||
this.in = in;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int read()
|
||||
{
|
||||
return in.readByte()&0xFF;
|
||||
public int read() {
|
||||
return in.readByte() & 0xFF;
|
||||
}
|
||||
}
|
||||
@@ -5,23 +5,38 @@ import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraftforge.fluids.FluidStack;
|
||||
|
||||
public interface MCDataOutput
|
||||
{
|
||||
public interface MCDataOutput {
|
||||
public MCDataOutput writeLong(long l);
|
||||
|
||||
public MCDataOutput writeInt(int i);
|
||||
|
||||
public MCDataOutput writeShort(int s);
|
||||
|
||||
public MCDataOutput writeByte(int b);
|
||||
|
||||
public MCDataOutput writeDouble(double d);
|
||||
|
||||
public MCDataOutput writeFloat(float f);
|
||||
|
||||
public MCDataOutput writeBoolean(boolean b);
|
||||
|
||||
public MCDataOutput writeChar(char c);
|
||||
|
||||
public MCDataOutput writeVarInt(int i);
|
||||
|
||||
public MCDataOutput writeVarShort(int s);
|
||||
|
||||
public MCDataOutput writeByteArray(byte[] array);
|
||||
|
||||
public MCDataOutput writeString(String s);
|
||||
|
||||
public MCDataOutput writeCoord(int x, int y, int z);
|
||||
|
||||
public MCDataOutput writeCoord(BlockCoord coord);
|
||||
|
||||
public MCDataOutput writeNBTTagCompound(NBTTagCompound tag);
|
||||
|
||||
public MCDataOutput writeItemStack(ItemStack stack);
|
||||
|
||||
public MCDataOutput writeFluidStack(FluidStack liquid);
|
||||
}
|
||||
@@ -2,18 +2,15 @@ package codechicken.lib.data;
|
||||
|
||||
import java.io.OutputStream;
|
||||
|
||||
public class MCDataOutputStream extends OutputStream
|
||||
{
|
||||
public class MCDataOutputStream extends OutputStream {
|
||||
private MCDataOutput out;
|
||||
|
||||
public MCDataOutputStream(MCDataOutput out)
|
||||
{
|
||||
|
||||
public MCDataOutputStream(MCDataOutput out) {
|
||||
this.out = out;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void write(int b)
|
||||
{
|
||||
public void write(int b) {
|
||||
out.writeByte(b);
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,8 @@ package codechicken.lib.data;
|
||||
import codechicken.lib.vec.BlockCoord;
|
||||
import com.google.common.base.Charsets;
|
||||
import cpw.mods.fml.common.network.ByteBufUtils;
|
||||
import java.io.DataOutput;
|
||||
import java.io.IOException;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.CompressedStreamTools;
|
||||
@@ -10,11 +12,7 @@ import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraftforge.fluids.FluidStack;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
|
||||
import java.io.DataOutput;
|
||||
import java.io.IOException;
|
||||
|
||||
public class MCDataOutputWrapper implements MCDataOutput
|
||||
{
|
||||
public class MCDataOutputWrapper implements MCDataOutput {
|
||||
/**
|
||||
* Mimics ByteBufUtils
|
||||
* Write an integer using variable length encoding.
|
||||
@@ -41,11 +39,9 @@ public class MCDataOutputWrapper implements MCDataOutput
|
||||
public static void writeVarShort(DataOutput to, int s) throws IOException {
|
||||
int low = s & 0x7FFF;
|
||||
int high = (s & 0x7F8000) >> 15;
|
||||
if (high != 0)
|
||||
low |= 0x8000;
|
||||
if (high != 0) low |= 0x8000;
|
||||
to.writeShort(low);
|
||||
if (high != 0)
|
||||
to.writeByte(high);
|
||||
if (high != 0) to.writeByte(high);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -57,7 +53,8 @@ public class MCDataOutputWrapper implements MCDataOutput
|
||||
*/
|
||||
public static void writeUTF8String(DataOutput to, String string) throws IOException {
|
||||
byte[] utf8Bytes = string.getBytes(Charsets.UTF_8);
|
||||
Validate.isTrue(ByteBufUtils.varIntByteCount(utf8Bytes.length) < 3, "The string is too long for this encoding.");
|
||||
Validate.isTrue(
|
||||
ByteBufUtils.varIntByteCount(utf8Bytes.length) < 3, "The string is too long for this encoding.");
|
||||
writeVarInt(to, utf8Bytes.length);
|
||||
to.write(utf8Bytes);
|
||||
}
|
||||
@@ -203,10 +200,8 @@ public class MCDataOutputWrapper implements MCDataOutput
|
||||
writeShort(-1);
|
||||
} else {
|
||||
writeShort(Item.getIdFromItem(stack.getItem()));
|
||||
if (large)
|
||||
writeInt(stack.stackSize);
|
||||
else
|
||||
writeByte(stack.stackSize);
|
||||
if (large) writeInt(stack.stackSize);
|
||||
else writeByte(stack.stackSize);
|
||||
writeShort(stack.getItemDamage());
|
||||
writeNBTTagCompound(stack.stackTagCompound);
|
||||
}
|
||||
|
||||
@@ -6,8 +6,7 @@ import codechicken.lib.render.TextureUtils;
|
||||
import net.minecraft.client.renderer.Tessellator;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
|
||||
public class Canvas9Seg
|
||||
{
|
||||
public class Canvas9Seg {
|
||||
public final ResourceLocation tex;
|
||||
public float[] seg_u = new float[4];
|
||||
public float[] seg_v = new float[4];
|
||||
@@ -24,12 +23,11 @@ public class Canvas9Seg
|
||||
|
||||
int marker = 1;
|
||||
int prev_col = data.data[0];
|
||||
for(int i = 1; i < size; i++) {
|
||||
if(data.data[i*stride] != prev_col) {
|
||||
for (int i = 1; i < size; i++) {
|
||||
if (data.data[i * stride] != prev_col) {
|
||||
markers[marker] = i;
|
||||
prev_col = data.data[i*stride];
|
||||
if(++marker == 4)
|
||||
break;
|
||||
prev_col = data.data[i * stride];
|
||||
if (++marker == 4) break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,10 +38,9 @@ public class Canvas9Seg
|
||||
|
||||
private void parseMarkers(TextureDataHolder data, int stride, int size, int[] sizes, float[] texcoords) {
|
||||
int[] markers = readMarkers(data, stride, size);
|
||||
for(int i = 0; i < 4; i++) {
|
||||
texcoords[i] = markers[i]/(float)size;
|
||||
if(i > 0)
|
||||
sizes[i-1] = markers[i]-markers[i-1];
|
||||
for (int i = 0; i < 4; i++) {
|
||||
texcoords[i] = markers[i] / (float) size;
|
||||
if (i > 0) sizes[i - 1] = markers[i] - markers[i - 1];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,11 +52,12 @@ public class Canvas9Seg
|
||||
|
||||
private void drawSeg(int[] sw, int[] sh, int seg) {
|
||||
Tessellator t = Tessellator.instance;
|
||||
int u = seg%3; int v = seg/3;
|
||||
int u = seg % 3;
|
||||
int v = seg / 3;
|
||||
t.addVertexWithUV(sw[u], sh[v], 0, seg_u[u], seg_v[v]);
|
||||
t.addVertexWithUV(sw[u], sh[v+1], 0, seg_u[u], seg_v[v+1]);
|
||||
t.addVertexWithUV(sw[u+1], sh[v+1], 0, seg_u[u+1], seg_v[v+1]);
|
||||
t.addVertexWithUV(sw[u+1], sh[v], 0, seg_u[u+1], seg_v[v]);
|
||||
t.addVertexWithUV(sw[u], sh[v + 1], 0, seg_u[u], seg_v[v + 1]);
|
||||
t.addVertexWithUV(sw[u + 1], sh[v + 1], 0, seg_u[u + 1], seg_v[v + 1]);
|
||||
t.addVertexWithUV(sw[u + 1], sh[v], 0, seg_u[u + 1], seg_v[v]);
|
||||
}
|
||||
|
||||
public void draw(int x, int y, int w, int h) {
|
||||
@@ -67,11 +65,10 @@ public class Canvas9Seg
|
||||
CCRenderState.reset();
|
||||
CCRenderState.startDrawing();
|
||||
|
||||
int[] sw = new int[]{x, x+seg_w[0], x+w-seg_w[2], x+w};
|
||||
int[] sh = new int[]{y, y+seg_h[0], y+h-seg_h[2], y+h};
|
||||
int[] sw = new int[] {x, x + seg_w[0], x + w - seg_w[2], x + w};
|
||||
int[] sh = new int[] {y, y + seg_h[0], y + h - seg_h[2], y + h};
|
||||
|
||||
for(int seg = 0; seg < 9; seg++)
|
||||
drawSeg(sw, sh, seg);
|
||||
for (int seg = 0; seg < 9; seg++) drawSeg(sw, sh, seg);
|
||||
|
||||
CCRenderState.draw();
|
||||
}
|
||||
|
||||
@@ -2,27 +2,23 @@ package codechicken.lib.gui;
|
||||
|
||||
import codechicken.lib.math.MathHelper;
|
||||
import codechicken.lib.render.CCRenderState;
|
||||
import java.awt.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.FontRenderer;
|
||||
import net.minecraft.client.gui.Gui;
|
||||
import net.minecraft.client.gui.ScaledResolution;
|
||||
import net.minecraft.client.renderer.RenderHelper;
|
||||
import net.minecraft.client.renderer.texture.TextureManager;
|
||||
import net.minecraft.util.EnumChatFormatting;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import org.lwjgl.input.Mouse;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
import org.lwjgl.opengl.GL12;
|
||||
|
||||
import java.awt.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class GuiDraw
|
||||
{
|
||||
public static class GuiHook extends Gui
|
||||
{
|
||||
public class GuiDraw {
|
||||
public static class GuiHook extends Gui {
|
||||
public void setZLevel(float f) {
|
||||
zLevel = f;
|
||||
}
|
||||
@@ -58,10 +54,8 @@ public class GuiDraw
|
||||
}
|
||||
|
||||
public static void drawString(String text, int x, int y, int colour, boolean shadow) {
|
||||
if (shadow)
|
||||
fontRenderer.drawStringWithShadow(text, x, y, colour);
|
||||
else
|
||||
fontRenderer.drawString(text, x, y, colour);
|
||||
if (shadow) fontRenderer.drawStringWithShadow(text, x, y, colour);
|
||||
else fontRenderer.drawString(text, x, y, colour);
|
||||
}
|
||||
|
||||
public static void drawString(String text, int x, int y, int colour) {
|
||||
@@ -137,10 +131,10 @@ public class GuiDraw
|
||||
* Have a string in the tooltip list with TOOLTIP_HANDLER + getTipLineId(handler) for a custom handler
|
||||
*/
|
||||
public static final String TOOLTIP_HANDLER = "\u00A7x";
|
||||
|
||||
private static List<ITooltipLineHandler> tipLineHandlers = new ArrayList<ITooltipLineHandler>();
|
||||
|
||||
public static interface ITooltipLineHandler
|
||||
{
|
||||
public static interface ITooltipLineHandler {
|
||||
public Dimension getSize();
|
||||
|
||||
public void draw(int x, int y);
|
||||
@@ -148,12 +142,11 @@ public class GuiDraw
|
||||
|
||||
public static int getTipLineId(ITooltipLineHandler handler) {
|
||||
tipLineHandlers.add(handler);
|
||||
return tipLineHandlers.size()-1;
|
||||
return tipLineHandlers.size() - 1;
|
||||
}
|
||||
|
||||
public static ITooltipLineHandler getTipLine(String line) {
|
||||
if(!line.startsWith(TOOLTIP_HANDLER))
|
||||
return null;
|
||||
if (!line.startsWith(TOOLTIP_HANDLER)) return null;
|
||||
return tipLineHandlers.get(Integer.parseInt(line.substring(2)));
|
||||
}
|
||||
|
||||
@@ -162,8 +155,7 @@ public class GuiDraw
|
||||
}
|
||||
|
||||
public static void drawMultilineTip(FontRenderer font, int x, int y, List<String> list) {
|
||||
if (list.isEmpty())
|
||||
return;
|
||||
if (list.isEmpty()) return;
|
||||
|
||||
GL11.glDisable(GL12.GL_RESCALE_NORMAL);
|
||||
GL11.glDisable(GL11.GL_DEPTH_TEST);
|
||||
@@ -174,17 +166,19 @@ public class GuiDraw
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
String s = list.get(i);
|
||||
ITooltipLineHandler line = getTipLine(s);
|
||||
Dimension d = line != null ?
|
||||
line.getSize() :
|
||||
new Dimension(font.getStringWidth(s), list.get(i).endsWith(TOOLTIP_LINESPACE) && i + 1 < list.size() ? 12 : 10);
|
||||
Dimension d = line != null
|
||||
? line.getSize()
|
||||
: new Dimension(
|
||||
font.getStringWidth(s),
|
||||
list.get(i).endsWith(TOOLTIP_LINESPACE) && i + 1 < list.size() ? 12 : 10);
|
||||
w = Math.max(w, d.width);
|
||||
h += d.height;
|
||||
}
|
||||
|
||||
if (x < 8) x = 8;
|
||||
else if (x > displaySize().width - w - 8) {
|
||||
x -= 24 + w;//flip side of cursor
|
||||
if(x < 8) x = 8;
|
||||
x -= 24 + w; // flip side of cursor
|
||||
if (x < 8) x = 8;
|
||||
}
|
||||
y = (int) MathHelper.clip(y, 8, displaySize().height - 8 - h);
|
||||
|
||||
@@ -192,11 +186,10 @@ public class GuiDraw
|
||||
drawTooltipBox(x - 4, y - 4, w + 7, h + 7);
|
||||
for (String s : list) {
|
||||
ITooltipLineHandler line = getTipLine(s);
|
||||
if(line != null) {
|
||||
if (line != null) {
|
||||
line.draw(x, y);
|
||||
y += line.getSize().height;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
font.drawStringWithShadow(s, x, y, -1);
|
||||
y += s.endsWith(TOOLTIP_LINESPACE) ? 12 : 10;
|
||||
}
|
||||
@@ -214,7 +207,7 @@ public class GuiDraw
|
||||
int bg = 0xf0100010;
|
||||
drawGradientRect(x + 1, y, w - 1, 1, bg, bg);
|
||||
drawGradientRect(x + 1, y + h, w - 1, 1, bg, bg);
|
||||
drawGradientRect(x + 1, y + 1, w - 1, h - 1, bg, bg);//center
|
||||
drawGradientRect(x + 1, y + 1, w - 1, h - 1, bg, bg); // center
|
||||
drawGradientRect(x, y + 1, 1, h - 1, bg, bg);
|
||||
drawGradientRect(x + w, y + 1, 1, h - 1, bg, bg);
|
||||
int grad1 = 0x505000ff;
|
||||
|
||||
@@ -1,22 +1,21 @@
|
||||
package codechicken.lib.inventory;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import codechicken.lib.packet.PacketCustom;
|
||||
import codechicken.lib.packet.PacketCustom.IClientPacketHandler;
|
||||
import codechicken.lib.packet.PacketCustom.IServerPacketHandler;
|
||||
import cpw.mods.fml.common.FMLCommonHandler;
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.inventory.Container;
|
||||
import net.minecraft.inventory.ICrafting;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraft.entity.player.InventoryPlayer;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.inventory.Container;
|
||||
import net.minecraft.inventory.ICrafting;
|
||||
import net.minecraft.inventory.Slot;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.network.play.INetHandlerPlayClient;
|
||||
import net.minecraft.network.play.INetHandlerPlayServer;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
@@ -26,37 +25,30 @@ import org.apache.logging.log4j.LogManager;
|
||||
* Easy shift-click handling.
|
||||
* Hooks for slot clicks, large stack sizes and some networking.
|
||||
*/
|
||||
public abstract class ContainerExtended extends Container implements ICrafting
|
||||
{
|
||||
public abstract class ContainerExtended extends Container implements ICrafting {
|
||||
private static final String netChannel = "CCL:Container";
|
||||
private static int nextNetworkID = 0;
|
||||
|
||||
static {
|
||||
PacketCustom.assignHandler(netChannel, new IClientPacketHandler()
|
||||
{
|
||||
PacketCustom.assignHandler(netChannel, new IClientPacketHandler() {
|
||||
@Override
|
||||
public void handlePacket(PacketCustom packet, Minecraft mc, INetHandlerPlayClient handler) {
|
||||
Container cont = mc.thePlayer.openContainer;
|
||||
if(!(cont instanceof ContainerExtended))
|
||||
return;
|
||||
if (!(cont instanceof ContainerExtended)) return;
|
||||
|
||||
ContainerExtended c = (ContainerExtended)cont;
|
||||
if(packet.getType() == 1)
|
||||
c.netID = packet.readInt();
|
||||
else if(c.netID == packet.readInt())
|
||||
c.handleClientPacket(packet);
|
||||
ContainerExtended c = (ContainerExtended) cont;
|
||||
if (packet.getType() == 1) c.netID = packet.readInt();
|
||||
else if (c.netID == packet.readInt()) c.handleClientPacket(packet);
|
||||
}
|
||||
});
|
||||
PacketCustom.assignHandler(netChannel, new IServerPacketHandler()
|
||||
{
|
||||
PacketCustom.assignHandler(netChannel, new IServerPacketHandler() {
|
||||
@Override
|
||||
public void handlePacket(PacketCustom packet, EntityPlayerMP sender, INetHandlerPlayServer handler) {
|
||||
Container cont = sender.openContainer;
|
||||
if(!(cont instanceof ContainerExtended))
|
||||
return;
|
||||
if (!(cont instanceof ContainerExtended)) return;
|
||||
|
||||
ContainerExtended c = (ContainerExtended)cont;
|
||||
if(c.netID == packet.readInt())
|
||||
c.handleServerPacket(packet);
|
||||
ContainerExtended c = (ContainerExtended) cont;
|
||||
if (c.netID == packet.readInt()) c.handleServerPacket(packet);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -66,8 +58,7 @@ public abstract class ContainerExtended extends Container implements ICrafting
|
||||
|
||||
public ContainerExtended() {
|
||||
crafters.add(this);
|
||||
if(FMLCommonHandler.instance().getEffectiveSide() == Side.SERVER)
|
||||
netID = ++nextNetworkID;
|
||||
if (FMLCommonHandler.instance().getEffectiveSide() == Side.SERVER) netID = ++nextNetworkID;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -77,23 +68,18 @@ public abstract class ContainerExtended extends Container implements ICrafting
|
||||
sendNetID((EntityPlayerMP) icrafting);
|
||||
sendContainerAndContentsToPlayer(this, getInventory(), Arrays.asList((EntityPlayerMP) icrafting));
|
||||
detectAndSendChanges();
|
||||
} else
|
||||
super.addCraftingToCrafters(icrafting);
|
||||
} else super.addCraftingToCrafters(icrafting);
|
||||
}
|
||||
|
||||
private void sendNetID(EntityPlayerMP player) {
|
||||
if(netID == 0)
|
||||
LogManager.getLogger("CodeChickenLib").error("Player added to container with 0 network ID");
|
||||
else
|
||||
new PacketCustom(netChannel, 1).writeInt(netID).sendToPlayer(player);
|
||||
if (netID == 0) LogManager.getLogger("CodeChickenLib").error("Player added to container with 0 network ID");
|
||||
else new PacketCustom(netChannel, 1).writeInt(netID).sendToPlayer(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeCraftingFromCrafters(ICrafting icrafting) {
|
||||
if (icrafting instanceof EntityPlayerMP)
|
||||
playerCrafters.remove(icrafting);
|
||||
else
|
||||
super.removeCraftingFromCrafters(icrafting);
|
||||
if (icrafting instanceof EntityPlayerMP) playerCrafters.remove(icrafting);
|
||||
else super.removeCraftingFromCrafters(icrafting);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -101,51 +87,43 @@ public abstract class ContainerExtended extends Container implements ICrafting
|
||||
sendContainerAndContentsToPlayer(container, list, playerCrafters);
|
||||
}
|
||||
|
||||
public void sendContainerAndContentsToPlayer(Container container, List<ItemStack> list, List<EntityPlayerMP> playerCrafters) {
|
||||
public void sendContainerAndContentsToPlayer(
|
||||
Container container, List<ItemStack> list, List<EntityPlayerMP> playerCrafters) {
|
||||
LinkedList<ItemStack> largeStacks = new LinkedList<ItemStack>();
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
ItemStack stack = list.get(i);
|
||||
if (stack != null && stack.stackSize > Byte.MAX_VALUE) {
|
||||
list.set(i, null);
|
||||
largeStacks.add(stack);
|
||||
} else
|
||||
largeStacks.add(null);
|
||||
} else largeStacks.add(null);
|
||||
}
|
||||
|
||||
for (EntityPlayerMP player : playerCrafters)
|
||||
player.sendContainerAndContentsToPlayer(container, list);
|
||||
for (EntityPlayerMP player : playerCrafters) player.sendContainerAndContentsToPlayer(container, list);
|
||||
|
||||
for (int i = 0; i < largeStacks.size(); i++) {
|
||||
ItemStack stack = largeStacks.get(i);
|
||||
if (stack != null)
|
||||
sendLargeStack(stack, i, playerCrafters);
|
||||
if (stack != null) sendLargeStack(stack, i, playerCrafters);
|
||||
}
|
||||
}
|
||||
|
||||
public void sendLargeStack(ItemStack stack, int slot, List<EntityPlayerMP> players) {
|
||||
}
|
||||
public void sendLargeStack(ItemStack stack, int slot, List<EntityPlayerMP> players) {}
|
||||
|
||||
@Override
|
||||
public void sendProgressBarUpdate(Container container, int i, int j) {
|
||||
for (EntityPlayerMP player : playerCrafters)
|
||||
player.sendProgressBarUpdate(container, i, j);
|
||||
for (EntityPlayerMP player : playerCrafters) player.sendProgressBarUpdate(container, i, j);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendSlotContents(Container container, int slot, ItemStack stack) {
|
||||
if (stack != null && stack.stackSize > Byte.MAX_VALUE)
|
||||
sendLargeStack(stack, slot, playerCrafters);
|
||||
else
|
||||
for (EntityPlayerMP player : playerCrafters)
|
||||
player.sendSlotContents(container, slot, stack);
|
||||
if (stack != null && stack.stackSize > Byte.MAX_VALUE) sendLargeStack(stack, slot, playerCrafters);
|
||||
else for (EntityPlayerMP player : playerCrafters) player.sendSlotContents(container, slot, stack);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack slotClick(int par1, int par2, int par3, EntityPlayer player) {
|
||||
if (par1 >= 0 && par1 < inventorySlots.size()) {
|
||||
Slot slot = getSlot(par1);
|
||||
if (slot instanceof SlotHandleClicks)
|
||||
return ((SlotHandleClicks) slot).slotClick(this, player, par2, par3);
|
||||
if (slot instanceof SlotHandleClicks) return ((SlotHandleClicks) slot).slotClick(this, player, par2, par3);
|
||||
}
|
||||
return super.slotClick(par1, par2, par3, player);
|
||||
}
|
||||
@@ -159,13 +137,10 @@ public abstract class ContainerExtended extends Container implements ICrafting
|
||||
ItemStack stack = slot.getStack();
|
||||
transferredStack = stack.copy();
|
||||
|
||||
if (!doMergeStackAreas(slotIndex, stack))
|
||||
return null;
|
||||
if (!doMergeStackAreas(slotIndex, stack)) return null;
|
||||
|
||||
if (stack.stackSize == 0)
|
||||
slot.putStack(null);
|
||||
else
|
||||
slot.onSlotChanged();
|
||||
if (stack.stackSize == 0) slot.putStack(null);
|
||||
else slot.onSlotChanged();
|
||||
}
|
||||
|
||||
return transferredStack;
|
||||
@@ -176,18 +151,18 @@ public abstract class ContainerExtended extends Container implements ICrafting
|
||||
boolean merged = false;
|
||||
int slotIndex = reverse ? endIndex - 1 : startIndex;
|
||||
|
||||
if (stack == null)
|
||||
return false;
|
||||
if (stack == null) return false;
|
||||
|
||||
if (stack.isStackable())//search for stacks to increase
|
||||
if (stack.isStackable()) // search for stacks to increase
|
||||
{
|
||||
while (stack.stackSize > 0 && (reverse ? slotIndex >= startIndex : slotIndex < endIndex)) {
|
||||
Slot slot = (Slot) inventorySlots.get(slotIndex);
|
||||
ItemStack slotStack = slot.getStack();
|
||||
|
||||
if (slotStack != null && slotStack.getItem() == stack.getItem() &&
|
||||
(!stack.getHasSubtypes() || stack.getItemDamage() == slotStack.getItemDamage()) &&
|
||||
ItemStack.areItemStackTagsEqual(stack, slotStack)) {
|
||||
if (slotStack != null
|
||||
&& slotStack.getItem() == stack.getItem()
|
||||
&& (!stack.getHasSubtypes() || stack.getItemDamage() == slotStack.getItemDamage())
|
||||
&& ItemStack.areItemStackTagsEqual(stack, slotStack)) {
|
||||
int totalStackSize = slotStack.stackSize + stack.stackSize;
|
||||
int maxStackSize = Math.min(stack.getMaxStackSize(), slot.getSlotStackLimit());
|
||||
if (totalStackSize <= maxStackSize) {
|
||||
@@ -207,7 +182,7 @@ public abstract class ContainerExtended extends Container implements ICrafting
|
||||
}
|
||||
}
|
||||
|
||||
if (stack.stackSize > 0)//normal transfer :)
|
||||
if (stack.stackSize > 0) // normal transfer :)
|
||||
{
|
||||
slotIndex = reverse ? endIndex - 1 : startIndex;
|
||||
|
||||
@@ -253,8 +228,7 @@ public abstract class ContainerExtended extends Container implements ICrafting
|
||||
for (int row = 0; row < 3; row++)
|
||||
for (int col = 0; col < 9; col++)
|
||||
addSlotToContainer(new Slot(inventoryPlayer, col + row * 9 + 9, x + col * 18, y + row * 18));
|
||||
for (int slot = 0; slot < 9; slot++)
|
||||
addSlotToContainer(new Slot(inventoryPlayer, slot, x + slot * 18, y + 58));
|
||||
for (int slot = 0; slot < 9; slot++) addSlotToContainer(new Slot(inventoryPlayer, slot, x + slot * 18, y + 58));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -263,8 +237,7 @@ public abstract class ContainerExtended extends Container implements ICrafting
|
||||
}
|
||||
|
||||
public void sendContainerPacket(PacketCustom packet) {
|
||||
for (EntityPlayerMP player : playerCrafters)
|
||||
packet.sendToPlayer(player);
|
||||
for (EntityPlayerMP player : playerCrafters) packet.sendToPlayer(player);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -272,10 +245,11 @@ public abstract class ContainerExtended extends Container implements ICrafting
|
||||
* @return A packet on the CCL inventory channel that will be recieved by this container on the other network side
|
||||
*/
|
||||
public PacketCustom getPacket(int type) {
|
||||
if(netID == 0)
|
||||
if (netID == 0)
|
||||
LogManager.getLogger("CodeChickenLib").error("Tried to get packet for container with 0 network ID");
|
||||
if(type == 1)
|
||||
throw new IllegalArgumentException("Packet type 1 is reserved for network synchronisation in ContainerExtended");
|
||||
if (type == 1)
|
||||
throw new IllegalArgumentException(
|
||||
"Packet type 1 is reserved for network synchronisation in ContainerExtended");
|
||||
|
||||
return new PacketCustom(netChannel, type).writeInt(netID);
|
||||
}
|
||||
@@ -291,7 +265,6 @@ public abstract class ContainerExtended extends Container implements ICrafting
|
||||
public void handleServerPacket(PacketCustom packet) {}
|
||||
|
||||
public void sendProgressBarUpdate(int barID, int value) {
|
||||
for (ICrafting crafting : (List<ICrafting>) crafters)
|
||||
crafting.sendProgressBarUpdate(this, barID, value);
|
||||
for (ICrafting crafting : (List<ICrafting>) crafters) crafting.sendProgressBarUpdate(this, barID, value);
|
||||
}
|
||||
}
|
||||
@@ -1,17 +1,14 @@
|
||||
package codechicken.lib.inventory;
|
||||
|
||||
import codechicken.lib.packet.PacketCustom;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraft.inventory.Container;
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
import codechicken.lib.packet.PacketCustom;
|
||||
|
||||
public abstract class ContainerSynchronised extends ContainerExtended
|
||||
{
|
||||
public abstract class ContainerSynchronised extends ContainerExtended {
|
||||
private ArrayList<IContainerSyncVar> syncVars = new ArrayList<IContainerSyncVar>();
|
||||
|
||||
/**
|
||||
@@ -39,7 +36,8 @@ public abstract class ContainerSynchronised extends ContainerExtended
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendContainerAndContentsToPlayer(Container container, List<ItemStack> list, List<EntityPlayerMP> playerCrafters) {
|
||||
public void sendContainerAndContentsToPlayer(
|
||||
Container container, List<ItemStack> list, List<EntityPlayerMP> playerCrafters) {
|
||||
super.sendContainerAndContentsToPlayer(container, list, playerCrafters);
|
||||
for (int i = 0; i < syncVars.size(); i++) {
|
||||
IContainerSyncVar var = syncVars.get(i);
|
||||
@@ -47,8 +45,7 @@ public abstract class ContainerSynchronised extends ContainerExtended
|
||||
packet.writeByte(i);
|
||||
var.writeChange(packet);
|
||||
var.reset();
|
||||
for (EntityPlayerMP player : playerCrafters)
|
||||
packet.sendToPlayer(player);
|
||||
for (EntityPlayerMP player : playerCrafters) packet.sendToPlayer(player);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,13 +2,12 @@ package codechicken.lib.inventory;
|
||||
|
||||
import codechicken.lib.packet.PacketCustom;
|
||||
|
||||
public interface IContainerSyncVar
|
||||
{
|
||||
public interface IContainerSyncVar {
|
||||
public boolean changed();
|
||||
|
||||
|
||||
public void reset();
|
||||
|
||||
|
||||
public void writeChange(PacketCustom packet);
|
||||
|
||||
|
||||
public void readChange(PacketCustom packet);
|
||||
}
|
||||
@@ -2,33 +2,28 @@ package codechicken.lib.inventory;
|
||||
|
||||
import codechicken.lib.packet.PacketCustom;
|
||||
|
||||
public abstract class IntegerSync implements IContainerSyncVar
|
||||
{
|
||||
public abstract class IntegerSync implements IContainerSyncVar {
|
||||
public int c_value;
|
||||
|
||||
|
||||
@Override
|
||||
public boolean changed()
|
||||
{
|
||||
public boolean changed() {
|
||||
return getValue() != c_value;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void reset()
|
||||
{
|
||||
public void reset() {
|
||||
c_value = getValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeChange(PacketCustom packet)
|
||||
{
|
||||
public void writeChange(PacketCustom packet) {
|
||||
packet.writeInt(getValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readChange(PacketCustom packet)
|
||||
{
|
||||
public void readChange(PacketCustom packet) {
|
||||
c_value = packet.readInt();
|
||||
}
|
||||
|
||||
|
||||
public abstract int getValue();
|
||||
}
|
||||
@@ -7,35 +7,28 @@ import net.minecraft.item.ItemStack;
|
||||
/**
|
||||
* Creates a copy of an IInventory for extended simulation
|
||||
*/
|
||||
public class InventoryCopy implements IInventory
|
||||
{
|
||||
public class InventoryCopy implements IInventory {
|
||||
public boolean[] accessible;
|
||||
public ItemStack[] items;
|
||||
public IInventory inv;
|
||||
|
||||
public InventoryCopy(IInventory inv)
|
||||
{
|
||||
|
||||
public InventoryCopy(IInventory inv) {
|
||||
items = new ItemStack[inv.getSizeInventory()];
|
||||
accessible = new boolean[inv.getSizeInventory()];
|
||||
this.inv = inv;
|
||||
update();
|
||||
}
|
||||
|
||||
public void update()
|
||||
{
|
||||
for(int i = 0; i < items.length; i++)
|
||||
{
|
||||
|
||||
public void update() {
|
||||
for (int i = 0; i < items.length; i++) {
|
||||
ItemStack stack = inv.getStackInSlot(i);
|
||||
if(stack != null)
|
||||
items[i] = stack.copy();
|
||||
if (stack != null) items[i] = stack.copy();
|
||||
}
|
||||
}
|
||||
|
||||
public InventoryCopy open(InventoryRange access)
|
||||
{
|
||||
|
||||
public InventoryCopy open(InventoryRange access) {
|
||||
int lslot = access.lastSlot();
|
||||
if(lslot > accessible.length)
|
||||
{
|
||||
if (lslot > accessible.length) {
|
||||
boolean[] l_accessible = new boolean[lslot];
|
||||
ItemStack[] l_items = new ItemStack[lslot];
|
||||
System.arraycopy(accessible, 0, l_accessible, 0, accessible.length);
|
||||
@@ -44,83 +37,66 @@ public class InventoryCopy implements IInventory
|
||||
items = l_items;
|
||||
}
|
||||
|
||||
for(int slot : access.slots)
|
||||
accessible[slot] = true;
|
||||
for (int slot : access.slots) accessible[slot] = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getSizeInventory()
|
||||
{
|
||||
public int getSizeInventory() {
|
||||
return items.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getStackInSlot(int slot)
|
||||
{
|
||||
public ItemStack getStackInSlot(int slot) {
|
||||
return items[slot];
|
||||
}
|
||||
|
||||
public ItemStack decrStackSize(int slot, int amount)
|
||||
{
|
||||
public ItemStack decrStackSize(int slot, int amount) {
|
||||
return InventoryUtils.decrStackSize(this, slot, amount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getStackInSlotOnClosing(int slot)
|
||||
{
|
||||
public ItemStack getStackInSlotOnClosing(int slot) {
|
||||
return InventoryUtils.getStackInSlotOnClosing(this, slot);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setInventorySlotContents(int slot, ItemStack stack)
|
||||
{
|
||||
public void setInventorySlotContents(int slot, ItemStack stack) {
|
||||
items[slot] = stack;
|
||||
markDirty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInventoryName()
|
||||
{
|
||||
public String getInventoryName() {
|
||||
return "copy";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUseableByPlayer(EntityPlayer player)
|
||||
{
|
||||
public boolean isUseableByPlayer(EntityPlayer player) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void openInventory()
|
||||
{
|
||||
}
|
||||
public void openInventory() {}
|
||||
|
||||
@Override
|
||||
public void closeInventory()
|
||||
{
|
||||
}
|
||||
public void closeInventory() {}
|
||||
|
||||
@Override
|
||||
public int getInventoryStackLimit()
|
||||
{
|
||||
public int getInventoryStackLimit() {
|
||||
return 64;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void markDirty()
|
||||
{
|
||||
}
|
||||
|
||||
public void markDirty() {}
|
||||
|
||||
@Override
|
||||
public boolean isItemValidForSlot(int i, ItemStack itemstack)
|
||||
{
|
||||
public boolean isItemValidForSlot(int i, ItemStack itemstack) {
|
||||
return inv.isItemValidForSlot(i, itemstack);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean hasCustomInventoryName()
|
||||
{
|
||||
public boolean hasCustomInventoryName() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -8,103 +8,83 @@ import net.minecraft.nbt.NBTTagCompound;
|
||||
/**
|
||||
* IInventory implementation which saves and loads from an NBT tag
|
||||
*/
|
||||
public class InventoryNBT implements IInventory
|
||||
{
|
||||
public class InventoryNBT implements IInventory {
|
||||
protected ItemStack[] items;
|
||||
protected NBTTagCompound tag;
|
||||
|
||||
public InventoryNBT(int size, NBTTagCompound tag)
|
||||
{
|
||||
|
||||
public InventoryNBT(int size, NBTTagCompound tag) {
|
||||
this.tag = tag;
|
||||
items = new ItemStack[size];
|
||||
readNBT();
|
||||
}
|
||||
|
||||
private void writeNBT()
|
||||
{
|
||||
|
||||
private void writeNBT() {
|
||||
tag.setTag("items", InventoryUtils.writeItemStacksToTag(items, getInventoryStackLimit()));
|
||||
}
|
||||
|
||||
private void readNBT()
|
||||
{
|
||||
if(tag.hasKey("items"))
|
||||
InventoryUtils.readItemStacksFromTag(items, tag.getTagList("items", 10));
|
||||
|
||||
private void readNBT() {
|
||||
if (tag.hasKey("items")) InventoryUtils.readItemStacksFromTag(items, tag.getTagList("items", 10));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getSizeInventory()
|
||||
{
|
||||
public int getSizeInventory() {
|
||||
return items.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getStackInSlot(int slot)
|
||||
{
|
||||
public ItemStack getStackInSlot(int slot) {
|
||||
return items[slot];
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack decrStackSize(int slot, int amount)
|
||||
{
|
||||
public ItemStack decrStackSize(int slot, int amount) {
|
||||
return InventoryUtils.decrStackSize(this, slot, amount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getStackInSlotOnClosing(int slot)
|
||||
{
|
||||
public ItemStack getStackInSlotOnClosing(int slot) {
|
||||
return InventoryUtils.getStackInSlotOnClosing(this, slot);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setInventorySlotContents(int slot, ItemStack stack)
|
||||
{
|
||||
public void setInventorySlotContents(int slot, ItemStack stack) {
|
||||
items[slot] = stack;
|
||||
markDirty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInventoryName()
|
||||
{
|
||||
public String getInventoryName() {
|
||||
return "NBT";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getInventoryStackLimit()
|
||||
{
|
||||
public int getInventoryStackLimit() {
|
||||
return 64;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void markDirty()
|
||||
{
|
||||
public void markDirty() {
|
||||
writeNBT();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUseableByPlayer(EntityPlayer var1)
|
||||
{
|
||||
public boolean isUseableByPlayer(EntityPlayer var1) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void openInventory()
|
||||
{
|
||||
public void openInventory() {}
|
||||
|
||||
@Override
|
||||
public void closeInventory() {}
|
||||
|
||||
@Override
|
||||
public boolean isItemValidForSlot(int i, ItemStack itemstack) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void closeInventory()
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isItemValidForSlot(int i, ItemStack itemstack)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasCustomInventoryName()
|
||||
{
|
||||
public boolean hasCustomInventoryName() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -7,68 +7,52 @@ import net.minecraft.item.ItemStack;
|
||||
/**
|
||||
* Inventory wrapper for unified ISided/IInventory access
|
||||
*/
|
||||
public class InventoryRange
|
||||
{
|
||||
public class InventoryRange {
|
||||
public IInventory inv;
|
||||
public int side;
|
||||
public ISidedInventory sidedInv;
|
||||
public int[] slots;
|
||||
|
||||
public InventoryRange(IInventory inv, int side)
|
||||
{
|
||||
|
||||
public InventoryRange(IInventory inv, int side) {
|
||||
this.inv = inv;
|
||||
this.side = side;
|
||||
if(inv instanceof ISidedInventory)
|
||||
{
|
||||
sidedInv = (ISidedInventory)inv;
|
||||
if (inv instanceof ISidedInventory) {
|
||||
sidedInv = (ISidedInventory) inv;
|
||||
slots = sidedInv.getAccessibleSlotsFromSide(side);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
slots = new int[inv.getSizeInventory()];
|
||||
for(int i = 0; i < slots.length; i++)
|
||||
slots[i] = i;
|
||||
for (int i = 0; i < slots.length; i++) slots[i] = i;
|
||||
}
|
||||
}
|
||||
|
||||
public InventoryRange(IInventory inv)
|
||||
{
|
||||
public InventoryRange(IInventory inv) {
|
||||
this(inv, 0);
|
||||
}
|
||||
|
||||
public InventoryRange(IInventory inv, int fslot, int size)
|
||||
{
|
||||
|
||||
public InventoryRange(IInventory inv, int fslot, int size) {
|
||||
this.inv = inv;
|
||||
slots = new int[size];
|
||||
for(int i = 0; i < slots.length; i++)
|
||||
slots[i] = fslot+i;
|
||||
for (int i = 0; i < slots.length; i++) slots[i] = fslot + i;
|
||||
}
|
||||
|
||||
public InventoryRange(IInventory inv, InventoryRange access)
|
||||
{
|
||||
public InventoryRange(IInventory inv, InventoryRange access) {
|
||||
this.inv = inv;
|
||||
this.slots = access.slots;
|
||||
this.side = access.side;
|
||||
if(inv instanceof ISidedInventory)
|
||||
sidedInv = (ISidedInventory) inv;
|
||||
if (inv instanceof ISidedInventory) sidedInv = (ISidedInventory) inv;
|
||||
}
|
||||
|
||||
public boolean canInsertItem(int slot, ItemStack item)
|
||||
{
|
||||
public boolean canInsertItem(int slot, ItemStack item) {
|
||||
return sidedInv == null ? inv.isItemValidForSlot(slot, item) : sidedInv.canInsertItem(slot, item, side);
|
||||
}
|
||||
|
||||
public boolean canExtractItem(int slot, ItemStack item)
|
||||
{
|
||||
|
||||
public boolean canExtractItem(int slot, ItemStack item) {
|
||||
return sidedInv == null ? inv.isItemValidForSlot(slot, item) : sidedInv.canExtractItem(slot, item, side);
|
||||
}
|
||||
|
||||
public int lastSlot()
|
||||
{
|
||||
public int lastSlot() {
|
||||
int last = 0;
|
||||
for(int slot : slots)
|
||||
if(slot > last)
|
||||
last = slot;
|
||||
for (int slot : slots) if (slot > last) last = slot;
|
||||
return last;
|
||||
}
|
||||
}
|
||||
@@ -7,127 +7,102 @@ import net.minecraft.item.ItemStack;
|
||||
/**
|
||||
* Simple IInventory implementation with an array of items, name and maximum stack size
|
||||
*/
|
||||
public class InventorySimple implements IInventory
|
||||
{
|
||||
public class InventorySimple implements IInventory {
|
||||
public ItemStack[] items;
|
||||
public int limit;
|
||||
public String name;
|
||||
|
||||
public InventorySimple(ItemStack[] items, int limit, String name)
|
||||
{
|
||||
|
||||
public InventorySimple(ItemStack[] items, int limit, String name) {
|
||||
this.items = items;
|
||||
this.limit = limit;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public InventorySimple(ItemStack[] items, String name)
|
||||
{
|
||||
|
||||
public InventorySimple(ItemStack[] items, String name) {
|
||||
this(items, 64, name);
|
||||
}
|
||||
|
||||
public InventorySimple(ItemStack[] items, int limit)
|
||||
{
|
||||
|
||||
public InventorySimple(ItemStack[] items, int limit) {
|
||||
this(items, limit, "inv");
|
||||
}
|
||||
|
||||
public InventorySimple(ItemStack[] items)
|
||||
{
|
||||
|
||||
public InventorySimple(ItemStack[] items) {
|
||||
this(items, 64, "inv");
|
||||
}
|
||||
|
||||
public InventorySimple(int size, int limit, String name)
|
||||
{
|
||||
public InventorySimple(int size, int limit, String name) {
|
||||
this(new ItemStack[size], limit, name);
|
||||
}
|
||||
|
||||
public InventorySimple(int size, int limit)
|
||||
{
|
||||
|
||||
public InventorySimple(int size, int limit) {
|
||||
this(size, limit, "inv");
|
||||
}
|
||||
|
||||
public InventorySimple(int size, String name)
|
||||
{
|
||||
|
||||
public InventorySimple(int size, String name) {
|
||||
this(size, 64, name);
|
||||
}
|
||||
|
||||
public InventorySimple(int size)
|
||||
{
|
||||
|
||||
public InventorySimple(int size) {
|
||||
this(size, 64, "inv");
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSizeInventory()
|
||||
{
|
||||
public int getSizeInventory() {
|
||||
return items.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getStackInSlot(int slot)
|
||||
{
|
||||
public ItemStack getStackInSlot(int slot) {
|
||||
return items[slot];
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack decrStackSize(int slot, int amount)
|
||||
{
|
||||
public ItemStack decrStackSize(int slot, int amount) {
|
||||
return InventoryUtils.decrStackSize(this, slot, amount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getStackInSlotOnClosing(int slot)
|
||||
{
|
||||
public ItemStack getStackInSlotOnClosing(int slot) {
|
||||
return InventoryUtils.getStackInSlotOnClosing(this, slot);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setInventorySlotContents(int slot, ItemStack stack)
|
||||
{
|
||||
public void setInventorySlotContents(int slot, ItemStack stack) {
|
||||
items[slot] = stack;
|
||||
markDirty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInventoryName()
|
||||
{
|
||||
public String getInventoryName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getInventoryStackLimit()
|
||||
{
|
||||
public int getInventoryStackLimit() {
|
||||
return limit;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUseableByPlayer(EntityPlayer var1)
|
||||
{
|
||||
public boolean isUseableByPlayer(EntityPlayer var1) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void openInventory()
|
||||
{
|
||||
public void openInventory() {}
|
||||
|
||||
@Override
|
||||
public void closeInventory() {}
|
||||
|
||||
@Override
|
||||
public boolean isItemValidForSlot(int i, ItemStack itemstack) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void closeInventory()
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isItemValidForSlot(int i, ItemStack itemstack)
|
||||
{
|
||||
public boolean hasCustomInventoryName() {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean hasCustomInventoryName()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void markDirty()
|
||||
{
|
||||
}
|
||||
public void markDirty() {}
|
||||
}
|
||||
@@ -17,8 +17,7 @@ import net.minecraft.tileentity.TileEntityChest;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.common.util.ForgeDirection;
|
||||
|
||||
public class InventoryUtils
|
||||
{
|
||||
public class InventoryUtils {
|
||||
/**
|
||||
* Constructor for ItemStack with tag
|
||||
*/
|
||||
@@ -48,10 +47,8 @@ public class InventoryUtils
|
||||
return item;
|
||||
}
|
||||
ItemStack itemstack1 = item.splitStack(size);
|
||||
if (item.stackSize == 0)
|
||||
inv.setInventorySlotContents(slot, null);
|
||||
else
|
||||
inv.setInventorySlotContents(slot, item);
|
||||
if (item.stackSize == 0) inv.setInventorySlotContents(slot, null);
|
||||
else inv.setInventorySlotContents(slot, item);
|
||||
|
||||
inv.markDirty();
|
||||
return itemstack1;
|
||||
@@ -72,8 +69,7 @@ public class InventoryUtils
|
||||
* @return The quantity of items from addition that can be added to base
|
||||
*/
|
||||
public static int incrStackSize(ItemStack base, ItemStack addition) {
|
||||
if (canStack(base, addition))
|
||||
return incrStackSize(base, addition.stackSize);
|
||||
if (canStack(base, addition)) return incrStackSize(base, addition.stackSize);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -84,10 +80,8 @@ public class InventoryUtils
|
||||
public static int incrStackSize(ItemStack base, int addition) {
|
||||
int totalSize = base.stackSize + addition;
|
||||
|
||||
if (totalSize <= base.getMaxStackSize())
|
||||
return addition;
|
||||
else if (base.stackSize < base.getMaxStackSize())
|
||||
return base.getMaxStackSize() - base.stackSize;
|
||||
if (totalSize <= base.getMaxStackSize()) return addition;
|
||||
else if (base.stackSize < base.getMaxStackSize()) return base.getMaxStackSize() - base.stackSize;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -110,10 +104,8 @@ public class InventoryUtils
|
||||
tag.setShort("Slot", (short) i);
|
||||
items[i].writeToNBT(tag);
|
||||
|
||||
if (maxQuantity > Short.MAX_VALUE)
|
||||
tag.setInteger("Quantity", items[i].stackSize);
|
||||
else if (maxQuantity > Byte.MAX_VALUE)
|
||||
tag.setShort("Quantity", (short) items[i].stackSize);
|
||||
if (maxQuantity > Short.MAX_VALUE) tag.setInteger("Quantity", items[i].stackSize);
|
||||
else if (maxQuantity > Byte.MAX_VALUE) tag.setShort("Quantity", (short) items[i].stackSize);
|
||||
|
||||
tagList.appendTag(tag);
|
||||
}
|
||||
@@ -149,8 +141,7 @@ public class InventoryUtils
|
||||
* Copies an itemstack with a new quantity
|
||||
*/
|
||||
public static ItemStack copyStack(ItemStack stack, int quantity) {
|
||||
if (stack == null)
|
||||
return null;
|
||||
if (stack == null) return null;
|
||||
|
||||
stack = stack.copy();
|
||||
stack.stackSize = quantity;
|
||||
@@ -163,8 +154,7 @@ public class InventoryUtils
|
||||
public static int getInsertibleQuantity(InventoryRange inv, ItemStack stack) {
|
||||
int quantity = 0;
|
||||
stack = copyStack(stack, Integer.MAX_VALUE);
|
||||
for (int slot : inv.slots)
|
||||
quantity += fitStackInSlot(inv, slot, stack);
|
||||
for (int slot : inv.slots) quantity += fitStackInSlot(inv, slot, stack);
|
||||
|
||||
return quantity;
|
||||
}
|
||||
@@ -175,10 +165,11 @@ public class InventoryUtils
|
||||
|
||||
public static int fitStackInSlot(InventoryRange inv, int slot, ItemStack stack) {
|
||||
ItemStack base = inv.inv.getStackInSlot(slot);
|
||||
if (!canStack(base, stack) || !inv.canInsertItem(slot, stack))
|
||||
return 0;
|
||||
if (!canStack(base, stack) || !inv.canInsertItem(slot, stack)) return 0;
|
||||
|
||||
int fit = base != null ? incrStackSize(base, inv.inv.getInventoryStackLimit() - base.stackSize) : inv.inv.getInventoryStackLimit();
|
||||
int fit = base != null
|
||||
? incrStackSize(base, inv.inv.getInventoryStackLimit() - base.stackSize)
|
||||
: inv.inv.getInventoryStackLimit();
|
||||
return Math.min(fit, stack.stackSize);
|
||||
}
|
||||
|
||||
@@ -195,11 +186,9 @@ public class InventoryUtils
|
||||
for (int pass = 0; pass < 2; pass++) {
|
||||
for (int slot : inv.slots) {
|
||||
ItemStack base = inv.inv.getStackInSlot(slot);
|
||||
if((pass == 0) == (base == null))
|
||||
continue;
|
||||
if ((pass == 0) == (base == null)) continue;
|
||||
int fit = fitStackInSlot(inv, slot, stack);
|
||||
if (fit == 0)
|
||||
continue;
|
||||
if (fit == 0) continue;
|
||||
|
||||
if (base != null) {
|
||||
stack.stackSize -= fit;
|
||||
@@ -208,12 +197,10 @@ public class InventoryUtils
|
||||
inv.inv.setInventorySlotContents(slot, base);
|
||||
}
|
||||
} else {
|
||||
if (!simulate)
|
||||
inv.inv.setInventorySlotContents(slot, copyStack(stack, fit));
|
||||
if (!simulate) inv.inv.setInventorySlotContents(slot, copyStack(stack, fit));
|
||||
stack.stackSize -= fit;
|
||||
}
|
||||
if (stack.stackSize == 0)
|
||||
return 0;
|
||||
if (stack.stackSize == 0) return 0;
|
||||
}
|
||||
}
|
||||
return stack.stackSize;
|
||||
@@ -228,8 +215,7 @@ public class InventoryUtils
|
||||
*/
|
||||
public static ItemStack getExtractableStack(InventoryRange inv, int slot) {
|
||||
ItemStack stack = inv.inv.getStackInSlot(slot);
|
||||
if (stack == null || !inv.canExtractItem(slot, stack))
|
||||
return null;
|
||||
if (stack == null || !inv.canExtractItem(slot, stack)) return null;
|
||||
|
||||
return stack;
|
||||
}
|
||||
@@ -239,8 +225,7 @@ public class InventoryUtils
|
||||
}
|
||||
|
||||
public static boolean areStacksIdentical(ItemStack stack1, ItemStack stack2) {
|
||||
if (stack1 == null || stack2 == null)
|
||||
return stack1 == stack2;
|
||||
if (stack1 == null || stack2 == null) return stack1 == stack2;
|
||||
|
||||
return stack1.getItem() == stack2.getItem()
|
||||
&& stack1.getItemDamage() == stack2.getItemDamage()
|
||||
@@ -253,32 +238,42 @@ public class InventoryUtils
|
||||
*/
|
||||
public static IInventory getInventory(World world, int x, int y, int z) {
|
||||
TileEntity tile = world.getTileEntity(x, y, z);
|
||||
if (!(tile instanceof IInventory))
|
||||
return null;
|
||||
if (!(tile instanceof IInventory)) return null;
|
||||
|
||||
if (tile instanceof TileEntityChest)
|
||||
return getChest((TileEntityChest) tile);
|
||||
if (tile instanceof TileEntityChest) return getChest((TileEntityChest) tile);
|
||||
return (IInventory) tile;
|
||||
|
||||
}
|
||||
|
||||
public static final ForgeDirection[] chestSides = new ForgeDirection[]{ForgeDirection.WEST, ForgeDirection.EAST, ForgeDirection.NORTH, ForgeDirection.SOUTH};
|
||||
public static final ForgeDirection[] chestSides =
|
||||
new ForgeDirection[] {ForgeDirection.WEST, ForgeDirection.EAST, ForgeDirection.NORTH, ForgeDirection.SOUTH};
|
||||
|
||||
public static IInventory getChest(TileEntityChest chest) {
|
||||
for (ForgeDirection fside : chestSides) {
|
||||
if (chest.getWorldObj().getBlock(chest.xCoord + fside.offsetX, chest.yCoord + fside.offsetY, chest.zCoord + fside.offsetZ) == chest.getBlockType())
|
||||
return new InventoryLargeChest("container.chestDouble",
|
||||
(TileEntityChest) chest.getWorldObj().getTileEntity(chest.xCoord + fside.offsetX, chest.yCoord + fside.offsetY, chest.zCoord + fside.offsetZ), chest);
|
||||
if (chest.getWorldObj()
|
||||
.getBlock(
|
||||
chest.xCoord + fside.offsetX,
|
||||
chest.yCoord + fside.offsetY,
|
||||
chest.zCoord + fside.offsetZ)
|
||||
== chest.getBlockType())
|
||||
return new InventoryLargeChest(
|
||||
"container.chestDouble",
|
||||
(TileEntityChest) chest.getWorldObj()
|
||||
.getTileEntity(
|
||||
chest.xCoord + fside.offsetX,
|
||||
chest.yCoord + fside.offsetY,
|
||||
chest.zCoord + fside.offsetZ),
|
||||
chest);
|
||||
}
|
||||
return chest;
|
||||
}
|
||||
|
||||
public static boolean canStack(ItemStack stack1, ItemStack stack2) {
|
||||
return stack1 == null || stack2 == null ||
|
||||
(stack1.getItem() == stack2.getItem() &&
|
||||
(!stack2.getHasSubtypes() || stack2.getItemDamage() == stack1.getItemDamage()) &&
|
||||
ItemStack.areItemStackTagsEqual(stack2, stack1)) &&
|
||||
stack1.isStackable();
|
||||
return stack1 == null
|
||||
|| stack2 == null
|
||||
|| (stack1.getItem() == stack2.getItem()
|
||||
&& (!stack2.getHasSubtypes() || stack2.getItemDamage() == stack1.getItemDamage())
|
||||
&& ItemStack.areItemStackTagsEqual(stack2, stack1))
|
||||
&& stack1.isStackable();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -309,8 +304,7 @@ public class InventoryUtils
|
||||
public static void dropOnClose(EntityPlayer player, IInventory inv) {
|
||||
for (int i = 0; i < inv.getSizeInventory(); i++) {
|
||||
ItemStack stack = inv.getStackInSlotOnClosing(i);
|
||||
if (stack != null)
|
||||
player.dropPlayerItemWithRandomChoice(stack, false);
|
||||
if (stack != null) player.dropPlayerItemWithRandomChoice(stack, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -324,12 +318,11 @@ public class InventoryUtils
|
||||
public static ItemStack loadPersistant(NBTTagCompound tag) {
|
||||
String name = tag.getString("name");
|
||||
Item item = (Item) Item.itemRegistry.getObject(name);
|
||||
if(item == null) return null;
|
||||
if (item == null) return null;
|
||||
int count = tag.hasKey("Count") ? tag.getByte("Count") : 1;
|
||||
int damage = tag.hasKey("Damage") ? tag.getShort("Damage") : 0;
|
||||
ItemStack stack = new ItemStack(item, count, damage);
|
||||
if(tag.hasKey("tag", 10))
|
||||
stack.stackTagCompound = tag.getCompoundTag("tag");
|
||||
if (tag.hasKey("tag", 10)) stack.stackTagCompound = tag.getCompoundTag("tag");
|
||||
return stack;
|
||||
}
|
||||
}
|
||||
@@ -1,18 +1,17 @@
|
||||
package codechicken.lib.inventory;
|
||||
|
||||
import static codechicken.lib.inventory.InventoryUtils.actualDamage;
|
||||
|
||||
import com.google.common.base.Objects;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraftforge.oredict.OreDictionary;
|
||||
|
||||
import static codechicken.lib.inventory.InventoryUtils.actualDamage;
|
||||
|
||||
/**
|
||||
* Comparable ItemStack with a hashCode implementation.
|
||||
*/
|
||||
public class ItemKey implements Comparable<ItemKey>
|
||||
{
|
||||
public class ItemKey implements Comparable<ItemKey> {
|
||||
public ItemStack stack;
|
||||
private int hashcode = 0;
|
||||
|
||||
@@ -35,18 +34,19 @@ public class ItemKey implements Comparable<ItemKey>
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (!(obj instanceof ItemKey))
|
||||
return false;
|
||||
if (!(obj instanceof ItemKey)) return false;
|
||||
|
||||
ItemKey k = (ItemKey) obj;
|
||||
return stack.getItem() == k.stack.getItem() &&
|
||||
actualDamage(stack) == actualDamage(k.stack) &&
|
||||
Objects.equal(stack.stackTagCompound, k.stack.stackTagCompound);
|
||||
return stack.getItem() == k.stack.getItem()
|
||||
&& actualDamage(stack) == actualDamage(k.stack)
|
||||
&& Objects.equal(stack.stackTagCompound, k.stack.stackTagCompound);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return hashcode != 0 ? hashcode : (hashcode = Objects.hashCode(stack.getItem(), actualDamage(stack), stack.stackTagCompound));
|
||||
return hashcode != 0
|
||||
? hashcode
|
||||
: (hashcode = Objects.hashCode(stack.getItem(), actualDamage(stack), stack.stackTagCompound));
|
||||
}
|
||||
|
||||
public int compareInt(int a, int b) {
|
||||
@@ -57,8 +57,7 @@ public class ItemKey implements Comparable<ItemKey>
|
||||
public int compareTo(ItemKey o) {
|
||||
if (stack.getItem() != o.stack.getItem())
|
||||
return compareInt(Item.getIdFromItem(stack.getItem()), Item.getIdFromItem(o.stack.getItem()));
|
||||
if (actualDamage(stack) != actualDamage(o.stack))
|
||||
return compareInt(actualDamage(stack), actualDamage(o.stack));
|
||||
if (actualDamage(stack) != actualDamage(o.stack)) return compareInt(actualDamage(stack), actualDamage(o.stack));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -4,69 +4,51 @@ import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.inventory.IInventory;
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
public class SlotDummy extends SlotHandleClicks
|
||||
{
|
||||
public class SlotDummy extends SlotHandleClicks {
|
||||
public final int stackLimit;
|
||||
public SlotDummy(IInventory inv, int slot, int x, int y)
|
||||
{
|
||||
|
||||
public SlotDummy(IInventory inv, int slot, int x, int y) {
|
||||
this(inv, slot, x, y, 64);
|
||||
}
|
||||
|
||||
public SlotDummy(IInventory inv, int slot, int x, int y, int limit)
|
||||
{
|
||||
|
||||
public SlotDummy(IInventory inv, int slot, int x, int y, int limit) {
|
||||
super(inv, slot, x, y);
|
||||
stackLimit = limit;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public ItemStack slotClick(ContainerExtended container, EntityPlayer player, int button, int modifier)
|
||||
{
|
||||
public ItemStack slotClick(ContainerExtended container, EntityPlayer player, int button, int modifier) {
|
||||
ItemStack held = player.inventory.getItemStack();
|
||||
boolean shift = modifier == 1;
|
||||
slotClick(held, button, shift);
|
||||
return null;
|
||||
}
|
||||
|
||||
public void slotClick(ItemStack held, int button, boolean shift)
|
||||
{
|
||||
|
||||
public void slotClick(ItemStack held, int button, boolean shift) {
|
||||
ItemStack tstack = getStack();
|
||||
if(held != null && (tstack == null || !InventoryUtils.canStack(held, tstack)))
|
||||
{
|
||||
if (held != null && (tstack == null || !InventoryUtils.canStack(held, tstack))) {
|
||||
int quantity = Math.min(held.stackSize, stackLimit);
|
||||
if(shift)
|
||||
quantity = Math.min(stackLimit, held.getMaxStackSize()*16);
|
||||
if(button == 1)
|
||||
quantity = 1;
|
||||
if (shift) quantity = Math.min(stackLimit, held.getMaxStackSize() * 16);
|
||||
if (button == 1) quantity = 1;
|
||||
putStack(InventoryUtils.copyStack(held, quantity));
|
||||
}
|
||||
else if(tstack != null)
|
||||
{
|
||||
} else if (tstack != null) {
|
||||
int inc;
|
||||
if(held != null)
|
||||
{
|
||||
if (held != null) {
|
||||
inc = button == 1 ? -held.stackSize : held.stackSize;
|
||||
if(shift)
|
||||
inc *= 16;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (shift) inc *= 16;
|
||||
} else {
|
||||
inc = button == 1 ? -1 : 1;
|
||||
if(shift)
|
||||
inc *= 16;
|
||||
if (shift) inc *= 16;
|
||||
}
|
||||
int quantity = tstack.stackSize+inc;
|
||||
if(quantity <= 0)
|
||||
putStack(null);
|
||||
else
|
||||
putStack(InventoryUtils.copyStack(tstack, quantity));
|
||||
int quantity = tstack.stackSize + inc;
|
||||
if (quantity <= 0) putStack(null);
|
||||
else putStack(InventoryUtils.copyStack(tstack, quantity));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void putStack(ItemStack stack)
|
||||
{
|
||||
if(stack != null && stack.stackSize > stackLimit)
|
||||
stack = InventoryUtils.copyStack(stack, stackLimit);
|
||||
public void putStack(ItemStack stack) {
|
||||
if (stack != null && stack.stackSize > stackLimit) stack = InventoryUtils.copyStack(stack, stackLimit);
|
||||
super.putStack(stack);
|
||||
}
|
||||
}
|
||||
@@ -4,16 +4,13 @@ import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.inventory.IInventory;
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
public class SlotDummyOutput extends SlotHandleClicks
|
||||
{
|
||||
public SlotDummyOutput(IInventory inv, int slot, int x, int y)
|
||||
{
|
||||
public class SlotDummyOutput extends SlotHandleClicks {
|
||||
public SlotDummyOutput(IInventory inv, int slot, int x, int y) {
|
||||
super(inv, slot, x, y);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public ItemStack slotClick(ContainerExtended container, EntityPlayer player, int button, int modifier)
|
||||
{
|
||||
public ItemStack slotClick(ContainerExtended container, EntityPlayer player, int button, int modifier) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -5,10 +5,8 @@ import net.minecraft.inventory.IInventory;
|
||||
import net.minecraft.inventory.Slot;
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
public abstract class SlotHandleClicks extends Slot
|
||||
{
|
||||
public SlotHandleClicks(IInventory inv, int slot, int x, int y)
|
||||
{
|
||||
public abstract class SlotHandleClicks extends Slot {
|
||||
public SlotHandleClicks(IInventory inv, int slot, int x, int y) {
|
||||
super(inv, slot, x, y);
|
||||
}
|
||||
|
||||
|
||||
@@ -5,8 +5,7 @@ import codechicken.lib.util.Copyable;
|
||||
import codechicken.lib.vec.Rotation;
|
||||
import codechicken.lib.vec.Vector3;
|
||||
|
||||
public class LC implements Copyable<LC>
|
||||
{
|
||||
public class LC implements Copyable<LC> {
|
||||
public int side;
|
||||
public float fa;
|
||||
public float fb;
|
||||
@@ -40,8 +39,7 @@ public class LC implements Copyable<LC>
|
||||
|
||||
public LC compute(Vector3 vec, Vector3 normal) {
|
||||
int side = CCModel.findSide(normal);
|
||||
if (side < 0)
|
||||
return set(12, 1, 0, 0, 0);
|
||||
if (side < 0) return set(12, 1, 0, 0, 0);
|
||||
return compute(vec, side);
|
||||
}
|
||||
|
||||
@@ -67,8 +65,7 @@ public class LC implements Copyable<LC>
|
||||
offset = vec.x >= 1;
|
||||
break;
|
||||
}
|
||||
if (!offset)
|
||||
side += 6;
|
||||
if (!offset) side += 6;
|
||||
return computeO(vec, side);
|
||||
}
|
||||
|
||||
@@ -86,4 +83,4 @@ public class LC implements Copyable<LC>
|
||||
public LC copy() {
|
||||
return new LC(side, fa, fb, fc, fd);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10,8 +10,7 @@ import net.minecraft.world.IBlockAccess;
|
||||
/**
|
||||
* Note that when using the class as a vertex transformer, the vertices are assumed to be within the BB (x, y, z) -> (x+1, y+1, z+1)
|
||||
*/
|
||||
public class LightMatrix implements CCRenderState.IVertexOperation
|
||||
{
|
||||
public class LightMatrix implements CCRenderState.IVertexOperation {
|
||||
public static final int operationIndex = CCRenderState.registerOperation();
|
||||
|
||||
public int computed = 0;
|
||||
@@ -28,30 +27,34 @@ public class LightMatrix implements CCRenderState.IVertexOperation
|
||||
/**
|
||||
* The 9 positions in the sample array for each side, sides >= 6 are centered on sample 13 (the block itself)
|
||||
*/
|
||||
public static final int[][] ssamplem = new int[][]{
|
||||
{ 0, 1, 2, 3, 4, 5, 6, 7, 8},
|
||||
{18,19,20,21,22,23,24,25,26},
|
||||
{ 0, 9,18, 1,10,19, 2,11,20},
|
||||
{ 6,15,24, 7,16,25, 8,17,26},
|
||||
{ 0, 3, 6, 9,12,15,18,21,24},
|
||||
{ 2, 5, 8,11,14,17,20,23,26},
|
||||
{ 9,10,11,12,13,14,15,16,17},
|
||||
{ 9,10,11,12,13,14,15,16,17},
|
||||
{ 3,12,21, 4,13,22, 5,14,23},
|
||||
{ 3,12,21, 4,13,22, 5,14,23},
|
||||
{ 1, 4, 7,10,13,16,19,22,25},
|
||||
{ 1, 4, 7,10,13,16,19,22,25},
|
||||
{13,13,13,13,13,13,13,13,13}};
|
||||
public static final int[][] qsamplem = new int[][]{//the positions in the side sample array for each corner
|
||||
{0,1,3,4},
|
||||
{5,1,2,4},
|
||||
{6,7,3,4},
|
||||
{5,7,8,4}};
|
||||
public static final float[] sideao = new float[]{
|
||||
public static final int[][] ssamplem = new int[][] {
|
||||
{0, 1, 2, 3, 4, 5, 6, 7, 8},
|
||||
{18, 19, 20, 21, 22, 23, 24, 25, 26},
|
||||
{0, 9, 18, 1, 10, 19, 2, 11, 20},
|
||||
{6, 15, 24, 7, 16, 25, 8, 17, 26},
|
||||
{0, 3, 6, 9, 12, 15, 18, 21, 24},
|
||||
{2, 5, 8, 11, 14, 17, 20, 23, 26},
|
||||
{9, 10, 11, 12, 13, 14, 15, 16, 17},
|
||||
{9, 10, 11, 12, 13, 14, 15, 16, 17},
|
||||
{3, 12, 21, 4, 13, 22, 5, 14, 23},
|
||||
{3, 12, 21, 4, 13, 22, 5, 14, 23},
|
||||
{1, 4, 7, 10, 13, 16, 19, 22, 25},
|
||||
{1, 4, 7, 10, 13, 16, 19, 22, 25},
|
||||
{13, 13, 13, 13, 13, 13, 13, 13, 13}
|
||||
};
|
||||
|
||||
public static final int[][] qsamplem = new int[][] { // the positions in the side sample array for each corner
|
||||
{0, 1, 3, 4},
|
||||
{5, 1, 2, 4},
|
||||
{6, 7, 3, 4},
|
||||
{5, 7, 8, 4}
|
||||
};
|
||||
public static final float[] sideao = new float[] {
|
||||
0.5F, 1F, 0.8F, 0.8F, 0.6F, 0.6F,
|
||||
0.5F, 1F, 0.8F, 0.8F, 0.6F, 0.6F,
|
||||
1F};
|
||||
|
||||
1F
|
||||
};
|
||||
|
||||
/*static
|
||||
{
|
||||
int[][] os = new int[][]{
|
||||
@@ -61,7 +64,7 @@ public class LightMatrix implements CCRenderState.IVertexOperation
|
||||
{0,0, 1},
|
||||
{-1,0,0},
|
||||
{ 1,0,0}};
|
||||
|
||||
|
||||
for(int s = 0; s < 12; s++)
|
||||
{
|
||||
int[] d0 = s < 6 ? new int[]{os[s][0]+1, os[s][1]+1, os[s][2]+1} : new int[]{1, 1, 1};
|
||||
@@ -110,16 +113,18 @@ public class LightMatrix implements CCRenderState.IVertexOperation
|
||||
int[] qsample = qsamplem[q];
|
||||
if (Minecraft.isAmbientOcclusionEnabled())
|
||||
interp(side, q, ssample[qsample[0]], ssample[qsample[1]], ssample[qsample[2]], ssample[qsample[3]]);
|
||||
else
|
||||
interp(side, q, ssample[4], ssample[4], ssample[4], ssample[4]);
|
||||
else interp(side, q, ssample[4], ssample[4], ssample[4], ssample[4]);
|
||||
}
|
||||
computed |= 1 << side;
|
||||
}
|
||||
}
|
||||
|
||||
private void interp(int s, int q, int a, int b, int c, int d) {
|
||||
sample(a); sample(b); sample(c); sample(d);
|
||||
ao[s][q] = interpAO(aSamples[a], aSamples[b], aSamples[c], aSamples[d])*sideao[s];
|
||||
sample(a);
|
||||
sample(b);
|
||||
sample(c);
|
||||
sample(d);
|
||||
ao[s][q] = interpAO(aSamples[a], aSamples[b], aSamples[c], aSamples[d]) * sideao[s];
|
||||
brightness[s][q] = interpBrightness(bSamples[a], bSamples[b], bSamples[c], bSamples[d]);
|
||||
}
|
||||
|
||||
@@ -128,19 +133,15 @@ public class LightMatrix implements CCRenderState.IVertexOperation
|
||||
}
|
||||
|
||||
public static int interpBrightness(int a, int b, int c, int d) {
|
||||
if (a == 0)
|
||||
a = d;
|
||||
if (b == 0)
|
||||
b = d;
|
||||
if (c == 0)
|
||||
c = d;
|
||||
if (a == 0) a = d;
|
||||
if (b == 0) b = d;
|
||||
if (c == 0) c = d;
|
||||
return (a + b + c + d) >> 2 & 0xFF00FF;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean load() {
|
||||
if(!CCRenderState.computeLighting)
|
||||
return false;
|
||||
if (!CCRenderState.computeLighting) return false;
|
||||
|
||||
CCRenderState.pipeline.addDependency(CCRenderState.colourAttrib);
|
||||
CCRenderState.pipeline.addDependency(CCRenderState.lightCoordAttrib);
|
||||
@@ -161,4 +162,4 @@ public class LightMatrix implements CCRenderState.IVertexOperation
|
||||
public int operationID() {
|
||||
return operationIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,12 +4,10 @@ import codechicken.lib.render.CCRenderState;
|
||||
import codechicken.lib.vec.Rotation;
|
||||
import codechicken.lib.vec.Vector3;
|
||||
|
||||
public class LightModel implements CCRenderState.IVertexOperation
|
||||
{
|
||||
public class LightModel implements CCRenderState.IVertexOperation {
|
||||
public static final int operationIndex = CCRenderState.registerOperation();
|
||||
|
||||
public static class Light
|
||||
{
|
||||
public static class Light {
|
||||
public Vector3 ambient = new Vector3();
|
||||
public Vector3 diffuse = new Vector3();
|
||||
public Vector3 position;
|
||||
@@ -28,17 +26,16 @@ public class LightModel implements CCRenderState.IVertexOperation
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static LightModel standardLightModel;
|
||||
|
||||
static {
|
||||
standardLightModel = new LightModel()
|
||||
.setAmbient(new Vector3(0.4, 0.4, 0.4))
|
||||
.addLight(new Light(new Vector3(0.2, 1, -0.7))
|
||||
.setDiffuse(new Vector3(0.6, 0.6, 0.6)))
|
||||
.addLight(new Light(new Vector3(-0.2, 1, 0.7))
|
||||
.setDiffuse(new Vector3(0.6, 0.6, 0.6)));
|
||||
.addLight(new Light(new Vector3(0.2, 1, -0.7)).setDiffuse(new Vector3(0.6, 0.6, 0.6)))
|
||||
.addLight(new Light(new Vector3(-0.2, 1, 0.7)).setDiffuse(new Vector3(0.6, 0.6, 0.6)));
|
||||
}
|
||||
|
||||
|
||||
private Vector3 ambient = new Vector3();
|
||||
private Light[] lights = new Light[8];
|
||||
private int lightCount;
|
||||
@@ -69,21 +66,20 @@ public class LightModel implements CCRenderState.IVertexOperation
|
||||
n_colour.z += light.ambient.z + f * light.diffuse.z * n_l;
|
||||
}
|
||||
|
||||
if (n_colour.x > 1)
|
||||
n_colour.x = 1;
|
||||
if (n_colour.y > 1)
|
||||
n_colour.y = 1;
|
||||
if (n_colour.z > 1)
|
||||
n_colour.z = 1;
|
||||
if (n_colour.x > 1) n_colour.x = 1;
|
||||
if (n_colour.y > 1) n_colour.y = 1;
|
||||
if (n_colour.z > 1) n_colour.z = 1;
|
||||
|
||||
n_colour.multiply((colour >>> 24) / 255D, (colour >> 16 & 0xFF) / 255D, (colour >> 8 & 0xFF) / 255D);
|
||||
return (int) (n_colour.x * 255) << 24 | (int) (n_colour.y * 255) << 16 | (int) (n_colour.z * 255) << 8 | colour & 0xFF;
|
||||
return (int) (n_colour.x * 255) << 24
|
||||
| (int) (n_colour.y * 255) << 16
|
||||
| (int) (n_colour.z * 255) << 8
|
||||
| colour & 0xFF;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean load() {
|
||||
if(!CCRenderState.computeLighting)
|
||||
return false;
|
||||
if (!CCRenderState.computeLighting) return false;
|
||||
|
||||
CCRenderState.pipeline.addDependency(CCRenderState.normalAttrib);
|
||||
CCRenderState.pipeline.addDependency(CCRenderState.colourAttrib);
|
||||
@@ -102,8 +98,7 @@ public class LightModel implements CCRenderState.IVertexOperation
|
||||
|
||||
public PlanarLightModel reducePlanar() {
|
||||
int[] colours = new int[6];
|
||||
for (int i = 0; i < 6; i++)
|
||||
colours[i] = apply(-1, Rotation.axes[i]);
|
||||
for (int i = 0; i < 6; i++) colours[i] = apply(-1, Rotation.axes[i]);
|
||||
return new PlanarLightModel(colours);
|
||||
}
|
||||
}
|
||||
@@ -5,8 +5,7 @@ import codechicken.lib.vec.BlockCoord;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.world.IBlockAccess;
|
||||
|
||||
public class PlanarLightMatrix extends PlanarLightModel
|
||||
{
|
||||
public class PlanarLightMatrix extends PlanarLightModel {
|
||||
public static final int operationIndex = CCRenderState.registerOperation();
|
||||
public static PlanarLightMatrix instance = new PlanarLightMatrix();
|
||||
|
||||
@@ -28,9 +27,10 @@ public class PlanarLightMatrix extends PlanarLightModel
|
||||
}
|
||||
|
||||
public int brightness(int side) {
|
||||
if((sampled & 1 << side) == 0) {
|
||||
if ((sampled & 1 << side) == 0) {
|
||||
Block b = access.getBlock(pos.x, pos.y, pos.z);
|
||||
brightness[side] = access.getLightBrightnessForSkyBlocks(pos.x, pos.y, pos.z, b.getLightValue(access, pos.x, pos.y, pos.z));
|
||||
brightness[side] = access.getLightBrightnessForSkyBlocks(
|
||||
pos.x, pos.y, pos.z, b.getLightValue(access, pos.x, pos.y, pos.z));
|
||||
sampled |= 1 << side;
|
||||
}
|
||||
return brightness[side];
|
||||
|
||||
@@ -6,8 +6,7 @@ import codechicken.lib.render.CCRenderState;
|
||||
/**
|
||||
* Faster precomputed version of LightModel that only works for axis planar sides
|
||||
*/
|
||||
public class PlanarLightModel implements CCRenderState.IVertexOperation
|
||||
{
|
||||
public class PlanarLightModel implements CCRenderState.IVertexOperation {
|
||||
public static PlanarLightModel standardLightModel = LightModel.standardLightModel.reducePlanar();
|
||||
|
||||
public int[] colours;
|
||||
@@ -18,8 +17,7 @@ public class PlanarLightModel implements CCRenderState.IVertexOperation
|
||||
|
||||
@Override
|
||||
public boolean load() {
|
||||
if(!CCRenderState.computeLighting)
|
||||
return false;
|
||||
if (!CCRenderState.computeLighting) return false;
|
||||
|
||||
CCRenderState.pipeline.addDependency(CCRenderState.sideAttrib);
|
||||
CCRenderState.pipeline.addDependency(CCRenderState.colourAttrib);
|
||||
|
||||
@@ -8,8 +8,7 @@ import net.minecraft.world.IBlockAccess;
|
||||
/**
|
||||
* Faster precomputed version of LightModel that only works for axis planar sides
|
||||
*/
|
||||
public class SimpleBrightnessModel implements CCRenderState.IVertexOperation
|
||||
{
|
||||
public class SimpleBrightnessModel implements CCRenderState.IVertexOperation {
|
||||
public static final int operationIndex = CCRenderState.registerOperation();
|
||||
public static SimpleBrightnessModel instance = new SimpleBrightnessModel();
|
||||
|
||||
@@ -30,7 +29,8 @@ public class SimpleBrightnessModel implements CCRenderState.IVertexOperation
|
||||
if ((sampled & 1 << side) == 0) {
|
||||
c.set(pos).offset(side);
|
||||
Block block = access.getBlock(c.x, c.y, c.z);
|
||||
samples[side] = access.getLightBrightnessForSkyBlocks(c.x, c.y, c.z, block.getLightValue(access, c.x, c.y, c.z));
|
||||
samples[side] =
|
||||
access.getLightBrightnessForSkyBlocks(c.x, c.y, c.z, block.getLightValue(access, c.x, c.y, c.z));
|
||||
sampled |= 1 << side;
|
||||
}
|
||||
return samples[side];
|
||||
|
||||
@@ -1,59 +1,49 @@
|
||||
package codechicken.lib.math;
|
||||
|
||||
public class MathHelper
|
||||
{
|
||||
public class MathHelper {
|
||||
public static final double phi = 1.618033988749894;
|
||||
public static final double pi = Math.PI;
|
||||
public static final double todeg = 57.29577951308232;
|
||||
public static final double torad = 0.017453292519943;
|
||||
public static final double sqrt2 = 1.414213562373095;
|
||||
|
||||
|
||||
public static double[] SIN_TABLE = new double[65536];
|
||||
static
|
||||
{
|
||||
for (int i = 0; i < 65536; ++i)
|
||||
SIN_TABLE[i] = Math.sin(i / 65536D * 2 * Math.PI);
|
||||
|
||||
|
||||
static {
|
||||
for (int i = 0; i < 65536; ++i) SIN_TABLE[i] = Math.sin(i / 65536D * 2 * Math.PI);
|
||||
|
||||
SIN_TABLE[0] = 0;
|
||||
SIN_TABLE[16384] = 1;
|
||||
SIN_TABLE[32768] = 0;
|
||||
SIN_TABLE[49152] = 1;
|
||||
}
|
||||
|
||||
public static double sin(double d)
|
||||
{
|
||||
return SIN_TABLE[(int)((float)d * 10430.378F) & 65535];
|
||||
|
||||
public static double sin(double d) {
|
||||
return SIN_TABLE[(int) ((float) d * 10430.378F) & 65535];
|
||||
}
|
||||
|
||||
public static double cos(double d)
|
||||
{
|
||||
return SIN_TABLE[(int)((float)d * 10430.378F + 16384.0F) & 65535];
|
||||
|
||||
public static double cos(double d) {
|
||||
return SIN_TABLE[(int) ((float) d * 10430.378F + 16384.0F) & 65535];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param a The value
|
||||
* @param b The value to approach
|
||||
* @param max The maximum step
|
||||
* @return the closed value to b no less than max from a
|
||||
*/
|
||||
public static float approachLinear(float a, float b, float max)
|
||||
{
|
||||
return (a > b) ?
|
||||
(a - b < max ? b : a-max) :
|
||||
(b - a < max ? b : a+max);
|
||||
public static float approachLinear(float a, float b, float max) {
|
||||
return (a > b) ? (a - b < max ? b : a - max) : (b - a < max ? b : a + max);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param a The value
|
||||
* @param b The value to approach
|
||||
* @param max The maximum step
|
||||
* @return the closed value to b no less than max from a
|
||||
*/
|
||||
public static double approachLinear(double a, double b, double max)
|
||||
{
|
||||
return (a > b) ?
|
||||
(a - b < max ? b : a-max) :
|
||||
(b - a < max ? b : a+max);
|
||||
public static double approachLinear(double a, double b, double max) {
|
||||
return (a > b) ? (a - b < max ? b : a - max) : (b - a < max ? b : a + max);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -62,9 +52,8 @@ public class MathHelper
|
||||
* @param d The interpolation factor, between 0 and 1
|
||||
* @return a+(b-a)*d
|
||||
*/
|
||||
public static float interpolate(float a, float b, float d)
|
||||
{
|
||||
return a+(b-a)*d;
|
||||
public static float interpolate(float a, float b, float d) {
|
||||
return a + (b - a) * d;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -73,20 +62,18 @@ public class MathHelper
|
||||
* @param d The interpolation factor, between 0 and 1
|
||||
* @return a+(b-a)*d
|
||||
*/
|
||||
public static double interpolate(double a, double b, double d)
|
||||
{
|
||||
return a+(b-a)*d;
|
||||
public static double interpolate(double a, double b, double d) {
|
||||
return a + (b - a) * d;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param a The value
|
||||
* @param b The value to approach
|
||||
* @param ratio The ratio to reduce the difference by
|
||||
* @return a+(b-a)*ratio
|
||||
*/
|
||||
public static double approachExp(double a, double b, double ratio)
|
||||
{
|
||||
return a+(b-a)*ratio;
|
||||
public static double approachExp(double a, double b, double ratio) {
|
||||
return a + (b - a) * ratio;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -96,12 +83,10 @@ public class MathHelper
|
||||
* @param cap The maximum amount to advance by
|
||||
* @return a+(b-a)*ratio
|
||||
*/
|
||||
public static double approachExp(double a, double b, double ratio, double cap)
|
||||
{
|
||||
double d = (b-a)*ratio;
|
||||
if(Math.abs(d) > cap)
|
||||
d = Math.signum(d)*cap;
|
||||
return a+d;
|
||||
public static double approachExp(double a, double b, double ratio, double cap) {
|
||||
double d = (b - a) * ratio;
|
||||
if (Math.abs(d) > cap) d = Math.signum(d) * cap;
|
||||
return a + d;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -112,67 +97,55 @@ public class MathHelper
|
||||
* @param kick The difference when a == c
|
||||
* @return
|
||||
*/
|
||||
public static double retreatExp(double a, double b, double c, double ratio, double kick)
|
||||
{
|
||||
double d = (Math.abs(c-a)+kick)*ratio;
|
||||
if(d > Math.abs(b-a))
|
||||
return b;
|
||||
return a+Math.signum(b-a)*d;
|
||||
public static double retreatExp(double a, double b, double c, double ratio, double kick) {
|
||||
double d = (Math.abs(c - a) + kick) * ratio;
|
||||
if (d > Math.abs(b - a)) return b;
|
||||
return a + Math.signum(b - a) * d;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param value The value
|
||||
* @param min The min value
|
||||
* @param max The max value
|
||||
* @return The clipped value between min and max
|
||||
*/
|
||||
public static double clip(double value, double min, double max)
|
||||
{
|
||||
if(value > max)
|
||||
value = max;
|
||||
if(value < min)
|
||||
value = min;
|
||||
public static double clip(double value, double min, double max) {
|
||||
if (value > max) value = max;
|
||||
if (value < min) value = min;
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a <= x <= b
|
||||
*/
|
||||
public static boolean between(double a, double x, double b)
|
||||
{
|
||||
public static boolean between(double a, double x, double b) {
|
||||
return a <= x && x <= b;
|
||||
}
|
||||
|
||||
public static int approachExpI(int a, int b, double ratio)
|
||||
{
|
||||
int r = (int)Math.round(approachExp(a, b, ratio));
|
||||
public static int approachExpI(int a, int b, double ratio) {
|
||||
int r = (int) Math.round(approachExp(a, b, ratio));
|
||||
return r == a ? b : r;
|
||||
}
|
||||
|
||||
public static int retreatExpI(int a, int b, int c, double ratio, int kick)
|
||||
{
|
||||
int r = (int)Math.round(retreatExp(a, b, c, ratio, kick));
|
||||
public static int retreatExpI(int a, int b, int c, double ratio, int kick) {
|
||||
int r = (int) Math.round(retreatExp(a, b, c, ratio, kick));
|
||||
return r == a ? b : r;
|
||||
}
|
||||
|
||||
public static int floor_double(double d)
|
||||
{
|
||||
|
||||
public static int floor_double(double d) {
|
||||
return net.minecraft.util.MathHelper.floor_double(d);
|
||||
}
|
||||
|
||||
public static int roundAway(double d)
|
||||
{
|
||||
|
||||
public static int roundAway(double d) {
|
||||
return (int) (d < 0 ? Math.floor(d) : Math.ceil(d));
|
||||
}
|
||||
|
||||
public static int compare(int a, int b)
|
||||
{
|
||||
|
||||
public static int compare(int a, int b) {
|
||||
return a == b ? 0 : a < b ? -1 : 1;
|
||||
}
|
||||
|
||||
public static int compare(double a, double b)
|
||||
{
|
||||
|
||||
public static int compare(double a, double b) {
|
||||
return a == b ? 0 : a < b ? -1 : 1;
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
package codechicken.lib.packet;
|
||||
|
||||
public interface ICustomPacketTile
|
||||
{
|
||||
public interface ICustomPacketTile {
|
||||
public void handleDescriptionPacket(PacketCustom packet);
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
package codechicken.lib.packet;
|
||||
|
||||
|
||||
import codechicken.lib.data.MCDataInput;
|
||||
import codechicken.lib.data.MCDataOutput;
|
||||
import codechicken.lib.vec.BlockCoord;
|
||||
@@ -19,6 +18,10 @@ import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.ChannelInboundHandlerAdapter;
|
||||
import io.netty.channel.SimpleChannelInboundHandler;
|
||||
import io.netty.util.AttributeKey;
|
||||
import java.util.EnumMap;
|
||||
import java.util.List;
|
||||
import java.util.zip.Deflater;
|
||||
import java.util.zip.Inflater;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
@@ -38,32 +41,21 @@ import net.minecraftforge.fluids.Fluid;
|
||||
import net.minecraftforge.fluids.FluidRegistry;
|
||||
import net.minecraftforge.fluids.FluidStack;
|
||||
|
||||
import java.util.EnumMap;
|
||||
import java.util.List;
|
||||
import java.util.zip.Deflater;
|
||||
import java.util.zip.Inflater;
|
||||
public final class PacketCustom implements MCDataInput, MCDataOutput {
|
||||
public static interface ICustomPacketHandler {}
|
||||
|
||||
public final class PacketCustom implements MCDataInput, MCDataOutput
|
||||
{
|
||||
public static interface ICustomPacketHandler
|
||||
{
|
||||
}
|
||||
|
||||
public interface IClientPacketHandler extends ICustomPacketHandler
|
||||
{
|
||||
public interface IClientPacketHandler extends ICustomPacketHandler {
|
||||
public void handlePacket(PacketCustom packetCustom, Minecraft mc, INetHandlerPlayClient handler);
|
||||
}
|
||||
|
||||
public interface IServerPacketHandler extends ICustomPacketHandler
|
||||
{
|
||||
public interface IServerPacketHandler extends ICustomPacketHandler {
|
||||
public void handlePacket(PacketCustom packetCustom, EntityPlayerMP sender, INetHandlerPlayServer handler);
|
||||
}
|
||||
|
||||
public static AttributeKey<CustomInboundHandler> cclHandler = new AttributeKey<CustomInboundHandler>("ccl:handler");
|
||||
|
||||
@ChannelHandler.Sharable
|
||||
public static class CustomInboundHandler extends SimpleChannelInboundHandler<FMLProxyPacket>
|
||||
{
|
||||
public static class CustomInboundHandler extends SimpleChannelInboundHandler<FMLProxyPacket> {
|
||||
public EnumMap<Side, CustomHandler> handlers = Maps.newEnumMap(Side.class);
|
||||
|
||||
@Override
|
||||
@@ -75,19 +67,18 @@ public final class PacketCustom implements MCDataInput, MCDataOutput
|
||||
@Override
|
||||
protected void channelRead0(ChannelHandlerContext ctx, FMLProxyPacket msg) throws Exception {
|
||||
handlers.get(ctx.channel().attr(NetworkRegistry.CHANNEL_SOURCE).get())
|
||||
.handle(ctx.channel().attr(NetworkRegistry.NET_HANDLER).get(),
|
||||
.handle(
|
||||
ctx.channel().attr(NetworkRegistry.NET_HANDLER).get(),
|
||||
ctx.channel().attr(NetworkRegistry.FML_CHANNEL).get(),
|
||||
new PacketCustom(msg.payload()));
|
||||
}
|
||||
}
|
||||
|
||||
private static interface CustomHandler
|
||||
{
|
||||
private static interface CustomHandler {
|
||||
public void handle(INetHandler handler, String channel, PacketCustom packet) throws Exception;
|
||||
}
|
||||
|
||||
public static class ClientInboundHandler implements CustomHandler
|
||||
{
|
||||
public static class ClientInboundHandler implements CustomHandler {
|
||||
private IClientPacketHandler handler;
|
||||
|
||||
public ClientInboundHandler(ICustomPacketHandler handler) {
|
||||
@@ -98,13 +89,11 @@ public final class PacketCustom implements MCDataInput, MCDataOutput
|
||||
public void handle(INetHandler netHandler, String channel, PacketCustom packet) throws Exception {
|
||||
if (netHandler instanceof INetHandlerPlayClient)
|
||||
handler.handlePacket(packet, Minecraft.getMinecraft(), (INetHandlerPlayClient) netHandler);
|
||||
else
|
||||
System.err.println("Invalid INetHandler for PacketCustom on channel: " + channel);
|
||||
else System.err.println("Invalid INetHandler for PacketCustom on channel: " + channel);
|
||||
}
|
||||
}
|
||||
|
||||
public static class ServerInboundHandler implements CustomHandler
|
||||
{
|
||||
public static class ServerInboundHandler implements CustomHandler {
|
||||
private IServerPacketHandler handler;
|
||||
|
||||
public ServerInboundHandler(ICustomPacketHandler handler) {
|
||||
@@ -114,19 +103,17 @@ public final class PacketCustom implements MCDataInput, MCDataOutput
|
||||
@Override
|
||||
public void handle(INetHandler netHandler, String channel, PacketCustom packet) throws Exception {
|
||||
if (netHandler instanceof NetHandlerPlayServer)
|
||||
handler.handlePacket(packet, ((NetHandlerPlayServer) netHandler).playerEntity, (INetHandlerPlayServer) netHandler);
|
||||
else
|
||||
System.err.println("Invalid INetHandler for PacketCustom on channel: " + channel);
|
||||
handler.handlePacket(
|
||||
packet, ((NetHandlerPlayServer) netHandler).playerEntity, (INetHandlerPlayServer) netHandler);
|
||||
else System.err.println("Invalid INetHandler for PacketCustom on channel: " + channel);
|
||||
}
|
||||
}
|
||||
|
||||
public static interface IHandshakeHandler
|
||||
{
|
||||
public static interface IHandshakeHandler {
|
||||
public void handshakeRecieved(NetHandlerPlayServer netHandler);
|
||||
}
|
||||
|
||||
public static class HandshakeInboundHandler extends ChannelInboundHandlerAdapter
|
||||
{
|
||||
public static class HandshakeInboundHandler extends ChannelInboundHandlerAdapter {
|
||||
public IHandshakeHandler handler;
|
||||
|
||||
public HandshakeInboundHandler(IHandshakeHandler handler) {
|
||||
@@ -136,25 +123,27 @@ public final class PacketCustom implements MCDataInput, MCDataOutput
|
||||
@Override
|
||||
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
|
||||
if (evt instanceof NetworkHandshakeEstablished) {
|
||||
INetHandler netHandler = ((NetworkDispatcher) ctx.channel().attr(FMLOutboundHandler.FML_MESSAGETARGETARGS).get()).getNetHandler();
|
||||
INetHandler netHandler = ((NetworkDispatcher) ctx.channel()
|
||||
.attr(FMLOutboundHandler.FML_MESSAGETARGETARGS)
|
||||
.get())
|
||||
.getNetHandler();
|
||||
if (netHandler instanceof NetHandlerPlayServer)
|
||||
handler.handshakeRecieved((NetHandlerPlayServer) netHandler);
|
||||
} else
|
||||
ctx.fireUserEventTriggered(evt);
|
||||
} else ctx.fireUserEventTriggered(evt);
|
||||
}
|
||||
}
|
||||
|
||||
public static String channelName(Object channelKey) {
|
||||
if (channelKey instanceof String)
|
||||
return (String) channelKey;
|
||||
if (channelKey instanceof String) return (String) channelKey;
|
||||
|
||||
ModContainer mc = channelKey instanceof ModContainer ?
|
||||
(ModContainer) channelKey :
|
||||
FMLCommonHandler.instance().findContainerFor(channelKey);
|
||||
ModContainer mc = channelKey instanceof ModContainer
|
||||
? (ModContainer) channelKey
|
||||
: FMLCommonHandler.instance().findContainerFor(channelKey);
|
||||
if (mc != null) {
|
||||
String s = mc.getModId();
|
||||
if(s.length() > 20)
|
||||
throw new IllegalArgumentException("Mod ID ("+s+") too long for use as channel (20 chars). Use a string identifier");
|
||||
if (s.length() > 20)
|
||||
throw new IllegalArgumentException(
|
||||
"Mod ID (" + s + ") too long for use as channel (20 chars). Use a string identifier");
|
||||
return s;
|
||||
}
|
||||
|
||||
@@ -171,7 +160,10 @@ public final class PacketCustom implements MCDataInput, MCDataOutput
|
||||
String channelName = channelName(channelKey);
|
||||
Side side = handler instanceof IServerPacketHandler ? Side.SERVER : Side.CLIENT;
|
||||
FMLEmbeddedChannel channel = getOrCreateChannel(channelName, side);
|
||||
channel.attr(cclHandler).get().handlers.put(side, side == Side.SERVER ? new ServerInboundHandler(handler) : new ClientInboundHandler(handler));
|
||||
channel.attr(cclHandler)
|
||||
.get()
|
||||
.handlers
|
||||
.put(side, side == Side.SERVER ? new ServerInboundHandler(handler) : new ClientInboundHandler(handler));
|
||||
}
|
||||
|
||||
public static void assignHandshakeHandler(Object channelKey, IHandshakeHandler handler) {
|
||||
@@ -187,8 +179,7 @@ public final class PacketCustom implements MCDataInput, MCDataOutput
|
||||
byteBuf = payload;
|
||||
|
||||
type = byteBuf.readUnsignedByte();
|
||||
if (type > 0x80)
|
||||
decompress();
|
||||
if (type > 0x80) decompress();
|
||||
type &= 0x7F;
|
||||
}
|
||||
|
||||
@@ -233,8 +224,8 @@ public final class PacketCustom implements MCDataInput, MCDataOutput
|
||||
deflater.finish();
|
||||
ByteBuf out = Unpooled.buffer(len + 5);
|
||||
int clen = deflater.deflate(out.array(), 5, len);
|
||||
if (clen >= len - 5 || !deflater.finished())//not worth compressing, gets larger
|
||||
return;
|
||||
if (clen >= len - 5 || !deflater.finished()) // not worth compressing, gets larger
|
||||
return;
|
||||
|
||||
out.setByte(0, type | 0x80);
|
||||
out.setInt(1, len);
|
||||
@@ -261,10 +252,8 @@ public final class PacketCustom implements MCDataInput, MCDataOutput
|
||||
}
|
||||
|
||||
public PacketCustom compress() {
|
||||
if (incoming())
|
||||
throw new IllegalStateException("Tried to compress an incoming packet");
|
||||
if ((type & 0x80) != 0)
|
||||
throw new IllegalStateException("Packet already compressed");
|
||||
if (incoming()) throw new IllegalStateException("Tried to compress an incoming packet");
|
||||
if ((type & 0x80) != 0) throw new IllegalStateException("Packet already compressed");
|
||||
type |= 0x80;
|
||||
return this;
|
||||
}
|
||||
@@ -354,10 +343,8 @@ public final class PacketCustom implements MCDataInput, MCDataOutput
|
||||
writeShort(-1);
|
||||
} else {
|
||||
writeShort(Item.getIdFromItem(stack.getItem()));
|
||||
if (large)
|
||||
writeInt(stack.stackSize);
|
||||
else
|
||||
writeByte(stack.stackSize);
|
||||
if (large) writeInt(stack.stackSize);
|
||||
else writeByte(stack.stackSize);
|
||||
writeShort(stack.getItemDamage());
|
||||
writeNBTTagCompound(stack.stackTagCompound);
|
||||
}
|
||||
@@ -468,20 +455,17 @@ public final class PacketCustom implements MCDataInput, MCDataOutput
|
||||
|
||||
public FluidStack readFluidStack() {
|
||||
Fluid fluid = FluidRegistry.getFluid(readShort());
|
||||
if(fluid == null)
|
||||
fluid = FluidRegistry.WATER;
|
||||
if (fluid == null) fluid = FluidRegistry.WATER;
|
||||
|
||||
return new FluidStack(fluid, readVarInt(), readNBTTagCompound());
|
||||
}
|
||||
|
||||
public FMLProxyPacket toPacket() {
|
||||
if (incoming())
|
||||
throw new IllegalStateException("Tried to write an incoming packet");
|
||||
if (incoming()) throw new IllegalStateException("Tried to write an incoming packet");
|
||||
|
||||
if (byteBuf.readableBytes() > 32000 || (type & 0x80) != 0)
|
||||
do_compress();
|
||||
if (byteBuf.readableBytes() > 32000 || (type & 0x80) != 0) do_compress();
|
||||
|
||||
//FML packet impl returns the whole of the backing array, copy used portion of array to another ByteBuf
|
||||
// FML packet impl returns the whole of the backing array, copy used portion of array to another ByteBuf
|
||||
return new FMLProxyPacket(byteBuf.copy(), channel);
|
||||
}
|
||||
|
||||
@@ -490,10 +474,8 @@ public final class PacketCustom implements MCDataInput, MCDataOutput
|
||||
}
|
||||
|
||||
public static void sendToPlayer(Packet packet, EntityPlayer player) {
|
||||
if (player == null)
|
||||
sendToClients(packet);
|
||||
else
|
||||
((EntityPlayerMP) player).playerNetServerHandler.sendPacket(packet);
|
||||
if (player == null) sendToClients(packet);
|
||||
else ((EntityPlayerMP) player).playerNetServerHandler.sendPacket(packet);
|
||||
}
|
||||
|
||||
public void sendToClients() {
|
||||
@@ -525,10 +507,10 @@ public final class PacketCustom implements MCDataInput, MCDataOutput
|
||||
}
|
||||
|
||||
public static void sendToChunk(Packet packet, World world, int chunkX, int chunkZ) {
|
||||
PlayerManager playerManager = ((WorldServer)world).getPlayerManager();
|
||||
for (EntityPlayerMP player : (List<EntityPlayerMP>) MinecraftServer.getServer().getConfigurationManager().playerEntityList)
|
||||
if(playerManager.isPlayerWatchingChunk(player, chunkX, chunkZ))
|
||||
sendToPlayer(packet, player);
|
||||
PlayerManager playerManager = ((WorldServer) world).getPlayerManager();
|
||||
for (EntityPlayerMP player :
|
||||
(List<EntityPlayerMP>) MinecraftServer.getServer().getConfigurationManager().playerEntityList)
|
||||
if (playerManager.isPlayerWatchingChunk(player, chunkX, chunkZ)) sendToPlayer(packet, player);
|
||||
|
||||
/* Commented until forge accepts access tranformer request
|
||||
PlayerInstance p = ((WorldServer) world).getPlayerManager().getOrCreateChunkWatcher(chunkX, chunkZ, false);
|
||||
@@ -541,7 +523,8 @@ public final class PacketCustom implements MCDataInput, MCDataOutput
|
||||
}
|
||||
|
||||
public static void sendToOps(Packet packet) {
|
||||
for (EntityPlayerMP player : (List<EntityPlayerMP>) MinecraftServer.getServer().getConfigurationManager().playerEntityList)
|
||||
for (EntityPlayerMP player :
|
||||
(List<EntityPlayerMP>) MinecraftServer.getServer().getConfigurationManager().playerEntityList)
|
||||
if (MinecraftServer.getServer().getConfigurationManager().func_152596_g(player.getGameProfile()))
|
||||
sendToPlayer(packet, player);
|
||||
}
|
||||
|
||||
@@ -4,28 +4,24 @@ import net.minecraft.entity.Entity;
|
||||
import net.minecraft.util.MovingObjectPosition;
|
||||
import net.minecraft.util.Vec3;
|
||||
|
||||
public class ExtendedMOP extends MovingObjectPosition implements Comparable<ExtendedMOP>
|
||||
{
|
||||
public class ExtendedMOP extends MovingObjectPosition implements Comparable<ExtendedMOP> {
|
||||
public Object data;
|
||||
/**
|
||||
* The square distance from the start of the raytrace.
|
||||
*/
|
||||
public double dist;
|
||||
|
||||
public ExtendedMOP(Entity entity, Object data)
|
||||
{
|
||||
|
||||
public ExtendedMOP(Entity entity, Object data) {
|
||||
super(entity);
|
||||
setData(data);
|
||||
}
|
||||
|
||||
public ExtendedMOP(int x, int y, int z, int side, Vec3 hit, Object data)
|
||||
{
|
||||
|
||||
public ExtendedMOP(int x, int y, int z, int side, Vec3 hit, Object data) {
|
||||
super(x, y, z, side, hit);
|
||||
setData(data);
|
||||
}
|
||||
|
||||
public ExtendedMOP(MovingObjectPosition mop, Object data, double dist)
|
||||
{
|
||||
|
||||
public ExtendedMOP(MovingObjectPosition mop, Object data, double dist) {
|
||||
super(0, 0, 0, 0, mop.hitVec);
|
||||
typeOfHit = mop.typeOfHit;
|
||||
blockX = mop.blockX;
|
||||
@@ -37,25 +33,20 @@ public class ExtendedMOP extends MovingObjectPosition implements Comparable<Exte
|
||||
this.dist = dist;
|
||||
}
|
||||
|
||||
public void setData(Object data)
|
||||
{
|
||||
if(data instanceof Integer)
|
||||
subHit = ((Integer) data).intValue();
|
||||
public void setData(Object data) {
|
||||
if (data instanceof Integer) subHit = ((Integer) data).intValue();
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> T getData(MovingObjectPosition mop)
|
||||
{
|
||||
if(mop instanceof ExtendedMOP)
|
||||
return (T)((ExtendedMOP)mop).data;
|
||||
|
||||
return (T)Integer.valueOf(mop.subHit);
|
||||
public static <T> T getData(MovingObjectPosition mop) {
|
||||
if (mop instanceof ExtendedMOP) return (T) ((ExtendedMOP) mop).data;
|
||||
|
||||
return (T) Integer.valueOf(mop.subHit);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int compareTo(ExtendedMOP o)
|
||||
{
|
||||
public int compareTo(ExtendedMOP o) {
|
||||
return dist == o.dist ? 0 : dist < o.dist ? -1 : 1;
|
||||
}
|
||||
}
|
||||
@@ -2,13 +2,11 @@ package codechicken.lib.raytracer;
|
||||
|
||||
import codechicken.lib.vec.Cuboid6;
|
||||
|
||||
public class IndexedCuboid6 extends Cuboid6
|
||||
{
|
||||
public class IndexedCuboid6 extends Cuboid6 {
|
||||
public Object data;
|
||||
|
||||
public IndexedCuboid6(Object data, Cuboid6 cuboid)
|
||||
{
|
||||
|
||||
public IndexedCuboid6(Object data, Cuboid6 cuboid) {
|
||||
super(cuboid);
|
||||
this.data = data;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,9 +6,9 @@ import codechicken.lib.vec.Cuboid6;
|
||||
import codechicken.lib.vec.Vector3;
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
import java.util.List;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraft.util.MovingObjectPosition;
|
||||
@@ -16,10 +16,7 @@ import net.minecraft.util.MovingObjectPosition.MovingObjectType;
|
||||
import net.minecraft.util.Vec3;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class RayTracer
|
||||
{
|
||||
public class RayTracer {
|
||||
private Vector3 vec = new Vector3();
|
||||
private Vector3 vec2 = new Vector3();
|
||||
|
||||
@@ -27,23 +24,19 @@ public class RayTracer
|
||||
private double s_dist;
|
||||
private int s_side;
|
||||
private IndexedCuboid6 c_cuboid;
|
||||
|
||||
|
||||
private static ThreadLocal<RayTracer> t_inst = new ThreadLocal<RayTracer>();
|
||||
|
||||
public static RayTracer instance()
|
||||
{
|
||||
|
||||
public static RayTracer instance() {
|
||||
RayTracer inst = t_inst.get();
|
||||
if(inst == null)
|
||||
t_inst.set(inst = new RayTracer());
|
||||
if (inst == null) t_inst.set(inst = new RayTracer());
|
||||
return inst;
|
||||
}
|
||||
|
||||
private void traceSide(int side, Vector3 start, Vector3 end, Cuboid6 cuboid)
|
||||
{
|
||||
|
||||
private void traceSide(int side, Vector3 start, Vector3 end, Cuboid6 cuboid) {
|
||||
vec.set(start);
|
||||
Vector3 hit = null;
|
||||
switch(side)
|
||||
{
|
||||
switch (side) {
|
||||
case 0:
|
||||
hit = vec.XZintercept(end, cuboid.min.y);
|
||||
break;
|
||||
@@ -63,87 +56,78 @@ public class RayTracer
|
||||
hit = vec.YZintercept(end, cuboid.max.x);
|
||||
break;
|
||||
}
|
||||
if(hit == null)
|
||||
return;
|
||||
|
||||
switch(side)
|
||||
{
|
||||
if (hit == null) return;
|
||||
|
||||
switch (side) {
|
||||
case 0:
|
||||
case 1:
|
||||
if(!MathHelper.between(cuboid.min.x, hit.x, cuboid.max.x) || !MathHelper.between(cuboid.min.z, hit.z, cuboid.max.z)) return;
|
||||
if (!MathHelper.between(cuboid.min.x, hit.x, cuboid.max.x)
|
||||
|| !MathHelper.between(cuboid.min.z, hit.z, cuboid.max.z)) return;
|
||||
break;
|
||||
case 2:
|
||||
case 3:
|
||||
if(!MathHelper.between(cuboid.min.x, hit.x, cuboid.max.x) || !MathHelper.between(cuboid.min.y, hit.y, cuboid.max.y)) return;
|
||||
if (!MathHelper.between(cuboid.min.x, hit.x, cuboid.max.x)
|
||||
|| !MathHelper.between(cuboid.min.y, hit.y, cuboid.max.y)) return;
|
||||
break;
|
||||
case 4:
|
||||
case 5:
|
||||
if(!MathHelper.between(cuboid.min.y, hit.y, cuboid.max.y) || !MathHelper.between(cuboid.min.z, hit.z, cuboid.max.z)) return;
|
||||
if (!MathHelper.between(cuboid.min.y, hit.y, cuboid.max.y)
|
||||
|| !MathHelper.between(cuboid.min.z, hit.z, cuboid.max.z)) return;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
double dist = vec2.set(hit).subtract(start).magSquared();
|
||||
if(dist < s_dist)
|
||||
{
|
||||
if (dist < s_dist) {
|
||||
s_side = side;
|
||||
s_dist = dist;
|
||||
s_vec.set(vec);
|
||||
}
|
||||
}
|
||||
|
||||
public MovingObjectPosition rayTraceCuboid(Vector3 start, Vector3 end, Cuboid6 cuboid)
|
||||
{
|
||||
|
||||
public MovingObjectPosition rayTraceCuboid(Vector3 start, Vector3 end, Cuboid6 cuboid) {
|
||||
s_dist = Double.MAX_VALUE;
|
||||
s_side = -1;
|
||||
|
||||
for(int i = 0; i < 6; i++)
|
||||
traceSide(i, start, end, cuboid);
|
||||
|
||||
if(s_side < 0)
|
||||
return null;
|
||||
|
||||
|
||||
for (int i = 0; i < 6; i++) traceSide(i, start, end, cuboid);
|
||||
|
||||
if (s_side < 0) return null;
|
||||
|
||||
MovingObjectPosition mop = new MovingObjectPosition(0, 0, 0, s_side, s_vec.toVec3D());
|
||||
mop.typeOfHit = null;
|
||||
return mop;
|
||||
}
|
||||
|
||||
public MovingObjectPosition rayTraceCuboids(Vector3 start, Vector3 end, List<IndexedCuboid6> cuboids)
|
||||
{
|
||||
public MovingObjectPosition rayTraceCuboids(Vector3 start, Vector3 end, List<IndexedCuboid6> cuboids) {
|
||||
double c_dist = Double.MAX_VALUE;
|
||||
MovingObjectPosition c_hit = null;
|
||||
|
||||
for(IndexedCuboid6 cuboid : cuboids)
|
||||
{
|
||||
|
||||
for (IndexedCuboid6 cuboid : cuboids) {
|
||||
MovingObjectPosition mop = rayTraceCuboid(start, end, cuboid);
|
||||
if(mop != null && s_dist < c_dist)
|
||||
{
|
||||
if (mop != null && s_dist < c_dist) {
|
||||
mop = new ExtendedMOP(mop, cuboid.data, s_dist);
|
||||
c_dist = s_dist;
|
||||
c_hit = mop;
|
||||
c_cuboid = cuboid;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return c_hit;
|
||||
}
|
||||
|
||||
public MovingObjectPosition rayTraceCuboids(Vector3 start, Vector3 end, List<IndexedCuboid6> cuboids, BlockCoord pos, Block block)
|
||||
{
|
||||
public MovingObjectPosition rayTraceCuboids(
|
||||
Vector3 start, Vector3 end, List<IndexedCuboid6> cuboids, BlockCoord pos, Block block) {
|
||||
MovingObjectPosition mop = rayTraceCuboids(start, end, cuboids);
|
||||
if(mop != null)
|
||||
{
|
||||
if (mop != null) {
|
||||
mop.typeOfHit = MovingObjectType.BLOCK;
|
||||
mop.blockX = pos.x;
|
||||
mop.blockY = pos.y;
|
||||
mop.blockZ = pos.z;
|
||||
if(block != null)
|
||||
c_cuboid.add(new Vector3(-pos.x, -pos.y, -pos.z)).setBlockBounds(block);
|
||||
if (block != null) c_cuboid.add(new Vector3(-pos.x, -pos.y, -pos.z)).setBlockBounds(block);
|
||||
}
|
||||
return mop;
|
||||
}
|
||||
|
||||
public static MovingObjectPosition retraceBlock(World world, EntityPlayer player, int x, int y, int z)
|
||||
{
|
||||
public static MovingObjectPosition retraceBlock(World world, EntityPlayer player, int x, int y, int z) {
|
||||
Block block = world.getBlock(x, y, z);
|
||||
|
||||
Vec3 headVec = getCorrectedHeadVec(player);
|
||||
@@ -153,56 +137,49 @@ public class RayTracer
|
||||
return block.collisionRayTrace(world, x, y, z, headVec, endVec);
|
||||
}
|
||||
|
||||
private static double getBlockReachDistance_server(EntityPlayerMP player)
|
||||
{
|
||||
private static double getBlockReachDistance_server(EntityPlayerMP player) {
|
||||
return player.theItemInWorldManager.getBlockReachDistance();
|
||||
}
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
private static double getBlockReachDistance_client()
|
||||
{
|
||||
private static double getBlockReachDistance_client() {
|
||||
return Minecraft.getMinecraft().playerController.getBlockReachDistance();
|
||||
}
|
||||
|
||||
public static MovingObjectPosition reTrace(World world, EntityPlayer player)
|
||||
{
|
||||
|
||||
public static MovingObjectPosition reTrace(World world, EntityPlayer player) {
|
||||
return reTrace(world, player, getBlockReachDistance(player));
|
||||
}
|
||||
|
||||
public static MovingObjectPosition reTrace(World world, EntityPlayer player, double reach)
|
||||
{
|
||||
public static MovingObjectPosition reTrace(World world, EntityPlayer player, double reach) {
|
||||
Vec3 headVec = getCorrectedHeadVec(player);
|
||||
Vec3 lookVec = player.getLook(1);
|
||||
Vec3 endVec = headVec.addVector(lookVec.xCoord * reach, lookVec.yCoord * reach, lookVec.zCoord * reach);
|
||||
return world.func_147447_a(headVec, endVec, true, false, true);
|
||||
}
|
||||
|
||||
public static Vec3 getCorrectedHeadVec(EntityPlayer player)
|
||||
{
|
||||
|
||||
public static Vec3 getCorrectedHeadVec(EntityPlayer player) {
|
||||
Vec3 v = Vec3.createVectorHelper(player.posX, player.posY, player.posZ);
|
||||
if(player.worldObj.isRemote) {
|
||||
v.yCoord+=player.getEyeHeight()-player.getDefaultEyeHeight();//compatibility with eye height changing mods
|
||||
if (player.worldObj.isRemote) {
|
||||
v.yCoord +=
|
||||
player.getEyeHeight() - player.getDefaultEyeHeight(); // compatibility with eye height changing mods
|
||||
} else {
|
||||
v.yCoord+=player.getEyeHeight();
|
||||
if(player instanceof EntityPlayerMP && player.isSneaking())
|
||||
v.yCoord-=0.08;
|
||||
v.yCoord += player.getEyeHeight();
|
||||
if (player instanceof EntityPlayerMP && player.isSneaking()) v.yCoord -= 0.08;
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
public static Vec3 getStartVec(EntityPlayer player)
|
||||
{
|
||||
|
||||
public static Vec3 getStartVec(EntityPlayer player) {
|
||||
return getCorrectedHeadVec(player);
|
||||
}
|
||||
|
||||
public static double getBlockReachDistance(EntityPlayer player)
|
||||
{
|
||||
return player.worldObj.isRemote ? getBlockReachDistance_client() :
|
||||
player instanceof EntityPlayerMP ? getBlockReachDistance_server((EntityPlayerMP) player) : 5D;
|
||||
|
||||
public static double getBlockReachDistance(EntityPlayer player) {
|
||||
return player.worldObj.isRemote
|
||||
? getBlockReachDistance_client()
|
||||
: player instanceof EntityPlayerMP ? getBlockReachDistance_server((EntityPlayerMP) player) : 5D;
|
||||
}
|
||||
|
||||
public static Vec3 getEndVec(EntityPlayer player)
|
||||
{
|
||||
|
||||
public static Vec3 getEndVec(EntityPlayer player) {
|
||||
Vec3 headVec = getCorrectedHeadVec(player);
|
||||
Vec3 lookVec = player.getLook(1.0F);
|
||||
double reach = getBlockReachDistance(player);
|
||||
|
||||
@@ -4,12 +4,10 @@ import codechicken.lib.lighting.LC;
|
||||
import codechicken.lib.render.CCRenderState.VertexAttribute;
|
||||
import codechicken.lib.vec.Cuboid6;
|
||||
|
||||
public class BlockRenderer
|
||||
{
|
||||
public static class BlockFace implements CCRenderState.IVertexSource
|
||||
{
|
||||
public Vertex5[] verts = new Vertex5[]{new Vertex5(), new Vertex5(), new Vertex5(), new Vertex5()};
|
||||
public LC[] lightCoords = new LC[]{new LC(), new LC(), new LC(), new LC()};
|
||||
public class BlockRenderer {
|
||||
public static class BlockFace implements CCRenderState.IVertexSource {
|
||||
public Vertex5[] verts = new Vertex5[] {new Vertex5(), new Vertex5(), new Vertex5(), new Vertex5()};
|
||||
public LC[] lightCoords = new LC[] {new LC(), new LC(), new LC(), new LC()};
|
||||
public boolean lcComputed = false;
|
||||
public int side;
|
||||
|
||||
@@ -20,7 +18,7 @@ public class BlockRenderer
|
||||
|
||||
@Override
|
||||
public <T> T getAttributes(CCRenderState.VertexAttribute<T> attr) {
|
||||
return attr == CCRenderState.lightCoordAttrib && lcComputed ? (T)lightCoords : null;
|
||||
return attr == CCRenderState.lightCoordAttrib && lcComputed ? (T) lightCoords : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -34,9 +32,8 @@ public class BlockRenderer
|
||||
}
|
||||
|
||||
public BlockFace computeLightCoords() {
|
||||
if(!lcComputed) {
|
||||
for (int i = 0; i < 4; i++)
|
||||
lightCoords[i].compute(verts[i].vec, side);
|
||||
if (!lcComputed) {
|
||||
for (int i = 0; i < 4; i++) lightCoords[i].compute(verts[i].vec, side);
|
||||
lcComputed = true;
|
||||
}
|
||||
return this;
|
||||
@@ -49,54 +46,69 @@ public class BlockRenderer
|
||||
double y2 = c.max.y;
|
||||
double z1 = c.min.z;
|
||||
double z2 = c.max.z;
|
||||
double u1; double u2; double v1; double v2;
|
||||
double u1;
|
||||
double u2;
|
||||
double v1;
|
||||
double v2;
|
||||
this.side = side;
|
||||
lcComputed = false;
|
||||
|
||||
switch(side) {
|
||||
switch (side) {
|
||||
case 0:
|
||||
u1 = x1; v1 = z1;
|
||||
u2 = x2; v2 = z2;
|
||||
u1 = x1;
|
||||
v1 = z1;
|
||||
u2 = x2;
|
||||
v2 = z2;
|
||||
verts[0].set(x1, y1, z2, u1, v2, 0);
|
||||
verts[1].set(x1, y1, z1, u1, v1, 0);
|
||||
verts[2].set(x2, y1, z1, u2, v1, 0);
|
||||
verts[3].set(x2, y1, z2, u2, v2, 0);
|
||||
break;
|
||||
case 1:
|
||||
u1 = x1; v1 = z1;
|
||||
u2 = x2; v2 = z2;
|
||||
u1 = x1;
|
||||
v1 = z1;
|
||||
u2 = x2;
|
||||
v2 = z2;
|
||||
verts[0].set(x2, y2, z2, u2, v2, 1);
|
||||
verts[1].set(x2, y2, z1, u2, v1, 1);
|
||||
verts[2].set(x1, y2, z1, u1, v1, 1);
|
||||
verts[3].set(x1, y2, z2, u1, v2, 1);
|
||||
break;
|
||||
case 2:
|
||||
u1 = 1-x1; v1 = 1-y2;
|
||||
u2 = 1-x2; v2 = 1-y1;
|
||||
u1 = 1 - x1;
|
||||
v1 = 1 - y2;
|
||||
u2 = 1 - x2;
|
||||
v2 = 1 - y1;
|
||||
verts[0].set(x1, y1, z1, u1, v2, 2);
|
||||
verts[1].set(x1, y2, z1, u1, v1, 2);
|
||||
verts[2].set(x2, y2, z1, u2, v1, 2);
|
||||
verts[3].set(x2, y1, z1, u2, v2, 2);
|
||||
break;
|
||||
case 3:
|
||||
u1 = x1; v1 = 1-y2;
|
||||
u2 = x2; v2 = 1-y1;
|
||||
u1 = x1;
|
||||
v1 = 1 - y2;
|
||||
u2 = x2;
|
||||
v2 = 1 - y1;
|
||||
verts[0].set(x2, y1, z2, u2, v2, 3);
|
||||
verts[1].set(x2, y2, z2, u2, v1, 3);
|
||||
verts[2].set(x1, y2, z2, u1, v1, 3);
|
||||
verts[3].set(x1, y1, z2, u1, v2, 3);
|
||||
break;
|
||||
case 4:
|
||||
u1 = z1; v1 = 1-y2;
|
||||
u2 = z2; v2 = 1-y1;
|
||||
u1 = z1;
|
||||
v1 = 1 - y2;
|
||||
u2 = z2;
|
||||
v2 = 1 - y1;
|
||||
verts[0].set(x1, y1, z2, u2, v2, 4);
|
||||
verts[1].set(x1, y2, z2, u2, v1, 4);
|
||||
verts[2].set(x1, y2, z1, u1, v1, 4);
|
||||
verts[3].set(x1, y1, z1, u1, v2, 4);
|
||||
break;
|
||||
case 5:
|
||||
u1 = 1-z1; v1 = 1-y2;
|
||||
u2 = 1-z2; v2 = 1-y1;
|
||||
u1 = 1 - z1;
|
||||
v1 = 1 - y2;
|
||||
u2 = 1 - z2;
|
||||
v2 = 1 - y1;
|
||||
verts[0].set(x2, y1, z1, u1, v2, 5);
|
||||
verts[1].set(x2, y2, z1, u1, v1, 5);
|
||||
verts[2].set(x2, y2, z2, u2, v1, 5);
|
||||
@@ -106,14 +118,12 @@ public class BlockRenderer
|
||||
}
|
||||
}
|
||||
|
||||
public static class FullBlock implements CCRenderState.IVertexSource
|
||||
{
|
||||
public static class FullBlock implements CCRenderState.IVertexSource {
|
||||
public Vertex5[] verts = CCModel.quadModel(24).generateBlock(0, Cuboid6.full).verts;
|
||||
public LC[] lightCoords = new LC[24];
|
||||
|
||||
public FullBlock() {
|
||||
for(int i = 0; i < 24; i++)
|
||||
lightCoords[i] = new LC().compute(verts[i].vec, i/4);
|
||||
for (int i = 0; i < 24; i++) lightCoords[i] = new LC().compute(verts[i].vec, i / 4);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -133,11 +143,12 @@ public class BlockRenderer
|
||||
|
||||
@Override
|
||||
public void prepareVertex() {
|
||||
CCRenderState.side = CCRenderState.vertexIndex>>2;
|
||||
CCRenderState.side = CCRenderState.vertexIndex >> 2;
|
||||
}
|
||||
}
|
||||
|
||||
public static FullBlock fullBlock = new FullBlock();
|
||||
|
||||
public static void renderFullBlock(int sideMask) {
|
||||
CCRenderState.setModel(fullBlock);
|
||||
renderFaces(sideMask);
|
||||
@@ -148,10 +159,10 @@ public class BlockRenderer
|
||||
* @param sideMask A mask of faces not to render
|
||||
*/
|
||||
public static void renderFaces(int sideMask) {
|
||||
if(sideMask == 0x3F) return;
|
||||
for(int s = 0; s < 6; s++)
|
||||
if((sideMask & 1<<s) == 0) {
|
||||
CCRenderState.setVertexRange(s*4, (s+1)*4);
|
||||
if (sideMask == 0x3F) return;
|
||||
for (int s = 0; s < 6; s++)
|
||||
if ((sideMask & 1 << s) == 0) {
|
||||
CCRenderState.setVertexRange(s * 4, (s + 1) * 4);
|
||||
CCRenderState.render();
|
||||
}
|
||||
}
|
||||
@@ -163,11 +174,11 @@ public class BlockRenderer
|
||||
* @param sideMask A mask of faces not to render
|
||||
*/
|
||||
public static void renderCuboid(Cuboid6 bounds, int sideMask) {
|
||||
if(sideMask == 0x3F) return;
|
||||
if (sideMask == 0x3F) return;
|
||||
|
||||
CCRenderState.setModel(face);
|
||||
for(int s = 0; s < 6; s++)
|
||||
if((sideMask & 1<<s) == 0) {
|
||||
for (int s = 0; s < 6; s++)
|
||||
if ((sideMask & 1 << s) == 0) {
|
||||
face.loadCuboidFace(bounds, s);
|
||||
CCRenderState.render();
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -1,89 +1,91 @@
|
||||
package codechicken.lib.render;
|
||||
|
||||
import codechicken.lib.vec.*;
|
||||
|
||||
import static codechicken.lib.math.MathHelper.phi;
|
||||
|
||||
public class CCModelLibrary
|
||||
{
|
||||
import codechicken.lib.vec.*;
|
||||
|
||||
public class CCModelLibrary {
|
||||
public static CCModel icosahedron4;
|
||||
public static CCModel icosahedron7;
|
||||
|
||||
|
||||
private static int i;
|
||||
|
||||
static
|
||||
{
|
||||
|
||||
static {
|
||||
generateIcosahedron();
|
||||
}
|
||||
|
||||
private static void generateIcosahedron()
|
||||
{
|
||||
private static void generateIcosahedron() {
|
||||
Vector3[] verts = new Vector3[12];
|
||||
|
||||
verts[0] = new Vector3(-1, phi, 0);
|
||||
verts[1] = new Vector3( 1, phi, 0);
|
||||
verts[2] = new Vector3( 1,-phi, 0);
|
||||
verts[3] = new Vector3(-1,-phi, 0);
|
||||
verts[1] = new Vector3(1, phi, 0);
|
||||
verts[2] = new Vector3(1, -phi, 0);
|
||||
verts[3] = new Vector3(-1, -phi, 0);
|
||||
|
||||
verts[4] = new Vector3(0,-1, phi);
|
||||
verts[4] = new Vector3(0, -1, phi);
|
||||
verts[5] = new Vector3(0, 1, phi);
|
||||
verts[6] = new Vector3(0, 1,-phi);
|
||||
verts[7] = new Vector3(0,-1,-phi);
|
||||
verts[6] = new Vector3(0, 1, -phi);
|
||||
verts[7] = new Vector3(0, -1, -phi);
|
||||
|
||||
verts[8] = new Vector3( phi, 0,-1);
|
||||
verts[9] = new Vector3( phi, 0, 1);
|
||||
verts[8] = new Vector3(phi, 0, -1);
|
||||
verts[9] = new Vector3(phi, 0, 1);
|
||||
verts[10] = new Vector3(-phi, 0, 1);
|
||||
verts[11] = new Vector3(-phi, 0,-1);
|
||||
verts[11] = new Vector3(-phi, 0, -1);
|
||||
|
||||
Quat quat = Quat.aroundAxis(0, 0, 1, Math.atan(1 / phi));
|
||||
for (Vector3 vec : verts) quat.rotate(vec);
|
||||
|
||||
Quat quat = Quat.aroundAxis(0, 0, 1, Math.atan(1/phi));
|
||||
for(Vector3 vec : verts)
|
||||
quat.rotate(vec);
|
||||
|
||||
icosahedron4 = CCModel.newModel(4, 60);
|
||||
icosahedron7 = CCModel.newModel(7, 80);
|
||||
|
||||
i = 0;
|
||||
//top
|
||||
// top
|
||||
addIcosahedronTriangle(verts[1], 0.5, 0, verts[0], 0, 0.25, verts[5], 1, 0.25);
|
||||
addIcosahedronTriangle(verts[1], 0.5, 0, verts[5], 0, 0.25, verts[9], 1, 0.25);
|
||||
addIcosahedronTriangle(verts[1], 0.5, 0, verts[9], 0, 0.25, verts[8], 1, 0.25);
|
||||
addIcosahedronTriangle(verts[1], 0.5, 0, verts[8], 0, 0.25, verts[6], 1, 0.25);
|
||||
addIcosahedronTriangle(verts[1], 0.5, 0, verts[6], 0, 0.25, verts[0], 1, 0.25);
|
||||
//centre 1vert top
|
||||
addIcosahedronTriangle(verts[0], 0.5, 0.25, verts[11],0, 0.75, verts[10],1, 0.75);
|
||||
addIcosahedronTriangle(verts[5], 0.5, 0.25, verts[10],0, 0.75, verts[4], 1, 0.75);
|
||||
// centre 1vert top
|
||||
addIcosahedronTriangle(verts[0], 0.5, 0.25, verts[11], 0, 0.75, verts[10], 1, 0.75);
|
||||
addIcosahedronTriangle(verts[5], 0.5, 0.25, verts[10], 0, 0.75, verts[4], 1, 0.75);
|
||||
addIcosahedronTriangle(verts[9], 0.5, 0.25, verts[4], 0, 0.75, verts[2], 1, 0.75);
|
||||
addIcosahedronTriangle(verts[8], 0.5, 0.25, verts[2], 0, 0.75, verts[7], 1, 0.75);
|
||||
addIcosahedronTriangle(verts[6], 0.5, 0.25, verts[7], 0, 0.75, verts[11],1, 0.75);
|
||||
//centre 1vert bottom
|
||||
addIcosahedronTriangle(verts[6], 0.5, 0.25, verts[7], 0, 0.75, verts[11], 1, 0.75);
|
||||
// centre 1vert bottom
|
||||
addIcosahedronTriangle(verts[2], 0.5, 0.75, verts[8], 0, 0.25, verts[9], 1, 0.25);
|
||||
addIcosahedronTriangle(verts[7], 0.5, 0.75, verts[6], 0, 0.25, verts[8], 1, 0.25);
|
||||
addIcosahedronTriangle(verts[11],0.5, 0.75, verts[0], 0, 0.25, verts[6], 1, 0.25);
|
||||
addIcosahedronTriangle(verts[10],0.5, 0.75, verts[5], 0, 0.25, verts[0], 1, 0.25);
|
||||
addIcosahedronTriangle(verts[11], 0.5, 0.75, verts[0], 0, 0.25, verts[6], 1, 0.25);
|
||||
addIcosahedronTriangle(verts[10], 0.5, 0.75, verts[5], 0, 0.25, verts[0], 1, 0.25);
|
||||
addIcosahedronTriangle(verts[4], 0.5, 0.75, verts[9], 0, 0.25, verts[5], 1, 0.25);
|
||||
//bottom
|
||||
// bottom
|
||||
addIcosahedronTriangle(verts[3], 0.5, 1, verts[2], 0, 0.75, verts[4], 1, 0.75);
|
||||
addIcosahedronTriangle(verts[3], 0.5, 1, verts[7], 0, 0.75, verts[2], 1, 0.75);
|
||||
addIcosahedronTriangle(verts[3], 0.5, 1, verts[11],0, 0.75, verts[7], 1, 0.75);
|
||||
addIcosahedronTriangle(verts[3], 0.5, 1, verts[10],0, 0.75, verts[11],1, 0.75);
|
||||
addIcosahedronTriangle(verts[3], 0.5, 1, verts[4], 0, 0.75, verts[10],1, 0.75);
|
||||
|
||||
addIcosahedronTriangle(verts[3], 0.5, 1, verts[11], 0, 0.75, verts[7], 1, 0.75);
|
||||
addIcosahedronTriangle(verts[3], 0.5, 1, verts[10], 0, 0.75, verts[11], 1, 0.75);
|
||||
addIcosahedronTriangle(verts[3], 0.5, 1, verts[4], 0, 0.75, verts[10], 1, 0.75);
|
||||
|
||||
icosahedron4.computeNormals().smoothNormals();
|
||||
icosahedron7.computeNormals().smoothNormals();
|
||||
}
|
||||
|
||||
private static void addIcosahedronTriangle(Vector3 vec1, double u1, double v1,
|
||||
Vector3 vec2, double u2, double v2,
|
||||
Vector3 vec3, double u3, double v3)
|
||||
{
|
||||
icosahedron4.verts[i*3] = icosahedron7.verts[i*4] = new Vertex5(vec1, u1, v1);
|
||||
icosahedron4.verts[i*3+1] = icosahedron7.verts[i*4+1] = new Vertex5(vec2, u2, v2);
|
||||
icosahedron4.verts[i*3+2] = icosahedron7.verts[i*4+2] = icosahedron7.verts[i*4+3] = new Vertex5(vec3, u3, v3);
|
||||
private static void addIcosahedronTriangle(
|
||||
Vector3 vec1,
|
||||
double u1,
|
||||
double v1,
|
||||
Vector3 vec2,
|
||||
double u2,
|
||||
double v2,
|
||||
Vector3 vec3,
|
||||
double u3,
|
||||
double v3) {
|
||||
icosahedron4.verts[i * 3] = icosahedron7.verts[i * 4] = new Vertex5(vec1, u1, v1);
|
||||
icosahedron4.verts[i * 3 + 1] = icosahedron7.verts[i * 4 + 1] = new Vertex5(vec2, u2, v2);
|
||||
icosahedron4.verts[i * 3 + 2] =
|
||||
icosahedron7.verts[i * 4 + 2] = icosahedron7.verts[i * 4 + 3] = new Vertex5(vec3, u3, v3);
|
||||
i++;
|
||||
}
|
||||
|
||||
public static Matrix4 getRenderMatrix(Vector3 position, Rotation rotation, double scale)
|
||||
{
|
||||
|
||||
public static Matrix4 getRenderMatrix(Vector3 position, Rotation rotation, double scale) {
|
||||
return new Matrix4().translate(position).apply(new Scale(scale)).apply(rotation);
|
||||
}
|
||||
}
|
||||
@@ -2,21 +2,17 @@ package codechicken.lib.render;
|
||||
|
||||
import codechicken.lib.render.CCRenderState.IVertexOperation;
|
||||
import codechicken.lib.render.CCRenderState.VertexAttribute;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class CCRenderPipeline
|
||||
{
|
||||
public class PipelineBuilder
|
||||
{
|
||||
public class CCRenderPipeline {
|
||||
public class PipelineBuilder {
|
||||
public PipelineBuilder add(IVertexOperation op) {
|
||||
ops.add(op);
|
||||
return this;
|
||||
}
|
||||
|
||||
public PipelineBuilder add(IVertexOperation... ops) {
|
||||
for(int i = 0; i < ops.length; i++)
|
||||
CCRenderPipeline.this.ops.add(ops[i]);
|
||||
for (int i = 0; i < ops.length; i++) CCRenderPipeline.this.ops.add(ops[i]);
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -30,17 +26,14 @@ public class CCRenderPipeline
|
||||
}
|
||||
}
|
||||
|
||||
private class PipelineNode
|
||||
{
|
||||
private class PipelineNode {
|
||||
public ArrayList<PipelineNode> deps = new ArrayList<PipelineNode>();
|
||||
public IVertexOperation op;
|
||||
|
||||
public void add() {
|
||||
if(op == null)
|
||||
return;
|
||||
if (op == null) return;
|
||||
|
||||
for(int i = 0; i < deps.size(); i++)
|
||||
deps.get(i).add();
|
||||
for (int i = 0; i < deps.size(); i++) deps.get(i).add();
|
||||
deps.clear();
|
||||
sorted.add(op);
|
||||
op = null;
|
||||
@@ -56,8 +49,7 @@ public class CCRenderPipeline
|
||||
|
||||
public void setPipeline(IVertexOperation... ops) {
|
||||
this.ops.clear();
|
||||
for(int i = 0; i < ops.length; i++)
|
||||
this.ops.add(ops[i]);
|
||||
for (int i = 0; i < ops.length; i++) this.ops.add(ops[i]);
|
||||
rebuild();
|
||||
}
|
||||
|
||||
@@ -67,44 +59,34 @@ public class CCRenderPipeline
|
||||
}
|
||||
|
||||
private void unbuild() {
|
||||
for(int i = 0; i < attribs.size(); i++)
|
||||
attribs.get(i).active = false;
|
||||
for (int i = 0; i < attribs.size(); i++) attribs.get(i).active = false;
|
||||
attribs.clear();
|
||||
sorted.clear();
|
||||
}
|
||||
|
||||
public void rebuild() {
|
||||
if(ops.isEmpty() || CCRenderState.model == null)
|
||||
return;
|
||||
if (ops.isEmpty() || CCRenderState.model == null) return;
|
||||
|
||||
//ensure enough nodes for all ops
|
||||
while(nodes.size() < CCRenderState.operationCount())
|
||||
nodes.add(new PipelineNode());
|
||||
// ensure enough nodes for all ops
|
||||
while (nodes.size() < CCRenderState.operationCount()) nodes.add(new PipelineNode());
|
||||
unbuild();
|
||||
|
||||
if(CCRenderState.useNormals)
|
||||
addAttribute(CCRenderState.normalAttrib);
|
||||
if(CCRenderState.useColour)
|
||||
addAttribute(CCRenderState.colourAttrib);
|
||||
if(CCRenderState.computeLighting)
|
||||
addAttribute(CCRenderState.lightingAttrib);
|
||||
if (CCRenderState.useNormals) addAttribute(CCRenderState.normalAttrib);
|
||||
if (CCRenderState.useColour) addAttribute(CCRenderState.colourAttrib);
|
||||
if (CCRenderState.computeLighting) addAttribute(CCRenderState.lightingAttrib);
|
||||
|
||||
for(int i = 0; i < ops.size(); i++) {
|
||||
for (int i = 0; i < ops.size(); i++) {
|
||||
IVertexOperation op = ops.get(i);
|
||||
loading = nodes.get(op.operationID());
|
||||
boolean loaded = op.load();
|
||||
if(loaded)
|
||||
loading.op = op;
|
||||
if (loaded) loading.op = op;
|
||||
|
||||
if(op instanceof VertexAttribute)
|
||||
if(loaded)
|
||||
attribs.add((VertexAttribute)op);
|
||||
else
|
||||
((VertexAttribute)op).active = false;
|
||||
if (op instanceof VertexAttribute)
|
||||
if (loaded) attribs.add((VertexAttribute) op);
|
||||
else ((VertexAttribute) op).active = false;
|
||||
}
|
||||
|
||||
for(int i = 0; i < nodes.size(); i++)
|
||||
nodes.get(i).add();
|
||||
for (int i = 0; i < nodes.size(); i++) nodes.get(i).add();
|
||||
}
|
||||
|
||||
public void addRequirement(int opRef) {
|
||||
@@ -117,15 +99,14 @@ public class CCRenderPipeline
|
||||
}
|
||||
|
||||
public void addAttribute(VertexAttribute attrib) {
|
||||
if(!attrib.active) {
|
||||
if (!attrib.active) {
|
||||
ops.add(attrib);
|
||||
attrib.active = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void operate() {
|
||||
for(int i = 0; i < sorted.size(); i++)
|
||||
sorted.get(i).operate();
|
||||
for (int i = 0; i < sorted.size(); i++) sorted.get(i).operate();
|
||||
}
|
||||
|
||||
public PipelineBuilder builder() {
|
||||
|
||||
@@ -7,20 +7,18 @@ import codechicken.lib.util.Copyable;
|
||||
import codechicken.lib.vec.Rotation;
|
||||
import codechicken.lib.vec.Transformation;
|
||||
import codechicken.lib.vec.Vector3;
|
||||
import java.util.ArrayList;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.OpenGlHelper;
|
||||
import net.minecraft.client.renderer.Tessellator;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.world.IBlockAccess;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* The core of the CodeChickenLib render system.
|
||||
* Rendering operations are written to avoid object allocations by reusing static variables.
|
||||
*/
|
||||
public class CCRenderState
|
||||
{
|
||||
public class CCRenderState {
|
||||
private static int nextOperationIndex;
|
||||
|
||||
public static int registerOperation() {
|
||||
@@ -34,8 +32,7 @@ public class CCRenderState
|
||||
/**
|
||||
* Represents an operation to be run for each vertex that operates on and modifies the current state
|
||||
*/
|
||||
public static interface IVertexOperation
|
||||
{
|
||||
public static interface IVertexOperation {
|
||||
/**
|
||||
* Load any required references and add dependencies to the pipeline based on the current model (may be null)
|
||||
* Return false if this operation is redundant in the pipeline with the given model
|
||||
@@ -55,9 +52,10 @@ public class CCRenderState
|
||||
}
|
||||
|
||||
private static ArrayList<VertexAttribute<?>> vertexAttributes = new ArrayList<VertexAttribute<?>>();
|
||||
|
||||
private static int registerVertexAttribute(VertexAttribute<?> attr) {
|
||||
vertexAttributes.add(attr);
|
||||
return vertexAttributes.size()-1;
|
||||
return vertexAttributes.size() - 1;
|
||||
}
|
||||
|
||||
public static VertexAttribute<?> getAttribute(int index) {
|
||||
@@ -69,8 +67,7 @@ public class CCRenderState
|
||||
* This class should handle the loading of the attrute from an array provided by IVertexSource.getAttributes or the computation of this attrute from others
|
||||
* @param <T> The array type for this attrute eg. int[], Vector3[]
|
||||
*/
|
||||
public static abstract class VertexAttribute<T> implements IVertexOperation
|
||||
{
|
||||
public abstract static class VertexAttribute<T> implements IVertexOperation {
|
||||
public final int attributeIndex = registerVertexAttribute(this);
|
||||
private final int operationIndex = registerOperation();
|
||||
/**
|
||||
@@ -91,23 +88,20 @@ public class CCRenderState
|
||||
|
||||
public static void arrayCopy(Object src, int srcPos, Object dst, int destPos, int length) {
|
||||
System.arraycopy(src, srcPos, dst, destPos, length);
|
||||
if(dst instanceof Copyable[]) {
|
||||
Object[] oa = (Object[])dst;
|
||||
Copyable<Object>[] c = (Copyable[])dst;
|
||||
for(int i = destPos; i < destPos+length; i++)
|
||||
if(c[i] != null)
|
||||
oa[i] = c[i].copy();
|
||||
if (dst instanceof Copyable[]) {
|
||||
Object[] oa = (Object[]) dst;
|
||||
Copyable<Object>[] c = (Copyable[]) dst;
|
||||
for (int i = destPos; i < destPos + length; i++) if (c[i] != null) oa[i] = c[i].copy();
|
||||
}
|
||||
}
|
||||
|
||||
public static <T> T copyOf(VertexAttribute<T> attr, T src, int length) {
|
||||
T dst = attr.newArray(length);
|
||||
arrayCopy(src, 0, dst, 0, ((Object[])src).length);
|
||||
arrayCopy(src, 0, dst, 0, ((Object[]) src).length);
|
||||
return dst;
|
||||
}
|
||||
|
||||
public static interface IVertexSource
|
||||
{
|
||||
public static interface IVertexSource {
|
||||
public Vertex5[] getVertices();
|
||||
|
||||
/**
|
||||
@@ -140,22 +134,20 @@ public class CCRenderState
|
||||
@Override
|
||||
public boolean load() {
|
||||
normalRef = model.getAttributes(this);
|
||||
if(model.hasAttribute(this))
|
||||
return normalRef != null;
|
||||
if (model.hasAttribute(this)) return normalRef != null;
|
||||
|
||||
if(model.hasAttribute(sideAttrib)) {
|
||||
if (model.hasAttribute(sideAttrib)) {
|
||||
pipeline.addDependency(sideAttrib);
|
||||
return true;
|
||||
}
|
||||
throw new IllegalStateException("Normals requested but neither normal or side attrutes are provided by the model");
|
||||
throw new IllegalStateException(
|
||||
"Normals requested but neither normal or side attrutes are provided by the model");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void operate() {
|
||||
if(normalRef != null)
|
||||
setNormal(normalRef[vertexIndex]);
|
||||
else
|
||||
setNormal(Rotation.axes[side]);
|
||||
if (normalRef != null) setNormal(normalRef[vertexIndex]);
|
||||
else setNormal(Rotation.axes[side]);
|
||||
}
|
||||
};
|
||||
public static VertexAttribute<int[]> colourAttrib = new VertexAttribute<int[]>() {
|
||||
@@ -174,10 +166,8 @@ public class CCRenderState
|
||||
|
||||
@Override
|
||||
public void operate() {
|
||||
if(colourRef != null)
|
||||
setColour(ColourRGBA.multiply(baseColour, colourRef[vertexIndex]));
|
||||
else
|
||||
setColour(baseColour);
|
||||
if (colourRef != null) setColour(ColourRGBA.multiply(baseColour, colourRef[vertexIndex]));
|
||||
else setColour(baseColour);
|
||||
}
|
||||
};
|
||||
public static VertexAttribute<int[]> lightingAttrib = new VertexAttribute<int[]>() {
|
||||
@@ -190,11 +180,10 @@ public class CCRenderState
|
||||
|
||||
@Override
|
||||
public boolean load() {
|
||||
if(!computeLighting || !useColour || !model.hasAttribute(this))
|
||||
return false;
|
||||
if (!computeLighting || !useColour || !model.hasAttribute(this)) return false;
|
||||
|
||||
colourRef = model.getAttributes(this);
|
||||
if(colourRef != null) {
|
||||
if (colourRef != null) {
|
||||
pipeline.addDependency(colourAttrib);
|
||||
return true;
|
||||
}
|
||||
@@ -217,8 +206,7 @@ public class CCRenderState
|
||||
@Override
|
||||
public boolean load() {
|
||||
sideRef = model.getAttributes(this);
|
||||
if(model.hasAttribute(this))
|
||||
return sideRef != null;
|
||||
if (model.hasAttribute(this)) return sideRef != null;
|
||||
|
||||
pipeline.addDependency(normalAttrib);
|
||||
return true;
|
||||
@@ -226,10 +214,8 @@ public class CCRenderState
|
||||
|
||||
@Override
|
||||
public void operate() {
|
||||
if(sideRef != null)
|
||||
side = sideRef[vertexIndex];
|
||||
else
|
||||
side = CCModel.findSide(normal);
|
||||
if (sideRef != null) side = sideRef[vertexIndex];
|
||||
else side = CCModel.findSide(normal);
|
||||
}
|
||||
};
|
||||
/**
|
||||
@@ -237,7 +223,7 @@ public class CCRenderState
|
||||
*/
|
||||
public static VertexAttribute<LC[]> lightCoordAttrib = new VertexAttribute<LC[]>() {
|
||||
private LC[] lcRef;
|
||||
private Vector3 vec = new Vector3();//for computation
|
||||
private Vector3 vec = new Vector3(); // for computation
|
||||
private Vector3 pos = new Vector3();
|
||||
|
||||
@Override
|
||||
@@ -248,8 +234,7 @@ public class CCRenderState
|
||||
@Override
|
||||
public boolean load() {
|
||||
lcRef = model.getAttributes(this);
|
||||
if(model.hasAttribute(this))
|
||||
return lcRef != null;
|
||||
if (model.hasAttribute(this)) return lcRef != null;
|
||||
|
||||
pos.set(lightMatrix.pos.x, lightMatrix.pos.y, lightMatrix.pos.z);
|
||||
pipeline.addDependency(sideAttrib);
|
||||
@@ -259,21 +244,19 @@ public class CCRenderState
|
||||
|
||||
@Override
|
||||
public void operate() {
|
||||
if(lcRef != null)
|
||||
lc.set(lcRef[vertexIndex]);
|
||||
else
|
||||
lc.compute(vec.set(vert.vec).sub(pos), side);
|
||||
if (lcRef != null) lc.set(lcRef[vertexIndex]);
|
||||
else lc.compute(vec.set(vert.vec).sub(pos), side);
|
||||
}
|
||||
};
|
||||
|
||||
//pipeline state
|
||||
// pipeline state
|
||||
public static IVertexSource model;
|
||||
public static int firstVertexIndex;
|
||||
public static int lastVertexIndex;
|
||||
public static int vertexIndex;
|
||||
public static CCRenderPipeline pipeline = new CCRenderPipeline();
|
||||
|
||||
//context
|
||||
// context
|
||||
public static int baseColour;
|
||||
public static int alphaOverride;
|
||||
public static boolean useNormals;
|
||||
@@ -281,7 +264,7 @@ public class CCRenderState
|
||||
public static boolean useColour;
|
||||
public static LightMatrix lightMatrix = new LightMatrix();
|
||||
|
||||
//vertex outputs
|
||||
// vertex outputs
|
||||
public static Vertex5 vert = new Vertex5();
|
||||
public static boolean hasNormal;
|
||||
public static Vector3 normal = new Vector3();
|
||||
@@ -290,7 +273,7 @@ public class CCRenderState
|
||||
public static boolean hasBrightness;
|
||||
public static int brightness;
|
||||
|
||||
//attrute storage
|
||||
// attrute storage
|
||||
public static int side;
|
||||
public static LC lc = new LC();
|
||||
|
||||
@@ -313,7 +296,7 @@ public class CCRenderState
|
||||
}
|
||||
|
||||
public static void bindModel(IVertexSource model) {
|
||||
if(CCRenderState.model != model) {
|
||||
if (CCRenderState.model != model) {
|
||||
CCRenderState.model = model;
|
||||
pipeline.rebuild();
|
||||
}
|
||||
@@ -340,7 +323,7 @@ public class CCRenderState
|
||||
|
||||
public static void render() {
|
||||
Vertex5[] verts = model.getVertices();
|
||||
for(vertexIndex = firstVertexIndex; vertexIndex < lastVertexIndex; vertexIndex++) {
|
||||
for (vertexIndex = firstVertexIndex; vertexIndex < lastVertexIndex; vertexIndex++) {
|
||||
model.prepareVertex();
|
||||
vert.set(verts[vertexIndex]);
|
||||
runPipeline();
|
||||
@@ -353,12 +336,14 @@ public class CCRenderState
|
||||
}
|
||||
|
||||
public static void writeVert() {
|
||||
if(hasNormal)
|
||||
Tessellator.instance.setNormal((float)normal.x, (float)normal.y, (float)normal.z);
|
||||
if(hasColour)
|
||||
Tessellator.instance.setColorRGBA(colour>>>24, colour>>16 & 0xFF, colour>>8 & 0xFF, alphaOverride >= 0 ? alphaOverride : colour & 0xFF);
|
||||
if(hasBrightness)
|
||||
Tessellator.instance.setBrightness(brightness);
|
||||
if (hasNormal) Tessellator.instance.setNormal((float) normal.x, (float) normal.y, (float) normal.z);
|
||||
if (hasColour)
|
||||
Tessellator.instance.setColorRGBA(
|
||||
colour >>> 24,
|
||||
colour >> 16 & 0xFF,
|
||||
colour >> 8 & 0xFF,
|
||||
alphaOverride >= 0 ? alphaOverride : colour & 0xFF);
|
||||
if (hasBrightness) Tessellator.instance.setBrightness(brightness);
|
||||
Tessellator.instance.addVertexWithUV(vert.vec.x, vert.vec.y, vert.vec.z, vert.uv.u, vert.uv.v);
|
||||
}
|
||||
|
||||
@@ -387,7 +372,7 @@ public class CCRenderState
|
||||
}
|
||||
|
||||
public static void pullLightmap() {
|
||||
setBrightness((int)OpenGlHelper.lastBrightnessY << 16 | (int)OpenGlHelper.lastBrightnessX);
|
||||
setBrightness((int) OpenGlHelper.lastBrightnessY << 16 | (int) OpenGlHelper.lastBrightnessX);
|
||||
}
|
||||
|
||||
public static void pushLightmap() {
|
||||
@@ -416,10 +401,13 @@ public class CCRenderState
|
||||
|
||||
public static void startDrawing(int mode) {
|
||||
Tessellator.instance.startDrawing(mode);
|
||||
if(hasColour)
|
||||
Tessellator.instance.setColorRGBA(colour>>>24, colour>>16 & 0xFF, colour>>8 & 0xFF, alphaOverride >= 0 ? alphaOverride : colour & 0xFF);
|
||||
if(hasBrightness)
|
||||
Tessellator.instance.setBrightness(brightness);
|
||||
if (hasColour)
|
||||
Tessellator.instance.setColorRGBA(
|
||||
colour >>> 24,
|
||||
colour >> 16 & 0xFF,
|
||||
colour >> 8 & 0xFF,
|
||||
alphaOverride >= 0 ? alphaOverride : colour & 0xFF);
|
||||
if (hasBrightness) Tessellator.instance.setBrightness(brightness);
|
||||
}
|
||||
|
||||
public static void draw() {
|
||||
|
||||
@@ -2,8 +2,7 @@ package codechicken.lib.render;
|
||||
|
||||
import codechicken.lib.colour.ColourRGBA;
|
||||
|
||||
public class ColourMultiplier implements CCRenderState.IVertexOperation
|
||||
{
|
||||
public class ColourMultiplier implements CCRenderState.IVertexOperation {
|
||||
private static ColourMultiplier instance = new ColourMultiplier(-1);
|
||||
|
||||
public static ColourMultiplier instance(int colour) {
|
||||
@@ -20,7 +19,7 @@ public class ColourMultiplier implements CCRenderState.IVertexOperation
|
||||
|
||||
@Override
|
||||
public boolean load() {
|
||||
if(colour == -1) {
|
||||
if (colour == -1) {
|
||||
CCRenderState.setColour(-1);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -8,23 +8,20 @@ import net.minecraft.client.renderer.Tessellator;
|
||||
import net.minecraft.util.IIcon;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class EntityDigIconFX extends EntityFX
|
||||
{
|
||||
public EntityDigIconFX(World world, double x, double y, double z, double dx, double dy, double dz, IIcon icon)
|
||||
{
|
||||
public class EntityDigIconFX extends EntityFX {
|
||||
public EntityDigIconFX(World world, double x, double y, double z, double dx, double dy, double dz, IIcon icon) {
|
||||
super(world, x, y, z, dx, dy, dz);
|
||||
particleIcon = icon;
|
||||
particleGravity = 1;
|
||||
particleRed = particleGreen = particleBlue = 0.6F;
|
||||
particleScale /= 2.0F;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getFXLayer()
|
||||
{
|
||||
public int getFXLayer() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
public void setScale(float scale) {
|
||||
particleScale = scale;
|
||||
}
|
||||
@@ -32,91 +29,94 @@ public class EntityDigIconFX extends EntityFX
|
||||
public float getScale() {
|
||||
return particleScale;
|
||||
}
|
||||
|
||||
public void setMaxAge(int age){
|
||||
|
||||
public void setMaxAge(int age) {
|
||||
particleMaxAge = age;
|
||||
}
|
||||
|
||||
public int getMaxAge(){
|
||||
|
||||
public int getMaxAge() {
|
||||
return particleMaxAge;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* copy pasted from EntityDiggingFX
|
||||
*/
|
||||
@Override
|
||||
public void renderParticle(Tessellator par1Tessellator, float par2, float par3, float par4, float par5, float par6, float par7)
|
||||
{
|
||||
public void renderParticle(
|
||||
Tessellator par1Tessellator, float par2, float par3, float par4, float par5, float par6, float par7) {
|
||||
float f6 = (particleTextureIndexX + particleTextureJitterX / 4.0F) / 16.0F;
|
||||
float f7 = f6 + 0.015609375F;
|
||||
float f8 = (particleTextureIndexY + particleTextureJitterY / 4.0F) / 16.0F;
|
||||
float f9 = f8 + 0.015609375F;
|
||||
float f10 = 0.1F * particleScale;
|
||||
|
||||
if (particleIcon != null)
|
||||
{
|
||||
if (particleIcon != null) {
|
||||
f6 = particleIcon.getInterpolatedU(particleTextureJitterX / 4.0F * 16.0F);
|
||||
f7 = particleIcon.getInterpolatedU((particleTextureJitterX + 1.0F) / 4.0F * 16.0F);
|
||||
f8 = particleIcon.getInterpolatedV(particleTextureJitterY / 4.0F * 16.0F);
|
||||
f9 = particleIcon.getInterpolatedV((particleTextureJitterY + 1.0F) / 4.0F * 16.0F);
|
||||
}
|
||||
|
||||
float f11 = (float)(prevPosX + (posX - prevPosX) * par2 - interpPosX);
|
||||
float f12 = (float)(prevPosY + (posY - prevPosY) * par2 - interpPosY);
|
||||
float f13 = (float)(prevPosZ + (posZ - prevPosZ) * par2 - interpPosZ);
|
||||
float f11 = (float) (prevPosX + (posX - prevPosX) * par2 - interpPosX);
|
||||
float f12 = (float) (prevPosY + (posY - prevPosY) * par2 - interpPosY);
|
||||
float f13 = (float) (prevPosZ + (posZ - prevPosZ) * par2 - interpPosZ);
|
||||
float f14 = 1.0F;
|
||||
par1Tessellator.setColorOpaque_F(f14 * particleRed, f14 * particleGreen, f14 * particleBlue);
|
||||
par1Tessellator.addVertexWithUV(f11 - par3 * f10 - par6 * f10, f12 - par4 * f10, f13 - par5 * f10 - par7 * f10, f6, f9);
|
||||
par1Tessellator.addVertexWithUV(f11 - par3 * f10 + par6 * f10, f12 + par4 * f10, f13 - par5 * f10 + par7 * f10, f6, f8);
|
||||
par1Tessellator.addVertexWithUV(f11 + par3 * f10 + par6 * f10, f12 + par4 * f10, f13 + par5 * f10 + par7 * f10, f7, f8);
|
||||
par1Tessellator.addVertexWithUV(f11 + par3 * f10 - par6 * f10, f12 - par4 * f10, f13 + par5 * f10 - par7 * f10, f7, f9);
|
||||
par1Tessellator.addVertexWithUV(
|
||||
f11 - par3 * f10 - par6 * f10, f12 - par4 * f10, f13 - par5 * f10 - par7 * f10, f6, f9);
|
||||
par1Tessellator.addVertexWithUV(
|
||||
f11 - par3 * f10 + par6 * f10, f12 + par4 * f10, f13 - par5 * f10 + par7 * f10, f6, f8);
|
||||
par1Tessellator.addVertexWithUV(
|
||||
f11 + par3 * f10 + par6 * f10, f12 + par4 * f10, f13 + par5 * f10 + par7 * f10, f7, f8);
|
||||
par1Tessellator.addVertexWithUV(
|
||||
f11 + par3 * f10 - par6 * f10, f12 - par4 * f10, f13 + par5 * f10 - par7 * f10, f7, f9);
|
||||
}
|
||||
|
||||
public static void addBlockHitEffects(World world, Cuboid6 bounds, int side, IIcon icon, EffectRenderer effectRenderer)
|
||||
{
|
||||
|
||||
public static void addBlockHitEffects(
|
||||
World world, Cuboid6 bounds, int side, IIcon icon, EffectRenderer effectRenderer) {
|
||||
float border = 0.1F;
|
||||
Vector3 diff = bounds.max.copy().subtract(bounds.min).add(-2*border);
|
||||
diff.x*=world.rand.nextDouble();
|
||||
diff.y*=world.rand.nextDouble();
|
||||
diff.z*=world.rand.nextDouble();
|
||||
Vector3 diff = bounds.max.copy().subtract(bounds.min).add(-2 * border);
|
||||
diff.x *= world.rand.nextDouble();
|
||||
diff.y *= world.rand.nextDouble();
|
||||
diff.z *= world.rand.nextDouble();
|
||||
Vector3 pos = diff.add(bounds.min).add(border);
|
||||
|
||||
if (side == 0)
|
||||
diff.y = bounds.min.y - border;
|
||||
if (side == 1)
|
||||
diff.y = bounds.max.y + border;
|
||||
if (side == 2)
|
||||
diff.z = bounds.min.z - border;
|
||||
if (side == 3)
|
||||
diff.z = bounds.max.z + border;
|
||||
if (side == 4)
|
||||
diff.x = bounds.min.x - border;
|
||||
if (side == 5)
|
||||
diff.x = bounds.max.x + border;
|
||||
|
||||
effectRenderer.addEffect(
|
||||
new EntityDigIconFX(world, pos.x, pos.y, pos.z, 0, 0, 0, icon)
|
||||
.multiplyVelocity(0.2F).multipleParticleScaleBy(0.6F));
|
||||
|
||||
if (side == 0) diff.y = bounds.min.y - border;
|
||||
if (side == 1) diff.y = bounds.max.y + border;
|
||||
if (side == 2) diff.z = bounds.min.z - border;
|
||||
if (side == 3) diff.z = bounds.max.z + border;
|
||||
if (side == 4) diff.x = bounds.min.x - border;
|
||||
if (side == 5) diff.x = bounds.max.x + border;
|
||||
|
||||
effectRenderer.addEffect(new EntityDigIconFX(world, pos.x, pos.y, pos.z, 0, 0, 0, icon)
|
||||
.multiplyVelocity(0.2F)
|
||||
.multipleParticleScaleBy(0.6F));
|
||||
}
|
||||
|
||||
public static void addBlockDestroyEffects(World world, Cuboid6 bounds, IIcon[] icons, EffectRenderer effectRenderer)
|
||||
{
|
||||
|
||||
public static void addBlockDestroyEffects(
|
||||
World world, Cuboid6 bounds, IIcon[] icons, EffectRenderer effectRenderer) {
|
||||
Vector3 diff = bounds.max.copy().subtract(bounds.min);
|
||||
Vector3 center = bounds.min.copy().add(bounds.max).multiply(0.5);
|
||||
Vector3 density = diff.copy().multiply(4);
|
||||
density.x = Math.ceil(density.x);
|
||||
density.y = Math.ceil(density.y);
|
||||
density.z = Math.ceil(density.z);
|
||||
|
||||
|
||||
for (int i = 0; i < density.x; ++i)
|
||||
for (int j = 0; j < density.y; ++j)
|
||||
for (int k = 0; k < density.z; ++k)
|
||||
{
|
||||
double x = bounds.min.x+(i+0.5)*diff.x/density.x;
|
||||
double y = bounds.min.y+(j+0.5)*diff.y/density.y;
|
||||
double z = bounds.min.z+(k+0.5)*diff.z/density.z;
|
||||
effectRenderer.addEffect(
|
||||
new EntityDigIconFX(world, x, y, z, x-center.x, y-center.y, z-center.z, icons[world.rand.nextInt(icons.length)]));
|
||||
for (int k = 0; k < density.z; ++k) {
|
||||
double x = bounds.min.x + (i + 0.5) * diff.x / density.x;
|
||||
double y = bounds.min.y + (j + 0.5) * diff.y / density.y;
|
||||
double z = bounds.min.z + (k + 0.5) * diff.z / density.z;
|
||||
effectRenderer.addEffect(new EntityDigIconFX(
|
||||
world,
|
||||
x,
|
||||
y,
|
||||
z,
|
||||
x - center.x,
|
||||
y - center.y,
|
||||
z - center.z,
|
||||
icons[world.rand.nextInt(icons.length)]));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,62 +5,53 @@ import net.minecraft.client.gui.FontRenderer;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
public class FontUtils
|
||||
{
|
||||
public class FontUtils {
|
||||
public static FontRenderer fontRenderer = Minecraft.getMinecraft().fontRenderer;
|
||||
|
||||
public static void drawCenteredString(String s, int xCenter, int y, int colour)
|
||||
{
|
||||
fontRenderer.drawString(s, xCenter-fontRenderer.getStringWidth(s)/2, y, colour);
|
||||
|
||||
public static void drawCenteredString(String s, int xCenter, int y, int colour) {
|
||||
fontRenderer.drawString(s, xCenter - fontRenderer.getStringWidth(s) / 2, y, colour);
|
||||
}
|
||||
|
||||
public static void drawRightString(String s, int xRight, int y, int colour)
|
||||
{
|
||||
fontRenderer.drawString(s, xRight-fontRenderer.getStringWidth(s), y, colour);
|
||||
|
||||
public static void drawRightString(String s, int xRight, int y, int colour) {
|
||||
fontRenderer.drawString(s, xRight - fontRenderer.getStringWidth(s), y, colour);
|
||||
}
|
||||
|
||||
public static final String[] prefixes = new String[]{"K", "M", "G"};
|
||||
public static void drawItemQuantity(int x, int y, ItemStack item, String quantity, int mode)
|
||||
{
|
||||
if(item == null || (quantity == null && item.stackSize <= 1))
|
||||
return;
|
||||
|
||||
if(quantity == null)
|
||||
{
|
||||
switch(mode)
|
||||
{
|
||||
|
||||
public static final String[] prefixes = new String[] {"K", "M", "G"};
|
||||
|
||||
public static void drawItemQuantity(int x, int y, ItemStack item, String quantity, int mode) {
|
||||
if (item == null || (quantity == null && item.stackSize <= 1)) return;
|
||||
|
||||
if (quantity == null) {
|
||||
switch (mode) {
|
||||
case 2:
|
||||
int q = item.stackSize;
|
||||
String postfix = "";
|
||||
for(int p = 0; p < 3 && q > 1000; p++)
|
||||
{
|
||||
q/=1000;
|
||||
for (int p = 0; p < 3 && q > 1000; p++) {
|
||||
q /= 1000;
|
||||
postfix = prefixes[p];
|
||||
}
|
||||
quantity = Integer.toString(q)+postfix;
|
||||
quantity = Integer.toString(q) + postfix;
|
||||
case 1:
|
||||
quantity = "";
|
||||
if(item.stackSize/64 > 0)
|
||||
quantity+=item.stackSize/64 + "s";
|
||||
if(item.stackSize%64 > 0)
|
||||
quantity+=item.stackSize%64;
|
||||
break;
|
||||
if (item.stackSize / 64 > 0) quantity += item.stackSize / 64 + "s";
|
||||
if (item.stackSize % 64 > 0) quantity += item.stackSize % 64;
|
||||
break;
|
||||
default:
|
||||
quantity = Integer.toString(item.stackSize);
|
||||
break;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
double scale = quantity.length() > 2 ? 0.5 : 1;
|
||||
double sheight = 8*scale;
|
||||
double swidth = fontRenderer.getStringWidth(quantity)*scale;
|
||||
double sheight = 8 * scale;
|
||||
double swidth = fontRenderer.getStringWidth(quantity) * scale;
|
||||
|
||||
GL11.glDisable(GL11.GL_LIGHTING);
|
||||
GL11.glDisable(GL11.GL_DEPTH_TEST);
|
||||
GL11.glPushMatrix();
|
||||
GL11.glTranslated(x+16-swidth, y+16-sheight, 0);
|
||||
GL11.glScaled(scale, scale, 1);
|
||||
fontRenderer.drawStringWithShadow(quantity, 0, 0, 0xFFFFFF);
|
||||
GL11.glTranslated(x + 16 - swidth, y + 16 - sheight, 0);
|
||||
GL11.glScaled(scale, scale, 1);
|
||||
fontRenderer.drawStringWithShadow(quantity, 0, 0, 0xFFFFFF);
|
||||
GL11.glPopMatrix();
|
||||
GL11.glEnable(GL11.GL_LIGHTING);
|
||||
GL11.glEnable(GL11.GL_DEPTH_TEST);
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package codechicken.lib.render;
|
||||
|
||||
public interface IFaceRenderer
|
||||
{
|
||||
public interface IFaceRenderer {
|
||||
public void renderFace(Vertex5[] face, int side);
|
||||
}
|
||||
@@ -1,29 +1,23 @@
|
||||
package codechicken.lib.render;
|
||||
|
||||
public class ManagedTextureFX extends TextureFX
|
||||
{
|
||||
public class ManagedTextureFX extends TextureFX {
|
||||
public boolean changed;
|
||||
|
||||
public ManagedTextureFX(int size, String name)
|
||||
{
|
||||
|
||||
public ManagedTextureFX(int size, String name) {
|
||||
super(size, name);
|
||||
imageData = new int[size*size];
|
||||
imageData = new int[size * size];
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setup()
|
||||
{
|
||||
}
|
||||
|
||||
public void setData(int[] data)
|
||||
{
|
||||
public void setup() {}
|
||||
|
||||
public void setData(int[] data) {
|
||||
System.arraycopy(data, 0, imageData, 0, imageData.length);
|
||||
changed = true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean changed()
|
||||
{
|
||||
public boolean changed() {
|
||||
boolean r = changed;
|
||||
changed = false;
|
||||
return r;
|
||||
|
||||
@@ -4,8 +4,7 @@ import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||
import net.minecraft.client.resources.IResourceManager;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
|
||||
public class PlaceholderTexture extends TextureAtlasSprite
|
||||
{
|
||||
public class PlaceholderTexture extends TextureAtlasSprite {
|
||||
protected PlaceholderTexture(String par1) {
|
||||
super(par1);
|
||||
}
|
||||
|
||||
@@ -5,20 +5,17 @@ import codechicken.lib.render.uv.UVScale;
|
||||
import codechicken.lib.vec.*;
|
||||
import com.google.common.collect.HashMultimap;
|
||||
import com.google.common.collect.Multimap;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import javax.imageio.ImageIO;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.texture.IIconRegister;
|
||||
import net.minecraft.util.IIcon;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
public class QBImporter
|
||||
{
|
||||
private static class ImagePackNode
|
||||
{
|
||||
public class QBImporter {
|
||||
private static class ImagePackNode {
|
||||
Rectangle4i rect;
|
||||
ImagePackNode child1;
|
||||
ImagePackNode child2;
|
||||
@@ -29,59 +26,49 @@ public class QBImporter
|
||||
}
|
||||
|
||||
public boolean pack(QBImage img) {
|
||||
if(child1 != null)
|
||||
return child1.pack(img) || child2.pack(img);
|
||||
if (child1 != null) return child1.pack(img) || child2.pack(img);
|
||||
|
||||
if(packed != null)
|
||||
return false;
|
||||
if (packed != null) return false;
|
||||
|
||||
int fit = getFit(img.width(), img.height());
|
||||
if(fit == 0)
|
||||
return false;
|
||||
if (fit == 0) return false;
|
||||
|
||||
if((fit & 2) != 0) {//exact fit
|
||||
if ((fit & 2) != 0) { // exact fit
|
||||
packed = img;
|
||||
img.packSlot = rect;
|
||||
img.packT = new ImageTransform((fit&1)<<2);
|
||||
img.packT = new ImageTransform((fit & 1) << 2);
|
||||
return true;
|
||||
}
|
||||
|
||||
int w = (fit & 1) == 0 ? img.width() : img.height();
|
||||
int h = (fit & 1) == 0 ? img.height() : img.width();
|
||||
|
||||
if(rect.w - w > rect.h - h) {//create split with biggest leftover space
|
||||
if (rect.w - w > rect.h - h) { // create split with biggest leftover space
|
||||
child1 = new ImagePackNode(rect.x, rect.y, w, rect.h);
|
||||
child2 = new ImagePackNode(rect.x+w, rect.y, rect.w-w, rect.h);
|
||||
child2 = new ImagePackNode(rect.x + w, rect.y, rect.w - w, rect.h);
|
||||
} else {
|
||||
child1 = new ImagePackNode(rect.x, rect.y, rect.w, h);
|
||||
child2 = new ImagePackNode(rect.x, rect.y+h, rect.w, rect.h-h);
|
||||
child2 = new ImagePackNode(rect.x, rect.y + h, rect.w, rect.h - h);
|
||||
}
|
||||
return child1.pack(img);
|
||||
}
|
||||
|
||||
private int getFit(int w, int h) {
|
||||
if(w == rect.w && h == rect.h)
|
||||
return 2;
|
||||
if(w == rect.h && h == rect.w)
|
||||
return 3;
|
||||
if(rect.w >= w && rect.h >= h)
|
||||
return 4;
|
||||
if(rect.w >= h && rect.h >= w)
|
||||
return 5;
|
||||
if (w == rect.w && h == rect.h) return 2;
|
||||
if (w == rect.h && h == rect.w) return 3;
|
||||
if (rect.w >= w && rect.h >= h) return 4;
|
||||
if (rect.w >= h && rect.h >= w) return 5;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
private static void nextSize(Rectangle4i rect, boolean square) {
|
||||
if(square) {
|
||||
if (square) {
|
||||
rect.w <<= 1;
|
||||
rect.h <<= 1;
|
||||
}
|
||||
else {
|
||||
if(rect.w == rect.h)
|
||||
rect.w *= 2;
|
||||
else
|
||||
rect.h *= 2;
|
||||
} else {
|
||||
if (rect.w == rect.h) rect.w *= 2;
|
||||
else rect.h *= 2;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,23 +76,20 @@ public class QBImporter
|
||||
Collections.sort(images);
|
||||
|
||||
int area = 0;
|
||||
for(QBImage img : images)
|
||||
area+=img.area();
|
||||
for (QBImage img : images) area += img.area();
|
||||
|
||||
ImagePackNode node = new ImagePackNode(0, 0, 2, 2);
|
||||
while(node.rect.area() < area)
|
||||
nextSize(node.rect, square);
|
||||
while (node.rect.area() < area) nextSize(node.rect, square);
|
||||
|
||||
while(true) {
|
||||
while (true) {
|
||||
boolean packed = true;
|
||||
for(QBImage img : images)
|
||||
if(!node.pack(img)) {
|
||||
for (QBImage img : images)
|
||||
if (!node.pack(img)) {
|
||||
packed = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if(packed)
|
||||
return node;
|
||||
if (packed) return node;
|
||||
|
||||
node.child1 = node.child2 = null;
|
||||
nextSize(node.rect, square);
|
||||
@@ -119,23 +103,21 @@ public class QBImporter
|
||||
}
|
||||
|
||||
private void write(BufferedImage img) {
|
||||
if(child1 != null) {
|
||||
if (child1 != null) {
|
||||
child1.write(img);
|
||||
child2.write(img);
|
||||
}
|
||||
else if(packed != null) {
|
||||
} else if (packed != null) {
|
||||
ImageTransform t = packed.packT;
|
||||
for(int u = 0; u < rect.w; u++)
|
||||
for(int v = 0; v < rect.h; v++) {
|
||||
for (int u = 0; u < rect.w; u++)
|
||||
for (int v = 0; v < rect.h; v++) {
|
||||
int rgba = t.access(packed, u, v);
|
||||
img.setRGB(u+rect.x, v+rect.y, rgba>>>8 | rgba<<24);
|
||||
img.setRGB(u + rect.x, v + rect.y, rgba >>> 8 | rgba << 24);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class ImageTransform
|
||||
{
|
||||
private static class ImageTransform {
|
||||
int transform;
|
||||
|
||||
public ImageTransform(int i) {
|
||||
@@ -147,44 +129,43 @@ public class QBImporter
|
||||
}
|
||||
|
||||
public boolean transpose() {
|
||||
return (transform&4) != 0;
|
||||
return (transform & 4) != 0;
|
||||
}
|
||||
|
||||
public boolean flipU() {
|
||||
return (transform&1) != 0;
|
||||
return (transform & 1) != 0;
|
||||
}
|
||||
|
||||
public boolean flipV() {
|
||||
return (transform&2) != 0;
|
||||
return (transform & 2) != 0;
|
||||
}
|
||||
|
||||
public int access(QBImage img, int u, int v) {
|
||||
if(transpose()) {
|
||||
int tmp = u; u = v; v = tmp;
|
||||
if (transpose()) {
|
||||
int tmp = u;
|
||||
u = v;
|
||||
v = tmp;
|
||||
}
|
||||
if(flipU())
|
||||
u = img.width()-1-u;
|
||||
if(flipV())
|
||||
v = img.height()-1-v;
|
||||
if (flipU()) u = img.width() - 1 - u;
|
||||
if (flipV()) v = img.height() - 1 - v;
|
||||
|
||||
return img.data[u][v];
|
||||
}
|
||||
|
||||
public UV transform(UV uv) {
|
||||
if(transpose()) {
|
||||
double tmp = uv.u; uv.u = uv.v; uv.v = tmp;
|
||||
if (transpose()) {
|
||||
double tmp = uv.u;
|
||||
uv.u = uv.v;
|
||||
uv.v = tmp;
|
||||
}
|
||||
if(flipU())
|
||||
uv.u = 1-uv.u;
|
||||
if(flipV())
|
||||
uv.v = 1-uv.v;
|
||||
if (flipU()) uv.u = 1 - uv.u;
|
||||
if (flipV()) uv.v = 1 - uv.v;
|
||||
|
||||
return uv;
|
||||
}
|
||||
}
|
||||
|
||||
public static class QBImage implements Comparable<QBImage>
|
||||
{
|
||||
public static class QBImage implements Comparable<QBImage> {
|
||||
int[][] data;
|
||||
ImageTransform packT;
|
||||
Rectangle4i packSlot;
|
||||
@@ -198,57 +179,54 @@ public class QBImporter
|
||||
}
|
||||
|
||||
public int area() {
|
||||
return width()*height();
|
||||
return width() * height();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(QBImage o) {
|
||||
int a = area(); int b = o.area();
|
||||
int a = area();
|
||||
int b = o.area();
|
||||
return a > b ? -1 : a == b ? 0 : 1;
|
||||
}
|
||||
|
||||
public ImageTransform transformTo(QBImage img) {
|
||||
if(width() == img.width() && height() == img.height())
|
||||
for(int i = 0; i < 4; i++) {
|
||||
if (width() == img.width() && height() == img.height())
|
||||
for (int i = 0; i < 4; i++) {
|
||||
ImageTransform t = new ImageTransform(i);
|
||||
if(equals(img, t))
|
||||
return t;
|
||||
if (equals(img, t)) return t;
|
||||
}
|
||||
if(width() == img.height() && height() == img.width())
|
||||
for(int i = 4; i < 8; i++) {
|
||||
if (width() == img.height() && height() == img.width())
|
||||
for (int i = 4; i < 8; i++) {
|
||||
ImageTransform t = new ImageTransform(i);
|
||||
if(equals(img, t))
|
||||
return t;
|
||||
if (equals(img, t)) return t;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean equals(QBImage img, ImageTransform t) {
|
||||
for(int u = 0; u < img.width(); u++)
|
||||
for(int v = 0; v < img.height(); v++)
|
||||
if(t.access(this, u, v) != img.data[u][v])
|
||||
return false;
|
||||
for (int u = 0; u < img.width(); u++)
|
||||
for (int v = 0; v < img.height(); v++) if (t.access(this, u, v) != img.data[u][v]) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void transform(UV uv) {
|
||||
packT.transform(uv);
|
||||
uv.u*=packSlot.w;
|
||||
uv.v*=packSlot.h;
|
||||
uv.u+=packSlot.x;
|
||||
uv.v+=packSlot.y;
|
||||
uv.u *= packSlot.w;
|
||||
uv.v *= packSlot.h;
|
||||
uv.u += packSlot.x;
|
||||
uv.v += packSlot.y;
|
||||
}
|
||||
}
|
||||
|
||||
private static final int[][] vertOrder = new int[][] {//clockwise because MC is left handed
|
||||
{3, 0},
|
||||
{1, 0},
|
||||
{1, 2},
|
||||
{3, 2}};
|
||||
private static final int[][] vertOrder = new int[][] { // clockwise because MC is left handed
|
||||
{3, 0},
|
||||
{1, 0},
|
||||
{1, 2},
|
||||
{3, 2}
|
||||
};
|
||||
|
||||
public static class QBQuad
|
||||
{
|
||||
public static class QBQuad {
|
||||
public Vertex5[] verts = new Vertex5[4];
|
||||
public QBImage image = new QBImage();
|
||||
public ImageTransform t = new ImageTransform();
|
||||
@@ -259,24 +237,24 @@ public class QBImporter
|
||||
}
|
||||
|
||||
public void applyImageT() {
|
||||
for(Vertex5 vert : verts) {
|
||||
for (Vertex5 vert : verts) {
|
||||
t.transform(vert.uv);
|
||||
image.transform(vert.uv);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static QBQuad restore(Rectangle4i flat, int side, double d, QBImage img) {
|
||||
QBQuad quad = new QBQuad(side);
|
||||
quad.image = img;
|
||||
|
||||
Transformation t = new Scale(-1, 1, -1).with(Rotation.sideOrientation(side, 0)).with(new Translation(new Vector3().setSide(side, d)));
|
||||
Transformation t = new Scale(-1, 1, -1)
|
||||
.with(Rotation.sideOrientation(side, 0))
|
||||
.with(new Translation(new Vector3().setSide(side, d)));
|
||||
quad.verts[0] = new Vertex5(flat.x, 0, flat.y, 0, 0);
|
||||
quad.verts[1] = new Vertex5(flat.x+flat.w, 0, flat.y, 1, 0);
|
||||
quad.verts[2] = new Vertex5(flat.x+flat.w, 0, flat.y+flat.h, 1, 1);
|
||||
quad.verts[3] = new Vertex5(flat.x, 0, flat.y+flat.h, 0, 1);
|
||||
for(Vertex5 vert : quad.verts)
|
||||
vert.apply(t);
|
||||
quad.verts[1] = new Vertex5(flat.x + flat.w, 0, flat.y, 1, 0);
|
||||
quad.verts[2] = new Vertex5(flat.x + flat.w, 0, flat.y + flat.h, 1, 1);
|
||||
quad.verts[3] = new Vertex5(flat.x, 0, flat.y + flat.h, 0, 1);
|
||||
for (Vertex5 vert : quad.verts) vert.apply(t);
|
||||
|
||||
return quad;
|
||||
}
|
||||
@@ -285,12 +263,11 @@ public class QBImporter
|
||||
Transformation t = Rotation.sideOrientation(side, 0).inverse().with(new Scale(-1, 0, -1));
|
||||
Vector3 vmin = verts[0].vec.copy().apply(t);
|
||||
Vector3 vmax = verts[2].vec.copy().apply(t);
|
||||
return new Rectangle4i((int)vmin.x, (int)vmin.z, (int)(vmax.x-vmin.x), (int)(vmax.z-vmin.z));
|
||||
return new Rectangle4i((int) vmin.x, (int) vmin.z, (int) (vmax.x - vmin.x), (int) (vmax.z - vmin.z));
|
||||
}
|
||||
}
|
||||
|
||||
public static class QBCuboid
|
||||
{
|
||||
public static class QBCuboid {
|
||||
public QBMatrix mat;
|
||||
public CuboidCoord c;
|
||||
public int sides;
|
||||
@@ -304,16 +281,16 @@ public class QBImporter
|
||||
public static boolean intersects(QBCuboid a, QBCuboid b) {
|
||||
CuboidCoord c = a.c;
|
||||
CuboidCoord d = b.c;
|
||||
return c.min.x <= d.max.x &&
|
||||
d.min.x <= c.max.x &&
|
||||
c.min.y <= d.max.y &&
|
||||
d.min.y <= c.max.y &&
|
||||
c.min.z <= d.max.z &&
|
||||
d.min.z <= c.max.z;
|
||||
return c.min.x <= d.max.x
|
||||
&& d.min.x <= c.max.x
|
||||
&& c.min.y <= d.max.y
|
||||
&& d.min.y <= c.max.y
|
||||
&& c.min.z <= d.max.z
|
||||
&& d.min.z <= c.max.z;
|
||||
}
|
||||
|
||||
public static void clip(QBCuboid a, QBCuboid b) {
|
||||
if(intersects(a, b)) {
|
||||
if (intersects(a, b)) {
|
||||
a.clip(b);
|
||||
b.clip(a);
|
||||
}
|
||||
@@ -321,22 +298,21 @@ public class QBImporter
|
||||
|
||||
public void clip(QBCuboid o) {
|
||||
CuboidCoord d = o.c;
|
||||
for(int a = 0; a < 6; a+=2)
|
||||
{
|
||||
int a1 = (a+2)%6;
|
||||
int a2 = (a+4)%6;
|
||||
if(c.getSide(a1+1) <= d.getSide(a1+1) &&
|
||||
c.getSide(a1) >= d.getSide(a1) &&
|
||||
c.getSide(a2+1) <= d.getSide(a2+1) &&
|
||||
c.getSide(a2) >= d.getSide(a2)) {
|
||||
for (int a = 0; a < 6; a += 2) {
|
||||
int a1 = (a + 2) % 6;
|
||||
int a2 = (a + 4) % 6;
|
||||
if (c.getSide(a1 + 1) <= d.getSide(a1 + 1)
|
||||
&& c.getSide(a1) >= d.getSide(a1)
|
||||
&& c.getSide(a2 + 1) <= d.getSide(a2 + 1)
|
||||
&& c.getSide(a2) >= d.getSide(a2)) {
|
||||
|
||||
if(c.getSide(a) <= d.getSide(a+1) && c.getSide(a) >= d.getSide(a)) {
|
||||
if (c.getSide(a) <= d.getSide(a + 1) && c.getSide(a) >= d.getSide(a)) {
|
||||
c.setSide(a, d.getSide(a + 1) + 1);
|
||||
sides|=1<<a;
|
||||
sides |= 1 << a;
|
||||
}
|
||||
if(c.getSide(a+1) >= d.getSide(a) && c.getSide(a+1) <= d.getSide(a+1)) {
|
||||
if (c.getSide(a + 1) >= d.getSide(a) && c.getSide(a + 1) <= d.getSide(a + 1)) {
|
||||
c.setSide(a + 1, d.getSide(a) - 1);
|
||||
sides|=2<<a;
|
||||
sides |= 2 << a;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -344,24 +320,22 @@ public class QBImporter
|
||||
|
||||
public void extractQuads(List<QBQuad> quads) {
|
||||
Cuboid6 box = c.bounds();
|
||||
for(int s = 0; s < 6; s++)
|
||||
if((sides & 1<<s) == 0)
|
||||
quads.add(extractQuad(s, box));
|
||||
for (int s = 0; s < 6; s++) if ((sides & 1 << s) == 0) quads.add(extractQuad(s, box));
|
||||
}
|
||||
|
||||
private QBQuad extractQuad(int side, Cuboid6 box) {
|
||||
double[] da = new double[3];
|
||||
da[side>>1] = box.getSide(side);
|
||||
da[side >> 1] = box.getSide(side);
|
||||
|
||||
QBQuad quad = new QBQuad(side);
|
||||
for(int i = 0; i < 4; i++) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
int rU = vertOrder[i][0];
|
||||
int rV = vertOrder[i][1];
|
||||
int sideU = Rotation.rotateSide(side, rU);
|
||||
int sideV = Rotation.rotateSide(side, rV);
|
||||
da[sideU>>1] = box.getSide(sideU);
|
||||
da[sideV>>1] = box.getSide(sideV);
|
||||
quad.verts[i] = new Vertex5(Vector3.fromAxes(da), (3-rU)/2, rV/2);
|
||||
da[sideU >> 1] = box.getSide(sideU);
|
||||
da[sideV >> 1] = box.getSide(sideV);
|
||||
quad.verts[i] = new Vertex5(Vector3.fromAxes(da), (3 - rU) / 2, rV / 2);
|
||||
}
|
||||
|
||||
int sideU = Rotation.rotateSide(side, 1);
|
||||
@@ -370,47 +344,44 @@ public class QBImporter
|
||||
QBImage image = quad.image;
|
||||
|
||||
int[] ia = new int[3];
|
||||
ia[side>>1] = c.getSide(side); ia[sideU>>1] = c.getSide(sideU^1); ia[sideV>>1] = c.getSide(sideV^1);
|
||||
ia[side >> 1] = c.getSide(side);
|
||||
ia[sideU >> 1] = c.getSide(sideU ^ 1);
|
||||
ia[sideV >> 1] = c.getSide(sideV ^ 1);
|
||||
BlockCoord b = BlockCoord.fromAxes(ia);
|
||||
BlockCoord bU = BlockCoord.sideOffsets[sideU];
|
||||
BlockCoord bV = BlockCoord.sideOffsets[sideV];
|
||||
for(int u = 0; u < image.width(); u++)
|
||||
for(int v = 0; v < image.height(); v++)
|
||||
image.data[u][v] = mat.matrix[b.x+bU.x*u+bV.x*v][b.y+bU.y*u+bV.y*v][b.z+bU.z*u+bV.z*v];
|
||||
for (int u = 0; u < image.width(); u++)
|
||||
for (int v = 0; v < image.height(); v++)
|
||||
image.data[u][v] =
|
||||
mat.matrix[b.x + bU.x * u + bV.x * v][b.y + bU.y * u + bV.y * v][b.z + bU.z * u + bV.z * v];
|
||||
|
||||
return quad;
|
||||
}
|
||||
}
|
||||
|
||||
public static class QBMatrix
|
||||
{
|
||||
public static class QBMatrix {
|
||||
public String name;
|
||||
public BlockCoord pos;
|
||||
public BlockCoord size;
|
||||
public int[][][] matrix;
|
||||
|
||||
public void readMatrix(DataInputStream din, boolean compressed) throws IOException {
|
||||
if(compressed) {
|
||||
if (compressed) {
|
||||
int z = 0;
|
||||
while (z < size.z)
|
||||
{
|
||||
while (z < size.z) {
|
||||
int index = 0;
|
||||
|
||||
while (true)
|
||||
{
|
||||
while (true) {
|
||||
int data = din.readInt();
|
||||
|
||||
if (data == NEXTSLICEFLAG)
|
||||
break;
|
||||
if (data == NEXTSLICEFLAG) break;
|
||||
|
||||
if (data == CODEFLAG) {
|
||||
int count = readTni(din);
|
||||
data = din.readInt();
|
||||
|
||||
for(int j = 0; j < count; j++, index++)
|
||||
matrix[index % size.x][index / size.x][z] = data;
|
||||
}
|
||||
else {
|
||||
for (int j = 0; j < count; j++, index++) matrix[index % size.x][index / size.x][z] = data;
|
||||
} else {
|
||||
matrix[index % size.x][index / size.x][z] = data;
|
||||
index++;
|
||||
}
|
||||
@@ -418,28 +389,23 @@ public class QBImporter
|
||||
z++;
|
||||
}
|
||||
} else {
|
||||
for(int z = 0; z < size.z; z++)
|
||||
for(int y = 0; y < size.y; y++)
|
||||
for(int x = 0; x < size.x; x++)
|
||||
matrix[x][y][z] = din.readInt();
|
||||
for (int z = 0; z < size.z; z++)
|
||||
for (int y = 0; y < size.y; y++) for (int x = 0; x < size.x; x++) matrix[x][y][z] = din.readInt();
|
||||
}
|
||||
}
|
||||
|
||||
public void convertBGRAtoRGBA() {
|
||||
for(int z = 0; z < size.z; z++)
|
||||
for(int y = 0; y < size.y; y++)
|
||||
for(int x = 0; x < size.x; x++) {
|
||||
for (int z = 0; z < size.z; z++)
|
||||
for (int y = 0; y < size.y; y++)
|
||||
for (int x = 0; x < size.x; x++) {
|
||||
int i = matrix[x][y][z];
|
||||
matrix[x][y][z] = Integer.reverseBytes(i>>>8)|i&0xFF;
|
||||
matrix[x][y][z] = Integer.reverseBytes(i >>> 8) | i & 0xFF;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean voxelFull(boolean[][][] solid, CuboidCoord c) {
|
||||
for(BlockCoord b : c)
|
||||
if(matrix[b.x][b.y][b.z] == 0)
|
||||
return false;
|
||||
for(BlockCoord b : c)
|
||||
solid[b.x][b.y][b.z] = false;
|
||||
for (BlockCoord b : c) if (matrix[b.x][b.y][b.z] == 0) return false;
|
||||
for (BlockCoord b : c) solid[b.x][b.y][b.z] = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -447,14 +413,13 @@ public class QBImporter
|
||||
CuboidCoord c = new CuboidCoord(b);
|
||||
solid[b.x][b.y][b.z] = false;
|
||||
|
||||
for(int s = 0; s < 6; s++) {
|
||||
for (int s = 0; s < 6; s++) {
|
||||
CuboidCoord slice = c.copy();
|
||||
slice.expand(s^1, -(slice.size(s)-1));
|
||||
slice.expand(s ^ 1, -(slice.size(s) - 1));
|
||||
slice.expand(s, 1);
|
||||
|
||||
while(slice.getSide(s) >= 0 && slice.getSide(s) < size.getSide(s)) {
|
||||
if(!voxelFull(solid, slice))
|
||||
break;
|
||||
while (slice.getSide(s) >= 0 && slice.getSide(s) < size.getSide(s)) {
|
||||
if (!voxelFull(solid, slice)) break;
|
||||
slice.expand(s ^ 1, -1);
|
||||
slice.expand(s, 1);
|
||||
c.expand(s, 1);
|
||||
@@ -466,105 +431,93 @@ public class QBImporter
|
||||
public List<QBCuboid> rectangulate() {
|
||||
List<QBCuboid> list = new ArrayList<QBCuboid>();
|
||||
boolean[][][] solid = new boolean[size.x][size.y][size.z];
|
||||
for(int z = 0; z < size.z; z++)
|
||||
for(int y = 0; y < size.y; y++)
|
||||
for(int x = 0; x < size.x; x++)
|
||||
solid[x][y][z] = matrix[x][y][z] != 0;
|
||||
for (int z = 0; z < size.z; z++)
|
||||
for (int y = 0; y < size.y; y++) for (int x = 0; x < size.x; x++) solid[x][y][z] = matrix[x][y][z] != 0;
|
||||
|
||||
for(int x = 0; x < size.x; x++)
|
||||
for(int z = 0; z < size.z; z++)
|
||||
for(int y = 0; y < size.y; y++)
|
||||
if(solid[x][y][z])
|
||||
list.add(expand(solid, new BlockCoord(x, y, z)));
|
||||
for (int x = 0; x < size.x; x++)
|
||||
for (int z = 0; z < size.z; z++)
|
||||
for (int y = 0; y < size.y; y++)
|
||||
if (solid[x][y][z]) list.add(expand(solid, new BlockCoord(x, y, z)));
|
||||
|
||||
for(int i = 0; i < list.size(); i++)
|
||||
for(int j = i+1; j < list.size(); j++)
|
||||
QBCuboid.clip(list.get(i), list.get(j));
|
||||
for (int i = 0; i < list.size(); i++)
|
||||
for (int j = i + 1; j < list.size(); j++) QBCuboid.clip(list.get(i), list.get(j));
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
public List<QBQuad> extractQuads(boolean texturePlanes) {
|
||||
List<QBQuad> quads = new LinkedList<QBQuad>();
|
||||
for(QBCuboid c : rectangulate())
|
||||
c.extractQuads(quads);
|
||||
for (QBCuboid c : rectangulate()) c.extractQuads(quads);
|
||||
|
||||
if(texturePlanes)
|
||||
optimisePlanes(quads);
|
||||
if (texturePlanes) optimisePlanes(quads);
|
||||
|
||||
return quads;
|
||||
}
|
||||
|
||||
private void optimisePlanes(List<QBQuad> quads) {
|
||||
Multimap<Integer, QBQuad> map = HashMultimap.create();
|
||||
for(QBQuad quad : quads)
|
||||
map.put(quad.side | ((int)quad.verts[0].vec.getSide(quad.side))<<3, quad);
|
||||
for (QBQuad quad : quads) map.put(quad.side | ((int) quad.verts[0].vec.getSide(quad.side)) << 3, quad);
|
||||
|
||||
quads.clear();
|
||||
for(Integer key : map.keySet()) {
|
||||
for (Integer key : map.keySet()) {
|
||||
Collection<QBQuad> plane = map.get(key);
|
||||
if(plane.size() == 1) {
|
||||
if (plane.size() == 1) {
|
||||
quads.add(plane.iterator().next());
|
||||
continue;
|
||||
}
|
||||
|
||||
int side = key&7;
|
||||
int side = key & 7;
|
||||
Rectangle4i rect = null;
|
||||
for(QBQuad q : plane)
|
||||
if(rect == null)
|
||||
rect = q.flatten();
|
||||
else
|
||||
rect.include(q.flatten());
|
||||
for (QBQuad q : plane)
|
||||
if (rect == null) rect = q.flatten();
|
||||
else rect.include(q.flatten());
|
||||
|
||||
QBImage img = new QBImage();
|
||||
img.data = new int[rect.w][rect.h];
|
||||
for(QBQuad q : plane) {
|
||||
for (QBQuad q : plane) {
|
||||
QBImage from = q.image;
|
||||
Rectangle4i r = q.flatten();
|
||||
int du = r.x-rect.x;
|
||||
int dv = r.y-rect.y;
|
||||
for(int u = 0; u < from.width(); u++)
|
||||
for(int v = 0; v < from.height(); v++)
|
||||
img.data[du+u][dv+v] = from.data[u][v];
|
||||
int du = r.x - rect.x;
|
||||
int dv = r.y - rect.y;
|
||||
for (int u = 0; u < from.width(); u++)
|
||||
for (int v = 0; v < from.height(); v++) img.data[du + u][dv + v] = from.data[u][v];
|
||||
}
|
||||
|
||||
quads.add(QBQuad.restore(rect, side, key>>3, img));
|
||||
quads.add(QBQuad.restore(rect, side, key >> 3, img));
|
||||
}
|
||||
}
|
||||
|
||||
public CCModel buildModel(List<QBQuad> quads, BufferedImage img, boolean scaleMC) {
|
||||
CCModel m = CCModel.quadModel(quads.size()*4);
|
||||
CCModel m = CCModel.quadModel(quads.size() * 4);
|
||||
int i = 0;
|
||||
for(QBQuad quad : quads) {
|
||||
for (QBQuad quad : quads) {
|
||||
quad.applyImageT();
|
||||
m.verts[i++] = quad.verts[0];
|
||||
m.verts[i++] = quad.verts[1];
|
||||
m.verts[i++] = quad.verts[2];
|
||||
m.verts[i++] = quad.verts[3];
|
||||
}
|
||||
m.apply(new UVScale(1D/img.getWidth(), 1D/img.getHeight()));
|
||||
m.apply(new UVScale(1D / img.getWidth(), 1D / img.getHeight()));
|
||||
m.apply(new Translation(pos.x, pos.y, pos.z));
|
||||
if(scaleMC)
|
||||
m.apply(new Scale(1/16D));
|
||||
if (scaleMC) m.apply(new Scale(1 / 16D));
|
||||
m.computeNormals();
|
||||
return m;
|
||||
}
|
||||
|
||||
private static void addImages(List<QBQuad> quads, List<QBImage> images) {
|
||||
for(QBQuad q : quads) {
|
||||
for (QBQuad q : quads) {
|
||||
QBImage img = q.image;
|
||||
boolean matched = false;
|
||||
for(QBImage img2 : images) {
|
||||
for (QBImage img2 : images) {
|
||||
ImageTransform t = img.transformTo(img2);
|
||||
if(t != null) {
|
||||
if (t != null) {
|
||||
q.t = t;
|
||||
q.image = img2;
|
||||
matched = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!matched)
|
||||
images.add(img);
|
||||
if (!matched) images.add(img);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -573,8 +526,8 @@ public class QBImporter
|
||||
public static final int SQUARETEXTURE = 2;
|
||||
public static final int MERGETEXTURES = 4;
|
||||
public static final int SCALEMC = 8;
|
||||
public static class QBModel
|
||||
{
|
||||
|
||||
public static class QBModel {
|
||||
public QBMatrix[] matrices;
|
||||
public boolean rightHanded;
|
||||
|
||||
@@ -588,21 +541,21 @@ public class QBImporter
|
||||
boolean mergeTextures = (flags & MERGETEXTURES) != 0;
|
||||
boolean scaleMC = (flags & SCALEMC) != 0;
|
||||
|
||||
for(QBMatrix mat : matrices) {
|
||||
for (QBMatrix mat : matrices) {
|
||||
List<QBQuad> quads = mat.extractQuads(texturePlanes);
|
||||
modelQuads.add(quads);
|
||||
QBMatrix.addImages(quads, qbImages);
|
||||
if(!mergeTextures) {
|
||||
if (!mergeTextures) {
|
||||
images.add(ImagePackNode.pack(qbImages, squareTextures).toImage());
|
||||
qbImages.clear();
|
||||
}
|
||||
}
|
||||
|
||||
if(mergeTextures)
|
||||
if (mergeTextures)
|
||||
images.add(ImagePackNode.pack(qbImages, squareTextures).toImage());
|
||||
|
||||
RasterisedModel m = new RasterisedModel(images);
|
||||
for(int i = 0; i < matrices.length; i++) {
|
||||
for (int i = 0; i < matrices.length; i++) {
|
||||
QBMatrix mat = matrices[i];
|
||||
BufferedImage img = images.get(mergeTextures ? 0 : i);
|
||||
m.add(mat.name, mat.buildModel(modelQuads.get(i), img, scaleMC));
|
||||
@@ -611,8 +564,7 @@ public class QBImporter
|
||||
}
|
||||
}
|
||||
|
||||
public static class RasterisedModel
|
||||
{
|
||||
public static class RasterisedModel {
|
||||
private class Holder {
|
||||
CCModel m;
|
||||
int img;
|
||||
@@ -633,7 +585,7 @@ public class QBImporter
|
||||
}
|
||||
|
||||
public void add(String name, CCModel m) {
|
||||
map.put(name, new Holder(m, Math.min(map.size(), images.size()-1)));
|
||||
map.put(name, new Holder(m, Math.min(map.size(), images.size() - 1)));
|
||||
}
|
||||
|
||||
public CCModel getModel(String key) {
|
||||
@@ -642,41 +594,37 @@ public class QBImporter
|
||||
|
||||
public IIcon getIcon(String key, IIconRegister r, String iconName) {
|
||||
int img = map.get(key).img;
|
||||
if(icons[img] != null && !iconName.equals(icons[img]))
|
||||
throw new IllegalArgumentException("Attempted to get a previously registered icon by a different name: "+icons[img]+", "+iconName);
|
||||
if(icons[img] != null)
|
||||
return r.registerIcon(iconName);
|
||||
if (icons[img] != null && !iconName.equals(icons[img]))
|
||||
throw new IllegalArgumentException("Attempted to get a previously registered icon by a different name: "
|
||||
+ icons[img] + ", " + iconName);
|
||||
if (icons[img] != null) return r.registerIcon(iconName);
|
||||
|
||||
icons[img] = iconName;
|
||||
return TextureUtils.getTextureSpecial(r, iconName).addTexture(new TextureDataHolder(images.get(img)));
|
||||
}
|
||||
|
||||
private void exportImg(BufferedImage img, File imgFile) throws IOException {
|
||||
if(!imgFile.exists())
|
||||
imgFile.createNewFile();
|
||||
if (!imgFile.exists()) imgFile.createNewFile();
|
||||
ImageIO.write(img, "PNG", imgFile);
|
||||
}
|
||||
|
||||
public void export(File objFile, File imgDir) {
|
||||
try {
|
||||
if(!objFile.exists())
|
||||
objFile.createNewFile();
|
||||
if(!imgDir.exists())
|
||||
imgDir.mkdirs();
|
||||
if (!objFile.exists()) objFile.createNewFile();
|
||||
if (!imgDir.exists()) imgDir.mkdirs();
|
||||
|
||||
Map<String, CCModel> modelMap = new HashMap<String, CCModel>();
|
||||
for(Map.Entry<String, Holder> e : map.entrySet())
|
||||
modelMap.put(e.getKey(), e.getValue().m);
|
||||
for (Map.Entry<String, Holder> e : map.entrySet()) modelMap.put(e.getKey(), e.getValue().m);
|
||||
|
||||
PrintWriter p = new PrintWriter(objFile);
|
||||
CCModel.exportObj(modelMap, p);
|
||||
p.close();
|
||||
|
||||
if(images.size() < map.size())
|
||||
if (images.size() < map.size())
|
||||
exportImg(images.get(0), new File(imgDir, objFile.getName().replaceAll("(.+)\\..+", "$1.png")));
|
||||
else
|
||||
for(Map.Entry<String, Holder> e : map.entrySet())
|
||||
exportImg(images.get(e.getValue().img), new File(imgDir, e.getKey()+".png"));
|
||||
for (Map.Entry<String, Holder> e : map.entrySet())
|
||||
exportImg(images.get(e.getValue().img), new File(imgDir, e.getKey() + ".png"));
|
||||
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
@@ -685,7 +633,7 @@ public class QBImporter
|
||||
}
|
||||
|
||||
private static String readAsciiString(DataInputStream din) throws IOException {
|
||||
byte[] bytes = new byte[din.readByte()&0xFF];
|
||||
byte[] bytes = new byte[din.readByte() & 0xFF];
|
||||
din.readFully(bytes);
|
||||
return new String(bytes, "US-ASCII");
|
||||
}
|
||||
@@ -696,6 +644,7 @@ public class QBImporter
|
||||
|
||||
private static final int CODEFLAG = Integer.reverseBytes(2);
|
||||
private static final int NEXTSLICEFLAG = Integer.reverseBytes(6);
|
||||
|
||||
public static QBModel loadQB(InputStream input) throws IOException {
|
||||
DataInputStream din = new DataInputStream(input);
|
||||
|
||||
@@ -706,11 +655,10 @@ public class QBImporter
|
||||
boolean compressed = din.readInt() != 0;
|
||||
boolean visEncoded = din.readInt() != 0;
|
||||
|
||||
if(visEncoded)
|
||||
throw new IllegalArgumentException("Encoded Visiblity States not supported");
|
||||
if (visEncoded) throw new IllegalArgumentException("Encoded Visiblity States not supported");
|
||||
|
||||
m.matrices = new QBMatrix[readTni(din)];
|
||||
for(int i = 0; i < m.matrices.length; i++) {
|
||||
for (int i = 0; i < m.matrices.length; i++) {
|
||||
QBMatrix mat = new QBMatrix();
|
||||
m.matrices[i] = mat;
|
||||
mat.name = readAsciiString(din);
|
||||
@@ -718,8 +666,7 @@ public class QBImporter
|
||||
mat.pos = new BlockCoord(readTni(din), readTni(din), readTni(din));
|
||||
mat.matrix = new int[mat.size.x][mat.size.y][mat.size.z];
|
||||
mat.readMatrix(din, compressed);
|
||||
if(colorFormat == 1)
|
||||
mat.convertBGRAtoRGBA();
|
||||
if (colorFormat == 1) mat.convertBGRAtoRGBA();
|
||||
}
|
||||
|
||||
return m;
|
||||
@@ -727,9 +674,12 @@ public class QBImporter
|
||||
|
||||
public static QBModel loadQB(ResourceLocation res) {
|
||||
try {
|
||||
return loadQB(Minecraft.getMinecraft().getResourceManager().getResource(res).getInputStream());
|
||||
} catch(Exception e) {
|
||||
throw new RuntimeException("failed to load model: "+res, e);
|
||||
return loadQB(Minecraft.getMinecraft()
|
||||
.getResourceManager()
|
||||
.getResource(res)
|
||||
.getInputStream());
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("failed to load model: " + res, e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -741,8 +691,8 @@ public class QBImporter
|
||||
} finally {
|
||||
fin.close();
|
||||
}
|
||||
} catch(Exception e) {
|
||||
throw new RuntimeException("failed to load model: "+file.getPath(), e);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("failed to load model: " + file.getPath(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,8 @@
|
||||
package codechicken.lib.render;
|
||||
|
||||
import static net.minecraftforge.client.IItemRenderer.ItemRenderType.ENTITY;
|
||||
import static net.minecraftforge.client.IItemRenderer.ItemRendererHelper.BLOCK_3D;
|
||||
|
||||
import codechicken.lib.vec.Cuboid6;
|
||||
import codechicken.lib.vec.Rectangle4i;
|
||||
import codechicken.lib.vec.Vector3;
|
||||
@@ -19,35 +22,32 @@ import net.minecraftforge.fluids.Fluid;
|
||||
import net.minecraftforge.fluids.FluidStack;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
import static net.minecraftforge.client.IItemRenderer.ItemRenderType.ENTITY;
|
||||
import static net.minecraftforge.client.IItemRenderer.ItemRendererHelper.BLOCK_3D;
|
||||
|
||||
public class RenderUtils
|
||||
{
|
||||
public class RenderUtils {
|
||||
static Vector3[] vectors = new Vector3[8];
|
||||
static RenderItem uniformRenderItem = new RenderItem()
|
||||
{
|
||||
public boolean shouldBob()
|
||||
{
|
||||
static RenderItem uniformRenderItem = new RenderItem() {
|
||||
public boolean shouldBob() {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
static EntityItem entityItem;
|
||||
|
||||
static
|
||||
{
|
||||
for(int i = 0; i < vectors.length; i++)
|
||||
vectors[i] = new Vector3();
|
||||
|
||||
|
||||
static {
|
||||
for (int i = 0; i < vectors.length; i++) vectors[i] = new Vector3();
|
||||
|
||||
uniformRenderItem.setRenderManager(RenderManager.instance);
|
||||
|
||||
|
||||
entityItem = new EntityItem(null);
|
||||
entityItem.hoverStart = 0;
|
||||
}
|
||||
|
||||
public static void renderFluidQuad(Vector3 point1, Vector3 point2, Vector3 point3, Vector3 point4, IIcon icon, double res)
|
||||
{
|
||||
renderFluidQuad(point2, vectors[0].set(point4).subtract(point1), vectors[1].set(point1).subtract(point2), icon, res);
|
||||
public static void renderFluidQuad(
|
||||
Vector3 point1, Vector3 point2, Vector3 point3, Vector3 point4, IIcon icon, double res) {
|
||||
renderFluidQuad(
|
||||
point2,
|
||||
vectors[0].set(point4).subtract(point1),
|
||||
vectors[1].set(point1).subtract(point2),
|
||||
icon,
|
||||
res);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -57,60 +57,60 @@ public class RenderUtils
|
||||
* @param high The left side of the quad
|
||||
* @param res Units per icon
|
||||
*/
|
||||
public static void renderFluidQuad(Vector3 base, Vector3 wide, Vector3 high, IIcon icon, double res)
|
||||
{
|
||||
public static void renderFluidQuad(Vector3 base, Vector3 wide, Vector3 high, IIcon icon, double res) {
|
||||
Tessellator t = Tessellator.instance;
|
||||
|
||||
double u1 = icon.getMinU();
|
||||
double du = icon.getMaxU()-icon.getMinU();
|
||||
double du = icon.getMaxU() - icon.getMinU();
|
||||
double v2 = icon.getMaxV();
|
||||
double dv = icon.getMaxV()-icon.getMinV();
|
||||
double dv = icon.getMaxV() - icon.getMinV();
|
||||
|
||||
double wlen = wide.mag();
|
||||
double hlen = high.mag();
|
||||
|
||||
|
||||
double x = 0;
|
||||
while(x < wlen)
|
||||
{
|
||||
while (x < wlen) {
|
||||
double rx = wlen - x;
|
||||
if(rx > res)
|
||||
rx = res;
|
||||
if (rx > res) rx = res;
|
||||
|
||||
double y = 0;
|
||||
while(y < hlen)
|
||||
{
|
||||
double ry = hlen-y;
|
||||
if(ry > res)
|
||||
ry = res;
|
||||
while (y < hlen) {
|
||||
double ry = hlen - y;
|
||||
if (ry > res) ry = res;
|
||||
|
||||
Vector3 dx1 = vectors[2].set(wide).multiply(x/wlen);
|
||||
Vector3 dx2 = vectors[3].set(wide).multiply((x+rx)/wlen);
|
||||
Vector3 dy1 = vectors[4].set(high).multiply(y/hlen);
|
||||
Vector3 dy2 = vectors[5].set(high).multiply((y+ry)/hlen);
|
||||
Vector3 dx1 = vectors[2].set(wide).multiply(x / wlen);
|
||||
Vector3 dx2 = vectors[3].set(wide).multiply((x + rx) / wlen);
|
||||
Vector3 dy1 = vectors[4].set(high).multiply(y / hlen);
|
||||
Vector3 dy2 = vectors[5].set(high).multiply((y + ry) / hlen);
|
||||
|
||||
t.addVertexWithUV(base.x+dx1.x+dy2.x, base.y+dx1.y+dy2.y, base.z+dx1.z+dy2.z, u1, v2-ry/res*dv);
|
||||
t.addVertexWithUV(base.x+dx1.x+dy1.x, base.y+dx1.y+dy1.y, base.z+dx1.z+dy1.z, u1, v2);
|
||||
t.addVertexWithUV(base.x+dx2.x+dy1.x, base.y+dx2.y+dy1.y, base.z+dx2.z+dy1.z, u1+rx/res*du, v2);
|
||||
t.addVertexWithUV(base.x+dx2.x+dy2.x, base.y+dx2.y+dy2.y, base.z+dx2.z+dy2.z, u1+rx/res*du, v2-ry/res*dv);
|
||||
|
||||
y+=ry;
|
||||
t.addVertexWithUV(
|
||||
base.x + dx1.x + dy2.x, base.y + dx1.y + dy2.y, base.z + dx1.z + dy2.z, u1, v2 - ry / res * dv);
|
||||
t.addVertexWithUV(base.x + dx1.x + dy1.x, base.y + dx1.y + dy1.y, base.z + dx1.z + dy1.z, u1, v2);
|
||||
t.addVertexWithUV(
|
||||
base.x + dx2.x + dy1.x, base.y + dx2.y + dy1.y, base.z + dx2.z + dy1.z, u1 + rx / res * du, v2);
|
||||
t.addVertexWithUV(
|
||||
base.x + dx2.x + dy2.x,
|
||||
base.y + dx2.y + dy2.y,
|
||||
base.z + dx2.z + dy2.z,
|
||||
u1 + rx / res * du,
|
||||
v2 - ry / res * dv);
|
||||
|
||||
y += ry;
|
||||
}
|
||||
|
||||
x+=rx;
|
||||
|
||||
x += rx;
|
||||
}
|
||||
}
|
||||
|
||||
public static void translateToWorldCoords(Entity entity, float frame)
|
||||
{
|
||||
|
||||
public static void translateToWorldCoords(Entity entity, float frame) {
|
||||
double interpPosX = entity.lastTickPosX + (entity.posX - entity.lastTickPosX) * frame;
|
||||
double interpPosY = entity.lastTickPosY + (entity.posY - entity.lastTickPosY) * frame;
|
||||
double interpPosZ = entity.lastTickPosZ + (entity.posZ - entity.lastTickPosZ) * frame;
|
||||
|
||||
|
||||
GL11.glTranslated(-interpPosX, -interpPosY, -interpPosZ);
|
||||
}
|
||||
|
||||
public static void drawCuboidOutline(Cuboid6 c)
|
||||
{
|
||||
|
||||
public static void drawCuboidOutline(Cuboid6 c) {
|
||||
Tessellator var2 = Tessellator.instance;
|
||||
var2.startDrawing(3);
|
||||
var2.addVertex(c.min.x, c.min.y, c.min.z);
|
||||
@@ -137,130 +137,130 @@ public class RenderUtils
|
||||
var2.addVertex(c.min.x, c.max.y, c.max.z);
|
||||
var2.draw();
|
||||
}
|
||||
|
||||
public static void renderFluidCuboid(Cuboid6 bound, IIcon tex, double res)
|
||||
{
|
||||
renderFluidQuad(//bottom
|
||||
|
||||
public static void renderFluidCuboid(Cuboid6 bound, IIcon tex, double res) {
|
||||
renderFluidQuad( // bottom
|
||||
new Vector3(bound.min.x, bound.min.y, bound.min.z),
|
||||
new Vector3(bound.max.x, bound.min.y, bound.min.z),
|
||||
new Vector3(bound.max.x, bound.min.y, bound.max.z),
|
||||
new Vector3(bound.min.x, bound.min.y, bound.max.z),
|
||||
tex, res);
|
||||
renderFluidQuad(//top
|
||||
new Vector3(bound.min.x, bound.min.y, bound.max.z),
|
||||
tex,
|
||||
res);
|
||||
renderFluidQuad( // top
|
||||
new Vector3(bound.min.x, bound.max.y, bound.min.z),
|
||||
new Vector3(bound.min.x, bound.max.y, bound.max.z),
|
||||
new Vector3(bound.max.x, bound.max.y, bound.max.z),
|
||||
new Vector3(bound.max.x, bound.max.y, bound.min.z),
|
||||
tex, res);
|
||||
renderFluidQuad(//-x
|
||||
new Vector3(bound.max.x, bound.max.y, bound.min.z),
|
||||
tex,
|
||||
res);
|
||||
renderFluidQuad( // -x
|
||||
new Vector3(bound.min.x, bound.max.y, bound.min.z),
|
||||
new Vector3(bound.min.x, bound.min.y, bound.min.z),
|
||||
new Vector3(bound.min.x, bound.min.y, bound.max.z),
|
||||
new Vector3(bound.min.x, bound.max.y, bound.max.z),
|
||||
tex, res);
|
||||
renderFluidQuad(//+x
|
||||
new Vector3(bound.min.x, bound.max.y, bound.max.z),
|
||||
tex,
|
||||
res);
|
||||
renderFluidQuad( // +x
|
||||
new Vector3(bound.max.x, bound.max.y, bound.max.z),
|
||||
new Vector3(bound.max.x, bound.min.y, bound.max.z),
|
||||
new Vector3(bound.max.x, bound.min.y, bound.min.z),
|
||||
new Vector3(bound.max.x, bound.max.y, bound.min.z),
|
||||
tex, res);
|
||||
renderFluidQuad(//-z
|
||||
new Vector3(bound.max.x, bound.max.y, bound.min.z),
|
||||
tex,
|
||||
res);
|
||||
renderFluidQuad( // -z
|
||||
new Vector3(bound.max.x, bound.max.y, bound.min.z),
|
||||
new Vector3(bound.max.x, bound.min.y, bound.min.z),
|
||||
new Vector3(bound.min.x, bound.min.y, bound.min.z),
|
||||
new Vector3(bound.min.x, bound.max.y, bound.min.z),
|
||||
tex, res);
|
||||
renderFluidQuad(//+z
|
||||
new Vector3(bound.min.x, bound.max.y, bound.min.z),
|
||||
tex,
|
||||
res);
|
||||
renderFluidQuad( // +z
|
||||
new Vector3(bound.min.x, bound.max.y, bound.max.z),
|
||||
new Vector3(bound.min.x, bound.min.y, bound.max.z),
|
||||
new Vector3(bound.max.x, bound.min.y, bound.max.z),
|
||||
new Vector3(bound.max.x, bound.max.y, bound.max.z),
|
||||
tex, res);
|
||||
new Vector3(bound.max.x, bound.max.y, bound.max.z),
|
||||
tex,
|
||||
res);
|
||||
}
|
||||
|
||||
public static void renderBlockOverlaySide(int x, int y, int z, int side, double tx1, double tx2, double ty1, double ty2)
|
||||
{
|
||||
double[] points = new double[]{x - 0.009, x + 1.009, y - 0.009, y + 1.009, z - 0.009, z + 1.009};
|
||||
|
||||
public static void renderBlockOverlaySide(
|
||||
int x, int y, int z, int side, double tx1, double tx2, double ty1, double ty2) {
|
||||
double[] points = new double[] {x - 0.009, x + 1.009, y - 0.009, y + 1.009, z - 0.009, z + 1.009};
|
||||
|
||||
Tessellator tessellator = Tessellator.instance;
|
||||
switch(side)
|
||||
{
|
||||
switch (side) {
|
||||
case 0:
|
||||
tessellator.addVertexWithUV(points[0], points[2], points[4], tx1, ty1);
|
||||
tessellator.addVertexWithUV(points[1], points[2], points[4], tx2, ty1);
|
||||
tessellator.addVertexWithUV(points[1], points[2], points[5], tx2, ty2);
|
||||
tessellator.addVertexWithUV(points[0], points[2], points[5], tx1, ty2);
|
||||
break;
|
||||
break;
|
||||
case 1:
|
||||
tessellator.addVertexWithUV(points[1], points[3], points[4], tx2, ty1);
|
||||
tessellator.addVertexWithUV(points[0], points[3], points[4], tx1, ty1);
|
||||
tessellator.addVertexWithUV(points[0], points[3], points[5], tx1, ty2);
|
||||
tessellator.addVertexWithUV(points[1], points[3], points[5], tx2, ty2);
|
||||
break;
|
||||
break;
|
||||
case 2:
|
||||
tessellator.addVertexWithUV(points[0], points[3], points[4], tx2, ty1);
|
||||
tessellator.addVertexWithUV(points[1], points[3], points[4], tx1, ty1);
|
||||
tessellator.addVertexWithUV(points[1], points[2], points[4], tx1, ty2);
|
||||
tessellator.addVertexWithUV(points[0], points[2], points[4], tx2, ty2);
|
||||
break;
|
||||
break;
|
||||
case 3:
|
||||
tessellator.addVertexWithUV(points[1], points[3], points[5], tx2, ty1);
|
||||
tessellator.addVertexWithUV(points[0], points[3], points[5], tx1, ty1);
|
||||
tessellator.addVertexWithUV(points[0], points[2], points[5], tx1, ty2);
|
||||
tessellator.addVertexWithUV(points[1], points[2], points[5], tx2, ty2);
|
||||
break;
|
||||
break;
|
||||
case 4:
|
||||
tessellator.addVertexWithUV(points[0], points[3], points[5], tx2, ty1);
|
||||
tessellator.addVertexWithUV(points[0], points[3], points[4], tx1, ty1);
|
||||
tessellator.addVertexWithUV(points[0], points[2], points[4], tx1, ty2);
|
||||
tessellator.addVertexWithUV(points[0], points[2], points[5], tx2, ty2);
|
||||
break;
|
||||
break;
|
||||
case 5:
|
||||
tessellator.addVertexWithUV(points[1], points[3], points[4], tx2, ty1);
|
||||
tessellator.addVertexWithUV(points[1], points[3], points[5], tx1, ty1);
|
||||
tessellator.addVertexWithUV(points[1], points[2], points[5], tx1, ty2);
|
||||
tessellator.addVertexWithUV(points[1], points[2], points[4], tx2, ty2);
|
||||
break;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean shouldRenderFluid(FluidStack stack)
|
||||
{
|
||||
public static boolean shouldRenderFluid(FluidStack stack) {
|
||||
return stack.amount > 0 && stack.getFluid() != null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param stack The fluid stack to render
|
||||
* @return The icon of the fluid
|
||||
*/
|
||||
public static IIcon prepareFluidRender(FluidStack stack, int alpha)
|
||||
{
|
||||
public static IIcon prepareFluidRender(FluidStack stack, int alpha) {
|
||||
GL11.glDisable(GL11.GL_LIGHTING);
|
||||
GL11.glEnable(GL11.GL_BLEND);
|
||||
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
|
||||
Fluid fluid = stack.getFluid();
|
||||
CCRenderState.setColour(fluid.getColor(stack)<<8|alpha);
|
||||
CCRenderState.setColour(fluid.getColor(stack) << 8 | alpha);
|
||||
TextureUtils.bindAtlas(fluid.getSpriteNumber());
|
||||
return TextureUtils.safeIcon(fluid.getIcon(stack));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Re-enables lighting and disables blending.
|
||||
*/
|
||||
public static void postFluidRender()
|
||||
{
|
||||
public static void postFluidRender() {
|
||||
GL11.glEnable(GL11.GL_LIGHTING);
|
||||
GL11.glDisable(GL11.GL_BLEND);
|
||||
}
|
||||
|
||||
public static double fluidDensityToAlpha(double density)
|
||||
{
|
||||
|
||||
public static double fluidDensityToAlpha(double density) {
|
||||
return Math.pow(density, 0.4);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders a fluid within a bounding box.
|
||||
* Renders a fluid within a bounding box.
|
||||
* If the fluid is a liquid it will render as a normal tank with height equal to density/bound.height.
|
||||
* If the fluid is a gas, it will render the full box with an alpha equal to density.
|
||||
* Warning, bound will be mutated if the fluid is a liquid
|
||||
@@ -269,50 +269,43 @@ public class RenderUtils
|
||||
* @param density The volume of fluid / the capacity of the tank. For gases this determines the alpha, for liquids this determines the height.
|
||||
* @param res The resolution to render at.
|
||||
*/
|
||||
public static void renderFluidCuboid(FluidStack stack, Cuboid6 bound, double density, double res)
|
||||
{
|
||||
if(!shouldRenderFluid(stack))
|
||||
return;
|
||||
|
||||
public static void renderFluidCuboid(FluidStack stack, Cuboid6 bound, double density, double res) {
|
||||
if (!shouldRenderFluid(stack)) return;
|
||||
|
||||
int alpha = 255;
|
||||
if(stack.getFluid().isGaseous())
|
||||
alpha = (int) (fluidDensityToAlpha(density)*255);
|
||||
else
|
||||
bound.max.y = bound.min.y+(bound.max.y-bound.min.y)*density;
|
||||
|
||||
if (stack.getFluid().isGaseous()) alpha = (int) (fluidDensityToAlpha(density) * 255);
|
||||
else bound.max.y = bound.min.y + (bound.max.y - bound.min.y) * density;
|
||||
|
||||
IIcon tex = prepareFluidRender(stack, alpha);
|
||||
CCRenderState.startDrawing();
|
||||
renderFluidCuboid(bound, tex, res);
|
||||
CCRenderState.draw();
|
||||
postFluidRender();
|
||||
}
|
||||
|
||||
public static void renderFluidGauge(FluidStack stack, Rectangle4i rect, double density, double res)
|
||||
{
|
||||
if(!shouldRenderFluid(stack))
|
||||
return;
|
||||
|
||||
|
||||
public static void renderFluidGauge(FluidStack stack, Rectangle4i rect, double density, double res) {
|
||||
if (!shouldRenderFluid(stack)) return;
|
||||
|
||||
int alpha = 255;
|
||||
if(stack.getFluid().isGaseous())
|
||||
alpha = (int) (fluidDensityToAlpha(density)*255);
|
||||
else
|
||||
{
|
||||
int height = (int) (rect.h*density);
|
||||
rect.y +=rect.h-height;
|
||||
if (stack.getFluid().isGaseous()) alpha = (int) (fluidDensityToAlpha(density) * 255);
|
||||
else {
|
||||
int height = (int) (rect.h * density);
|
||||
rect.y += rect.h - height;
|
||||
rect.h = height;
|
||||
}
|
||||
|
||||
|
||||
IIcon tex = prepareFluidRender(stack, alpha);
|
||||
CCRenderState.startDrawing();
|
||||
renderFluidQuad(
|
||||
new Vector3(rect.x, rect.y+rect.h, 0),
|
||||
new Vector3(rect.w,0, 0),
|
||||
new Vector3(0, -rect.h, 0), tex, res);
|
||||
new Vector3(rect.x, rect.y + rect.h, 0),
|
||||
new Vector3(rect.w, 0, 0),
|
||||
new Vector3(0, -rect.h, 0),
|
||||
tex,
|
||||
res);
|
||||
CCRenderState.draw();
|
||||
postFluidRender();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Renders items and blocks in the world at 0,0,0 with transformations that size them appropriately
|
||||
*/
|
||||
@@ -324,33 +317,29 @@ public class RenderUtils
|
||||
* Renders items and blocks in the world at 0,0,0 with transformations that size them appropriately
|
||||
* @param spin The spin angle of the item around the y axis in degrees
|
||||
*/
|
||||
public static void renderItemUniform(ItemStack item, double spin)
|
||||
{
|
||||
public static void renderItemUniform(ItemStack item, double spin) {
|
||||
IItemRenderer customRenderer = MinecraftForgeClient.getItemRenderer(item, ENTITY);
|
||||
boolean is3D = customRenderer != null && customRenderer.shouldUseRenderHelper(ENTITY, item, BLOCK_3D);
|
||||
|
||||
boolean larger = false;
|
||||
if (item.getItem() instanceof ItemBlock && RenderBlocks.renderItemIn3d(Block.getBlockFromItem(item.getItem()).getRenderType()))
|
||||
{
|
||||
if (item.getItem() instanceof ItemBlock
|
||||
&& RenderBlocks.renderItemIn3d(
|
||||
Block.getBlockFromItem(item.getItem()).getRenderType())) {
|
||||
int renderType = Block.getBlockFromItem(item.getItem()).getRenderType();
|
||||
larger = !(renderType == 1 || renderType == 19 || renderType == 12 || renderType == 2);
|
||||
}
|
||||
else if(is3D)
|
||||
{
|
||||
} else if (is3D) {
|
||||
larger = true;
|
||||
}
|
||||
|
||||
|
||||
double d = 2;
|
||||
double d1 = 1/d;
|
||||
if(larger)
|
||||
GL11.glScaled(d, d, d);
|
||||
double d1 = 1 / d;
|
||||
if (larger) GL11.glScaled(d, d, d);
|
||||
|
||||
GL11.glColor4f(1, 1, 1, 1);
|
||||
|
||||
|
||||
entityItem.setEntityItemStack(item);
|
||||
uniformRenderItem.doRender(entityItem, 0, larger ? 0.09 : 0.06, 0, 0, (float)(spin*9/Math.PI));
|
||||
|
||||
if(larger)
|
||||
GL11.glScaled(d1, d1, d1);
|
||||
uniformRenderItem.doRender(entityItem, 0, larger ? 0.09 : 0.06, 0, 0, (float) (spin * 9 / Math.PI));
|
||||
|
||||
if (larger) GL11.glScaled(d1, d1, d1);
|
||||
}
|
||||
}
|
||||
@@ -1,137 +1,109 @@
|
||||
package codechicken.lib.render;
|
||||
|
||||
import org.lwjgl.opengl.ARBShaderObjects;
|
||||
import org.lwjgl.opengl.ARBVertexShader;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
import org.lwjgl.util.vector.Matrix4f;
|
||||
import static org.lwjgl.opengl.ARBShaderObjects.*;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import org.lwjgl.opengl.ARBShaderObjects;
|
||||
import org.lwjgl.opengl.ARBVertexShader;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
import org.lwjgl.util.vector.Matrix4f;
|
||||
|
||||
import static org.lwjgl.opengl.ARBShaderObjects.*;
|
||||
|
||||
public class ShaderProgram
|
||||
{
|
||||
public class ShaderProgram {
|
||||
int programID;
|
||||
|
||||
public ShaderProgram()
|
||||
{
|
||||
|
||||
public ShaderProgram() {
|
||||
programID = glCreateProgramObjectARB();
|
||||
if(programID == 0)
|
||||
throw new RuntimeException("Unable to allocate shader program object.");
|
||||
if (programID == 0) throw new RuntimeException("Unable to allocate shader program object.");
|
||||
}
|
||||
|
||||
public void attach(int shaderType, String resource)
|
||||
{
|
||||
|
||||
public void attach(int shaderType, String resource) {
|
||||
InputStream stream = ShaderProgram.class.getResourceAsStream(resource);
|
||||
if(stream == null)
|
||||
throw new RuntimeException("Unable to locate resource: "+resource);
|
||||
|
||||
if (stream == null) throw new RuntimeException("Unable to locate resource: " + resource);
|
||||
|
||||
attach(shaderType, stream);
|
||||
}
|
||||
|
||||
public void use()
|
||||
{
|
||||
|
||||
public void use() {
|
||||
glUseProgramObjectARB(programID);
|
||||
}
|
||||
|
||||
public static void restore()
|
||||
{
|
||||
|
||||
public static void restore() {
|
||||
glUseProgramObjectARB(0);
|
||||
}
|
||||
|
||||
public void link()
|
||||
{
|
||||
|
||||
public void link() {
|
||||
glLinkProgramARB(programID);
|
||||
if(glGetObjectParameteriARB(programID, GL_OBJECT_LINK_STATUS_ARB) == GL11.GL_FALSE)
|
||||
throw new RuntimeException("Error linking program: "+getInfoLog(programID));
|
||||
|
||||
if (glGetObjectParameteriARB(programID, GL_OBJECT_LINK_STATUS_ARB) == GL11.GL_FALSE)
|
||||
throw new RuntimeException("Error linking program: " + getInfoLog(programID));
|
||||
|
||||
glValidateProgramARB(programID);
|
||||
if(glGetObjectParameteriARB(programID, GL_OBJECT_VALIDATE_STATUS_ARB) == GL11.GL_FALSE)
|
||||
throw new RuntimeException("Error validating program: "+getInfoLog(programID));
|
||||
|
||||
if (glGetObjectParameteriARB(programID, GL_OBJECT_VALIDATE_STATUS_ARB) == GL11.GL_FALSE)
|
||||
throw new RuntimeException("Error validating program: " + getInfoLog(programID));
|
||||
|
||||
use();
|
||||
onLink();
|
||||
restore();
|
||||
}
|
||||
|
||||
public void attach(int shaderType, InputStream stream)
|
||||
{
|
||||
if(stream == null)
|
||||
throw new RuntimeException("Invalid shader inputstream");
|
||||
|
||||
|
||||
public void attach(int shaderType, InputStream stream) {
|
||||
if (stream == null) throw new RuntimeException("Invalid shader inputstream");
|
||||
|
||||
int shaderID = 0;
|
||||
try
|
||||
{
|
||||
try {
|
||||
shaderID = glCreateShaderObjectARB(shaderType);
|
||||
if(shaderID == 0)
|
||||
throw new RuntimeException("Unable to allocate shader object.");
|
||||
|
||||
try
|
||||
{
|
||||
if (shaderID == 0) throw new RuntimeException("Unable to allocate shader object.");
|
||||
|
||||
try {
|
||||
glShaderSourceARB(shaderID, asString(stream));
|
||||
}
|
||||
catch(IOException e)
|
||||
{
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("Error reading inputstream.", e);
|
||||
}
|
||||
|
||||
|
||||
glCompileShaderARB(shaderID);
|
||||
if(glGetObjectParameteriARB(shaderID, GL_OBJECT_COMPILE_STATUS_ARB) == GL11.GL_FALSE)
|
||||
throw new RuntimeException("Error compiling shader: "+getInfoLog(shaderID));
|
||||
|
||||
if (glGetObjectParameteriARB(shaderID, GL_OBJECT_COMPILE_STATUS_ARB) == GL11.GL_FALSE)
|
||||
throw new RuntimeException("Error compiling shader: " + getInfoLog(shaderID));
|
||||
|
||||
glAttachObjectARB(programID, shaderID);
|
||||
}
|
||||
catch(RuntimeException e)
|
||||
{
|
||||
} catch (RuntimeException e) {
|
||||
glDeleteObjectARB(shaderID);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static String asString(InputStream stream) throws IOException
|
||||
{
|
||||
public static String asString(InputStream stream) throws IOException {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
BufferedReader bin = new BufferedReader(new InputStreamReader(stream));
|
||||
String line;
|
||||
while((line = bin.readLine()) != null)
|
||||
sb.append(line).append('\n');
|
||||
while ((line = bin.readLine()) != null) sb.append(line).append('\n');
|
||||
stream.close();
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private static String getInfoLog(int shaderID)
|
||||
{
|
||||
|
||||
private static String getInfoLog(int shaderID) {
|
||||
return glGetInfoLogARB(shaderID, glGetObjectParameteriARB(shaderID, GL_OBJECT_INFO_LOG_LENGTH_ARB));
|
||||
}
|
||||
|
||||
public int getUniformLoc(String name)
|
||||
{
|
||||
|
||||
public int getUniformLoc(String name) {
|
||||
return ARBShaderObjects.glGetUniformLocationARB(programID, name);
|
||||
}
|
||||
|
||||
public int getAttribLoc(String name)
|
||||
{
|
||||
public int getAttribLoc(String name) {
|
||||
return ARBVertexShader.glGetAttribLocationARB(programID, name);
|
||||
}
|
||||
|
||||
public void uniformTexture(String name, int textureIndex)
|
||||
{
|
||||
public void uniformTexture(String name, int textureIndex) {
|
||||
ARBShaderObjects.glUniform1iARB(getUniformLoc(name), textureIndex);
|
||||
}
|
||||
|
||||
public void onLink()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public void glVertexAttributeMat4(int loc, Matrix4f matrix)
|
||||
{
|
||||
ARBVertexShader.glVertexAttrib4fARB(loc , matrix.m00, matrix.m01, matrix.m02, matrix.m03);
|
||||
ARBVertexShader.glVertexAttrib4fARB(loc+1, matrix.m10, matrix.m11, matrix.m12, matrix.m13);
|
||||
ARBVertexShader.glVertexAttrib4fARB(loc+2, matrix.m20, matrix.m21, matrix.m22, matrix.m23);
|
||||
ARBVertexShader.glVertexAttrib4fARB(loc+3, matrix.m30, matrix.m31, matrix.m32, matrix.m33);
|
||||
|
||||
public void onLink() {}
|
||||
|
||||
public void glVertexAttributeMat4(int loc, Matrix4f matrix) {
|
||||
ARBVertexShader.glVertexAttrib4fARB(loc, matrix.m00, matrix.m01, matrix.m02, matrix.m03);
|
||||
ARBVertexShader.glVertexAttrib4fARB(loc + 1, matrix.m10, matrix.m11, matrix.m12, matrix.m13);
|
||||
ARBVertexShader.glVertexAttrib4fARB(loc + 2, matrix.m20, matrix.m21, matrix.m22, matrix.m23);
|
||||
ARBVertexShader.glVertexAttrib4fARB(loc + 3, matrix.m30, matrix.m31, matrix.m32, matrix.m33);
|
||||
}
|
||||
}
|
||||
@@ -3,19 +3,16 @@ package codechicken.lib.render;
|
||||
import codechicken.lib.render.TextureUtils.IIconSelfRegister;
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import net.minecraft.client.renderer.texture.IIconRegister;
|
||||
import net.minecraft.client.renderer.texture.TextureMap;
|
||||
import net.minecraft.util.IIcon;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
public class SpriteSheetManager
|
||||
{
|
||||
public class SpriteSheetManager {
|
||||
@SideOnly(Side.CLIENT)
|
||||
public static class SpriteSheet implements IIconSelfRegister
|
||||
{
|
||||
public static class SpriteSheet implements IIconSelfRegister {
|
||||
private int tilesX;
|
||||
private int tilesY;
|
||||
private ArrayList<Integer> newSprites = new ArrayList<Integer>();
|
||||
@@ -24,119 +21,106 @@ public class SpriteSheetManager
|
||||
private TextureDataHolder texture;
|
||||
private int spriteWidth;
|
||||
private int spriteHeight;
|
||||
|
||||
|
||||
public int atlasIndex;
|
||||
|
||||
private SpriteSheet(int tilesX, int tilesY, ResourceLocation textureFile)
|
||||
{
|
||||
|
||||
private SpriteSheet(int tilesX, int tilesY, ResourceLocation textureFile) {
|
||||
this.tilesX = tilesX;
|
||||
this.tilesY = tilesY;
|
||||
this.resource = textureFile;
|
||||
sprites = new TextureSpecial[tilesX*tilesY];
|
||||
sprites = new TextureSpecial[tilesX * tilesY];
|
||||
}
|
||||
|
||||
public void requestIndicies(int... indicies)
|
||||
{
|
||||
for(int i : indicies)
|
||||
setupSprite(i);
|
||||
|
||||
public void requestIndicies(int... indicies) {
|
||||
for (int i : indicies) setupSprite(i);
|
||||
}
|
||||
|
||||
public void registerIcons(IIconRegister register)
|
||||
{
|
||||
TextureMap textureMap = (TextureMap)register;
|
||||
|
||||
if(TextureUtils.refreshTexture(textureMap, resource.getResourcePath()))
|
||||
{
|
||||
|
||||
public void registerIcons(IIconRegister register) {
|
||||
TextureMap textureMap = (TextureMap) register;
|
||||
|
||||
if (TextureUtils.refreshTexture(textureMap, resource.getResourcePath())) {
|
||||
reloadTexture();
|
||||
for (TextureSpecial sprite : sprites)
|
||||
if (sprite != null)
|
||||
textureMap.setTextureEntry(sprite.getIconName(), sprite);
|
||||
}
|
||||
else
|
||||
{
|
||||
for(int i : newSprites)
|
||||
textureMap.setTextureEntry(sprites[i].getIconName(), sprites[i]);
|
||||
if (sprite != null) textureMap.setTextureEntry(sprite.getIconName(), sprite);
|
||||
} else {
|
||||
for (int i : newSprites) textureMap.setTextureEntry(sprites[i].getIconName(), sprites[i]);
|
||||
}
|
||||
newSprites.clear();
|
||||
}
|
||||
|
||||
public TextureSpecial setupSprite(int i)
|
||||
{
|
||||
if(sprites[i] == null)
|
||||
{
|
||||
String name = resource+"_"+i;
|
||||
|
||||
public TextureSpecial setupSprite(int i) {
|
||||
if (sprites[i] == null) {
|
||||
String name = resource + "_" + i;
|
||||
sprites[i] = new TextureSpecial(name).baseFromSheet(this, i);
|
||||
newSprites.add(i);
|
||||
}
|
||||
return sprites[i];
|
||||
}
|
||||
|
||||
private void reloadTexture()
|
||||
{
|
||||
private void reloadTexture() {
|
||||
texture = TextureUtils.loadTexture(resource);
|
||||
spriteWidth = texture.width/tilesX;
|
||||
spriteHeight = texture.height/tilesY;
|
||||
spriteWidth = texture.width / tilesX;
|
||||
spriteHeight = texture.height / tilesY;
|
||||
}
|
||||
|
||||
public IIcon getSprite(int index)
|
||||
{
|
||||
public IIcon getSprite(int index) {
|
||||
IIcon i = sprites[index];
|
||||
if(i == null)
|
||||
throw new IllegalArgumentException("Sprite at index: "+index+" from texture file "+resource+" was not preloaded.");
|
||||
if (i == null)
|
||||
throw new IllegalArgumentException(
|
||||
"Sprite at index: " + index + " from texture file " + resource + " was not preloaded.");
|
||||
return i;
|
||||
}
|
||||
|
||||
public TextureDataHolder createSprite(int spriteIndex)
|
||||
{
|
||||
int sx = spriteIndex%tilesX;
|
||||
int sy = spriteIndex/tilesX;
|
||||
public TextureDataHolder createSprite(int spriteIndex) {
|
||||
int sx = spriteIndex % tilesX;
|
||||
int sy = spriteIndex / tilesX;
|
||||
TextureDataHolder sprite = new TextureDataHolder(spriteWidth, spriteHeight);
|
||||
TextureUtils.copySubImg(texture.data, texture.width, sx*spriteWidth, sy*spriteHeight,
|
||||
spriteWidth, spriteHeight,
|
||||
sprite.data, spriteWidth, 0, 0);
|
||||
TextureUtils.copySubImg(
|
||||
texture.data,
|
||||
texture.width,
|
||||
sx * spriteWidth,
|
||||
sy * spriteHeight,
|
||||
spriteWidth,
|
||||
spriteHeight,
|
||||
sprite.data,
|
||||
spriteWidth,
|
||||
0,
|
||||
0);
|
||||
return sprite;
|
||||
}
|
||||
|
||||
public int spriteWidth()
|
||||
{
|
||||
public int spriteWidth() {
|
||||
return spriteWidth;
|
||||
}
|
||||
|
||||
public int spriteHeight()
|
||||
{
|
||||
|
||||
public int spriteHeight() {
|
||||
return spriteHeight;
|
||||
}
|
||||
|
||||
public TextureSpecial bindTextureFX(int i, TextureFX textureFX)
|
||||
{
|
||||
public TextureSpecial bindTextureFX(int i, TextureFX textureFX) {
|
||||
return setupSprite(i).addTextureFX(textureFX);
|
||||
}
|
||||
|
||||
public SpriteSheet selfRegister(int atlas)
|
||||
{
|
||||
public SpriteSheet selfRegister(int atlas) {
|
||||
TextureUtils.addIconRegistrar(this);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int atlasIndex()
|
||||
{
|
||||
public int atlasIndex() {
|
||||
return atlasIndex;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static HashMap<String, SpriteSheet> spriteSheets = new HashMap<String, SpriteSheet>();
|
||||
|
||||
public static SpriteSheet getSheet(ResourceLocation resource)
|
||||
{
|
||||
|
||||
public static SpriteSheet getSheet(ResourceLocation resource) {
|
||||
return getSheet(16, 16, resource);
|
||||
}
|
||||
|
||||
public static SpriteSheet getSheet(int tilesX, int tilesY, ResourceLocation resource)
|
||||
{
|
||||
public static SpriteSheet getSheet(int tilesX, int tilesY, ResourceLocation resource) {
|
||||
SpriteSheet sheet = spriteSheets.get(resource.toString());
|
||||
if(sheet == null)
|
||||
spriteSheets.put(resource.toString(), sheet = new SpriteSheet(tilesX, tilesY, resource));
|
||||
if (sheet == null) spriteSheets.put(resource.toString(), sheet = new SpriteSheet(tilesX, tilesY, resource));
|
||||
return sheet;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,34 +2,29 @@ package codechicken.lib.render;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
|
||||
public class TextureDataHolder
|
||||
{
|
||||
public class TextureDataHolder {
|
||||
public int width;
|
||||
public int height;
|
||||
public int[] data;
|
||||
|
||||
public TextureDataHolder(int width, int height)
|
||||
{
|
||||
|
||||
public TextureDataHolder(int width, int height) {
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
data = new int[width*height];
|
||||
data = new int[width * height];
|
||||
}
|
||||
|
||||
public TextureDataHolder(int[] data, int width)
|
||||
{
|
||||
public TextureDataHolder(int[] data, int width) {
|
||||
this.data = data;
|
||||
this.width = width;
|
||||
height = data.length/width;
|
||||
height = data.length / width;
|
||||
}
|
||||
|
||||
public TextureDataHolder(BufferedImage img)
|
||||
{
|
||||
public TextureDataHolder(BufferedImage img) {
|
||||
this(img.getWidth(), img.getHeight());
|
||||
img.getRGB(0, 0, width, height, data, 0, width);
|
||||
}
|
||||
|
||||
public TextureDataHolder copyData()
|
||||
{
|
||||
public TextureDataHolder copyData() {
|
||||
int[] copy = new int[data.length];
|
||||
System.arraycopy(data, 0, copy, 0, data.length);
|
||||
data = copy;
|
||||
|
||||
@@ -6,8 +6,7 @@ import cpw.mods.fml.relauncher.SideOnly;
|
||||
import net.minecraft.client.Minecraft;
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
public class TextureFX
|
||||
{
|
||||
public class TextureFX {
|
||||
public int[] imageData;
|
||||
public int tileSizeBase = 16;
|
||||
public int tileSizeSquare = 256;
|
||||
@@ -50,8 +49,7 @@ public class TextureFX
|
||||
onTick();
|
||||
}
|
||||
|
||||
public void onTick() {
|
||||
}
|
||||
public void onTick() {}
|
||||
|
||||
public boolean changed() {
|
||||
return true;
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
package codechicken.lib.render;
|
||||
|
||||
import codechicken.lib.asm.ObfMapping;
|
||||
import codechicken.lib.render.SpriteSheetManager.SpriteSheet;
|
||||
import codechicken.lib.render.TextureUtils.IIconSelfRegister;
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.util.ArrayList;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.texture.IIconRegister;
|
||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||
@@ -15,16 +16,13 @@ import net.minecraft.client.resources.data.AnimationMetadataSection;
|
||||
import net.minecraft.client.settings.GameSettings;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.util.ArrayList;
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
public class TextureSpecial extends TextureAtlasSprite implements IIconSelfRegister {
|
||||
//sprite sheet fields
|
||||
// sprite sheet fields
|
||||
private int spriteIndex;
|
||||
private SpriteSheet spriteSheet;
|
||||
|
||||
//textureFX fields
|
||||
// textureFX fields
|
||||
private TextureFX textureFX;
|
||||
private int mipmapLevels;
|
||||
private int rawWidth;
|
||||
@@ -41,8 +39,7 @@ public class TextureSpecial extends TextureAtlasSprite implements IIconSelfRegis
|
||||
}
|
||||
|
||||
public TextureSpecial addTexture(TextureDataHolder t) {
|
||||
if (baseTextures == null)
|
||||
baseTextures = new ArrayList<TextureDataHolder>();
|
||||
if (baseTextures == null) baseTextures = new ArrayList<TextureDataHolder>();
|
||||
baseTextures.add(t);
|
||||
return this;
|
||||
}
|
||||
@@ -61,8 +58,7 @@ public class TextureSpecial extends TextureAtlasSprite implements IIconSelfRegis
|
||||
@Override
|
||||
public void initSprite(int sheetWidth, int sheetHeight, int originX, int originY, boolean rotated) {
|
||||
super.initSprite(sheetWidth, sheetHeight, originX, originY, rotated);
|
||||
if (textureFX != null)
|
||||
textureFX.onTextureDimensionsUpdate(rawWidth, rawHeight);
|
||||
if (textureFX != null) textureFX.onTextureDimensionsUpdate(rawWidth, rawHeight);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -79,25 +75,19 @@ public class TextureSpecial extends TextureAtlasSprite implements IIconSelfRegis
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Copy paste mojang code because it's private, and CCL can't have access transformers or reflection
|
||||
*/
|
||||
public int[][] prepareAnisotropicFiltering(int[][] mipmaps) {
|
||||
if (Minecraft.getMinecraft().gameSettings.anisotropicFiltering <= 1)
|
||||
{
|
||||
if (Minecraft.getMinecraft().gameSettings.anisotropicFiltering <= 1) {
|
||||
return mipmaps;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
int[][] aint1 = new int[mipmaps.length][];
|
||||
|
||||
for (int k = 0; k < mipmaps.length; ++k)
|
||||
{
|
||||
for (int k = 0; k < mipmaps.length; ++k) {
|
||||
int[] aint2 = mipmaps[k];
|
||||
|
||||
if (aint2 != null)
|
||||
{
|
||||
if (aint2 != null) {
|
||||
int[] aint3 = new int[(rawWidth + 16 >> k) * (rawHeight + 16 >> k)];
|
||||
System.arraycopy(aint2, 0, aint3, 0, aint2.length);
|
||||
aint1[k] = TextureUtil.prepareAnisotropicData(aint3, rawWidth >> k, rawHeight >> k, 8 >> k);
|
||||
@@ -109,7 +99,8 @@ public class TextureSpecial extends TextureAtlasSprite implements IIconSelfRegis
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadSprite(BufferedImage[] images, AnimationMetadataSection animationMeta, boolean anisotropicFiltering) {
|
||||
public void loadSprite(
|
||||
BufferedImage[] images, AnimationMetadataSection animationMeta, boolean anisotropicFiltering) {
|
||||
rawWidth = images[0].getWidth();
|
||||
rawHeight = images[0].getHeight();
|
||||
super.loadSprite(images, animationMeta, anisotropicFiltering);
|
||||
@@ -128,7 +119,7 @@ public class TextureSpecial extends TextureAtlasSprite implements IIconSelfRegis
|
||||
|
||||
public void addFrame(int[] data, int width, int height) {
|
||||
GameSettings settings = Minecraft.getMinecraft().gameSettings;
|
||||
BufferedImage[] images = new BufferedImage[settings.mipmapLevels+1];
|
||||
BufferedImage[] images = new BufferedImage[settings.mipmapLevels + 1];
|
||||
images[0] = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
|
||||
images[0].setRGB(0, 0, width, height, data, 0, width);
|
||||
|
||||
@@ -138,19 +129,15 @@ public class TextureSpecial extends TextureAtlasSprite implements IIconSelfRegis
|
||||
@Override
|
||||
public boolean load(IResourceManager manager, ResourceLocation location) {
|
||||
if (baseTextures != null) {
|
||||
for (TextureDataHolder tex : baseTextures)
|
||||
addFrame(tex.data, tex.width, tex.height);
|
||||
}
|
||||
else if (spriteSheet != null) {
|
||||
for (TextureDataHolder tex : baseTextures) addFrame(tex.data, tex.width, tex.height);
|
||||
} else if (spriteSheet != null) {
|
||||
TextureDataHolder tex = spriteSheet.createSprite(spriteIndex);
|
||||
addFrame(tex.data, tex.width, tex.height);
|
||||
}
|
||||
else if (blankSize > 0) {
|
||||
} else if (blankSize > 0) {
|
||||
addFrame(new int[blankSize * blankSize], blankSize, blankSize);
|
||||
}
|
||||
|
||||
if (framesTextureData.isEmpty())
|
||||
throw new RuntimeException("No base frame for texture: " + getIconName());
|
||||
if (framesTextureData.isEmpty()) throw new RuntimeException("No base frame for texture: " + getIconName());
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -162,8 +149,7 @@ public class TextureSpecial extends TextureAtlasSprite implements IIconSelfRegis
|
||||
|
||||
@Override
|
||||
public int getFrameCount() {
|
||||
if (textureFX != null)
|
||||
return 1;
|
||||
if (textureFX != null) return 1;
|
||||
|
||||
return super.getFrameCount();
|
||||
}
|
||||
@@ -181,8 +167,7 @@ public class TextureSpecial extends TextureAtlasSprite implements IIconSelfRegis
|
||||
|
||||
@Override
|
||||
public void registerIcons(IIconRegister register) {
|
||||
if (selfRegister)
|
||||
((TextureMap) register).setTextureEntry(getIconName(), this);
|
||||
if (selfRegister) ((TextureMap) register).setTextureEntry(getIconName(), this);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -3,6 +3,11 @@ package codechicken.lib.render;
|
||||
import codechicken.lib.colour.Colour;
|
||||
import codechicken.lib.colour.ColourARGB;
|
||||
import cpw.mods.fml.common.eventhandler.SubscribeEvent;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import javax.imageio.ImageIO;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.texture.IIconRegister;
|
||||
import net.minecraft.client.renderer.texture.TextureManager;
|
||||
@@ -14,16 +19,8 @@ import net.minecraftforge.common.MinecraftForge;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
import org.lwjgl.opengl.GL12;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class TextureUtils
|
||||
{
|
||||
public static interface IIconSelfRegister
|
||||
{
|
||||
public class TextureUtils {
|
||||
public static interface IIconSelfRegister {
|
||||
public void registerIcons(IIconRegister register);
|
||||
|
||||
public int atlasIndex();
|
||||
@@ -42,8 +39,7 @@ public class TextureUtils
|
||||
@SubscribeEvent
|
||||
public void textureLoad(TextureStitchEvent.Pre event) {
|
||||
for (IIconSelfRegister reg : iconRegistrars)
|
||||
if (reg.atlasIndex() == event.map.getTextureType())
|
||||
reg.registerIcons(event.map);
|
||||
if (reg.atlasIndex() == event.map.getTextureType()) reg.registerIcons(event.map);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -56,13 +52,15 @@ public class TextureUtils
|
||||
public static Colour[] loadTextureColours(ResourceLocation resource) {
|
||||
int[] idata = loadTextureData(resource);
|
||||
Colour[] data = new Colour[idata.length];
|
||||
for (int i = 0; i < data.length; i++)
|
||||
data[i] = new ColourARGB(idata[i]);
|
||||
for (int i = 0; i < data.length; i++) data[i] = new ColourARGB(idata[i]);
|
||||
return data;
|
||||
}
|
||||
|
||||
public static InputStream getTextureResource(ResourceLocation textureFile) throws IOException {
|
||||
return Minecraft.getMinecraft().getResourceManager().getResource(textureFile).getInputStream();
|
||||
return Minecraft.getMinecraft()
|
||||
.getResourceManager()
|
||||
.getResource(textureFile)
|
||||
.getInputStream();
|
||||
}
|
||||
|
||||
public static BufferedImage loadBufferedImage(ResourceLocation textureFile) {
|
||||
@@ -85,7 +83,17 @@ public class TextureUtils
|
||||
return Minecraft.getMinecraft().renderEngine;
|
||||
}
|
||||
|
||||
public static void copySubImg(int[] fromTex, int fromWidth, int fromX, int fromY, int width, int height, int[] toTex, int toWidth, int toX, int toY) {
|
||||
public static void copySubImg(
|
||||
int[] fromTex,
|
||||
int fromWidth,
|
||||
int fromX,
|
||||
int fromY,
|
||||
int width,
|
||||
int height,
|
||||
int[] toTex,
|
||||
int toWidth,
|
||||
int toX,
|
||||
int toY) {
|
||||
for (int y = 0; y < height; y++)
|
||||
for (int x = 0; x < width; x++) {
|
||||
int fp = (y + fromY) * fromWidth + x + fromX;
|
||||
@@ -112,8 +120,7 @@ public class TextureUtils
|
||||
public static TextureSpecial getTextureSpecial(IIconRegister iconRegister, String name) {
|
||||
TextureMap textureMap = (TextureMap) iconRegister;
|
||||
IIcon entry = textureMap.getTextureExtry(name);
|
||||
if (entry != null)
|
||||
throw new IllegalStateException("Texture: " + name + " is already registered");
|
||||
if (entry != null) throw new IllegalStateException("Texture: " + name + " is already registered");
|
||||
|
||||
TextureSpecial icon = new TextureSpecial(name);
|
||||
textureMap.setTextureEntry(name, icon);
|
||||
@@ -136,8 +143,7 @@ public class TextureUtils
|
||||
|
||||
public static TextureDataHolder loadTexture(ResourceLocation resource) {
|
||||
BufferedImage img = loadBufferedImage(resource);
|
||||
if (img == null)
|
||||
throw new RuntimeException("Texture not found: " + resource);
|
||||
if (img == null) throw new RuntimeException("Texture not found: " + resource);
|
||||
return new TextureDataHolder(img);
|
||||
}
|
||||
|
||||
@@ -160,8 +166,7 @@ public class TextureUtils
|
||||
}
|
||||
|
||||
public static boolean isMissing(IIcon icon, ResourceLocation atlas) {
|
||||
if(icon == null)
|
||||
return true;
|
||||
if (icon == null) return true;
|
||||
|
||||
IIcon missing = ((TextureMap) engine().getTexture(atlas)).getAtlasSprite("missingno");
|
||||
return icon.getMinU() == missing.getMinU() && icon.getMinV() == missing.getMinV();
|
||||
|
||||
@@ -5,13 +5,11 @@ import codechicken.lib.render.uv.UVTransformation;
|
||||
import codechicken.lib.util.Copyable;
|
||||
import codechicken.lib.vec.Transformation;
|
||||
import codechicken.lib.vec.Vector3;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.MathContext;
|
||||
import java.math.RoundingMode;
|
||||
|
||||
public class Vertex5 implements Copyable<Vertex5>
|
||||
{
|
||||
public class Vertex5 implements Copyable<Vertex5> {
|
||||
public Vector3 vec;
|
||||
public UV uv;
|
||||
|
||||
@@ -64,8 +62,9 @@ public class Vertex5 implements Copyable<Vertex5>
|
||||
|
||||
public String toString() {
|
||||
MathContext cont = new MathContext(4, RoundingMode.HALF_UP);
|
||||
return "Vertex: (" + new BigDecimal(vec.x, cont) + ", " + new BigDecimal(vec.y, cont) + ", " + new BigDecimal(vec.z, cont) + ") " +
|
||||
"(" + new BigDecimal(uv.u, cont) + ", " + new BigDecimal(uv.v, cont) + ") ("+uv.tex+")";
|
||||
return "Vertex: (" + new BigDecimal(vec.x, cont) + ", " + new BigDecimal(vec.y, cont) + ", "
|
||||
+ new BigDecimal(vec.z, cont) + ") " + "(" + new BigDecimal(uv.u, cont) + ", "
|
||||
+ new BigDecimal(uv.v, cont) + ") (" + uv.tex + ")";
|
||||
}
|
||||
|
||||
public Vertex5 apply(Transformation t) {
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package codechicken.lib.render.uv;
|
||||
|
||||
import codechicken.lib.util.Copyable;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.MathContext;
|
||||
import java.math.RoundingMode;
|
||||
@@ -11,8 +10,7 @@ public class UV implements Copyable<UV> {
|
||||
public double v;
|
||||
public int tex;
|
||||
|
||||
public UV() {
|
||||
}
|
||||
public UV() {}
|
||||
|
||||
public UV(double u, double v) {
|
||||
this(u, v, 0);
|
||||
@@ -71,9 +69,8 @@ public class UV implements Copyable<UV> {
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (!(o instanceof UV))
|
||||
return false;
|
||||
if (!(o instanceof UV)) return false;
|
||||
UV uv = (UV) o;
|
||||
return u == uv.u && v == uv.v;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,11 @@
|
||||
package codechicken.lib.render.uv;
|
||||
|
||||
import codechicken.lib.math.MathHelper;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.MathContext;
|
||||
import java.math.RoundingMode;
|
||||
|
||||
public class UVRotation extends UVTransformation
|
||||
{
|
||||
public class UVRotation extends UVTransformation {
|
||||
public double angle;
|
||||
|
||||
/**
|
||||
@@ -21,8 +19,8 @@ public class UVRotation extends UVTransformation
|
||||
public void apply(UV uv) {
|
||||
double c = MathHelper.cos(angle);
|
||||
double s = MathHelper.sin(angle);
|
||||
double u2 = c*uv.u + s*uv.v;
|
||||
uv.v = - s*uv.u + c*uv.v;
|
||||
double u2 = c * uv.u + s * uv.v;
|
||||
uv.v = -s * uv.u + c * uv.v;
|
||||
uv.u = u2;
|
||||
}
|
||||
|
||||
@@ -33,8 +31,7 @@ public class UVRotation extends UVTransformation
|
||||
|
||||
@Override
|
||||
public UVTransformation merge(UVTransformation next) {
|
||||
if(next instanceof UVRotation)
|
||||
return new UVRotation(angle+((UVRotation)next).angle);
|
||||
if (next instanceof UVRotation) return new UVRotation(angle + ((UVRotation) next).angle);
|
||||
|
||||
return null;
|
||||
}
|
||||
@@ -45,8 +42,7 @@ public class UVRotation extends UVTransformation
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
public String toString() {
|
||||
MathContext cont = new MathContext(4, RoundingMode.HALF_UP);
|
||||
return "UVRotation(" + new BigDecimal(angle, cont) + ")";
|
||||
}
|
||||
|
||||
@@ -6,12 +6,13 @@ import codechicken.lib.vec.ITransformation;
|
||||
/**
|
||||
* Abstract supertype for any UV transformation
|
||||
*/
|
||||
public abstract class UVTransformation extends ITransformation<UV, UVTransformation> implements CCRenderState.IVertexOperation
|
||||
{
|
||||
public abstract class UVTransformation extends ITransformation<UV, UVTransformation>
|
||||
implements CCRenderState.IVertexOperation {
|
||||
public static final int operationIndex = CCRenderState.registerOperation();
|
||||
|
||||
public UVTransformation at(UV point) {
|
||||
return new UVTransformationList(new UVTranslation(-point.u, -point.v), this, new UVTranslation(point.u, point.v));
|
||||
return new UVTransformationList(
|
||||
new UVTranslation(-point.u, -point.v), this, new UVTranslation(point.u, point.v));
|
||||
}
|
||||
|
||||
public UVTransformationList with(UVTransformation t) {
|
||||
@@ -33,5 +34,3 @@ public abstract class UVTransformation extends ITransformation<UV, UVTransformat
|
||||
return operationIndex;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,52 +3,38 @@ package codechicken.lib.render.uv;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
|
||||
public class UVTransformationList extends UVTransformation
|
||||
{
|
||||
public class UVTransformationList extends UVTransformation {
|
||||
private ArrayList<UVTransformation> transformations = new ArrayList<UVTransformation>();
|
||||
|
||||
public UVTransformationList(UVTransformation... transforms)
|
||||
{
|
||||
for(UVTransformation t : transforms)
|
||||
if(t instanceof UVTransformationList)
|
||||
transformations.addAll(((UVTransformationList)t).transformations);
|
||||
else
|
||||
transformations.add(t);
|
||||
public UVTransformationList(UVTransformation... transforms) {
|
||||
for (UVTransformation t : transforms)
|
||||
if (t instanceof UVTransformationList) transformations.addAll(((UVTransformationList) t).transformations);
|
||||
else transformations.add(t);
|
||||
|
||||
compact();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply(UV uv)
|
||||
{
|
||||
for(int i = 0; i < transformations.size(); i++)
|
||||
transformations.get(i).apply(uv);
|
||||
public void apply(UV uv) {
|
||||
for (int i = 0; i < transformations.size(); i++) transformations.get(i).apply(uv);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UVTransformationList with(UVTransformation t)
|
||||
{
|
||||
if(t.isRedundant())
|
||||
return this;
|
||||
public UVTransformationList with(UVTransformation t) {
|
||||
if (t.isRedundant()) return this;
|
||||
|
||||
if(t instanceof UVTransformationList)
|
||||
transformations.addAll(((UVTransformationList)t).transformations);
|
||||
else
|
||||
transformations.add(t);
|
||||
if (t instanceof UVTransformationList) transformations.addAll(((UVTransformationList) t).transformations);
|
||||
else transformations.add(t);
|
||||
|
||||
compact();
|
||||
return this;
|
||||
}
|
||||
|
||||
public UVTransformationList prepend(UVTransformation t)
|
||||
{
|
||||
if(t.isRedundant())
|
||||
return this;
|
||||
public UVTransformationList prepend(UVTransformation t) {
|
||||
if (t.isRedundant()) return this;
|
||||
|
||||
if(t instanceof UVTransformationList)
|
||||
transformations.addAll(0, ((UVTransformationList)t).transformations);
|
||||
else
|
||||
transformations.add(0, t);
|
||||
if (t instanceof UVTransformationList) transformations.addAll(0, ((UVTransformationList) t).transformations);
|
||||
else transformations.add(0, t);
|
||||
|
||||
compact();
|
||||
return this;
|
||||
@@ -58,27 +44,21 @@ public class UVTransformationList extends UVTransformation
|
||||
ArrayList<UVTransformation> newList = new ArrayList<UVTransformation>(transformations.size());
|
||||
Iterator<UVTransformation> iterator = transformations.iterator();
|
||||
UVTransformation prev = null;
|
||||
while(iterator.hasNext()) {
|
||||
while (iterator.hasNext()) {
|
||||
UVTransformation t = iterator.next();
|
||||
if(t.isRedundant())
|
||||
continue;
|
||||
if (t.isRedundant()) continue;
|
||||
|
||||
if(prev != null) {
|
||||
if (prev != null) {
|
||||
UVTransformation m = prev.merge(t);
|
||||
if(m == null)
|
||||
newList.add(prev);
|
||||
else if(m.isRedundant())
|
||||
t = null;
|
||||
else
|
||||
t = m;
|
||||
if (m == null) newList.add(prev);
|
||||
else if (m.isRedundant()) t = null;
|
||||
else t = m;
|
||||
}
|
||||
prev = t;
|
||||
}
|
||||
if(prev != null)
|
||||
newList.add(prev);
|
||||
if (prev != null) newList.add(prev);
|
||||
|
||||
if(newList.size() < transformations.size())
|
||||
transformations = newList;
|
||||
if (newList.size() < transformations.size()) transformations = newList;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -87,20 +67,17 @@ public class UVTransformationList extends UVTransformation
|
||||
}
|
||||
|
||||
@Override
|
||||
public UVTransformation inverse()
|
||||
{
|
||||
public UVTransformation inverse() {
|
||||
UVTransformationList rev = new UVTransformationList();
|
||||
for(int i = transformations.size()-1; i >= 0; i--)
|
||||
for (int i = transformations.size() - 1; i >= 0; i--)
|
||||
rev.with(transformations.get(i).inverse());
|
||||
return rev;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
public String toString() {
|
||||
String s = "";
|
||||
for(UVTransformation t : transformations)
|
||||
s+="\n"+t.toString();
|
||||
for (UVTransformation t : transformations) s += "\n" + t.toString();
|
||||
return s.trim();
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
package codechicken.lib.render.uv;
|
||||
|
||||
import codechicken.lib.math.MathHelper;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.MathContext;
|
||||
import java.math.RoundingMode;
|
||||
@@ -34,8 +33,8 @@ public class UVTranslation extends UVTransformation {
|
||||
@Override
|
||||
public UVTransformation merge(UVTransformation next) {
|
||||
if (next instanceof UVTranslation) {
|
||||
UVTranslation t = (UVTranslation)next;
|
||||
return new UVTranslation(du+t.du, dv+t.dv);
|
||||
UVTranslation t = (UVTranslation) next;
|
||||
return new UVTranslation(du + t.du, dv + t.dv);
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
@@ -11,64 +11,56 @@ import java.nio.ByteBuffer;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
public class LibDownloader
|
||||
{
|
||||
public class LibDownloader {
|
||||
private static String[] libs = new String[] {
|
||||
"org/ow2/asm/asm-debug-all/5.0.3/asm-debug-all-5.0.3.jar",
|
||||
"com/google/guava/guava/14.0/guava-14.0.jar",
|
||||
"net/sf/jopt-simple/jopt-simple/4.5/jopt-simple-4.5.jar",
|
||||
"org/apache/logging/log4j/log4j-core/2.0-beta9/log4j-core-2.0-beta9.jar",
|
||||
"org/apache/logging/log4j/log4j-api/2.0-beta9/log4j-api-2.0-beta9.jar"};
|
||||
"org/ow2/asm/asm-debug-all/5.0.3/asm-debug-all-5.0.3.jar",
|
||||
"com/google/guava/guava/14.0/guava-14.0.jar",
|
||||
"net/sf/jopt-simple/jopt-simple/4.5/jopt-simple-4.5.jar",
|
||||
"org/apache/logging/log4j/log4j-core/2.0-beta9/log4j-core-2.0-beta9.jar",
|
||||
"org/apache/logging/log4j/log4j-api/2.0-beta9/log4j-api-2.0-beta9.jar"
|
||||
};
|
||||
private static File libDir = new File("lib");
|
||||
|
||||
private static ByteBuffer downloadBuffer = ByteBuffer.allocateDirect(1 << 23);
|
||||
|
||||
public static void load() {
|
||||
if(!libDir.exists())
|
||||
libDir.mkdir();
|
||||
if(!libDir.isDirectory())
|
||||
throw new RuntimeException("/lib is not a directory");
|
||||
if (!libDir.exists()) libDir.mkdir();
|
||||
if (!libDir.isDirectory()) throw new RuntimeException("/lib is not a directory");
|
||||
|
||||
List<String> missing = checkExists();
|
||||
for(String lib : missing)
|
||||
download(lib);
|
||||
for (String lib : missing) download(lib);
|
||||
addPaths(libs);
|
||||
}
|
||||
|
||||
private static void addPaths(String[] libs) {
|
||||
try {
|
||||
URLClassLoader cl = (URLClassLoader) ClassLoader.getSystemClassLoader();
|
||||
Method m_addURL = URLClassLoader.class.getDeclaredMethod("addURL", new Class[]{URL.class});
|
||||
Method m_addURL = URLClassLoader.class.getDeclaredMethod("addURL", new Class[] {URL.class});
|
||||
m_addURL.setAccessible(true);
|
||||
for(String lib : libs)
|
||||
for (String lib : libs)
|
||||
m_addURL.invoke(cl, new File(libDir, fileName(lib)).toURI().toURL());
|
||||
}
|
||||
catch (Exception e) {
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Failed to add libraries to classpath", e);
|
||||
}
|
||||
}
|
||||
|
||||
private static void download(String lib) {
|
||||
File libFile = new File(libDir, fileName(lib));
|
||||
try
|
||||
{
|
||||
URL libDownload = new URL("http://repo1.maven.org/maven2/"+lib);
|
||||
try {
|
||||
URL libDownload = new URL("http://repo1.maven.org/maven2/" + lib);
|
||||
URLConnection connection = libDownload.openConnection();
|
||||
connection.setConnectTimeout(5000);
|
||||
connection.setReadTimeout(5000);
|
||||
connection.setRequestProperty("User-Agent", "CodeChickenLib Downloader");
|
||||
int sizeGuess = connection.getContentLength();
|
||||
download(connection.getInputStream(), sizeGuess, libFile);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
} catch (Exception e) {
|
||||
libFile.delete();
|
||||
throw new RuntimeException("A download error occured", e);
|
||||
}
|
||||
}
|
||||
|
||||
private static void download(InputStream is, int sizeGuess, File target) throws Exception
|
||||
{
|
||||
private static void download(InputStream is, int sizeGuess, File target) throws Exception {
|
||||
String name = target.getName();
|
||||
if (sizeGuess > downloadBuffer.capacity())
|
||||
throw new Exception(String.format("The file %s is too large to be downloaded", name));
|
||||
@@ -88,8 +80,7 @@ public class LibDownloader
|
||||
is.close();
|
||||
downloadBuffer.limit(fullLength);
|
||||
|
||||
if(!target.exists())
|
||||
target.createNewFile();
|
||||
if (!target.exists()) target.createNewFile();
|
||||
|
||||
downloadBuffer.position(0);
|
||||
FileOutputStream fos = new FileOutputStream(target);
|
||||
@@ -103,12 +94,10 @@ public class LibDownloader
|
||||
|
||||
private static List<String> checkExists() {
|
||||
LinkedList<String> list = new LinkedList<String>();
|
||||
for(String lib : libs) {
|
||||
for (String lib : libs) {
|
||||
File file = new File(libDir, fileName(lib));
|
||||
if(!file.exists())
|
||||
list.add(lib);
|
||||
if (!file.exists()) list.add(lib);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package codechicken.lib.tool;
|
||||
|
||||
import codechicken.lib.asm.ASMHelper;
|
||||
import java.util.Iterator;
|
||||
import org.objectweb.asm.ClassReader;
|
||||
import org.objectweb.asm.MethodVisitor;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
@@ -9,16 +10,13 @@ import org.objectweb.asm.commons.RemappingMethodAdapter;
|
||||
import org.objectweb.asm.tree.ClassNode;
|
||||
import org.objectweb.asm.tree.MethodNode;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
public class MCStripTransformer {
|
||||
public static class ReferenceDetector extends Remapper {
|
||||
boolean found = false;
|
||||
|
||||
@Override
|
||||
public String map(String typeName) {
|
||||
if(typeName.startsWith("net/minecraft") || !typeName.contains("/"))
|
||||
found = true;
|
||||
if (typeName.startsWith("net/minecraft") || !typeName.contains("/")) found = true;
|
||||
return typeName;
|
||||
}
|
||||
}
|
||||
@@ -28,17 +26,16 @@ public class MCStripTransformer {
|
||||
|
||||
boolean changed = false;
|
||||
Iterator<MethodNode> it = cnode.methods.iterator();
|
||||
while(it.hasNext()) {
|
||||
while (it.hasNext()) {
|
||||
MethodNode mnode = it.next();
|
||||
ReferenceDetector r = new ReferenceDetector();
|
||||
mnode.accept(new RemappingMethodAdapter(mnode.access, mnode.desc, new MethodVisitor(Opcodes.ASM4) {}, r));
|
||||
if(r.found) {
|
||||
if (r.found) {
|
||||
it.remove();
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
if(changed)
|
||||
bytes = ASMHelper.createBytes(cnode, 0);
|
||||
if (changed) bytes = ASMHelper.createBytes(cnode, 0);
|
||||
return bytes;
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,11 @@
|
||||
package codechicken.lib.tool;
|
||||
|
||||
public class Main
|
||||
{
|
||||
public class Main {
|
||||
public static void main(String[] args) {
|
||||
LibDownloader.load();
|
||||
try {
|
||||
Class<?> c_toolMain = new StripClassLoader().loadClass("codechicken.lib.tool.ToolMain");
|
||||
c_toolMain.getDeclaredMethod("main", String[].class).invoke(null, new Object[]{args});
|
||||
c_toolMain.getDeclaredMethod("main", String[].class).invoke(null, new Object[] {args});
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
@@ -6,27 +6,24 @@ import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
|
||||
public class StripClassLoader extends URLClassLoader
|
||||
{
|
||||
public class StripClassLoader extends URLClassLoader {
|
||||
public StripClassLoader() {
|
||||
super(new URL[0], StripClassLoader.class.getClassLoader());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> loadClass(String name) throws ClassNotFoundException {
|
||||
if(!name.startsWith("codechicken.lib"))
|
||||
return super.loadClass(name);
|
||||
if (!name.startsWith("codechicken.lib")) return super.loadClass(name);
|
||||
|
||||
try {
|
||||
String resName = name.replace('.', '/')+".class";
|
||||
String resName = name.replace('.', '/') + ".class";
|
||||
InputStream res = getResourceAsStream(resName);
|
||||
if(res == null)
|
||||
throw new ClassNotFoundException("Could not find resource: "+resName);
|
||||
if (res == null) throw new ClassNotFoundException("Could not find resource: " + resName);
|
||||
byte[] bytes = readFully(res);
|
||||
bytes = transform(bytes);
|
||||
return defineClass(name, bytes, 0, bytes.length);
|
||||
|
||||
} catch(IOException e) {
|
||||
} catch (IOException e) {
|
||||
throw new ClassNotFoundException(name, e);
|
||||
}
|
||||
}
|
||||
@@ -36,8 +33,7 @@ public class StripClassLoader extends URLClassLoader
|
||||
|
||||
int read;
|
||||
byte[] data = new byte[16384];
|
||||
while ((read = is.read(data, 0, data.length)) > 0)
|
||||
buffer.write(data, 0, read);
|
||||
while ((read = is.read(data, 0, data.length)) > 0) buffer.write(data, 0, read);
|
||||
|
||||
return buffer.toByteArray();
|
||||
}
|
||||
|
||||
@@ -2,38 +2,36 @@ package codechicken.lib.tool;
|
||||
|
||||
import codechicken.lib.tool.module.ModuleQBConverter;
|
||||
|
||||
public class ToolMain
|
||||
{
|
||||
public class ToolMain {
|
||||
public static interface Module {
|
||||
public void main(String[] args);
|
||||
|
||||
public String name();
|
||||
|
||||
public void printHelp();
|
||||
}
|
||||
|
||||
public static Module[] modules = new Module[]{
|
||||
new ModuleQBConverter()
|
||||
};
|
||||
public static Module[] modules = new Module[] {new ModuleQBConverter()};
|
||||
|
||||
private static void printHelp() {
|
||||
System.out.println("Usage: [module] [args]");
|
||||
System.out.println(" Modules: ");
|
||||
for(Module m : modules)
|
||||
System.out.println(" - "+m.name());
|
||||
for (Module m : modules) System.out.println(" - " + m.name());
|
||||
System.out.println("-h [module] for module help");
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
if(args.length > 0) {
|
||||
for(Module m : modules)
|
||||
if(args[0].equals(m.name())) {
|
||||
String[] args2 = new String[args.length-1];
|
||||
if (args.length > 0) {
|
||||
for (Module m : modules)
|
||||
if (args[0].equals(m.name())) {
|
||||
String[] args2 = new String[args.length - 1];
|
||||
System.arraycopy(args, 1, args2, 0, args2.length);
|
||||
m.main(args2);
|
||||
return;
|
||||
}
|
||||
if(args[0].equals("-h") && args.length >= 2) {
|
||||
for(Module m : modules)
|
||||
if(args[1].equals(m.name())) {
|
||||
if (args[0].equals("-h") && args.length >= 2) {
|
||||
for (Module m : modules)
|
||||
if (args[1].equals(m.name())) {
|
||||
m.printHelp();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1,36 +1,28 @@
|
||||
package codechicken.lib.tool.module;
|
||||
|
||||
import codechicken.lib.tool.ToolMain;
|
||||
import java.io.IOException;
|
||||
import joptsimple.OptionException;
|
||||
import joptsimple.OptionParser;
|
||||
import joptsimple.OptionSet;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public abstract class JOptModule implements ToolMain.Module
|
||||
{
|
||||
public abstract class JOptModule implements ToolMain.Module {
|
||||
OptionParser parser = new OptionParser();
|
||||
|
||||
@Override
|
||||
public void main(String[] args) {
|
||||
OptionSet options;
|
||||
try
|
||||
{
|
||||
try {
|
||||
options = parser.parse(args);
|
||||
}
|
||||
catch(OptionException ex)
|
||||
{
|
||||
} catch (OptionException ex) {
|
||||
System.err.println(ex.getLocalizedMessage());
|
||||
System.exit(-1);
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
try {
|
||||
main(parser, options);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,22 +1,26 @@
|
||||
package codechicken.lib.tool.module;
|
||||
|
||||
import codechicken.lib.render.QBImporter;
|
||||
import joptsimple.OptionParser;
|
||||
import joptsimple.OptionSet;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
|
||||
public class ModuleQBConverter extends JOptModule
|
||||
{
|
||||
import codechicken.lib.render.QBImporter;
|
||||
import java.io.File;
|
||||
import joptsimple.OptionParser;
|
||||
import joptsimple.OptionSet;
|
||||
|
||||
public class ModuleQBConverter extends JOptModule {
|
||||
public ModuleQBConverter() {
|
||||
parser.acceptsAll(asList("?", "h", "help"), "Show the help");
|
||||
parser.acceptsAll(asList("i", "input"), "comma separated list of paths to models (.qb or directories)")
|
||||
.withRequiredArg().ofType(File.class).withValuesSeparatedBy(',').required();
|
||||
.withRequiredArg()
|
||||
.ofType(File.class)
|
||||
.withValuesSeparatedBy(',')
|
||||
.required();
|
||||
parser.acceptsAll(asList("o", "out"), "Output Directory")
|
||||
.withRequiredArg().ofType(File.class);
|
||||
parser.acceptsAll(asList("o2", "textureplanes"), "2nd level optimisation. Merges coplanar polygons. Increases texture size");
|
||||
.withRequiredArg()
|
||||
.ofType(File.class);
|
||||
parser.acceptsAll(
|
||||
asList("o2", "textureplanes"),
|
||||
"2nd level optimisation. Merges coplanar polygons. Increases texture size");
|
||||
parser.acceptsAll(asList("s", "squaretextures"), "Produce square textures");
|
||||
parser.acceptsAll(asList("t", "mergetextures"), "Use the same texture for all models");
|
||||
parser.acceptsAll(asList("r", "scalemc"), "Resize model to mc standard (shrink by factor of 16)");
|
||||
@@ -24,41 +28,35 @@ public class ModuleQBConverter extends JOptModule
|
||||
|
||||
protected void main(OptionParser parser, OptionSet options) {
|
||||
int flags = 0;
|
||||
if(options.has("o2")) flags |= QBImporter.TEXTUREPLANES;
|
||||
if(options.has("s")) flags |= QBImporter.SQUARETEXTURE;
|
||||
if(options.has("t")) flags |= QBImporter.MERGETEXTURES;
|
||||
if(options.has("r")) flags |= QBImporter.SCALEMC;
|
||||
if (options.has("o2")) flags |= QBImporter.TEXTUREPLANES;
|
||||
if (options.has("s")) flags |= QBImporter.SQUARETEXTURE;
|
||||
if (options.has("t")) flags |= QBImporter.MERGETEXTURES;
|
||||
if (options.has("r")) flags |= QBImporter.SCALEMC;
|
||||
|
||||
File[] input = options.valuesOf("input").toArray(new File[0]);
|
||||
File[] outDir = new File[input.length];
|
||||
if(options.has("out")) {
|
||||
File output = (File)options.valueOf("out");
|
||||
if(output.isFile())
|
||||
throw new RuntimeException("Output Path is not a directory");
|
||||
if(!output.exists())
|
||||
output.mkdirs();
|
||||
if (options.has("out")) {
|
||||
File output = (File) options.valueOf("out");
|
||||
if (output.isFile()) throw new RuntimeException("Output Path is not a directory");
|
||||
if (!output.exists()) output.mkdirs();
|
||||
|
||||
for(int i = 0; i < input.length; i++)
|
||||
outDir[i] = output;
|
||||
for (int i = 0; i < input.length; i++) outDir[i] = output;
|
||||
} else {
|
||||
for(int i = 0; i < input.length; i++)
|
||||
for (int i = 0; i < input.length; i++)
|
||||
outDir[i] = input[i].isDirectory() ? input[i] : input[i].getParentFile();
|
||||
}
|
||||
|
||||
for(int i = 0; i < input.length; i++) {
|
||||
for (int i = 0; i < input.length; i++) {
|
||||
File file = input[i];
|
||||
if(file.isDirectory()) {
|
||||
for(File file2 : file.listFiles())
|
||||
if(file2.getName().endsWith(".qb"))
|
||||
convert(file2, outDir[i], flags);
|
||||
}
|
||||
else
|
||||
convert(file, outDir[i], flags);
|
||||
if (file.isDirectory()) {
|
||||
for (File file2 : file.listFiles())
|
||||
if (file2.getName().endsWith(".qb")) convert(file2, outDir[i], flags);
|
||||
} else convert(file, outDir[i], flags);
|
||||
}
|
||||
}
|
||||
|
||||
private void convert(File in, File outDir, int flags) {
|
||||
System.out.println("Converting: "+in.getName());
|
||||
System.out.println("Converting: " + in.getName());
|
||||
QBImporter.RasterisedModel m = QBImporter.loadQB(in).toRasterisedModel(flags);
|
||||
m.export(new File(outDir, in.getName().replace(".qb", ".obj")), outDir);
|
||||
}
|
||||
|
||||
@@ -2,19 +2,18 @@ package codechicken.lib.util;
|
||||
|
||||
import net.minecraft.util.StatCollector;
|
||||
|
||||
public class LangProxy
|
||||
{
|
||||
public class LangProxy {
|
||||
public final String namespace;
|
||||
|
||||
public LangProxy(String namespace) {
|
||||
this.namespace = namespace+".";
|
||||
this.namespace = namespace + ".";
|
||||
}
|
||||
|
||||
public String translate(String key) {
|
||||
return StatCollector.translateToLocal(namespace+key);
|
||||
return StatCollector.translateToLocal(namespace + key);
|
||||
}
|
||||
|
||||
public String format(String key, Object... params) {
|
||||
return StatCollector.translateToLocalFormatted(namespace+key, params);
|
||||
return StatCollector.translateToLocalFormatted(namespace + key, params);
|
||||
}
|
||||
}
|
||||
@@ -1,21 +1,39 @@
|
||||
package codechicken.lib.vec;
|
||||
|
||||
public class AxisCycle
|
||||
{
|
||||
public static Transformation[] cycles = new Transformation[]{
|
||||
public class AxisCycle {
|
||||
public static Transformation[] cycles = new Transformation[] {
|
||||
new RedundantTransformation(),
|
||||
new VariableTransformation(new Matrix4(0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1)){
|
||||
@Override public void apply(Vector3 vec){
|
||||
double d0 = vec.x; double d1 = vec.y; double d2 = vec.z;
|
||||
vec.x = d2; vec.y = d0; vec.z = d1;
|
||||
} @Override public Transformation inverse(){
|
||||
new VariableTransformation(new Matrix4(0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1)) {
|
||||
@Override
|
||||
public void apply(Vector3 vec) {
|
||||
double d0 = vec.x;
|
||||
double d1 = vec.y;
|
||||
double d2 = vec.z;
|
||||
vec.x = d2;
|
||||
vec.y = d0;
|
||||
vec.z = d1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Transformation inverse() {
|
||||
return cycles[2];
|
||||
}},
|
||||
new VariableTransformation(new Matrix4(0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1)){
|
||||
@Override public void apply(Vector3 vec){
|
||||
double d0 = vec.x; double d1 = vec.y; double d2 = vec.z;
|
||||
vec.x = d1; vec.y = d2; vec.z = d0;
|
||||
} @Override public Transformation inverse(){
|
||||
}
|
||||
},
|
||||
new VariableTransformation(new Matrix4(0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1)) {
|
||||
@Override
|
||||
public void apply(Vector3 vec) {
|
||||
double d0 = vec.x;
|
||||
double d1 = vec.y;
|
||||
double d2 = vec.z;
|
||||
vec.x = d1;
|
||||
vec.y = d2;
|
||||
vec.z = d0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Transformation inverse() {
|
||||
return cycles[1];
|
||||
}}};
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -4,157 +4,131 @@ import codechicken.lib.math.MathHelper;
|
||||
import codechicken.lib.util.Copyable;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
|
||||
public class BlockCoord implements Comparable<BlockCoord>, Copyable<BlockCoord>
|
||||
{
|
||||
public class BlockCoord implements Comparable<BlockCoord>, Copyable<BlockCoord> {
|
||||
public int x;
|
||||
public int y;
|
||||
public int z;
|
||||
|
||||
public BlockCoord(int x, int y, int z)
|
||||
{
|
||||
public BlockCoord(int x, int y, int z) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
}
|
||||
|
||||
public BlockCoord(Vector3 v)
|
||||
{
|
||||
public BlockCoord(Vector3 v) {
|
||||
this(MathHelper.floor_double(v.x), MathHelper.floor_double(v.y), MathHelper.floor_double(v.z));
|
||||
}
|
||||
|
||||
public BlockCoord(TileEntity tile)
|
||||
{
|
||||
public BlockCoord(TileEntity tile) {
|
||||
this(tile.xCoord, tile.yCoord, tile.zCoord);
|
||||
}
|
||||
|
||||
public BlockCoord(int[] ia)
|
||||
{
|
||||
public BlockCoord(int[] ia) {
|
||||
this(ia[0], ia[1], ia[2]);
|
||||
}
|
||||
|
||||
public BlockCoord()
|
||||
{
|
||||
}
|
||||
public BlockCoord() {}
|
||||
|
||||
public static BlockCoord fromAxes(int[] ia)
|
||||
{
|
||||
public static BlockCoord fromAxes(int[] ia) {
|
||||
return new BlockCoord(ia[2], ia[0], ia[1]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj)
|
||||
{
|
||||
if(!(obj instanceof BlockCoord))
|
||||
return false;
|
||||
BlockCoord o2 = (BlockCoord)obj;
|
||||
public boolean equals(Object obj) {
|
||||
if (!(obj instanceof BlockCoord)) return false;
|
||||
BlockCoord o2 = (BlockCoord) obj;
|
||||
return x == o2.x && y == o2.y && z == o2.z;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
return (x^z)*31 + y;
|
||||
public int hashCode() {
|
||||
return (x ^ z) * 31 + y;
|
||||
}
|
||||
|
||||
public int compareTo(BlockCoord o)
|
||||
{
|
||||
if(x != o.x)return x < o.x ? 1 : -1;
|
||||
if(y != o.y)return y < o.y ? 1 : -1;
|
||||
if(z != o.z)return z < o.z ? 1 : -1;
|
||||
public int compareTo(BlockCoord o) {
|
||||
if (x != o.x) return x < o.x ? 1 : -1;
|
||||
if (y != o.y) return y < o.y ? 1 : -1;
|
||||
if (z != o.z) return z < o.z ? 1 : -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
public Vector3 toVector3Centered()
|
||||
{
|
||||
return new Vector3(x+0.5, y+0.5, z+0.5);
|
||||
public Vector3 toVector3Centered() {
|
||||
return new Vector3(x + 0.5, y + 0.5, z + 0.5);
|
||||
}
|
||||
|
||||
public BlockCoord multiply(int i)
|
||||
{
|
||||
x*=i;
|
||||
y*=i;
|
||||
z*=i;
|
||||
public BlockCoord multiply(int i) {
|
||||
x *= i;
|
||||
y *= i;
|
||||
z *= i;
|
||||
return this;
|
||||
}
|
||||
|
||||
public double mag()
|
||||
{
|
||||
return Math.sqrt(x*x+y*y+z*z);
|
||||
public double mag() {
|
||||
return Math.sqrt(x * x + y * y + z * z);
|
||||
}
|
||||
|
||||
public int mag2()
|
||||
{
|
||||
return x*x+y*y+z*z;
|
||||
public int mag2() {
|
||||
return x * x + y * y + z * z;
|
||||
}
|
||||
|
||||
public boolean isZero()
|
||||
{
|
||||
public boolean isZero() {
|
||||
return x == 0 && y == 0 && z == 0;
|
||||
}
|
||||
|
||||
public boolean isAxial()
|
||||
{
|
||||
public boolean isAxial() {
|
||||
return x == 0 ? (y == 0 || z == 0) : (y == 0 && z == 0);
|
||||
}
|
||||
|
||||
public BlockCoord add(BlockCoord coord2)
|
||||
{
|
||||
x+=coord2.x;
|
||||
y+=coord2.y;
|
||||
z+=coord2.z;
|
||||
public BlockCoord add(BlockCoord coord2) {
|
||||
x += coord2.x;
|
||||
y += coord2.y;
|
||||
z += coord2.z;
|
||||
return this;
|
||||
}
|
||||
|
||||
public BlockCoord add(int i, int j, int k)
|
||||
{
|
||||
x+=i;
|
||||
y+=j;
|
||||
z+=k;
|
||||
public BlockCoord add(int i, int j, int k) {
|
||||
x += i;
|
||||
y += j;
|
||||
z += k;
|
||||
return this;
|
||||
}
|
||||
|
||||
public BlockCoord sub(BlockCoord coord2)
|
||||
{
|
||||
x-=coord2.x;
|
||||
y-=coord2.y;
|
||||
z-=coord2.z;
|
||||
public BlockCoord sub(BlockCoord coord2) {
|
||||
x -= coord2.x;
|
||||
y -= coord2.y;
|
||||
z -= coord2.z;
|
||||
return this;
|
||||
}
|
||||
|
||||
public BlockCoord sub(int i, int j, int k)
|
||||
{
|
||||
x-=i;
|
||||
y-=j;
|
||||
z-=k;
|
||||
public BlockCoord sub(int i, int j, int k) {
|
||||
x -= i;
|
||||
y -= j;
|
||||
z -= k;
|
||||
return this;
|
||||
}
|
||||
|
||||
public BlockCoord offset(int side)
|
||||
{
|
||||
public BlockCoord offset(int side) {
|
||||
return offset(side, 1);
|
||||
}
|
||||
|
||||
public BlockCoord offset(int side, int amount)
|
||||
{
|
||||
public BlockCoord offset(int side, int amount) {
|
||||
BlockCoord offset = sideOffsets[side];
|
||||
x+=offset.x*amount;
|
||||
y+=offset.y*amount;
|
||||
z+=offset.z*amount;
|
||||
x += offset.x * amount;
|
||||
y += offset.y * amount;
|
||||
z += offset.z * amount;
|
||||
return this;
|
||||
}
|
||||
|
||||
public BlockCoord inset(int side)
|
||||
{
|
||||
public BlockCoord inset(int side) {
|
||||
return inset(side, 1);
|
||||
}
|
||||
|
||||
public BlockCoord inset(int side, int amount)
|
||||
{
|
||||
public BlockCoord inset(int side, int amount) {
|
||||
return offset(side, -amount);
|
||||
}
|
||||
|
||||
public int getSide(int side) {
|
||||
switch(side) {
|
||||
switch (side) {
|
||||
case 0:
|
||||
case 1:
|
||||
return y;
|
||||
@@ -168,54 +142,55 @@ public class BlockCoord implements Comparable<BlockCoord>, Copyable<BlockCoord>
|
||||
throw new IndexOutOfBoundsException("Switch Falloff");
|
||||
}
|
||||
|
||||
public BlockCoord setSide(int s, int v)
|
||||
{
|
||||
switch(s)
|
||||
{
|
||||
public BlockCoord setSide(int s, int v) {
|
||||
switch (s) {
|
||||
case 0:
|
||||
case 1: y = v; break;
|
||||
case 1:
|
||||
y = v;
|
||||
break;
|
||||
case 2:
|
||||
case 3: z = v; break;
|
||||
case 3:
|
||||
z = v;
|
||||
break;
|
||||
case 4:
|
||||
case 5: x = v; break;
|
||||
default: throw new IndexOutOfBoundsException("Switch Falloff");
|
||||
case 5:
|
||||
x = v;
|
||||
break;
|
||||
default:
|
||||
throw new IndexOutOfBoundsException("Switch Falloff");
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public static final BlockCoord[] sideOffsets = new BlockCoord[]{
|
||||
new BlockCoord( 0,-1, 0),
|
||||
new BlockCoord( 0, 1, 0),
|
||||
new BlockCoord( 0, 0,-1),
|
||||
new BlockCoord( 0, 0, 1),
|
||||
public static final BlockCoord[] sideOffsets = new BlockCoord[] {
|
||||
new BlockCoord(0, -1, 0),
|
||||
new BlockCoord(0, 1, 0),
|
||||
new BlockCoord(0, 0, -1),
|
||||
new BlockCoord(0, 0, 1),
|
||||
new BlockCoord(-1, 0, 0),
|
||||
new BlockCoord( 1, 0, 0)};
|
||||
new BlockCoord(1, 0, 0)
|
||||
};
|
||||
|
||||
public int[] intArray()
|
||||
{
|
||||
return new int[]{x, y, z};
|
||||
public int[] intArray() {
|
||||
return new int[] {x, y, z};
|
||||
}
|
||||
|
||||
public BlockCoord copy()
|
||||
{
|
||||
public BlockCoord copy() {
|
||||
return new BlockCoord(x, y, z);
|
||||
}
|
||||
|
||||
public BlockCoord set(int i, int j, int k)
|
||||
{
|
||||
public BlockCoord set(int i, int j, int k) {
|
||||
x = i;
|
||||
y = j;
|
||||
z = k;
|
||||
return this;
|
||||
}
|
||||
|
||||
public BlockCoord set(BlockCoord coord)
|
||||
{
|
||||
public BlockCoord set(BlockCoord coord) {
|
||||
return set(coord.x, coord.y, coord.z);
|
||||
}
|
||||
|
||||
public BlockCoord set(int[] ia)
|
||||
{
|
||||
public BlockCoord set(int[] ia) {
|
||||
return set(ia[0], ia[1], ia[2]);
|
||||
}
|
||||
|
||||
@@ -223,28 +198,23 @@ public class BlockCoord implements Comparable<BlockCoord>, Copyable<BlockCoord>
|
||||
return set(tile.xCoord, tile.yCoord, tile.zCoord);
|
||||
}
|
||||
|
||||
public int toSide()
|
||||
{
|
||||
if(!isAxial()) return -1;
|
||||
if(y < 0) return 0;
|
||||
if(y > 0) return 1;
|
||||
if(z < 0) return 2;
|
||||
if(z > 0) return 3;
|
||||
if(x < 0) return 4;
|
||||
if(x > 0) return 5;
|
||||
public int toSide() {
|
||||
if (!isAxial()) return -1;
|
||||
if (y < 0) return 0;
|
||||
if (y > 0) return 1;
|
||||
if (z < 0) return 2;
|
||||
if (z > 0) return 3;
|
||||
if (x < 0) return 4;
|
||||
if (x > 0) return 5;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
public int absSum()
|
||||
{
|
||||
return (x < 0 ? -x : x) +
|
||||
(y < 0 ? -y : y) +
|
||||
(z < 0 ? -z : z);
|
||||
public int absSum() {
|
||||
return (x < 0 ? -x : x) + (y < 0 ? -y : y) + (z < 0 ? -z : z);
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return "("+x+", "+y+", "+z+")";
|
||||
public String toString() {
|
||||
return "(" + x + ", " + y + ", " + z + ")";
|
||||
}
|
||||
}
|
||||
@@ -1,51 +1,43 @@
|
||||
package codechicken.lib.vec;
|
||||
|
||||
import codechicken.lib.util.Copyable;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.util.AxisAlignedBB;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.MathContext;
|
||||
import java.math.RoundingMode;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.util.AxisAlignedBB;
|
||||
|
||||
public class Cuboid6 implements Copyable<Cuboid6>
|
||||
{
|
||||
public class Cuboid6 implements Copyable<Cuboid6> {
|
||||
public static Cuboid6 full = new Cuboid6(0, 0, 0, 1, 1, 1);
|
||||
|
||||
|
||||
public Vector3 min;
|
||||
public Vector3 max;
|
||||
|
||||
public Cuboid6(Vector3 min, Vector3 max)
|
||||
{
|
||||
|
||||
public Cuboid6(Vector3 min, Vector3 max) {
|
||||
this.min = min;
|
||||
this.max = max;
|
||||
}
|
||||
|
||||
public Cuboid6(AxisAlignedBB aabb)
|
||||
{
|
||||
public Cuboid6(AxisAlignedBB aabb) {
|
||||
min = new Vector3(aabb.minX, aabb.minY, aabb.minZ);
|
||||
max = new Vector3(aabb.maxX, aabb.maxY, aabb.maxZ);
|
||||
max = new Vector3(aabb.maxX, aabb.maxY, aabb.maxZ);
|
||||
}
|
||||
|
||||
public Cuboid6(Cuboid6 cuboid)
|
||||
{
|
||||
|
||||
public Cuboid6(Cuboid6 cuboid) {
|
||||
min = cuboid.min.copy();
|
||||
max = cuboid.max.copy();
|
||||
}
|
||||
|
||||
public Cuboid6(double minx, double miny, double minz, double maxx, double maxy, double maxz)
|
||||
{
|
||||
public Cuboid6(double minx, double miny, double minz, double maxx, double maxy, double maxz) {
|
||||
min = new Vector3(minx, miny, minz);
|
||||
max = new Vector3(maxx, maxy, maxz);
|
||||
}
|
||||
|
||||
public AxisAlignedBB toAABB()
|
||||
{
|
||||
public AxisAlignedBB toAABB() {
|
||||
return AxisAlignedBB.getBoundingBox(min.x, min.y, min.z, max.x, max.y, max.z);
|
||||
}
|
||||
|
||||
public Cuboid6 copy()
|
||||
{
|
||||
|
||||
public Cuboid6 copy() {
|
||||
return new Cuboid6(this);
|
||||
}
|
||||
|
||||
@@ -65,127 +57,144 @@ public class Cuboid6 implements Copyable<Cuboid6>
|
||||
return this;
|
||||
}
|
||||
|
||||
public Cuboid6 add(Vector3 vec)
|
||||
{
|
||||
public Cuboid6 add(Vector3 vec) {
|
||||
min.add(vec);
|
||||
max.add(vec);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Cuboid6 sub(Vector3 vec)
|
||||
{
|
||||
|
||||
public Cuboid6 sub(Vector3 vec) {
|
||||
min.subtract(vec);
|
||||
max.subtract(vec);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Cuboid6 expand(double d)
|
||||
{
|
||||
|
||||
public Cuboid6 expand(double d) {
|
||||
return expand(new Vector3(d, d, d));
|
||||
}
|
||||
|
||||
public Cuboid6 expand(Vector3 vec)
|
||||
{
|
||||
|
||||
public Cuboid6 expand(Vector3 vec) {
|
||||
min.sub(vec);
|
||||
max.add(vec);
|
||||
return this;
|
||||
}
|
||||
|
||||
public void setBlockBounds(Block block)
|
||||
{
|
||||
block.setBlockBounds((float)min.x, (float)min.y, (float)min.z, (float)max.x, (float)max.y, (float)max.z);
|
||||
public void setBlockBounds(Block block) {
|
||||
block.setBlockBounds((float) min.x, (float) min.y, (float) min.z, (float) max.x, (float) max.y, (float) max.z);
|
||||
}
|
||||
|
||||
public boolean intersects(Cuboid6 b)
|
||||
{
|
||||
return max.x-1E-5 > b.min.x &&
|
||||
b.max.x-1E-5 > min.x &&
|
||||
max.y-1E-5 > b.min.y &&
|
||||
b.max.y-1E-5 > min.y &&
|
||||
max.z-1E-5 > b.min.z &&
|
||||
b.max.z-1E-5 > min.z;
|
||||
public boolean intersects(Cuboid6 b) {
|
||||
return max.x - 1E-5 > b.min.x
|
||||
&& b.max.x - 1E-5 > min.x
|
||||
&& max.y - 1E-5 > b.min.y
|
||||
&& b.max.y - 1E-5 > min.y
|
||||
&& max.z - 1E-5 > b.min.z
|
||||
&& b.max.z - 1E-5 > min.z;
|
||||
}
|
||||
|
||||
public Cuboid6 offset(Cuboid6 o)
|
||||
{
|
||||
|
||||
public Cuboid6 offset(Cuboid6 o) {
|
||||
min.add(o.min);
|
||||
max.add(o.max);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Vector3 center()
|
||||
{
|
||||
|
||||
public Vector3 center() {
|
||||
return min.copy().add(max).multiply(0.5);
|
||||
}
|
||||
|
||||
public static boolean intersects(Cuboid6 a, Cuboid6 b)
|
||||
{
|
||||
|
||||
public static boolean intersects(Cuboid6 a, Cuboid6 b) {
|
||||
return a != null && b != null && a.intersects(b);
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
|
||||
public String toString() {
|
||||
MathContext cont = new MathContext(4, RoundingMode.HALF_UP);
|
||||
return "Cuboid: ("+new BigDecimal(min.x, cont)+", "+new BigDecimal(min.y, cont)+", "+new BigDecimal(min.z, cont)+") -> ("+
|
||||
new BigDecimal(max.x, cont)+", "+new BigDecimal(max.y, cont)+", "+new BigDecimal(max.z, cont)+")";
|
||||
return "Cuboid: (" + new BigDecimal(min.x, cont) + ", " + new BigDecimal(min.y, cont) + ", "
|
||||
+ new BigDecimal(min.z, cont) + ") -> (" + new BigDecimal(max.x, cont) + ", "
|
||||
+ new BigDecimal(max.y, cont) + ", " + new BigDecimal(max.z, cont) + ")";
|
||||
}
|
||||
|
||||
public Cuboid6 enclose(Vector3 vec)
|
||||
{
|
||||
if(min.x > vec.x) min.x = vec.x;
|
||||
if(min.y > vec.y) min.y = vec.y;
|
||||
if(min.z > vec.z) min.z = vec.z;
|
||||
if(max.x < vec.x) max.x = vec.x;
|
||||
if(max.y < vec.y) max.y = vec.y;
|
||||
if(max.z < vec.z) max.z = vec.z;
|
||||
public Cuboid6 enclose(Vector3 vec) {
|
||||
if (min.x > vec.x) min.x = vec.x;
|
||||
if (min.y > vec.y) min.y = vec.y;
|
||||
if (min.z > vec.z) min.z = vec.z;
|
||||
if (max.x < vec.x) max.x = vec.x;
|
||||
if (max.y < vec.y) max.y = vec.y;
|
||||
if (max.z < vec.z) max.z = vec.z;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Cuboid6 enclose(Cuboid6 c)
|
||||
{
|
||||
if(min.x > c.min.x) min.x = c.min.x;
|
||||
if(min.y > c.min.y) min.y = c.min.y;
|
||||
if(min.z > c.min.z) min.z = c.min.z;
|
||||
if(max.x < c.max.x) max.x = c.max.x;
|
||||
if(max.y < c.max.y) max.y = c.max.y;
|
||||
if(max.z < c.max.z) max.z = c.max.z;
|
||||
|
||||
public Cuboid6 enclose(Cuboid6 c) {
|
||||
if (min.x > c.min.x) min.x = c.min.x;
|
||||
if (min.y > c.min.y) min.y = c.min.y;
|
||||
if (min.z > c.min.z) min.z = c.min.z;
|
||||
if (max.x < c.max.x) max.x = c.max.x;
|
||||
if (max.y < c.max.y) max.y = c.max.y;
|
||||
if (max.z < c.max.z) max.z = c.max.z;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Cuboid6 apply(Transformation t)
|
||||
{
|
||||
|
||||
public Cuboid6 apply(Transformation t) {
|
||||
t.apply(min);
|
||||
t.apply(max);
|
||||
double temp;
|
||||
if(min.x > max.x) {temp = min.x; min.x = max.x; max.x = temp;}
|
||||
if(min.y > max.y) {temp = min.y; min.y = max.y; max.y = temp;}
|
||||
if(min.z > max.z) {temp = min.z; min.z = max.z; max.z = temp;}
|
||||
if (min.x > max.x) {
|
||||
temp = min.x;
|
||||
min.x = max.x;
|
||||
max.x = temp;
|
||||
}
|
||||
if (min.y > max.y) {
|
||||
temp = min.y;
|
||||
min.y = max.y;
|
||||
max.y = temp;
|
||||
}
|
||||
if (min.z > max.z) {
|
||||
temp = min.z;
|
||||
min.z = max.z;
|
||||
max.z = temp;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public double getSide(int s)
|
||||
{
|
||||
switch(s) {
|
||||
case 0: return min.y;
|
||||
case 1: return max.y;
|
||||
case 2: return min.z;
|
||||
case 3: return max.z;
|
||||
case 4: return min.x;
|
||||
case 5: return max.x;
|
||||
|
||||
public double getSide(int s) {
|
||||
switch (s) {
|
||||
case 0:
|
||||
return min.y;
|
||||
case 1:
|
||||
return max.y;
|
||||
case 2:
|
||||
return min.z;
|
||||
case 3:
|
||||
return max.z;
|
||||
case 4:
|
||||
return min.x;
|
||||
case 5:
|
||||
return max.x;
|
||||
}
|
||||
throw new IndexOutOfBoundsException("Switch Falloff");
|
||||
}
|
||||
|
||||
public Cuboid6 setSide(int s, double d)
|
||||
{
|
||||
switch(s) {
|
||||
case 0: min.y = d; break;
|
||||
case 1: max.y = d; break;
|
||||
case 2: min.z = d; break;
|
||||
case 3: max.z = d; break;
|
||||
case 4: min.x = d; break;
|
||||
case 5: max.x = d; break;
|
||||
default: throw new IndexOutOfBoundsException("Switch Falloff");
|
||||
|
||||
public Cuboid6 setSide(int s, double d) {
|
||||
switch (s) {
|
||||
case 0:
|
||||
min.y = d;
|
||||
break;
|
||||
case 1:
|
||||
max.y = d;
|
||||
break;
|
||||
case 2:
|
||||
min.z = d;
|
||||
break;
|
||||
case 3:
|
||||
max.z = d;
|
||||
break;
|
||||
case 4:
|
||||
min.x = d;
|
||||
break;
|
||||
case 5:
|
||||
max.x = d;
|
||||
break;
|
||||
default:
|
||||
throw new IndexOutOfBoundsException("Switch Falloff");
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
package codechicken.lib.vec;
|
||||
|
||||
import codechicken.lib.util.Copyable;
|
||||
import java.util.Iterator;
|
||||
import net.minecraft.util.AxisAlignedBB;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
public class CuboidCoord implements Iterable<BlockCoord>, Copyable<CuboidCoord>
|
||||
{
|
||||
public class CuboidCoord implements Iterable<BlockCoord>, Copyable<CuboidCoord> {
|
||||
public BlockCoord min;
|
||||
public BlockCoord max;
|
||||
|
||||
@@ -43,10 +41,9 @@ public class CuboidCoord implements Iterable<BlockCoord>, Copyable<CuboidCoord>
|
||||
}
|
||||
|
||||
public CuboidCoord expand(int side, int amount) {
|
||||
if (side % 2 == 0)//negative side
|
||||
min = min.offset(side, amount);
|
||||
else
|
||||
max = max.offset(side, amount);
|
||||
if (side % 2 == 0) // negative side
|
||||
min = min.offset(side, amount);
|
||||
else max = max.offset(side, amount);
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -61,58 +58,78 @@ public class CuboidCoord implements Iterable<BlockCoord>, Copyable<CuboidCoord>
|
||||
max.add(x, y, z);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public int size(int s) {
|
||||
switch(s) {
|
||||
switch (s) {
|
||||
case 0:
|
||||
case 1:
|
||||
return max.y - min.y+1;
|
||||
return max.y - min.y + 1;
|
||||
case 2:
|
||||
case 3:
|
||||
return max.z - min.z+1;
|
||||
return max.z - min.z + 1;
|
||||
case 4:
|
||||
case 5:
|
||||
return max.x - min.x+1;
|
||||
return max.x - min.x + 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public int getSide(int s) {
|
||||
switch(s) {
|
||||
case 0: return min.y;
|
||||
case 1: return max.y;
|
||||
case 2: return min.z;
|
||||
case 3: return max.z;
|
||||
case 4: return min.x;
|
||||
case 5: return max.x;
|
||||
switch (s) {
|
||||
case 0:
|
||||
return min.y;
|
||||
case 1:
|
||||
return max.y;
|
||||
case 2:
|
||||
return min.z;
|
||||
case 3:
|
||||
return max.z;
|
||||
case 4:
|
||||
return min.x;
|
||||
case 5:
|
||||
return max.x;
|
||||
}
|
||||
throw new IndexOutOfBoundsException("Switch Falloff");
|
||||
}
|
||||
|
||||
public CuboidCoord setSide(int s, int v) {
|
||||
switch(s) {
|
||||
case 0: min.y = v; break;
|
||||
case 1: max.y = v; break;
|
||||
case 2: min.z = v; break;
|
||||
case 3: max.z = v; break;
|
||||
case 4: min.x = v; break;
|
||||
case 5: max.x = v; break;
|
||||
default: throw new IndexOutOfBoundsException("Switch Falloff");
|
||||
switch (s) {
|
||||
case 0:
|
||||
min.y = v;
|
||||
break;
|
||||
case 1:
|
||||
max.y = v;
|
||||
break;
|
||||
case 2:
|
||||
min.z = v;
|
||||
break;
|
||||
case 3:
|
||||
max.z = v;
|
||||
break;
|
||||
case 4:
|
||||
min.x = v;
|
||||
break;
|
||||
case 5:
|
||||
max.x = v;
|
||||
break;
|
||||
default:
|
||||
throw new IndexOutOfBoundsException("Switch Falloff");
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public int getVolume() {
|
||||
return (max.x-min.x+1)*(max.y-min.y+1)*(max.z-min.z+1);
|
||||
return (max.x - min.x + 1) * (max.y - min.y + 1) * (max.z - min.z + 1);
|
||||
}
|
||||
|
||||
public Vector3 getCenterVec() {
|
||||
return new Vector3(min.x+(max.x-min.x+1)/2D, min.y+(max.y-min.y+1)/2D, min.z+(max.z-min.z+1)/2D);
|
||||
return new Vector3(
|
||||
min.x + (max.x - min.x + 1) / 2D, min.y + (max.y - min.y + 1) / 2D, min.z + (max.z - min.z + 1) / 2D);
|
||||
}
|
||||
|
||||
public BlockCoord getCenter(BlockCoord store) {
|
||||
store.set(min.x+(max.x-min.x)/2, min.y+(max.y-min.y)/2, min.z+(max.z-min.z)/2);
|
||||
store.set(min.x + (max.x - min.x) / 2, min.y + (max.y - min.y) / 2, min.z + (max.z - min.z) / 2);
|
||||
return store;
|
||||
}
|
||||
|
||||
@@ -121,13 +138,11 @@ public class CuboidCoord implements Iterable<BlockCoord>, Copyable<CuboidCoord>
|
||||
}
|
||||
|
||||
public boolean contains(int x, int y, int z) {
|
||||
return x >= min.x && x <= max.x
|
||||
&& y >= min.y && y <= max.y
|
||||
&& z >= min.z && z <= max.z;
|
||||
return x >= min.x && x <= max.x && y >= min.y && y <= max.y && z >= min.z && z <= max.z;
|
||||
}
|
||||
|
||||
public int[] intArray() {
|
||||
return new int[]{min.x, min.y, min.z, max.x, max.y, max.z};
|
||||
return new int[] {min.x, min.y, min.z, max.x, max.y, max.z};
|
||||
}
|
||||
|
||||
public CuboidCoord copy() {
|
||||
@@ -171,12 +186,12 @@ public class CuboidCoord implements Iterable<BlockCoord>, Copyable<CuboidCoord>
|
||||
}
|
||||
|
||||
public CuboidCoord include(int x, int y, int z) {
|
||||
if(x < min.x) min.x = x;
|
||||
else if(x > max.x) max.x = x;
|
||||
if(y < min.y) min.y = y;
|
||||
else if(y > max.y) max.y = y;
|
||||
if(z < min.z) min.z = z;
|
||||
else if(z > max.z) max.z = z;
|
||||
if (x < min.x) min.x = x;
|
||||
else if (x > max.x) max.x = x;
|
||||
if (y < min.y) min.y = y;
|
||||
else if (y > max.y) max.y = y;
|
||||
if (z < min.z) min.z = z;
|
||||
else if (z > max.z) max.z = z;
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -189,15 +204,12 @@ public class CuboidCoord implements Iterable<BlockCoord>, Copyable<CuboidCoord>
|
||||
}
|
||||
|
||||
public BlockCoord next() {
|
||||
if(b == null)
|
||||
b = min.copy();
|
||||
if (b == null) b = min.copy();
|
||||
else {
|
||||
if(b.z != max.z)
|
||||
b.z++;
|
||||
if (b.z != max.z) b.z++;
|
||||
else {
|
||||
b.z = min.z;
|
||||
if(b.y != max.y)
|
||||
b.y++;
|
||||
if (b.y != max.y) b.y++;
|
||||
else {
|
||||
b.y = min.y;
|
||||
b.x++;
|
||||
|
||||
@@ -5,8 +5,7 @@ package codechicken.lib.vec;
|
||||
* @param <Vector> The vector type
|
||||
* @param <Transformation> The transformation type
|
||||
*/
|
||||
public abstract class ITransformation<Vector, Transformation extends ITransformation>
|
||||
{
|
||||
public abstract class ITransformation<Vector, Transformation extends ITransformation> {
|
||||
/**
|
||||
* Applies this transformation to vec
|
||||
*/
|
||||
|
||||
@@ -1,18 +1,15 @@
|
||||
package codechicken.lib.vec;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class IrreversibleTransformationException extends RuntimeException
|
||||
{
|
||||
public class IrreversibleTransformationException extends RuntimeException {
|
||||
public ITransformation t;
|
||||
|
||||
public IrreversibleTransformationException(ITransformation t)
|
||||
{
|
||||
|
||||
public IrreversibleTransformationException(ITransformation t) {
|
||||
this.t = t;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getMessage()
|
||||
{
|
||||
return "The following transformation is irreversible:\n"+t;
|
||||
public String getMessage() {
|
||||
return "The following transformation is irreversible:\n" + t;
|
||||
}
|
||||
}
|
||||
@@ -1,27 +1,22 @@
|
||||
package codechicken.lib.vec;
|
||||
|
||||
|
||||
public class Line3
|
||||
{
|
||||
public class Line3 {
|
||||
public static final double tol = 0.0001D;
|
||||
|
||||
|
||||
public Vector3 pt1;
|
||||
public Vector3 pt2;
|
||||
|
||||
public Line3(Vector3 pt1, Vector3 pt2)
|
||||
{
|
||||
|
||||
public Line3(Vector3 pt1, Vector3 pt2) {
|
||||
this.pt1 = pt1;
|
||||
this.pt2 = pt2;
|
||||
}
|
||||
|
||||
public Line3()
|
||||
{
|
||||
public Line3() {
|
||||
this(new Vector3(), new Vector3());
|
||||
}
|
||||
|
||||
public static boolean intersection2D(Line3 line1, Line3 line2, Vector3 store)
|
||||
{
|
||||
// calculate differences
|
||||
public static boolean intersection2D(Line3 line1, Line3 line2, Vector3 store) {
|
||||
// calculate differences
|
||||
double xD1 = line1.pt2.x - line1.pt1.x;
|
||||
double zD1 = line1.pt2.z - line1.pt1.z;
|
||||
double xD2 = line2.pt2.x - line2.pt1.x;
|
||||
@@ -29,18 +24,21 @@ public class Line3
|
||||
|
||||
double xD3 = line1.pt1.x - line2.pt1.x;
|
||||
double zD3 = line1.pt1.z - line2.pt1.z;
|
||||
|
||||
|
||||
double div = zD2 * xD1 - xD2 * zD1;
|
||||
if(div == 0)//lines are parallel
|
||||
return false;
|
||||
if (div == 0) // lines are parallel
|
||||
return false;
|
||||
double ua = (xD2 * zD3 - zD2 * xD3) / div;
|
||||
store.set(line1.pt1.x + ua * xD1, 0, line1.pt1.z + ua * zD1);
|
||||
|
||||
if(store.x >= Math.min(line1.pt1.x, line1.pt2.x)-tol && store.x >= Math.min(line2.pt1.x, line2.pt2.x)-tol
|
||||
&& store.z >= Math.min(line1.pt1.z, line1.pt2.z)-tol && store.z >= Math.min(line2.pt1.z, line2.pt2.z)-tol
|
||||
&& store.x <= Math.max(line1.pt1.x, line1.pt2.x)+tol && store.x <= Math.max(line2.pt1.x, line2.pt2.x)+tol
|
||||
&& store.z <= Math.max(line1.pt1.z, line1.pt2.z)+tol && store.z <= Math.max(line2.pt1.z, line2.pt2.z)+tol)
|
||||
return true;
|
||||
if (store.x >= Math.min(line1.pt1.x, line1.pt2.x) - tol
|
||||
&& store.x >= Math.min(line2.pt1.x, line2.pt2.x) - tol
|
||||
&& store.z >= Math.min(line1.pt1.z, line1.pt2.z) - tol
|
||||
&& store.z >= Math.min(line2.pt1.z, line2.pt2.z) - tol
|
||||
&& store.x <= Math.max(line1.pt1.x, line1.pt2.x) + tol
|
||||
&& store.x <= Math.max(line2.pt1.x, line2.pt2.x) + tol
|
||||
&& store.z <= Math.max(line1.pt1.z, line1.pt2.z) + tol
|
||||
&& store.z <= Math.max(line2.pt1.z, line2.pt2.z) + tol) return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -3,32 +3,42 @@ package codechicken.lib.vec;
|
||||
import codechicken.lib.util.Copyable;
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.MathContext;
|
||||
import java.math.RoundingMode;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.nio.DoubleBuffer;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
public class Matrix4 extends Transformation implements Copyable<Matrix4>
|
||||
{
|
||||
private static DoubleBuffer glBuf = ByteBuffer.allocateDirect(16*8).order(ByteOrder.nativeOrder()).asDoubleBuffer();
|
||||
|
||||
//m<row><column>
|
||||
public class Matrix4 extends Transformation implements Copyable<Matrix4> {
|
||||
private static DoubleBuffer glBuf =
|
||||
ByteBuffer.allocateDirect(16 * 8).order(ByteOrder.nativeOrder()).asDoubleBuffer();
|
||||
|
||||
// m<row><column>
|
||||
public double m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23, m30, m31, m32, m33;
|
||||
|
||||
public Matrix4()
|
||||
{
|
||||
|
||||
public Matrix4() {
|
||||
m00 = m11 = m22 = m33 = 1;
|
||||
}
|
||||
|
||||
public Matrix4(double d00, double d01, double d02, double d03,
|
||||
double d10, double d11, double d12, double d13,
|
||||
double d20, double d21, double d22, double d23,
|
||||
double d30, double d31, double d32, double d33)
|
||||
{
|
||||
|
||||
public Matrix4(
|
||||
double d00,
|
||||
double d01,
|
||||
double d02,
|
||||
double d03,
|
||||
double d10,
|
||||
double d11,
|
||||
double d12,
|
||||
double d13,
|
||||
double d20,
|
||||
double d21,
|
||||
double d22,
|
||||
double d23,
|
||||
double d30,
|
||||
double d31,
|
||||
double d32,
|
||||
double d33) {
|
||||
m00 = d00;
|
||||
m01 = d01;
|
||||
m02 = d02;
|
||||
@@ -46,32 +56,28 @@ public class Matrix4 extends Transformation implements Copyable<Matrix4>
|
||||
m32 = d32;
|
||||
m33 = d33;
|
||||
}
|
||||
|
||||
public Matrix4(Matrix4 mat)
|
||||
{
|
||||
|
||||
public Matrix4(Matrix4 mat) {
|
||||
set(mat);
|
||||
}
|
||||
|
||||
public Matrix4 setIdentity()
|
||||
{
|
||||
|
||||
public Matrix4 setIdentity() {
|
||||
m00 = m11 = m22 = m33 = 1;
|
||||
m01 = m02 = m03 = m10 = m12 = m13 = m20 = m21 = m23 = m30 = m31 = m32 = 0;
|
||||
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public Matrix4 translate(Vector3 vec)
|
||||
{
|
||||
|
||||
public Matrix4 translate(Vector3 vec) {
|
||||
m03 += m00 * vec.x + m01 * vec.y + m02 * vec.z;
|
||||
m13 += m10 * vec.x + m11 * vec.y + m12 * vec.z;
|
||||
m23 += m20 * vec.x + m21 * vec.y + m22 * vec.z;
|
||||
m33 += m30 * vec.x + m31 * vec.y + m32 * vec.z;
|
||||
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public Matrix4 scale(Vector3 vec)
|
||||
{
|
||||
|
||||
public Matrix4 scale(Vector3 vec) {
|
||||
m00 *= vec.x;
|
||||
m10 *= vec.x;
|
||||
m20 *= vec.x;
|
||||
@@ -84,33 +90,32 @@ public class Matrix4 extends Transformation implements Copyable<Matrix4>
|
||||
m12 *= vec.z;
|
||||
m22 *= vec.z;
|
||||
m32 *= vec.z;
|
||||
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public Matrix4 rotate(double angle, Vector3 axis)
|
||||
{
|
||||
|
||||
public Matrix4 rotate(double angle, Vector3 axis) {
|
||||
double c = Math.cos(angle);
|
||||
double s = Math.sin(angle);
|
||||
double mc = 1.0f - c;
|
||||
double xy = axis.x*axis.y;
|
||||
double yz = axis.y*axis.z;
|
||||
double xz = axis.x*axis.z;
|
||||
double xs = axis.x*s;
|
||||
double ys = axis.y*s;
|
||||
double zs = axis.z*s;
|
||||
double xy = axis.x * axis.y;
|
||||
double yz = axis.y * axis.z;
|
||||
double xz = axis.x * axis.z;
|
||||
double xs = axis.x * s;
|
||||
double ys = axis.y * s;
|
||||
double zs = axis.z * s;
|
||||
|
||||
double f00 = axis.x*axis.x*mc+c;
|
||||
double f10 = xy*mc+zs;
|
||||
double f20 = xz*mc-ys;
|
||||
|
||||
double f01 = xy*mc-zs;
|
||||
double f11 = axis.y*axis.y*mc+c;
|
||||
double f21 = yz*mc+xs;
|
||||
|
||||
double f02 = xz*mc+ys;
|
||||
double f12 = yz*mc-xs;
|
||||
double f22 = axis.z*axis.z*mc+c;
|
||||
double f00 = axis.x * axis.x * mc + c;
|
||||
double f10 = xy * mc + zs;
|
||||
double f20 = xz * mc - ys;
|
||||
|
||||
double f01 = xy * mc - zs;
|
||||
double f11 = axis.y * axis.y * mc + c;
|
||||
double f21 = yz * mc + xs;
|
||||
|
||||
double f02 = xz * mc + ys;
|
||||
double f12 = yz * mc - xs;
|
||||
double f22 = axis.z * axis.z * mc + c;
|
||||
|
||||
double t00 = m00 * f00 + m01 * f10 + m02 * f20;
|
||||
double t10 = m10 * f00 + m11 * f10 + m12 * f20;
|
||||
@@ -132,18 +137,16 @@ public class Matrix4 extends Transformation implements Copyable<Matrix4>
|
||||
m11 = t11;
|
||||
m21 = t21;
|
||||
m31 = t31;
|
||||
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public Matrix4 rotate(Rotation rotation)
|
||||
{
|
||||
|
||||
public Matrix4 rotate(Rotation rotation) {
|
||||
rotation.apply(this);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Matrix4 leftMultiply(Matrix4 mat)
|
||||
{
|
||||
|
||||
public Matrix4 leftMultiply(Matrix4 mat) {
|
||||
double n00 = m00 * mat.m00 + m10 * mat.m01 + m20 * mat.m02 + m30 * mat.m03;
|
||||
double n01 = m01 * mat.m00 + m11 * mat.m01 + m21 * mat.m02 + m31 * mat.m03;
|
||||
double n02 = m02 * mat.m00 + m12 * mat.m01 + m22 * mat.m02 + m32 * mat.m03;
|
||||
@@ -177,12 +180,11 @@ public class Matrix4 extends Transformation implements Copyable<Matrix4>
|
||||
m31 = n31;
|
||||
m32 = n32;
|
||||
m33 = n33;
|
||||
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public Matrix4 multiply(Matrix4 mat)
|
||||
{
|
||||
|
||||
public Matrix4 multiply(Matrix4 mat) {
|
||||
double n00 = m00 * mat.m00 + m01 * mat.m10 + m02 * mat.m20 + m03 * mat.m30;
|
||||
double n01 = m00 * mat.m01 + m01 * mat.m11 + m02 * mat.m21 + m03 * mat.m31;
|
||||
double n02 = m00 * mat.m02 + m01 * mat.m12 + m02 * mat.m22 + m03 * mat.m32;
|
||||
@@ -216,12 +218,11 @@ public class Matrix4 extends Transformation implements Copyable<Matrix4>
|
||||
m31 = n31;
|
||||
m32 = n32;
|
||||
m33 = n33;
|
||||
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public Matrix4 transpose()
|
||||
{
|
||||
|
||||
public Matrix4 transpose() {
|
||||
double n00 = m00;
|
||||
double n10 = m01;
|
||||
double n20 = m02;
|
||||
@@ -255,17 +256,15 @@ public class Matrix4 extends Transformation implements Copyable<Matrix4>
|
||||
m31 = n31;
|
||||
m32 = n32;
|
||||
m33 = n33;
|
||||
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public Matrix4 copy()
|
||||
{
|
||||
|
||||
public Matrix4 copy() {
|
||||
return new Matrix4(this);
|
||||
}
|
||||
|
||||
public Matrix4 set(Matrix4 mat)
|
||||
{
|
||||
|
||||
public Matrix4 set(Matrix4 mat) {
|
||||
m00 = mat.m00;
|
||||
m01 = mat.m01;
|
||||
m02 = mat.m02;
|
||||
@@ -282,72 +281,80 @@ public class Matrix4 extends Transformation implements Copyable<Matrix4>
|
||||
m31 = mat.m31;
|
||||
m32 = mat.m32;
|
||||
m33 = mat.m33;
|
||||
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void apply(Matrix4 mat)
|
||||
{
|
||||
public void apply(Matrix4 mat) {
|
||||
mat.multiply(this);
|
||||
}
|
||||
|
||||
private void mult3x3(Vector3 vec)
|
||||
{
|
||||
|
||||
private void mult3x3(Vector3 vec) {
|
||||
double x = m00 * vec.x + m01 * vec.y + m02 * vec.z;
|
||||
double y = m10 * vec.x + m11 * vec.y + m12 * vec.z;
|
||||
double z = m20 * vec.x + m21 * vec.y + m22 * vec.z;
|
||||
|
||||
|
||||
vec.x = x;
|
||||
vec.y = y;
|
||||
vec.z = z;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void apply(Vector3 vec)
|
||||
{
|
||||
public void apply(Vector3 vec) {
|
||||
mult3x3(vec);
|
||||
vec.add(m03, m13, m23);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void applyN(Vector3 vec)
|
||||
{
|
||||
public void applyN(Vector3 vec) {
|
||||
mult3x3(vec);
|
||||
vec.normalize();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
public String toString() {
|
||||
MathContext cont = new MathContext(4, RoundingMode.HALF_UP);
|
||||
return "["+new BigDecimal(m00, cont)+","+new BigDecimal(m01, cont)+","+new BigDecimal(m02, cont)+","+new BigDecimal(m03, cont)+"]\n"+
|
||||
"["+new BigDecimal(m10, cont)+","+new BigDecimal(m11, cont)+","+new BigDecimal(m12, cont)+","+new BigDecimal(m13, cont)+"]\n"+
|
||||
"["+new BigDecimal(m20, cont)+","+new BigDecimal(m21, cont)+","+new BigDecimal(m22, cont)+","+new BigDecimal(m23, cont)+"]\n"+
|
||||
"["+new BigDecimal(m30, cont)+","+new BigDecimal(m31, cont)+","+new BigDecimal(m32, cont)+","+new BigDecimal(m33, cont)+"]";
|
||||
return "[" + new BigDecimal(m00, cont) + "," + new BigDecimal(m01, cont) + "," + new BigDecimal(m02, cont) + ","
|
||||
+ new BigDecimal(m03, cont) + "]\n" + "["
|
||||
+ new BigDecimal(m10, cont) + "," + new BigDecimal(m11, cont) + "," + new BigDecimal(m12, cont) + ","
|
||||
+ new BigDecimal(m13, cont) + "]\n" + "["
|
||||
+ new BigDecimal(m20, cont) + "," + new BigDecimal(m21, cont) + "," + new BigDecimal(m22, cont) + ","
|
||||
+ new BigDecimal(m23, cont) + "]\n" + "["
|
||||
+ new BigDecimal(m30, cont) + "," + new BigDecimal(m31, cont) + "," + new BigDecimal(m32, cont) + ","
|
||||
+ new BigDecimal(m33, cont) + "]";
|
||||
}
|
||||
|
||||
public Matrix4 apply(Transformation t)
|
||||
{
|
||||
|
||||
public Matrix4 apply(Transformation t) {
|
||||
t.apply(this);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@SideOnly(Side.CLIENT)
|
||||
public void glApply()
|
||||
{
|
||||
glBuf.put(m00).put(m10).put(m20).put(m30)
|
||||
.put(m01).put(m11).put(m21).put(m31)
|
||||
.put(m02).put(m12).put(m22).put(m32)
|
||||
.put(m03).put(m13).put(m23).put(m33);
|
||||
public void glApply() {
|
||||
glBuf.put(m00)
|
||||
.put(m10)
|
||||
.put(m20)
|
||||
.put(m30)
|
||||
.put(m01)
|
||||
.put(m11)
|
||||
.put(m21)
|
||||
.put(m31)
|
||||
.put(m02)
|
||||
.put(m12)
|
||||
.put(m22)
|
||||
.put(m32)
|
||||
.put(m03)
|
||||
.put(m13)
|
||||
.put(m23)
|
||||
.put(m33);
|
||||
glBuf.flip();
|
||||
GL11.glMultMatrix(glBuf);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Transformation inverse()
|
||||
{
|
||||
throw new IrreversibleTransformationException(this);//Don't waste your cpu with matrix inverses
|
||||
public Transformation inverse() {
|
||||
throw new IrreversibleTransformationException(this); // Don't waste your cpu with matrix inverses
|
||||
}
|
||||
}
|
||||
@@ -2,86 +2,74 @@ package codechicken.lib.vec;
|
||||
|
||||
import codechicken.lib.math.MathHelper;
|
||||
import codechicken.lib.util.Copyable;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.MathContext;
|
||||
import java.math.RoundingMode;
|
||||
|
||||
public class Quat implements Copyable<Quat>
|
||||
{
|
||||
public class Quat implements Copyable<Quat> {
|
||||
public double x;
|
||||
public double y;
|
||||
public double z;
|
||||
public double s;
|
||||
|
||||
public Quat()
|
||||
{
|
||||
public Quat() {
|
||||
s = 1;
|
||||
x = 0;
|
||||
y = 0;
|
||||
z = 0;
|
||||
}
|
||||
|
||||
public Quat(Quat quat)
|
||||
{
|
||||
public Quat(Quat quat) {
|
||||
x = quat.x;
|
||||
y = quat.y;
|
||||
z = quat.z;
|
||||
s = quat.s;
|
||||
}
|
||||
|
||||
public Quat(double d, double d1, double d2, double d3)
|
||||
{
|
||||
public Quat(double d, double d1, double d2, double d3) {
|
||||
x = d1;
|
||||
y = d2;
|
||||
z = d3;
|
||||
s = d;
|
||||
}
|
||||
|
||||
public Quat set(Quat quat)
|
||||
{
|
||||
public Quat set(Quat quat) {
|
||||
x = quat.x;
|
||||
y = quat.y;
|
||||
z = quat.z;
|
||||
s = quat.s;
|
||||
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public Quat set(double d, double d1, double d2, double d3)
|
||||
{
|
||||
public Quat set(double d, double d1, double d2, double d3) {
|
||||
x = d1;
|
||||
y = d2;
|
||||
z = d3;
|
||||
s = d;
|
||||
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public static Quat aroundAxis(double ax, double ay, double az, double angle)
|
||||
{
|
||||
|
||||
public static Quat aroundAxis(double ax, double ay, double az, double angle) {
|
||||
return new Quat().setAroundAxis(ax, ay, az, angle);
|
||||
}
|
||||
|
||||
public static Quat aroundAxis(Vector3 axis, double angle)
|
||||
{
|
||||
public static Quat aroundAxis(Vector3 axis, double angle) {
|
||||
return aroundAxis(axis.x, axis.y, axis.z, angle);
|
||||
}
|
||||
|
||||
public Quat setAroundAxis(double ax, double ay, double az, double angle)
|
||||
{
|
||||
|
||||
public Quat setAroundAxis(double ax, double ay, double az, double angle) {
|
||||
angle *= 0.5;
|
||||
double d4 = MathHelper.sin(angle);
|
||||
return set(MathHelper.cos(angle), ax * d4, ay * d4, az * d4);
|
||||
}
|
||||
|
||||
public Quat setAroundAxis(Vector3 axis, double angle)
|
||||
{
|
||||
|
||||
public Quat setAroundAxis(Vector3 axis, double angle) {
|
||||
return setAroundAxis(axis.x, axis.y, axis.z, angle);
|
||||
}
|
||||
|
||||
public Quat multiply(Quat quat)
|
||||
{
|
||||
public Quat multiply(Quat quat) {
|
||||
double d = s * quat.s - x * quat.x - y * quat.y - z * quat.z;
|
||||
double d1 = s * quat.x + x * quat.s - y * quat.z + z * quat.y;
|
||||
double d2 = s * quat.y + x * quat.z + y * quat.s - z * quat.x;
|
||||
@@ -90,12 +78,11 @@ public class Quat implements Copyable<Quat>
|
||||
x = d1;
|
||||
y = d2;
|
||||
z = d3;
|
||||
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public Quat rightMultiply(Quat quat)
|
||||
{
|
||||
public Quat rightMultiply(Quat quat) {
|
||||
double d = s * quat.s - x * quat.x - y * quat.y - z * quat.z;
|
||||
double d1 = s * quat.x + x * quat.s + y * quat.z - z * quat.y;
|
||||
double d2 = s * quat.y - x * quat.z + y * quat.s + z * quat.x;
|
||||
@@ -104,37 +91,32 @@ public class Quat implements Copyable<Quat>
|
||||
x = d1;
|
||||
y = d2;
|
||||
z = d3;
|
||||
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public double mag()
|
||||
{
|
||||
public double mag() {
|
||||
return Math.sqrt(x * x + y * y + z * z + s * s);
|
||||
}
|
||||
|
||||
public Quat normalize()
|
||||
{
|
||||
public Quat normalize() {
|
||||
double d = mag();
|
||||
if(d != 0)
|
||||
{
|
||||
if (d != 0) {
|
||||
d = 1 / d;
|
||||
x *= d;
|
||||
y *= d;
|
||||
z *= d;
|
||||
s *= d;
|
||||
}
|
||||
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public Quat copy()
|
||||
{
|
||||
public Quat copy() {
|
||||
return new Quat(this);
|
||||
}
|
||||
|
||||
public void rotate(Vector3 vec)
|
||||
{
|
||||
public void rotate(Vector3 vec) {
|
||||
double d = -x * vec.x - y * vec.y - z * vec.z;
|
||||
double d1 = s * vec.x + y * vec.z - z * vec.y;
|
||||
double d2 = s * vec.y - x * vec.z + z * vec.x;
|
||||
@@ -144,14 +126,13 @@ public class Quat implements Copyable<Quat>
|
||||
vec.z = d3 * s - d * z - d1 * y + d2 * x;
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
public String toString() {
|
||||
MathContext cont = new MathContext(4, RoundingMode.HALF_UP);
|
||||
return "Quat("+new BigDecimal(s, cont)+", "+new BigDecimal(x, cont)+", "+new BigDecimal(y, cont)+", "+new BigDecimal(z, cont)+")";
|
||||
return "Quat(" + new BigDecimal(s, cont) + ", " + new BigDecimal(x, cont) + ", " + new BigDecimal(y, cont)
|
||||
+ ", " + new BigDecimal(z, cont) + ")";
|
||||
}
|
||||
|
||||
public Rotation rotation()
|
||||
{
|
||||
public Rotation rotation() {
|
||||
return new Rotation(this);
|
||||
}
|
||||
}
|
||||
@@ -1,18 +1,14 @@
|
||||
package codechicken.lib.vec;
|
||||
|
||||
public class Rectangle4i
|
||||
{
|
||||
public class Rectangle4i {
|
||||
public int x;
|
||||
public int y;
|
||||
public int w;
|
||||
public int h;
|
||||
|
||||
public Rectangle4i()
|
||||
{
|
||||
}
|
||||
|
||||
public Rectangle4i(int x, int y, int w, int h)
|
||||
{
|
||||
|
||||
public Rectangle4i() {}
|
||||
|
||||
public Rectangle4i(int x, int y, int w, int h) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.w = w;
|
||||
@@ -28,11 +24,11 @@ public class Rectangle4i
|
||||
}
|
||||
|
||||
public int x2() {
|
||||
return x+w-1;
|
||||
return x + w - 1;
|
||||
}
|
||||
|
||||
public int y2() {
|
||||
return y+h-1;
|
||||
return y + h - 1;
|
||||
}
|
||||
|
||||
public void set(int x, int y, int w, int h) {
|
||||
@@ -41,25 +37,23 @@ public class Rectangle4i
|
||||
this.w = w;
|
||||
this.h = h;
|
||||
}
|
||||
|
||||
public Rectangle4i offset(int dx, int dy)
|
||||
{
|
||||
x+=dx;
|
||||
y+=dy;
|
||||
|
||||
public Rectangle4i offset(int dx, int dy) {
|
||||
x += dx;
|
||||
y += dy;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public Rectangle4i with(int px, int py)
|
||||
{
|
||||
public Rectangle4i with(int px, int py) {
|
||||
return include(px, py);
|
||||
}
|
||||
|
||||
public Rectangle4i include(int px, int py) {
|
||||
if(px < x) expand(px-x, 0);
|
||||
if(px >= x+w) expand(px-x-w+1, 0);
|
||||
if(py < y) expand(0, py-y);
|
||||
if(py >= y+h) expand(0, py-y-h+1);
|
||||
if (px < x) expand(px - x, 0);
|
||||
if (px >= x + w) expand(px - x - w + 1, 0);
|
||||
if (py < y) expand(0, py - y);
|
||||
if (py >= y + h) expand(0, py - y - h + 1);
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -69,32 +63,25 @@ public class Rectangle4i
|
||||
}
|
||||
|
||||
public Rectangle4i expand(int px, int py) {
|
||||
if(px > 0)
|
||||
w+=px;
|
||||
if (px > 0) w += px;
|
||||
else {
|
||||
x+=px;
|
||||
w-=px;
|
||||
x += px;
|
||||
w -= px;
|
||||
}
|
||||
if(py > 0)
|
||||
h+=py;
|
||||
if (py > 0) h += py;
|
||||
else {
|
||||
y+=py;
|
||||
h-=py;
|
||||
y += py;
|
||||
h -= py;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean contains(int px, int py)
|
||||
{
|
||||
return x <= px && px < x+w && y <= py && py < y+h;
|
||||
|
||||
public boolean contains(int px, int py) {
|
||||
return x <= px && px < x + w && y <= py && py < y + h;
|
||||
}
|
||||
|
||||
public boolean intersects(Rectangle4i r)
|
||||
{
|
||||
return r.x+r.w > x &&
|
||||
r.x < x+w &&
|
||||
r.y+r.h > y &&
|
||||
r.y < y+h;
|
||||
|
||||
public boolean intersects(Rectangle4i r) {
|
||||
return r.x + r.w > x && r.x < x + w && r.y + r.h > y && r.y < y + h;
|
||||
}
|
||||
|
||||
public int area() {
|
||||
|
||||
@@ -3,46 +3,42 @@ package codechicken.lib.vec;
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
|
||||
public class RedundantTransformation extends Transformation
|
||||
{
|
||||
public class RedundantTransformation extends Transformation {
|
||||
@Override
|
||||
public void apply(Vector3 vec){}
|
||||
public void apply(Vector3 vec) {}
|
||||
|
||||
@Override
|
||||
public void apply(Matrix4 mat){}
|
||||
|
||||
public void apply(Matrix4 mat) {}
|
||||
|
||||
@Override
|
||||
public void applyN(Vector3 normal){}
|
||||
|
||||
public void applyN(Vector3 normal) {}
|
||||
|
||||
@Override
|
||||
public Transformation at(Vector3 point)
|
||||
{
|
||||
public Transformation at(Vector3 point) {
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@SideOnly(Side.CLIENT)
|
||||
public void glApply(){}
|
||||
|
||||
public void glApply() {}
|
||||
|
||||
@Override
|
||||
public Transformation inverse()
|
||||
{
|
||||
public Transformation inverse() {
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Transformation merge(Transformation next) {
|
||||
return next;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isRedundant() {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
public String toString() {
|
||||
return "Nothing()";
|
||||
}
|
||||
}
|
||||
Loaded 100 of 114 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user