Compare commits
	
		
			No commits in common. '8444f32adf965a43fad72535235c1e22b27b103e' and 'f81103fbc6d09092b3082a0b99b8a2c3d45e4944' have entirely different histories. 
		
	
	
		
			8444f32adf
			...
			f81103fbc6
		
	
		
	| @ -0,0 +1,138 @@ | |||||||
|  | package com.zivilon.cinder_loe; | ||||||
|  | 
 | ||||||
|  | import java.util.ArrayList; | ||||||
|  | import java.util.EnumSet; | ||||||
|  | import java.util.HashMap; | ||||||
|  | import java.util.List; | ||||||
|  | import java.util.Map; | ||||||
|  | import lotr.common.LOTRAchievement; | ||||||
|  | import lotr.common.fac.LOTRFaction; | ||||||
|  | import lotr.common.world.LOTRWorldProvider; | ||||||
|  | import lotr.common.world.LOTRWorldProviderMiddleEarth; | ||||||
|  | import lotr.common.world.LOTRWorldProviderUtumno; | ||||||
|  | import lotr.common.world.biome.LOTRBiome; | ||||||
|  | import net.minecraft.util.StatCollector; | ||||||
|  | import net.minecraft.world.World; | ||||||
|  | import net.minecraft.world.WorldProvider; | ||||||
|  | import net.minecraftforge.common.DimensionManager; | ||||||
|  | import net.minecraftforge.common.config.Configuration; | ||||||
|  | 
 | ||||||
|  | import java.util.*; | ||||||
|  | 
 | ||||||
