From f02900f8401f09b1d031b7fc64502a7500d34bb8 Mon Sep 17 00:00:00 2001 From: Brian Wuest Date: Sun, 28 Jun 2020 08:16:51 -0500 Subject: [PATCH] Adding NBT data for bosses and drops This gives awesome flexability when it comes to the monsters created by the mod. Also updating example fights to show how to drop a totem of summoning as a reward. --- sample_fights/creeper.json | 17 +- sample_fights/slime.json | 31 +++ .../EntityInfo/BaseMonster.java | 25 +- .../EntityInfo/BossAddInfo.java | 3 +- .../from_the_depths/EntityInfo/BossInfo.java | 1 - .../from_the_depths/EntityInfo/DropInfo.java | 255 ++++++++++-------- 6 files changed, 193 insertions(+), 139 deletions(-) create mode 100644 sample_fights/slime.json diff --git a/sample_fights/creeper.json b/sample_fights/creeper.json index 616707d..20406fa 100644 --- a/sample_fights/creeper.json +++ b/sample_fights/creeper.json @@ -8,8 +8,7 @@ "maxHealth": 40, "attackDamage": 10.5, "alwaysShowDisplayName": true, - "additionalDrops": [ - { + "additionalDrops": [{ "item": "minecraft:diamond", "minDrops": 1, "maxDrops": 4, @@ -19,13 +18,23 @@ "item": "minecraft:gold_chestplate", "minDrops": 1, "maxDrops": 1, - "dropChance": 715 + "dropChance": 71 }, { "item": "minecraft:diamond_sword", "minDrops": 1, "maxDrops": 1, "dropChance": 75 + }, + { + "item": "from_the_depths:item_totem_of_summoning", + "minDrops": 1, + "maxDrops": 1, + "dropChance": 100, + "_comment": "Provide a drop for the next monster in a sequence of bosses. This is especially helpful to get players to build up to a mega boss!", + "nbt": { + "spawn_info": "Custom_Skeleton" + } } ] }, @@ -48,4 +57,4 @@ "count": 1 } } -} +} \ No newline at end of file diff --git a/sample_fights/slime.json b/sample_fights/slime.json new file mode 100644 index 0000000..882b7fc --- /dev/null +++ b/sample_fights/slime.json @@ -0,0 +1,31 @@ +{ + "key": "Custom_slime", + "bossInfo": { + "domain": "minecraft", + "name": "slime", + "displayName": "Custom Slime Rawr!", + "maxHealth": 40, + "attackDamage": 10.5, + "alwaysShowDisplayName": true, + "nbt": {"Size": -1 }, + "additionalDrops": [{ + "item": "minecraft:diamond", + "minDrops": 1, + "maxDrops": 4, + "dropChance": 70 + }, + { + "item": "minecraft:gold_chestplate", + "minDrops": 1, + "maxDrops": 1, + "dropChance": 715 + }, + { + "item": "minecraft:diamond_sword", + "minDrops": 1, + "maxDrops": 1, + "dropChance": 75 + } + ] + } +} \ No newline at end of file diff --git a/src/main/java/com/wuest/from_the_depths/EntityInfo/BaseMonster.java b/src/main/java/com/wuest/from_the_depths/EntityInfo/BaseMonster.java index 6dac9e2..36560ea 100644 --- a/src/main/java/com/wuest/from_the_depths/EntityInfo/BaseMonster.java +++ b/src/main/java/com/wuest/from_the_depths/EntityInfo/BaseMonster.java @@ -27,7 +27,6 @@ public abstract class BaseMonster { public ArrayList additionalDrops; public String commandToRunAtSpawn; public JsonObject nbt; - protected NBTTagCompound convertedNBT; public BaseMonster() { this.maxHealth = -1; @@ -95,9 +94,6 @@ public Entity createEntityForWorld(World world, BlockPos pos, ICommandSender com NBTTagCompound entityCompoundTag = entityLiving.getEntityData(); entityCompoundTag.setTag("from_the_depths", trackingTag); - // Serialize the entity NBT data so it can be updated. - NBTTagCompound serializedEntity = entityLiving.serializeNBT(); - entityLiving.forceSpawn = true; entityLiving.rotationYawHead = entityLiving.rotationYaw; entityLiving.renderYawOffset = entityLiving.rotationYaw; @@ -105,21 +101,26 @@ public Entity createEntityForWorld(World world, BlockPos pos, ICommandSender com entityLiving.onInitialSpawn(world.getDifficultyForLocation(new BlockPos(spawnPos)), (IEntityLivingData) null); + // Serialize the entity NBT data so it can be updated. + NBTTagCompound serializedEntity = entityLiving.serializeNBT(); // This has to be after the "onInitialSpawn" call since some monsters will set properties to random values which need to be set specifically. if (this.nbt != null) { + NBTTagCompound compound = null; try { - this.convertedNBT = JsonToNBT.getTagFromJson(this.nbt.toString()); + compound = JsonToNBT.getTagFromJson(this.nbt.toString()); } catch (NBTException exception) { FromTheDepths.logger.error(exception); } - for (String tagKey : this.convertedNBT.getKeySet()) { - serializedEntity.setTag(tagKey, this.convertedNBT.getTag(tagKey)); - } + if (compound != null && !compound.hasNoTags()) { + for (String tagKey : compound.getKeySet()) { + serializedEntity.setTag(tagKey, compound.getTag(tagKey)); + } - entityLiving.readEntityFromNBT(serializedEntity); + entityLiving = (EntityLiving)EntityList.createEntityFromNBT(serializedEntity,world); + } } world.spawnEntity(entityLiving); @@ -272,12 +273,6 @@ public void loadFromNBT(NBTTagCompound tag) { this.commandToRunAtSpawn = tag.getString("commandToRunAtSpawn"); if (tag.hasKey("nbt")) { - try { - this.convertedNBT = JsonToNBT.getTagFromJson(tag.getString("nbt")); - } catch (NBTException exception) { - FromTheDepths.logger.error(exception); - } - JsonParser parser = new JsonParser(); this.nbt = (JsonObject)parser.parse(tag.getString("nbt")); } diff --git a/src/main/java/com/wuest/from_the_depths/EntityInfo/BossAddInfo.java b/src/main/java/com/wuest/from_the_depths/EntityInfo/BossAddInfo.java index 85fd683..d891f19 100644 --- a/src/main/java/com/wuest/from_the_depths/EntityInfo/BossAddInfo.java +++ b/src/main/java/com/wuest/from_the_depths/EntityInfo/BossAddInfo.java @@ -188,7 +188,8 @@ public BossAddInfo clone() { newInstance.numberLeftToSpawn = this.numberLeftToSpawn; newInstance.timeUntilNextSpawn = this.timeUntilNextSpawn; newInstance.commandToRunAtSpawn = this.commandToRunAtSpawn; - + newInstance.nbt = this.nbt; + if (this.nextWaveOfAdds != null) { newInstance.nextWaveOfAdds = this.nextWaveOfAdds.clone(); } diff --git a/src/main/java/com/wuest/from_the_depths/EntityInfo/BossInfo.java b/src/main/java/com/wuest/from_the_depths/EntityInfo/BossInfo.java index 8e70ab6..45f5b1c 100644 --- a/src/main/java/com/wuest/from_the_depths/EntityInfo/BossInfo.java +++ b/src/main/java/com/wuest/from_the_depths/EntityInfo/BossInfo.java @@ -31,7 +31,6 @@ public BossInfo clone() { newInstance.timeToWaitBeforeSpawn = this.timeToWaitBeforeSpawn; newInstance.commandToRunAtSpawn = this.commandToRunAtSpawn; newInstance.nbt = this.nbt; - newInstance.convertedNBT = this.convertedNBT; for (DropInfo info : this.additionalDrops) { newInstance.additionalDrops.add(info.clone()); diff --git a/src/main/java/com/wuest/from_the_depths/EntityInfo/DropInfo.java b/src/main/java/com/wuest/from_the_depths/EntityInfo/DropInfo.java index 58ed95b..f06401e 100644 --- a/src/main/java/com/wuest/from_the_depths/EntityInfo/DropInfo.java +++ b/src/main/java/com/wuest/from_the_depths/EntityInfo/DropInfo.java @@ -1,131 +1,150 @@ package com.wuest.from_the_depths.EntityInfo; -import java.util.Random; - +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; import com.wuest.from_the_depths.FromTheDepths; - import net.minecraft.entity.item.EntityItem; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; +import net.minecraft.nbt.JsonToNBT; +import net.minecraft.nbt.NBTException; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; public class DropInfo implements INBTSerializable { - public String item; - public int minDrops; - public int maxDrops; - public int dropChance; - public int data; - public NBTTagCompound nbt; - - public DropInfo() { - super(); - this.item = ""; - this.minDrops = 0; - this.maxDrops = 0; - this.dropChance = 5; - this.data = 0; - this.nbt = null; - } - - @Override - public void writeToNBT(NBTTagCompound tag) { - tag.setString("item", this.item); - tag.setInteger("minDrops", this.minDrops); - tag.setInteger("maxDrops", this.maxDrops); - tag.setInteger("dropChance", this.dropChance); - tag.setInteger("data", this.data); - - if (this.nbt != null) { - tag.setTag("nbt", this.nbt); - } - } - - @Override - public DropInfo loadFromNBTData(NBTTagCompound nbtData) { - this.item = nbtData.getString("item"); - this.minDrops = nbtData.getInteger("minDrops"); - this.maxDrops = nbtData.getInteger("maxDrops"); - this.dropChance = nbtData.getInteger("dropChance"); - this.data = nbtData.getInteger("data"); - this.nbt = nbtData.getCompoundTag("nbt"); - - if (this.minDrops < 0) { - this.minDrops = 0; - FromTheDepths.logger.warn("Minimum Drops value is less than zero; please check your files. Setting to zero."); - } - - if (this.maxDrops < 0) { - this.maxDrops = 0; - FromTheDepths.logger.warn("Maximum Drops value is less than zero; please check your files. Setting to zero."); - } - - if (this.maxDrops < this.minDrops) { - this.maxDrops = this.minDrops; - FromTheDepths.logger - .warn("Maximum Drops value is less than minimum drops; please check your files. Setting to minimum drops."); - } - - if (this.dropChance < 0) { - this.dropChance = 5; - FromTheDepths.logger.warn("The drop chance is less than zero; please check yoru files. Setting to five."); - } - - if (this.data < 0) { - this.data = 0; - } - - return this; - } - - @Override - public DropInfo clone() { - DropInfo newInstance = new DropInfo(); - - newInstance.item = this.item; - newInstance.minDrops = this.minDrops; - newInstance.maxDrops = this.maxDrops; - newInstance.dropChance = this.dropChance; - newInstance.data = this.data; - newInstance.nbt = this.nbt; - - return newInstance; - } - - public EntityItem createEntityItem(World world, BlockPos pos) { - ResourceLocation itemLocation = new ResourceLocation(this.item); - int randomValue = BaseMonster.determineRandomInt(100, world); - - if (randomValue <= this.dropChance && this.maxDrops > 0) { - // This drop will be created; determine how many to put into a stack. - int amountToDrop; - - if (this.minDrops == this.maxDrops) { - amountToDrop = this.maxDrops; - } else { - amountToDrop = BaseMonster.determineRandomInt(this.maxDrops, world); - - if (amountToDrop <= this.minDrops) { - amountToDrop = this.minDrops; - } - } - - try { - Item registryItem = Item.REGISTRY.getObject(itemLocation); - - if (registryItem != null) { - ItemStack stack = new ItemStack(registryItem, amountToDrop, data); - return new EntityItem(world, pos.getX(), pos.getY(), pos.getZ(), stack); - } - } catch (Exception ex) { - FromTheDepths.logger.warn(String.format( - "An item with registration name [{}] wasn't found. Make sure the domain and item name are spelled correctly. Monster drops not created.", - this.item)); - } - } - - return null; - } + public String item; + public int minDrops; + public int maxDrops; + public int dropChance; + public int data; + public JsonObject nbt; + + public DropInfo() { + super(); + this.item = ""; + this.minDrops = 0; + this.maxDrops = 0; + this.dropChance = 5; + this.data = 0; + this.nbt = null; + } + + @Override + public void writeToNBT(NBTTagCompound tag) { + tag.setString("item", this.item); + tag.setInteger("minDrops", this.minDrops); + tag.setInteger("maxDrops", this.maxDrops); + tag.setInteger("dropChance", this.dropChance); + tag.setInteger("data", this.data); + + if (this.nbt != null) { + tag.setString("nbt", this.nbt.toString()); + } + } + + @Override + public DropInfo loadFromNBTData(NBTTagCompound nbtData) { + this.item = nbtData.getString("item"); + this.minDrops = nbtData.getInteger("minDrops"); + this.maxDrops = nbtData.getInteger("maxDrops"); + this.dropChance = nbtData.getInteger("dropChance"); + this.data = nbtData.getInteger("data"); + + if (nbtData.hasKey("nbt")) { + JsonParser parser = new JsonParser(); + this.nbt = (JsonObject) parser.parse(nbtData.getString("nbt")); + } + + if (this.minDrops < 0) { + this.minDrops = 0; + FromTheDepths.logger.warn("Minimum Drops value is less than zero; please check your files. Setting to zero."); + } + + if (this.maxDrops < 0) { + this.maxDrops = 0; + FromTheDepths.logger.warn("Maximum Drops value is less than zero; please check your files. Setting to zero."); + } + + if (this.maxDrops < this.minDrops) { + this.maxDrops = this.minDrops; + FromTheDepths.logger + .warn("Maximum Drops value is less than minimum drops; please check your files. Setting to minimum drops."); + } + + if (this.dropChance < 0) { + this.dropChance = 5; + FromTheDepths.logger.warn("The drop chance is less than zero; please check yoru files. Setting to five."); + } + + if (this.data < 0) { + this.data = 0; + } + + return this; + } + + @Override + public DropInfo clone() { + DropInfo newInstance = new DropInfo(); + + newInstance.item = this.item; + newInstance.minDrops = this.minDrops; + newInstance.maxDrops = this.maxDrops; + newInstance.dropChance = this.dropChance; + newInstance.data = this.data; + newInstance.nbt = this.nbt; + + return newInstance; + } + + public EntityItem createEntityItem(World world, BlockPos pos) { + ResourceLocation itemLocation = new ResourceLocation(this.item); + int randomValue = BaseMonster.determineRandomInt(100, world); + + if (randomValue <= this.dropChance && this.maxDrops > 0) { + // This drop will be created; determine how many to put into a stack. + int amountToDrop; + + if (this.minDrops == this.maxDrops) { + amountToDrop = this.maxDrops; + } else { + amountToDrop = BaseMonster.determineRandomInt(this.maxDrops, world); + + if (amountToDrop <= this.minDrops) { + amountToDrop = this.minDrops; + } + } + + try { + Item registryItem = Item.REGISTRY.getObject(itemLocation); + + if (registryItem != null) { + ItemStack stack = new ItemStack(registryItem, amountToDrop, data); + + if (this.nbt != null) { + NBTTagCompound compound = null; + try { + compound = JsonToNBT.getTagFromJson(this.nbt.toString()); + } catch (NBTException exception) { + FromTheDepths.logger.error(exception); + } + + if (compound != null && !compound.hasNoTags()) { + stack.setTagCompound(compound); + } + } + + return new EntityItem(world, pos.getX(), pos.getY(), pos.getZ(), stack); + } + } catch (Exception ex) { + FromTheDepths.logger.warn(String.format( + "An item with registration name [{}] wasn't found. Make sure the domain and item name are spelled correctly. Monster drops not created.", + this.item)); + } + } + + return null; + } } \ No newline at end of file