[Tutorial] [1.7] Editing the Spawns in a Biome

Discussion in 'Resources' started by krazytraynz, Nov 30, 2013.

Thread Status:
Not open for further replies.
  1. Offline

    krazytraynz

    I've recently figured out how to change what entities spawn in a biome, and how often they spawn through the use of reflection. It's fairly simple, but it does require some digging through NMS classes (you can find them here). Sorry in advance if the tutorial isn't too clear or if I use improper terminology, I'm not very good at explaining things :p


    First off, create a new class (or do this in your main class, if you prefer) and create a new method, which for the purpose of this tutorial I will be naming addSpawn. Create an undefined variable, an instance of whatever biome you with to change. In this case I'll be using the Nether, or BiomeHell. Keep in mind you can change as many biomes as you wish in one class, but for the purpose of this tutorial I will only be changing one. Inside of a try block, create a new instance of the biome using the integer used for your biome in BiomeBase.java, as the constructor for most Biomes use an integer. For special cases, see the spoiler at the bottom of this post.

    Code:java
    1. package com.example.tutorial;
    2.  
    3. import net.minecraft.server.v1_7_R1.BiomeHell;
    4.  
    5. public class ModifySpawn {
    6.  
    7. private BiomeHell biomehell;
    8.  
    9. public void addSpawn(){
    10. try{
    11. biomehell = new BiomeHell(8);
    12. }catch(Exception e){
    13. e.printStackTrace(); //More graceful error handling is recommended
    14. }
    15. }
    16. }
    17.  


    Get the fields as, at, au, and av from BiomeBase.class, and set them accessible. From my current understanding, as is the ArrayList used for spawning entities that extend EntityMonster, at is used for entities that extend EntityCreature, au is used for entites that extend EntityWaterAnimal, and av is used for entites that extend EntityAmbient. Create 4 new respective ArrayLists, with the element BiomeMeta.

    Code:java
    1. package com.example.tutorial;
    2.  
    3. import java.lang.reflect.Field;
    4. import java.util.ArrayList;
    5.  
    6. import net.minecraft.server.v1_7_R1.BiomeHell;
    7. import net.minecraft.server.v1_7_R1.BiomeMeta;
    8.  
    9. public class ModifySpawn {
    10.  
    11. private BiomeHell biomehell;
    12.  
    13. public void addSpawn(){
    14. try{
    15. biomehell = new BiomeHell(8);
    16.  
    17. Field as = net.minecraft.server.v1_7_R1.BiomeBase.class.getDeclaredField("as");
    18. Field at = net.minecraft.server.v1_7_R1.BiomeBase.class.getDeclaredField("at");
    19. Field au = net.minecraft.server.v1_7_R1.BiomeBase.class.getDeclaredField("au");
    20. Field av = net.minecraft.server.v1_7_R1.BiomeBase.class.getDeclaredField("av");
    21.  
    22. as.setAccessible(true);
    23. at.setAccessible(true);
    24. au.setAccessible(true);
    25. av.setAccessible(true);
    26.  
    27. ArrayList<BiomeMeta> asList = new ArrayList<BiomeMeta>();
    28. ArrayList<BiomeMeta> atList = new ArrayList<BiomeMeta>();
    29. ArrayList<BiomeMeta> auList = new ArrayList<BiomeMeta>();
    30. ArrayList<BiomeMeta> avList = new ArrayList<BiomeMeta>();
    31. }catch(Exception e){
    32. e.printStackTrace(); //More graceful error handling is recommended
    33. }
    34. }
    35. }
    36.  


    Create a second try block, and add the BiomeMeta of the entites you want to add to their respective ArrayLists. Using the Field.set() method, set fields as, at, au, and av using set(yourbiome, ArrayList).

    Arguments for BiomeMeta:
    Show Spoiler

    BiomeMeta(Class arg0, int arg1, int arg2, int arg3)

    Class arg0: The class of whichever entity you are trying to spawn.

    int arg1: Spawn Probablility - The weighted probability of the mob spawning. See BiomeBase.java for the defaults of common mobs, other mobs may have to be found in different biome classes.

    int arg2: minSpawn - The minimum amount of mobs allowed in a spawn group.

    int arg3: maxSpawn - The maximum amount of mobs allowed in a spawn group.


    Your finished class should look something like this (I changed the spawns in the Nether to Creepers, Skeletons, Magma Cubes, and Zombies in this case):
    Code:java
    1. package com.example.tutorial;
    2.  
    3. import java.lang.reflect.Field;
    4. import java.util.ArrayList;
    5.  
    6. import net.minecraft.server.v1_7_R1.BiomeHell;
    7. import net.minecraft.server.v1_7_R1.BiomeMeta;
    8. import net.minecraft.server.v1_7_R1.EntityCreeper;
    9. import net.minecraft.server.v1_7_R1.EntityGhast;
    10. import net.minecraft.server.v1_7_R1.EntityMagmaCube;
    11. import net.minecraft.server.v1_7_R1.EntityPigZombie;
    12.  
    13. public class ModifySpawn {
    14.  
    15. private BiomeHell biomehell;
    16.  
    17. public void addSpawn(){
    18. try{
    19. biomehell = new BiomeHell(8);
    20.  
    21. Field as = net.minecraft.server.v1_7_R1.BiomeBase.class.getDeclaredField("as");
    22. Field at = net.minecraft.server.v1_7_R1.BiomeBase.class.getDeclaredField("at");
    23. Field au = net.minecraft.server.v1_7_R1.BiomeBase.class.getDeclaredField("au");
    24. Field av = net.minecraft.server.v1_7_R1.BiomeBase.class.getDeclaredField("av");
    25.  
    26. as.setAccessible(true);
    27. at.setAccessible(true);
    28. au.setAccessible(true);
    29. av.setAccessible(true);
    30.  
    31. ArrayList<BiomeMeta> asList = new ArrayList<BiomeMeta>();
    32. ArrayList<BiomeMeta> atList = new ArrayList<BiomeMeta>();
    33. ArrayList<BiomeMeta> auList = new ArrayList<BiomeMeta>();
    34. ArrayList<BiomeMeta> avLost = new ArrayList<BiomeMeta>();
    35.  
    36. try{
    37. asList.add(new BiomeMeta(EntityCreeper.class, 50, 4, 4));
    38. asList.add(new BiomeMeta(EntitySkeleton.class, 50, 4, 4));
    39. asList.add(new BiomeMeta(EntityZombie.class, 100, 4, 4));
    40. asList.add(new BiomeMeta(EntityMagmaCube.class, 20, 4, 4));
    41.  
    42. as.set(biomehell, asList);
    43. at.set(biomehell, atList);
    44. au.set(biomehell, auList);
    45. av.set(biomehell, avList);
    46. }catch(Exception e){
    47. e.printStackTrace(); //Again, try to handle your errors better
    48. }
    49. }catch(Exception e){
    50. e.printStackTrace(); //More graceful error handling is recommended
    51. }
    52. }
    53. }


    Afterwards, just call addSpawn() in your onEnable() method, and you're all set! Keep in mind that this completely overwrites the spawns in a biome, it doesn't add to them. If you want to add spawns, you have to use whatever spawns are used in the original biome's class, and the additional spawns.

    Show Spoiler

    In some cases you may have to do a little extra to get an instance of a biome. I'll explain what you have to do first, but here's a list of the current biomes that you'll have to use this method for.

    Any biome that's an instance of:
    • BiomeHills (e.g Extreme Hills, Extreme Hills M)
    • BiomeSnow(e.g Ice Plains, Ice Mountains)
    • BiomeJungle(e.g Jungle, Junge Hills)
    • BiomeMesa(e.g Mesa, Mesa Plateau)
    These biome classes use special constructors, which you'll also have to access through reflection.
    Set up everything the way you would normally, but this time create a variable for the constructor of BiomeJungle outside of addSpawn(), and two variables for the classes of int and boolean inside of the try block, which is what you'll need to initialize the constructor in this case.
    Code:java
    1. package com.github.KrazyTraynz;
    2.  
    3. import net.minecraft.server.v1_7_R1.BiomeJungle;
    4.  
    5. import java.lang.reflect.Constructor;
    6.  
    7.  
    8. public class Test {
    9.  
    10. private BiomeJungle jungle;
    11.  
    12. private Constructor<BiomeJungle> jungleConstructor;
    13.  
    14. public void addSpawn(){
    15. try{
    16. Class<?> integer = int.class;
    17. Class<?> bool = boolean.class;
    18.  
    19.  
    20. }
    21. }
    22. }
    23.  

    Initialize the constructor using the getDeclaredConstructor() method, and whatever arguments are necessary to successfully call the method. Afterwards, set the constructor acessable and instantiate your biome using yourConstructor.newInstance(), again using whatever arguments you need.
    Code:java
    1. package com.tutorial.example;
    2.  
    3. import net.minecraft.server.v1_7_R1.BiomeJungle;
    4.  
    5. import java.lang.reflect.Constructor;
    6. import java.lang.reflect.InvocationTargetException;
    7.  
    8.  
    9. public class Test {
    10.  
    11. private BiomeJungle jungle;
    12.  
    13. private Constructor<BiomeJungle> jungleConstructor;
    14.  
    15. public void addSpawn(){
    16. Class<?> integer = int.class;
    17. Class<?> bool = boolean.class;
    18.  
    19. try {
    20. jungleConstructor = BiomeJungle.class.getDeclaredConstructor(integer, bool);
    21. jungleConstructor.setAccessible(true);
    22.  
    23. jungle = jungleConstructor.newInstance(21, false);
    24. } catch (NoSuchMethodException e) {
    25. e.printStackTrace();
    26. e.printStackTrace();
    27. } catch (InstantiationException e) {
    28. e.printStackTrace();
    29. } catch (IllegalAccessException e) {
    30. e.printStackTrace();
    31. }
    32. }

    You can continue as you would normally from here. Keep in mind the constructor must be exactly the same as the constructor in the Biome's class (you can find NMS classes in the beginning of this post) or everything will be broken.


    Please let me know if there's something I need to change/explain better. I hope this tutorial helped you guys!
     
    Bart and Ultimate_n00b like this.
  2. Offline

    Ultimate_n00b

    Hmph, interesting.

    I was looking at this and realized something. You're not modifying the objects the server is using, you're modifying your own instance. Don't we have to modify those static variables?

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jun 5, 2016
    krazytraynz likes this.
  3. Offline

    krazytraynz

    It sounds like it would be the only way to do this, but creating a separate instance still successfully overrides the original spawns. I am not entirely sure if one method works better than the other, however, as I've only tested the one mentioned in this tutorial.
     
    Ultimate_n00b likes this.
  4. Offline

    Bart

    It looks like now the field names have changed to the following:
    'as' is now used for hostile mobs
    'au' is now used for water mobs
    'av' for bats
    'at' for friendly mobs
     
  5. Offline

    krazytraynz

    Bart
    Thanks, working on updating this now since I just found the beta for MCP 9.0.2 :p
     
  6. Offline

    Bart

    It gives a lot of errors because it interferes with how minecraft checks the achievement given for exploring all biomes.. it's weird and I'm not quite sure what causes it.
     
  7. Offline

    krazytraynz

    Bart
    Hm, I haven't put in the time to test it yet because I've been adding the 17 new biomes to my plugin that uses this, but I'll look into it. That does seem a bit odd.

    EDIT: When are you getting the error?
     
  8. Offline

    Bart

    Logging in/out
     
  9. Offline

    97WaterPolo

    krazytraynz
    This works pretty well, awesome tutorial. I have an error in which when the server saves/starts/restarts I get the following error.
    Code:
    12.02 00:27:03 [Server] INFO CONSOLE: Save complete.
    12.02 00:27:03 [Server] INFO java.lang.NullPointerException
    12.02 00:27:03 [Server] WARN Couldn't save statistic TranslatableComponent{key='achievement.exploreAllBiomes', args=[], siblings=[], style=Style{hasParent=false, color=?5, bold=null, italic=null, underlined=null, obfuscated=null, clickEvent=null, hoverEvent=HoverEvent{action=SHOW_ACHIEVEMENT, value='TextComponent{text='achievement.exploreAllBiomes', siblings=[], style=Style{hasParent=false, color=null, bold=null, italic=null, underlined=null, obfuscated=null, clickEvent=null, hoverEvent=null}}'}}}: error serializing progress
    12.02 00:27:03 [Server] INFO java.lang.NullPointerException
    12.02 00:27:03 [Server] WARN Couldn't save statistic TranslatableComponent{key='achievement.exploreAllBiomes', args=[], siblings=[], style=Style{hasParent=false, color=?5, bold=null, italic=null, underlined=null, obfuscated=null, clickEvent=null, hoverEvent=HoverEvent{action=SHOW_ACHIEVEMENT, value='TextComponent{text='achievement.exploreAllBiomes', siblings=[], style=Style{hasParent=false, color=null, bold=null, italic=null, underlined=null, obfuscated=null, clickEvent=null, hoverEvent=null}}'}}}: error serializing progress
    12.02 00:27:03 [Server] INFO CONSOLE: Forcing save..
    12.02 00:27:03 [Server] INFO CONSOLE: Enabled level saving..
    12.02 00:27:03 [Multicraft] Auto-saving world...
    It still works, adds the mobs to the biome, but I would rather find a fix to it if possible. Code is: http://hastebin.com/lovoqapoji.avrasm
     
  10. Offline

    x2nec

    For some reason or another, this is not working for me. I have tried changing some things here and there but nothing is playing right - I still have creepers and spiders and what ever else spawning in my jungle biome, for example. The code I have at the moment is below, and I'd be grateful if you could help me :)

    Code:java
    1. package me.main.wgen.utils;
    2.  
    3. import java.lang.reflect.Constructor;
    4. import java.lang.reflect.Field;
    5. import java.util.ArrayList;
    6.  
    7. import net.minecraft.server.v1_7_R1.*;
    8.  
    9. import org.bukkit.block.Biome;
    10.  
    11. public class ModifySpawns {
    12.  
    13. public void addSpawn(Biome biome) {
    14. try {
    15. Field as = net.minecraft.server.v1_7_R1.BiomeBase.class
    16. .getDeclaredField("as");
    17. Field au = net.minecraft.server.v1_7_R1.BiomeBase.class
    18. .getDeclaredField("au");
    19. Field av = net.minecraft.server.v1_7_R1.BiomeBase.class
    20. .getDeclaredField("av");
    21. Field at = net.minecraft.server.v1_7_R1.BiomeBase.class
    22. .getDeclaredField("at");
    23.  
    24. as.setAccessible(true);
    25. au.setAccessible(true);
    26. av.setAccessible(true);
    27. at.setAccessible(true);
    28.  
    29. ArrayList<BiomeMeta> listas = new ArrayList<BiomeMeta>();
    30. ArrayList<BiomeMeta> listau = new ArrayList<BiomeMeta>();
    31. ArrayList<BiomeMeta> listav = new ArrayList<BiomeMeta>();
    32. ArrayList<BiomeMeta> listat = new ArrayList<BiomeMeta>();
    33. try {
    34. if (biome.name().equalsIgnoreCase(Biome.JUNGLE.name())) {
    35. BiomeJungle jungle;
    36. Constructor<BiomeJungle> jungleConstructor;
    37. jungleConstructor = BiomeJungle.class.getDeclaredConstructor(int.class, boolean.class);
    38. jungleConstructor.setAccessible(true);
    39. jungle = jungleConstructor.newInstance(21, false);
    40. listas.add(new BiomeMeta(EntitySkeleton.class, 50, 1, 3));
    41. listas.add(new BiomeMeta(EntityZombie.class, 100, 1, 3));
    42. as.set(jungle, listas);
    43. au.set(jungle, listau);
    44. av.set(jungle, listav);
    45. at.set(jungle, listat);
    46. } else if (biome.name().equalsIgnoreCase(Biome.FOREST.name())) {
    47. BiomeForest biomeforest = new BiomeForest(8, 8);
    48. listas.add(new BiomeMeta(EntitySkeleton.class, 50, 2, 4));
    49. listas.add(new BiomeMeta(EntityZombie.class, 100, 2, 4));
    50. listat.add(new BiomeMeta(EntityWolf.class, 50, 1, 2));
    51. as.set(biomeforest, listas);
    52. au.set(biomeforest, listau);
    53. av.set(biomeforest, listav);
    54. at.set(biomeforest, listat);
    55. } else if (biome.name().equalsIgnoreCase(Biome.DESERT.name())) {
    56. BiomeDesert biomedesert = new BiomeDesert(8);
    57. listas.add(new BiomeMeta(EntityZombie.class, 100, 4, 6));
    58. listas.add(new BiomeMeta(EntitySkeleton.class, 50, 4, 8));
    59. listas.add(new BiomeMeta(EntityBlaze.class, 5, 1, 3));
    60. listas.add(new BiomeMeta(EntityEnderDragon.class, 1, 1, 1));
    61. as.set(biomedesert, listas);
    62. au.set(biomedesert, listau);
    63. av.set(biomedesert, listav);
    64. at.set(biomedesert, listat);
    65. } else if (biome.name().equalsIgnoreCase(Biome.TAIGA.name())) {
    66. BiomeTaiga taiga;
    67. Constructor<BiomeTaiga> taigaConstructor;
    68. taigaConstructor = BiomeTaiga.class.getDeclaredConstructor(int.class, int.class);
    69. taigaConstructor.setAccessible(true);
    70. taiga = taigaConstructor.newInstance(21, 8);
    71. listas.add(new BiomeMeta(EntityZombie.class, 100, 6, 8));
    72. listas.add(new BiomeMeta(EntitySilverfish.class, 20, 6, 9));
    73. listat.add(new BiomeMeta(EntityIronGolem.class, 5, 1, 2));
    74. as.set(taiga, listas);
    75. au.set(taiga, listau);
    76. av.set(taiga, listav);
    77. at.set(taiga, listat);
    78. } else if (biome.name().equalsIgnoreCase(Biome.ICE_PLAINS.name())) {
    79. BiomeIcePlains iceplains;
    80. Constructor<BiomeIcePlains> iceplainsConstructor;
    81. iceplainsConstructor = BiomeIcePlains.class.getDeclaredConstructor(int.class, boolean.class);
    82. iceplainsConstructor.setAccessible(true);
    83. iceplains = iceplainsConstructor.newInstance(21, false);
    84. listas.add(new BiomeMeta(EntityZombie.class, 120, 8, 8));
    85. listas.add(new BiomeMeta(EntitySpider.class, 10, 8, 8));
    86. listas.add(new BiomeMeta(EntityEnderDragon.class, 1, 1, 1));
    87. as.set(iceplains, listas);
    88. au.set(iceplains, listau);
    89. av.set(iceplains, listav);
    90. at.set(iceplains, listat);
    91. } else if (biome.name().equalsIgnoreCase(Biome.STONE_BEACH.name())) {
    92. BiomeStoneBeach biomestonebeach = new BiomeStoneBeach(8);
    93. as.set(biomestonebeach, listas);
    94. au.set(biomestonebeach, listau);
    95. av.set(biomestonebeach, listav);
    96. at.set(biomestonebeach, listat);
    97. } else if (biome.name().equalsIgnoreCase(Biome.MESA.name())) {
    98. BiomeMesa biomemesa;
    99. Constructor<BiomeMesa> biomemesaConstructor;
    100. biomemesaConstructor = BiomeMesa.class.getDeclaredConstructor(int.class, boolean.class, boolean.class);
    101. biomemesaConstructor.setAccessible(true);
    102. biomemesa = biomemesaConstructor.newInstance(21, false, false);
    103. listas.add(new BiomeMeta(EntityZombie.class, 120, 9, 9));
    104. listas.add(new BiomeMeta(EntitySkeleton.class, 50, 9, 9));
    105. listas.add(new BiomeMeta(EntityCreeper.class, 50, 4, 6));
    106. listas.add(new BiomeMeta(EntityPigZombie.class, 50, 9, 9));
    107. listas.add(new BiomeMeta(EntityBlaze.class, 20, 3, 5));
    108. listas.add(new BiomeMeta(EntityGhast.class, 10, 1, 3));
    109. listas.add(new BiomeMeta(EntityEnderDragon.class, 1, 1, 1));
    110. as.set(biomemesa, listas);
    111. au.set(biomemesa, listau);
    112. av.set(biomemesa, listav);
    113. at.set(biomemesa, listat);
    114. } else if (biome.name().equalsIgnoreCase(Biome.MUSHROOM_ISLAND.name())) {
    115. BiomeMushrooms biomeMushrooms = new BiomeMushrooms(8);
    116. listas.add(new BiomeMeta(EntityZombie.class, 120, 2, 4));
    117. listas.add(new BiomeMeta(EntitySkeleton.class, 50, 2, 4));
    118. as.set(biomeMushrooms, listas);
    119. au.set(biomeMushrooms, listau);
    120. av.set(biomeMushrooms, listav);
    121. at.set(biomeMushrooms, listat);
    122. }
    123. } catch (Exception e) {
    124. e.printStackTrace(); // Again, try to handle your errors better
    125. }
    126. } catch (Exception e) {
    127. e.printStackTrace(); // More graceful error handling is recommended
    128. }
    129. }
    130.  
    131. }
    132.  


    There are no printed errors, and the code flow definitely enters the IF blocks for each biome. Maybe there is something I'm missing?

    Thanks in advance! :)
     
  11. Offline

    krazytraynz

    x2nec
    There wasn't too much wrong with your code, but I'll explain what you needed to fix.

    Code:java
    1. BiomeDesert biomedesert;
    2.  
    3. BiomeForest biomeforest;
    4.  
    5. BiomeIcePlains iceplains;
    6. Constructor<BiomeIcePlains> iceplainsConstructor;
    7.  
    8. BiomeJungle jungle;
    9. Constructor<BiomeJungle> jungleConstructor;
    10.  
    11. BiomeMesa biomemesa;
    12. Constructor<BiomeMesa> biomemesaConstructor;
    13.  
    14. BiomeMushrooms biomeMushrooms;
    15.  
    16. BiomeTaiga taiga;
    17. Constructor<BiomeTaiga> taigaConstructor;
    18.  
    19.  
    20. public void addSpawn() {
    21. try {
    22. Field as = net.minecraft.server.v1_7_R1.BiomeBase.class
    23. .getDeclaredField("as");
    24. Field au = net.minecraft.server.v1_7_R1.BiomeBase.class
    25. .getDeclaredField("au");
    26. Field av = net.minecraft.server.v1_7_R1.BiomeBase.class
    27. .getDeclaredField("av");
    28. Field at = net.minecraft.server.v1_7_R1.BiomeBase.class
    29. .getDeclaredField("at");
    30.  
    31. as.setAccessible(true);
    32. au.setAccessible(true);
    33. av.setAccessible(true);
    34. at.setAccessible(true);
    35.  
    36. ArrayList<BiomeMeta> listas = new ArrayList<BiomeMeta>();
    37. ArrayList<BiomeMeta> listau = new ArrayList<BiomeMeta>();
    38. ArrayList<BiomeMeta> listav = new ArrayList<BiomeMeta>();
    39. ArrayList<BiomeMeta> listat = new ArrayList<BiomeMeta>();
    40. try{
    41. jungleConstructor = BiomeJungle.class.getDeclaredConstructor(int.class, boolean.class);
    42. jungleConstructor.setAccessible(true);
    43. jungle = jungleConstructor.newInstance(21, false);
    44.  
    45. listas.add(new BiomeMeta(EntitySkeleton.class, 50, 1, 3));
    46. listas.add(new BiomeMeta(EntityZombie.class, 100, 1, 3));
    47.  
    48. as.set(jungle, listas);
    49. au.set(jungle, listau);
    50. av.set(jungle, listav);
    51. at.set(jungle, listat);
    52.  
    53.  
    54. biomeforest = new BiomeForest(8, 8);
    55.  
    56. listas.add(new BiomeMeta(EntitySkeleton.class, 50, 2, 4));
    57. listas.add(new BiomeMeta(EntityZombie.class, 100, 2, 4));
    58. listat.add(new BiomeMeta(EntityWolf.class, 50, 1, 2));
    59.  
    60. as.set(biomeforest, listas);
    61. au.set(biomeforest, listau);
    62. av.set(biomeforest, listav);
    63. at.set(biomeforest, listat);
    64.  
    65.  
    66. biomedesert = new BiomeDesert(8);
    67.  
    68. listas.add(new BiomeMeta(EntityZombie.class, 100, 4, 6));
    69. listas.add(new BiomeMeta(EntitySkeleton.class, 50, 4, 8));
    70. listas.add(new BiomeMeta(EntityBlaze.class, 5, 1, 3));
    71. listas.add(new BiomeMeta(EntityEnderDragon.class, 1, 1, 1));
    72.  
    73. as.set(biomedesert, listas);
    74. au.set(biomedesert, listau);
    75. av.set(biomedesert, listav);
    76. at.set(biomedesert, listat);
    77.  
    78.  
    79. taigaConstructor = BiomeTaiga.class.getDeclaredConstructor(int.class, int.class);
    80. taigaConstructor.setAccessible(true);
    81.  
    82. taiga = taigaConstructor.newInstance(21, 8);
    83.  
    84. listas.add(new BiomeMeta(EntityZombie.class, 100, 6, 8));
    85. listas.add(new BiomeMeta(EntitySilverfish.class, 20, 6, 9));
    86. listat.add(new BiomeMeta(EntityIronGolem.class, 5, 1, 2));
    87.  
    88. as.set(taiga, listas);
    89. au.set(taiga, listau);
    90. av.set(taiga, listav);
    91. at.set(taiga, listat);
    92.  
    93.  
    94. iceplainsConstructor = BiomeIcePlains.class.getDeclaredConstructor(int.class, boolean.class);
    95. iceplainsConstructor.setAccessible(true);
    96.  
    97. iceplains = iceplainsConstructor.newInstance(21, false);
    98.  
    99. listas.add(new BiomeMeta(EntityZombie.class, 120, 8, 8));
    100. listas.add(new BiomeMeta(EntitySpider.class, 10, 8, 8));
    101. listas.add(new BiomeMeta(EntityEnderDragon.class, 1, 1, 1));
    102.  
    103. as.set(iceplains, listas);
    104. au.set(iceplains, listau);
    105. av.set(iceplains, listav);
    106. at.set(iceplains, listat);
    107.  
    108.  
    109. biomemesaConstructor = BiomeMesa.class.getDeclaredConstructor(int.class, boolean.class, boolean.class);
    110. biomemesaConstructor.setAccessible(true);
    111.  
    112. biomemesa = biomemesaConstructor.newInstance(21, false, false);
    113.  
    114. listas.add(new BiomeMeta(EntityZombie.class, 120, 9, 9));
    115. listas.add(new BiomeMeta(EntitySkeleton.class, 50, 9, 9));
    116. listas.add(new BiomeMeta(EntityCreeper.class, 50, 4, 6));
    117. listas.add(new BiomeMeta(EntityPigZombie.class, 50, 9, 9));
    118. listas.add(new BiomeMeta(EntityBlaze.class, 20, 3, 5));
    119. listas.add(new BiomeMeta(EntityGhast.class, 10, 1, 3));
    120. listas.add(new BiomeMeta(EntityEnderDragon.class, 1, 1, 1));
    121.  
    122. as.set(biomemesa, listas);
    123. au.set(biomemesa, listau);
    124. av.set(biomemesa, listav);
    125. at.set(biomemesa, listat);
    126.  
    127.  
    128. biomeMushrooms = new BiomeMushrooms(8);
    129.  
    130. listas.add(new BiomeMeta(EntityZombie.class, 120, 2, 4));
    131. listas.add(new BiomeMeta(EntitySkeleton.class, 50, 2, 4));
    132.  
    133. as.set(biomeMushrooms, listas);
    134. au.set(biomeMushrooms, listau);
    135. av.set(biomeMushrooms, listav);
    136. at.set(biomeMushrooms, listat);
    137. }catch(Exception e){
    138. e.printStackTrace();
    139. }
    140. } catch (Exception e) {
    141. e.printStackTrace(); // Again, try to handle your errors better
    142. }
    143. }


    1. You don't need the 'if' statements for the biomes, and you don't need Biome as a parameter.
    2. You never did anything with BiomeStoneBeach, so there was really no point to having it there.
    3. Creating the variables outside of the method and instantiating them inside of it can keep it more organized.
     
  12. Offline

    x2nec



    Hmm, okay this is great - I can see something working. However, the spawning is all wrong, I have blazes in wrong biomes (I do clear the lists each time) and the error reported before concerning achievements is genuine. Maybe the biome is no longer recognised?
     
  13. Offline

    Bart

    The only way to remove the error is to use another server software that allows you to disable stat saving entirely.
     
  14. Offline

    krazytraynz


    Weird. Would you mind posting your code again?
     
  15. Offline

    97WaterPolo

    krazytraynz
    Hallo! Last time I used this it was more for fun, but now it might be a core part of my plugin. I was wondering if you could help me fix an error.

    Code:
    12.02 00:27:03 [Server] INFO CONSOLE: Save complete.
    12.02 00:27:03 [Server] INFO java.lang.NullPointerException
    12.02 00:27:03 [Server] WARN Couldn't save statistic TranslatableComponent{key='achievement.exploreAllBiomes', args=[], siblings=[], style=Style{hasParent=false, color=?5, bold=null, italic=null, underlined=null, obfuscated=null, clickEvent=null, hoverEvent=HoverEvent{action=SHOW_ACHIEVEMENT, value='TextComponent{text='achievement.exploreAllBiomes', siblings=[], style=Style{hasParent=false, color=null, bold=null, italic=null, underlined=null, obfuscated=null, clickEvent=null, hoverEvent=null}}'}}}: error serializing progress
    12.02 00:27:03 [Server] INFO java.lang.NullPointerException
    12.02 00:27:03 [Server] WARN Couldn't save statistic TranslatableComponent{key='achievement.exploreAllBiomes', args=[], siblings=[], style=Style{hasParent=false, color=?5, bold=null, italic=null, underlined=null, obfuscated=null, clickEvent=null, hoverEvent=HoverEvent{action=SHOW_ACHIEVEMENT, value='TextComponent{text='achievement.exploreAllBiomes', siblings=[], style=Style{hasParent=false, color=null, bold=null, italic=null, underlined=null, obfuscated=null, clickEvent=null, hoverEvent=null}}'}}}: error serializing progress
    12.02 00:27:03 [Server] INFO CONSOLE: Forcing save..
    12.02 00:27:03 [Server] INFO CONSOLE: Enabled level saving..
    12.02 00:27:03 [Multicraft] Auto-saving world...
     
  16. Offline

    Bart

    I already posted the name once but it got removed. It's made by md_5
     
  17. Offline

    97WaterPolo

    Bart
    Thank you!
     
  18. Offline

    RawCode

    uberprotip that nobody knows due to lack of sourcecode reading skills:

    replace "SpawnerCreature" class embedded with World class with your own implementation and handle spawns completely differently, including variable mob limits and anything else you may like.
     
Thread Status:
Not open for further replies.

Share This Page