|  | public enum CinderDimension { | ||||||
|  |     ISLAND("Island", 101, LOTRWorldProviderMiddleEarth.class, false, 500, EnumSet.of(DimensionRegion.REG)); | ||||||
|  | 
 | ||||||
|  |     public String dimensionName; | ||||||
|  |     private int defaultID; | ||||||
|  |     public int dimensionID; | ||||||
|  |     private Class providerClass; | ||||||
|  |     private boolean loadSpawn; | ||||||
|  |     public LOTRBiome[] biomeList = new LOTRBiome[256]; | ||||||
|  |     public Map<Integer, Integer> colorsToBiomeIDs = new HashMap<Integer, Integer>(); | ||||||
|  |     public List<LOTRBiome> majorBiomes = new ArrayList<LOTRBiome>(); | ||||||
|  |     public List<LOTRAchievement.Category> achievementCategories = new ArrayList<LOTRAchievement.Category>(); | ||||||
|  |     public List<LOTRAchievement> allAchievements = new ArrayList<LOTRAchievement>(); | ||||||
|  |     public List<LOTRFaction> factionList = new ArrayList<LOTRFaction>(); | ||||||
|  |     public List<CinderDimension.DimensionRegion> dimensionRegions = new ArrayList<CinderDimension.DimensionRegion>(); | ||||||
|  |     public int spawnCap; | ||||||
|  | 
 | ||||||
|  |     private CinderDimension(String s, int i, Class c, boolean flag, int spawns, EnumSet<DimensionRegion> regions) { | ||||||
|  |         this.dimensionName = s; | ||||||
|  |         this.defaultID = i; | ||||||
|  |         this.providerClass = c; | ||||||
|  |         this.loadSpawn = flag; | ||||||
|  |         this.spawnCap = spawns; | ||||||
|  |         this.dimensionRegions.addAll(regions); | ||||||
|  |         for (DimensionRegion r : this.dimensionRegions) { | ||||||
|  |             r.setDimension(this); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     public String getUntranslatedDimensionName() { | ||||||
|  |         return "lotr.dimension." + this.dimensionName; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public String getDimensionName() { | ||||||
|  |         return StatCollector.translateToLocal((String)this.getUntranslatedDimensionName()); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static void configureDimensions(Configuration config, String category) { | ||||||
|  |         for (CinderDimension dim : CinderDimension.values()) { | ||||||
|  |             dim.dimensionID = config.get(category, "Dimension ID: " + dim.dimensionName, dim.defaultID).getInt(); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static void registerDimensions() { | ||||||
|  |         for (CinderDimension dim : CinderDimension.values()) { | ||||||
|  |             DimensionManager.registerProviderType((int)dim.dimensionID, (Class)dim.providerClass, (boolean)dim.loadSpawn); | ||||||
|  |             DimensionManager.registerDimension((int)dim.dimensionID, (int)dim.dimensionID); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static CinderDimension getCurrentDimension(World world) { | ||||||
|  |         WorldProvider provider; | ||||||
|  |         if (world != null && (provider = world.provider) instanceof LOTRWorldProvider) { | ||||||
|  |             return ((LOTRWorldProvider)provider).getLOTRDimension(); | ||||||
|  |         } | ||||||
|  |         return null; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static CinderDimension getCurrentDimensionWithFallback(World world) { | ||||||
|  |         CinderDimension dim = CinderDimension.getCurrentDimension(world); | ||||||
|  |         if (dim == null) { | ||||||
|  |             return ISLAND; | ||||||
|  |         } | ||||||
|  |         return dim; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static CinderDimension forName(String s) { | ||||||
|  |         for (CinderDimension dim : CinderDimension.values()) { | ||||||
|  |             if (!dim.dimensionName.equals(s)) continue; | ||||||
|  |             return dim; | ||||||
|  |         } | ||||||
|  |         return null; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static enum DimensionRegion { | ||||||
|  |         REG("island"); | ||||||
|  | 
 | ||||||
|  |         private String regionName; | ||||||
|  |         private CinderDimension dimension; | ||||||
|  |         public List<LOTRFaction> factionList = new ArrayList<LOTRFaction>(); | ||||||
|  | 
 | ||||||
|  |         private DimensionRegion(String s) { | ||||||
|  |             this.regionName = s; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         public void setDimension(CinderDimension dim) { | ||||||
|  |             this.dimension = dim; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         public CinderDimension getDimension() { | ||||||
|  |             return this.dimension; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         public String codeName() { | ||||||
|  |             return this.regionName; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         public String getRegionName() { | ||||||
|  |             return StatCollector.translateToLocal((String)("lotr.dimension." + this.dimension.dimensionName + "." + this.codeName())); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         public static DimensionRegion forName(String regionName) { | ||||||
|  |             for (DimensionRegion r : DimensionRegion.values()) { | ||||||
|  |                 if (!r.codeName().equals(regionName)) continue; | ||||||
|  |                 return r; | ||||||
|  |             } | ||||||
|  |             return null; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         public static DimensionRegion forID(int ID) { | ||||||
|  |             for (DimensionRegion r : DimensionRegion.values()) { | ||||||
|  |                 if (r.ordinal() != ID) continue; | ||||||
|  |                 return r; | ||||||
|  |             } | ||||||
|  |             return null; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -1,206 +0,0 @@ | |||||||
| package com.zivilon.cinder_loe.coremod; |  | ||||||
| 
 |  | ||||||
| import com.zivilon.cinder_loe.world.CinderWorldProviderIsland; |  | ||||||
| 
 |  | ||||||
| import net.minecraft.launchwrapper.IClassTransformer; |  | ||||||
| import org.objectweb.asm.ClassReader; |  | ||||||
| import org.objectweb.asm.ClassWriter; |  | ||||||
| import org.objectweb.asm.Opcodes; |  | ||||||
| import org.objectweb.asm.Type; |  | ||||||
| import org.objectweb.asm.tree.ClassNode; |  | ||||||
| import org.objectweb.asm.tree.FieldNode; |  | ||||||
| import org.objectweb.asm.tree.InsnList; |  | ||||||
| import org.objectweb.asm.tree.AbstractInsnNode; |  | ||||||
| import org.objectweb.asm.tree.IntInsnNode; |  | ||||||
| import org.objectweb.asm.tree.TypeInsnNode; |  | ||||||
| import org.objectweb.asm.tree.InsnNode; |  | ||||||
| import org.objectweb.asm.tree.LdcInsnNode; |  | ||||||
| import org.objectweb.asm.tree.FieldInsnNode; |  | ||||||
| import org.objectweb.asm.tree.MethodInsnNode; |  | ||||||
| import org.objectweb.asm.tree.MethodNode; |  | ||||||
| 
 |  | ||||||
| import java.util.List; |  | ||||||
| import java.util.ArrayList; |  | ||||||
| 
 |  | ||||||
| public class LOTRDimensionAdder implements IClassTransformer { |  | ||||||
|     public static List<DimensionInfo> custom_dimensions = new ArrayList<>(); |  | ||||||
| 
 |  | ||||||
|     // This is where you add new dimensions
 |  | ||||||
|     public void registerDimensions() { |  | ||||||
|         System.out.println("Registering dimensions"); |  | ||||||
|         custom_dimensions = new ArrayList<>(); |  | ||||||
| //        register("ISLAND", "Island", 102, CinderWorldProviderIsland.class, 100);
 |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     // The ASM code you shouldn't touch
 |  | ||||||
|     @Override |  | ||||||
|     public byte[] transform(String name, String transformedName, byte[] basicClass) { |  | ||||||
|         if ("lotr.common.LOTRDimension".equals(transformedName)) { |  | ||||||
|             registerDimensions(); |  | ||||||
|             if (custom_dimensions.isEmpty()) return basicClass; |  | ||||||
| 
 |  | ||||||
|             // Get class
 |  | ||||||
|             ClassReader classReader = new ClassReader(basicClass); |  | ||||||
|             ClassNode classNode = new ClassNode(); |  | ||||||
|             classReader.accept(classNode, 0); |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|             // Add the new enum constant
 |  | ||||||
|             for (DimensionInfo dimension : custom_dimensions) { |  | ||||||
|                 FieldNode newEnumConstant = new FieldNode( |  | ||||||
|                         Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC + Opcodes.ACC_FINAL + Opcodes.ACC_ENUM, |  | ||||||
|                         dimension.enum_name, |  | ||||||
|                         "Llotr/common/LOTRDimension;", |  | ||||||
|                         null, |  | ||||||
|                         null |  | ||||||
|                 ); |  | ||||||
|                 classNode.fields.add(newEnumConstant); |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|             // Locate <clinit>
 |  | ||||||
|             MethodNode clinit = null; |  | ||||||
|             for (MethodNode method : classNode.methods) { |  | ||||||
|                 if ("<clinit>".equals(method.name)) { |  | ||||||
|                     clinit = method; |  | ||||||
|                     break; |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             InsnList insns = clinit.instructions; |  | ||||||
|             AbstractInsnNode constructor_injection_point = null; |  | ||||||
| 
 |  | ||||||
|             for (AbstractInsnNode insn : clinit.instructions.toArray()) { |  | ||||||
|                 if (insn.getOpcode() == Opcodes.ICONST_2) { |  | ||||||
|                     constructor_injection_point = insn; |  | ||||||
|                     int list_size = 2 + custom_dimensions.size(); |  | ||||||
|                     IntInsnNode push_size = new IntInsnNode(Opcodes.BIPUSH, 2 + custom_dimensions.size()); |  | ||||||
|                     clinit.instructions.insert(insn, push_size); |  | ||||||
|                     clinit.instructions.remove(insn); |  | ||||||
|                     constructor_injection_point = push_size; |  | ||||||
|                     System.out.println("LOTRDimension list size: " + list_size); |  | ||||||
|                     break; |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|             // Create the constructor instructions to add new dimension
 |  | ||||||
|             InsnList constructor_injection = new InsnList(); |  | ||||||
|             int i = 2; |  | ||||||
|             for (DimensionInfo dimension : custom_dimensions) { |  | ||||||
|                 System.out.println("Registering with enum " + dimension.enum_name); |  | ||||||
|                 System.out.println("Registering with ordinal " + i); |  | ||||||
|                 System.out.println("Registering with name " + dimension.dimension_name); |  | ||||||
|                 System.out.println("Registering with ID " + dimension.dimension_id); |  | ||||||
| 
 |  | ||||||
|                 constructor_injection.add(new TypeInsnNode(Opcodes.NEW, "lotr/common/LOTRDimension")); |  | ||||||
|                 constructor_injection.add(new InsnNode(Opcodes.DUP)); |  | ||||||
|                 constructor_injection.add(new LdcInsnNode(dimension.enum_name)); |  | ||||||
|                 constructor_injection.add(new IntInsnNode(Opcodes.BIPUSH, i)); |  | ||||||
|                 constructor_injection.add(new LdcInsnNode(dimension.dimension_name)); |  | ||||||
|                 constructor_injection.add(new IntInsnNode(Opcodes.BIPUSH, dimension.dimension_id)); |  | ||||||
|                 constructor_injection.add(new LdcInsnNode(Type.getType(dimension.world_provider))); // World provider class
 |  | ||||||
|                 constructor_injection.add(new InsnNode(Opcodes.ICONST_0)); // Do not load spawn persistently
 |  | ||||||
|                 constructor_injection.add(new IntInsnNode(Opcodes.BIPUSH, dimension.spawn_limit)); // Set spawn cap for dimension
 |  | ||||||
| 
 |  | ||||||
|                 // Add no DimensionRegions
 |  | ||||||
|                 constructor_injection.add(new LdcInsnNode(Type.getType("Llotr/common/LOTRDimension$DimensionRegion;"))); |  | ||||||
|                 constructor_injection.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "java/util/EnumSet", "noneOf", "(Ljava/lang/Class;)Ljava/util/EnumSet;", false)); |  | ||||||
| 
 |  | ||||||
|                 // Add PUTSTATIC
 |  | ||||||
|                 constructor_injection.add(new MethodInsnNode(Opcodes.INVOKESPECIAL, "lotr/common/LOTRDimension", "<init>", "(Ljava/lang/String;ILjava/lang/String;ILjava/lang/Class;ZILjava/util/EnumSet;)V", false)); |  | ||||||
|                 constructor_injection.add(new FieldInsnNode(Opcodes.PUTSTATIC, "lotr/common/LOTRDimension", dimension.enum_name, "Llotr/common/LOTRDimension;")); |  | ||||||
|                 i++; |  | ||||||
|             } |  | ||||||
|             // Insert the new instructions
 |  | ||||||
|             if (constructor_injection_point != null) { |  | ||||||
|                 insns.insertBefore(constructor_injection_point, constructor_injection); |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             // Modifying the $VALUES array
 |  | ||||||
|             // Create new instruction list to be injected later
 |  | ||||||
|             InsnList values_array_injection = new InsnList(); |  | ||||||
| 
 |  | ||||||
|             // Add instructions to the instruction list
 |  | ||||||
|             i = 2; |  | ||||||
|             for (DimensionInfo dimension : custom_dimensions) { |  | ||||||
|                 values_array_injection.add(new InsnNode(Opcodes.DUP)); |  | ||||||
|                 values_array_injection.add(new IntInsnNode(Opcodes.BIPUSH, i)); |  | ||||||
|                 values_array_injection.add(new FieldInsnNode(Opcodes.GETSTATIC, "lotr/common/LOTRDimension", dimension.enum_name, "Llotr/common/LOTRDimension;")); |  | ||||||
|                 values_array_injection.add(new InsnNode(Opcodes.AASTORE)); |  | ||||||
|                 i++; |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             // Find the putstatic instruction for $VALUES
 |  | ||||||
|             // This is where the fields are injected into a list, we want to inject our instructions before this
 |  | ||||||
|             AbstractInsnNode values_injection_point = null; |  | ||||||
| 
 |  | ||||||
|             AbstractInsnNode cursor = constructor_injection_point; |  | ||||||
|             while (cursor != null) { |  | ||||||
|                 if (cursor.getOpcode() == Opcodes.PUTSTATIC) { |  | ||||||
|                     values_injection_point = cursor; |  | ||||||
|                     break; |  | ||||||
|                 } |  | ||||||
|                 cursor = cursor.getNext(); |  | ||||||
|             } |  | ||||||
|             if (values_injection_point == null) { |  | ||||||
|                 throw new RuntimeException("[CinderLoE] Could not locate $VALUES PUTSTATIC injection point for LOTRDimension!"); |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             // Insert the new instructions before the putstatic instruction
 |  | ||||||
|             if (values_injection_point != null) { |  | ||||||
|                 insns.insertBefore(values_injection_point, values_array_injection); |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             // Write the modified class back to a byte array
 |  | ||||||
|             ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS); |  | ||||||
|             classNode.accept(classWriter); |  | ||||||
|             return classWriter.toByteArray(); // Return the modified class
 |  | ||||||
|         } |  | ||||||
|         return basicClass; // Return the unmodified class for all other classes
 |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public void register(String enum_name, String dimension_name, int dimension_id, Class<?> world_provider, int spawn_limit) { |  | ||||||
|         System.out.println("Registering dimension " + enum_name + " " + dimension_name + " with ID " + dimension_id); |  | ||||||
|         custom_dimensions.add(new DimensionInfo(enum_name, dimension_name, dimension_id, world_provider, spawn_limit)); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public class DimensionInfo { |  | ||||||
|         String enum_name; |  | ||||||
|         String dimension_name; |  | ||||||
|         int dimension_id; |  | ||||||
|         Class<?> world_provider; |  | ||||||
|         int spawn_limit; |  | ||||||
| 
 |  | ||||||
|         public DimensionInfo(String enum_name, String dimension_name, int dimension_id, Class<?> world_provider, int spawn_limit) { |  | ||||||
|             this.enum_name = enum_name; |  | ||||||
|             this.dimension_name = dimension_name; |  | ||||||
|             this.dimension_id = dimension_id; |  | ||||||
|             this.world_provider = world_provider; |  | ||||||
|             this.spawn_limit = spawn_limit; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /* Reference |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| L0:     new lotr/common/LOTRDimension |  | ||||||
| L3:     dup |  | ||||||
| L4:     ldc 'MIDDLE_EARTH' |  | ||||||
| L6:     iconst_0 |  | ||||||
| L7:     ldc 'MiddleEarth' |  | ||||||
| L9:     bipush 100 |  | ||||||
| L11:    ldc Class lotr/common/world/LOTRWorldProviderMiddleEarth |  | ||||||
| L13:    iconst_1 |  | ||||||
| L14:    bipush 100 |  | ||||||
| L16:    getstatic Field lotr/common/LOTRDimension$DimensionRegion WEST Llotr/common/LOTRDimension$DimensionRegion; |  | ||||||
| L19:    getstatic Field lotr/common/LOTRDimension$DimensionRegion EAST Llotr/common/LOTRDimension$DimensionRegion; |  | ||||||
| L22:    getstatic Field lotr/common/LOTRDimension$DimensionRegion SOUTH Llotr/common/LOTRDimension$DimensionRegion; |  | ||||||
| L25:    invokestatic Method java/util/EnumSet of (Ljava/lang/Enum;Ljava/lang/Enum;Ljava/lang/Enum;)Ljava/util/EnumSet; |  | ||||||
| L28:    invokespecial Method lotr/common/LOTRDimension <init> (Ljava/lang/String;ILjava/lang/String;ILjava/lang/Class;ZILjava/util/EnumSet;)V |  | ||||||
| L31:    putstatic Field lotr/common/LOTRDimension MIDDLE_EARTH Llotr/common/LOTRDimension; |  | ||||||
| L34:    new lotr/common/LOTRDimension |  | ||||||
| 
 |  | ||||||
| */ |  | ||||||
					Loading…
					
					
				
		Reference in New Issue