From b6d4e95ec9573857bc3a936a1ab86e2d4c5e3c83 Mon Sep 17 00:00:00 2001 From: George Paton Date: Sat, 1 Feb 2025 19:35:46 +1100 Subject: [PATCH 01/12] bedrock ore grade filters! --- .../com/hbm/inventory/gui/GUIAutocrafter.java | 12 ++------ .../hbm/inventory/gui/GUICounterTorch.java | 12 ++------ .../hbm/inventory/gui/GUICraneExtractor.java | 12 ++------ .../hbm/inventory/gui/GUICraneGrabber.java | 12 ++------ .../com/hbm/inventory/gui/GUICraneRouter.java | 11 +------ .../hbm/inventory/gui/GUIDroneRequester.java | 12 ++------ .../hbm/inventory/gui/GUIMachineCustom.java | 12 ++------ .../com/hbm/module/ModulePatternMatcher.java | 29 +++++++++++++++++-- 8 files changed, 40 insertions(+), 72 deletions(-) diff --git a/src/main/java/com/hbm/inventory/gui/GUIAutocrafter.java b/src/main/java/com/hbm/inventory/gui/GUIAutocrafter.java index 49ed13445..cc26020ab 100644 --- a/src/main/java/com/hbm/inventory/gui/GUIAutocrafter.java +++ b/src/main/java/com/hbm/inventory/gui/GUIAutocrafter.java @@ -7,6 +7,7 @@ import org.lwjgl.opengl.GL11; import com.hbm.interfaces.NotableComments; import com.hbm.inventory.container.ContainerAutocrafter; import com.hbm.lib.RefStrings; +import com.hbm.module.ModulePatternMatcher; import com.hbm.tileentity.machine.TileEntityMachineAutocrafter; import net.minecraft.client.Minecraft; @@ -41,16 +42,7 @@ public class GUIAutocrafter extends GuiInfoContainer { Slot slot = (Slot) this.inventorySlots.inventorySlots.get(i); if(this.isMouseOverSlot(slot, x, y) && diFurnace.matcher.modes[i] != null) { - - String label = EnumChatFormatting.YELLOW + ""; - - switch(diFurnace.matcher.modes[i]) { - case "exact": label += "Item and meta match"; break; - case "wildcard": label += "Item matches"; break; - default: label += "Ore dict key matches: " + diFurnace.matcher.modes[i]; break; - } - - this.func_146283_a(Arrays.asList(new String[] { EnumChatFormatting.RED + "Right click to change", label }), x, y - 30); + this.func_146283_a(Arrays.asList(new String[] { EnumChatFormatting.RED + "Right click to change", ModulePatternMatcher.getLabel(diFurnace.matcher.modes[i]) }), x, y - 30); } } diff --git a/src/main/java/com/hbm/inventory/gui/GUICounterTorch.java b/src/main/java/com/hbm/inventory/gui/GUICounterTorch.java index 6a066a684..8a27e27cf 100644 --- a/src/main/java/com/hbm/inventory/gui/GUICounterTorch.java +++ b/src/main/java/com/hbm/inventory/gui/GUICounterTorch.java @@ -7,6 +7,7 @@ import org.lwjgl.opengl.GL11; import com.hbm.inventory.container.ContainerCounterTorch; import com.hbm.lib.RefStrings; +import com.hbm.module.ModulePatternMatcher; import com.hbm.packet.PacketDispatcher; import com.hbm.packet.toserver.NBTControlPacket; import com.hbm.tileentity.network.TileEntityRadioTorchCounter; @@ -72,16 +73,7 @@ public class GUICounterTorch extends GuiInfoContainer { Slot slot = (Slot) this.inventorySlots.inventorySlots.get(i); if(this.isMouseOverSlot(slot, x, y) && counter.matcher.modes[i] != null) { - - String label = EnumChatFormatting.YELLOW + ""; - - switch(counter.matcher.modes[i]) { - case "exact": label += "Item and meta match"; break; - case "wildcard": label += "Item matches"; break; - default: label += "Ore dict key matches: " + counter.matcher.modes[i]; break; - } - - this.func_146283_a(Arrays.asList(new String[] { EnumChatFormatting.RED + "Right click to change", label }), x, y - 30); + this.func_146283_a(Arrays.asList(new String[] { EnumChatFormatting.RED + "Right click to change", ModulePatternMatcher.getLabel(counter.matcher.modes[i]) }), x, y - 30); } } } diff --git a/src/main/java/com/hbm/inventory/gui/GUICraneExtractor.java b/src/main/java/com/hbm/inventory/gui/GUICraneExtractor.java index 7e8f74ab0..18cd12019 100644 --- a/src/main/java/com/hbm/inventory/gui/GUICraneExtractor.java +++ b/src/main/java/com/hbm/inventory/gui/GUICraneExtractor.java @@ -6,6 +6,7 @@ import org.lwjgl.opengl.GL11; import com.hbm.inventory.container.ContainerCraneExtractor; import com.hbm.lib.RefStrings; +import com.hbm.module.ModulePatternMatcher; import com.hbm.packet.PacketDispatcher; import com.hbm.packet.toserver.NBTControlPacket; import com.hbm.tileentity.network.TileEntityCraneExtractor; @@ -41,16 +42,7 @@ public class GUICraneExtractor extends GuiInfoContainer { Slot slot = (Slot) this.inventorySlots.inventorySlots.get(i); if(this.isMouseOverSlot(slot, x, y) && ejector.matcher.modes[i] != null) { - - String label = EnumChatFormatting.YELLOW + ""; - - switch(ejector.matcher.modes[i]) { - case "exact": label += "Item and meta match"; break; - case "wildcard": label += "Item matches"; break; - default: label += "Ore dict key matches: " + ejector.matcher.modes[i]; break; - } - - this.func_146283_a(Arrays.asList(new String[] { EnumChatFormatting.RED + "Right click to change", label }), x, y - 30); + this.func_146283_a(Arrays.asList(new String[] { EnumChatFormatting.RED + "Right click to change", ModulePatternMatcher.getLabel(ejector.matcher.modes[i]) }), x, y - 30); } } } diff --git a/src/main/java/com/hbm/inventory/gui/GUICraneGrabber.java b/src/main/java/com/hbm/inventory/gui/GUICraneGrabber.java index 6bff412fc..641f7eba9 100644 --- a/src/main/java/com/hbm/inventory/gui/GUICraneGrabber.java +++ b/src/main/java/com/hbm/inventory/gui/GUICraneGrabber.java @@ -6,6 +6,7 @@ import org.lwjgl.opengl.GL11; import com.hbm.inventory.container.ContainerCraneGrabber; import com.hbm.lib.RefStrings; +import com.hbm.module.ModulePatternMatcher; import com.hbm.packet.PacketDispatcher; import com.hbm.packet.toserver.NBTControlPacket; import com.hbm.tileentity.network.TileEntityCraneGrabber; @@ -41,16 +42,7 @@ public class GUICraneGrabber extends GuiInfoContainer { Slot slot = (Slot) this.inventorySlots.inventorySlots.get(i); if(this.isMouseOverSlot(slot, x, y) && grabber.matcher.modes[i] != null) { - - String label = EnumChatFormatting.YELLOW + ""; - - switch(grabber.matcher.modes[i]) { - case "exact": label += "Item and meta match"; break; - case "wildcard": label += "Item matches"; break; - default: label += "Ore dict key matches: " + grabber.matcher.modes[i]; break; - } - - this.func_146283_a(Arrays.asList(new String[] { EnumChatFormatting.RED + "Right click to change", label }), x, y - 30); + this.func_146283_a(Arrays.asList(new String[] { EnumChatFormatting.RED + "Right click to change", ModulePatternMatcher.getLabel(grabber.matcher.modes[i]) }), x, y - 30); } } } diff --git a/src/main/java/com/hbm/inventory/gui/GUICraneRouter.java b/src/main/java/com/hbm/inventory/gui/GUICraneRouter.java index 77798355b..55b2648b5 100644 --- a/src/main/java/com/hbm/inventory/gui/GUICraneRouter.java +++ b/src/main/java/com/hbm/inventory/gui/GUICraneRouter.java @@ -83,16 +83,7 @@ public class GUICraneRouter extends GuiInfoContainer { int index = i % 5; if(this.isMouseOverSlot(slot, x, y) && matcher.modes[index] != null) { - - String label = EnumChatFormatting.YELLOW + ""; - - switch(matcher.modes[index]) { - case "exact": label += "Item and meta match"; break; - case "wildcard": label += "Item matches"; break; - default: label += "Ore dict key matches: " + matcher.modes[index]; break; - } - - this.func_146283_a(Arrays.asList(new String[] { EnumChatFormatting.RED + "Right click to change", label}), x, y - 30); + this.func_146283_a(Arrays.asList(new String[] { EnumChatFormatting.RED + "Right click to change", ModulePatternMatcher.getLabel(matcher.modes[i])}), x, y - 30); } } } diff --git a/src/main/java/com/hbm/inventory/gui/GUIDroneRequester.java b/src/main/java/com/hbm/inventory/gui/GUIDroneRequester.java index 4fec012e5..9010e1ce6 100644 --- a/src/main/java/com/hbm/inventory/gui/GUIDroneRequester.java +++ b/src/main/java/com/hbm/inventory/gui/GUIDroneRequester.java @@ -6,6 +6,7 @@ import org.lwjgl.opengl.GL11; import com.hbm.inventory.container.ContainerDroneRequester; import com.hbm.lib.RefStrings; +import com.hbm.module.ModulePatternMatcher; import com.hbm.tileentity.network.TileEntityDroneRequester; import net.minecraft.client.Minecraft; @@ -37,16 +38,7 @@ public class GUIDroneRequester extends GuiInfoContainer { Slot slot = (Slot) this.inventorySlots.inventorySlots.get(i); if(this.isMouseOverSlot(slot, x, y) && diFurnace.matcher.modes[i] != null) { - - String label = EnumChatFormatting.YELLOW + ""; - - switch(diFurnace.matcher.modes[i]) { - case "exact": label += "Item and meta match"; break; - case "wildcard": label += "Item matches"; break; - default: label += "Ore dict key matches: " + diFurnace.matcher.modes[i]; break; - } - - this.func_146283_a(Arrays.asList(new String[] { EnumChatFormatting.RED + "Right click to change", label }), x, y - 30); + this.func_146283_a(Arrays.asList(new String[] { EnumChatFormatting.RED + "Right click to change", ModulePatternMatcher.getLabel(diFurnace.matcher.modes[i]) }), x, y - 30); } } } diff --git a/src/main/java/com/hbm/inventory/gui/GUIMachineCustom.java b/src/main/java/com/hbm/inventory/gui/GUIMachineCustom.java index 2a02cd763..d106f3717 100644 --- a/src/main/java/com/hbm/inventory/gui/GUIMachineCustom.java +++ b/src/main/java/com/hbm/inventory/gui/GUIMachineCustom.java @@ -10,6 +10,7 @@ import com.hbm.inventory.SlotPattern; import com.hbm.inventory.container.ContainerMachineCustom; import com.hbm.lib.RefStrings; import com.hbm.main.MainRegistry; +import com.hbm.module.ModulePatternMatcher; import com.hbm.tileentity.machine.TileEntityCustomMachine; import net.minecraft.client.Minecraft; @@ -44,16 +45,7 @@ public class GUIMachineCustom extends GuiInfoContainer { int tileIndex = slot.getSlotIndex(); if(this.isMouseOverSlot(slot, x, y) && slot instanceof SlotPattern && custom.matcher.modes[tileIndex - 10] != null) { - - String label = EnumChatFormatting.YELLOW + ""; - - switch(custom.matcher.modes[tileIndex - 10]) { - case "exact": label += "Item and meta match"; break; - case "wildcard": label += "Item matches"; break; - default: label += "Ore dict key matches: " + custom.matcher.modes[tileIndex - 10]; break; - } - - this.func_146283_a(Arrays.asList(new String[] { EnumChatFormatting.RED + "Right click to change", label }), x, y - 30); + this.func_146283_a(Arrays.asList(new String[] { EnumChatFormatting.RED + "Right click to change", ModulePatternMatcher.getLabel(custom.matcher.modes[tileIndex - 10]) }), x, y - 30); } } } diff --git a/src/main/java/com/hbm/module/ModulePatternMatcher.java b/src/main/java/com/hbm/module/ModulePatternMatcher.java index 279a2c1e9..61c7e245c 100644 --- a/src/main/java/com/hbm/module/ModulePatternMatcher.java +++ b/src/main/java/com/hbm/module/ModulePatternMatcher.java @@ -2,18 +2,21 @@ package com.hbm.module; import java.util.List; +import com.hbm.items.special.ItemBedrockOreNew; import com.hbm.util.BufferUtil; import com.hbm.util.ItemStackUtil; import io.netty.buffer.ByteBuf; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.EnumChatFormatting; import net.minecraft.world.World; public class ModulePatternMatcher { public static final String MODE_EXACT = "exact"; public static final String MODE_WILDCARD = "wildcard"; + public static final String MODE_BEDROCK = "bedrock"; public String[] modes; public ModulePatternMatcher() { @@ -68,8 +71,10 @@ public class ModulePatternMatcher { modes[i] = null; return; } - - if(stack.getHasSubtypes()) { + + if(stack.getItem() instanceof ItemBedrockOreNew) { + modes[i] = MODE_BEDROCK; + } else if(stack.getHasSubtypes()) { modes[i] = MODE_EXACT; } else { modes[i] = MODE_WILDCARD; @@ -88,6 +93,12 @@ public class ModulePatternMatcher { if(modes[i] == null) { modes[i] = MODE_EXACT; } else if(MODE_EXACT.equals(modes[i])) { + if(pattern.getItem() instanceof ItemBedrockOreNew) { + modes[i] = MODE_BEDROCK; + } else { + modes[i] = MODE_WILDCARD; + } + } else if(MODE_BEDROCK.equals(modes[i])) { modes[i] = MODE_WILDCARD; } else if(MODE_WILDCARD.equals(modes[i])) { @@ -128,6 +139,10 @@ public class ModulePatternMatcher { switch(mode) { case MODE_EXACT: return input.isItemEqual(filter) && ItemStack.areItemStackTagsEqual(input, filter); case MODE_WILDCARD: return input.getItem() == filter.getItem() && ItemStack.areItemStackTagsEqual(input, filter); + case MODE_BEDROCK: + if(input.getItem() != filter.getItem()) return false; + if(!(input.getItem() instanceof ItemBedrockOreNew)) return false; + return ((ItemBedrockOreNew)input.getItem()).getGrade(input.getItemDamage()) == ((ItemBedrockOreNew)filter.getItem()).getGrade(filter.getItemDamage()); default: List keys = ItemStackUtil.getOreDictNames(input); return keys.contains(mode); @@ -165,4 +180,14 @@ public class ModulePatternMatcher { modes[i] = BufferUtil.readString(buf); } } + + public static String getLabel(String mode) { + switch(mode) { + case MODE_EXACT: return EnumChatFormatting.YELLOW + "Item and meta match"; + case MODE_WILDCARD: return EnumChatFormatting.YELLOW + "Item matches"; + case MODE_BEDROCK: return EnumChatFormatting.YELLOW + "Item and bedrock grade match"; + default: return EnumChatFormatting.YELLOW + "Ore dict key matches: " + mode; + } + } + } From c4e973dc0301b1d2097216cfb35195560007ee9a Mon Sep 17 00:00:00 2001 From: George Paton Date: Sat, 1 Feb 2025 20:00:24 +1100 Subject: [PATCH 02/12] oops: fix sorter filter crash --- src/main/java/com/hbm/inventory/gui/GUICraneRouter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/hbm/inventory/gui/GUICraneRouter.java b/src/main/java/com/hbm/inventory/gui/GUICraneRouter.java index 55b2648b5..657a09736 100644 --- a/src/main/java/com/hbm/inventory/gui/GUICraneRouter.java +++ b/src/main/java/com/hbm/inventory/gui/GUICraneRouter.java @@ -83,7 +83,7 @@ public class GUICraneRouter extends GuiInfoContainer { int index = i % 5; if(this.isMouseOverSlot(slot, x, y) && matcher.modes[index] != null) { - this.func_146283_a(Arrays.asList(new String[] { EnumChatFormatting.RED + "Right click to change", ModulePatternMatcher.getLabel(matcher.modes[i])}), x, y - 30); + this.func_146283_a(Arrays.asList(new String[] { EnumChatFormatting.RED + "Right click to change", ModulePatternMatcher.getLabel(matcher.modes[index])}), x, y - 30); } } } From 6d920ce91dbeae01921bcd9ae8d84f8fc0ba0e36 Mon Sep 17 00:00:00 2001 From: George Paton Date: Sat, 1 Feb 2025 20:02:21 +1100 Subject: [PATCH 03/12] sorters default to bedrock sorting now too --- src/main/java/com/hbm/module/ModulePatternMatcher.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/hbm/module/ModulePatternMatcher.java b/src/main/java/com/hbm/module/ModulePatternMatcher.java index 61c7e245c..ecde925fa 100644 --- a/src/main/java/com/hbm/module/ModulePatternMatcher.java +++ b/src/main/java/com/hbm/module/ModulePatternMatcher.java @@ -44,7 +44,9 @@ public class ModulePatternMatcher { if(iterateAndCheck(names, i ,"nugget")) return; if(iterateAndCheck(names, i ,"plate")) return; - if(stack.getHasSubtypes()) { + if(stack.getItem() instanceof ItemBedrockOreNew) { + modes[i] = MODE_BEDROCK; + } else if(stack.getHasSubtypes()) { modes[i] = MODE_EXACT; } else { modes[i] = MODE_WILDCARD; From 18af9680735259c29d286c9dd1895b7a452a9402 Mon Sep 17 00:00:00 2001 From: George Paton Date: Sat, 1 Feb 2025 20:21:46 +1100 Subject: [PATCH 04/12] updated boble --- .../com/hbm/blocks/generic/BlockBobble.java | 2 +- .../hbm/render/tileentity/RenderBobble.java | 21 ++++++++++++------ .../models/trinkets/mellowrpg8_glow.png | Bin 0 -> 14747 bytes 3 files changed, 15 insertions(+), 8 deletions(-) create mode 100644 src/main/resources/assets/hbm/textures/models/trinkets/mellowrpg8_glow.png diff --git a/src/main/java/com/hbm/blocks/generic/BlockBobble.java b/src/main/java/com/hbm/blocks/generic/BlockBobble.java index 5e5226e6f..df5d158ea 100644 --- a/src/main/java/com/hbm/blocks/generic/BlockBobble.java +++ b/src/main/java/com/hbm/blocks/generic/BlockBobble.java @@ -200,7 +200,7 @@ public class BlockBobble extends BlockContainer implements IGUIProvider { CIRNO( "Cirno", "Cirno", "the only multi layered skin i had", "No brain. Head empty.", true, ScrapType.BOARD_BLANK), MICROWAVE( "Microwave", "Microwave", "OC Compatibility and massive RBMK/packet optimizations", "they call me the food heater$john optimization", true, ScrapType.BOARD_CONVERTER), PEEP( "Peep", "LePeeperSauvage", "Coilgun, Leadburster and Congo Lake models, BDCL QC", "Fluffy ears can't hide in ash, nor snow.", true, ScrapType.CARD_BOARD), - MELLOW( "MELLOWARPEGGIATION", "Mellow", "Industrial lighting, animation tools", "Make something cool now, ask for permission later.", true, ScrapType.CARD_PROCESSOR); + MELLOW( "MELLOWARPEGGIATION", "Mellow", "NBT Structures, industrial lighting, animation tools", "Make something cool now, ask for permission later.", true, ScrapType.CARD_PROCESSOR); public String name; //the title of the tooltip public String label; //the name engraved in the socket diff --git a/src/main/java/com/hbm/render/tileentity/RenderBobble.java b/src/main/java/com/hbm/render/tileentity/RenderBobble.java index d5039e39b..08dfa1283 100644 --- a/src/main/java/com/hbm/render/tileentity/RenderBobble.java +++ b/src/main/java/com/hbm/render/tileentity/RenderBobble.java @@ -49,9 +49,14 @@ public class RenderBobble extends TileEntitySpecialRenderer { public static final ResourceLocation bobble_microwave = new ResourceLocation(RefStrings.MODID, "textures/models/trinkets/microwave.png"); public static final ResourceLocation bobble_peep = new ResourceLocation(RefStrings.MODID, "textures/models/trinkets/peep.png"); public static final ResourceLocation bobble_mellow = new ResourceLocation(RefStrings.MODID, "textures/models/trinkets/mellowrpg8.png"); + public static final ResourceLocation bobble_mellow_glow = new ResourceLocation(RefStrings.MODID, "textures/models/trinkets/mellowrpg8_glow.png"); + + private long time; @Override public void renderTileEntityAt(TileEntity tile, double x, double y, double z, float intero) { + time = System.currentTimeMillis(); + GL11.glPushMatrix(); GL11.glTranslated(x + 0.5, y, z + 0.5); @@ -288,8 +293,8 @@ public class RenderBobble extends TileEntitySpecialRenderer { GL11.glPushMatrix(); GL11.glTranslated(0, 1.75, 0); - GL11.glRotated(Math.sin(System.currentTimeMillis() * speed) * amplitude, 1, 0, 0); - GL11.glRotated(Math.sin(System.currentTimeMillis() * speed + (Math.PI * 0.5)) * amplitude, 0, 0, 1); + GL11.glRotated(Math.sin(time * speed) * amplitude, 1, 0, 0); + GL11.glRotated(Math.sin(time * speed + (Math.PI * 0.5)) * amplitude, 0, 0, 1); GL11.glRotated(rotHead[0], 1, 0, 0); GL11.glRotated(rotHead[1], 0, 1, 0); @@ -342,7 +347,7 @@ public class RenderBobble extends TileEntitySpecialRenderer { GL11.glAlphaFunc(GL11.GL_GREATER, 0); OpenGlHelper.glBlendFunc(770, 771, 1, 0); - GL11.glColor4f(1.0F, 1.0F, 0.0F, 0.1F + (float) Math.sin(System.currentTimeMillis() * 0.001D) * 0.05F); + GL11.glColor4f(1.0F, 1.0F, 0.0F, 0.1F + (float) Math.sin(time * 0.001D) * 0.05F); bobble.renderPart("PelletShine"); GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); @@ -365,8 +370,8 @@ public class RenderBobble extends TileEntitySpecialRenderer { GL11.glPushMatrix(); GL11.glTranslated(0, 0.75, 0); - GL11.glRotated(Math.sin(System.currentTimeMillis() * speed) * amplitude, 1, 0, 0); - GL11.glRotated(Math.sin(System.currentTimeMillis() * speed + (Math.PI * 0.5)) * amplitude, 0, 0, 1); + GL11.glRotated(Math.sin(time * speed) * amplitude, 1, 0, 0); + GL11.glRotated(Math.sin(time * speed + (Math.PI * 0.5)) * amplitude, 0, 0, 1); GL11.glTranslated(0, -0.75, 0); GL11.glDisable(GL11.GL_CULL_FACE); @@ -452,11 +457,13 @@ public class RenderBobble extends TileEntitySpecialRenderer { //shotgun.renderDud(0.0625F); break; case MELLOW: + GL11.glPushAttrib(GL11.GL_LIGHTING_BIT); + OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240F, 240F); + bindTexture(bobble_mellow_glow); + renderGuy(type); GL11.glEnable(GL11.GL_BLEND); GL11.glAlphaFunc(GL11.GL_GREATER, 0); GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE); - GL11.glPushAttrib(GL11.GL_LIGHTING_BIT); - OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240F, 240F); this.bindTexture(lamp); bobble.renderPart("Fluoro"); this.bindTexture(glow); diff --git a/src/main/resources/assets/hbm/textures/models/trinkets/mellowrpg8_glow.png b/src/main/resources/assets/hbm/textures/models/trinkets/mellowrpg8_glow.png new file mode 100644 index 0000000000000000000000000000000000000000..84a06adcf3a4d212c961a9546487bee719b017ff GIT binary patch literal 14747 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 PCxE=Pid3b9+1vjEzlDNY literal 0 HcmV?d00001 From a581cb74d0b6ba6eda7ce8aa62fdc9f3cf1ede09 Mon Sep 17 00:00:00 2001 From: George Paton Date: Mon, 3 Feb 2025 10:38:47 +1100 Subject: [PATCH 05/12] Refueling Station! Refuels armor, attached armor mods, and any held items! Now Black Mesa themed! --- src/main/java/com/hbm/blocks/ModBlocks.java | 3 + .../com/hbm/blocks/machine/BlockRefueler.java | 101 ++ src/main/java/com/hbm/main/ClientProxy.java | 17 + .../java/com/hbm/main/CraftingManager.java | 2 + .../java/com/hbm/main/ResourceManager.java | 2 + .../hbm/render/tileentity/RenderRefueler.java | 103 ++ .../java/com/hbm/tileentity/TileMappings.java | 1 + .../machine/TileEntityRefueler.java | 157 +++ src/main/resources/assets/hbm/lang/en_US.lang | 1 + .../assets/hbm/models/blocks/refueler.obj | 1100 +++++++++++++++++ .../hbm/textures/models/machines/refueler.png | Bin 0 -> 4920 bytes 11 files changed, 1487 insertions(+) create mode 100644 src/main/java/com/hbm/blocks/machine/BlockRefueler.java create mode 100644 src/main/java/com/hbm/render/tileentity/RenderRefueler.java create mode 100644 src/main/java/com/hbm/tileentity/machine/TileEntityRefueler.java create mode 100644 src/main/resources/assets/hbm/models/blocks/refueler.obj create mode 100644 src/main/resources/assets/hbm/textures/models/machines/refueler.png diff --git a/src/main/java/com/hbm/blocks/ModBlocks.java b/src/main/java/com/hbm/blocks/ModBlocks.java index c428d8ae0..c80573666 100644 --- a/src/main/java/com/hbm/blocks/ModBlocks.java +++ b/src/main/java/com/hbm/blocks/ModBlocks.java @@ -603,6 +603,7 @@ public class ModBlocks { public static Block spikes; public static Block charger; + public static Block refueler; public static Block tesla; @@ -2068,6 +2069,7 @@ public class ModBlocks { spikes = new Spikes(Material.iron).setBlockName("spikes").setHardness(2.5F).setResistance(5.0F).setCreativeTab(MainRegistry.blockTab).setBlockTextureName(RefStrings.MODID + ":spikes"); charger = new Charger(Material.iron).setBlockName("charger").setHardness(5.0F).setResistance(10.0F).setCreativeTab(MainRegistry.blockTab).setBlockTextureName(RefStrings.MODID + ":block_steel"); + refueler = new BlockRefueler(Material.iron).setBlockName("refueler").setHardness(5.0F).setResistance(10.0F).setCreativeTab(MainRegistry.blockTab).setBlockTextureName(RefStrings.MODID + ":block_steel"); tesla = new MachineTesla(Material.iron).setBlockName("tesla").setHardness(5.0F).setResistance(10.0F).setCreativeTab(MainRegistry.blockTab).setBlockTextureName(RefStrings.MODID + ":tesla"); @@ -2709,6 +2711,7 @@ public class ModBlocks { //Charger GameRegistry.registerBlock(charger, charger.getUnlocalizedName()); + GameRegistry.registerBlock(refueler, refueler.getUnlocalizedName()); //GameRegistry.registerBlock(floodlight, floodlight.getUnlocalizedName()); //Decoration Blocks diff --git a/src/main/java/com/hbm/blocks/machine/BlockRefueler.java b/src/main/java/com/hbm/blocks/machine/BlockRefueler.java new file mode 100644 index 000000000..543e8963d --- /dev/null +++ b/src/main/java/com/hbm/blocks/machine/BlockRefueler.java @@ -0,0 +1,101 @@ +package com.hbm.blocks.machine; + +import com.hbm.inventory.fluid.FluidType; +import com.hbm.items.machine.IItemFluidIdentifier; +import com.hbm.tileentity.machine.TileEntityRefueler; + +import net.minecraft.block.BlockContainer; +import net.minecraft.block.material.Material; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.AxisAlignedBB; +import net.minecraft.util.ChatComponentText; +import net.minecraft.util.ChatComponentTranslation; +import net.minecraft.util.ChatStyle; +import net.minecraft.util.EnumChatFormatting; +import net.minecraft.util.MathHelper; +import net.minecraft.world.IBlockAccess; +import net.minecraft.world.World; + +public class BlockRefueler extends BlockContainer { + + public BlockRefueler(Material mat) { + super(mat); + } + + @Override + public TileEntity createNewTileEntity(World world, int meta) { + return new TileEntityRefueler(); + } + + @Override + public int getRenderType() { + return -1; + } + + @Override + public boolean isOpaqueCube() { + return false; + } + + @Override + public boolean renderAsNormalBlock() { + return false; + } + + @Override + public boolean onBlockActivated(World world, int x, int y, int z, EntityPlayer player, int side, float hitX, float hitY, float hitZ) { + if(!world.isRemote && !player.isSneaking()) { + if(player.getHeldItem() != null && player.getHeldItem().getItem() instanceof IItemFluidIdentifier) { + TileEntity te = world.getTileEntity(x, y, z); + + if(!(te instanceof TileEntityRefueler)) + return false; + + TileEntityRefueler refueler = (TileEntityRefueler) te; + FluidType type = ((IItemFluidIdentifier) player.getHeldItem().getItem()).getType(world, x, y, z, player.getHeldItem()); + refueler.tank.setTankType(type); + refueler.markDirty(); + player.addChatComponentMessage(new ChatComponentText("Changed type to ").setChatStyle(new ChatStyle().setColor(EnumChatFormatting.YELLOW)).appendSibling(new ChatComponentTranslation(type.getConditionalName())).appendSibling(new ChatComponentText("!"))); + + return true; + } + + return false; + } else { + return true; + } + } + + @Override + public void onBlockPlacedBy(World world, int x, int y, int z, EntityLivingBase player, ItemStack stack) { + int i = MathHelper.floor_double(player.rotationYaw * 4.0F / 360.0F + 0.5D) & 3; + + if(i == 0) world.setBlockMetadataWithNotify(x, y, z, 2, 2); + if(i == 1) world.setBlockMetadataWithNotify(x, y, z, 5, 2); + if(i == 2) world.setBlockMetadataWithNotify(x, y, z, 3, 2); + if(i == 3) world.setBlockMetadataWithNotify(x, y, z, 4, 2); + } + + @Override + public void setBlockBoundsBasedOnState(IBlockAccess world, int x, int y, int z) { + float f = 0.0625F; + + switch(world.getBlockMetadata(x, y, z)) { + case 2: this.setBlockBounds(0F, 0F, 12 * f, 1F, 1F, 1F); break; + case 3: this.setBlockBounds(0F, 0F, 0F, 1F, 1F, 4 * f); break; + case 4: this.setBlockBounds(12 * f, 0F, 0F, 1F, 1F, 1F); break; + case 5: this.setBlockBounds(0F, 0F, 0F, 4 * f, 1F, 1F); break; + default: this.setBlockBounds(0F, 0F, 0F, 1F, 1F, 1F); break; + } + } + + @Override + public AxisAlignedBB getCollisionBoundingBoxFromPool(World world, int x, int y, int z) { + this.setBlockBoundsBasedOnState(world, x, y, z); + return AxisAlignedBB.getBoundingBox(x + this.minX, y + this.minY, z + this.minZ, x + this.maxX, y + this.maxY, z + this.maxZ); + } + +} diff --git a/src/main/java/com/hbm/main/ClientProxy.java b/src/main/java/com/hbm/main/ClientProxy.java index 04feaf810..95534ecbc 100644 --- a/src/main/java/com/hbm/main/ClientProxy.java +++ b/src/main/java/com/hbm/main/ClientProxy.java @@ -376,6 +376,7 @@ public class ClientProxy extends ServerProxy { ClientRegistry.bindTileEntitySpecialRenderer(TileEntitySubstation.class, new RenderSubstation()); //chargers ClientRegistry.bindTileEntitySpecialRenderer(TileEntityCharger.class, new RenderCharger()); + ClientRegistry.bindTileEntitySpecialRenderer(TileEntityRefueler.class, new RenderRefueler()); //DecoContainer ClientRegistry.bindTileEntitySpecialRenderer(TileEntityFileCabinet.class, new RenderFileCabinet()); //multiblocks @@ -1725,6 +1726,22 @@ public class ClientProxy extends ServerProxy { } } + if("fluidfill".equals(type)) { + double mX = data.getDouble("mX"); + double mY = data.getDouble("mY"); + double mZ = data.getDouble("mZ"); + + EntityFX fx = new net.minecraft.client.particle.EntityCritFX(world, x, y, z, mX, mY, mZ); + fx.nextTextureIndexX(); + + if(data.hasKey("color")) { + Color color = new Color(data.getInteger("color")); + fx.setRBGColorF(color.getRed() / 255F, color.getGreen() / 255F, color.getBlue() / 255F); + } + + Minecraft.getMinecraft().effectRenderer.addEffect(fx); + } + if("deadleaf".equals(type)) { if(particleSetting == 0 || (particleSetting == 1 && rand.nextBoolean())) Minecraft.getMinecraft().effectRenderer.addEffect(new ParticleDeadLeaf(man, world, x, y, z)); diff --git a/src/main/java/com/hbm/main/CraftingManager.java b/src/main/java/com/hbm/main/CraftingManager.java index 7b59c3c46..aec7ef876 100644 --- a/src/main/java/com/hbm/main/CraftingManager.java +++ b/src/main/java/com/hbm/main/CraftingManager.java @@ -11,6 +11,7 @@ import com.hbm.config.GeneralConfig; import com.hbm.crafting.*; import com.hbm.crafting.handlers.*; import com.hbm.inventory.OreDictManager; +import com.hbm.inventory.OreDictManager.DictFrame; import com.hbm.inventory.fluid.Fluids; import com.hbm.inventory.material.MaterialShapes; import com.hbm.inventory.material.Mats; @@ -913,6 +914,7 @@ public class CraftingManager { addRecipeAuto(new ItemStack(ModBlocks.charger), new Object[] { "G", "S", "C", 'G', Items.glowstone_dust, 'S', STEEL.ingot(), 'C', ModItems.coil_copper }); addRecipeAuto(new ItemStack(ModBlocks.charger, 16), new Object[] { "G", "S", "C", 'G', Blocks.glowstone, 'S', STEEL.block(), 'C', ModItems.coil_copper_torus }); + addRecipeAuto(new ItemStack(ModBlocks.refueler), new Object[] { "SS", "HC", "SS", 'S', TI.plate(), 'H', DictFrame.fromOne(ModItems.part_generic, EnumPartType.PISTON_HYDRAULIC), 'C', DictFrame.fromOne(ModItems.circuit, EnumCircuitType.BASIC) }); addRecipeAuto(new ItemStack(ModBlocks.press_preheater), new Object[] { "CCC", "SLS", "TST", 'C', CU.plate(), 'S', Blocks.stone, 'L', Fluids.LAVA.getDict(1000), 'T', W.ingot() }); addRecipeAuto(new ItemStack(ModItems.fluid_identifier_multi), new Object[] { "D", "C", "P", 'D', "dye", 'C', DictFrame.fromOne(ModItems.circuit, EnumCircuitType.ANALOG), 'P', IRON.plate() }); diff --git a/src/main/java/com/hbm/main/ResourceManager.java b/src/main/java/com/hbm/main/ResourceManager.java index 010e5e9bf..f21340455 100644 --- a/src/main/java/com/hbm/main/ResourceManager.java +++ b/src/main/java/com/hbm/main/ResourceManager.java @@ -391,6 +391,7 @@ public class ResourceManager { //Charging Station public static final IModelCustom charger = new HFRWavefrontObject(new ResourceLocation(RefStrings.MODID, "models/blocks/charger.obj")); + public static final IModelCustom refueler = new HFRWavefrontObject(new ResourceLocation(RefStrings.MODID, "models/blocks/refueler.obj")); //DecoContainer (File Cabinet for now) public static final IModelCustom file_cabinet = AdvancedModelLoader.loadModel(new ResourceLocation(RefStrings.MODID, "models/file_cabinet.obj")); @@ -805,6 +806,7 @@ public class ResourceManager { //Charger public static final ResourceLocation charger_tex = new ResourceLocation(RefStrings.MODID, "textures/models/machines/charger.png"); + public static final ResourceLocation refueler_tex = new ResourceLocation(RefStrings.MODID, "textures/models/machines/refueler.png"); //DecoContainer public static final ResourceLocation file_cabinet_tex = new ResourceLocation(RefStrings.MODID, "textures/models/file_cabinet.png"); diff --git a/src/main/java/com/hbm/render/tileentity/RenderRefueler.java b/src/main/java/com/hbm/render/tileentity/RenderRefueler.java new file mode 100644 index 000000000..b8c30a352 --- /dev/null +++ b/src/main/java/com/hbm/render/tileentity/RenderRefueler.java @@ -0,0 +1,103 @@ +package com.hbm.render.tileentity; + +import java.awt.Color; +import java.nio.DoubleBuffer; + +import org.lwjgl.opengl.GL11; + +import com.hbm.blocks.ModBlocks; +import com.hbm.main.ResourceManager; +import com.hbm.render.item.ItemRenderBase; +import com.hbm.tileentity.machine.TileEntityRefueler; + +import net.minecraft.client.renderer.GLAllocation; +import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer; +import net.minecraft.item.Item; +import net.minecraft.tileentity.TileEntity; +import net.minecraftforge.client.IItemRenderer; + +public class RenderRefueler extends TileEntitySpecialRenderer implements IItemRendererProvider { + + private static DoubleBuffer clip = null; + + @Override + public void renderTileEntityAt(TileEntity tile, double x, double y, double z, float interp) { + TileEntityRefueler refueler = (TileEntityRefueler) tile; + + GL11.glPushMatrix(); + { + + GL11.glTranslated(x + 0.5, y, z + 0.5); + GL11.glEnable(GL11.GL_LIGHTING); + GL11.glEnable(GL11.GL_CULL_FACE); + GL11.glRotatef(90, 0F, 1F, 0F); + switch(tile.getBlockMetadata()) { + case 4: GL11.glRotatef(90, 0F, 1F, 0F); break; + case 3: GL11.glRotatef(180, 0F, 1F, 0F); break; + case 5: GL11.glRotatef(270, 0F, 1F, 0F); break; + case 2: GL11.glRotatef(0, 0F, 1F, 0F); break; + } + + GL11.glShadeModel(GL11.GL_SMOOTH); + + bindTexture(ResourceManager.refueler_tex); + ResourceManager.refueler.renderPart("Fueler"); + + + if(clip == null) { + clip = GLAllocation.createDirectByteBuffer(8*4).asDoubleBuffer(); + clip.put(new double[] {0, 1, 0, -0.125 }); + clip.rewind(); + } + + GL11.glEnable(GL11.GL_CLIP_PLANE0); + GL11.glClipPlane(GL11.GL_CLIP_PLANE0, clip); + + GL11.glEnable(GL11.GL_BLEND); + GL11.glDisable(GL11.GL_TEXTURE_2D); + + GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE); + + double fillLevel = refueler.prevFillLevel + (refueler.fillLevel - refueler.prevFillLevel) * interp; + GL11.glTranslated(0, (1 - fillLevel) * -0.625, 0); + + Color color = new Color(refueler.tank.getTankType().getColor()); + GL11.glColor4f(color.getRed() / 255F, color.getGreen() / 255F, color.getBlue() / 255F, 0.75F); + ResourceManager.refueler.renderPart("Fluid"); + GL11.glColor4f(1, 1, 1, 1); + + GL11.glEnable(GL11.GL_TEXTURE_2D); + GL11.glDisable(GL11.GL_BLEND); + + GL11.glDisable(GL11.GL_CLIP_PLANE0); + + GL11.glShadeModel(GL11.GL_FLAT); + + } + GL11.glPopMatrix(); + } + + @Override + public Item getItemForRenderer() { + return Item.getItemFromBlock(ModBlocks.refueler); + } + + @Override + public IItemRenderer getRenderer() { + return new ItemRenderBase() { + public void renderInventory() { + GL11.glTranslated(0, -3, 0); + GL11.glScaled(6, 6, 6); + } + public void renderCommon() { + GL11.glScaled(2, 2, 2); + GL11.glTranslated(0.5, 0, 0); + GL11.glShadeModel(GL11.GL_SMOOTH); + bindTexture(ResourceManager.refueler_tex); + ResourceManager.refueler.renderPart("Fueler"); + GL11.glShadeModel(GL11.GL_FLAT); + } + }; + } + +} diff --git a/src/main/java/com/hbm/tileentity/TileMappings.java b/src/main/java/com/hbm/tileentity/TileMappings.java index f2c4a50c0..12257b52e 100644 --- a/src/main/java/com/hbm/tileentity/TileMappings.java +++ b/src/main/java/com/hbm/tileentity/TileMappings.java @@ -217,6 +217,7 @@ public class TileMappings { put(TileEntityDoorGeneric.class, "tileentity_ntm_door"); put(TileEntityCharger.class, "tileentity_ntm_charger"); + put(TileEntityRefueler.class, "tileentity_ntm_refueler"); put(TileEntityFileCabinet.class, "tileentity_file_cabinet"); diff --git a/src/main/java/com/hbm/tileentity/machine/TileEntityRefueler.java b/src/main/java/com/hbm/tileentity/machine/TileEntityRefueler.java new file mode 100644 index 000000000..54b131657 --- /dev/null +++ b/src/main/java/com/hbm/tileentity/machine/TileEntityRefueler.java @@ -0,0 +1,157 @@ +package com.hbm.tileentity.machine; + +import java.util.List; +import java.util.Random; + +import com.hbm.handler.ArmorModHandler; +import com.hbm.inventory.fluid.Fluids; +import com.hbm.inventory.fluid.tank.FluidTank; +import com.hbm.main.MainRegistry; +import com.hbm.tileentity.TileEntityLoadedBase; +import com.hbm.util.BobMathUtil; + +import api.hbm.fluid.IFillableItem; +import api.hbm.fluid.IFluidStandardReceiver; +import io.netty.buffer.ByteBuf; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemArmor; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.AxisAlignedBB; +import net.minecraftforge.common.util.ForgeDirection; + +public class TileEntityRefueler extends TileEntityLoadedBase implements IFluidStandardReceiver { + + public double fillLevel; + public double prevFillLevel; + + private boolean isOperating = false; + private int operatingTime; + + public FluidTank tank; + + public TileEntityRefueler() { + super(); + tank = new FluidTank(Fluids.KEROSENE, 100); + } + + @SuppressWarnings("unchecked") + @Override + public void updateEntity() { + ForgeDirection dir = ForgeDirection.getOrientation(this.getBlockMetadata()).getOpposite(); + ForgeDirection rot = dir.getRotation(ForgeDirection.UP); + + if(!worldObj.isRemote) { + trySubscribe(tank.getTankType(), worldObj, xCoord + dir.offsetX, yCoord, zCoord + dir.offsetZ, dir); + + isOperating = false; + + List players = worldObj.getEntitiesWithinAABB(EntityPlayer.class, AxisAlignedBB.getBoundingBox(xCoord + 0.5, yCoord, zCoord + 0.5, xCoord + 0.5, yCoord + 0.5, zCoord + 0.5).expand(0.5, 0.0, 0.5)); + + for(EntityPlayer player : players) { + for(int i = 0; i < 5; i++) { + + ItemStack stack = player.getEquipmentInSlot(i); + if(stack == null) continue; + + if(fillFillable(stack)) { + isOperating = true; + } + + if(stack.getItem() instanceof ItemArmor && ArmorModHandler.hasMods(stack)) { + for(ItemStack mod : ArmorModHandler.pryMods(stack)) { + if(mod == null) continue; + + if(fillFillable(mod)) { + ArmorModHandler.applyMod(stack, mod); + isOperating = true; + } + } + } + } + } + + if(isOperating) { + if(operatingTime % 20 == 0) + worldObj.playSoundEffect(xCoord + 0.5, yCoord + 0.5, zCoord + 0.5, "random.fizz", 0.2F, 0.5F); + + operatingTime++; + } else { + operatingTime = 0; + } + + networkPackNT(150); + } else { + if(isOperating) { + Random rand = worldObj.rand; + + NBTTagCompound data = new NBTTagCompound(); + data.setString("type", "fluidfill"); + data.setInteger("color", tank.getTankType().getColor()); + data.setDouble("posX", xCoord + 0.5 + rand.nextDouble() * 0.0625 + dir.offsetX * 0.5 + rot.offsetX * 0.25); + data.setDouble("posZ", zCoord + 0.5 + rand.nextDouble() * 0.0625 + dir.offsetZ * 0.5 + rot.offsetZ * 0.25); + data.setDouble("posY", yCoord + 0.375); + data.setDouble("mX", -dir.offsetX + rand.nextGaussian() * 0.1); + data.setDouble("mZ", -dir.offsetZ + rand.nextGaussian() * 0.1); + data.setDouble("mY", 0D); + + MainRegistry.proxy.effectNT(data); + } + + prevFillLevel = fillLevel; + + double targetFill = (double)tank.getFill() / (double)tank.getMaxFill(); + fillLevel = BobMathUtil.interp(fillLevel, targetFill, targetFill > fillLevel || !isOperating ? 0.1F : 0.01F); + } + + + } + + private boolean fillFillable(ItemStack stack) { + if(stack.getItem() instanceof IFillableItem) { + IFillableItem fillable = (IFillableItem) stack.getItem(); + if(fillable.acceptsFluid(tank.getTankType(), stack)) { + int prevFill = tank.getFill(); + tank.setFill(fillable.tryFill(tank.getTankType(), tank.getFill(), stack)); + return tank.getFill() < prevFill; + } + } + + return false; + } + + @Override + public void serialize(ByteBuf buf) { + buf.writeBoolean(isOperating); + tank.serialize(buf); + } + + @Override + public void deserialize(ByteBuf buf) { + isOperating = buf.readBoolean(); + tank.deserialize(buf); + } + + @Override + public void readFromNBT(NBTTagCompound nbt) { + super.readFromNBT(nbt); + tank.readFromNBT(nbt, "t"); + } + + @Override + public void writeToNBT(NBTTagCompound nbt) { + super.writeToNBT(nbt); + tank.writeToNBT(nbt, "t"); + } + + @Override + public FluidTank[] getAllTanks() { + return new FluidTank[] { tank }; + } + + @Override + public FluidTank[] getReceivingTanks() { + return new FluidTank[] { tank }; + } + +} diff --git a/src/main/resources/assets/hbm/lang/en_US.lang b/src/main/resources/assets/hbm/lang/en_US.lang index efdcb62a9..076371b8a 100644 --- a/src/main/resources/assets/hbm/lang/en_US.lang +++ b/src/main/resources/assets/hbm/lang/en_US.lang @@ -5979,6 +5979,7 @@ tile.red_pylon_medium_steel_transformer.name=Medium Steel Electricity Pylon with tile.red_pylon_medium_wood.name=Medium Wooden Electricity Pylon tile.red_pylon_medium_wood_transformer.name=Medium Wooden Electricity Pylon with Transformer tile.red_wire_coated.name=Coated Red Copper Cable +tile.refueler.name=Refueling Station tile.reinforced_brick.name=Reinforced Stone tile.reinforced_brick_stairs.name=Reinforced Stone Stairs tile.reinforced_ducrete.name=Reinforced Ducrete diff --git a/src/main/resources/assets/hbm/models/blocks/refueler.obj b/src/main/resources/assets/hbm/models/blocks/refueler.obj new file mode 100644 index 000000000..25218d14e --- /dev/null +++ b/src/main/resources/assets/hbm/models/blocks/refueler.obj @@ -0,0 +1,1100 @@ +# Blender 4.0.1 +# www.blender.org +o Fluid +v -0.437500 0.120000 -0.095000 +v -0.437500 0.821132 -0.095000 +v -0.318750 0.120000 -0.063181 +v -0.318750 0.821132 -0.063181 +v -0.231819 0.120000 0.023750 +v -0.231819 0.821132 0.023750 +v -0.200000 0.120000 0.142500 +v -0.200000 0.821132 0.142500 +v -0.231819 0.120000 0.261250 +v -0.231819 0.821132 0.261250 +v -0.318750 0.120000 0.348181 +v -0.318750 0.821132 0.348181 +v -0.437500 0.120000 0.380000 +v -0.437500 0.821132 0.380000 +vn 0.2588 -0.0000 -0.9659 +vn 0.7071 -0.0000 -0.7071 +vn 0.9659 -0.0000 -0.2588 +vn 0.9659 -0.0000 0.2588 +vn 0.7071 -0.0000 0.7071 +vn 0.2588 -0.0000 0.9659 +vn -0.0000 -1.0000 -0.0000 +vn -0.0000 1.0000 -0.0000 +vt 0.553982 0.742726 +vt 0.546523 0.663764 +vt 0.553982 0.663764 +vt 0.546523 0.742726 +vt 0.539064 0.663764 +vt 0.539064 0.742726 +vt 0.531606 0.663764 +vt 0.531606 0.742726 +vt 0.524147 0.663764 +vt 0.524147 0.742726 +vt 0.516688 0.663764 +vt 0.516688 0.742726 +vt 0.509229 0.663764 +vt 0.509229 0.742726 +s 0 +f 2/1/1 3/2/1 1/3/1 +f 4/4/2 5/5/2 3/2/2 +f 6/6/3 7/7/3 5/5/3 +f 8/8/4 9/9/4 7/7/4 +f 10/10/5 11/11/5 9/9/5 +f 12/12/6 13/13/6 11/11/6 +f 3/2/7 7/7/7 11/11/7 +f 2/1/8 12/12/8 8/8/8 +f 2/1/1 4/4/1 3/2/1 +f 4/4/2 6/6/2 5/5/2 +f 6/6/3 8/8/3 7/7/3 +f 8/8/4 10/10/4 9/9/4 +f 10/10/5 12/12/5 11/11/5 +f 12/12/6 14/14/6 13/13/6 +f 13/13/7 1/3/7 3/2/7 +f 3/2/7 5/5/7 7/7/7 +f 7/7/7 9/9/7 11/11/7 +f 11/11/7 13/13/7 3/2/7 +f 6/6/8 4/4/8 2/1/8 +f 2/1/8 14/14/8 12/12/8 +f 12/12/8 10/10/8 8/8/8 +f 8/8/8 6/6/8 2/1/8 +o Fueler +v -0.437500 0.295000 -0.129375 +v -0.437500 0.495000 -0.129375 +v -0.437500 0.295000 -0.410625 +v -0.437500 0.495000 -0.410625 +v -0.312500 0.295000 -0.129375 +v -0.312500 0.495000 -0.129375 +v -0.312500 0.295000 -0.410625 +v -0.312500 0.495000 -0.410625 +v -0.413151 0.393750 -0.250217 +v -0.312500 0.393750 -0.250217 +v -0.413151 0.358241 -0.235509 +v -0.312500 0.358241 -0.235509 +v -0.413151 0.343533 -0.200000 +v -0.312500 0.343533 -0.200000 +v -0.413151 0.358241 -0.164491 +v -0.312500 0.358241 -0.164491 +v -0.413151 0.393750 -0.149783 +v -0.312500 0.393750 -0.149783 +v -0.413151 0.429259 -0.164491 +v -0.312500 0.429259 -0.164491 +v -0.413151 0.443967 -0.200000 +v -0.312500 0.443967 -0.200000 +v -0.413151 0.429259 -0.235509 +v -0.312500 0.429259 -0.235509 +v -0.413151 0.393750 -0.390217 +v -0.312500 0.393750 -0.390217 +v -0.413151 0.358241 -0.375509 +v -0.312500 0.358241 -0.375509 +v -0.413151 0.343533 -0.340000 +v -0.312500 0.343533 -0.340000 +v -0.413151 0.358241 -0.304491 +v -0.312500 0.358241 -0.304491 +v -0.413151 0.393750 -0.289783 +v -0.312500 0.393750 -0.289783 +v -0.413151 0.429259 -0.304491 +v -0.312500 0.429259 -0.304491 +v -0.413151 0.443967 -0.340000 +v -0.312500 0.443967 -0.340000 +v -0.413151 0.429259 -0.375509 +v -0.312500 0.429259 -0.375509 +v -0.500000 0.000000 0.500000 +v -0.500000 1.000000 0.500000 +v -0.500000 -0.000000 -0.500000 +v -0.500000 1.000000 -0.500000 +v -0.375000 0.062500 0.437500 +v -0.375000 0.937500 0.437500 +v -0.375000 0.062500 -0.437500 +v -0.375000 0.937500 -0.437500 +v -0.437500 0.937500 -0.437500 +v -0.437500 0.062500 -0.437500 +v -0.437500 0.062500 0.437500 +v -0.437500 0.937500 0.437500 +v -0.437500 0.100000 -0.100000 +v -0.437500 0.900000 -0.100000 +v -0.312500 0.100000 -0.066506 +v -0.312500 0.900000 -0.066506 +v -0.220994 0.100000 0.025000 +v -0.220994 0.900000 0.025000 +v -0.187500 0.100000 0.150000 +v -0.187500 0.900000 0.150000 +v -0.220994 0.100000 0.275000 +v -0.220994 0.900000 0.275000 +v -0.312500 0.100000 0.366506 +v -0.312500 0.900000 0.366506 +v -0.437500 0.100000 0.400000 +v -0.437500 0.900000 0.400000 +v -0.437500 0.100000 -0.100000 +v -0.437500 0.900000 -0.100000 +v -0.312500 0.100000 -0.066506 +v -0.312500 0.900000 -0.066506 +v -0.220994 0.100000 0.025000 +v -0.220994 0.900000 0.025000 +v -0.187500 0.100000 0.150000 +v -0.187500 0.900000 0.150000 +v -0.220994 0.100000 0.275000 +v -0.220994 0.900000 0.275000 +v -0.312500 0.100000 0.366506 +v -0.312500 0.900000 0.366506 +v -0.437500 0.100000 0.400000 +v -0.437500 0.900000 0.400000 +v -0.437500 0.695646 -0.233146 +v -0.437500 0.709375 -0.200000 +v -0.437500 0.695646 -0.166854 +v -0.437500 0.662500 -0.153125 +v -0.437500 0.629354 -0.166854 +v -0.437500 0.615625 -0.200000 +v -0.437500 0.629354 -0.233146 +v -0.437500 0.662500 -0.246875 +v -0.433174 0.695362 -0.233146 +v -0.431382 0.708974 -0.200000 +v -0.433174 0.695362 -0.166854 +v -0.437500 0.662500 -0.153125 +v -0.441826 0.629638 -0.166854 +v -0.443618 0.616026 -0.200000 +v -0.441826 0.629638 -0.233146 +v -0.437500 0.662500 -0.246875 +v -0.389677 0.682832 -0.233146 +v -0.382812 0.694722 -0.200000 +v -0.389677 0.682832 -0.166854 +v -0.406250 0.654127 -0.153125 +v -0.422823 0.625422 -0.166854 +v -0.429688 0.613532 -0.200000 +v -0.422823 0.625422 -0.233146 +v -0.406250 0.654127 -0.246875 +v -0.354668 0.647823 -0.233146 +v -0.342778 0.654688 -0.200000 +v -0.354668 0.647823 -0.166854 +v -0.383373 0.631250 -0.153125 +v -0.412078 0.614677 -0.166854 +v -0.423968 0.607813 -0.200000 +v -0.412078 0.614677 -0.233146 +v -0.383373 0.631250 -0.246875 +v -0.342138 0.604326 -0.233146 +v -0.328526 0.606118 -0.200000 +v -0.342138 0.604326 -0.166854 +v -0.375000 0.600000 -0.153125 +v -0.407862 0.595674 -0.166854 +v -0.421474 0.593882 -0.200000 +v -0.407862 0.595674 -0.233146 +v -0.375000 0.600000 -0.246875 +v -0.341854 0.475000 -0.233146 +v -0.328125 0.475000 -0.200000 +v -0.341854 0.475000 -0.166854 +v -0.375000 0.475000 -0.153125 +v -0.408146 0.475000 -0.166854 +v -0.421875 0.475000 -0.200000 +v -0.408146 0.475000 -0.233146 +v -0.375000 0.475000 -0.246875 +v -0.437500 0.695646 -0.306854 +v -0.437500 0.709375 -0.340000 +v -0.437500 0.695646 -0.373146 +v -0.437500 0.662500 -0.386875 +v -0.437500 0.629354 -0.373146 +v -0.437500 0.615625 -0.340000 +v -0.437500 0.629354 -0.306854 +v -0.437500 0.662500 -0.293125 +v -0.433174 0.695362 -0.306854 +v -0.431382 0.708974 -0.340000 +v -0.433174 0.695362 -0.373146 +v -0.437500 0.662500 -0.386875 +v -0.441826 0.629638 -0.373146 +v -0.443618 0.616026 -0.340000 +v -0.441826 0.629638 -0.306854 +v -0.437500 0.662500 -0.293125 +v -0.389677 0.682832 -0.306854 +v -0.382812 0.694722 -0.340000 +v -0.389677 0.682832 -0.373146 +v -0.406250 0.654127 -0.386875 +v -0.422823 0.625422 -0.373146 +v -0.429688 0.613532 -0.340000 +v -0.422823 0.625422 -0.306854 +v -0.406250 0.654127 -0.293125 +v -0.354668 0.647823 -0.306854 +v -0.342778 0.654688 -0.340000 +v -0.354668 0.647823 -0.373146 +v -0.383373 0.631250 -0.386875 +v -0.412078 0.614677 -0.373146 +v -0.423968 0.607813 -0.340000 +v -0.412078 0.614677 -0.306854 +v -0.383373 0.631250 -0.293125 +v -0.342138 0.604326 -0.306854 +v -0.328526 0.606118 -0.340000 +v -0.342138 0.604326 -0.373146 +v -0.375000 0.600000 -0.386875 +v -0.407862 0.595674 -0.373146 +v -0.421474 0.593882 -0.340000 +v -0.407862 0.595674 -0.306854 +v -0.375000 0.600000 -0.293125 +v -0.341854 0.475000 -0.306854 +v -0.328125 0.475000 -0.340000 +v -0.341854 0.475000 -0.373146 +v -0.375000 0.475000 -0.386875 +v -0.408146 0.475000 -0.373146 +v -0.421875 0.475000 -0.340000 +v -0.408146 0.475000 -0.306854 +v -0.375000 0.475000 -0.293125 +v -0.437500 0.092354 -0.233146 +v -0.437500 0.078625 -0.200000 +v -0.437500 0.092354 -0.166854 +v -0.437500 0.125500 -0.153125 +v -0.437500 0.158646 -0.166854 +v -0.437500 0.172375 -0.200000 +v -0.437500 0.158646 -0.233146 +v -0.437500 0.125500 -0.246875 +v -0.433174 0.092638 -0.233146 +v -0.431382 0.079026 -0.200000 +v -0.433174 0.092638 -0.166854 +v -0.437500 0.125500 -0.153125 +v -0.441826 0.158362 -0.166854 +v -0.443618 0.171974 -0.200000 +v -0.441826 0.158362 -0.233146 +v -0.437500 0.125500 -0.246875 +v -0.389677 0.105168 -0.233146 +v -0.382812 0.093278 -0.200000 +v -0.389677 0.105168 -0.166854 +v -0.406250 0.133873 -0.153125 +v -0.422823 0.162578 -0.166854 +v -0.429688 0.174468 -0.200000 +v -0.422823 0.162578 -0.233146 +v -0.406250 0.133873 -0.246875 +v -0.354668 0.140177 -0.233146 +v -0.342778 0.133313 -0.200000 +v -0.354668 0.140177 -0.166854 +v -0.383373 0.156750 -0.153125 +v -0.412078 0.173323 -0.166854 +v -0.423968 0.180188 -0.200000 +v -0.412078 0.173323 -0.233146 +v -0.383373 0.156750 -0.246875 +v -0.342138 0.183674 -0.233146 +v -0.328526 0.181882 -0.200000 +v -0.342138 0.183674 -0.166854 +v -0.375000 0.188000 -0.153125 +v -0.407862 0.192326 -0.166854 +v -0.421474 0.194118 -0.200000 +v -0.407862 0.192326 -0.233146 +v -0.375000 0.188000 -0.246875 +v -0.341854 0.313000 -0.233146 +v -0.328125 0.313000 -0.200000 +v -0.341854 0.313000 -0.166854 +v -0.375000 0.313000 -0.153125 +v -0.408146 0.313000 -0.166854 +v -0.421875 0.313000 -0.200000 +v -0.408146 0.313000 -0.233146 +v -0.375000 0.313000 -0.246875 +v -0.437500 0.092354 -0.306854 +v -0.437500 0.078625 -0.340000 +v -0.437500 0.092354 -0.373146 +v -0.437500 0.125500 -0.386875 +v -0.437500 0.158646 -0.373146 +v -0.437500 0.172375 -0.340000 +v -0.437500 0.158646 -0.306854 +v -0.437500 0.125500 -0.293125 +v -0.433174 0.092638 -0.306854 +v -0.431382 0.079026 -0.340000 +v -0.433174 0.092638 -0.373146 +v -0.437500 0.125500 -0.386875 +v -0.441826 0.158362 -0.373146 +v -0.443618 0.171974 -0.340000 +v -0.441826 0.158362 -0.306854 +v -0.437500 0.125500 -0.293125 +v -0.389677 0.105168 -0.306854 +v -0.382812 0.093278 -0.340000 +v -0.389677 0.105168 -0.373146 +v -0.406250 0.133873 -0.386875 +v -0.422823 0.162578 -0.373146 +v -0.429688 0.174468 -0.340000 +v -0.422823 0.162578 -0.306854 +v -0.406250 0.133873 -0.293125 +v -0.354668 0.140177 -0.306854 +v -0.342778 0.133313 -0.340000 +v -0.354668 0.140177 -0.373146 +v -0.383373 0.156750 -0.386875 +v -0.412078 0.173323 -0.373146 +v -0.423968 0.180188 -0.340000 +v -0.412078 0.173323 -0.306854 +v -0.383373 0.156750 -0.293125 +v -0.342138 0.183674 -0.306854 +v -0.328526 0.181882 -0.340000 +v -0.342138 0.183674 -0.373146 +v -0.375000 0.188000 -0.386875 +v -0.407862 0.192326 -0.373146 +v -0.421474 0.194118 -0.340000 +v -0.407862 0.192326 -0.306854 +v -0.375000 0.188000 -0.293125 +v -0.341854 0.313000 -0.306854 +v -0.328125 0.313000 -0.340000 +v -0.341854 0.313000 -0.373146 +v -0.375000 0.313000 -0.386875 +v -0.408146 0.313000 -0.373146 +v -0.421875 0.313000 -0.340000 +v -0.408146 0.313000 -0.306854 +v -0.375000 0.313000 -0.293125 +v -0.427500 0.925000 -0.145000 +v -0.427500 0.675000 -0.145000 +v -0.427500 0.925000 -0.395000 +v -0.427500 0.675000 -0.395000 +v -0.500000 0.312500 0.187500 +v -0.500000 0.687500 0.187500 +v -0.500000 0.312500 -0.187500 +v -0.500000 0.687500 -0.187500 +v -0.437500 0.312500 0.187500 +v -0.437500 0.687500 0.187500 +v -0.437500 0.312500 -0.187500 +v -0.437500 0.687500 -0.187500 +v -0.447500 0.750000 -0.250000 +v -0.447500 0.250000 -0.250000 +v -0.447500 0.750000 0.250000 +v -0.447500 0.250000 0.250000 +v -0.500000 0.250000 0.250000 +v -0.500000 0.750000 0.250000 +v -0.500000 0.250000 -0.250000 +v -0.500000 0.750000 -0.250000 +v -0.437500 0.250000 0.250000 +v -0.437500 0.750000 0.250000 +v -0.437500 0.250000 -0.250000 +v -0.437500 0.750000 -0.250000 +vn -0.0000 -0.0000 -1.0000 +vn -0.0000 -0.0000 1.0000 +vn -0.0000 -1.0000 -0.0000 +vn -0.0000 1.0000 -0.0000 +vn -0.0000 0.3827 0.9239 +vn -0.0000 0.9239 0.3827 +vn -0.0000 0.9239 -0.3827 +vn -0.0000 0.3827 -0.9239 +vn -0.0000 -0.3827 -0.9239 +vn -0.0000 -0.9239 -0.3827 +vn -0.0000 -0.9239 0.3827 +vn -0.0000 -0.3827 0.9239 +vn 1.0000 -0.0000 -0.0000 +vn -1.0000 -0.0000 -0.0000 +vn 0.4472 -0.0000 -0.8944 +vn 0.4472 -0.0000 0.8944 +vn 0.4472 -0.8944 -0.0000 +vn 0.4472 0.8944 -0.0000 +vn 0.2588 -0.0000 -0.9659 +vn 0.7071 -0.0000 -0.7071 +vn 0.9659 -0.0000 -0.2588 +vn 0.9659 -0.0000 0.2588 +vn 0.7071 -0.0000 0.7071 +vn 0.2588 -0.0000 0.9659 +vn -0.0001 1.0000 -0.0000 +vn -0.0000 1.0000 -0.0001 +vn 0.0604 0.9222 -0.3820 +vn 0.0605 0.9222 0.3820 +vn 0.0251 0.3825 0.9236 +vn 0.0251 0.3826 -0.9236 +vn 0.0251 0.3826 0.9236 +vn 0.0998 0.3724 -0.9227 +vn 0.2562 0.8892 -0.3790 +vn 0.2562 0.8892 0.3790 +vn 0.0998 0.3724 0.9227 +vn -0.0832 -0.3748 0.9234 +vn -0.1628 -0.9096 0.3823 +vn -0.1628 -0.9096 -0.3823 +vn -0.0832 -0.3748 -0.9234 +vn 0.2787 0.2787 -0.9191 +vn 0.6565 0.6565 -0.3715 +vn 0.6565 0.6565 0.3715 +vn 0.2787 0.2787 0.9191 +vn -0.2787 -0.2787 0.9191 +vn -0.6565 -0.6565 0.3715 +vn -0.6565 -0.6565 -0.3715 +vn -0.2787 -0.2787 -0.9191 +vn 0.3772 0.1086 -0.9198 +vn 0.8901 0.2612 -0.3734 +vn 0.8901 0.2612 0.3734 +vn 0.3772 0.1086 0.9197 +vn -0.3807 -0.1020 0.9191 +vn -0.9080 -0.2014 0.3674 +vn -0.9080 -0.2014 -0.3674 +vn -0.3807 -0.1020 -0.9191 +vn 0.3854 0.0008 -0.9228 +vn 0.9250 0.0028 -0.3800 +vn 0.9250 0.0028 0.3800 +vn 0.3854 0.0008 0.9228 +vn -0.3855 -0.0000 0.9227 +vn -0.9251 0.0022 0.3798 +vn -0.9251 0.0022 -0.3798 +vn -0.3855 -0.0000 -0.9227 +vn 0.0604 0.9222 0.3820 +vn 0.0605 0.9222 -0.3820 +vn 0.0001 1.0000 -0.0000 +vn -0.0001 1.0000 0.0001 +vn 0.1086 0.3772 0.9197 +vn 0.2612 0.8901 0.3734 +vn -0.2014 -0.9080 0.3674 +vn -0.1020 -0.3807 0.9191 +vn -0.6565 -0.6566 -0.3714 +vn 0.8892 0.2562 -0.3790 +vn 0.3724 0.0998 -0.9227 +vn -0.3748 -0.0832 -0.9234 +vn -0.9096 -0.1628 -0.3823 +vn 0.9239 0.0020 -0.3827 +vn 0.3827 -0.0000 -0.9239 +vn -0.3827 0.0009 -0.9239 +vn -0.9239 0.0031 -0.3827 +vn 0.0251 -0.3826 -0.9236 +vn 0.0604 -0.9222 -0.3820 +vn 0.0605 -0.9222 0.3820 +vn -0.0000 -1.0000 0.0001 +vn 0.0251 -0.3825 -0.9236 +vn 0.1086 -0.3772 -0.9197 +vn 0.2612 -0.8901 -0.3734 +vn 0.2562 -0.8892 0.3790 +vn 0.0998 -0.3724 0.9227 +vn -0.0832 0.3748 0.9234 +vn -0.1628 0.9096 0.3823 +vn -0.2014 0.9080 -0.3674 +vn -0.1020 0.3807 -0.9191 +vn 0.2787 -0.2787 -0.9191 +vn 0.6565 -0.6565 -0.3715 +vn 0.6565 -0.6565 0.3715 +vn 0.2787 -0.2787 0.9191 +vn -0.2787 0.2787 0.9191 +vn -0.6565 0.6565 0.3715 +vn -0.6565 0.6565 -0.3715 +vn -0.2787 0.2787 -0.9191 +vn 0.3772 -0.1086 -0.9198 +vn 0.8901 -0.2612 -0.3734 +vn 0.8892 -0.2562 0.3790 +vn 0.3724 -0.0998 0.9227 +vn -0.3748 0.0832 0.9234 +vn -0.9096 0.1628 0.3823 +vn -0.9080 0.2014 -0.3674 +vn -0.3807 0.1020 -0.9191 +vn 0.3854 -0.0008 -0.9228 +vn 0.9250 -0.0028 -0.3800 +vn 0.9239 -0.0020 0.3827 +vn 0.3827 -0.0000 0.9239 +vn -0.3827 -0.0009 0.9239 +vn -0.9239 -0.0031 0.3827 +vn -0.9251 -0.0022 -0.3798 +vn 0.0604 -0.9222 0.3820 +vn -0.0000 1.0000 0.0001 +vn 0.0003 1.0000 -0.0000 +vn 0.0605 -0.9222 -0.3820 +vn 0.2562 -0.8892 -0.3790 +vn 0.0998 -0.3724 -0.9227 +vn -0.0832 0.3748 -0.9234 +vn -0.1628 0.9096 -0.3823 +vn 0.3772 -0.1086 0.9197 +vn 0.8901 -0.2612 0.3734 +vn -0.9080 0.2014 0.3674 +vn -0.3807 0.1020 0.9191 +vn 0.3854 -0.0008 0.9228 +vn 0.9250 -0.0028 0.3800 +vn -0.9251 -0.0022 0.3798 +vn 0.0602 0.9222 -0.3820 +vn -0.9945 0.1050 0.0001 +vn -0.9945 0.1050 -0.0000 +vn 0.0001 1.0000 -0.0001 +vn 0.1086 0.3772 -0.9197 +vn 0.2612 0.8901 -0.3734 +vn -0.2014 -0.9080 -0.3674 +vn -0.1020 -0.3807 -0.9191 +vn -0.6565 -0.6566 0.3714 +vn 0.8892 0.2562 0.3790 +vn 0.3724 0.0998 0.9227 +vn -0.3748 -0.0832 0.9234 +vn -0.9096 -0.1628 0.3823 +vn 0.9239 0.0020 0.3827 +vn -0.3827 0.0009 0.9239 +vn -0.9239 0.0031 0.3827 +vn 0.0602 0.9222 0.3820 +vn 0.0251 0.3825 -0.9236 +vn 0.0003 1.0000 -0.0001 +vn 0.1086 0.3772 -0.9198 +vn 0.3772 0.1086 -0.9197 +vn 0.0602 -0.9222 -0.3820 +vn 0.0251 -0.3825 0.9236 +vn -0.9923 -0.1240 -0.0000 +vn -0.9923 -0.1240 0.0001 +vn 0.0251 -0.3826 0.9236 +vn 0.2612 -0.8901 0.3734 +vn 0.1086 -0.3772 0.9197 +vn -0.1020 0.3807 0.9191 +vn -0.2014 0.9080 0.3674 +vn 0.3724 -0.0998 -0.9227 +vn 0.8892 -0.2562 -0.3790 +vn -0.9096 0.1628 -0.3823 +vn -0.3748 0.0832 -0.9234 +vn 0.9239 -0.0020 -0.3827 +vn -0.9239 -0.0031 -0.3827 +vn -0.3827 -0.0009 -0.9239 +vn 0.0602 -0.9222 0.3820 +vn 0.1087 -0.3772 0.9197 +vn 0.1086 -0.3772 -0.9198 +vt 0.750000 0.531250 +vt 0.562500 0.593750 +vt 0.562500 0.531250 +vt 0.750000 0.593750 +vt 0.562500 0.656250 +vt 0.656250 0.531250 +vt 0.656250 0.656250 +vt 0.512204 0.569751 +vt 0.557287 0.558480 +vt 0.512204 0.558480 +vt 0.512204 0.581021 +vt 0.557287 0.569751 +vt 0.557287 0.581021 +vt 0.512204 0.592292 +vt 0.512204 0.603563 +vt 0.557287 0.592292 +vt 0.512204 0.614833 +vt 0.557287 0.603563 +vt 0.557287 0.614833 +vt 0.512204 0.626104 +vt 0.518170 0.606754 +vt 0.518170 0.575012 +vt 0.549912 0.575012 +vt 0.674236 0.594454 +vt 0.632365 0.572293 +vt 0.683416 0.572293 +vt 0.632365 0.616616 +vt 0.683416 0.616616 +vt 0.610203 0.625796 +vt 0.750000 0.656250 +vt 0.578862 0.594454 +vt 0.588042 0.616616 +vt 0.736919 0.594454 +vt 0.727739 0.572293 +vt 0.610203 0.563113 +vt 0.500000 1.000000 +vt 0.000000 0.500000 +vt 0.500000 0.500000 +vt 0.500000 -0.000000 +vt 0.031250 0.062500 +vt 0.000000 0.000000 +vt 0.468750 0.031250 +vt 0.468750 0.062500 +vt 0.437500 0.500000 +vt -0.000000 0.062500 +vt 0.437500 0.062500 +vt 0.937500 1.000000 +vt 0.875000 0.562500 +vt 0.937500 0.562500 +vt 0.875000 1.000000 +vt 0.812500 0.562500 +vt 0.812500 1.000000 +vt 0.750000 0.562500 +vt 0.579890 0.704562 +vt 0.659043 0.659099 +vt 0.738196 0.704562 +vt 0.749970 0.750025 +vt 0.704507 0.670872 +vt 0.613580 0.670872 +vt 0.568117 0.750025 +vt 0.812500 0.500000 +vt 0.750000 0.500000 +vt 0.875000 0.500000 +vt 1.000000 0.500000 +vt 0.937500 0.500000 +vt 1.000000 0.562500 +vt 0.343750 0.656250 +vt 0.156250 0.687500 +vt 0.156250 0.656250 +vt 0.343750 0.812500 +vt 0.156250 0.843750 +vt 0.156250 0.812500 +vt 0.187500 0.656250 +vt 0.312500 0.843750 +vt 0.312500 0.656250 +vt 0.500000 0.750000 +vt 0.750000 1.000000 +vt 0.500000 0.781250 +vt 0.750000 0.750000 +vt 0.750000 0.968750 +vt 0.500000 0.968750 +vt 0.531250 0.750000 +vt 0.718750 1.000000 +vt 0.718750 0.750000 +vt 0.557287 0.626104 +vt 0.556486 0.590883 +vt 0.549912 0.606754 +vt 0.534041 0.613328 +vt 0.511596 0.590883 +vt 0.534041 0.568438 +vt 0.641545 0.594454 +vt 0.705577 0.625796 +vt 0.588042 0.572293 +vt 0.727739 0.616616 +vt 0.705577 0.563113 +vt 0.000000 1.000000 +vt 0.031250 0.031250 +vt 1.000000 0.000000 +vt 0.343750 0.687500 +vt 0.343750 0.843750 +vt 0.187500 0.843750 +vt 0.750000 0.781250 +vt 0.531250 1.000000 +s 0 +f 18/15/9 21/16/9 17/17/9 +f 20/18/10 15/19/10 19/16/10 +f 21/20/11 15/19/11 17/17/11 +f 18/15/12 20/21/12 22/20/12 +f 25/22/13 24/23/13 23/24/13 +f 27/25/14 26/26/14 25/22/14 +f 29/25/15 28/27/15 27/25/15 +f 31/28/16 30/27/16 29/25/16 +f 33/29/17 32/30/17 31/28/17 +f 35/31/18 34/32/18 33/29/18 +f 37/31/19 36/33/19 35/31/19 +f 23/34/20 38/33/20 37/31/20 +f 33/35/21 29/36/21 25/37/21 +f 41/22/13 40/23/13 39/24/13 +f 43/25/14 42/26/14 41/22/14 +f 45/25/15 44/27/15 43/25/15 +f 47/28/16 46/27/16 45/25/16 +f 49/29/17 48/30/17 47/28/17 +f 51/31/18 50/32/18 49/29/18 +f 53/31/19 52/33/19 51/31/19 +f 39/34/20 54/33/20 53/31/20 +f 49/35/21 45/36/21 41/37/21 +f 24/38/21 50/39/21 38/40/21 +f 46/41/21 24/38/21 26/42/21 +f 44/43/21 26/42/21 19/44/21 +f 40/45/21 42/46/21 21/19/21 +f 32/47/21 34/48/21 20/15/21 +f 20/15/21 38/40/21 52/49/21 +f 56/50/22 57/51/22 55/52/22 +f 58/53/23 61/54/23 57/55/23 +f 60/54/11 63/56/11 62/57/11 +f 60/54/24 55/53/24 59/57/24 +f 61/57/25 55/55/25 57/53/25 +f 58/55/26 60/57/26 62/54/26 +f 63/58/21 65/59/21 64/60/21 +f 62/54/10 64/56/10 61/57/10 +f 59/54/9 66/56/9 60/57/9 +f 61/54/12 65/56/12 59/57/12 +f 68/61/27 69/62/27 67/63/27 +f 70/64/28 71/65/28 69/62/28 +f 72/66/29 73/67/29 71/65/29 +f 74/61/30 75/62/30 73/63/30 +f 76/64/31 77/65/31 75/62/31 +f 78/66/32 79/67/32 77/65/32 +f 69/68/11 73/69/11 77/70/11 +f 68/71/12 78/68/12 74/69/12 +f 93/71/12 89/72/12 85/73/12 +f 86/72/11 90/73/11 94/74/11 +f 95/67/33 110/75/9 102/76/34 +f 104/65/35 95/76/35 96/67/35 +f 105/65/36 96/76/36 97/67/36 +f 98/67/37 105/75/37 97/76/37 +f 107/65/38 98/76/38 99/67/38 +f 108/65/35 99/76/35 100/67/35 +f 102/67/39 109/75/39 101/76/39 +f 103/65/40 118/77/40 110/75/40 +f 104/65/41 111/77/41 103/75/41 +f 113/62/42 104/75/42 105/65/42 +f 114/62/43 105/75/43 106/65/43 +f 115/62/44 106/75/44 107/65/44 +f 116/62/45 107/75/45 108/65/45 +f 109/65/46 116/77/46 108/75/46 +f 110/65/47 117/77/47 109/75/47 +f 111/63/48 126/78/48 118/79/48 +f 120/80/49 111/79/49 112/63/49 +f 121/80/50 112/79/50 113/63/50 +f 122/80/51 113/79/51 114/63/51 +f 123/80/52 114/79/52 115/63/52 +f 116/63/53 123/78/53 115/79/53 +f 125/80/54 116/79/54 117/63/54 +f 126/80/55 117/79/55 118/63/55 +f 127/63/56 126/77/56 119/62/56 +f 128/63/57 119/77/57 120/62/57 +f 121/62/58 128/79/58 120/77/58 +f 122/62/59 129/79/59 121/77/59 +f 123/62/60 130/79/60 122/77/60 +f 124/62/61 131/79/61 123/77/61 +f 133/63/62 124/77/62 125/62/62 +f 134/63/63 125/77/63 126/62/63 +f 135/62/64 134/76/64 127/67/64 +f 136/62/65 127/76/65 128/67/65 +f 129/67/66 136/77/66 128/76/66 +f 130/67/67 137/77/67 129/76/67 +f 131/67/68 138/77/68 130/76/68 +f 132/67/69 139/77/69 131/76/69 +f 141/62/70 132/76/70 133/67/70 +f 142/62/71 133/76/71 134/67/71 +f 100/76/72 109/65/72 108/75/72 +f 143/67/39 158/75/39 151/65/39 +f 143/76/72 152/65/72 144/67/72 +f 144/76/73 153/65/73 145/67/73 +f 146/67/34 153/75/12 154/65/9 +f 147/67/39 154/75/39 155/65/39 +f 147/76/72 156/65/72 148/67/72 +f 150/67/74 157/75/75 158/65/10 +f 151/65/76 166/77/76 159/62/76 +f 152/65/77 159/77/77 160/62/77 +f 152/75/41 161/62/41 153/65/41 +f 153/75/40 162/62/40 154/65/40 +f 154/75/47 163/62/47 155/65/47 +f 155/75/46 164/62/46 156/65/46 +f 157/65/78 164/77/78 165/62/78 +f 158/65/79 165/77/79 166/62/79 +f 159/63/51 174/78/51 167/80/51 +f 159/79/50 168/80/50 160/63/50 +f 160/79/49 169/80/49 161/63/49 +f 161/79/48 170/80/48 162/63/48 +f 162/79/55 171/80/55 163/63/55 +f 164/63/80 171/78/80 172/80/80 +f 164/79/53 173/80/53 165/63/53 +f 165/79/52 174/80/52 166/63/52 +f 174/77/59 175/63/59 167/62/59 +f 167/77/58 176/63/58 168/62/58 +f 169/62/81 176/79/81 177/63/81 +f 170/62/82 177/79/82 178/63/82 +f 171/62/83 178/79/83 179/63/83 +f 172/62/84 179/79/84 180/63/84 +f 172/77/61 181/63/61 173/62/61 +f 173/77/60 182/63/60 174/62/60 +f 182/76/67 183/62/67 175/67/67 +f 175/76/66 184/62/66 176/67/66 +f 177/67/85 184/77/85 185/62/85 +f 178/67/86 185/77/86 186/62/86 +f 179/67/87 186/77/87 187/62/87 +f 180/67/88 187/77/88 188/62/88 +f 180/76/69 189/62/69 181/67/69 +f 181/76/68 190/62/68 182/67/68 +f 157/65/35 148/76/35 156/75/35 +f 191/67/89 206/75/89 199/65/89 +f 191/76/90 200/65/90 192/67/90 +f 192/76/91 201/65/91 193/67/91 +f 194/67/11 201/75/92 202/65/10 +f 194/76/93 203/65/93 195/67/93 +f 196/67/90 203/75/90 204/65/90 +f 198/67/34 205/75/12 206/65/9 +f 199/65/94 214/77/94 207/62/94 +f 200/65/95 207/77/95 208/62/95 +f 200/75/96 209/62/96 201/65/96 +f 201/75/97 210/62/97 202/65/97 +f 202/75/98 211/62/98 203/65/98 +f 203/75/99 212/62/99 204/65/99 +f 205/65/100 212/77/100 213/62/100 +f 206/65/101 213/77/101 214/62/101 +f 214/79/102 215/80/102 207/63/102 +f 207/79/103 216/80/103 208/63/103 +f 208/79/104 217/80/104 209/63/104 +f 210/63/105 217/78/105 218/80/105 +f 211/63/106 218/78/106 219/80/106 +f 211/79/107 220/80/107 212/63/107 +f 213/63/108 220/78/108 221/80/108 +f 213/79/109 222/80/109 214/63/109 +f 222/77/110 223/63/110 215/62/110 +f 215/77/111 224/63/111 216/62/111 +f 217/62/112 224/79/112 225/63/112 +f 218/62/113 225/79/113 226/63/113 +f 219/62/114 226/79/114 227/63/114 +f 220/62/115 227/79/115 228/63/115 +f 220/77/116 229/63/116 221/62/116 +f 221/77/117 230/63/117 222/62/117 +f 230/76/118 231/62/118 223/67/118 +f 223/76/119 232/62/119 224/67/119 +f 225/67/120 232/77/120 233/62/120 +f 226/67/121 233/77/121 234/62/121 +f 227/67/122 234/77/122 235/62/122 +f 228/67/123 235/77/123 236/62/123 +f 228/76/124 237/62/124 229/67/124 +f 229/76/71 238/62/71 230/67/71 +f 205/65/125 196/76/125 204/75/125 +f 239/67/126 254/75/10 246/76/127 +f 248/65/91 239/76/91 240/67/91 +f 249/65/128 240/76/128 241/67/128 +f 242/67/93 249/75/93 241/76/93 +f 243/67/127 250/75/9 242/76/34 +f 252/65/125 243/76/125 244/67/125 +f 246/67/89 253/75/89 245/76/89 +f 247/65/97 262/77/97 254/75/97 +f 248/65/96 255/77/96 247/75/96 +f 257/62/129 248/75/129 249/65/129 +f 258/62/130 249/75/130 250/65/130 +f 259/62/131 250/75/131 251/65/131 +f 260/62/132 251/75/132 252/65/132 +f 253/65/99 260/77/99 252/75/99 +f 254/65/98 261/77/98 253/75/98 +f 263/80/105 262/79/105 255/63/105 +f 256/63/104 263/78/104 255/79/104 +f 265/80/103 256/79/103 257/63/103 +f 266/80/102 257/79/102 258/63/102 +f 259/63/109 266/78/109 258/79/109 +f 268/80/108 259/79/108 260/63/108 +f 261/63/107 268/78/107 260/79/107 +f 270/80/106 261/79/106 262/63/106 +f 271/63/133 270/77/133 263/62/133 +f 272/63/134 263/77/134 264/62/134 +f 265/62/111 272/79/111 264/77/111 +f 266/62/110 273/79/110 265/77/110 +f 267/62/117 274/79/117 266/77/117 +f 268/62/116 275/79/116 267/77/116 +f 277/63/135 268/77/135 269/62/135 +f 278/63/136 269/77/136 270/62/136 +f 279/62/137 278/76/137 271/67/137 +f 280/62/138 271/76/138 272/67/138 +f 273/67/119 280/77/119 272/76/119 +f 274/67/118 281/77/118 273/76/118 +f 275/67/71 282/77/71 274/76/71 +f 276/67/124 283/77/124 275/76/124 +f 285/62/139 276/76/139 277/67/139 +f 286/62/68 277/76/68 278/67/68 +f 244/76/90 253/65/90 252/75/90 +f 288/53/21 289/78/21 287/52/21 +f 294/81/9 297/82/9 293/83/9 +f 296/84/10 291/85/10 295/86/10 +f 297/87/11 291/85/11 293/83/11 +f 294/81/12 296/88/12 298/89/12 +f 299/90/22 302/91/22 301/50/22 +f 309/92/10 306/93/10 305/90/10 +f 303/50/9 308/94/9 307/95/9 +f 303/50/12 309/96/12 305/90/12 +f 308/97/11 306/93/11 310/98/11 +f 18/15/9 22/18/9 21/16/9 +f 20/18/10 16/44/10 15/19/10 +f 21/20/11 19/21/11 15/19/11 +f 18/15/12 16/44/12 20/21/12 +f 25/22/13 26/26/13 24/23/13 +f 27/25/14 28/27/14 26/26/14 +f 29/25/15 30/27/15 28/27/15 +f 31/28/16 32/30/16 30/27/16 +f 33/29/17 34/32/17 32/30/17 +f 35/31/18 36/33/18 34/32/18 +f 37/31/19 38/33/19 36/33/19 +f 23/34/20 24/99/20 38/33/20 +f 25/37/21 23/100/21 37/101/21 +f 37/101/21 35/102/21 33/35/21 +f 33/35/21 31/103/21 29/36/21 +f 29/36/21 27/104/21 25/37/21 +f 25/37/21 37/101/21 33/35/21 +f 41/22/13 42/26/13 40/23/13 +f 43/25/14 44/27/14 42/26/14 +f 45/25/15 46/27/15 44/27/15 +f 47/28/16 48/30/16 46/27/16 +f 49/29/17 50/32/17 48/30/17 +f 51/31/18 52/33/18 50/32/18 +f 53/31/19 54/33/19 52/33/19 +f 39/34/20 40/99/20 54/33/20 +f 41/37/21 39/100/21 53/101/21 +f 53/101/21 51/102/21 49/35/21 +f 49/35/21 47/103/21 45/36/21 +f 45/36/21 43/104/21 41/37/21 +f 41/37/21 53/101/21 49/35/21 +f 24/38/21 48/105/21 50/39/21 +f 46/41/21 48/105/21 24/38/21 +f 19/44/21 21/19/21 44/43/21 +f 44/43/21 46/41/21 26/42/21 +f 26/42/21 28/106/21 19/44/21 +f 22/17/21 52/49/21 54/107/21 +f 22/17/21 54/107/21 40/45/21 +f 42/46/21 44/43/21 21/19/21 +f 21/19/21 22/17/21 40/45/21 +f 19/44/21 28/106/21 30/108/21 +f 19/44/21 30/108/21 32/47/21 +f 34/48/21 36/109/21 20/15/21 +f 20/15/21 19/44/21 32/47/21 +f 52/49/21 22/17/21 20/15/21 +f 20/15/21 36/109/21 38/40/21 +f 38/40/21 50/39/21 52/49/21 +f 56/50/22 58/110/22 57/51/22 +f 58/53/23 62/57/23 61/54/23 +f 60/54/11 66/111/11 63/56/11 +f 60/54/24 56/55/24 55/53/24 +f 61/57/25 59/54/25 55/55/25 +f 58/55/26 56/53/26 60/57/26 +f 63/58/21 66/51/21 65/59/21 +f 62/54/10 63/111/10 64/56/10 +f 59/54/9 65/111/9 66/56/9 +f 61/54/12 64/111/12 65/56/12 +f 68/61/27 70/64/27 69/62/27 +f 70/64/28 72/66/28 71/65/28 +f 72/66/29 74/91/29 73/67/29 +f 74/61/30 76/64/30 75/62/30 +f 76/64/31 78/66/31 77/65/31 +f 78/66/32 80/91/32 79/67/32 +f 79/71/11 67/74/11 69/68/11 +f 69/68/11 71/73/11 73/69/11 +f 73/69/11 75/72/11 77/70/11 +f 77/70/11 79/71/11 69/68/11 +f 72/72/12 70/70/12 68/71/12 +f 68/71/12 80/74/12 78/68/12 +f 78/68/12 76/73/12 74/69/12 +f 74/69/12 72/72/12 68/71/12 +f 83/68/12 81/74/12 93/71/12 +f 93/71/12 91/70/12 89/72/12 +f 89/72/12 87/69/12 85/73/12 +f 85/73/12 83/68/12 93/71/12 +f 82/71/11 84/70/11 86/72/11 +f 86/72/11 88/69/11 90/73/11 +f 90/73/11 92/68/11 94/74/11 +f 94/74/11 82/71/11 86/72/11 +f 95/67/38 103/65/38 110/75/38 +f 104/65/140 103/75/140 95/76/140 +f 105/65/72 104/75/72 96/76/72 +f 98/67/10 106/65/12 105/75/126 +f 107/65/141 106/75/10 98/76/142 +f 108/65/140 107/75/140 99/76/140 +f 102/67/9 110/65/143 109/75/33 +f 103/65/144 111/62/144 118/77/144 +f 104/65/145 112/62/145 111/77/145 +f 113/62/77 112/77/77 104/75/77 +f 114/62/76 113/77/76 105/75/76 +f 115/62/79 114/77/79 106/75/79 +f 116/62/78 115/77/78 107/75/78 +f 109/65/146 117/62/146 116/77/146 +f 110/65/147 118/62/147 117/77/147 +f 111/63/48 119/80/48 126/78/48 +f 120/80/49 119/78/49 111/79/49 +f 121/80/50 120/78/50 112/79/50 +f 122/80/51 121/78/51 113/79/51 +f 123/80/52 122/78/52 114/79/52 +f 116/63/148 124/80/148 123/78/148 +f 125/80/80 124/78/80 116/79/80 +f 126/80/55 125/78/55 117/79/55 +f 127/63/82 134/79/82 126/77/82 +f 128/63/81 127/79/81 119/77/81 +f 121/62/149 129/63/149 128/79/149 +f 122/62/150 130/63/150 129/79/150 +f 123/62/151 131/63/151 130/79/151 +f 124/62/152 132/63/152 131/79/152 +f 133/63/84 132/79/84 124/77/84 +f 134/63/83 133/79/83 125/77/83 +f 135/62/86 142/77/86 134/76/86 +f 136/62/85 135/77/85 127/76/85 +f 129/67/153 137/62/153 136/77/153 +f 130/67/121 138/62/121 137/77/121 +f 131/67/154 139/62/154 138/77/154 +f 132/67/155 140/62/155 139/77/155 +f 141/62/88 140/77/88 132/76/88 +f 142/62/87 141/77/87 133/76/87 +f 100/76/156 101/67/156 109/65/156 +f 143/67/75 150/76/10 158/75/12 +f 143/76/36 151/75/36 152/65/36 +f 144/76/35 152/75/35 153/65/35 +f 146/67/157 145/76/157 153/75/157 +f 147/67/12 146/76/9 154/75/158 +f 147/76/156 155/75/156 156/65/156 +f 150/67/38 149/76/38 157/75/38 +f 151/65/43 158/75/43 166/77/43 +f 152/65/42 151/75/42 159/77/42 +f 152/75/145 160/77/145 161/62/145 +f 153/75/159 161/77/159 162/62/159 +f 154/75/147 162/77/147 163/62/147 +f 155/75/146 163/77/146 164/62/146 +f 157/65/45 156/75/45 164/77/45 +f 158/65/44 157/75/44 165/77/44 +f 159/63/51 166/79/51 174/78/51 +f 159/79/50 167/78/50 168/80/50 +f 160/79/49 168/78/49 169/80/49 +f 161/79/48 169/78/48 170/80/48 +f 162/79/55 170/78/55 171/80/55 +f 164/63/54 163/79/54 171/78/54 +f 164/79/148 172/78/148 173/80/148 +f 165/79/52 173/78/52 174/80/52 +f 174/77/150 182/79/150 175/63/150 +f 167/77/149 175/79/149 176/63/149 +f 169/62/57 168/77/57 176/79/57 +f 170/62/160 169/77/160 177/79/160 +f 171/62/63 170/77/63 178/79/63 +f 172/62/62 171/77/62 179/79/62 +f 172/77/152 180/79/152 181/63/152 +f 173/77/151 181/79/151 182/63/151 +f 182/76/121 190/77/121 183/62/121 +f 175/76/153 183/77/153 184/62/153 +f 177/67/65 176/76/65 184/77/65 +f 178/67/64 177/76/64 185/77/64 +f 179/67/71 178/76/71 186/77/71 +f 180/67/70 179/76/70 187/77/70 +f 180/76/155 188/77/155 189/62/155 +f 181/76/154 189/77/154 190/62/154 +f 157/65/73 149/67/73 148/76/73 +f 191/67/12 198/76/9 206/75/158 +f 191/76/161 199/75/161 200/65/161 +f 192/76/125 200/75/125 201/65/125 +f 194/67/162 193/76/162 201/75/162 +f 194/76/10 202/75/163 203/65/164 +f 196/67/128 195/76/128 203/75/128 +f 198/67/165 197/76/165 205/75/165 +f 199/65/130 206/75/130 214/77/130 +f 200/65/129 199/75/129 207/77/129 +f 200/75/166 208/77/166 209/62/166 +f 201/75/167 209/77/167 210/62/167 +f 202/75/168 210/77/168 211/62/168 +f 203/75/169 211/77/169 212/62/169 +f 205/65/132 204/75/132 212/77/132 +f 206/65/131 205/75/131 213/77/131 +f 214/79/102 222/78/102 215/80/102 +f 207/79/103 215/78/103 216/80/103 +f 208/79/104 216/78/104 217/80/104 +f 210/63/105 209/79/105 217/78/105 +f 211/63/106 210/79/106 218/78/106 +f 211/79/107 219/78/107 220/80/107 +f 213/63/108 212/79/108 220/78/108 +f 213/79/109 221/78/109 222/80/109 +f 222/77/170 230/79/170 223/63/170 +f 215/77/171 223/79/171 224/63/171 +f 217/62/134 216/77/134 224/79/134 +f 218/62/133 217/77/133 225/79/133 +f 219/62/136 218/77/136 226/79/136 +f 220/62/135 219/77/135 227/79/135 +f 220/77/172 228/79/172 229/63/172 +f 221/77/173 229/79/173 230/63/173 +f 230/76/86 238/77/86 231/62/86 +f 223/76/174 231/77/174 232/62/174 +f 225/67/138 224/76/138 232/77/138 +f 226/67/137 225/76/137 233/77/137 +f 227/67/68 226/76/68 234/77/68 +f 228/67/139 227/76/139 235/77/139 +f 228/76/175 236/77/175 237/62/175 +f 229/76/176 237/77/176 238/62/176 +f 205/65/91 197/67/91 196/76/91 +f 239/67/165 247/65/165 254/75/165 +f 248/65/177 247/75/177 239/76/177 +f 249/65/90 248/75/90 240/76/90 +f 242/67/9 250/65/34 249/75/74 +f 243/67/162 251/65/162 250/75/162 +f 252/65/177 251/75/177 243/76/177 +f 246/67/10 254/65/12 253/75/126 +f 247/65/178 255/62/178 262/77/178 +f 248/65/166 256/62/166 255/77/166 +f 257/62/95 256/77/95 248/75/95 +f 258/62/179 257/77/179 249/75/179 +f 259/62/101 258/77/101 250/75/101 +f 260/62/100 259/77/100 251/75/100 +f 253/65/169 261/62/169 260/77/169 +f 254/65/168 262/62/168 261/77/168 +f 263/80/105 270/78/105 262/79/105 +f 256/63/104 264/80/104 263/78/104 +f 265/80/103 264/78/103 256/79/103 +f 266/80/102 265/78/102 257/79/102 +f 259/63/109 267/80/109 266/78/109 +f 268/80/108 267/78/108 259/79/108 +f 261/63/107 269/80/107 268/78/107 +f 270/80/106 269/78/106 261/79/106 +f 271/63/113 278/79/113 270/77/113 +f 272/63/112 271/79/112 263/77/112 +f 265/62/171 273/63/171 272/79/171 +f 266/62/170 274/63/170 273/79/170 +f 267/62/173 275/63/173 274/79/173 +f 268/62/172 276/63/172 275/79/172 +f 277/63/115 276/79/115 268/77/115 +f 278/63/114 277/79/114 269/77/114 +f 279/62/121 286/77/121 278/76/121 +f 280/62/120 279/77/120 271/76/120 +f 273/67/174 281/62/174 280/77/174 +f 274/67/86 282/62/86 281/77/86 +f 275/67/176 283/62/176 282/77/176 +f 276/67/175 284/62/175 283/77/175 +f 285/62/123 284/77/123 276/76/123 +f 286/62/122 285/77/122 277/76/122 +f 244/76/128 245/67/128 253/65/128 +f 288/53/21 290/112/21 289/78/21 +f 294/81/9 298/113/9 297/82/9 +f 296/84/10 292/114/10 291/85/10 +f 297/87/11 295/115/11 291/85/11 +f 294/81/12 292/114/12 296/88/12 +f 299/90/22 300/93/22 302/91/22 +f 309/92/10 310/116/10 306/93/10 +f 303/50/9 304/91/9 308/94/9 +f 303/50/12 307/117/12 309/96/12 +f 308/97/11 304/91/11 306/93/11 diff --git a/src/main/resources/assets/hbm/textures/models/machines/refueler.png b/src/main/resources/assets/hbm/textures/models/machines/refueler.png new file mode 100644 index 0000000000000000000000000000000000000000..856793f732077be43fcb81bca3da571fdcc86e16 GIT binary patch literal 4920 zcmeHKX;f3!7QO@p3>9&Bg1%N`a01P6Gmzwx2$CQ~jfO!9KB-*py@4xaAh{#~(blmd z;)IGKf&&kg0?!G>u_&UbT|Q@RohWTZk>Xqwq`s4Yi0gH&w_NM>pIPfp`+WO5dw*x| zvvM-kQ$l;w2h$-4>a7e@M1Uv5e!01TyE#4m1$b1YM`@@C)XFfL3|caoU{GmBfsU;O0Ak`fMU(TY&9tkb zai#K@oHOUbB;QlR-u_NO$FCjIw3DYt&>+ZZF)5d;m2&yJTtEi-b63m4s)M|j+$)|K z;^#52Z%VCtb5mWPdd-YIZUZO&W9u~6oJnuDDCKMF>ql1({QON!DN-qZ)L7@|wjhwv zydY;=*4kIG5s7_&{^E@6Xv;B<^`2AkzH?FgM$vcX5k>uBICs|Hod4yS=z-DaWo}I8 z?c1=p;nm@9Rz9}&E%-IIrNLWGAL*RIOj-MINyyRh(u3r~{FY34=~&-W4X1KkVpqLd z{b=ubL;fTWcPSsoucXv_?$I>HAIggPL7kb9S-q?z{P-$!%uh#aV#=<^v=zKrd}6_Y zH9sL`@bKM>hDUe~+rENcvfFcOtWS+1?*caDkMJ{v%-qT4bZ^N(^+NjDrwiYnczidn zW+N%`^>$95mE4AX?$$&rTcZ1F=q<~m9!~y6vTEB>9*3gNq=&x@)~4C97xYf4>dZAoqU z?OvYc?L259$5iG%JXZpW&O(CX(x@gQm_f%zaYH=8w&{$Z>L5rOXfvW%5>5}zk#3o}p zcoFb!H*=T_2ZTzJF*PbRLvAn;3;|of=CVR;q=m;EM`uV)xE6^}Oz5NlUovJQMHvwe z$7;2*t$en@l)!-{5($UPCHZNiVhA1Va80Pks=LxhMg0QH>6TB zCKHS^-o>Xgs#IO{dUK}=Ko5=$HF97!m!s2hx_g+Z5DOsb4Cqfi%u%36IT3`}kZQt+ z5DTHFe7aNMSeL&s)s*Z=2gf)>GNA)dGnf_rV9HRXO5NpQmmq=E8693g><^F>seLcj z2eH{l9O-lq1h{wcet>?Ly8{eRDixwIV5#=-lnNQsK0ksRFcL=`ue^9MpTPXNEFmVs zSOPxAWl4Bkf0h^%!&-j{K|QipS!GA{-FF1SVt&Bq*TL`U_bSEf1Dx zVSn78D{@fb7&5_N(xG5ENgbL%aE$r{$ADdMWV~7_WAfM?fjcbfWR%hZ2hang9yeIc z@4-=|j)%GJ{&Qv%*|9U*H(AFAM_G0n(!ON(BTC zJIDr+n+TLLn4%1ZWEs;Q0>kdvHLL;+g`*UzKq&%{a(P08%R{*QD3}ZG2oD|u!^nH( z5tRWawQ2tgZEqijv}4i3NHdr}&0*^3sYoKFq8pN%h@acg!dB&qTN?2#z$$YYjP(|?T-#vQfSaVSm5D_eYWg0 z7Y?4etaid+VZZ)&N-{I!?hI(}#g1w1FDPB=mG`R8qAit|G|f>9 zlrCGJ#?H-&e*XLylO(f89WN=NnYVB3`2h0~xx(0(I`3_3CK0o>EPto_;AzdnfPcM5dI5_rv+qOCPTdjNdlj+N^6f2|J zQdb3iaZ##S6h583E^JdV$2e!gN&2P4LQ`Jx>k`?vT{CtUe!0P2`)!WubgENTRZyVP zvXI&%J6UqiHO`p0;qj(T%V$YLD_VE>eq-A!IBk4XaAGTZkG(W!`GV>gtUJ&n)x%p!?Xj2RYgP`0d)?;od$Y z)Q<|sDUeF{FxttfGY=JuX?*DJ(YZq#SIvEM@nBwmPGRo6`;CL1#(J)wU){sQ<+A`$ z{h9JcKbv=Ci}XRxs)CDSvU^&LHQ#BD)w+Cb`pRjVUqv~s^4qr7>|2e6Nn38! gWfvMA`kcKwi#BFT*{GZDckDf)44I-R4~|>#A7{r!QUCw| literal 0 HcmV?d00001 From 3dbe648ebebd07256504b12d7ab7e4644050853b Mon Sep 17 00:00:00 2001 From: George Paton Date: Sun, 9 Feb 2025 18:39:15 +1100 Subject: [PATCH 06/12] bring NBTStructures to NTMain! --- .../java/com/hbm/blocks/BlockDummyable.java | 52 +- .../com/hbm/blocks/IBlockSideRotation.java | 23 + src/main/java/com/hbm/blocks/ModBlocks.java | 18 +- .../com/hbm/blocks/generic/BlockBobble.java | 17 +- .../com/hbm/blocks/generic/BlockDecoCRT.java | 23 +- .../hbm/blocks/generic/BlockDecoModel.java | 60 +- .../hbm/blocks/generic/BlockDecoToaster.java | 23 +- .../com/hbm/blocks/generic/BlockPipe.java | 17 +- .../com/hbm/blocks/generic/BlockWand.java | 51 + .../hbm/blocks/generic/BlockWandJigsaw.java | 387 ++++++ .../com/hbm/blocks/generic/BlockWandLoot.java | 338 +++++ .../com/hbm/blocks/generic/DecoBlock.java | 38 +- .../generic/DecoPoleSatelliteReceiver.java | 20 +- .../hbm/blocks/generic/DecoTapeRecorder.java | 23 +- .../com/hbm/blocks/machine/Spotlight.java | 46 +- .../java/com/hbm/config/StructureConfig.java | 24 +- .../crafting/handlers/MKUCraftingHandler.java | 74 +- .../java/com/hbm/items/tool/ItemWandS.java | 153 ++- src/main/java/com/hbm/lib/HbmWorld.java | 13 +- src/main/java/com/hbm/lib/HbmWorldGen.java | 31 - src/main/java/com/hbm/main/ClientProxy.java | 8 +- .../java/com/hbm/main/StructureManager.java | 63 + .../com/hbm/render/block/RenderBlockWand.java | 37 + .../java/com/hbm/tileentity/TileMappings.java | 47 +- src/main/java/com/hbm/util/LootGenerator.java | 56 +- .../gen/INBTTileEntityTransformable.java | 14 + .../com/hbm/world/gen/INBTTransformable.java | 161 +++ .../java/com/hbm/world/gen/NBTStructure.java | 1155 +++++++++++++++++ .../com/hbm/world/gen/NTMWorldGenerator.java | 222 ++-- .../hbm/world/gen/component/Component.java | 459 ++++--- src/main/resources/assets/hbm/lang/en_US.lang | 4 + .../hbm/structures/crashed-vertibird.nbt | Bin 0 -> 1664 bytes .../meteor/loot3x3/meteor-3-bale.nbt | Bin 0 -> 313 bytes .../meteor/loot3x3/meteor-3-blank.nbt | Bin 0 -> 251 bytes .../meteor/loot3x3/meteor-3-block.nbt | Bin 0 -> 312 bytes .../meteor/loot3x3/meteor-3-book.nbt | Bin 0 -> 383 bytes .../meteor/loot3x3/meteor-3-crab-tesla.nbt | Bin 0 -> 367 bytes .../meteor/loot3x3/meteor-3-crab.nbt | Bin 0 -> 308 bytes .../meteor/loot3x3/meteor-3-crate.nbt | Bin 0 -> 319 bytes .../meteor/loot3x3/meteor-3-dirt.nbt | Bin 0 -> 313 bytes .../meteor/loot3x3/meteor-3-lead.nbt | Bin 0 -> 361 bytes .../meteor/loot3x3/meteor-3-mku.nbt | Bin 0 -> 378 bytes .../meteor/loot3x3/meteor-3-ooze.nbt | Bin 0 -> 302 bytes .../meteor/loot3x3/meteor-3-pillar.nbt | Bin 0 -> 288 bytes .../meteor/loot3x3/meteor-3-star.nbt | Bin 0 -> 313 bytes .../meteor/loot3x3/meteor-3-statue.nbt | Bin 0 -> 330 bytes .../meteor/loot3x3/meteor-3-tesla.nbt | Bin 0 -> 338 bytes .../hbm/structures/meteor/meteor-core.nbt | Bin 0 -> 2734 bytes .../hbm/structures/meteor/meteor-corner.nbt | Bin 0 -> 1498 bytes .../hbm/structures/meteor/meteor-fallback.nbt | Bin 0 -> 315 bytes .../hbm/structures/meteor/meteor-spike.nbt | Bin 0 -> 433 bytes .../hbm/structures/meteor/meteor-stairs.nbt | Bin 0 -> 2074 bytes .../assets/hbm/structures/meteor/meteor-t.nbt | Bin 0 -> 1905 bytes .../meteor/room10/headloot/loot-chest.nbt | Bin 0 -> 829 bytes .../room10/headloot/loot-crate-crab.nbt | Bin 0 -> 787 bytes .../meteor/room10/headloot/loot-tesla.nbt | Bin 0 -> 886 bytes .../meteor/room10/headloot/loot-trap.nbt | Bin 0 -> 1038 bytes .../structures/meteor/room10/room-balcony.nbt | Bin 0 -> 2751 bytes .../meteor/room10/room-base-end.nbt | Bin 0 -> 1675 bytes .../meteor/room10/room-base-thru.nbt | Bin 0 -> 1613 bytes .../structures/meteor/room10/room-basic.nbt | Bin 0 -> 1092 bytes .../structures/meteor/room10/room-dragon.nbt | Bin 0 -> 3765 bytes .../meteor/room10/room-fallback.nbt | Bin 0 -> 449 bytes .../structures/meteor/room10/room-ladder.nbt | Bin 0 -> 2173 bytes .../structures/meteor/room10/room-ooze.nbt | Bin 0 -> 2211 bytes .../structures/meteor/room10/room-split.nbt | Bin 0 -> 2786 bytes .../structures/meteor/room10/room-stairs.nbt | Bin 0 -> 1797 bytes .../structures/meteor/room10/room-triple.nbt | Bin 0 -> 2339 bytes .../hbm/structures/test-jigsaw-core.nbt | Bin 0 -> 479 bytes .../hbm/structures/test-jigsaw-hall.nbt | Bin 0 -> 555 bytes .../assets/hbm/structures/test-jigsaw.nbt | Bin 0 -> 470 bytes .../assets/hbm/structures/test-rot.nbt | Bin 0 -> 4860 bytes .../assets/hbm/structures/vertibird.nbt | Bin 0 -> 1918 bytes .../assets/hbm/textures/blocks/wand_air.png | Bin 0 -> 653 bytes .../hbm/textures/blocks/wand_jigsaw.png | Bin 0 -> 5180 bytes .../hbm/textures/blocks/wand_jigsaw_back.png | Bin 0 -> 599 bytes .../hbm/textures/blocks/wand_jigsaw_side.png | Bin 0 -> 629 bytes .../hbm/textures/blocks/wand_jigsaw_top.png | Bin 0 -> 625 bytes .../assets/hbm/textures/blocks/wand_loot.png | Bin 0 -> 595 bytes .../hbm/textures/blocks/wand_loot_top.png | Bin 0 -> 4264 bytes 80 files changed, 3189 insertions(+), 468 deletions(-) create mode 100644 src/main/java/com/hbm/blocks/generic/BlockWand.java create mode 100644 src/main/java/com/hbm/blocks/generic/BlockWandJigsaw.java create mode 100644 src/main/java/com/hbm/blocks/generic/BlockWandLoot.java create mode 100644 src/main/java/com/hbm/main/StructureManager.java create mode 100644 src/main/java/com/hbm/render/block/RenderBlockWand.java create mode 100644 src/main/java/com/hbm/world/gen/INBTTileEntityTransformable.java create mode 100644 src/main/java/com/hbm/world/gen/INBTTransformable.java create mode 100644 src/main/java/com/hbm/world/gen/NBTStructure.java create mode 100644 src/main/resources/assets/hbm/structures/crashed-vertibird.nbt create mode 100644 src/main/resources/assets/hbm/structures/meteor/loot3x3/meteor-3-bale.nbt create mode 100644 src/main/resources/assets/hbm/structures/meteor/loot3x3/meteor-3-blank.nbt create mode 100644 src/main/resources/assets/hbm/structures/meteor/loot3x3/meteor-3-block.nbt create mode 100644 src/main/resources/assets/hbm/structures/meteor/loot3x3/meteor-3-book.nbt create mode 100644 src/main/resources/assets/hbm/structures/meteor/loot3x3/meteor-3-crab-tesla.nbt create mode 100644 src/main/resources/assets/hbm/structures/meteor/loot3x3/meteor-3-crab.nbt create mode 100644 src/main/resources/assets/hbm/structures/meteor/loot3x3/meteor-3-crate.nbt create mode 100644 src/main/resources/assets/hbm/structures/meteor/loot3x3/meteor-3-dirt.nbt create mode 100644 src/main/resources/assets/hbm/structures/meteor/loot3x3/meteor-3-lead.nbt create mode 100644 src/main/resources/assets/hbm/structures/meteor/loot3x3/meteor-3-mku.nbt create mode 100644 src/main/resources/assets/hbm/structures/meteor/loot3x3/meteor-3-ooze.nbt create mode 100644 src/main/resources/assets/hbm/structures/meteor/loot3x3/meteor-3-pillar.nbt create mode 100644 src/main/resources/assets/hbm/structures/meteor/loot3x3/meteor-3-star.nbt create mode 100644 src/main/resources/assets/hbm/structures/meteor/loot3x3/meteor-3-statue.nbt create mode 100644 src/main/resources/assets/hbm/structures/meteor/loot3x3/meteor-3-tesla.nbt create mode 100644 src/main/resources/assets/hbm/structures/meteor/meteor-core.nbt create mode 100644 src/main/resources/assets/hbm/structures/meteor/meteor-corner.nbt create mode 100644 src/main/resources/assets/hbm/structures/meteor/meteor-fallback.nbt create mode 100644 src/main/resources/assets/hbm/structures/meteor/meteor-spike.nbt create mode 100644 src/main/resources/assets/hbm/structures/meteor/meteor-stairs.nbt create mode 100644 src/main/resources/assets/hbm/structures/meteor/meteor-t.nbt create mode 100644 src/main/resources/assets/hbm/structures/meteor/room10/headloot/loot-chest.nbt create mode 100644 src/main/resources/assets/hbm/structures/meteor/room10/headloot/loot-crate-crab.nbt create mode 100644 src/main/resources/assets/hbm/structures/meteor/room10/headloot/loot-tesla.nbt create mode 100644 src/main/resources/assets/hbm/structures/meteor/room10/headloot/loot-trap.nbt create mode 100644 src/main/resources/assets/hbm/structures/meteor/room10/room-balcony.nbt create mode 100644 src/main/resources/assets/hbm/structures/meteor/room10/room-base-end.nbt create mode 100644 src/main/resources/assets/hbm/structures/meteor/room10/room-base-thru.nbt create mode 100644 src/main/resources/assets/hbm/structures/meteor/room10/room-basic.nbt create mode 100644 src/main/resources/assets/hbm/structures/meteor/room10/room-dragon.nbt create mode 100644 src/main/resources/assets/hbm/structures/meteor/room10/room-fallback.nbt create mode 100644 src/main/resources/assets/hbm/structures/meteor/room10/room-ladder.nbt create mode 100644 src/main/resources/assets/hbm/structures/meteor/room10/room-ooze.nbt create mode 100644 src/main/resources/assets/hbm/structures/meteor/room10/room-split.nbt create mode 100644 src/main/resources/assets/hbm/structures/meteor/room10/room-stairs.nbt create mode 100644 src/main/resources/assets/hbm/structures/meteor/room10/room-triple.nbt create mode 100644 src/main/resources/assets/hbm/structures/test-jigsaw-core.nbt create mode 100644 src/main/resources/assets/hbm/structures/test-jigsaw-hall.nbt create mode 100644 src/main/resources/assets/hbm/structures/test-jigsaw.nbt create mode 100644 src/main/resources/assets/hbm/structures/test-rot.nbt create mode 100644 src/main/resources/assets/hbm/structures/vertibird.nbt create mode 100644 src/main/resources/assets/hbm/textures/blocks/wand_air.png create mode 100644 src/main/resources/assets/hbm/textures/blocks/wand_jigsaw.png create mode 100644 src/main/resources/assets/hbm/textures/blocks/wand_jigsaw_back.png create mode 100644 src/main/resources/assets/hbm/textures/blocks/wand_jigsaw_side.png create mode 100644 src/main/resources/assets/hbm/textures/blocks/wand_jigsaw_top.png create mode 100644 src/main/resources/assets/hbm/textures/blocks/wand_loot.png create mode 100644 src/main/resources/assets/hbm/textures/blocks/wand_loot_top.png diff --git a/src/main/java/com/hbm/blocks/BlockDummyable.java b/src/main/java/com/hbm/blocks/BlockDummyable.java index cfedf6246..75dd39c2f 100644 --- a/src/main/java/com/hbm/blocks/BlockDummyable.java +++ b/src/main/java/com/hbm/blocks/BlockDummyable.java @@ -5,12 +5,15 @@ import com.hbm.handler.ThreeInts; import com.hbm.interfaces.ICopiable; import com.hbm.main.MainRegistry; import com.hbm.tileentity.IPersistentNBT; +import com.hbm.world.gen.INBTTransformable; + import cpw.mods.fml.common.network.internal.FMLNetworkHandler; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; import net.minecraft.block.Block; import net.minecraft.block.BlockContainer; import net.minecraft.block.material.Material; +import net.minecraft.client.renderer.RenderGlobal; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.item.EntityItem; @@ -32,7 +35,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Random; -public abstract class BlockDummyable extends BlockContainer implements ICustomBlockHighlight, ICopiable { +public abstract class BlockDummyable extends BlockContainer implements ICustomBlockHighlight, ICopiable, INBTTransformable { public BlockDummyable(Material mat) { super(mat); @@ -116,7 +119,7 @@ public abstract class BlockDummyable extends BlockContainer implements ICustomBl return findCoreRec(world, x, y, z); } - List positions = new ArrayList(); + List positions = new ArrayList<>(); public int[] findCoreRec(World world, int x, int y, int z) { @@ -216,11 +219,6 @@ public abstract class BlockDummyable extends BlockContainer implements ICustomBl super.onBlockPlacedBy(world, x, y, z, player, itemStack); } - /*@Override - public void onBlockAdded(World world, int x, int y, int z) { - lastBlockSet = new BlockPos(x, y, z); - }*/ - /** * A bit more advanced than the dir modifier, but it is important that the resulting direction meta is in the core range. * Using the "extra" metas is technically possible but requires a bit of tinkering, e.g. preventing a recursive loop @@ -267,9 +265,9 @@ public abstract class BlockDummyable extends BlockContainer implements ICustomBl return; // world.setBlockMetadataWithNotify(x, y, z, meta + extra, 3); - this.safeRem = true; + safeRem = true; world.setBlock(x, y, z, this, meta + extra, 3); - this.safeRem = false; + safeRem = false; } public void removeExtra(World world, int x, int y, int z) { @@ -283,9 +281,9 @@ public abstract class BlockDummyable extends BlockContainer implements ICustomBl return; // world.setBlockMetadataWithNotify(x, y, z, meta + extra, 3); - this.safeRem = true; + safeRem = true; world.setBlock(x, y, z, this, meta - extra, 3); - this.safeRem = false; + safeRem = false; } // checks if the dummy metadata is within the extra range @@ -423,8 +421,9 @@ public abstract class BlockDummyable extends BlockContainer implements ICustomBl return !bounding.isEmpty(); } - public List bounding = new ArrayList(); + public List bounding = new ArrayList<>(); + @SuppressWarnings({ "rawtypes", "unchecked" }) @Override public void addCollisionBoxesToList(World world, int x, int y, int z, AxisAlignedBB entityBounding, List list, Entity entity) { @@ -443,7 +442,7 @@ public abstract class BlockDummyable extends BlockContainer implements ICustomBl z = pos[2]; for(AxisAlignedBB aabb :this.bounding) { - AxisAlignedBB boxlet = getAABBRotationOffset(aabb, x + 0.5, y, z + 0.5, ForgeDirection.getOrientation(world.getBlockMetadata(x, y, z) - this.offset).getRotation(ForgeDirection.UP)); + AxisAlignedBB boxlet = getAABBRotationOffset(aabb, x + 0.5, y, z + 0.5, ForgeDirection.getOrientation(world.getBlockMetadata(x, y, z) - offset).getRotation(ForgeDirection.UP)); if(entityBounding.intersectsWith(boxlet)) { list.add(boxlet); @@ -504,7 +503,7 @@ public abstract class BlockDummyable extends BlockContainer implements ICustomBl int meta = world.getBlockMetadata(x, y, z); ICustomBlockHighlight.setup(); - for(AxisAlignedBB aabb : this.bounding) event.context.drawOutlinedBoundingBox(getAABBRotationOffset(aabb.expand(exp, exp, exp), 0, 0, 0, ForgeDirection.getOrientation(meta - offset).getRotation(ForgeDirection.UP)).getOffsetBoundingBox(x - dX + 0.5, y - dY, z - dZ + 0.5), -1); + for(AxisAlignedBB aabb : this.bounding) RenderGlobal.drawOutlinedBoundingBox(getAABBRotationOffset(aabb.expand(exp, exp, exp), 0, 0, 0, ForgeDirection.getOrientation(meta - offset).getRotation(ForgeDirection.UP)).getOffsetBoundingBox(x - dX + 0.5, y - dY, z - dZ + 0.5), -1); ICustomBlockHighlight.cleanup(); } @@ -534,4 +533,27 @@ public abstract class BlockDummyable extends BlockContainer implements ICustomBl return ((ICopiable) tile).infoForDisplay(world, x, y, z); return null; } -} + + @Override + public int transformMeta(int meta, int coordBaseMode) { + boolean isOffset = meta >= 12; // squishing causes issues + boolean isExtra = !isOffset && meta >= extra; + + if(isOffset) { + meta -= offset; + } else if(isExtra) { + meta -= extra; + } + + meta = INBTTransformable.transformMetaDeco(meta, coordBaseMode); + + if(isOffset) { + meta += offset; + } else if(isExtra) { + meta += extra; + } + + return meta; + } + +} \ No newline at end of file diff --git a/src/main/java/com/hbm/blocks/IBlockSideRotation.java b/src/main/java/com/hbm/blocks/IBlockSideRotation.java index d24282cce..a8769a139 100644 --- a/src/main/java/com/hbm/blocks/IBlockSideRotation.java +++ b/src/main/java/com/hbm/blocks/IBlockSideRotation.java @@ -11,4 +11,27 @@ public interface IBlockSideRotation { public static int getRenderType() { return renderID; } + + // 0 1 3 2 becomes 0 2 3 1 + // I want to smoke that swedish kush because it clearly makes you fucking stupid + public static int topToBottom(int topRotation) { + switch(topRotation) { + case 1: return 2; + case 2: return 1; + default: return topRotation; + } + } + + public static boolean isOpposite(int from, int to) { + switch(from) { + case 0: return to == 1; + case 1: return to == 0; + case 2: return to == 3; + case 3: return to == 2; + case 4: return to == 5; + case 5: return to == 4; + default: return false; + } + } + } diff --git a/src/main/java/com/hbm/blocks/ModBlocks.java b/src/main/java/com/hbm/blocks/ModBlocks.java index c80573666..6cf108b50 100644 --- a/src/main/java/com/hbm/blocks/ModBlocks.java +++ b/src/main/java/com/hbm/blocks/ModBlocks.java @@ -35,6 +35,7 @@ import net.minecraft.block.Block; import net.minecraft.block.BlockFalling; import net.minecraft.block.material.*; import net.minecraft.creativetab.CreativeTabs; +import net.minecraft.init.Blocks; import net.minecraft.item.Item; import net.minecraft.item.ItemBlock; import net.minecraft.item.ItemStack; @@ -1228,6 +1229,11 @@ public class ModBlocks { public static Block pink_double_slab; public static Block pink_stairs; + // NBT Structure wand blocks + public static Block wand_air; + public static Block wand_loot; + public static Block wand_jigsaw; + public static Material materialGas = new MaterialGas(); private static void initializeBlock() { @@ -1654,7 +1660,7 @@ public class ModBlocks { plant_dead = new BlockDeadPlant().setBlockName("plant_dead").setCreativeTab(MainRegistry.blockTab).setStepSound(Block.soundTypeGrass).setHardness(0.0F); reeds = new BlockReeds().setBlockName("plant_reeds").setCreativeTab(MainRegistry.blockTab).setStepSound(Block.soundTypeGrass).setHardness(0.0F); vine_phosphor = new BlockHangingVine(thick_foliage).setBlockName("vine_phosphor").setCreativeTab(MainRegistry.blockTab).setStepSound(Block.soundTypeGrass).setHardness(0.5F); - + waste_earth = new WasteEarth(Material.ground, true).setBlockName("waste_earth").setStepSound(Block.soundTypeGrass).setCreativeTab(MainRegistry.blockTab).setHardness(0.6F).setBlockTextureName(RefStrings.MODID + ":waste_earth"); waste_mycelium = new WasteEarth(Material.ground, true).setBlockName("waste_mycelium").setStepSound(Block.soundTypeGrass).setLightLevel(1F).setCreativeTab(MainRegistry.blockTab).setHardness(0.6F).setBlockTextureName(RefStrings.MODID + ":waste_mycelium_side"); waste_trinitite = new BlockOre(Material.sand).noFortune().setBlockName("waste_trinitite").setStepSound(Block.soundTypeSand).setCreativeTab(MainRegistry.blockTab).setHardness(0.5F).setResistance(2.5F).setBlockTextureName(RefStrings.MODID + ":waste_trinitite"); @@ -1836,7 +1842,7 @@ public class ModBlocks { pa_quadrupole = new BlockPAQuadrupole().setStepSound(Block.soundTypeMetal).setBlockName("pa_quadrupole").setHardness(5.0F).setResistance(10.0F); pa_dipole = new BlockPADipole().setStepSound(Block.soundTypeMetal).setBlockName("pa_dipole").setHardness(5.0F).setResistance(10.0F); pa_detector = new BlockPADetector().setStepSound(Block.soundTypeMetal).setBlockName("pa_detector").setHardness(5.0F).setResistance(10.0F); - + machine_electric_furnace_off = new MachineElectricFurnace(false).setBlockName("machine_electric_furnace_off").setHardness(5.0F).setResistance(10.0F).setCreativeTab(MainRegistry.machineTab); machine_electric_furnace_on = new MachineElectricFurnace(true).setBlockName("machine_electric_furnace_on").setHardness(5.0F).setLightLevel(1.0F).setResistance(10.0F); machine_arc_furnace_off = new MachineArcFurnace(false).setBlockName("machine_arc_furnace_off").setHardness(5.0F).setResistance(10.0F); @@ -2354,6 +2360,10 @@ public class ModBlocks { pink_slab = new BlockPinkSlab(false, Material.wood).setBlockName("pink_slab").setStepSound(Block.soundTypeWood).setCreativeTab(null).setBlockTextureName(RefStrings.MODID + ":pink_planks"); pink_double_slab = new BlockPinkSlab(true, Material.wood).setBlockName("pink_double_slab").setStepSound(Block.soundTypeWood).setCreativeTab(null).setBlockTextureName(RefStrings.MODID + ":pink_planks"); pink_stairs = new BlockGenericStairs(pink_planks, 0).setBlockName("pink_stairs").setStepSound(Block.soundTypeWood).setCreativeTab(null).setBlockTextureName(RefStrings.MODID + ":pink_planks"); + + wand_air = new BlockWand(Blocks.air).setBlockName("wand_air").setBlockTextureName(RefStrings.MODID + ":wand_air"); + wand_loot = new BlockWandLoot().setBlockName("wand_loot").setBlockTextureName(RefStrings.MODID + ":wand_loot"); + wand_jigsaw = new BlockWandJigsaw().setBlockName("wand_jigsaw").setBlockTextureName(RefStrings.MODID + ":wand_jigsaw"); } private static void registerBlock() { @@ -3475,6 +3485,10 @@ public class ModBlocks { GameRegistry.registerBlock(pink_slab, pink_slab.getUnlocalizedName()); GameRegistry.registerBlock(pink_double_slab, pink_double_slab.getUnlocalizedName()); GameRegistry.registerBlock(pink_stairs, pink_stairs.getUnlocalizedName()); + + register(wand_air); + register(wand_loot); + register(wand_jigsaw); } private static void register(Block b) { diff --git a/src/main/java/com/hbm/blocks/generic/BlockBobble.java b/src/main/java/com/hbm/blocks/generic/BlockBobble.java index df5d158ea..da175541c 100644 --- a/src/main/java/com/hbm/blocks/generic/BlockBobble.java +++ b/src/main/java/com/hbm/blocks/generic/BlockBobble.java @@ -4,6 +4,9 @@ import com.hbm.inventory.gui.GUIScreenBobble; import com.hbm.items.special.ItemPlasticScrap.ScrapType; import com.hbm.main.MainRegistry; import com.hbm.tileentity.IGUIProvider; +import com.hbm.world.gen.INBTTileEntityTransformable; +import com.hbm.world.gen.INBTTransformable; + import cpw.mods.fml.common.network.internal.FMLNetworkHandler; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; @@ -31,7 +34,7 @@ import net.minecraft.world.World; import java.util.List; import java.util.Random; -public class BlockBobble extends BlockContainer implements IGUIProvider { +public class BlockBobble extends BlockContainer implements IGUIProvider, INBTTransformable { public BlockBobble() { super(Material.iron); @@ -136,12 +139,17 @@ public class BlockBobble extends BlockContainer implements IGUIProvider { return AxisAlignedBB.getBoundingBox(x + this.minX, y + this.minY, z + this.minZ, x + this.maxX, y + this.maxY, z + this.maxZ); } + @Override + public int transformMeta(int meta, int coordBaseMode) { + return (meta + coordBaseMode * 4) % 16; + } + @Override public TileEntity createNewTileEntity(World world, int meta) { return new TileEntityBobble(); } - public static class TileEntityBobble extends TileEntity { + public static class TileEntityBobble extends TileEntity implements INBTTileEntityTransformable { public BobbleType type = BobbleType.NONE; @@ -173,6 +181,11 @@ public class BlockBobble extends BlockContainer implements IGUIProvider { super.writeToNBT(nbt); nbt.setByte("type", (byte) type.ordinal()); } + + @Override + public void transformTE(World world, int coordBaseMode) { + type = BobbleType.values()[world.rand.nextInt(BobbleType.values().length - 1) + 1]; + } } public static enum BobbleType { diff --git a/src/main/java/com/hbm/blocks/generic/BlockDecoCRT.java b/src/main/java/com/hbm/blocks/generic/BlockDecoCRT.java index 724912ed3..b1ede562a 100644 --- a/src/main/java/com/hbm/blocks/generic/BlockDecoCRT.java +++ b/src/main/java/com/hbm/blocks/generic/BlockDecoCRT.java @@ -2,6 +2,7 @@ package com.hbm.blocks.generic; import com.hbm.blocks.BlockMulti; import com.hbm.lib.RefStrings; +import com.hbm.world.gen.INBTTransformable; import cpw.mods.fml.client.registry.RenderingRegistry; import cpw.mods.fml.relauncher.Side; @@ -14,7 +15,7 @@ import net.minecraft.util.IIcon; import net.minecraft.util.MathHelper; import net.minecraft.world.World; -public class BlockDecoCRT extends BlockMulti { +public class BlockDecoCRT extends BlockMulti implements INBTTransformable { protected String[] variants = new String[] {"crt_clean", "crt_broken", "crt_blinking", "crt_bsod"}; @SideOnly(Side.CLIENT) protected IIcon[] icons; @@ -24,17 +25,17 @@ public class BlockDecoCRT extends BlockMulti { } public static int renderID = RenderingRegistry.getNextAvailableRenderId(); - + @Override public int getRenderType(){ return renderID; } - + @Override public boolean isOpaqueCube() { return false; } - + @Override public boolean renderAsNormalBlock() { return false; @@ -45,12 +46,12 @@ public class BlockDecoCRT extends BlockMulti { public void registerBlockIcons(IIconRegister reg) { super.registerBlockIcons(reg); this.icons = new IIcon[variants.length]; - + for(int i = 0; i < variants.length; i++) { this.icons[i] = reg.registerIcon(RefStrings.MODID + ":" + variants[i]); } } - + @Override @SideOnly(Side.CLIENT) public IIcon getIcon(int side, int meta) { @@ -61,7 +62,7 @@ public class BlockDecoCRT extends BlockMulti { public int damageDropped(int meta) { return (Math.abs(meta) % 16) / 4; } - + @Override public void onBlockPlacedBy(World world, int x, int y, int z, EntityLivingBase player, ItemStack stack) { int i = MathHelper.floor_double(player.rotationYaw * 4.0F / 360.0F + 0.5D) & 3; @@ -73,4 +74,10 @@ public class BlockDecoCRT extends BlockMulti { public int getSubCount() { return 4; } -} + + @Override + public int transformMeta(int meta, int coordBaseMode) { + return INBTTransformable.transformMetaDecoModel(meta, coordBaseMode); + } + +} \ No newline at end of file diff --git a/src/main/java/com/hbm/blocks/generic/BlockDecoModel.java b/src/main/java/com/hbm/blocks/generic/BlockDecoModel.java index d70fd5fe4..f10edc069 100644 --- a/src/main/java/com/hbm/blocks/generic/BlockDecoModel.java +++ b/src/main/java/com/hbm/blocks/generic/BlockDecoModel.java @@ -1,6 +1,7 @@ package com.hbm.blocks.generic; import com.hbm.blocks.BlockEnumMulti; +import com.hbm.world.gen.INBTTransformable; import cpw.mods.fml.client.registry.RenderingRegistry; import net.minecraft.block.material.Material; @@ -11,14 +12,14 @@ import net.minecraft.util.MathHelper; import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; -public class BlockDecoModel extends BlockEnumMulti { - +public class BlockDecoModel extends BlockEnumMulti implements INBTTransformable { + public BlockDecoModel(Material mat, Class theEnum, boolean multiName, boolean multiTexture) { super(mat, theEnum, multiName, multiTexture); } - + public static int renderID = RenderingRegistry.getNextAvailableRenderId(); - + @Override public int getRenderType() { return renderID; @@ -33,18 +34,18 @@ public class BlockDecoModel extends BlockEnumMulti { public boolean renderAsNormalBlock() { return false; } - + //Did somebody say - pain? //Alright fuckers, looks like 2/b010 = North, 3/b011 = South, 4/b100 = West, 5/b101 = East for sides. //I'll just opt for something similar (0/b00 North, 1/b01 South, 2/b10 West, 3/b11 East) - + //Assumes meta is using the third and fourth bits. @Override public void onBlockPlacedBy(World world, int x, int y, int z, EntityLivingBase player, ItemStack stack) { int i = MathHelper.floor_double(player.rotationYaw * 4.0F / 360.0F + 0.5D) & 3; - + int meta; - + if((i & 1) != 1) meta = i >> 1; //For North(b00>b00) and South(b10>b01), shift bits right by one else { @@ -53,15 +54,15 @@ public class BlockDecoModel extends BlockEnumMulti { else meta = 3; //For East(b01>b11), just set to 3 } - + world.setBlockMetadataWithNotify(x, y, z, (meta << 2) | stack.getItemDamage(), 2); } - + @Override public int damageDropped(int meta) { return meta & 3; } - + //These are separate because they have to be constant private float mnX = 0.0F; //min private float mnY = 0.0F; @@ -69,7 +70,7 @@ public class BlockDecoModel extends BlockEnumMulti { private float mxX = 1.0F; //max private float mxY = 1.0F; private float mxZ = 1.0F; - + public BlockDecoModel setBlockBoundsTo(float minX, float minY, float minZ, float maxX, float maxY, float maxZ) { mnX = minX; mnY = minY; @@ -77,10 +78,10 @@ public class BlockDecoModel extends BlockEnumMulti { mxX = maxX; mxY = maxY; mxZ = maxZ; - + return this; } - + @Override public void setBlockBoundsBasedOnState(IBlockAccess world, int x, int y, int z) { switch(world.getBlockMetadata(x, y, z) >> 2) { @@ -98,10 +99,39 @@ public class BlockDecoModel extends BlockEnumMulti { break; } } - + @Override public AxisAlignedBB getCollisionBoundingBoxFromPool(World world, int x, int y, int z) { this.setBlockBoundsBasedOnState(world, x, y, z); return AxisAlignedBB.getBoundingBox(x + this.minX, y + this.minY, z + this.minZ, x + this.maxX, y + this.maxY, z + this.maxZ); } + + @Override + public int transformMeta(int meta, int coordBaseMode) { + //N: 0b00, S: 0b01, W: 0b10, E: 0b11 + int rot = meta >> 2; + int type = meta & 3; + + switch(coordBaseMode) { + default: //South + break; + case 1: //West + if((rot & 3) < 2) //N & S can just have bits toggled + rot = rot ^ 3; + else //W & E can just have first bit set to 0 + rot = rot ^ 2; + break; + case 2: //North + rot = rot ^ 1; //N, W, E & S can just have first bit toggled + break; + case 3: //East + if((rot & 3) < 2)//N & S can just have second bit set to 1 + rot = rot ^ 2; + else //W & E can just have bits toggled + rot = rot ^ 3; + break; + } + //genuinely like. why did i do that + return (rot << 2) | type; //To accommodate for BlockDecoModel's shift in the rotation bits; otherwise, simply bit-shift right and or any non-rotation meta after + } } \ No newline at end of file diff --git a/src/main/java/com/hbm/blocks/generic/BlockDecoToaster.java b/src/main/java/com/hbm/blocks/generic/BlockDecoToaster.java index a11061fa0..c35dd1d3b 100644 --- a/src/main/java/com/hbm/blocks/generic/BlockDecoToaster.java +++ b/src/main/java/com/hbm/blocks/generic/BlockDecoToaster.java @@ -2,6 +2,7 @@ package com.hbm.blocks.generic; import com.hbm.blocks.BlockMulti; import com.hbm.lib.RefStrings; +import com.hbm.world.gen.INBTTransformable; import cpw.mods.fml.client.registry.RenderingRegistry; import cpw.mods.fml.relauncher.Side; @@ -16,7 +17,7 @@ import net.minecraft.util.MathHelper; import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; -public class BlockDecoToaster extends BlockMulti { +public class BlockDecoToaster extends BlockMulti implements INBTTransformable { protected String[] variants = new String[] {"toaster_iron", "toaster_steel", "toaster_wood"}; @SideOnly(Side.CLIENT) protected IIcon[] icons; @@ -26,17 +27,17 @@ public class BlockDecoToaster extends BlockMulti { } public static int renderID = RenderingRegistry.getNextAvailableRenderId(); - + @Override public int getRenderType(){ return renderID; } - + @Override public boolean isOpaqueCube() { return false; } - + @Override public boolean renderAsNormalBlock() { return false; @@ -47,12 +48,12 @@ public class BlockDecoToaster extends BlockMulti { public void registerBlockIcons(IIconRegister reg) { super.registerBlockIcons(reg); this.icons = new IIcon[variants.length]; - + for(int i = 0; i < variants.length; i++) { this.icons[i] = reg.registerIcon(RefStrings.MODID + ":" + variants[i]); } } - + @Override @SideOnly(Side.CLIENT) public IIcon getIcon(int side, int meta) { @@ -63,7 +64,7 @@ public class BlockDecoToaster extends BlockMulti { public int damageDropped(int meta) { return (Math.abs(meta) % 12) / 4; } - + @Override public void onBlockPlacedBy(World world, int x, int y, int z, EntityLivingBase player, ItemStack stack) { int i = MathHelper.floor_double(player.rotationYaw * 4.0F / 360.0F + 0.5D) & 3; @@ -90,4 +91,10 @@ public class BlockDecoToaster extends BlockMulti { this.setBlockBoundsBasedOnState(world, x, y, z); return AxisAlignedBB.getBoundingBox(x + this.minX, y + this.minY, z + this.minZ, x + this.maxX, y + this.maxY, z + this.maxZ); } -} + + @Override + public int transformMeta(int meta, int coordBaseMode) { + return INBTTransformable.transformMetaDecoModel(meta, coordBaseMode); + } + +} \ No newline at end of file diff --git a/src/main/java/com/hbm/blocks/generic/BlockPipe.java b/src/main/java/com/hbm/blocks/generic/BlockPipe.java index a41d6cfdf..27eaf3b27 100644 --- a/src/main/java/com/hbm/blocks/generic/BlockPipe.java +++ b/src/main/java/com/hbm/blocks/generic/BlockPipe.java @@ -4,6 +4,7 @@ import java.util.List; import com.hbm.blocks.ITooltipProvider; import com.hbm.lib.RefStrings; +import com.hbm.world.gen.INBTTransformable; import cpw.mods.fml.client.registry.RenderingRegistry; import cpw.mods.fml.relauncher.Side; @@ -16,7 +17,7 @@ import net.minecraft.item.ItemStack; import net.minecraft.util.IIcon; import net.minecraft.world.World; -public class BlockPipe extends Block implements ITooltipProvider { +public class BlockPipe extends Block implements ITooltipProvider, INBTTransformable { @SideOnly(Side.CLIENT) private IIcon sideIcon; @@ -24,7 +25,7 @@ public class BlockPipe extends Block implements ITooltipProvider { public IIcon frameIcon; @SideOnly(Side.CLIENT) public IIcon meshIcon; - + private String sideString; public int rType = 0; //because registering either new renderer classes or making new block classes is a pain in the ass @@ -33,7 +34,7 @@ public class BlockPipe extends Block implements ITooltipProvider { this.sideString = tex; this.rType = rType; } - + @Override @SideOnly(Side.CLIENT) public void registerBlockIcons(IIconRegister iconRegister) { @@ -42,7 +43,7 @@ public class BlockPipe extends Block implements ITooltipProvider { this.frameIcon = iconRegister.registerIcon(RefStrings.MODID + ":pipe_frame"); this.meshIcon = iconRegister.registerIcon(RefStrings.MODID + ":pipe_mesh"); } - + @Override @SideOnly(Side.CLIENT) public IIcon getIcon(int side, int metadata) { @@ -92,4 +93,10 @@ public class BlockPipe extends Block implements ITooltipProvider { public void addInformation(ItemStack stack, EntityPlayer player, List list, boolean ext) { list.add("Purely decorative"); } -} + + @Override + public int transformMeta(int meta, int coordBaseMode) { + return INBTTransformable.transformMetaPillar(meta, coordBaseMode); + } + +} \ No newline at end of file diff --git a/src/main/java/com/hbm/blocks/generic/BlockWand.java b/src/main/java/com/hbm/blocks/generic/BlockWand.java new file mode 100644 index 000000000..c25c390eb --- /dev/null +++ b/src/main/java/com/hbm/blocks/generic/BlockWand.java @@ -0,0 +1,51 @@ +package com.hbm.blocks.generic; + +import cpw.mods.fml.client.registry.RenderingRegistry; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import net.minecraft.block.Block; +import net.minecraft.block.material.Material; +import net.minecraft.util.AxisAlignedBB; +import net.minecraft.world.IBlockAccess; +import net.minecraft.world.World; + +public class BlockWand extends Block { + + public final Block exportAs; + + public BlockWand(Block exportAs) { + super(Material.glass); + this.exportAs = exportAs; + setBlockBounds(1F/16F, 1F/16F, 1F/16F, 15F/16F, 15F/16F, 15F/16F); + } + + @Override + public boolean isOpaqueCube() { + return false; + } + + @Override + public boolean renderAsNormalBlock() { + return false; + } + + @Override + public AxisAlignedBB getCollisionBoundingBoxFromPool(World world, int x, int y, int z) { + return null; + } + + public static int renderID = RenderingRegistry.getNextAvailableRenderId(); + + @Override + public int getRenderType() { + return renderID; + } + + @SideOnly(Side.CLIENT) + public boolean shouldSideBeRendered(IBlockAccess world, int x, int y, int z, int side) { + Block block = world.getBlock(x, y, z); + + return block != this; + } + +} \ No newline at end of file diff --git a/src/main/java/com/hbm/blocks/generic/BlockWandJigsaw.java b/src/main/java/com/hbm/blocks/generic/BlockWandJigsaw.java new file mode 100644 index 000000000..a8a44a55e --- /dev/null +++ b/src/main/java/com/hbm/blocks/generic/BlockWandJigsaw.java @@ -0,0 +1,387 @@ +package com.hbm.blocks.generic; + +import java.util.ArrayList; +import java.util.List; + +import org.lwjgl.input.Keyboard; + +import com.hbm.blocks.IBlockSideRotation; +import com.hbm.blocks.ILookOverlay; +import com.hbm.blocks.ModBlocks; +import com.hbm.interfaces.IControlReceiver; +import com.hbm.lib.RefStrings; +import com.hbm.main.MainRegistry; +import com.hbm.packet.PacketDispatcher; +import com.hbm.packet.toserver.NBTControlPacket; +import com.hbm.tileentity.IGUIProvider; +import com.hbm.tileentity.TileEntityLoadedBase; +import com.hbm.util.BufferUtil; +import com.hbm.util.I18nUtil; +import com.hbm.world.gen.INBTTransformable; + +import cpw.mods.fml.common.network.internal.FMLNetworkHandler; +import cpw.mods.fml.common.registry.GameRegistry; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import io.netty.buffer.ByteBuf; +import net.minecraft.block.Block; +import net.minecraft.block.BlockContainer; +import net.minecraft.block.BlockPistonBase; +import net.minecraft.block.material.Material; +import net.minecraft.client.gui.GuiButton; +import net.minecraft.client.gui.GuiScreen; +import net.minecraft.client.gui.GuiTextField; +import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.init.Blocks; +import net.minecraft.inventory.Container; +import net.minecraft.item.ItemBlock; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.EnumChatFormatting; +import net.minecraft.util.IIcon; +import net.minecraft.world.IBlockAccess; +import net.minecraft.world.World; +import net.minecraftforge.client.event.RenderGameOverlayEvent.Pre; + +public class BlockWandJigsaw extends BlockContainer implements IBlockSideRotation, INBTTransformable, IGUIProvider, ILookOverlay { + + private IIcon iconTop; + private IIcon iconSide; + private IIcon iconBack; + + public BlockWandJigsaw() { + super(Material.iron); + } + + @Override + public TileEntity createNewTileEntity(World world, int meta) { + return new TileEntityWandJigsaw(); + } + + @Override + public void onBlockPlacedBy(World world, int x, int y, int z, EntityLivingBase player, ItemStack stack) { + int l = BlockPistonBase.determineOrientation(world, x, y, z, player); + world.setBlockMetadataWithNotify(x, y, z, l, 2); + } + + @Override + @SideOnly(Side.CLIENT) + public void registerBlockIcons(IIconRegister iconRegister) { + this.blockIcon = iconRegister.registerIcon(RefStrings.MODID + ":wand_jigsaw"); + this.iconTop = iconRegister.registerIcon(RefStrings.MODID + ":wand_jigsaw_top"); + this.iconSide = iconRegister.registerIcon(RefStrings.MODID + ":wand_jigsaw_side"); + this.iconBack = iconRegister.registerIcon(RefStrings.MODID + ":wand_jigsaw_back"); + } + + @Override + public IIcon getIcon(int side, int meta) { + if(side == meta) return blockIcon; + if(IBlockSideRotation.isOpposite(side, meta)) return iconBack; + if(side <= 1) return iconTop; + if(side > 3 && meta <= 1) return iconTop; + return iconSide; + } + + @Override + public int getRotationFromSide(IBlockAccess world, int x, int y, int z, int side) { + if(side == 0) return IBlockSideRotation.topToBottom(getRotationFromSide(world, x, y, z, 1)); + + int meta = world.getBlockMetadata(x, y, z); + if(side == meta || IBlockSideRotation.isOpposite(side, meta)) return 0; + + // downwards facing has no changes, upwards flips anything not handled already + if(meta == 0) return 0; + if(meta == 1) return 3; + + // top (and bottom) is rotated fairly normally + if(side == 1) { + switch(meta) { + case 2: return 3; + case 3: return 0; + case 4: return 1; + case 5: return 2; + } + } + + // you know what I aint explaining further, it's a fucking mess here + if(meta == 2) return side == 4 ? 2 : 1; + if(meta == 3) return side == 4 ? 1 : 2; + if(meta == 4) return side == 2 ? 1 : 2; + if(meta == 5) return side == 2 ? 2 : 1; + + return 0; + } + + @Override + public int getRenderType() { + return IBlockSideRotation.getRenderType(); + } + + @Override + public int transformMeta(int meta, int coordBaseMode) { + return INBTTransformable.transformMetaDeco(meta, coordBaseMode); + } + + @Override + public boolean onBlockActivated(World world, int x, int y, int z, EntityPlayer player, int side, float hitX, float hitY, float hitZ) { + TileEntity te = world.getTileEntity(x, y, z); + + if(!(te instanceof TileEntityWandJigsaw)) return false; + + TileEntityWandJigsaw jigsaw = (TileEntityWandJigsaw) te; + + if(!player.isSneaking()) { + Block block = getBlock(world, player.getHeldItem()); + if(block == ModBlocks.wand_air) block = Blocks.air; + + if(block != null && block != ModBlocks.wand_jigsaw && block != ModBlocks.wand_loot) { + jigsaw.replaceBlock = block; + jigsaw.replaceMeta = player.getHeldItem().getItemDamage(); + + return true; + } + + if(world.isRemote) FMLNetworkHandler.openGui(player, MainRegistry.instance, 0, world, x, y, z); + + return true; + } + + return false; + } + + private Block getBlock(World world, ItemStack stack) { + if(stack == null) return null; + if(!(stack.getItem() instanceof ItemBlock)) return null; + + return ((ItemBlock) stack.getItem()).field_150939_a; + } + + @Override + @SideOnly(Side.CLIENT) + public Object provideGUI(int ID, EntityPlayer player, World world, int x, int y, int z) { + return new GuiWandJigsaw((TileEntityWandJigsaw) world.getTileEntity(x, y, z)); + } + + @Override + public Container provideContainer(int ID, EntityPlayer player, World world, int x, int y, int z) { + return null; + } + + @Override + public void printHook(Pre event, World world, int x, int y, int z) { + TileEntity te = world.getTileEntity(x, y, z); + if(!(te instanceof TileEntityWandJigsaw)) return; + TileEntityWandJigsaw jigsaw = (TileEntityWandJigsaw) te; + + List text = new ArrayList(); + + text.add(EnumChatFormatting.GRAY + "Target pool: " + EnumChatFormatting.RESET + jigsaw.pool); + text.add(EnumChatFormatting.GRAY + "Name: " + EnumChatFormatting.RESET + jigsaw.name); + text.add(EnumChatFormatting.GRAY + "Target name: " + EnumChatFormatting.RESET + jigsaw.target); + text.add(EnumChatFormatting.GRAY + "Turns into: " + EnumChatFormatting.RESET + GameRegistry.findUniqueIdentifierFor(jigsaw.replaceBlock).toString()); + text.add(EnumChatFormatting.GRAY + " with meta: " + EnumChatFormatting.RESET + jigsaw.replaceMeta); + text.add(EnumChatFormatting.GRAY + "Selection/Placement priority: " + EnumChatFormatting.RESET + jigsaw.selectionPriority + "/" + jigsaw.placementPriority); + text.add(EnumChatFormatting.GRAY + "Joint type: " + EnumChatFormatting.RESET + (jigsaw.isRollable ? "Rollable" : "Aligned")); + + ILookOverlay.printGeneric(event, I18nUtil.resolveKey(getUnlocalizedName() + ".name"), 0xffff00, 0x404000, text); + } + + + public static class TileEntityWandJigsaw extends TileEntityLoadedBase implements IControlReceiver { + + private int selectionPriority = 0; // higher priority = this jigsaw block is selected first for generation + private int placementPriority = 0; // higher priority = children of this jigsaw block are checked for jigsaw blocks of their own and selected first + private String pool = "default"; + private String name = "default"; + private String target = "default"; + private Block replaceBlock = Blocks.air; + private int replaceMeta = 0; + private boolean isRollable = true; // sets joint type, rollable joints can be placed in any orientation for vertical jigsaw connections + + @Override + public void updateEntity() { + if(!worldObj.isRemote) { + networkPackNT(15); + } + } + + @Override + public void serialize(ByteBuf buf) { + buf.writeInt(selectionPriority); + buf.writeInt(placementPriority); + BufferUtil.writeString(buf, pool); + BufferUtil.writeString(buf, name); + BufferUtil.writeString(buf, target); + buf.writeInt(Block.getIdFromBlock(replaceBlock)); + buf.writeInt(replaceMeta); + buf.writeBoolean(isRollable); + } + + @Override + public void deserialize(ByteBuf buf) { + selectionPriority = buf.readInt(); + placementPriority = buf.readInt(); + pool = BufferUtil.readString(buf); + name = BufferUtil.readString(buf); + target = BufferUtil.readString(buf); + replaceBlock = Block.getBlockById(buf.readInt()); + replaceMeta = buf.readInt(); + isRollable = buf.readBoolean(); + } + + @Override + public void writeToNBT(NBTTagCompound nbt) { + super.writeToNBT(nbt); + nbt.setInteger("direction", this.getBlockMetadata()); + + nbt.setInteger("selection", selectionPriority); + nbt.setInteger("placement", placementPriority); + nbt.setString("pool", pool); + nbt.setString("name", name); + nbt.setString("target", target); + nbt.setString("block", GameRegistry.findUniqueIdentifierFor(replaceBlock).toString()); + nbt.setInteger("meta", replaceMeta); + nbt.setBoolean("roll", isRollable); + } + + @Override + public void readFromNBT(NBTTagCompound nbt) { + super.readFromNBT(nbt); + + selectionPriority = nbt.getInteger("selection"); + placementPriority = nbt.getInteger("placement"); + pool = nbt.getString("pool"); + name = nbt.getString("name"); + target = nbt.getString("target"); + replaceBlock = Block.getBlockFromName(nbt.getString("block")); + replaceMeta = nbt.getInteger("meta"); + isRollable = nbt.getBoolean("roll"); + } + + @Override + public boolean hasPermission(EntityPlayer player) { + return true; + } + + @Override + public void receiveControl(NBTTagCompound nbt) { + readFromNBT(nbt); + markDirty(); + } + + } + + public static class GuiWandJigsaw extends GuiScreen { + + private final TileEntityWandJigsaw jigsaw; + + private GuiTextField textPool; + private GuiTextField textName; + private GuiTextField textTarget; + + private GuiTextField textSelectionPriority; + private GuiTextField textPlacementPriority; + + private GuiButton jointToggle; + + public GuiWandJigsaw(TileEntityWandJigsaw jigsaw) { + this.jigsaw = jigsaw; + } + + @Override + public void initGui() { + Keyboard.enableRepeatEvents(true); + + textPool = new GuiTextField(fontRendererObj, this.width / 2 - 150, 50, 300, 20); + textPool.setText(jigsaw.pool); + + textName = new GuiTextField(fontRendererObj, this.width / 2 - 150, 100, 140, 20); + textName.setText(jigsaw.name); + + textTarget = new GuiTextField(fontRendererObj, this.width / 2 + 10, 100, 140, 20); + textTarget.setText(jigsaw.target); + + textSelectionPriority = new GuiTextField(fontRendererObj, this.width / 2 - 150, 150, 90, 20); + textSelectionPriority.setText("" + jigsaw.selectionPriority); + + textPlacementPriority = new GuiTextField(fontRendererObj, this.width / 2 - 40, 150, 90, 20); + textPlacementPriority.setText("" + jigsaw.placementPriority); + + jointToggle = new GuiButton(0, this.width / 2 + 60, 150, 90, 20, jigsaw.isRollable ? "Rollable" : "Aligned"); + } + + @Override + public void drawScreen(int mouseX, int mouseY, float partialTicks) { + drawDefaultBackground(); + + drawString(fontRendererObj, "Target pool:", this.width / 2 - 150, 37, 0xA0A0A0); + textPool.drawTextBox(); + + drawString(fontRendererObj, "Name:", this.width / 2 - 150, 87, 0xA0A0A0); + textName.drawTextBox(); + + drawString(fontRendererObj, "Target name:", this.width / 2 + 10, 87, 0xA0A0A0); + textTarget.drawTextBox(); + + drawString(fontRendererObj, "Selection priority:", this.width / 2 - 150, 137, 0xA0A0A0); + textSelectionPriority.drawTextBox(); + + drawString(fontRendererObj, "Placement priority:", this.width / 2 - 40, 137, 0xA0A0A0); + textPlacementPriority.drawTextBox(); + + drawString(fontRendererObj, "Joint type:", this.width / 2 + 60, 137, 0xA0A0A0); + jointToggle.drawButton(mc, mouseX, mouseY); + + super.drawScreen(mouseX, mouseY, partialTicks); + } + + @Override + public void onGuiClosed() { + Keyboard.enableRepeatEvents(false); + + NBTTagCompound data = new NBTTagCompound(); + jigsaw.writeToNBT(data); + + data.setString("pool", textPool.getText()); + data.setString("name", textName.getText()); + data.setString("target", textTarget.getText()); + + try { data.setInteger("selection", Integer.parseInt(textSelectionPriority.getText())); } catch(Exception ex) {} + try { data.setInteger("placement", Integer.parseInt(textPlacementPriority.getText())); } catch(Exception ex) {} + + data.setBoolean("roll", jointToggle.displayString == "Rollable"); + + PacketDispatcher.wrapper.sendToServer(new NBTControlPacket(data, jigsaw.xCoord, jigsaw.yCoord, jigsaw.zCoord)); + } + + @Override + protected void keyTyped(char typedChar, int keyCode) { + super.keyTyped(typedChar, keyCode); + textPool.textboxKeyTyped(typedChar, keyCode); + textName.textboxKeyTyped(typedChar, keyCode); + textTarget.textboxKeyTyped(typedChar, keyCode); + textSelectionPriority.textboxKeyTyped(typedChar, keyCode); + textPlacementPriority.textboxKeyTyped(typedChar, keyCode); + } + + @Override + protected void mouseClicked(int mouseX, int mouseY, int mouseButton) { + super.mouseClicked(mouseX, mouseY, mouseButton); + textPool.mouseClicked(mouseX, mouseY, mouseButton); + textName.mouseClicked(mouseX, mouseY, mouseButton); + textTarget.mouseClicked(mouseX, mouseY, mouseButton); + textSelectionPriority.mouseClicked(mouseX, mouseY, mouseButton); + textPlacementPriority.mouseClicked(mouseX, mouseY, mouseButton); + + if(jointToggle.mousePressed(mc, mouseX, mouseY)) { + System.out.println("displayString: " + jointToggle.displayString); + jointToggle.displayString = jointToggle.displayString == "Rollable" ? "Aligned" : "Rollable"; + } + } + + } + +} diff --git a/src/main/java/com/hbm/blocks/generic/BlockWandLoot.java b/src/main/java/com/hbm/blocks/generic/BlockWandLoot.java new file mode 100644 index 000000000..80b1f3b92 --- /dev/null +++ b/src/main/java/com/hbm/blocks/generic/BlockWandLoot.java @@ -0,0 +1,338 @@ +package com.hbm.blocks.generic; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.UUID; + +import com.hbm.blocks.IBlockSideRotation; +import com.hbm.blocks.ILookOverlay; +import com.hbm.blocks.ITooltipProvider; +import com.hbm.blocks.ModBlocks; +import com.hbm.config.StructureConfig; +import com.hbm.itempool.ItemPool; +import com.hbm.lib.RefStrings; +import com.hbm.tileentity.TileEntityLoadedBase; +import com.hbm.util.BufferUtil; +import com.hbm.util.I18nUtil; +import com.hbm.util.LootGenerator; +import com.hbm.world.gen.INBTTileEntityTransformable; +import com.mojang.authlib.GameProfile; + +import api.hbm.block.IToolable; +import cpw.mods.fml.common.registry.GameRegistry; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import io.netty.buffer.ByteBuf; +import net.minecraft.block.Block; +import net.minecraft.block.BlockContainer; +import net.minecraft.block.ITileEntityProvider; +import net.minecraft.block.material.Material; +import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.IInventory; +import net.minecraft.item.ItemBlock; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.EnumChatFormatting; +import net.minecraft.util.IIcon; +import net.minecraft.util.MathHelper; +import net.minecraft.util.WeightedRandomChestContent; +import net.minecraft.world.IBlockAccess; +import net.minecraft.world.World; +import net.minecraft.world.WorldServer; +import net.minecraftforge.client.event.RenderGameOverlayEvent.Pre; +import net.minecraftforge.common.util.FakePlayer; +import net.minecraftforge.common.util.FakePlayerFactory; + +public class BlockWandLoot extends BlockContainer implements ILookOverlay, IToolable, ITooltipProvider, IBlockSideRotation { + + @SideOnly(Side.CLIENT) protected IIcon iconTop; + + public BlockWandLoot() { + super(Material.iron); + } + + @Override + @SideOnly(Side.CLIENT) + public void registerBlockIcons(IIconRegister iconRegister) { + this.blockIcon = iconRegister.registerIcon(RefStrings.MODID + ":wand_loot"); + this.iconTop = iconRegister.registerIcon(RefStrings.MODID + ":wand_loot_top"); + } + + @Override + public IIcon getIcon(int side, int meta) { + return (side <= 1) ? iconTop : blockIcon; + } + + @Override + public int getRotationFromSide(IBlockAccess world, int x, int y, int z, int side) { + if(side == 0) return IBlockSideRotation.topToBottom(world.getBlockMetadata(x, y, z)); + if(side == 1) return world.getBlockMetadata(x, y, z); + return 0; + } + + @Override + public int getRenderType() { + return IBlockSideRotation.getRenderType(); + } + + @Override + public void onBlockPlacedBy(World world, int x, int y, int z, EntityLivingBase player, ItemStack itemStack) { + int i = MathHelper.floor_double(player.rotationYaw * 4.0F / 360.0F + 0.5D) & 3; + + if(i == 0) world.setBlockMetadataWithNotify(x, y, z, 3, 2); + if(i == 1) world.setBlockMetadataWithNotify(x, y, z, 2, 2); + if(i == 2) world.setBlockMetadataWithNotify(x, y, z, 0, 2); + if(i == 3) world.setBlockMetadataWithNotify(x, y, z, 1, 2); + + TileEntity te = world.getTileEntity(x, y, z); + if(!(te instanceof TileEntityWandLoot)) return; + ((TileEntityWandLoot) te).placedRotation = player.rotationYaw; + } + + @Override + public void printHook(Pre event, World world, int x, int y, int z) { + TileEntity te = world.getTileEntity(x, y, z); + + if(!(te instanceof TileEntityWandLoot)) return; + + TileEntityWandLoot loot = (TileEntityWandLoot) te; + + List text = new ArrayList(); + text.add("Will replace with: " + loot.replaceBlock.getUnlocalizedName()); + text.add(" meta: " + loot.replaceMeta); + text.add("Loot pool: " + loot.poolName); + if(loot.replaceBlock != ModBlocks.deco_loot) { + text.add("Minimum items: " + loot.minItems); + text.add("Maximum items: " + loot.maxItems); + } + + ILookOverlay.printGeneric(event, I18nUtil.resolveKey(getUnlocalizedName() + ".name"), 0xffff00, 0x404000, text); + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Override + public void addInformation(ItemStack stack, EntityPlayer player, List list, boolean ext) { + list.add("Define loot crates/piles in .nbt structures"); + list.add(EnumChatFormatting.GOLD + "Use screwdriver to increase/decrease minimum loot"); + list.add(EnumChatFormatting.GOLD + "Use hand drill to increase/decrease maximum loot"); + list.add(EnumChatFormatting.GOLD + "Use defuser to cycle loot types"); + list.add(EnumChatFormatting.GOLD + "Use container block to set the block that spawns with loot inside"); + } + + @Override + public boolean onBlockActivated(World world, int x, int y, int z, EntityPlayer player, int side, float hitX, float hitY, float hitZ) { + TileEntity te = world.getTileEntity(x, y, z); + + if(!(te instanceof TileEntityWandLoot)) return false; + + TileEntityWandLoot loot = (TileEntityWandLoot) te; + + if(!player.isSneaking()) { + + Block block = getLootableBlock(world, player.getHeldItem()); + + if(block != null) { + loot.replaceBlock = block; + loot.replaceMeta = player.getHeldItem().getItemDamage(); + + List poolNames = loot.getPoolNames(block == ModBlocks.deco_loot); + if(!poolNames.contains(loot.poolName)) { + loot.poolName = poolNames.get(0); + } + + return true; + } + } + + return false; + } + + private Block getLootableBlock(World world, ItemStack stack) { + if(stack == null) return null; + + if(stack.getItem() instanceof ItemBlock) { + Block block = ((ItemBlock) stack.getItem()).field_150939_a; + + if(block == ModBlocks.deco_loot) return block; + + if(block instanceof ITileEntityProvider) { + TileEntity te = ((ITileEntityProvider) block).createNewTileEntity(world, 12); + if(te instanceof IInventory) return block; + } + } + + return null; + } + + @Override + public boolean onScrew(World world, EntityPlayer player, int x, int y, int z, int side, float fX, float fY, float fZ, ToolType tool) { + TileEntity te = world.getTileEntity(x, y, z); + + if(!(te instanceof TileEntityWandLoot)) return false; + + TileEntityWandLoot loot = (TileEntityWandLoot) te; + + switch(tool) { + case SCREWDRIVER: + if(player.isSneaking()) { + loot.minItems--; + if(loot.minItems < 0) loot.minItems = 0; + } else { + loot.minItems++; + loot.maxItems = Math.max(loot.minItems, loot.maxItems); + } + + return true; + + case HAND_DRILL: + if(player.isSneaking()) { + loot.maxItems--; + if(loot.maxItems < 0) loot.maxItems = 0; + loot.minItems = Math.min(loot.minItems, loot.maxItems); + } else { + loot.maxItems++; + } + + return true; + + case DEFUSER: + List poolNames = loot.getPoolNames(loot.replaceBlock == ModBlocks.deco_loot); + int index = poolNames.indexOf(loot.poolName); + + index += player.isSneaking() ? -1 : 1; + index = MathHelper.clamp_int(index, 0, poolNames.size() - 1); + + loot.poolName = poolNames.get(index); + + return true; + + default: return false; + } + } + + @Override + public TileEntity createNewTileEntity(World world, int meta) { + return new TileEntityWandLoot(); + } + + public static class TileEntityWandLoot extends TileEntityLoadedBase implements INBTTileEntityTransformable { + + private boolean triggerReplace; + + private Block replaceBlock = ModBlocks.deco_loot; + private int replaceMeta; + + private String poolName = LootGenerator.LOOT_BOOKLET; + private int minItems; + private int maxItems = 1; + + private float placedRotation; + + private static final GameProfile FAKE_PROFILE = new GameProfile(UUID.fromString("839eb18c-50bc-400c-8291-9383f09763e7"), "[NTM]"); + private static FakePlayer fakePlayer; + + @Override + public void updateEntity() { + if(!worldObj.isRemote) { + if(triggerReplace) { + // On the first tick of this TE, replace with intended block and fill with loot + replace(); + } else { + networkPackNT(15); + } + } + } + + private void replace() { + WeightedRandomChestContent[] pool = ItemPool.getPool(poolName); + + worldObj.setBlock(xCoord, yCoord, zCoord, replaceBlock, replaceMeta, 2); + + TileEntity te = worldObj.getTileEntity(xCoord, yCoord, zCoord); + + if(te instanceof IInventory) { + int count = minItems; + if(maxItems - minItems > 0) count += worldObj.rand.nextInt(maxItems - minItems); + WeightedRandomChestContent.generateChestContents(worldObj.rand, pool, (IInventory) te, count); + } else if(te instanceof BlockLoot.TileEntityLoot) { + LootGenerator.applyLoot(worldObj, xCoord, yCoord, zCoord, poolName); + } + + // Shouldn't happen but let's guard anyway, if it fails we just don't rotate the chest block correctly + if(!(worldObj instanceof WorldServer)) return; + + if(fakePlayer == null || fakePlayer.worldObj != worldObj) { + fakePlayer = FakePlayerFactory.get((WorldServer)worldObj, FAKE_PROFILE); + } + + fakePlayer.rotationYaw = fakePlayer.rotationYawHead = placedRotation; + + ItemStack fakeStack = new ItemStack(replaceBlock, 1, replaceMeta); + + replaceBlock.onBlockPlacedBy(worldObj, xCoord, yCoord, zCoord, fakePlayer, fakeStack); + } + + private List getPoolNames(boolean loot) { + if(loot) return Arrays.asList(LootGenerator.getLootNames()); + + List names = new ArrayList<>(); + names.addAll(ItemPool.pools.keySet()); + return names; + } + + @Override + public void transformTE(World world, int coordBaseMode) { + triggerReplace = !StructureConfig.debugStructures; + placedRotation = MathHelper.wrapAngleTo180_float(placedRotation + coordBaseMode * 90); + } + + @Override + public void writeToNBT(NBTTagCompound nbt) { + super.writeToNBT(nbt); + Block writeBlock = replaceBlock == null ? ModBlocks.deco_loot : replaceBlock; + nbt.setString("block", GameRegistry.findUniqueIdentifierFor(writeBlock).toString()); + nbt.setInteger("meta", replaceMeta); + nbt.setInteger("min", minItems); + nbt.setInteger("max", maxItems); + nbt.setString("pool", poolName); + nbt.setFloat("rot", placedRotation); + } + + @Override + public void readFromNBT(NBTTagCompound nbt) { + super.readFromNBT(nbt); + replaceBlock = Block.getBlockFromName(nbt.getString("block")); + replaceMeta = nbt.getInteger("meta"); + minItems = nbt.getInteger("min"); + maxItems = nbt.getInteger("max"); + poolName = nbt.getString("pool"); + placedRotation = nbt.getFloat("rot"); + + if(replaceBlock == null) replaceBlock = ModBlocks.deco_loot; + } + + @Override + public void serialize(ByteBuf buf) { + buf.writeInt(Block.getIdFromBlock(replaceBlock)); + buf.writeInt(replaceMeta); + buf.writeInt(minItems); + buf.writeInt(maxItems); + BufferUtil.writeString(buf, poolName); + } + + @Override + public void deserialize(ByteBuf buf) { + replaceBlock = Block.getBlockById(buf.readInt()); + replaceMeta = buf.readInt(); + minItems = buf.readInt(); + maxItems = buf.readInt(); + poolName = BufferUtil.readString(buf); + } + + } + +} \ No newline at end of file diff --git a/src/main/java/com/hbm/blocks/generic/DecoBlock.java b/src/main/java/com/hbm/blocks/generic/DecoBlock.java index 9037b4f6a..bf25850eb 100644 --- a/src/main/java/com/hbm/blocks/generic/DecoBlock.java +++ b/src/main/java/com/hbm/blocks/generic/DecoBlock.java @@ -6,6 +6,7 @@ import java.util.Random; import com.hbm.blocks.ModBlocks; import com.hbm.tileentity.deco.TileEntityDecoBlock; +import com.hbm.world.gen.INBTTransformable; import api.hbm.block.IToolable; import cpw.mods.fml.client.registry.RenderingRegistry; @@ -24,8 +25,8 @@ import net.minecraft.util.MathHelper; import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; -public class DecoBlock extends BlockContainer implements IToolable { - +public class DecoBlock extends BlockContainer implements IToolable, INBTTransformable { + Random rand = new Random(); public DecoBlock(Material p_i45386_1_) { @@ -36,7 +37,7 @@ public class DecoBlock extends BlockContainer implements IToolable { public boolean onScrew(World world, EntityPlayer player, int x, int y, int z, int side, float fX, float fY, float fZ, ToolType tool) { if(tool != ToolType.SCREWDRIVER) return false; if(this != ModBlocks.steel_wall && this != ModBlocks.steel_corner) return false; - + int meta = world.getBlockMetadata(x, y, z); if(!player.isSneaking()) { @@ -50,7 +51,7 @@ public class DecoBlock extends BlockContainer implements IToolable { else if(meta == 2) world.setBlockMetadataWithNotify(x, y, z, 4, 3); else if(meta == 5) world.setBlockMetadataWithNotify(x, y, z, 2, 3); } - + return true; } @@ -65,7 +66,7 @@ public class DecoBlock extends BlockContainer implements IToolable { public static int renderIDBeam = RenderingRegistry.getNextAvailableRenderId(); public static int renderIDWall = RenderingRegistry.getNextAvailableRenderId(); public static int renderIDCorner = RenderingRegistry.getNextAvailableRenderId(); - + @Override public int getRenderType(){ if(this == ModBlocks.steel_wall) return renderIDWall; @@ -73,32 +74,32 @@ public class DecoBlock extends BlockContainer implements IToolable { if(this == ModBlocks.steel_beam) return renderIDBeam; return -1; } - + @Override public boolean isOpaqueCube() { return false; } - + @Override public boolean renderAsNormalBlock() { return false; } - + @Override public Item getItemDropped(int p_149650_1_, Random p_149650_2_, int p_149650_3_) { return Item.getItemFromBlock(this); } - + @Override public void onBlockPlacedBy(World world, int x, int y, int z, EntityLivingBase player, ItemStack itemStack) { int i = MathHelper.floor_double(player.rotationYaw * 4.0F / 360.0F + 0.5D) & 3; - + if(i == 0) world.setBlockMetadataWithNotify(x, y, z, 3, 2); if(i == 1) world.setBlockMetadataWithNotify(x, y, z, 4, 2); if(i == 2) world.setBlockMetadataWithNotify(x, y, z, 2, 2); if(i == 3) world.setBlockMetadataWithNotify(x, y, z, 5, 2); } - + @Override public void setBlockBoundsBasedOnState(IBlockAccess world, int x, int y, int z) { int te = world.getBlockMetadata(x, y, z); @@ -141,14 +142,14 @@ public class DecoBlock extends BlockContainer implements IToolable { this.setBlockBoundsBasedOnState(world, x, y, z); return AxisAlignedBB.getBoundingBox(x + this.minX, y + this.minY, z + this.minZ, x + this.maxX, y + this.maxY, z + this.maxZ); } - + @Override public void addCollisionBoxesToList(World world, int x, int y, int z, AxisAlignedBB aabb, List list, Entity collider) { - + if(this == ModBlocks.steel_corner) { int meta = world.getBlockMetadata(x, y, z); List bbs = new ArrayList(); - + switch(meta) { case 2: bbs.add(AxisAlignedBB.getBoundingBox(x + 0.25D, y + 0D, z + 0.875D, x + 1D, y + 1D, z + 1D)); @@ -171,7 +172,7 @@ public class DecoBlock extends BlockContainer implements IToolable { bbs.add(AxisAlignedBB.getBoundingBox(x + 0.25D, y + 0D, z + 0D, x + 1D, y + 1D, z + 0.125D)); break; } - + for(AxisAlignedBB bb : bbs) { if(aabb.intersectsWith(bb)) { list.add(bb); @@ -181,4 +182,9 @@ public class DecoBlock extends BlockContainer implements IToolable { super.addCollisionBoxesToList(world, x, y, z, aabb, list, collider); } } -} + + @Override + public int transformMeta(int meta, int coordBaseMode) { + return INBTTransformable.transformMetaDeco(meta, coordBaseMode); + } +} \ No newline at end of file diff --git a/src/main/java/com/hbm/blocks/generic/DecoPoleSatelliteReceiver.java b/src/main/java/com/hbm/blocks/generic/DecoPoleSatelliteReceiver.java index 481236f78..109cabbc5 100644 --- a/src/main/java/com/hbm/blocks/generic/DecoPoleSatelliteReceiver.java +++ b/src/main/java/com/hbm/blocks/generic/DecoPoleSatelliteReceiver.java @@ -1,6 +1,7 @@ package com.hbm.blocks.generic; import com.hbm.tileentity.deco.TileEntityDecoPoleSatelliteReceiver; +import com.hbm.world.gen.INBTTransformable; import net.minecraft.block.BlockContainer; import net.minecraft.block.material.Material; @@ -10,7 +11,7 @@ import net.minecraft.tileentity.TileEntity; import net.minecraft.util.MathHelper; import net.minecraft.world.World; -public class DecoPoleSatelliteReceiver extends BlockContainer { +public class DecoPoleSatelliteReceiver extends BlockContainer implements INBTTransformable { public DecoPoleSatelliteReceiver(Material p_i45386_1_) { super(p_i45386_1_); @@ -20,26 +21,26 @@ public class DecoPoleSatelliteReceiver extends BlockContainer { public TileEntity createNewTileEntity(World p_149915_1_, int p_149915_2_) { return new TileEntityDecoPoleSatelliteReceiver(); } - + @Override public int getRenderType(){ return -1; } - + @Override public boolean isOpaqueCube() { return false; } - + @Override public boolean renderAsNormalBlock() { return false; } - + @Override public void onBlockPlacedBy(World world, int x, int y, int z, EntityLivingBase player, ItemStack itemStack) { int i = MathHelper.floor_double(player.rotationYaw * 4.0F / 360.0F + 0.5D) & 3; - + if(i == 0) { world.setBlockMetadataWithNotify(x, y, z, 2, 2); @@ -58,4 +59,9 @@ public class DecoPoleSatelliteReceiver extends BlockContainer { } } -} + @Override + public int transformMeta(int meta, int coordBaseMode) { + return INBTTransformable.transformMetaDeco(meta, coordBaseMode); + } + +} \ No newline at end of file diff --git a/src/main/java/com/hbm/blocks/generic/DecoTapeRecorder.java b/src/main/java/com/hbm/blocks/generic/DecoTapeRecorder.java index 6d94427e2..e7143aae6 100644 --- a/src/main/java/com/hbm/blocks/generic/DecoTapeRecorder.java +++ b/src/main/java/com/hbm/blocks/generic/DecoTapeRecorder.java @@ -1,5 +1,7 @@ package com.hbm.blocks.generic; +import com.hbm.world.gen.INBTTransformable; + import cpw.mods.fml.client.registry.RenderingRegistry; import net.minecraft.block.BlockContainer; import net.minecraft.block.material.Material; @@ -9,7 +11,7 @@ import net.minecraft.tileentity.TileEntity; import net.minecraft.util.MathHelper; import net.minecraft.world.World; -public class DecoTapeRecorder extends BlockContainer { +public class DecoTapeRecorder extends BlockContainer implements INBTTransformable { public DecoTapeRecorder(Material p_i45386_1_) { super(p_i45386_1_); @@ -19,28 +21,28 @@ public class DecoTapeRecorder extends BlockContainer { public TileEntity createNewTileEntity(World p_149915_1_, int p_149915_2_) { return null; } - + public static int renderID = RenderingRegistry.getNextAvailableRenderId(); - + @Override public int getRenderType(){ return renderID; } - + @Override public boolean isOpaqueCube() { return false; } - + @Override public boolean renderAsNormalBlock() { return false; } - + @Override public void onBlockPlacedBy(World world, int x, int y, int z, EntityLivingBase player, ItemStack itemStack) { int i = MathHelper.floor_double(player.rotationYaw * 4.0F / 360.0F + 0.5D) & 3; - + if(i == 0) { world.setBlockMetadataWithNotify(x, y, z, 2, 2); @@ -59,4 +61,9 @@ public class DecoTapeRecorder extends BlockContainer { } } -} + @Override + public int transformMeta(int meta, int coordBaseMode) { + return INBTTransformable.transformMetaDeco(meta, coordBaseMode); + } + +} \ No newline at end of file diff --git a/src/main/java/com/hbm/blocks/machine/Spotlight.java b/src/main/java/com/hbm/blocks/machine/Spotlight.java index c40a9ef9c..f5a89d404 100644 --- a/src/main/java/com/hbm/blocks/machine/Spotlight.java +++ b/src/main/java/com/hbm/blocks/machine/Spotlight.java @@ -7,6 +7,7 @@ import java.util.Random; import com.hbm.blocks.BlockEnums.LightType; import com.hbm.blocks.ISpotlight; import com.hbm.main.ResourceManager; +import com.hbm.world.gen.INBTTransformable; import cpw.mods.fml.client.registry.RenderingRegistry; import cpw.mods.fml.relauncher.Side; @@ -14,6 +15,7 @@ import cpw.mods.fml.relauncher.SideOnly; import net.minecraft.block.Block; import net.minecraft.block.BlockSlab; import net.minecraft.block.material.Material; +import net.minecraft.init.Blocks; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.util.AxisAlignedBB; @@ -22,7 +24,7 @@ import net.minecraft.world.World; import net.minecraftforge.client.model.obj.WavefrontObject; import net.minecraftforge.common.util.ForgeDirection; -public class Spotlight extends Block implements ISpotlight { +public class Spotlight extends Block implements ISpotlight, INBTTransformable { // I'd be extending the ReinforcedLamp class if it wasn't for the inverted behaviour of these specific lights // I want these blocks to be eminently useful, so removing the need for redstone by default is desired, @@ -38,7 +40,7 @@ public class Spotlight extends Block implements ISpotlight { this.beamLength = beamLength; this.type = type; this.isOn = isOn; - + this.setHardness(1F); if(isOn) setLightLevel(1.0F); @@ -123,6 +125,8 @@ public class Spotlight extends Block implements ISpotlight { } private boolean updatePower(World world, int x, int y, int z) { + if(isBroken(world.getBlockMetadata(x, y, z))) return false; + boolean isPowered = world.isBlockIndirectlyGettingPowered(x, y, z); if(isOn && isPowered) { world.scheduleBlockUpdate(x, y, z, this, 4); @@ -148,7 +152,7 @@ public class Spotlight extends Block implements ISpotlight { @Override public void updateTick(World world, int x, int y, int z, Random p_149674_5_) { if (world.isRemote) return; - + if (isOn && world.isBlockIndirectlyGettingPowered(x, y, z)) { world.setBlock(x, y, z, getOff(), world.getBlockMetadata(x, y, z), 2); } @@ -159,6 +163,7 @@ public class Spotlight extends Block implements ISpotlight { public void onNeighborBlockChange(World world, int x, int y, int z, Block neighborBlock) { if(world.isRemote) return; if(neighborBlock instanceof SpotlightBeam) return; + if(neighborBlock == Blocks.air) return; ForgeDirection dir = getDirection(world, x, y, z); @@ -172,13 +177,13 @@ public class Spotlight extends Block implements ISpotlight { updateBeam(world, x, y, z); } - + @Override public boolean canPlaceBlockOnSide(World world, int x, int y, int z, int side) { if(!super.canPlaceBlockOnSide(world, x, y, z, side)) return false; - + ForgeDirection dir = ForgeDirection.getOrientation(side); - + return canPlace(world, x, y, z, dir); } @@ -215,6 +220,10 @@ public class Spotlight extends Block implements ISpotlight { return ForgeDirection.getOrientation(metadata >> 1); } + public boolean isBroken(int metadata) { + return (metadata & 1) == 1; + } + @Override public Item getItemDropped(int i, Random r, int j) { return Item.getItemFromBlock(getOn()); @@ -292,20 +301,20 @@ public class Spotlight extends Block implements ISpotlight { backPropagate(world, x, y, z, dir); } - + protected Block getOff() { if(this == ModBlocks.spotlight_incandescent) return ModBlocks.spotlight_incandescent_off; if(this == ModBlocks.spotlight_fluoro) return ModBlocks.spotlight_fluoro_off; if(this == ModBlocks.spotlight_halogen) return ModBlocks.spotlight_halogen_off; - + return this; } - + protected Block getOn() { if(this == ModBlocks.spotlight_incandescent_off) return ModBlocks.spotlight_incandescent; if(this == ModBlocks.spotlight_fluoro_off) return ModBlocks.spotlight_fluoro; if(this == ModBlocks.spotlight_halogen_off) return ModBlocks.spotlight_halogen; - + return this; } @@ -313,4 +322,19 @@ public class Spotlight extends Block implements ISpotlight { public int getBeamLength() { return this.beamLength; } -} + + @Override + public int transformMeta(int meta, int coordBaseMode) { + // +1 to set as broken, won't turn on until broken and replaced + return (INBTTransformable.transformMetaDeco(meta >> 1, coordBaseMode) << 1) + 1; + } + + @Override + public Block transformBlock(Block block) { + if(block == ModBlocks.spotlight_incandescent) return ModBlocks.spotlight_incandescent_off; + if(block == ModBlocks.spotlight_fluoro) return ModBlocks.spotlight_fluoro_off; + if(block == ModBlocks.spotlight_halogen) return ModBlocks.spotlight_halogen_off; + return block; + } + +} \ No newline at end of file diff --git a/src/main/java/com/hbm/config/StructureConfig.java b/src/main/java/com/hbm/config/StructureConfig.java index 944a7cbb0..2f6bb9bf9 100644 --- a/src/main/java/com/hbm/config/StructureConfig.java +++ b/src/main/java/com/hbm/config/StructureConfig.java @@ -7,36 +7,40 @@ import com.hbm.main.MainRegistry; import net.minecraftforge.common.config.Configuration; public class StructureConfig { - + public static int enableStructures = 2; - + public static int structureMinChunks = 8; public static int structureMaxChunks = 24; - + public static double lootAmountFactor = 1D; - + + public static boolean debugStructures = false; + public static void loadFromConfig(Configuration config) { - + final String CATEGORY_STRUCTURES = CommonConfig.CATEGORY_STRUCTURES; String unparsedStructureFlag = CommonConfig.createConfigString(config, CATEGORY_STRUCTURES, "5.00_enableStructures", "Flag for whether modern NTM structures will spawn. Valid values are true|false|flag - flag will respect the \"Generate Structures\" world flag.", "flag"); enableStructures = CommonConfig.parseStructureFlag(unparsedStructureFlag); - + structureMinChunks = CommonConfig.createConfigInt(config, CATEGORY_STRUCTURES, "5.01_structureMinChunks", "Minimum non-zero distance between structures in chunks (Settings lower than 8 may be problematic).", 8); structureMaxChunks = CommonConfig.createConfigInt(config, CATEGORY_STRUCTURES, "5.02_structureMaxChunks", "Maximum non-zero distance between structures in chunks.", 24); - + lootAmountFactor = CommonConfig.createConfigDouble(config, CATEGORY_STRUCTURES, "5.03_lootAmountFactor", "General factor for loot spawns. Applies to spawned IInventories, not loot blocks.", 1D); - + + debugStructures = CommonConfig.createConfigBool(config, CATEGORY_STRUCTURES, "5.04_debugStructures", "If enabled, special structure blocks like jigsaw blocks will not be transformed after generating", false); + structureMinChunks = CommonConfig.setDef(structureMinChunks, 8); structureMaxChunks = CommonConfig.setDef(structureMaxChunks, 24); - + if(structureMinChunks > structureMaxChunks) { MainRegistry.logger.error("Fatal error config: Minimum value has been set higher than the maximum value!"); MainRegistry.logger.error(String.format(Locale.US, "Errored values will default back to %1$d and %2$d respectively, PLEASE REVIEW CONFIGURATION DESCRIPTION BEFORE MEDDLING WITH VALUES!", 8, 24)); structureMinChunks = 8; structureMaxChunks = 24; } - + } } diff --git a/src/main/java/com/hbm/crafting/handlers/MKUCraftingHandler.java b/src/main/java/com/hbm/crafting/handlers/MKUCraftingHandler.java index 5086e6388..8405b0f77 100644 --- a/src/main/java/com/hbm/crafting/handlers/MKUCraftingHandler.java +++ b/src/main/java/com/hbm/crafting/handlers/MKUCraftingHandler.java @@ -6,50 +6,52 @@ import java.util.List; import java.util.Random; import com.hbm.items.ModItems; +import com.hbm.items.special.ItemBookLore; import net.minecraft.inventory.InventoryCrafting; +import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.item.crafting.IRecipe; import net.minecraft.world.World; public class MKUCraftingHandler implements IRecipe { - + public static ItemStack[] MKURecipe; private static long lastSeed; @Override public boolean matches(InventoryCrafting inventory, World world) { - + if(world == null) return false; - + if(MKURecipe == null || world.getSeed() != lastSeed) generateRecipe(world); - + for(int i = 0; i < 9; i++) { ItemStack stack = inventory.getStackInRowAndColumn(i % 3, i / 3); ItemStack recipe = MKURecipe[i]; - + if(stack == null && recipe == null) continue; - + if(stack != null && recipe != null && stack.getItem() == recipe.getItem() && stack.getItemDamage() == recipe.getItemDamage()) continue; - + return false; } - + return true; } - + public static void generateRecipe(World world) { Random rand = new Random(world.getSeed()); - + if(lastSeed == world.getSeed() && MKURecipe != null) return; - + lastSeed = world.getSeed(); - + List list = Arrays.asList(new ItemStack[] { new ItemStack(ModItems.powder_iodine), new ItemStack(ModItems.powder_fire), @@ -61,12 +63,54 @@ public class MKUCraftingHandler implements IRecipe { null, null }); - + Collections.shuffle(list, rand); - + MKURecipe = list.toArray(new ItemStack[9]); } + public static Item getMKUItem(World world) { + switch(world.rand.nextInt(6)) { + case 0: return ModItems.powder_iodine; + case 1: return ModItems.powder_fire; + case 2: return ModItems.dust; + case 3: return ModItems.ingot_mercury; + case 4: return ModItems.morning_glory; + case 5: return ModItems.syringe_metal_empty; + default: return ModItems.flame_pony; + } + } + + public static ItemStack generateBook(World world, Item mkuItem) { + MKUCraftingHandler.generateRecipe(world); + ItemStack[] recipe = MKUCraftingHandler.MKURecipe; + + if(recipe == null) return new ItemStack(ModItems.flame_pony); + + String key = null; + int pages = 1; + if(mkuItem == ModItems.powder_iodine) { key = "book_iodine"; pages = 3; } + if(mkuItem == ModItems.powder_fire) { key = "book_phosphorous"; pages = 2; } + if(mkuItem == ModItems.dust) { key = "book_dust"; pages = 3; } + if(mkuItem == ModItems.ingot_mercury) { key = "book_mercury"; pages = 2; } + if(mkuItem == ModItems.morning_glory) { key = "book_flower"; pages = 2; } + if(mkuItem == ModItems.syringe_metal_empty) { key = "book_syringe"; pages = 2; } + + if(key == null) return new ItemStack(ModItems.flame_pony); + + int s = 1; + for(int i = 0; i < 9; i++) { + if(recipe[i] != null && recipe[i].getItem() == mkuItem) { + s = i + 1; break; + } + } + + ItemStack book = ItemBookLore.createBook(key, pages, 0x271E44, 0xFBFFF4); + ItemBookLore.addArgs(book, pages - 1, String.valueOf(s)); + + return book; + } + @Override public int getRecipeSize() { return 6; @@ -81,4 +125,4 @@ public class MKUCraftingHandler implements IRecipe { public ItemStack getRecipeOutput() { return new ItemStack(ModItems.syringe_mkunicorn); } -} +} \ No newline at end of file diff --git a/src/main/java/com/hbm/items/tool/ItemWandS.java b/src/main/java/com/hbm/items/tool/ItemWandS.java index 303a3114f..2de5998fb 100644 --- a/src/main/java/com/hbm/items/tool/ItemWandS.java +++ b/src/main/java/com/hbm/items/tool/ItemWandS.java @@ -1,7 +1,156 @@ package com.hbm.items.tool; +import java.util.Date; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.text.DateFormat; +import java.text.SimpleDateFormat; + +import com.hbm.blocks.ModBlocks; +import com.hbm.util.BobMathUtil; +import com.hbm.util.Tuple.Pair; +import com.hbm.world.gen.NBTStructure; + +import net.minecraft.block.Block; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.init.Blocks; import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.ChatComponentText; +import net.minecraft.util.EnumChatFormatting; +import net.minecraft.world.World; public class ItemWandS extends Item { - -} + + private static final DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd_HH.mm.ss"); + + @Override + public void addInformation(ItemStack stack, EntityPlayer player, List list, boolean bool) { + list.add("Creative-only item"); + list.add("\"Replication breeds decadence\""); + list.add("(Saves an area defined by two right-clicks,"); + list.add("adds a block to the blacklist by crouch right-clicking!)"); + + if(stack.stackTagCompound != null) { + int px = stack.stackTagCompound.getInteger("x"); + int py = stack.stackTagCompound.getInteger("y"); + int pz = stack.stackTagCompound.getInteger("z"); + + if(px != 0 || py != 0 || pz != 0) { + list.add(EnumChatFormatting.AQUA + "From: " + px + ", " + py + ", " + pz); + } else { + list.add(EnumChatFormatting.AQUA + "No start position set"); + } + + Set> blocks = getBlocks(stack); + + if(blocks.size() > 0) { + list.add("Blacklist:"); + for(Pair block : blocks) { + list.add(EnumChatFormatting.RED + "- " + block.key.getUnlocalizedName()); + } + } + } + } + + // why the fuck ye'd leave this whole thing obfuscated is beyond me + @Override + public boolean onItemUse(ItemStack stack, EntityPlayer player, World world, int x, int y, int z, int side, float fx, float fy, float fz) { + if(stack.stackTagCompound == null) { + stack.stackTagCompound = new NBTTagCompound(); + } + + if(player.isSneaking()) { + Pair target = new Pair(world.getBlock(x, y, z), world.getBlockMetadata(x, y, z)); + Set> blocks = getBlocks(stack); + + if(blocks.contains(target)) { + blocks.remove(target); + if(world.isRemote) player.addChatMessage(new ChatComponentText("Removed from blacklist " + target.key.getUnlocalizedName())); + } else { + blocks.add(target); + if(world.isRemote) player.addChatMessage(new ChatComponentText("Added to blacklist " + target.key.getUnlocalizedName())); + } + + setBlocks(stack, blocks); + + } else { + int px = stack.stackTagCompound.getInteger("x"); + int py = stack.stackTagCompound.getInteger("y"); + int pz = stack.stackTagCompound.getInteger("z"); + + if(px == 0 && py == 0 && pz == 0) { + setPosition(stack, x, y, z); + + if(world.isRemote) player.addChatMessage(new ChatComponentText("First position set!")); + } else { + setPosition(stack, 0, 0, 0); + + Set> blocks = getBlocks(stack); + blocks.add(new Pair(Blocks.air, 0)); + blocks.add(new Pair(ModBlocks.spotlight_beam, 0)); + + String filename = "structure_" + dateFormat.format(new Date()).toString() + ".nbt"; + + NBTStructure.saveArea(filename, world, x, y, z, px, py, pz, blocks); + + if(world.isRemote) player.addChatMessage(new ChatComponentText("Structure saved to: .minecraft/structures/" + filename)); + } + } + + return true; + } + + private void setPosition(ItemStack stack, int x, int y, int z) { + stack.stackTagCompound.setInteger("x", x); + stack.stackTagCompound.setInteger("y", y); + stack.stackTagCompound.setInteger("z", z); + } + + private Set> getBlocks(ItemStack stack) { + if(stack.stackTagCompound == null) { + return new HashSet<>(); + } + + int[] blockIds = stack.stackTagCompound.getIntArray("blocks"); + int[] metas = stack.stackTagCompound.getIntArray("metas"); + Set> blocks = new HashSet<>(blockIds.length); + + for(int i = 0; i < blockIds.length; i++) { + blocks.add(new Pair(Block.getBlockById(blockIds[i]), metas[i])); + } + + return blocks; + } + + @SuppressWarnings("unchecked") + private void setBlocks(ItemStack stack, Set> blocks) { + if(stack.stackTagCompound == null) { + stack.stackTagCompound = new NBTTagCompound(); + } + + stack.stackTagCompound.setIntArray("blocks", BobMathUtil.collectionToIntArray(blocks, i -> Block.getIdFromBlock(((Pair)i).getKey()))); + stack.stackTagCompound.setIntArray("metas", BobMathUtil.collectionToIntArray(blocks, i -> ((Pair)i).getValue())); + } + + @Override + public ItemStack onItemRightClick(ItemStack stack, World world, EntityPlayer player) { + if(stack.stackTagCompound == null) { + stack.stackTagCompound = new NBTTagCompound(); + } + + if(player.isSneaking()) { + stack.stackTagCompound.setIntArray("blocks", new int[0]); + stack.stackTagCompound.setIntArray("metas", new int[0]); + + if(world.isRemote) { + player.addChatMessage(new ChatComponentText("Cleared blacklist")); + } + } + + return stack; + } + +} \ No newline at end of file diff --git a/src/main/java/com/hbm/lib/HbmWorld.java b/src/main/java/com/hbm/lib/HbmWorld.java index 3cd40d0ba..ed4ca9208 100644 --- a/src/main/java/com/hbm/lib/HbmWorld.java +++ b/src/main/java/com/hbm/lib/HbmWorld.java @@ -1,6 +1,7 @@ package com.hbm.lib; import com.hbm.world.gen.MapGenNTMFeatures; +import com.hbm.world.gen.NBTStructure; import com.hbm.world.gen.NTMWorldGenerator; import com.hbm.world.gen.component.*; import com.hbm.world.gen.component.BunkerComponents.BunkerStart; @@ -18,9 +19,6 @@ public class HbmWorld { public static NTMWorldGenerator worldGenerator; public static void initWorldGen() { - - //MapGenStructureIO.registerStructure(StructureStartTest.class, "HFR_STRUCTURE"); - //MapGenStructureIO.func_143031_a(StructureComponentTest.class, "HFR_COMPONENT"); MapGenStructureIO.registerStructure(MapGenNTMFeatures.Start.class, "NTMFeatures"); MapGenStructureIO.registerStructure(BunkerStart.class, "NTMBunker"); registerNTMFeatures(); @@ -30,19 +28,20 @@ public class HbmWorld { worldGenerator = new NTMWorldGenerator(); registerWorldGen(worldGenerator, 1); //Ideally, move everything over from HbmWorldGen to NTMWorldGenerator MinecraftForge.EVENT_BUS.register(worldGenerator); - //registerWorldGen(new WorldGenTest(), 1); + + NBTStructure.register(); } - public static void registerWorldGen(IWorldGenerator nukerWorldGen, int weightedProbability) { + private static void registerWorldGen(IWorldGenerator nukerWorldGen, int weightedProbability) { GameRegistry.registerWorldGenerator(nukerWorldGen, weightedProbability); } /** Register structures in MapGenStructureIO */ - public static void registerNTMFeatures() { + private static void registerNTMFeatures() { CivilianFeatures.registerComponents(); OfficeFeatures.registerComponents(); RuinFeatures.registerComponents(); BunkerComponents.registerComponents(); MapGenStructureIO.func_143031_a(SiloComponent.class, "NTMSiloComponent"); } -} +} \ No newline at end of file diff --git a/src/main/java/com/hbm/lib/HbmWorldGen.java b/src/main/java/com/hbm/lib/HbmWorldGen.java index d3ed3f571..c78fe7219 100644 --- a/src/main/java/com/hbm/lib/HbmWorldGen.java +++ b/src/main/java/com/hbm/lib/HbmWorldGen.java @@ -545,37 +545,6 @@ public class HbmWorldGen implements IWorldGenerator { } - if (WorldConfig.meteorStructure > 0 && rand.nextInt(WorldConfig.meteorStructure) == 0 && biome != BiomeGenBase.ocean && biome != BiomeGenBase.deepOcean) { - int x = i + rand.nextInt(16) + 8; - int z = j + rand.nextInt(16) + 8; - - CellularDungeonFactory.meteor.generate(world, x, 10, z, rand); - - if(GeneralConfig.enableDebugMode) - MainRegistry.logger.info("[Debug] Successfully spawned meteor dungeon at " + x + " 10 " + z); - - int y = world.getHeightValue(x, z); - - for(int f = 0; f < 3; f++) - world.setBlock(x, y + f, z, ModBlocks.meteor_pillar); - world.setBlock(x, y + 3, z, ModBlocks.meteor_brick_chiseled); - - for(int f = 0; f < 10; f++) { - - x = i + rand.nextInt(65) - 32; - z = j + rand.nextInt(65) - 32; - y = world.getHeightValue(x, z); - - if(world.getBlock(x, y - 1, z).canPlaceTorchOnTop(world, x, y - 1, z)) { - world.setBlock(x, y, z, Blocks.skull, 1, 2); - TileEntitySkull skull = (TileEntitySkull)world.getTileEntity(x, y, z); - - if(skull != null) - skull.func_145903_a(rand.nextInt(16)); - } - } - } - if((biome == BiomeGenBase.jungle || biome == BiomeGenBase.jungleEdge || biome == BiomeGenBase.jungleHills) && WorldConfig.jungleStructure > 0 && rand.nextInt(WorldConfig.jungleStructure) == 0) { int x = i + rand.nextInt(16); diff --git a/src/main/java/com/hbm/main/ClientProxy.java b/src/main/java/com/hbm/main/ClientProxy.java index 95534ecbc..ed344f1e7 100644 --- a/src/main/java/com/hbm/main/ClientProxy.java +++ b/src/main/java/com/hbm/main/ClientProxy.java @@ -157,7 +157,7 @@ public class ClientProxy extends ServerProxy { registerBlockRenderer(); Jars.initJars(); - + ((IReloadableResourceManager) Minecraft.getMinecraft().getResourceManager()).registerReloadListener(new QMAWLoader()); if(GeneralConfig.enableSoundExtension) { @@ -831,6 +831,8 @@ public class ClientProxy extends ServerProxy { RenderingRegistry.registerBlockHandler(new RenderRBMKReflector()); RenderingRegistry.registerBlockHandler(new RenderRBMKControl()); RenderingRegistry.registerBlockHandler(new RenderPribris()); + + RenderingRegistry.registerBlockHandler(new RenderBlockWand()); } @Override @@ -1733,12 +1735,12 @@ public class ClientProxy extends ServerProxy { EntityFX fx = new net.minecraft.client.particle.EntityCritFX(world, x, y, z, mX, mY, mZ); fx.nextTextureIndexX(); - + if(data.hasKey("color")) { Color color = new Color(data.getInteger("color")); fx.setRBGColorF(color.getRed() / 255F, color.getGreen() / 255F, color.getBlue() / 255F); } - + Minecraft.getMinecraft().effectRenderer.addEffect(fx); } diff --git a/src/main/java/com/hbm/main/StructureManager.java b/src/main/java/com/hbm/main/StructureManager.java new file mode 100644 index 000000000..2456533ff --- /dev/null +++ b/src/main/java/com/hbm/main/StructureManager.java @@ -0,0 +1,63 @@ +package com.hbm.main; + +import com.hbm.lib.RefStrings; +import com.hbm.world.gen.NBTStructure; + +import net.minecraft.util.ResourceLocation; + +public class StructureManager { + + // METEOR DUNGEON + public static final NBTStructure meteor_spike = new NBTStructure(new ResourceLocation(RefStrings.MODID, "structures/meteor/meteor-spike.nbt")); + public static final NBTStructure meteor_core = new NBTStructure(new ResourceLocation(RefStrings.MODID, "structures/meteor/meteor-core.nbt")); + public static final NBTStructure meteor_corner = new NBTStructure(new ResourceLocation(RefStrings.MODID, "structures/meteor/meteor-corner.nbt")); + public static final NBTStructure meteor_t = new NBTStructure(new ResourceLocation(RefStrings.MODID, "structures/meteor/meteor-t.nbt")); + public static final NBTStructure meteor_stairs = new NBTStructure(new ResourceLocation(RefStrings.MODID, "structures/meteor/meteor-stairs.nbt")); + public static final NBTStructure meteor_fallback = new NBTStructure(new ResourceLocation(RefStrings.MODID, "structures/meteor/meteor-fallback.nbt")); + + public static final NBTStructure meteor_3_bale = new NBTStructure(new ResourceLocation(RefStrings.MODID, "structures/meteor/loot3x3/meteor-3-bale.nbt")); + public static final NBTStructure meteor_3_blank = new NBTStructure(new ResourceLocation(RefStrings.MODID, "structures/meteor/loot3x3/meteor-3-blank.nbt")); + public static final NBTStructure meteor_3_block = new NBTStructure(new ResourceLocation(RefStrings.MODID, "structures/meteor/loot3x3/meteor-3-block.nbt")); + public static final NBTStructure meteor_3_crab = new NBTStructure(new ResourceLocation(RefStrings.MODID, "structures/meteor/loot3x3/meteor-3-crab.nbt")); + public static final NBTStructure meteor_3_crab_tesla = new NBTStructure(new ResourceLocation(RefStrings.MODID, "structures/meteor/loot3x3/meteor-3-crab-tesla.nbt")); + public static final NBTStructure meteor_3_crate = new NBTStructure(new ResourceLocation(RefStrings.MODID, "structures/meteor/loot3x3/meteor-3-crate.nbt")); + public static final NBTStructure meteor_3_dirt = new NBTStructure(new ResourceLocation(RefStrings.MODID, "structures/meteor/loot3x3/meteor-3-dirt.nbt")); + public static final NBTStructure meteor_3_lead = new NBTStructure(new ResourceLocation(RefStrings.MODID, "structures/meteor/loot3x3/meteor-3-lead.nbt")); + public static final NBTStructure meteor_3_ooze = new NBTStructure(new ResourceLocation(RefStrings.MODID, "structures/meteor/loot3x3/meteor-3-ooze.nbt")); + public static final NBTStructure meteor_3_pillar = new NBTStructure(new ResourceLocation(RefStrings.MODID, "structures/meteor/loot3x3/meteor-3-pillar.nbt")); + public static final NBTStructure meteor_3_star = new NBTStructure(new ResourceLocation(RefStrings.MODID, "structures/meteor/loot3x3/meteor-3-star.nbt")); + public static final NBTStructure meteor_3_tesla = new NBTStructure(new ResourceLocation(RefStrings.MODID, "structures/meteor/loot3x3/meteor-3-tesla.nbt")); + public static final NBTStructure meteor_3_book = new NBTStructure(new ResourceLocation(RefStrings.MODID, "structures/meteor/loot3x3/meteor-3-book.nbt")); + public static final NBTStructure meteor_3_mku = new NBTStructure(new ResourceLocation(RefStrings.MODID, "structures/meteor/loot3x3/meteor-3-mku.nbt")); + public static final NBTStructure meteor_3_statue = new NBTStructure(new ResourceLocation(RefStrings.MODID, "structures/meteor/loot3x3/meteor-3-statue.nbt")); + + public static final NBTStructure meteor_room_base_end = new NBTStructure(new ResourceLocation(RefStrings.MODID, "structures/meteor/room10/room-base-end.nbt")); + public static final NBTStructure meteor_room_base_thru = new NBTStructure(new ResourceLocation(RefStrings.MODID, "structures/meteor/room10/room-base-thru.nbt")); + + public static final NBTStructure meteor_room_balcony = new NBTStructure(new ResourceLocation(RefStrings.MODID, "structures/meteor/room10/room-balcony.nbt")); + public static final NBTStructure meteor_room_basic = new NBTStructure(new ResourceLocation(RefStrings.MODID, "structures/meteor/room10/room-basic.nbt")); + public static final NBTStructure meteor_room_dragon = new NBTStructure(new ResourceLocation(RefStrings.MODID, "structures/meteor/room10/room-dragon.nbt")); + public static final NBTStructure meteor_room_ladder = new NBTStructure(new ResourceLocation(RefStrings.MODID, "structures/meteor/room10/room-ladder.nbt")); + public static final NBTStructure meteor_room_ooze = new NBTStructure(new ResourceLocation(RefStrings.MODID, "structures/meteor/room10/room-ooze.nbt")); + public static final NBTStructure meteor_room_split = new NBTStructure(new ResourceLocation(RefStrings.MODID, "structures/meteor/room10/room-split.nbt")); + public static final NBTStructure meteor_room_stairs = new NBTStructure(new ResourceLocation(RefStrings.MODID, "structures/meteor/room10/room-stairs.nbt")); + public static final NBTStructure meteor_room_triple = new NBTStructure(new ResourceLocation(RefStrings.MODID, "structures/meteor/room10/room-triple.nbt")); + public static final NBTStructure meteor_room_fallback = new NBTStructure(new ResourceLocation(RefStrings.MODID, "structures/meteor/room10/room-fallback.nbt")); + + public static final NBTStructure meteor_dragon_chest = new NBTStructure(new ResourceLocation(RefStrings.MODID, "structures/meteor/room10/headloot/loot-chest.nbt")); + public static final NBTStructure meteor_dragon_tesla = new NBTStructure(new ResourceLocation(RefStrings.MODID, "structures/meteor/room10/headloot/loot-tesla.nbt")); + public static final NBTStructure meteor_dragon_trap = new NBTStructure(new ResourceLocation(RefStrings.MODID, "structures/meteor/room10/headloot/loot-trap.nbt")); + public static final NBTStructure meteor_dragon_crate_crab = new NBTStructure(new ResourceLocation(RefStrings.MODID, "structures/meteor/room10/headloot/loot-crate-crab.nbt")); + + + + + public static final NBTStructure vertibird = new NBTStructure(new ResourceLocation(RefStrings.MODID, "structures/vertibird.nbt")); + public static final NBTStructure crashed_vertibird = new NBTStructure(new ResourceLocation(RefStrings.MODID, "structures/crashed-vertibird.nbt")); + + // public static final NBTStructure test_rot = new NBTStructure(new ResourceLocation(RefStrings.MODID, "structures/test-rot.nbt")); + // public static final NBTStructure test_jigsaw = new NBTStructure(new ResourceLocation(RefStrings.MODID, "structures/test-jigsaw.nbt")); + // public static final NBTStructure test_jigsaw_core = new NBTStructure(new ResourceLocation(RefStrings.MODID, "structures/test-jigsaw-core.nbt")); + // public static final NBTStructure test_jigsaw_hall = new NBTStructure(new ResourceLocation(RefStrings.MODID, "structures/test-jigsaw-hall.nbt")); + +} \ No newline at end of file diff --git a/src/main/java/com/hbm/render/block/RenderBlockWand.java b/src/main/java/com/hbm/render/block/RenderBlockWand.java new file mode 100644 index 000000000..d6d22efe2 --- /dev/null +++ b/src/main/java/com/hbm/render/block/RenderBlockWand.java @@ -0,0 +1,37 @@ +package com.hbm.render.block; + +import com.hbm.blocks.generic.BlockWand; + +import cpw.mods.fml.client.registry.ISimpleBlockRenderingHandler; +import net.minecraft.block.Block; +import net.minecraft.client.renderer.RenderBlocks; +import net.minecraft.world.IBlockAccess; + +public class RenderBlockWand implements ISimpleBlockRenderingHandler { + + @Override + public void renderInventoryBlock(Block block, int metadata, int modelId, RenderBlocks renderer) { + + } + + @Override + public boolean renderWorldBlock(IBlockAccess world, int x, int y, int z, Block block, int modelId, RenderBlocks renderer) { + renderer.renderFromInside = true; + renderer.renderStandardBlock(block, x, y, z); + renderer.renderFromInside = false; + renderer.renderStandardBlock(block, x, y, z); + + return true; + } + + @Override + public boolean shouldRender3DInInventory(int modelId) { + return false; + } + + @Override + public int getRenderId() { + return BlockWand.renderID; + } + +} \ No newline at end of file diff --git a/src/main/java/com/hbm/tileentity/TileMappings.java b/src/main/java/com/hbm/tileentity/TileMappings.java index 12257b52e..d1cc8eaf6 100644 --- a/src/main/java/com/hbm/tileentity/TileMappings.java +++ b/src/main/java/com/hbm/tileentity/TileMappings.java @@ -15,6 +15,8 @@ import com.hbm.blocks.generic.BlockPedestal.TileEntityPedestal; import com.hbm.blocks.generic.BlockPlushie.TileEntityPlushie; import com.hbm.blocks.generic.BlockSnowglobe.TileEntitySnowglobe; import com.hbm.blocks.generic.BlockSupplyCrate.TileEntitySupplyCrate; +import com.hbm.blocks.generic.BlockWandJigsaw.TileEntityWandJigsaw; +import com.hbm.blocks.generic.BlockWandLoot.TileEntityWandLoot; import com.hbm.blocks.generic.PartEmitter.TileEntityPartEmitter; import com.hbm.blocks.machine.BlockICF.TileEntityBlockICF; import com.hbm.blocks.machine.BlockPWR.TileEntityBlockPWR; @@ -48,7 +50,7 @@ public class TileMappings { public static HashMap, String[]> map = new HashMap, String[]>(); public static List> configurables = new ArrayList>(); - + public static void writeMappings() { put(TileEntityDiFurnace.class, "tilentity_diFurnace"); put(TileEntityObjTester.class, "tilentity_objtester"); @@ -206,7 +208,7 @@ public class TileMappings { put(TileEntityMachineOrbus.class, "tileentity_orbus"); put(TileEntityGlpyhidSpawner.class, "tileentity_glyphid_spawner"); put(TileEntityCustomMachine.class, "tileentity_custom_machine"); - + put(TileEntityLoot.class, "tileentity_ntm_loot"); put(TileEntityPedestal.class, "tileentity_ntm_pedestal"); put(TileEntityBobble.class, "tileentity_ntm_bobblehead"); @@ -218,9 +220,9 @@ public class TileMappings { put(TileEntityCharger.class, "tileentity_ntm_charger"); put(TileEntityRefueler.class, "tileentity_ntm_refueler"); - + put(TileEntityFileCabinet.class, "tileentity_file_cabinet"); - + put(TileEntityProxyInventory.class, "tileentity_proxy_inventory"); put(TileEntityProxyEnergy.class, "tileentity_proxy_power"); put(TileEntityProxyCombo.class, "tileentity_proxy_combo"); @@ -232,7 +234,10 @@ public class TileMappings { put(TileEntityPWRController.class, "tileentity_pwr_controller"); put(TileEntityData.class, "tileentity_data"); - + + put(TileEntityWandLoot.class, "tileentity_wand_loot"); + put(TileEntityWandJigsaw.class, "tileentity_wand_jigsaw"); + putNetwork(); putBombs(); putTurrets(); @@ -243,7 +248,7 @@ public class TileMappings { TileEntityMachineRadarNT.registerEntityClasses(); TileEntityMachineRadarNT.registerConverters(); } - + private static void putBombs() { put(TileEntityBombMulti.class, "tileentity_bombmulti"); put(TileEntityNukeGadget.class, "tilentity_nukegadget"); @@ -258,7 +263,7 @@ public class TileMappings { put(TileEntityCharge.class, "tileentity_explosive_charge"); put(TileEntityVolcanoCore.class, "tileentity_volcano_core"); } - + private static void putTurrets() { put(TileEntityTurretChekhov.class, "tileentity_turret_chekhov"); put(TileEntityTurretJeremy.class, "tileentity_turret_jeremy"); @@ -275,7 +280,7 @@ public class TileMappings { put(TileEntityTurretSentry.class, "tileentity_turret_sentry"); put(TileEntityTurretSentryDamaged.class, "tileentity_turret_sentry_damaged"); } - + private static void putMachines() { put(TileEntityHeaterFirebox.class, "tileentity_firebox"); put(TileEntityHeaterOven.class, "tileentity_heating_oven"); @@ -295,7 +300,7 @@ public class TileMappings { put(TileEntityMachinePumpSteam.class, "tileentity_steam_pump"); put(TileEntityMachinePumpElectric.class, "tileentity_electric_pump"); - + put(TileEntityFoundryMold.class, "tileentity_foundry_mold"); put(TileEntityFoundryBasin.class, "tileentity_foundry_basin"); put(TileEntityFoundryChannel.class, "tileentity_foundry_channel"); @@ -310,7 +315,7 @@ public class TileMappings { put(TileEntityDiFurnaceRTG.class, "tileentity_rtg_difurnace"); put(TileEntityMachineRadiolysis.class, "tileentity_radiolysis"); put(TileEntityMachineAutosaw.class, "tileentity_autosaw"); - + put(TileEntityCondenser.class, "tileentity_condenser"); put(TileEntityTowerSmall.class, "tileentity_cooling_tower_small"); put(TileEntityTowerLarge.class, "tileentity_cooling_tower_large"); @@ -332,12 +337,12 @@ public class TileMappings { put(TileEntityChungus.class, "tileentity_chungus"); put(TileEntityMachineCombustionEngine.class, "tileentity_combustion_engine"); - + put(TileEntityMachineAssembler.class, "tileentity_assembly_machine"); put(TileEntityMachineAssemfac.class, "tileentity_assemfac"); put(TileEntityMachineChemplant.class, "tileentity_chemical_plant"); put(TileEntityMachineChemfac.class, "tileentity_chemfac"); - + put(TileEntityMachineOilWell.class, "tileentity_derrick"); put(TileEntityMachinePumpjack.class, "tileentity_machine_pumpjack"); put(TileEntityMachineFrackingTower.class, "tileentity_fracking_tower"); @@ -353,21 +358,21 @@ public class TileMappings { put(TileEntityMachinePyroOven.class, "tileentity_pyrooven"); put(TileEntityChimneyBrick.class, "tileentity_chimney_brick"); put(TileEntityChimneyIndustrial.class, "tileentity_chimney_industrial"); - + put(TileEntityReactorZirnox.class, "tileentity_zirnox"); put(TileEntityZirnoxDestroyed.class, "tileentity_zirnox_destroyed"); put(TileEntityWatz.class, "tileentity_watz"); put(TileEntityWatzPump.class, "tileentity_watz_pump"); } - + private static void putPile() { put(TileEntityPileFuel.class, "tileentity_pile_fuel"); put(TileEntityPileSource.class, "tileentity_pile_source"); put(TileEntityPileBreedingFuel.class, "tileentity_pile_breedingfuel"); put(TileEntityPileNeutronDetector.class, "tileentity_pile_neutrondetector"); } - + private static void putRBMK() { put(TileEntityRBMKRod.class, "tileentity_rbmk_rod"); put(TileEntityRBMKRodReaSim.class, "tileentity_rbmk_rod_reasim"); @@ -387,12 +392,12 @@ public class TileMappings { put(TileEntityRBMKInlet.class, "tileentity_rbmk_inlet"); put(TileEntityRBMKOutlet.class, "tileentity_rbmk_outlet"); } - + private static void putNetwork() { put(TileEntityCableBaseNT.class, "tileentity_cable", "tileentity_wirecoated"); put(TileEntityCableSwitch.class, "tileentity_cable_switch"); put(TileEntityDiode.class, "tileentity_cable_diode"); - + put(TileEntityConnector.class, "tileentity_connector_redwire"); put(TileEntityPylon.class, "tileentity_pylon_redwire"); put(TileEntityPylonMedium.class, "tileentity_pylon_medium"); @@ -415,24 +420,24 @@ public class TileMappings { put(TileEntityRadioTorchCounter.class, "tileentity_rtty_counter"); put(TileEntityRadioTorchLogic.class, "tileentity_rtty_logic"); put(TileEntityRadioTelex.class, "tileentity_rtty_telex"); - + put(TileEntityDroneWaypoint.class, "tileentity_drone_waypoint"); put(TileEntityDroneCrate.class, "tileentity_drone_crate"); put(TileEntityDroneWaypointRequest.class, "tileentity_drone_waypoint_request"); put(TileEntityDroneDock.class, "tileentity_drone_dock"); put(TileEntityDroneProvider.class, "tileentity_drone_provider"); put(TileEntityDroneRequester.class, "tileentity_drone_requester"); - + put(TileEntityRailSwitch.class, "tileentity_rail_switch"); } - + private static void put(Class clazz, String... names) { map.put(clazz, names); /*if((IFluidSource.class.isAssignableFrom(clazz) || IFluidAcceptor.class.isAssignableFrom(clazz)) && !IFluidConnector.class.isAssignableFrom(clazz)) { LoggingUtil.errorWithHighlight(clazz.getCanonicalName() + " implements the old interfaces but not IFluidConnector!"); }*/ - + if(IConfigurableMachine.class.isAssignableFrom(clazz)) { configurables.add((Class) clazz); } diff --git a/src/main/java/com/hbm/util/LootGenerator.java b/src/main/java/com/hbm/util/LootGenerator.java index b55cc92c8..b14306b9e 100644 --- a/src/main/java/com/hbm/util/LootGenerator.java +++ b/src/main/java/com/hbm/util/LootGenerator.java @@ -2,6 +2,7 @@ package com.hbm.util; import com.hbm.blocks.ModBlocks; import com.hbm.blocks.generic.BlockLoot.TileEntityLoot; +import com.hbm.crafting.handlers.MKUCraftingHandler; import com.hbm.inventory.OreDictManager.DictFrame; import com.hbm.itempool.ItemPool; import com.hbm.itempool.ItemPoolsPile; @@ -10,6 +11,7 @@ import com.hbm.items.special.ItemBookLore; import com.hbm.items.weapon.sedna.factory.GunFactory.EnumAmmo; import net.minecraft.init.Items; +import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.world.World; @@ -17,6 +19,45 @@ import java.util.Random; public class LootGenerator { + public static final String LOOT_BOOKLET = "LOOT_BOOKLET"; + public static final String LOOT_CAPNUKE = "LOOT_CAPNUKE"; + public static final String LOOT_MEDICINE = "LOOT_MEDICINE"; + public static final String LOOT_CAPSTASH = "LOOT_CAPSTASH"; + public static final String LOOT_MAKESHIFT_GUN = "LOOT_MAKESHIFT_GUN"; + public static final String LOOT_NUKE_STORAGE = "LOOT_NUKE_STORAGE"; + public static final String LOOT_BONES = "LOOT_BONES"; + public static final String LOOT_GLYPHID_HIVE = "LOOT_GLYPHID_HIVE"; + public static final String LOOT_METEOR = "LOOT_METEOR"; + + public static void applyLoot(World world, int x, int y, int z, String name) { + switch(name) { + case LOOT_BOOKLET: lootBooklet(world, x, y, z); + case LOOT_CAPNUKE: lootCapNuke(world, x, y, z); + case LOOT_MEDICINE: lootMedicine(world, x, y, z); + case LOOT_CAPSTASH: lootCapStash(world, x, y, z); + case LOOT_MAKESHIFT_GUN: lootMakeshiftGun(world, x, y, z); + case LOOT_NUKE_STORAGE: lootNukeStorage(world, x, y, z); + case LOOT_BONES: lootBones(world, x, y, z); + case LOOT_GLYPHID_HIVE: lootGlyphidHive(world, x, y, z); + case LOOT_METEOR: lootBookMeteor(world, x, y, z); + default: lootBones(world, x, y, z); break; + } + } + + public static String[] getLootNames() { + return new String[] { + LOOT_BOOKLET, + LOOT_CAPNUKE, + LOOT_MEDICINE, + LOOT_CAPSTASH, + LOOT_MAKESHIFT_GUN, + LOOT_NUKE_STORAGE, + LOOT_BONES, + LOOT_GLYPHID_HIVE, + LOOT_METEOR, + }; + } + public static void setBlock(World world, int x, int y, int z) { world.setBlock(x, y, z, ModBlocks.deco_loot); } @@ -142,6 +183,19 @@ public class LootGenerator { } } + public static void lootBookMeteor(World world, int x, int y, int z) { + + TileEntityLoot loot = (TileEntityLoot) world.getTileEntity(x, y, z); + + if(loot != null && loot.items.isEmpty()) { + Item mkuItem = MKUCraftingHandler.getMKUItem(world); + ItemStack mkuBook = MKUCraftingHandler.generateBook(world, mkuItem); + + addItemWithDeviation(loot, world.rand, new ItemStack(mkuItem), 0, 0, 0.25); + addItemWithDeviation(loot, world.rand, mkuBook, 0, 0, -0.25); + } + } + public static void lootBookLore(World world, int x, int y, int z, ItemStack book) { TileEntityLoot loot = (TileEntityLoot) world.getTileEntity(x, y, z); @@ -157,4 +211,4 @@ public class LootGenerator { } } -} +} \ No newline at end of file diff --git a/src/main/java/com/hbm/world/gen/INBTTileEntityTransformable.java b/src/main/java/com/hbm/world/gen/INBTTileEntityTransformable.java new file mode 100644 index 000000000..33dc141c8 --- /dev/null +++ b/src/main/java/com/hbm/world/gen/INBTTileEntityTransformable.java @@ -0,0 +1,14 @@ +package com.hbm.world.gen; + +import net.minecraft.world.World; + +public interface INBTTileEntityTransformable { + + /** + * Like INBTTransformable but for TileEntities, like for randomizing bobbleheads + */ + + // Allows for the TE to modify itself when spawned in an NBT structure + public void transformTE(World world, int coordBaseMode); + +} \ No newline at end of file diff --git a/src/main/java/com/hbm/world/gen/INBTTransformable.java b/src/main/java/com/hbm/world/gen/INBTTransformable.java new file mode 100644 index 000000000..b42d6bd43 --- /dev/null +++ b/src/main/java/com/hbm/world/gen/INBTTransformable.java @@ -0,0 +1,161 @@ +package com.hbm.world.gen; + +import net.minecraft.block.Block; + +public interface INBTTransformable { + + /** + * Defines this block as something that has a rotation or some other blockstate + * which needs transformations applied when building from an .nbt structure file + */ + + // Takes the block current meta and translates it into a rotated meta + public int transformMeta(int meta, int coordBaseMode); + + // Takes the block and turns it into a different block entirely, to turn off lights, shit like that + public default Block transformBlock(Block block) { + return block; + } + + + /** + * A fair few blocks have generalized rotations so, since we have all this space, put em here + */ + + public static int transformMetaDeco(int meta, int coordBaseMode) { + switch(coordBaseMode) { + case 1: //West + switch(meta) { + case 2: return 5; + case 3: return 4; + case 4: return 2; + case 5: return 3; + } + case 2: //North + switch(meta) { + case 2: return 3; + case 3: return 2; + case 4: return 5; + case 5: return 4; + } + case 3: //East + switch(meta) { + case 2: return 4; + case 3: return 5; + case 4: return 3; + case 5: return 2; + } + } + return meta; + } + + public static int transformMetaDecoModel(int meta, int coordBaseMode) { + int rot = (meta + coordBaseMode) % 4; + int type = (meta / 4) * 4; + + return rot | type; + } + + public static int transformMetaStairs(int meta, int coordBaseMode) { + switch(coordBaseMode) { + case 1: //West + if((meta & 3) < 2) //Flip second bit for E/W + meta = meta ^ 2; + else + meta = meta ^ 3; //Flip both bits for N/S + break; + case 2: //North + meta = meta ^ 1; //Flip first bit + break; + case 3: //East + if((meta & 3) < 2) //Flip both bits for E/W + meta = meta ^ 3; + else //Flip second bit for N/S + meta = meta ^ 2; + break; + } + + return meta; + } + + public static int transformMetaPillar(int meta, int coordBaseMode) { + if(coordBaseMode == 2) return meta; + int type = meta & 3; + int rot = meta & 12; + + if(rot == 4) return type | 8; + if(rot == 8) return type | 4; + + return meta; + } + + public static int transformMetaDirectional(int meta, int coordBaseMode) { + int rot = meta & 3; + int other = meta & 12; + + switch(coordBaseMode) { + default: //S + break; + case 1: //W + rot = (rot + 1) % 4; break; + case 2: //N + rot ^= 2; break; + case 3: //E + rot = (rot + 3) % 4; break; + } + + return other | rot; + } + + public static int transformMetaTorch(int meta, int coordBaseMode) { + switch(coordBaseMode) { + case 1: //West + switch(meta) { + case 1: return 3; + case 2: return 4; + case 3: return 2; + case 4: return 1; + } + case 2: //North + switch(meta) { + case 1: return 2; + case 2: return 1; + case 3: return 4; + case 4: return 3; + } + case 3: //East + switch(meta) { + case 1: return 4; + case 2: return 3; + case 3: return 1; + case 4: return 2; + } + } + return meta; + } + + public static int transformMetaDoor(int meta, int coordBaseMode) { + if(meta == 8 || meta == 9) return meta; // ignore top parts + + return transformMetaDirectional(meta, coordBaseMode); + } + + public static int transformMetaLever(int meta, int coordBaseMode) { + if(meta <= 0 || meta >= 7) { //levers suck ass + switch(coordBaseMode) { + case 1: case 3: //west / east + meta ^= 0b111; + } + } else if(meta >= 5) { + switch(coordBaseMode) { + case 1: case 3: //west / east + meta = (meta + 1) % 2 + 5; + } + } else { + meta = transformMetaTorch(meta, coordBaseMode); + } + + return meta; + } + +} \ No newline at end of file diff --git a/src/main/java/com/hbm/world/gen/NBTStructure.java b/src/main/java/com/hbm/world/gen/NBTStructure.java new file mode 100644 index 000000000..43625a627 --- /dev/null +++ b/src/main/java/com/hbm/world/gen/NBTStructure.java @@ -0,0 +1,1155 @@ +package com.hbm.world.gen; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.*; +import java.util.function.Function; +import java.util.function.Predicate; + +import com.hbm.blocks.ModBlocks; +import com.hbm.blocks.generic.BlockWand; +import com.hbm.config.GeneralConfig; +import com.hbm.config.StructureConfig; +import com.hbm.handler.ThreeInts; +import com.hbm.main.MainRegistry; +import com.hbm.util.Tuple.Pair; +import com.hbm.util.Tuple.Quartet; + +import cpw.mods.fml.common.registry.GameRegistry; +import net.minecraft.block.*; +import net.minecraft.client.Minecraft; +import net.minecraft.init.Blocks; +import net.minecraft.item.Item; +import net.minecraft.nbt.CompressedStreamTools; +import net.minecraft.nbt.NBTBase; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagInt; +import net.minecraft.nbt.NBTTagList; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.MathHelper; +import net.minecraft.util.ResourceLocation; +import net.minecraft.world.World; +import net.minecraft.world.biome.BiomeGenBase; +import net.minecraft.world.chunk.IChunkProvider; +import net.minecraft.world.gen.structure.MapGenStructure; +import net.minecraft.world.gen.structure.MapGenStructureIO; +import net.minecraft.world.gen.structure.StructureBoundingBox; +import net.minecraft.world.gen.structure.StructureComponent; +import net.minecraft.world.gen.structure.StructureComponent.BlockSelector; +import net.minecraft.world.gen.structure.StructureStart; +import net.minecraftforge.common.util.ForgeDirection; +import net.minecraftforge.common.util.Constants.NBT; + +public class NBTStructure { + + /** + * Now with structure support! + * + * the type of structure to generate is saved into the Component, + * meaning this can generate all sorts of different structures, + * without having to define and register each structure manually + */ + + protected static Map> weightedMap = new HashMap<>(); + + // serialization data + protected static Map jigsawMap = new HashMap<>(); + + private String name; + + private boolean isLoaded; + + private ThreeInts size; + private List> itemPalette; + private BlockState[][][] blockArray; + + private List> fromConnections; + private Map> toTopConnections; + private Map> toBottomConnections; + private Map> toHorizontalConnections; + + public NBTStructure(ResourceLocation resource) { + // Can't use regular resource loading, servers don't know how! + InputStream stream = NBTStructure.class.getResourceAsStream("/assets/" + resource.getResourceDomain() + "/" + resource.getResourcePath()); + if(stream != null) { + name = resource.getResourcePath(); + loadStructure(stream); + } else { + MainRegistry.logger.error("NBT Structure not found: " + resource.getResourcePath()); + } + } + + public static void register() { + MapGenStructureIO.registerStructure(Start.class, "NBTStructures"); + MapGenStructureIO.func_143031_a(Component.class, "NBTComponents"); + } + + // Register a new structure for a given dimension + public static void registerStructure(int dimensionId, SpawnCondition spawn) { + List weightedList = weightedMap.computeIfAbsent(dimensionId, integer -> new ArrayList()); + for(int i = 0; i < spawn.spawnWeight; i++) { + weightedList.add(spawn); + } + } + + public static void registerStructure(SpawnCondition spawn, int... dimensionIds) { + for(int dimensionId : dimensionIds) { + registerStructure(dimensionId, spawn); + } + } + + // Add a chance for nothing to spawn at a given valid spawn location + public static void registerNullWeight(int dimensionId, int weight) { + registerNullWeight(dimensionId, weight, null); + } + + public static void registerNullWeight(int dimensionId, int weight, Predicate predicate) { + SpawnCondition spawn = new SpawnCondition() {{ + spawnWeight = weight; + canSpawn = predicate; + }}; + + List weightedList = weightedMap.computeIfAbsent(dimensionId, integer -> new ArrayList()); + for(int i = 0; i < spawn.spawnWeight; i++) { + weightedList.add(spawn); + } + } + + // Saves a selected area into an NBT structure (+ some of our non-standard stuff to support 1.7.10) + public static void saveArea(String filename, World world, int x1, int y1, int z1, int x2, int y2, int z2, Set> exclude) { + NBTTagCompound structure = new NBTTagCompound(); + NBTTagList nbtBlocks = new NBTTagList(); + NBTTagList nbtPalette = new NBTTagList(); + NBTTagList nbtItemPalette = new NBTTagList(); + + // Quick access hash slinging slashers + Map, Integer> palette = new HashMap<>(); + Map itemPalette = new HashMap<>(); + + structure.setInteger("version", 1); + + int ox = Math.min(x1, x2); + int oy = Math.min(y1, y2); + int oz = Math.min(z1, z2); + + for(int x = ox; x <= Math.max(x1, x2); x++) { + for(int y = oy; y <= Math.max(y1, y2); y++) { + for(int z = oz; z <= Math.max(z1, z2); z++) { + Pair block = new Pair(world.getBlock(x, y, z), world.getBlockMetadata(x, y, z)); + + if(exclude.contains(block)) continue; + + if(block.key instanceof BlockWand) { + block.key = ((BlockWand) block.key).exportAs; + } + + int paletteId = palette.size(); + if(palette.containsKey(block)) { + paletteId = palette.get(block); + } else { + palette.put(block, paletteId); + + NBTTagCompound nbtBlock = new NBTTagCompound(); + nbtBlock.setString("Name", GameRegistry.findUniqueIdentifierFor(block.key).toString()); + + NBTTagCompound nbtProp = new NBTTagCompound(); + nbtProp.setString("meta", block.value.toString()); + + nbtBlock.setTag("Properties", nbtProp); + + nbtPalette.appendTag(nbtBlock); + } + + NBTTagCompound nbtBlock = new NBTTagCompound(); + nbtBlock.setInteger("state", paletteId); + + NBTTagList nbtPos = new NBTTagList(); + nbtPos.appendTag(new NBTTagInt(x - ox)); + nbtPos.appendTag(new NBTTagInt(y - oy)); + nbtPos.appendTag(new NBTTagInt(z - oz)); + + nbtBlock.setTag("pos", nbtPos); + + TileEntity te = world.getTileEntity(x, y, z); + if(te != null) { + NBTTagCompound nbt = new NBTTagCompound(); + te.writeToNBT(nbt); + + nbt.removeTag("x"); + nbt.removeTag("y"); + nbt.removeTag("z"); + + nbtBlock.setTag("nbt", nbt); + + String itemKey = null; + if(nbt.hasKey("items")) itemKey = "items"; + if(nbt.hasKey("Items")) itemKey = "Items"; + + if(nbt.hasKey(itemKey)) { + NBTTagList items = nbt.getTagList(itemKey, NBT.TAG_COMPOUND); + for(int i = 0; i < items.tagCount(); i++) { + NBTTagCompound item = items.getCompoundTagAt(i); + short id = item.getShort("id"); + String name = GameRegistry.findUniqueIdentifierFor(Item.getItemById(id)).toString(); + + if(!itemPalette.containsKey(id)) { + int itemPaletteId = itemPalette.size(); + itemPalette.put(id, itemPaletteId); + + NBTTagCompound nbtItem = new NBTTagCompound(); + nbtItem.setShort("ID", id); + nbtItem.setString("Name", name); + + nbtItemPalette.appendTag(nbtItem); + } + } + } + } + + nbtBlocks.appendTag(nbtBlock); + } + } + } + + structure.setTag("blocks", nbtBlocks); + structure.setTag("palette", nbtPalette); + structure.setTag("itemPalette", nbtItemPalette); + + NBTTagList nbtSize = new NBTTagList(); + nbtSize.appendTag(new NBTTagInt(Math.abs(x1 - x2) + 1)); + nbtSize.appendTag(new NBTTagInt(Math.abs(y1 - y2) + 1)); + nbtSize.appendTag(new NBTTagInt(Math.abs(z1 - z2) + 1)); + structure.setTag("size", nbtSize); + + structure.setTag("entities", new NBTTagList()); + + try { + File structureDirectory = new File(Minecraft.getMinecraft().mcDataDir, "structures"); + structureDirectory.mkdir(); + + File structureFile = new File(structureDirectory, filename); + + CompressedStreamTools.writeCompressed(structure, new FileOutputStream(structureFile)); + } catch (Exception ex) { + MainRegistry.logger.warn("Failed to save NBT structure", ex); + } + } + + private void loadStructure(InputStream inputStream) { + try { + NBTTagCompound data = CompressedStreamTools.readCompressed(inputStream); + + + // GET SIZE (for offsetting to center) + size = parsePos(data.getTagList("size", NBT.TAG_INT)); + + + // PARSE BLOCK PALETTE + NBTTagList paletteList = data.getTagList("palette", NBT.TAG_COMPOUND); + BlockDefinition[] palette = new BlockDefinition[paletteList.tagCount()]; + + for(int i = 0; i < paletteList.tagCount(); i++) { + NBTTagCompound p = paletteList.getCompoundTagAt(i); + + String blockName = p.getString("Name"); + NBTTagCompound prop = p.getCompoundTag("Properties"); + + int meta = 0; + try { + meta = Integer.parseInt(prop.getString("meta")); + } catch(NumberFormatException ex) { + MainRegistry.logger.info("Failed to parse: " + prop.getString("meta")); + meta = 0; + } + + palette[i] = new BlockDefinition(blockName, meta); + } + + + // PARSE ITEM PALETTE (custom shite) + if(data.hasKey("itemPalette")) { + NBTTagList itemPaletteList = data.getTagList("itemPalette", NBT.TAG_COMPOUND); + itemPalette = new ArrayList<>(itemPaletteList.tagCount()); + + for(int i = 0; i < itemPaletteList.tagCount(); i++) { + NBTTagCompound p = itemPaletteList.getCompoundTagAt(i); + + short id = p.getShort("ID"); + String name = p.getString("Name"); + + itemPalette.add(new Pair<>(id, name)); + } + } else { + itemPalette = null; + } + + + // LOAD IN BLOCKS + NBTTagList blockData = data.getTagList("blocks", NBT.TAG_COMPOUND); + blockArray = new BlockState[size.x][size.y][size.z]; + + List connections = new ArrayList<>(); + + for(int i = 0; i < blockData.tagCount(); i++) { + NBTTagCompound block = blockData.getCompoundTagAt(i); + int state = block.getInteger("state"); + ThreeInts pos = parsePos(block.getTagList("pos", NBT.TAG_INT)); + + BlockState blockState = new BlockState(palette[state]); + + if(block.hasKey("nbt")) { + NBTTagCompound nbt = block.getCompoundTag("nbt"); + blockState.nbt = nbt; + + // Load in connection points for jigsaws + if(blockState.definition.block == ModBlocks.wand_jigsaw) { + if(toTopConnections == null) toTopConnections = new HashMap<>(); + if(toBottomConnections == null) toBottomConnections = new HashMap<>(); + if(toHorizontalConnections == null) toHorizontalConnections = new HashMap<>(); + + int selectionPriority = nbt.getInteger("selection"); + int placementPriority = nbt.getInteger("placement"); + ForgeDirection direction = ForgeDirection.getOrientation(nbt.getInteger("direction")); + String poolName = nbt.getString("pool"); + String ourName = nbt.getString("name"); + String targetName = nbt.getString("target"); + String replaceBlock = nbt.getString("block"); + int replaceMeta = nbt.getInteger("meta"); + boolean isRollable = nbt.getBoolean("roll"); + + JigsawConnection connection = new JigsawConnection(pos, direction, poolName, targetName, isRollable, selectionPriority, placementPriority); + + connections.add(connection); + + Map> toConnections = null; + if(direction == ForgeDirection.UP) { + toConnections = toTopConnections; + } else if(direction == ForgeDirection.DOWN) { + toConnections = toBottomConnections; + } else { + toConnections = toHorizontalConnections; + } + + List namedConnections = toConnections.computeIfAbsent(ourName, name -> new ArrayList<>()); + namedConnections.add(connection); + + if(!StructureConfig.debugStructures) { + blockState = new BlockState(new BlockDefinition(replaceBlock, replaceMeta)); + } + } + } + + blockArray[pos.x][pos.y][pos.z] = blockState; + } + + + // MAP OUT CONNECTIONS + PRIORITIES + if(connections.size() > 0) { + fromConnections = new ArrayList<>(); + + connections.sort((a, b) -> a.selectionPriority - b.selectionPriority); // sort by descending priority, highest first + + // Sort out our from connections, splitting into individual lists for each priority level + List innerList = null; + int currentPriority = 0; + for(JigsawConnection connection : connections) { + if(innerList == null || currentPriority != connection.selectionPriority) { + innerList = new ArrayList<>(); + fromConnections.add(innerList); + currentPriority = connection.selectionPriority; + } + + innerList.add(connection); + } + } + + + + isLoaded = true; + + } catch(Exception e) { + MainRegistry.logger.error("Exception reading NBT Structure format", e); + } finally { + try { + inputStream.close(); + } catch(IOException e) { + // hush + } + } + } + + private HashMap getWorldItemPalette() { + if(itemPalette == null) return null; + + HashMap worldItemPalette = new HashMap<>(); + + for(Pair entry : itemPalette) { + Item item = (Item)Item.itemRegistry.getObject(entry.getValue()); + + worldItemPalette.put(entry.getKey(), (short)Item.getIdFromItem(item)); + } + + return worldItemPalette; + } + + private TileEntity buildTileEntity(World world, Block block, HashMap worldItemPalette, NBTTagCompound nbt, int coordBaseMode) { + nbt = (NBTTagCompound)nbt.copy(); + + if(worldItemPalette != null) relinkItems(worldItemPalette, nbt); + + TileEntity te = TileEntity.createAndLoadEntity(nbt); + + if(te instanceof INBTTileEntityTransformable) { + ((INBTTileEntityTransformable) te).transformTE(world, coordBaseMode); + } + + return te; + } + + public void build(World world, int x, int y, int z) { + build(world, x, y, z, 0); + } + + public void build(World world, int x, int y, int z, int coordBaseMode) { + if(!isLoaded) { + MainRegistry.logger.info("NBTStructure is invalid"); + return; + } + + HashMap worldItemPalette = getWorldItemPalette(); + + boolean swizzle = coordBaseMode == 1 || coordBaseMode == 3; + x -= (swizzle ? size.z : size.x) / 2; + z -= (swizzle ? size.x : size.z) / 2; + + int maxX = size.x; + int maxZ = size.z; + + for(int bx = 0; bx < maxX; bx++) { + for(int bz = 0; bz < maxZ; bz++) { + int rx = rotateX(bx, bz, coordBaseMode) + x; + int rz = rotateZ(bx, bz, coordBaseMode) + z; + + for(int by = 0; by < size.y; by++) { + BlockState state = blockArray[bx][by][bz]; + if(state == null) continue; + + int ry = by + y; + + Block block = transformBlock(state.definition, null, world.rand); + int meta = coordBaseMode != 0 ? transformMeta(state.definition, coordBaseMode) : state.definition.meta; + + world.setBlock(rx, ry, rz, block, meta, 2); + + if(state.nbt != null) { + TileEntity te = buildTileEntity(world, block, worldItemPalette, state.nbt, coordBaseMode); + world.setTileEntity(rx, ry, rz, te); + } + } + } + } + } + + protected boolean build(World world, JigsawPiece piece, StructureBoundingBox totalBounds, StructureBoundingBox generatingBounds, int coordBaseMode) { + if(!isLoaded) { + MainRegistry.logger.info("NBTStructure is invalid"); + return false; + } + + HashMap worldItemPalette = getWorldItemPalette(); + + int sizeX = totalBounds.maxX - totalBounds.minX; + int sizeZ = totalBounds.maxZ - totalBounds.minZ; + + // voxel grid transforms can fuck you up + // you have my respect, vaer + int absMinX = Math.max(generatingBounds.minX - totalBounds.minX, 0); + int absMaxX = Math.min(generatingBounds.maxX - totalBounds.minX, sizeX); + int absMinZ = Math.max(generatingBounds.minZ - totalBounds.minZ, 0); + int absMaxZ = Math.min(generatingBounds.maxZ - totalBounds.minZ, sizeZ); + + // A check to see that we're actually inside the generating area at all + if(absMinX > sizeX || absMaxX < 0 || absMinZ > sizeZ || absMaxZ < 0) return true; + + int rotMinX = unrotateX(absMinX, absMinZ, coordBaseMode); + int rotMaxX = unrotateX(absMaxX, absMaxZ, coordBaseMode); + int rotMinZ = unrotateZ(absMinX, absMinZ, coordBaseMode); + int rotMaxZ = unrotateZ(absMaxX, absMaxZ, coordBaseMode); + + int minX = Math.min(rotMinX, rotMaxX); + int maxX = Math.max(rotMinX, rotMaxX); + int minZ = Math.min(rotMinZ, rotMaxZ); + int maxZ = Math.max(rotMinZ, rotMaxZ); + + for(int bx = minX; bx <= maxX; bx++) { + for(int bz = minZ; bz <= maxZ; bz++) { + int rx = rotateX(bx, bz, coordBaseMode) + totalBounds.minX; + int rz = rotateZ(bx, bz, coordBaseMode) + totalBounds.minZ; + int oy = piece.conformToTerrain ? world.getTopSolidOrLiquidBlock(rx, rz) + piece.heightOffset : totalBounds.minY; + + for(int by = 0; by < size.y; by++) { + BlockState state = blockArray[bx][by][bz]; + if(state == null) continue; + + int ry = by + oy; + + Block block = transformBlock(state.definition, piece.blockTable, world.rand); + int meta = coordBaseMode != 0 ? transformMeta(state.definition, coordBaseMode) : state.definition.meta; + + world.setBlock(rx, ry, rz, block, meta, 2); + + if(state.nbt != null) { + TileEntity te = buildTileEntity(world, block, worldItemPalette, state.nbt, coordBaseMode); + world.setTileEntity(rx, ry, rz, te); + } + } + } + } + + return true; + } + + // What a fucken mess, why even implement the IntArray NBT if ye aint gonna use it Moe Yang? + private ThreeInts parsePos(NBTTagList pos) { + NBTBase xb = (NBTBase)pos.tagList.get(0); + int x = ((NBTTagInt)xb).func_150287_d(); + NBTBase yb = (NBTBase)pos.tagList.get(1); + int y = ((NBTTagInt)yb).func_150287_d(); + NBTBase zb = (NBTBase)pos.tagList.get(2); + int z = ((NBTTagInt)zb).func_150287_d(); + + return new ThreeInts(x, y, z); + } + + // NON-STANDARD, items are serialized with IDs, which will differ from world to world! + // So our fixed exporter adds an itemPalette, please don't hunt me down for fucking with the spec + private void relinkItems(HashMap palette, NBTTagCompound nbt) { + NBTTagList items = null; + if(nbt.hasKey("items")) + items = nbt.getTagList("items", NBT.TAG_COMPOUND); + if(nbt.hasKey("Items")) + items = nbt.getTagList("Items", NBT.TAG_COMPOUND); + + if(items == null) return; + + for(int i = 0; i < items.tagCount(); i++) { + NBTTagCompound item = items.getCompoundTagAt(i); + item.setShort("id", palette.get(item.getShort("id"))); + } + } + + private Block transformBlock(BlockDefinition definition, Map blockTable, Random rand) { + if(blockTable != null && blockTable.containsKey(definition.block)) { + final BlockSelector selector = blockTable.get(definition.block); + selector.selectBlocks(rand, 0, 0, 0, false); // fuck the vanilla shit idc + return selector.func_151561_a(); + } + + if(definition.block instanceof INBTTransformable) return ((INBTTransformable) definition.block).transformBlock(definition.block); + + return definition.block; + } + + private int transformMeta(BlockDefinition definition, int coordBaseMode) { + // Our shit + if(definition.block instanceof INBTTransformable) return ((INBTTransformable) definition.block).transformMeta(definition.meta, coordBaseMode); + + // Vanilla shit + if(definition.block instanceof BlockStairs) return INBTTransformable.transformMetaStairs(definition.meta, coordBaseMode); + if(definition.block instanceof BlockRotatedPillar) return INBTTransformable.transformMetaPillar(definition.meta, coordBaseMode); + if(definition.block instanceof BlockDirectional) return INBTTransformable.transformMetaDirectional(definition.meta, coordBaseMode); + if(definition.block instanceof BlockTorch) return INBTTransformable.transformMetaTorch(definition.meta, coordBaseMode); + if(definition.block instanceof BlockButton) return INBTTransformable.transformMetaTorch(definition.meta, coordBaseMode); + if(definition.block instanceof BlockDoor) return INBTTransformable.transformMetaDoor(definition.meta, coordBaseMode); + if(definition.block instanceof BlockLever) return INBTTransformable.transformMetaLever(definition.meta, coordBaseMode); + if(definition.block instanceof BlockSign) return INBTTransformable.transformMetaDeco(definition.meta, coordBaseMode); + if(definition.block instanceof BlockLadder) return INBTTransformable.transformMetaDeco(definition.meta, coordBaseMode); + + return definition.meta; + } + + private int rotateX(int x, int z, int coordBaseMode) { + switch(coordBaseMode) { + case 1: return size.z - 1 - z; + case 2: return size.x - 1 - x; + case 3: return z; + default: return x; + } + } + + private int rotateZ(int x, int z, int coordBaseMode) { + switch(coordBaseMode) { + case 1: return x; + case 2: return size.z - 1 - z; + case 3: return size.x - 1 - x; + default: return z; + } + } + + private int unrotateX(int x, int z, int coordBaseMode) { + switch(coordBaseMode) { + case 3: return size.x - 1 - z; + case 2: return size.x - 1 - x; + case 1: return z; + default: return x; + } + } + + private int unrotateZ(int x, int z, int coordBaseMode) { + switch(coordBaseMode) { + case 3: return x; + case 2: return size.z - 1 - z; + case 1: return size.z - 1 - x; + default: return z; + } + } + + private static class BlockState { + + final BlockDefinition definition; + NBTTagCompound nbt; + + BlockState(BlockDefinition definition) { + this.definition = definition; + } + + } + + private static class BlockDefinition { + + final Block block; + final int meta; + + BlockDefinition(String name, int meta) { + Block block = Block.getBlockFromName(name); + if(block == null) block = Blocks.air; + + this.block = block; + this.meta = meta; + } + + } + + public static class SpawnCondition { + + // If defined, will spawn a single jigsaw piece, for single nbt structures + public JigsawPiece structure; + + // If defined, will spawn in a non-nbt structure component + public Function, StructureStart> start; + + public Predicate canSpawn; + public int spawnWeight = 1; + + // Named jigsaw pools that are referenced within the structure + public Map pools; + public String startPool; + + // Maximum amount of components in this structure + public int sizeLimit = 8; + + // Height modifiers, will clamp height that the start generates at, allowing for: + // * Submarines that must spawn under the ocean surface + // * Bunkers that sit underneath the ground + public int minHeight = 1; + public int maxHeight = 128; + + // Can this spawn in the current biome + protected boolean isValid(BiomeGenBase biome) { + if(canSpawn == null) return true; + return canSpawn.test(biome); + } + + protected JigsawPool getPool(String name) { + return pools.get(name).clone(); + } + + } + + // A set of pieces with weights + public static class JigsawPool { + + // Weighted list of pieces to pick from + private List> pieces = new ArrayList<>(); + private int totalWeight = 0; + + public String fallback; + + private boolean isClone; + + public void add(JigsawPiece piece, int weight) { + if(weight <= 0) throw new IllegalStateException("JigsawPool spawn weight must be positive!"); + pieces.add(new Pair<>(piece, weight)); + totalWeight += weight; + } + + protected JigsawPool clone() { + JigsawPool clone = new JigsawPool(); + clone.pieces = new ArrayList<>(this.pieces); + clone.fallback = this.fallback; + clone.totalWeight = this.totalWeight; + clone.isClone = true; + + return clone; + } + + // If from a clone, will remove from the pool + public JigsawPiece get(Random rand) { + if(totalWeight <= 0) return null; + int weight = rand.nextInt(totalWeight); + + for(int i = 0; i < pieces.size(); i++) { + Pair pair = pieces.get(i); + weight -= pair.getValue(); + + if(weight < 0) { + if(isClone) { + pieces.remove(i); + totalWeight -= pair.getValue(); + } + + return pair.getKey(); + } + } + + return null; + } + + } + + // Assigned to a Component to build + public static class JigsawPiece { + + public final String name; + public final NBTStructure structure; + + // Block modifiers, for randomization and terrain matching + public Map blockTable; + public boolean conformToTerrain = false; // moves every single column to the terrain (digging out trenches, natural formations) + public boolean alignToTerrain = false; // aligns this component y-level individually, without moving individual columns (village houses) + public int heightOffset = 0; // individual offset for the structure + + public JigsawPiece(String name, NBTStructure structure) { + this(name, structure, 0); + } + + public JigsawPiece(String name, NBTStructure structure, int heightOffset) { + if(name == null) throw new IllegalStateException("A severe error has occurred in NBTStructure! A jigsaw piece has been registered without a valid name!"); + if(jigsawMap.containsKey(name)) throw new IllegalStateException("A severe error has occurred in NBTStructure! A jigsaw piece has been registered with the same name as another: " + name); + + this.name = name; + this.structure = structure; + jigsawMap.put(name, this); + + this.heightOffset = heightOffset; + } + + } + + // Each jigsaw block in a structure will instance one of these + private static class JigsawConnection { + + private final ThreeInts pos; + private final ForgeDirection dir; + + // what pool should we look through to find a connection + private final String poolName; + + // when we successfully find a pool, what connections in that jigsaw piece can we target + private final String targetName; + + private final boolean isRollable; + + private final int selectionPriority; + private final int placementPriority; + + private JigsawConnection(ThreeInts pos, ForgeDirection dir, String poolName, String targetName, boolean isRollable, int selectionPriority, int placementPriority) { + this.pos = pos; + this.dir = dir; + this.poolName = poolName; + this.targetName = targetName; + this.isRollable = isRollable; + this.selectionPriority = selectionPriority; + this.placementPriority = placementPriority; + } + + } + + public static class Component extends StructureComponent { + + JigsawPiece piece; + + int minHeight = 1; + int maxHeight = 128; + + boolean heightUpdated = false; + + int priority; // placement priority not yet implemented because selection priority is far more useful whatever + + // this is fucking hacky but we need a way to update ALL component bounds once a Y-level is determined + private Start parent; + + private JigsawConnection connectedFrom; + + public Component() {} + + public Component(SpawnCondition spawn, JigsawPiece piece, Random rand, int x, int z) { + this(spawn, piece, rand, x, 0, z, rand.nextInt(4)); + } + + public Component(SpawnCondition spawn, JigsawPiece piece, Random rand, int x, int y, int z, int coordBaseMode) { + super(0); + this.coordBaseMode = coordBaseMode; + this.piece = piece; + this.minHeight = spawn.minHeight; + this.maxHeight = spawn.maxHeight; + + switch(this.coordBaseMode) { + case 1: + case 3: + this.boundingBox = new StructureBoundingBox(x, y, z, x + piece.structure.size.z - 1, y + piece.structure.size.y - 1, z + piece.structure.size.x - 1); + break; + default: + this.boundingBox = new StructureBoundingBox(x, y, z, x + piece.structure.size.x - 1, y + piece.structure.size.y - 1, z + piece.structure.size.z - 1); + break; + } + } + + public Component connectedFrom(JigsawConnection connection) { + this.connectedFrom = connection; + return this; + } + + // Save to NBT + @Override + protected void func_143012_a(NBTTagCompound nbt) { + nbt.setString("piece", piece.name); + nbt.setInteger("min", minHeight); + nbt.setInteger("max", maxHeight); + nbt.setBoolean("hasHeight", heightUpdated); + } + + // Load from NBT + @Override + protected void func_143011_b(NBTTagCompound nbt) { + piece = jigsawMap.get(nbt.getString("piece")); + minHeight = nbt.getInteger("min"); + maxHeight = nbt.getInteger("max"); + heightUpdated = nbt.getBoolean("hasHeight"); + } + + @Override + public boolean addComponentParts(World world, Random rand, StructureBoundingBox box) { + if(piece == null) return false; + + // now we're in the world, update minY/maxY + if(!piece.conformToTerrain && !heightUpdated) { + int y = MathHelper.clamp_int(getAverageHeight(world, box) + piece.heightOffset, minHeight, maxHeight); + + if(!piece.alignToTerrain && parent != null) { + parent.offsetYHeight(y); + } else { + offsetYHeight(y); + } + } + + return piece.structure.build(world, piece, boundingBox, box, coordBaseMode); + } + + public void offsetYHeight(int y) { + boundingBox.minY += y; + boundingBox.maxY += y; + + heightUpdated = true; + } + + // Overrides to fix Mojang's fucked rotations which FLIP instead of rotating in two instances + // vaer being in the mines doing this the hard way for years was absolutely not for naught + @Override + protected int getXWithOffset(int x, int z) { + return boundingBox.minX + piece.structure.rotateX(x, z, coordBaseMode); + } + + @Override + protected int getYWithOffset(int y) { + return boundingBox.minY + y; + } + + @Override + protected int getZWithOffset(int x, int z) { + return boundingBox.minZ + piece.structure.rotateZ(x, z, coordBaseMode); + } + + private ForgeDirection rotateDir(ForgeDirection dir) { + if(dir == ForgeDirection.UP || dir == ForgeDirection.DOWN) return dir; + switch(coordBaseMode) { + default: return dir; + case 1: return dir.getRotation(ForgeDirection.UP); + case 2: return dir.getOpposite(); + case 3: return dir.getRotation(ForgeDirection.DOWN); + } + } + + private int getAverageHeight(World world, StructureBoundingBox box) { + int total = 0; + int iterations = 0; + + for(int z = box.minZ; z <= box.maxZ; z++) { + for(int x = box.minX; x <= box.maxX; x++) { + total += world.getTopSolidOrLiquidBlock(x, z); + iterations++; + } + } + + if(iterations == 0) + return 64; + + return total / iterations; + } + + private int getNextCoordBase(JigsawConnection fromConnection, JigsawConnection toConnection, Random rand) { + if(fromConnection.dir == ForgeDirection.DOWN || fromConnection.dir == ForgeDirection.UP) { + if(fromConnection.isRollable) return rand.nextInt(4); + return coordBaseMode; + } + + return directionOffsetToCoordBase(fromConnection.dir.getOpposite(), toConnection.dir); + } + + private int directionOffsetToCoordBase(ForgeDirection from, ForgeDirection to) { + for(int i = 0; i < 4; i++) { + if(from == to) return (i + coordBaseMode) % 4; + from = from.getRotation(ForgeDirection.DOWN); + } + return coordBaseMode; + } + + protected boolean hasIntersectionIgnoringSelf(LinkedList components, StructureBoundingBox box) { + for(StructureComponent component : components) { + if(component == this) continue; + if(component.getBoundingBox() == null) continue; + + if(component.getBoundingBox().intersectsWith(box)) return true; + } + + return false; + } + + } + + public static class Start extends StructureStart { + + public Start() {} + + @SuppressWarnings("unchecked") + public Start(World world, Random rand, SpawnCondition spawn, int chunkX, int chunkZ) { + super(chunkX, chunkZ); + + int x = chunkX << 4; + int z = chunkZ << 4; + + JigsawPiece startPiece = spawn.structure != null ? spawn.structure : spawn.pools.get(spawn.startPool).get(rand); + + Component startComponent = new Component(spawn, startPiece, rand, x, z); + startComponent.parent = this; + + components.add(startComponent); + + List queuedComponents = new ArrayList<>(); + if(spawn.structure == null) queuedComponents.add(startComponent); + + // Iterate through and build out all the components we intend to spawn + while(!queuedComponents.isEmpty()) { + final int i = rand.nextInt(queuedComponents.size()); + Component fromComponent = queuedComponents.remove(i); + + if(fromComponent.piece.structure.fromConnections == null) continue; + + boolean fallbacksOnly = this.components.size() >= spawn.sizeLimit; + + for(List unshuffledList : fromComponent.piece.structure.fromConnections) { + List connectionList = new ArrayList<>(unshuffledList); + Collections.shuffle(connectionList, rand); + + for(JigsawConnection fromConnection : connectionList) { + if(fromComponent.connectedFrom == fromConnection) continue; // if we already connected to this piece, don't process + + if(fallbacksOnly) { + String fallback = spawn.pools.get(fromConnection.poolName).fallback; + + if(fallback != null) { + Component fallbackComponent = buildNextComponent(rand, spawn, spawn.pools.get(fallback), fromComponent, fromConnection); + addComponent(fallbackComponent, fromConnection.placementPriority); + } + + continue; + } + + JigsawPool nextPool = spawn.getPool(fromConnection.poolName); + + Component nextComponent = null; + + // Iterate randomly through the pool, attempting each piece until one fits + while(nextPool.totalWeight > 0) { + nextComponent = buildNextComponent(rand, spawn, nextPool, fromComponent, fromConnection); + if(nextComponent != null && !fromComponent.hasIntersectionIgnoringSelf(components, nextComponent.getBoundingBox())) break; + nextComponent = null; + } + + if(nextComponent != null) { + addComponent(nextComponent, fromConnection.placementPriority); + queuedComponents.add(nextComponent); + } else { + // If we failed to fit anything in, grab something from the fallback pool, ignoring bounds check + if(nextPool.fallback != null) { + nextComponent = buildNextComponent(rand, spawn, spawn.pools.get(nextPool.fallback), fromComponent, fromConnection); + addComponent(nextComponent, fromConnection.placementPriority); // don't add to queued list, we don't want to try continue from fallback + } + } + } + } + } + + if(GeneralConfig.enableDebugMode) { + MainRegistry.logger.info("[Debug] Spawning NBT structure at: " + chunkX * 16 + ", " + chunkZ * 16); + String componentList = "[Debug] Components: "; + for(Object component : this.components) { + componentList += ((Component) component).piece.structure.name + " "; + } + MainRegistry.logger.info(componentList); + } + + updateBoundingBox(); + } + + @SuppressWarnings("unchecked") + private void addComponent(Component component, int placementPriority) { + components.add(component); + + component.parent = this; + component.priority = placementPriority; + } + + private Component buildNextComponent(Random rand, SpawnCondition spawn, JigsawPool pool, Component fromComponent, JigsawConnection fromConnection) { + JigsawPiece nextPiece = pool.get(rand); + if(nextPiece == null) return null; + + List connectionPool = getConnectionPool(nextPiece, fromConnection); + if(connectionPool == null) return null; + + JigsawConnection toConnection = connectionPool.get(rand.nextInt(connectionPool.size())); + + // The direction this component is extending towards in ABSOLUTE direction + ForgeDirection extendDir = fromComponent.rotateDir(fromConnection.dir); + + // Rotate our incoming piece to plug it in + int nextCoordBase = fromComponent.getNextCoordBase(fromConnection, toConnection, rand); + + // Set the starting point for the next structure to the location of the connector block + int nextX = fromComponent.getXWithOffset(fromConnection.pos.x, fromConnection.pos.z) + extendDir.offsetX; + int nextY = fromComponent.getYWithOffset(fromConnection.pos.y) + extendDir.offsetY; + int nextZ = fromComponent.getZWithOffset(fromConnection.pos.x, fromConnection.pos.z) + extendDir.offsetZ; + + // offset the starting point to the connecting point + nextX -= nextPiece.structure.rotateX(toConnection.pos.x, toConnection.pos.z, nextCoordBase); + nextY -= toConnection.pos.y; + nextZ -= nextPiece.structure.rotateZ(toConnection.pos.x, toConnection.pos.z, nextCoordBase); + + return new Component(spawn, nextPiece, rand, nextX, nextY, nextZ, nextCoordBase).connectedFrom(toConnection); + } + + private List getConnectionPool(JigsawPiece nextPiece, JigsawConnection fromConnection) { + if(fromConnection.dir == ForgeDirection.DOWN) { + return nextPiece.structure.toTopConnections.get(fromConnection.targetName); + } else if(fromConnection.dir == ForgeDirection.UP) { + return nextPiece.structure.toBottomConnections.get(fromConnection.targetName); + } + + return nextPiece.structure.toHorizontalConnections.get(fromConnection.targetName); + } + + // post loading, update parent reference for loaded components + @Override + public void func_143017_b(NBTTagCompound nbt) { + for(Object o : components) { + ((Component) o).parent = this; + } + } + + public void offsetYHeight(int y) { + for(Object o : components) { + Component component = (Component) o; + if(component.heightUpdated || component.piece.conformToTerrain || component.piece.alignToTerrain) continue; + component.offsetYHeight(y); + } + } + + } + + public static class GenStructure extends MapGenStructure { + + private SpawnCondition nextSpawn; + + public void generateStructures(World world, Random rand, IChunkProvider chunkProvider, int chunkX, int chunkZ) { + Block[] ablock = new Block[65536]; + + func_151539_a(chunkProvider, world, chunkX, chunkZ, ablock); + generateStructuresInChunk(world, rand, chunkX, chunkZ); + } + + @Override + public String func_143025_a() { + return "NBTStructures"; + } + + @Override + protected boolean canSpawnStructureAtCoords(int chunkX, int chunkZ) { + if(!weightedMap.containsKey(worldObj.provider.dimensionId)) return false; + + int x = chunkX; + int z = chunkZ; + + if(x < 0) x -= StructureConfig.structureMaxChunks - 1; + if(z < 0) z -= StructureConfig.structureMaxChunks - 1; + + x /= StructureConfig.structureMaxChunks; + z /= StructureConfig.structureMaxChunks; + rand.setSeed((long)x * 341873128712L + (long)z * 132897987541L + this.worldObj.getWorldInfo().getSeed() + (long)996996996 - worldObj.provider.dimensionId); + x *= StructureConfig.structureMaxChunks; + z *= StructureConfig.structureMaxChunks; + x += rand.nextInt(StructureConfig.structureMaxChunks - StructureConfig.structureMinChunks); + z += rand.nextInt(StructureConfig.structureMaxChunks - StructureConfig.structureMinChunks); + + if(chunkX == x && chunkZ == z) { + BiomeGenBase biome = this.worldObj.getWorldChunkManager().getBiomeGenAt(chunkX * 16 + 8, chunkZ * 16 + 8); + + nextSpawn = findSpawn(biome); + + return nextSpawn != null && (nextSpawn.pools != null || nextSpawn.start != null || nextSpawn.structure != null); + } + + return false; + } + + @Override + protected StructureStart getStructureStart(int chunkX, int chunkZ) { + if(nextSpawn.start != null) return nextSpawn.start.apply(new Quartet(this.worldObj, this.rand, chunkX, chunkZ)); + return new Start(this.worldObj, this.rand, nextSpawn, chunkX, chunkZ); + } + + private SpawnCondition findSpawn(BiomeGenBase biome) { + List spawnList = weightedMap.get(worldObj.provider.dimensionId); + + for(int i = 0; i < 64; i++) { + SpawnCondition spawn = spawnList.get(rand.nextInt(spawnList.size())); + if(spawn.isValid(biome)) return spawn; + } + + return null; + } + + } + +} \ No newline at end of file diff --git a/src/main/java/com/hbm/world/gen/NTMWorldGenerator.java b/src/main/java/com/hbm/world/gen/NTMWorldGenerator.java index 6fb9e7fd1..3d9306b28 100644 --- a/src/main/java/com/hbm/world/gen/NTMWorldGenerator.java +++ b/src/main/java/com/hbm/world/gen/NTMWorldGenerator.java @@ -1,8 +1,22 @@ package com.hbm.world.gen; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import java.util.Random; +import com.hbm.blocks.ModBlocks; import com.hbm.config.StructureConfig; +import com.hbm.main.StructureManager; +import com.hbm.world.gen.NBTStructure.JigsawPiece; +import com.hbm.world.gen.NBTStructure.JigsawPool; +import com.hbm.world.gen.NBTStructure.SpawnCondition; +import com.hbm.world.gen.component.BunkerComponents.BunkerStart; +import com.hbm.world.gen.component.Component.CrabSpawners; +import com.hbm.world.gen.component.Component.GreenOoze; +import com.hbm.world.gen.component.Component.MeteorBricks; +import com.hbm.world.gen.component.Component.SupplyCrates; import cpw.mods.fml.common.IWorldGenerator; import cpw.mods.fml.common.eventhandler.SubscribeEvent; @@ -10,125 +24,163 @@ import net.minecraft.block.Block; import net.minecraft.world.World; import net.minecraft.world.biome.BiomeGenBase; import net.minecraft.world.chunk.IChunkProvider; -import static net.minecraftforge.common.BiomeDictionary.*; +import net.minecraft.world.gen.structure.StructureComponent.BlockSelector; import net.minecraftforge.event.terraingen.InitMapGenEvent.EventType; import net.minecraftforge.event.terraingen.PopulateChunkEvent; -import static net.minecraftforge.event.terraingen.TerrainGen.*; +import net.minecraftforge.event.terraingen.TerrainGen; import net.minecraftforge.event.world.WorldEvent; public class NTMWorldGenerator implements IWorldGenerator { - private MapGenNTMFeatures scatteredFeatureGen = new MapGenNTMFeatures(); - + + boolean regTest = false; + + public NTMWorldGenerator() { + final List invalidBiomes = Arrays.asList(new BiomeGenBase[] {BiomeGenBase.ocean, BiomeGenBase.river, BiomeGenBase.frozenOcean, BiomeGenBase.frozenRiver, BiomeGenBase.deepOcean}); + + NBTStructure.registerStructure(0, new SpawnCondition() {{ + canSpawn = biome -> !invalidBiomes.contains(biome); + start = d -> new MapGenNTMFeatures.Start(d.getW(), d.getX(), d.getY(), d.getZ()); + spawnWeight = 14; + }}); + + NBTStructure.registerStructure(0, new SpawnCondition() {{ + canSpawn = biome -> !invalidBiomes.contains(biome); + start = d -> new BunkerStart(d.getW(), d.getX(), d.getY(), d.getZ()); + spawnWeight = 1; + }}); + + Map bricks = new HashMap() {{ + put(ModBlocks.meteor_brick, new MeteorBricks()); + }}; + Map crates = new HashMap() {{ + put(ModBlocks.meteor_brick, new MeteorBricks()); + put(ModBlocks.crate, new SupplyCrates()); + put(ModBlocks.meteor_spawner, new CrabSpawners()); + }}; + Map ooze = new HashMap() {{ + put(ModBlocks.meteor_brick, new MeteorBricks()); + put(ModBlocks.concrete_colored, new GreenOoze()); + }}; + + NBTStructure.registerStructure(0, new SpawnCondition() {{ + minHeight = 32; + maxHeight = 32; + sizeLimit = 128; + canSpawn = biome -> biome.rootHeight >= 0; + startPool = "start"; + pools = new HashMap() {{ + put("start", new JigsawPool() {{ + add(new JigsawPiece("meteor_core", StructureManager.meteor_core) {{ blockTable = bricks; }}, 1); + }}); + put("spike", new JigsawPool() {{ + add(new JigsawPiece("meteor_spike", StructureManager.meteor_spike) {{ heightOffset = -3; conformToTerrain = true; }}, 1); + }}); + put("default", new JigsawPool() {{ + add(new JigsawPiece("meteor_corner", StructureManager.meteor_corner) {{ blockTable = bricks; }}, 2); + add(new JigsawPiece("meteor_t", StructureManager.meteor_t) {{ blockTable = bricks; }}, 3); + add(new JigsawPiece("meteor_stairs", StructureManager.meteor_stairs) {{ blockTable = bricks; }}, 1); + add(new JigsawPiece("meteor_room_base_thru", StructureManager.meteor_room_base_thru) {{ blockTable = bricks; }}, 3); + add(new JigsawPiece("meteor_room_base_end", StructureManager.meteor_room_base_end) {{ blockTable = bricks; }}, 4); + fallback = "fallback"; + }}); + put("10room", new JigsawPool() {{ + add(new JigsawPiece("meteor_room_basic", StructureManager.meteor_room_basic) {{ blockTable = bricks; }}, 1); + add(new JigsawPiece("meteor_room_balcony", StructureManager.meteor_room_balcony) {{ blockTable = bricks; }}, 1); + add(new JigsawPiece("meteor_room_dragon", StructureManager.meteor_room_dragon) {{ blockTable = bricks; }}, 1); + add(new JigsawPiece("meteor_room_ladder", StructureManager.meteor_room_ladder) {{ blockTable = bricks; }}, 1); + add(new JigsawPiece("meteor_room_ooze", StructureManager.meteor_room_ooze) {{ blockTable = ooze; }}, 1); + add(new JigsawPiece("meteor_room_split", StructureManager.meteor_room_split) {{ blockTable = bricks; }}, 1); + add(new JigsawPiece("meteor_room_stairs", StructureManager.meteor_room_stairs) {{ blockTable = bricks; }}, 1); + add(new JigsawPiece("meteor_room_triple", StructureManager.meteor_room_triple) {{ blockTable = bricks; }}, 1); + fallback = "roomback"; + }}); + put("3x3loot", new JigsawPool() {{ + add(new JigsawPiece("meteor_3_bale", StructureManager.meteor_3_bale), 1); + add(new JigsawPiece("meteor_3_blank", StructureManager.meteor_3_blank), 1); + add(new JigsawPiece("meteor_3_block", StructureManager.meteor_3_block), 1); + add(new JigsawPiece("meteor_3_crab", StructureManager.meteor_3_crab), 1); + add(new JigsawPiece("meteor_3_crab_tesla", StructureManager.meteor_3_crab_tesla), 1); + add(new JigsawPiece("meteor_3_crate", StructureManager.meteor_3_crate), 1); + add(new JigsawPiece("meteor_3_dirt", StructureManager.meteor_3_dirt), 1); + add(new JigsawPiece("meteor_3_lead", StructureManager.meteor_3_lead), 1); + add(new JigsawPiece("meteor_3_ooze", StructureManager.meteor_3_ooze), 1); + add(new JigsawPiece("meteor_3_pillar", StructureManager.meteor_3_pillar), 1); + add(new JigsawPiece("meteor_3_star", StructureManager.meteor_3_star), 1); + add(new JigsawPiece("meteor_3_tesla", StructureManager.meteor_3_tesla), 1); + add(new JigsawPiece("meteor_3_book", StructureManager.meteor_3_book), 1); + add(new JigsawPiece("meteor_3_mku", StructureManager.meteor_3_mku), 1); + add(new JigsawPiece("meteor_3_statue", StructureManager.meteor_3_statue), 1); + }}); + put("headloot", new JigsawPool() {{ + add(new JigsawPiece("meteor_dragon_chest", StructureManager.meteor_dragon_chest) {{ blockTable = crates; }}, 1); + add(new JigsawPiece("meteor_dragon_tesla", StructureManager.meteor_dragon_tesla) {{ blockTable = crates; }}, 1); + add(new JigsawPiece("meteor_dragon_trap", StructureManager.meteor_dragon_trap) {{ blockTable = crates; }}, 1); + add(new JigsawPiece("meteor_dragon_crate_crab", StructureManager.meteor_dragon_crate_crab) {{ blockTable = crates; }}, 1); + }}); + put("fallback", new JigsawPool() {{ + add(new JigsawPiece("meteor_fallback", StructureManager.meteor_fallback) {{ blockTable = bricks; }}, 1); + }}); + put("roomback", new JigsawPool() {{ + add(new JigsawPiece("meteor_room_fallback", StructureManager.meteor_room_fallback) {{ blockTable = bricks; }}, 1); + }}); + }}; + }}); + } + + private NBTStructure.GenStructure nbtGen = new NBTStructure.GenStructure(); + private final Random rand = new Random(); //A central random, used to cleanly generate our stuff without affecting vanilla or modded seeds. - + /** Inits all MapGen upon the loading of a new world. Hopefully clears out structureMaps and structureData when a different world is loaded. */ @SubscribeEvent public void onLoad(WorldEvent.Load event) { - scatteredFeatureGen = (MapGenNTMFeatures) getModdedMapGen(new MapGenNTMFeatures(), EventType.CUSTOM); - + nbtGen = (NBTStructure.GenStructure) TerrainGen.getModdedMapGen(new NBTStructure.GenStructure(), EventType.CUSTOM); + hasPopulationEvent = false; } - + /** Called upon the initial population of a chunk. Called in the pre-population event first; called again if pre-population didn't occur (flatland) */ private void setRandomSeed(World world, int chunkX, int chunkZ) { - rand.setSeed(world.getSeed()); + rand.setSeed(world.getSeed() + world.provider.dimensionId); final long i = rand.nextLong() / 2L * 2L + 1L; final long j = rand.nextLong() / 2L * 2L + 1L; rand.setSeed((long)chunkX * i + (long)chunkZ * j ^ world.getSeed()); } - + /* * Pre-population Events / Structure Generation * Used to generate structures without unnecessary intrusion by biome decoration, like trees. */ - + private boolean hasPopulationEvent = false; // Does the given chunkGenerator have a population event? If not (flatlands), default to using generate. - + @SubscribeEvent public void generateStructures(PopulateChunkEvent.Pre event) { - setRandomSeed(event.world, event.chunkX, event.chunkZ); //Set random for population down the line. hasPopulationEvent = true; - + if(StructureConfig.enableStructures == 0) return; if(StructureConfig.enableStructures == 2 && !event.world.getWorldInfo().isMapFeaturesEnabled()) return; - - switch (event.world.provider.dimensionId) { - case -1: - break; - case 0: - generateOverworldStructures(event.world, event.chunkProvider, event.chunkX, event.chunkZ); - break; - case 1: - break; - } + + setRandomSeed(event.world, event.chunkX, event.chunkZ); //Set random for population down the line. + + nbtGen.generateStructures(event.world, rand, event.chunkProvider, event.chunkX, event.chunkZ); } - - protected void generateOverworldStructures(World world, IChunkProvider chunkProvider, int chunkX, int chunkZ) { - Block[] ablock = new Block[65536]; //ablock isn't actually used for anything in MapGenStructure - - this.scatteredFeatureGen.func_151539_a(chunkProvider, world, chunkX, chunkZ, ablock); - this.scatteredFeatureGen.generateStructuresInChunk(world, rand, chunkX, chunkZ); - } - + /* * Post-Vanilla / Modded Generation * Used to generate features that don't care about intrusions (ores, craters, caves, etc.) */ - + @Override - public void generate(Random rand, int chunkX, int chunkZ, World world, IChunkProvider chunkGenerator, IChunkProvider chunkProvider) { - - switch (world.provider.dimensionId) { - case -1: - generateNether(world, rand, chunkGenerator, chunkX, chunkZ); break; - case 0: - generateSurface(world, rand, chunkGenerator, chunkProvider, chunkX, chunkZ); break; - case 1: - generateEnd(world, rand, chunkGenerator, chunkX, chunkZ); break; - } - } - - private void generateNether(World world, Random rand, IChunkProvider chunkGenerator, int chunkX, int chunkZ) { } - - /* Overworld Generation */ - - private void generateSurface(World world, Random rand, IChunkProvider chunkGenerator, IChunkProvider chunkProvider, int chunkX, int chunkZ) { - if(!hasPopulationEvent) { //If we've failed to generate any structures (flatlands) - setRandomSeed(world, chunkX, chunkZ); //Reset the random seed to compensate - - boolean enableStructures = world.getWorldInfo().isMapFeaturesEnabled(); - if(StructureConfig.enableStructures == 1) enableStructures = true; - if(StructureConfig.enableStructures == 0) enableStructures = false; + public void generate(Random unusedRandom, int chunkX, int chunkZ, World world, IChunkProvider chunkGenerator, IChunkProvider chunkProvider) { + if(hasPopulationEvent) return; //If we've failed to generate any structures (flatlands) - if(enableStructures) generateOverworldStructures(world, chunkGenerator, chunkX, chunkZ); //Do it through the post-population generation directly - } - - /* biome dictionary my beloved <3 - * no check for tom here because the event handler already checks for decoration events, + this way they won't become permanently extinct. - */ - - /* Biome check, followed by chance, followed by event (for compat, both intra- and inter- (in the case of Tom). */ - - + if(StructureConfig.enableStructures == 0) return; + if(StructureConfig.enableStructures == 2 && !world.getWorldInfo().isMapFeaturesEnabled()) return; + + setRandomSeed(world, chunkX, chunkZ); //Reset the random seed to compensate + + nbtGen.generateStructures(world, rand, chunkProvider, chunkX, chunkZ); } - private void generateEnd(World world, Random rand, IChunkProvider chunkGenerator, int chunkX, int chunkZ) { } - - /** Utility method for biome checking multiple types exclusively. Not sure why it wasn't already present. */ - public static boolean isBiomeOfTypes(BiomeGenBase biome, Type... types) { //If new biomes are implemented, move this to any biome-related utility class. - for(Type type : types) { - if(!isBiomeOfType(biome, type)) return false; - } - - return true; - } - - /** utility method, same as above but inclusive. useful for catch-alls, like the dirty glass structures have */ - public static boolean doesBiomeHaveTypes(BiomeGenBase biome, Type... types) { - for(Type type : types) { - if(isBiomeOfType(biome, type)) return true; - } - - return false; - } } \ No newline at end of file diff --git a/src/main/java/com/hbm/world/gen/component/Component.java b/src/main/java/com/hbm/world/gen/component/Component.java index 0a652a6eb..80d85bcfd 100644 --- a/src/main/java/com/hbm/world/gen/component/Component.java +++ b/src/main/java/com/hbm/world/gen/component/Component.java @@ -12,6 +12,7 @@ import com.hbm.tileentity.machine.TileEntityLockableBase; import net.minecraft.block.Block; import net.minecraft.block.material.Material; +import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.Blocks; import net.minecraft.inventory.IInventory; import net.minecraft.item.ItemStack; @@ -27,19 +28,19 @@ abstract public class Component extends StructureComponent { /** Average height (Presumably stands for height position) */ protected int hpos = -1; - + protected Component() { super(0); } - + protected Component(int componentType) { super(componentType); } - + protected Component(Random rand, int minX, int minY, int minZ, int maxX, int maxY, int maxZ ) { super(0); this.coordBaseMode = rand.nextInt(4); - + switch(this.coordBaseMode) { case 0: this.boundingBox = new StructureBoundingBox(minX, minY, minZ, minX + maxX, minY + maxY, minZ + maxZ); @@ -55,25 +56,25 @@ abstract public class Component extends StructureComponent { break; default: this.boundingBox = new StructureBoundingBox(minX, minY, minZ, minX + maxX, minY + maxY, minZ + maxZ); - + } } - + /** Set to NBT */ protected void func_143012_a(NBTTagCompound nbt) { nbt.setInteger("HPos", this.hpos); } - + /** Get from NBT */ protected void func_143011_b(NBTTagCompound nbt) { this.hpos = nbt.getInteger("HPos"); } - + protected boolean setAverageHeight(World world, StructureBoundingBox box, int y) { - + int total = 0; int iterations = 0; - + for(int z = this.boundingBox.minZ; z <= this.boundingBox.maxZ; z++) { for(int x = this.boundingBox.minX; x <= this.boundingBox.maxX; x++) { if(box.isVecInside(x, y, z)) { @@ -82,20 +83,20 @@ abstract public class Component extends StructureComponent { } } } - + if(iterations == 0) return false; - + this.hpos = total / iterations; //finds mean of every block in bounding box this.boundingBox.offset(0, this.hpos - this.boundingBox.minY, 0); return true; } - + protected static int getAverageHeight(World world, StructureBoundingBox area, StructureBoundingBox box, int y) { - + int total = 0; int iterations = 0; - + for(int z = area.minZ; z <= area.maxZ; z++) { for(int x = area.minX; x <= area.maxX; x++) { if(box.isVecInside(x, y, z)) { @@ -104,19 +105,19 @@ abstract public class Component extends StructureComponent { } } } - + if(iterations == 0) return -1; - + return total / iterations; } - + public int getCoordMode() { return this.coordBaseMode; } - + /** Metadata for Decoration Methods **/ - + /** * Gets metadata for rotatable pillars. * @param metadata (First two digits are equal to block metadata, other two are equal to orientation @@ -125,10 +126,10 @@ abstract public class Component extends StructureComponent { protected int getPillarMeta(int metadata) { if(this.coordBaseMode % 2 != 0 && this.coordBaseMode != -1) metadata = metadata ^ 12; - + return metadata; } - + /** * Gets metadata for rotatable DecoBlock * honestly i don't remember how i did this and i'm scared to optimize it because i fail to see any reasonable patterns like the pillar @@ -168,14 +169,14 @@ abstract public class Component extends StructureComponent { } return 0; } - + /** * Get orientation-offset metadata for BlockDecoModel; also suitable for trapdoors * @param metadata (0 for facing North, 1 for facing South, 2 for facing West, 3 for facing East) */ protected int getDecoModelMeta(int metadata) { //N: 0b00, S: 0b01, W: 0b10, E: 0b11 - + switch(this.coordBaseMode) { default: //South break; @@ -198,12 +199,12 @@ abstract public class Component extends StructureComponent { //genuinely like. why did i do that return metadata << 2; //To accommodate for BlockDecoModel's shift in the rotation bits; otherwise, simply bit-shift right and or any non-rotation meta after } - + //works for crts, toasters, and anything that follows mc's cardinal dirs. S: 0, W: 1, N: 2, E: 3 protected int getCRTMeta(int meta) { return (meta + this.coordBaseMode) % 4; } - + /** * Gets orientation-adjusted meta for stairs. * 0 = West, 1 = East, 2 = North, 3 = South @@ -228,11 +229,11 @@ abstract public class Component extends StructureComponent { metadata = metadata ^ 2; break; } - + return metadata; } - - /* + + /* * Assuming door is on opposite side of block from direction: East: 0, South: 1, West: 2, North: 3
* Doors cleverly take advantage of the use of two blocks to get around the 16 value limit on metadata, with the top and bottom blocks essentially relying on eachother for everything.
*
  • The 4th bit (0b1000 or 8) indicates whether it is the top block: on for yes, off for no. @@ -245,9 +246,9 @@ abstract public class Component extends StructureComponent { int posX = this.getXWithOffset(featureX, featureZ); int posY = this.getYWithOffset(featureY); int posZ = this.getZWithOffset(featureX, featureZ); - + if(!box.isVecInside(posX, posY, posZ)) return; - + switch(this.coordBaseMode) { default: //South break; @@ -258,11 +259,11 @@ abstract public class Component extends StructureComponent { case 3: //East dirMeta = (dirMeta + 3) % 4; break; //fuck you modulo } - + //hee hoo int metaTop = opensRight ? 0b1001 : 0b1000; int metaBottom = dirMeta | (isOpen ? 0b100 : 0); - + if(world.doesBlockHaveSolidTopSurface(world, posX, posY - 1, posZ)) { world.setBlock(posX, posY, posZ, door, metaBottom, 2); world.setBlock(posX, posY + 1, posZ, door, metaTop, 2); @@ -273,9 +274,9 @@ abstract public class Component extends StructureComponent { int posX = this.getXWithOffset(featureX, featureZ); int posY = this.getYWithOffset(featureY); int posZ = this.getZWithOffset(featureX, featureZ); - + if(!box.isVecInside(posX, posY, posZ)) return; - + if(dirMeta <= 0 || dirMeta >= 7) { //levers suck ass switch(this.coordBaseMode) { case 1: case 3: //west / east @@ -289,10 +290,10 @@ abstract public class Component extends StructureComponent { } else { dirMeta = getButtonMeta(dirMeta); } - + world.setBlock(posX, posY, posZ, Blocks.lever, on ? dirMeta | 8 : dirMeta, 2); } - + /** pain. works for side-facing levers as well */ protected int getButtonMeta(int dirMeta) { switch(this.coordBaseMode) { //are you ready for the pain? @@ -310,12 +311,12 @@ abstract public class Component extends StructureComponent { return dirMeta; } } - + /**N:0 W:1 S:2 E:3 */ protected void placeBed(World world, StructureBoundingBox box, int meta, int featureX, int featureY, int featureZ) { int xOffset = 0; int zOffset = 0; - + switch(meta & 3) { default: zOffset = 1; break; @@ -326,7 +327,7 @@ abstract public class Component extends StructureComponent { case 3: xOffset = 1; break; } - + switch(this.coordBaseMode) { default: //S break; @@ -337,11 +338,11 @@ abstract public class Component extends StructureComponent { case 3: //E meta = (meta - 1) % 4; break; } - + placeBlockAtCurrentPosition(world, Blocks.bed, meta, featureX, featureY, featureZ, box); placeBlockAtCurrentPosition(world, Blocks.bed, meta + 8, featureX + xOffset, featureY, featureZ + zOffset, box); } - + /**Tripwire Hook: S:0 W:1 N:2 E:3 */ protected int getTripwireMeta(int metadata) { switch(this.coordBaseMode) { @@ -355,10 +356,10 @@ abstract public class Component extends StructureComponent { return (metadata - 1) % 4; } } - - + + /** Loot Methods **/ - + /** * it feels disgusting to make a method with this many parameters but fuck it, it's easier * @return TE implementing IInventory with randomized contents @@ -366,29 +367,29 @@ abstract public class Component extends StructureComponent { protected boolean generateInvContents(World world, StructureBoundingBox box, Random rand, Block block, int featureX, int featureY, int featureZ, WeightedRandomChestContent[] content, int amount) { return generateInvContents(world, box, rand, block, 0, featureX, featureY, featureZ, content, amount); } - + //TODO: explore min / max item generations: e.g., between 3 and 5 separate items are generated protected boolean generateInvContents(World world, StructureBoundingBox box, Random rand, Block block, int meta, int featureX, int featureY, int featureZ, WeightedRandomChestContent[] content, int amount) { int posX = this.getXWithOffset(featureX, featureZ); int posY = this.getYWithOffset(featureY); int posZ = this.getZWithOffset(featureX, featureZ); - + if(!box.isVecInside(posX, posY, posZ) || world.getBlock(posX, posY, posZ) == block) //replacement for hasPlacedLoot checks return true; - + this.placeBlockAtCurrentPosition(world, block, meta, featureX, featureY, featureZ, box); IInventory inventory = (IInventory)world.getTileEntity(posX, posY, posZ); - + if(inventory != null) { amount = (int)Math.floor(amount * StructureConfig.lootAmountFactor); WeightedRandomChestContent.generateChestContents(rand, content, inventory, amount < 1 ? 1 : amount); return true; } - + return false; } - - + + /** * Block TE MUST extend TileEntityLockableBase, otherwise this will not work and crash! * @return TE implementing IInventory and extending TileEntityLockableBase with randomized contents + lock @@ -397,48 +398,48 @@ abstract public class Component extends StructureComponent { WeightedRandomChestContent[] content, int amount, double mod) { return generateLockableContents(world, box, rand, block, 0, featureX, featureY, featureZ, content, amount, mod); } - + protected boolean generateLockableContents(World world, StructureBoundingBox box, Random rand, Block block, int meta, int featureX, int featureY, int featureZ, WeightedRandomChestContent[] content, int amount, double mod) { int posX = this.getXWithOffset(featureX, featureZ); int posY = this.getYWithOffset(featureY); int posZ = this.getZWithOffset(featureX, featureZ); - + if(!box.isVecInside(posX, posY, posZ) || world.getBlock(posX, posY, posZ) == block) //replacement for hasPlacedLoot checks return false; - + this.placeBlockAtCurrentPosition(world, block, meta, featureX, featureY, featureZ, box); TileEntity tile = world.getTileEntity(posX, posY, posZ); TileEntityLockableBase lock = (TileEntityLockableBase) tile; IInventory inventory = (IInventory) tile; - + if(inventory != null && lock != null) { amount = (int)Math.floor(amount * StructureConfig.lootAmountFactor); WeightedRandomChestContent.generateChestContents(rand, content, inventory, amount < 1 ? 1 : amount); - + lock.setPins(rand.nextInt(999) + 1); lock.setMod(mod); lock.lock(); return true; } - + return false; } - + protected void generateLoreBook(World world, StructureBoundingBox box, int featureX, int featureY, int featureZ, int slot, ItemStack stack) { //kept for compat int posX = this.getXWithOffset(featureX, featureZ); int posY = this.getYWithOffset(featureY); int posZ = this.getZWithOffset(featureX, featureZ); - + if(!box.isVecInside(posX, posY, posZ)) return; - + IInventory inventory = (IInventory) world.getTileEntity(posX, posY, posZ); - + if(inventory != null) { inventory.setInventorySlotContents(slot, stack); } } - + /** * Places random bobblehead with a randomized orientation at specified location */ @@ -446,71 +447,71 @@ abstract public class Component extends StructureComponent { int posX = this.getXWithOffset(featureX, featureZ); int posY = this.getYWithOffset(featureY); int posZ = this.getZWithOffset(featureX, featureZ); - + placeBlockAtCurrentPosition(world, ModBlocks.bobblehead, rand.nextInt(16), featureX, featureY, featureZ, box); TileEntityBobble bobble = (TileEntityBobble) world.getTileEntity(posX, posY, posZ); - + if(bobble != null) { bobble.type = BobbleType.values()[rand.nextInt(BobbleType.values().length - 1) + 1]; bobble.markDirty(); } } - + /** Block Placement Utility Methods **/ - + /** * Places blocks underneath location until reaching a solid block; good for foundations */ protected void placeFoundationUnderneath(World world, Block placeBlock, int meta, int minX, int minZ, int maxX, int maxZ, int featureY, StructureBoundingBox box) { - + for(int featureX = minX; featureX <= maxX; featureX++) { for(int featureZ = minZ; featureZ <= maxZ; featureZ++) { int posX = this.getXWithOffset(featureX, featureZ); int posY = this.getYWithOffset(featureY); int posZ = this.getZWithOffset(featureX, featureZ); - + if(box.isVecInside(posX, posY, posZ)) { Block block = world.getBlock(posX, posY, posZ); int brake = 0; - - while ((world.isAirBlock(posX, posY, posZ) || - !block.getMaterial().isSolid() || - (block.isFoliage(world, posX, posY, posZ) || block.getMaterial() == Material.leaves)) && + + while ((world.isAirBlock(posX, posY, posZ) || + !block.getMaterial().isSolid() || + (block.isFoliage(world, posX, posY, posZ) || block.getMaterial() == Material.leaves)) && posY > 1 && brake <= 15) { world.setBlock(posX, posY, posZ, placeBlock, meta, 2); block = world.getBlock(posX, --posY, posZ); - + brake++; } } } } } - + /** * Places specified blocks on top of pre-existing blocks in a given area, up to a certain height. Does NOT place blocks on top of liquids. * Useful for stuff like fences and walls most likely. */ protected void placeBlocksOnTop(World world, StructureBoundingBox box, Block block, int minX, int minZ, int maxX, int maxZ, int height) { - + for(int x = minX; x <= maxX; x++) { for(int z = minZ; z <= maxZ; z++) { int posX = this.getXWithOffset(x, z); int posZ = this.getZWithOffset(x, z); int topHeight = world.getTopSolidOrLiquidBlock(posX, posZ); - + if(!world.getBlock(posX, topHeight, posZ).getMaterial().isLiquid()) { - + for(int i = 0; i < height; i++) { int posY = topHeight + i; - + world.setBlock(posX, posY, posZ, block, 0, 2); } } } } } - + /** getXWithOffset & getZWithOffset Methods that are actually fixed **/ //Turns out, this entire time every single minecraft structure is mirrored instead of rotated when facing East and North //Also turns out, it's a scarily easy fix that they somehow didn't see *entirely* @@ -529,7 +530,7 @@ abstract public class Component extends StructureComponent { return x; } } - + @Override public int getZWithOffset(int x, int z) { switch(this.coordBaseMode) { @@ -545,46 +546,46 @@ abstract public class Component extends StructureComponent { return z; } } - + /** Methods that are actually optimized, including ones that cut out replaceBlock and onlyReplace functionality when it's redundant. */ protected void fillWithAir(World world, StructureBoundingBox box, int minX, int minY, int minZ, int maxX, int maxY, int maxZ) { - + if(getYWithOffset(minY) < box.minY || getYWithOffset(maxY) > box.maxY) return; - + for(int x = minX; x <= maxX; x++) { //TODO these could technically be optimized a bit more. probably won't do anything but worth - + for(int z = minZ; z <= maxZ; z++) { int posX = getXWithOffset(x, z); int posZ = getZWithOffset(x, z); - + if(posX >= box.minX && posX <= box.maxX && posZ >= box.minZ && posZ <= box.maxZ) { for(int y = minY; y <= maxY; y++) { int posY = getYWithOffset(y); - + world.setBlock(posX, posY, posZ, Blocks.air, 0, 2); } } } } } - + @Override protected void fillWithBlocks(World world, StructureBoundingBox box, int minX, int minY, int minZ, int maxX, int maxY, int maxZ, Block block, Block replaceBlock, boolean onlyReplace) { - + if(getYWithOffset(minY) < box.minY || getYWithOffset(maxY) > box.maxY) return; - + for(int x = minX; x <= maxX; x++) { - + for(int z = minZ; z <= maxZ; z++) { int posX = getXWithOffset(x, z); int posZ = getZWithOffset(x, z); - + if(posX >= box.minX && posX <= box.maxX && posZ >= box.minZ && posZ <= box.maxZ) { for(int y = minY; y <= maxY; y++) { int posY = getYWithOffset(y); - + if(!onlyReplace || world.getBlock(posX, posY, posZ).getMaterial() != Material.air) { if(x != minX && x != maxX && y != minY && y != maxY && z != minZ && z != maxZ) world.setBlock(posX, posY, posZ, replaceBlock, 0, 2); @@ -596,49 +597,49 @@ abstract public class Component extends StructureComponent { } } } - + protected void fillWithBlocks(World world, StructureBoundingBox box, int minX, int minY, int minZ, int maxX, int maxY, int maxZ, Block block) { - + if(getYWithOffset(minY) < box.minY || getYWithOffset(maxY) > box.maxY) return; - + for(int x = minX; x <= maxX; x++) { - + for(int z = minZ; z <= maxZ; z++) { int posX = getXWithOffset(x, z); int posZ = getZWithOffset(x, z); - + if(posX >= box.minX && posX <= box.maxX && posZ >= box.minZ && posZ <= box.maxZ) { for(int y = minY; y <= maxY; y++) { int posY = getYWithOffset(y); - + world.setBlock(posX, posY, posZ, block, 0, 2); } } } } } - + @Override protected void fillWithMetadataBlocks(World world, StructureBoundingBox box, int minX, int minY, int minZ, int maxX, int maxY, int maxZ, Block block, int meta, Block replaceBlock, int replaceMeta, boolean onlyReplace) { - + if(getYWithOffset(minY) < box.minY || getYWithOffset(maxY) > box.maxY) return; - + for(int x = minX; x <= maxX; x++) { - + for(int z = minZ; z <= maxZ; z++) { int posX = getXWithOffset(x, z); int posZ = getZWithOffset(x, z); - + if(posX >= box.minX && posX <= box.maxX && posZ >= box.minZ && posZ <= box.maxZ) { for(int y = minY; y <= maxY; y++) { int posY = getYWithOffset(y); - + if(!onlyReplace || world.getBlock(posX, posY, posZ).getMaterial() != Material.air) { if(x != minX && x != maxX && y != minY && y != maxY && z != minZ && z != maxZ) world.setBlock(posX, posY, posZ, replaceBlock, replaceMeta, 2); - else + else world.setBlock(posX, posY, posZ, block, meta, 2); } } @@ -646,45 +647,45 @@ abstract public class Component extends StructureComponent { } } } - + protected void fillWithMetadataBlocks(World world, StructureBoundingBox box, int minX, int minY, int minZ, int maxX, int maxY, int maxZ, Block block, int meta) { - + if(getYWithOffset(minY) < box.minY || getYWithOffset(maxY) > box.maxY) return; - + for(int x = minX; x <= maxX; x++) { - + for(int z = minZ; z <= maxZ; z++) { int posX = getXWithOffset(x, z); int posZ = getZWithOffset(x, z); - + if(posX >= box.minX && posX <= box.maxX && posZ >= box.minZ && posZ <= box.maxZ) { for(int y = minY; y <= maxY; y++) { int posY = getYWithOffset(y); - + world.setBlock(posX, posY, posZ, block, meta, 2); } } } } } - + @Override protected void fillWithRandomizedBlocks(World world, StructureBoundingBox box, int minX, int minY, int minZ, int maxX, int maxY, int maxZ, boolean onlyReplace, Random rand, BlockSelector selector) { - + if(getYWithOffset(minY) < box.minY || getYWithOffset(maxY) > box.maxY) return; - + for(int x = minX; x <= maxX; x++) { - + for(int z = minZ; z <= maxZ; z++) { int posX = getXWithOffset(x, z); int posZ = getZWithOffset(x, z); - + if(posX >= box.minX && posX <= box.maxX && posZ >= box.minZ && posZ <= box.maxZ) { for(int y = minY; y <= maxY; y++) { int posY = getYWithOffset(y); - + if(!onlyReplace || world.getBlock(posX, posY, posZ).getMaterial() != Material.air) { selector.selectBlocks(rand, posX, posY, posZ, x == minX || x == maxX || y == minY || y == maxY || z == minZ || z == maxZ); world.setBlock(posX, posY, posZ, selector.func_151561_a(), selector.getSelectedBlockMetaData(), 2); @@ -696,16 +697,16 @@ abstract public class Component extends StructureComponent { } //TODO replace the shitty block selector with something else. probably a lambda that returns a metablock for convenience protected void fillWithRandomizedBlocks(World world, StructureBoundingBox box, int minX, int minY, int minZ, int maxX, int maxY, int maxZ, Random rand, BlockSelector selector) { //so i don't have to replace shit - + if(getYWithOffset(minY) < box.minY || getYWithOffset(maxY) > box.maxY) return; - + for(int x = minX; x <= maxX; x++) { - + for(int z = minZ; z <= maxZ; z++) { int posX = getXWithOffset(x, z); int posZ = getZWithOffset(x, z); - + if(posX >= box.minX && posX <= box.maxX && posZ >= box.minZ && posZ <= box.maxZ) { for(int y = minY; y <= maxY; y++) { int posY = getYWithOffset(y); @@ -717,19 +718,19 @@ abstract public class Component extends StructureComponent { } } } - + //stairs and shit protected void fillWithRandomizedBlocksMeta(World world, StructureBoundingBox box, int minX, int minY, int minZ, int maxX, int maxY, int maxZ, Random rand, BlockSelector selector, int meta) { - + if(getYWithOffset(minY) < box.minY || getYWithOffset(maxY) > box.maxY) return; - + for(int x = minX; x <= maxX; x++) { - + for(int z = minZ; z <= maxZ; z++) { int posX = getXWithOffset(x, z); int posZ = getZWithOffset(x, z); - + if(posX >= box.minX && posX <= box.maxX && posZ >= box.minZ && posZ <= box.maxZ) { for(int y = minY; y <= maxY; y++) { int posY = getYWithOffset(y); @@ -741,23 +742,23 @@ abstract public class Component extends StructureComponent { } } } - + @Override protected void randomlyFillWithBlocks(World world, StructureBoundingBox box, Random rand, float randLimit, int minX, int minY, int minZ, int maxX, int maxY, int maxZ, Block block, Block replaceBlock, boolean onlyReplace) { - + if(getYWithOffset(minY) < box.minY || getYWithOffset(maxY) > box.maxY) return; - + for(int x = minX; x <= maxX; x++) { - + for(int z = minZ; z <= maxZ; z++) { int posX = getXWithOffset(x, z); int posZ = getZWithOffset(x, z); - + if(posX >= box.minX && posX <= box.maxX && posZ >= box.minZ && posZ <= box.maxZ) { for(int y = minY; y <= maxY; y++) { int posY = getYWithOffset(y); - + if(rand.nextFloat() <= randLimit && (!onlyReplace || world.getBlock(posX, posY, posZ).getMaterial() != Material.air)) { if(x != minX && x != maxX && y != minY && y != maxY && z != minZ && z != maxZ) world.setBlock(posX, posY, posZ, replaceBlock, 0, 2); @@ -769,22 +770,22 @@ abstract public class Component extends StructureComponent { } } } - + protected void randomlyFillWithBlocks(World world, StructureBoundingBox box, Random rand, float randLimit, int minX, int minY, int minZ, int maxX, int maxY, int maxZ, Block block) { - + if(getYWithOffset(minY) < box.minY || getYWithOffset(maxY) > box.maxY) return; - + for(int x = minX; x <= maxX; x++) { - + for(int z = minZ; z <= maxZ; z++) { int posX = getXWithOffset(x, z); int posZ = getZWithOffset(x, z); - + if(posX >= box.minX && posX <= box.maxX && posZ >= box.minZ && posZ <= box.maxZ) { for(int y = minY; y <= maxY; y++) { int posY = getYWithOffset(y); - + if(rand.nextFloat() <= randLimit) world.setBlock(posX, posY, posZ, block, 0, 2); } @@ -792,22 +793,22 @@ abstract public class Component extends StructureComponent { } } } - + protected void randomlyFillWithBlocks(World world, StructureBoundingBox box, Random rand, float randLimit, int minX, int minY, int minZ, int maxX, int maxY, int maxZ, Block block, int meta) { - + if(getYWithOffset(minY) < box.minY || getYWithOffset(maxY) > box.maxY) return; - + for(int x = minX; x <= maxX; x++) { - + for(int z = minZ; z <= maxZ; z++) { int posX = getXWithOffset(x, z); int posZ = getZWithOffset(x, z); - + if(posX >= box.minX && posX <= box.maxX && posZ >= box.minZ && posZ <= box.maxZ) { for(int y = minY; y <= maxY; y++) { int posY = getYWithOffset(y); - + if(rand.nextFloat() <= randLimit) world.setBlock(posX, posY, posZ, block, meta, 2); } @@ -815,7 +816,7 @@ abstract public class Component extends StructureComponent { } } } - + protected ForgeDirection getDirection(ForgeDirection dir) { switch(coordBaseMode) { default: //South @@ -828,7 +829,7 @@ abstract public class Component extends StructureComponent { return dir.getRotation(ForgeDirection.DOWN); } } - + /** Sets the core block for a BlockDummyable multiblock. WARNING: Does not take {@link com.hbm.blocks.BlockDummyable#getDirModified(ForgeDirection)} or {@link com.hbm.blocks.BlockDummyable#getMetaForCore(World, int, int, int, EntityPlayer, int)} * into account yet! This will be changed as it comes up!
    * For BlockDummyables, 'dir' always faces the player, being the opposite of the player's direction. This is already taken into account. */ @@ -836,47 +837,47 @@ abstract public class Component extends StructureComponent { int posX = getXWithOffset(x, z); int posZ = getZWithOffset(x, z); int posY = getYWithOffset(y); - + if(!box.isVecInside(posX, posY, posZ)) return; - + if(dir == null) dir = ForgeDirection.NORTH; - + dir = getDirection(dir.getOpposite()); world.setBlock(posX, posY, posZ, block, dir.ordinal() + BlockDummyable.offset, 2); } - + //always set the core block first /** StructureComponent-friendly method for {@link com.hbm.handler.MultiblockHandlerXR#fillSpace(World, int, int, int, int[], Block, ForgeDirection)}. Prevents runoff outside of the provided bounding box.
    * For BlockDummyables, 'dir' always faces the player, being the opposite of the player's direction. This is already taken into account. */ protected void fillSpace(World world, StructureBoundingBox box, int x, int y, int z, int[] dim, Block block, ForgeDirection dir) { - + if(getYWithOffset(y - dim[1]) < box.minY || getYWithOffset(y + dim[0]) > box.maxY) //the BlockDummyable will be fucked regardless if it goes beyond either limit return; - + if(dir == null) dir = ForgeDirection.NORTH; - + dir = getDirection(dir.getOpposite()); - + int count = 0; - + int[] rot = MultiblockHandlerXR.rotate(dim, dir); - + int posX = getXWithOffset(x, z); int posZ = getZWithOffset(x, z); //MY SILLY ASS OPERATING WITH ALREADY FUCKING MODIFIED VARIABLES CLOWNKOEN int posY = getYWithOffset(y); - + BlockDummyable.safeRem = true; - + for(int a = posX - rot[4]; a <= posX + rot[5]; a++) { for(int c = posZ - rot[2]; c <= posZ + rot[3]; c++) { - + if(a >= box.minX && a <= box.maxX && c >= box.minZ && c <= box.maxZ) { for(int b = posY - rot[1]; b <= posY + rot[0]; b++) { - + int meta = 0; - + if(b < posY) { meta = ForgeDirection.DOWN.ordinal(); } else if(b > posY) { @@ -892,14 +893,14 @@ abstract public class Component extends StructureComponent { } else { continue; } - + world.setBlock(a, b, c, block, meta, 2); - + count++; - + if(count > 2000) { System.out.println("component's fillspace: ded " + a + " " + b + " " + c + " " + x + " " + y + " " + z); - + BlockDummyable.safeRem = false; return; } @@ -907,19 +908,19 @@ abstract public class Component extends StructureComponent { } } } - + BlockDummyable.safeRem = false; } - + /** StructureComponent-friendly method for {@link com.hbm.blocks.BlockDummyable#makeExtra(World, int, int, int)}. Prevents runoff outside of the provided bounding box. */ public void makeExtra(World world, StructureBoundingBox box, Block block, int x, int y, int z) { int posX = getXWithOffset(x, z); int posZ = getZWithOffset(x, z); int posY = getYWithOffset(y); - + if(!box.isVecInside(posX, posY, posZ)) return; - + if(world.getBlock(posX, posY, posZ) != block) return; @@ -927,23 +928,23 @@ abstract public class Component extends StructureComponent { if(meta > 5) return; - + BlockDummyable.safeRem = true; world.setBlock(posX, posY, posZ, block, meta + BlockDummyable.extra, 3); BlockDummyable.safeRem = false; } - + /** Block Selectors **/ - + static class Sandstone extends StructureComponent.BlockSelector { - + Sandstone() { } - + /** Selects blocks */ @Override public void selectBlocks(Random rand, int posX, int posY, int posZ, boolean notInterior) { float chance = rand.nextFloat(); - + if(chance > 0.6F) { this.field_151562_a = Blocks.sandstone; } else if (chance < 0.5F ) { @@ -953,16 +954,16 @@ abstract public class Component extends StructureComponent { } } } - + static class ConcreteBricks extends StructureComponent.BlockSelector { - + ConcreteBricks() { } - + /** Selects blocks */ @Override public void selectBlocks(Random rand, int posX, int posY, int posZ, boolean notInterior) { float chance = rand.nextFloat(); - + if(chance < 0.4F) { this.field_151562_a = ModBlocks.brick_concrete; } else if (chance < 0.7F) { @@ -974,18 +975,18 @@ abstract public class Component extends StructureComponent { } } } - + static class ConcreteBricksStairs extends StructureComponent.BlockSelector { - + ConcreteBricksStairs() { this.selectedBlockMetaData = 0; } - + /** Selects blocks */ @Override public void selectBlocks(Random rand, int posX, int posY, int posZ, boolean notInterior) { float chance = rand.nextFloat(); - + if(chance < 0.4F) { this.field_151562_a = ModBlocks.brick_concrete_stairs; } else if (chance < 0.7F) { @@ -997,19 +998,19 @@ abstract public class Component extends StructureComponent { } } } - + static class ConcreteBricksSlabs extends StructureComponent.BlockSelector { - + ConcreteBricksSlabs() { this.field_151562_a = ModBlocks.concrete_brick_slab; this.selectedBlockMetaData = 0; } - + /** Selects blocks */ @Override public void selectBlocks(Random rand, int posX, int posY, int posZ, boolean notInterior) { float chance = rand.nextFloat(); - + if (chance >= 0.4F && chance < 0.7F) { this.selectedBlockMetaData |= 1; } else if (chance < 0.9F) { @@ -1019,17 +1020,17 @@ abstract public class Component extends StructureComponent { } } } - + //ag static class LabTiles extends StructureComponent.BlockSelector { - + LabTiles() { } - + /** Selects blocks */ @Override public void selectBlocks(Random rand, int posX, int posY, int posZ, boolean notInterior) { float chance = rand.nextFloat(); - + if(chance < 0.5F) { this.field_151562_a = ModBlocks.tile_lab; } else if (chance < 0.9F) { @@ -1039,18 +1040,84 @@ abstract public class Component extends StructureComponent { } } } - + static class SuperConcrete extends StructureComponent.BlockSelector { - + SuperConcrete() { this.field_151562_a = ModBlocks.concrete_super; } - + /** Selects blocks */ @Override public void selectBlocks(Random rand, int posX, int posY, int posZ, boolean notInterior) { this.selectedBlockMetaData = rand.nextInt(6) + 10; } } - + + public static class MeteorBricks extends BlockSelector { + + @Override + public void selectBlocks(Random rand, int posX, int posY, int posZ, boolean notInterior) { + float chance = rand.nextFloat(); + + if(chance < 0.4F) { + this.field_151562_a = ModBlocks.meteor_brick; + } else if (chance < 0.7F) { + this.field_151562_a = ModBlocks.meteor_brick_mossy; + } else { + this.field_151562_a = ModBlocks.meteor_brick_cracked; + } + } + + } + + public static class SupplyCrates extends BlockSelector { + + @Override + public void selectBlocks(Random rand, int posX, int posY, int posZ, boolean notInterior) { + float chance = rand.nextFloat(); + + if(chance < 0.6F) { + this.field_151562_a = Blocks.air; + } else if(chance < 0.8F) { + this.field_151562_a = ModBlocks.crate_ammo; + } else if(chance < 0.9F) { + this.field_151562_a = ModBlocks.crate_can; + } else { + this.field_151562_a = ModBlocks.crate; + } + } + + } + + public static class CrabSpawners extends BlockSelector { + + @Override + public void selectBlocks(Random rand, int posX, int posY, int posZ, boolean notInterior) { + float chance = rand.nextFloat(); + + if(chance < 0.8F) { + this.field_151562_a = ModBlocks.meteor_brick; + } else { + this.field_151562_a = ModBlocks.meteor_spawner; + } + } + + } + + public static class GreenOoze extends BlockSelector { + + @Override + public void selectBlocks(Random rand, int posX, int posY, int posZ, boolean notInterior) { + float chance = rand.nextFloat(); + + if(chance < 0.8F) { + this.field_151562_a = ModBlocks.toxic_block; + } else { + this.field_151562_a = ModBlocks.meteor_polished; + } + } + + } + } diff --git a/src/main/resources/assets/hbm/lang/en_US.lang b/src/main/resources/assets/hbm/lang/en_US.lang index d4817b135..14ce1f4f0 100644 --- a/src/main/resources/assets/hbm/lang/en_US.lang +++ b/src/main/resources/assets/hbm/lang/en_US.lang @@ -5329,6 +5329,7 @@ tile.deco_computer.ibm_300pl.name=IBM Personal Computer 300PL tile.deco_crt.name=Old CRT Screen tile.deco_emitter.name=Deco Light Emitter tile.deco_lead.name=Lead Deco Block +tile.deco_loot.name=Loot Pile tile.deco_rbmk.name=RBMK Deco Block tile.deco_rbmk_smooth.name=Smooth RBMK Deco Block tile.deco_red_copper.name=Red Copper Deco Block @@ -6151,6 +6152,9 @@ tile.vitrified_barrel.name=Vitrified Nuclear Waste Drum tile.volcanic_lava_block.name=Volcanic Lava tile.volcano_core.name=Volcano Core tile.volcano_rad_core.name=Rad Volcano Core +tile.wand_air.name=Structure Wand Block (Air) +tile.wand_loot.name=Structure Wand Block (Lootable) +tile.wand_jigsaw.name=Structure Wand Block (Jigsaw) tile.waste_earth.name=Dead Grass tile.waste_leaves.name=Dead Leaves tile.waste_log.name=Charred Log diff --git a/src/main/resources/assets/hbm/structures/crashed-vertibird.nbt b/src/main/resources/assets/hbm/structures/crashed-vertibird.nbt new file mode 100644 index 0000000000000000000000000000000000000000..93e22b9fbcba743bc4c538bd72cb58b3042a7447 GIT binary patch literal 1664 zcmV-`27mbg-0S+{E;OmPFti`eS@NC(VL*XDQchrg2YIR zpmzc-tz)8;D3EmB^p*M!?W>ifG%~#+=S-jo5DX(9chAhu&djcvm?$E@O#ikX5jEe7 z`a7?`&ms!#rb?^SmehPAnp|i3@{ckm8vPiNx6Mm_sQFClukpx~RZ`jg6J2JcWCFm9 z_dmPLsE6^J`4mh57^4`+D8@myj}^AFk46f{>oDUUX6%gP4KQOcSL;W`Tm~?nLXW4= z<2knXF}^cS-(0?OoQZ-70Am~<4lyV;+*loAkRBAP%%Hg@in%l~A1LMulyij&CIU>T z&=V^3gbF>OLQkX^=dAud5g4C#A1SvqOp{wk!F0#*2N-EDGb8Q6b{{)>+`Y_9cP=x) zNPCbODOQ>3uDhG-{QXblLpL7|F;W~dBgLW5zE&_&j4>m{s!zN8gVx4jj!Y-8OnL&1;JkJcW zD^%DODKtk4&8Vg@gW@n&j1wzjwPB_T=1jrN05esL(=c-da}F3yU2d4C0%K_Rk#aaQ z-Q4TeriMZFof#>IGb82jwhlORxwV@aDMv9Q?PWu_<}!nPh-xk~(*9y50&9WlGBeWt zVn*7hhHzbG2CXTo%gl83xaZ~e9HW>E)ox}`Y#i6+n7qw(HKw4jt6$Rhw=^EnS(cR5 zTe~W&d}HhNn$-XHD!*^!2kX0=o6N523_VU)bWx?5ZEsILEUuHPvc(6V%r?Kb1?@j0 z3b#d?7d0}9$fT8B@9tR!Zov@s4{}rA(SPWt#RIEE{=9odALd_gAkCXBV4v3B% zaN=N7;LV0PQ+QKq{S4uDl^Ik{-Ilgb&v8q8f|K0d_au+IO>&>d8%An?nUNY`W>9n6 zFc*NC5-wWPBainpQuEKu>{G3rdy+V5<=i7j-^w+NbmU+Lt;$rfDrZMga)NR0S?MHC zxreGgPtAZACbauVO?tziLlra9r71H~lg^CPI5!Ns5M@T{Ihc`}H)f;@(Fx(h88gVw z?N0?G)ywu!aWvOQ^iu!*^Z9Tu_3rZRZ!dp(`S#~e&`Yt>t~G8i#f((bn2~DQWWOUu zU?q(rLX9FqjY6|gXhz3KW>BP~VpknQLynHlLSnHi1kQn%E`sls-2ieU!Xj;^Gc zLAJYRj-hchwo7M@c8@CTLRaL>AkFBCoEfAUb;-;~Cj@4s6GFqFD{^L}POaI;=+zl! zq*rGG!mrLSBh^7>x^uZ_L}sMdYnYKbozqG3>;XGY5NA>nuq6)_en^n?mMkwQ2L<&8zLQkyF6D#JLD#kfeGExPQx$|94Be>;0p;MPJ#I55U4kZoMzJ+oH(+#RB(Fi zqzP5kmnF+u@67Ic#s!cgaq5?10MkywnIof)6)SQGE61|ZX8q*~9~3#_-nfY{uNVu* zlIg%WhY@#RqAM72wpW3;t2jf_8>5ld)X1G?fy5fEMTR9yyCI%4F>*(m)~rl77E4-U zISh!j-8GG-8opj9TbfxJ7J~+O*;eg4D^0JSMaGuB(aLS9&Jd{@&mlFa_fzg=SC^k^ zr-RXyjJ#qhzl=0R!m&L+)_-O)QL_o(H#y>m}?GBnA3S46jQsBns~lS z`!NjvDK1c~tm(;y|CSxh5O2YOkKn*X!EuZEG&7H!xXF5)S(Tr%@h{U>`%1*gYO z(!ffVz23FIneBiUb<#gn0l2Ta>@6fY)~qR^M2mfI{BTKKPDF>w^(;{b?+u!fCUrF| zP)Bc!kl3?|XX33=p-p6HVC@}dOl^r(ISMrPI!%T~yb0>2vN3gdqP004-q Bbb$Z> literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/hbm/structures/meteor/loot3x3/meteor-3-block.nbt b/src/main/resources/assets/hbm/structures/meteor/loot3x3/meteor-3-block.nbt new file mode 100644 index 0000000000000000000000000000000000000000..53fd15326cf7ef1e8f08d8dccf0e151296ec39c5 GIT binary patch literal 312 zcmV-80muFyiwFP!000000F6>xZi6ro90LiD{>H%7}=Xf?dgjl z&v+F&c46l{{z`h^*0CBv`YwJK`x5B6XyxU}c)2SX2|s zen78JR+~MGex#i%9na}f}nCgwx#M4#W z4x#@~VTNpDO-t7Qx8!7oc=HZ?cn7WujwR;f#5{9ik@YmOdc*UfYxl(Xo2(oB68Hl; K?1qIu0{{T6-9%8}2jg_OL4l?`tBW*cpN6uf za{#oE`se#{y{ou#@N_aBKSYnC*U|VndbztFS?MQMx?%~|dWUVjLQ35+DQT&3S{Ubm z95tAIIchNN9369w>4XW?_LrB}N0VwALO3a8j)h6Rzp;v38&{r84tk#*{$ma;b1M%$ dtQ*TZ+htX*Qt&>oP<3Po`~ngS)V0C`000{@tm6Ox literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/hbm/structures/meteor/loot3x3/meteor-3-crab-tesla.nbt b/src/main/resources/assets/hbm/structures/meteor/loot3x3/meteor-3-crab-tesla.nbt new file mode 100644 index 0000000000000000000000000000000000000000..f707d794e1334bc48ff24edabfc171bab624b47a GIT binary patch literal 367 zcmV-#0g(P5iwFP!000000HssyZi6rkbbuDZq-j6)^%T>7?;)nX0Se%@*#e0YcUAZF zBQO|cbd|bD2sz1}?eirC;1D_ai6H>=U*!KB60Av*L?=EeEltXB=>jA?G zVc|#+wm}MEol^pVEa8Tv!j|ul6;|X9<{8+Cft|P$T%3i?)X4^h$Y`w~E^#e(iWo#z zE5#C6lCT@3;Uom^P+>t**Bx0@A&Itph^yUtt+0fKuND;!s00?Re(#)*BC(c`5Br4JR5M%NblGRWKvfQJ0?VZbU}t zl*kG#6^Df+tUCM5(6dQ_;p9&6Z&&pUf4Qo^bL=V(SHAX@P)Ng8Y`W0DfGCA@Wwk-; zUr6$80ru?Y{_5xcI32UmO1f>M**WAdgE%AhHQKYl+W|Oo&RNv;fNDqAh!TIGb)B&o Nd;yc9$ekku001Iyt#JSV literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/hbm/structures/meteor/loot3x3/meteor-3-crab.nbt b/src/main/resources/assets/hbm/structures/meteor/loot3x3/meteor-3-crab.nbt new file mode 100644 index 0000000000000000000000000000000000000000..7891ce8b035c0eac170cad79d9b59307054d9ec2 GIT binary patch literal 308 zcmV-40n7d$iwFP!000000HssgPQx$^J!!l3!V3=w{sQsLN1**dmA2jpBu$lgRPgmQ zEh|N0Aa#+V$Z>q^;}aJ^j>M}EiUFK<63!eMwX9f?M_4(wmA3V(FM?4ZZY$0ZsRq}q zG>vcH%i77x4{zhn`V-u|Vr)E1rqNh~ATCCTRwIZ%StOmc8fim&dDJYBIIFeDux05E z#Iq+x?nzV4%C-|&Vuf7k`=P7Z&RfezM4MrI^f4 zYU24S?ItsfMpU5KIopv7qmzBlbH?oev_M$S)K3VZ@Vp#GxL G0{{R}M32A# literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/hbm/structures/meteor/loot3x3/meteor-3-crate.nbt b/src/main/resources/assets/hbm/structures/meteor/loot3x3/meteor-3-crate.nbt new file mode 100644 index 0000000000000000000000000000000000000000..22c5c2e30d8e4c976c557d1dca341400a69bcf91 GIT binary patch literal 319 zcmV-F0l@wriwFP!000000F6>xZo?oD9E=k``d3wLPf_)|hp2J`i`bil6dMGjQG5DA z9J`T~7ZO6t&g?ETlt6*h$zS3ChMmTPUXnvx1?Eeo>n~S^pe(?Rb^~Et95d&I zrz7JWhTVZlu3*^NUL|<9^f^+awL;d=O6-(pNUc_i<(PY6*W||xN8w0O?WOMeVrffW z90o+z?p7;B4MM$6v^27E%nlmhWwUHQyj1iSSfp*`jM#T%b0o6CbIcsX`>FP#YpShW zJFyQvjS@ArA=URR8fpJ$xbV^VPwhe|^5a!z z`Y?VcUZPxBZOF#&mLI)f@6mwIXu#`KZ=;oTn_$r`=F`YLapETHab(ptyrQz96G!$< R*7asF`~ecTUluz9006q`nPvb0 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/hbm/structures/meteor/loot3x3/meteor-3-dirt.nbt b/src/main/resources/assets/hbm/structures/meteor/loot3x3/meteor-3-dirt.nbt new file mode 100644 index 0000000000000000000000000000000000000000..3afc135c2af5e560d2b7b18dd7d430fc2d39fce8 GIT binary patch literal 313 zcmV-90ml9xiwFP!000000F6>xPQx$|94Be>;0p;MPJ#I55U4kZ+-BPv>^QQwRB(Fi zrU_NlmnF+u@67Ic#uZQ^^XivU0K?AWS)!np6)WOzns~g* zyFQHnDXmZ~obAZP|5hB$5O2|ekLbWf!EuZEG%`<|xXF4PSuLA7xWwUk`8PS=dnND( LDD_MzI|Bd!k@T9s literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/hbm/structures/meteor/loot3x3/meteor-3-lead.nbt b/src/main/resources/assets/hbm/structures/meteor/loot3x3/meteor-3-lead.nbt new file mode 100644 index 0000000000000000000000000000000000000000..8ea4a132ba5d38ffc733876a9619a220717c1bd5 GIT binary patch literal 361 zcmV-v0hazBiwFP!000000F_kBZo?oDT(A>AdaJ5l`VUpl{fH`mU=g!PNwKlarfK{2 zHF0o!a0*4TES6cujAtkT3P`Q`!2|&Ole%{SIku!op#?VzSZ}qdKWsTno(f1hV|~Lk z5?EOhgqMyb42!_<0ER_yu?Q{}!NnuEcmx*@aIr-VOGw%+<&bv9Xvie)#8DH2v^QF_ z9M&ZIJ<_z2Kw(j1P0F<6W@&>Y#=~aKaktYbVc4$~4NhG-tj_-y9^SXjD=Cf7WWH2g zovS%;CE?MP&yM)6PNJ37LG7(L4TPN*H8#W2NLWbKUq9f+Dd%dj8<>zJhIfjv*$9m^m9lP}y89|A zq1^PQ!`|Iz`6U$W#US_zrFs;Ig| zA<#mqmS7JBPidy{!05w}3oyFn#;Ut=4Pl_y&(A6ZoL+mLe(#48Cq5VUhM%~Z&%s9<^pdj7RoX%q~L0cX#fsS z;mVY1_deo1%hULUZxq{CLkqzY%&Jl|G)#Ht<#_4f`0?qhA9nIK#)5_}f zfR<8!fBkr;ifaeQ5A*plew;05^JlAiVpXS@$XH0J8@cSLwqOFa{p1(T)uft65G_hsU};hx9IPU@#+4_NgTdbp|1qbQd6b6%)}3Wd YPFc096#O?VRTCKkziuuYqQV0J08KQnu>b%7 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/hbm/structures/meteor/loot3x3/meteor-3-ooze.nbt b/src/main/resources/assets/hbm/structures/meteor/loot3x3/meteor-3-ooze.nbt new file mode 100644 index 0000000000000000000000000000000000000000..27df02e1a31547a1b8d391d7ba816b2211c2f38c GIT binary patch literal 302 zcmV+}0nz>+iwFP!000000F9DeZi6rogvUU_PhYF5r>OeeLsYo|GO#3W3`X{*X?yx& zNJvyc8cUYt-C582vojz?&51S{^hDMAm3660BL;E%B5Ikvh^;vNG*>Skw^9 zp+UsWp{_Mm=+A3qLsM0P)xZFcyP|nxrRjyumn!oinjlaWo_u&9_njYQTjd{W>*TRF z?6fSY=~JU&S}A*JVBwb6w8Vnu7OmipmkDOPmNb989u!lvk(zi4#of5||0KweZLI0Y z`hS$1Ad6Q|_T7_xoP$Es^v!=ST-@HL{jE zdDbkDI;*wFv0>>B#50nh@T93>WqXV^sUeo}Dv+6T*J)}I>h;pltje(-J+VF3=8cu6 zT~LvA)u6PNF2_o>*hXON^{cwbzO6pg!OKgq9JFl61Zc7>TIGIQ2ooiP^|zq~rX>=r zJxiuL9I@bte>kfJXB9Y4iplJyCZ0=Y!}Po+TJD`4$i>9-YdqpLX7V00d7dNqGb0|U m?gaNx_p;R0PBo{hIjZ=LZJ0FsBxZo)7S94CQ1`dd{!Mb+;fqT&XTNfvPH#F4!ewWqJ0 zkbn>nELoPlGy9lv0pv)W`lA@YxRY?^$f#w-iX6hqv0Q6YeY?V6iX3rg+(?*KjD=&# zbYxt^hzBsy9gMhIt3ceYIYZJJqmkCMk$cSoi8We_3`>@FOFTtl5|tV}y3OB!O? zH;A;^Z#J50_+*Hzqw-Ox(cCDJCxRL>HLo0S8CSJqJh3Wj{}fsaZ))JUyk| za1H+{E>Ntj>BxrvmL1Iy@4CCggx%)Vv|fE*Gle=r7s;U@mgA;Xp=NwnZk4(qMb)u%0-QREPJ+75(p zVpv(?glEPahFyV)E@0Sft^(qAOBp1c)(TRAH9sg~kQl8L%V161?2v*dhTNjUillD) zU`d0-PX$8S9O_!302i<24F*;QtJ4hNaldWeNGg1GEYzm#w32p@B7;Z@c<`>%^uEg@ zZ$KqSbTT_Ny* zxg_v_nF@R(37ZX9NZ~8(deg64TtKlgxUZ6!i;6LVlV2*@ZV7&&` cZD2heTDKgox%3N-?S*9U3-8GQNmv5_0F8N?-v9sr literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/hbm/structures/meteor/loot3x3/meteor-3-tesla.nbt b/src/main/resources/assets/hbm/structures/meteor/loot3x3/meteor-3-tesla.nbt new file mode 100644 index 0000000000000000000000000000000000000000..b5e1c69a2b54a01cfbd07e823f58aae6754acb24 GIT binary patch literal 338 zcmV-Y0j>TYiwFP!000000F6>xZi6roT=NK+O8x5V6ji@_h$=Tg1~!RXgOR;yl%Bpe z1WFNkSVGA5%&mqNzBuTX37l&1$bopg7x5+q!t+oSUTp`4k z1mTIXgkd*ef(sb7*eipuDJX@g)mlMP;YREgF^G&-ilwk3VYW!)O$gkg!jhzJ`eIRy zBszhR)cegwVFj*UBWfI3Da4%z@VqPPcajQU9SgO|3qgeDm_i^cc=9)$dB^-9nkxU4 zTPqH(XRAbswY%zj@=BUN4QB?O8ph6Gf(0}F&EaJ|PGk{UCGt{B#UYl2bszFVc{Y;} z%rLDMt3@v-|Mbz09L(wUTz{ kT)D=47@3n0ud?n(R_C#sE%`=c`-~a<0%QfLZE^zu008QqrvLx| literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/hbm/structures/meteor/meteor-core.nbt b/src/main/resources/assets/hbm/structures/meteor/meteor-core.nbt new file mode 100644 index 0000000000000000000000000000000000000000..9b5444901c3ec843a0492f31f15958997ce509f3 GIT binary patch literal 2734 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 d{l6IcS0()nFSm%Zlhb`v;eG literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/hbm/structures/meteor/meteor-fallback.nbt b/src/main/resources/assets/hbm/structures/meteor/meteor-fallback.nbt new file mode 100644 index 0000000000000000000000000000000000000000..fa3e955c7f23a7fddd85f093dd90b3815bef646f GIT binary patch literal 315 zcmV-B0mS|viwFP!000000F6`2Zo?oDT)>VWJ@nG{Gpee`engc&u&}*OX|SWKR8{0Dw#7zE}k%PNYbogD@)CwAyrgSNq9*1!6YtLWn~^ z?nn}z8P^z=fZ+)kk$}l=VA!hW8pPC63E6CnhN8zo9yBq?tkIg4upw!8NUtgz`%QAh$SNT}c?pjn?f6DYu}y1Lw=aRK9-hMbDT43j zD5t*pR68e+{=`|!4oBZwPON%mqXNEi&1>7)3g(vWEWvh`U^`EEDm>w-@C3~~K{NkH z^PM6bw^Ad;rD9&D;REm*>a8_1+VDZjbL#9RMExG3UQZU*X|Iv?5NUrR_u7gtv~Ee5 N!7rTN?liUo000O8m}39{ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/hbm/structures/meteor/meteor-spike.nbt b/src/main/resources/assets/hbm/structures/meteor/meteor-spike.nbt new file mode 100644 index 0000000000000000000000000000000000000000..a28c2c30924904f57b1e67259e76998370732927 GIT binary patch literal 433 zcmV;i0Z#rOiwFP!000000G*W0Zo?o9$DKezl3k}BciDZ~VTWlCG4%~1lDI7^`4FM2 zwx?fcK3cIhK}F(#_}TtrVKvgZJ7eT1G+M=Fr2*fQ)%(bYiJ^{2u&HEy<^03)R zETHpO@e(Ji2!hiefz>W6KeUke(ph1x(nd(hRRq2$U}Y{&f9oeb@~TL`#J1(fE@UHl zj%9b%hl~rM&Ju3C^D?L82D6keyMA_!ry4pi#DSp>dglJ_$b=3ITVRNT9_qjZ4oqk< z)MDtBJllOTGIPB&GHiwk9AX6yu|{UDULo{rZuW(+JRid=v1~mfWB-i@p|M$09TWLJ`BH z&B(GM{F#)vWd~Bq%K!=zUI7itD{8ttjDc~>OGrYSXkrM2y^(Isw$9!;b7#)ue)l`y zIoPkAP+Ld&jWX+<)SVxPZH`Ty$a754Iyw1w`mPqOIh4yOUr9LcDQb&_LjliPAGynD z#}lINhyU%`c#!yW{ftNEWNqW{dgq3ie=TZFHfGf6*J(||t$D$jRD~vX4cqYOiCT{} zA8C%@nOpa_EpC*bSuP}uU%%f-xFQ^@H)%1G2(y^ygRqKe`w*O@ec&KR$-kqCOfld@ zc~_@;K2y!?%Q*vyJ2*k;P1CH0n9i!+WClf|_=-BY=%vjSh8uku!c2$(HZ-yo3 z#i(VkqB;D z7<#c7@d8>UY{e~gAY=~n1`KcS01W-zI|L8jP;>U$gB#Wq zVg`Zw>YBW(%T5fTPX0@CC}57GvWL{bZql3Wpwz>Z3MKJm&LDYpx#o-6B96ud*L46{ z>ZNBabVYDU4^6i4YT0>bw0x+`j{6KwO!?x3@3))%x5o{D zxvqdK;!SdRXTDmz8~Jm0XZ=DwPZB-9@g-*li!5z;b<@DotvOJBI83kU-3GD3qr2ae zkdHY)Ml@v(CI+^h--qT;2YYbGGBEYNGx79{v=u)Peo@Ib9Fvf9x5K%At+tas7oD(y z*JANr7q3KxuU_U{z)*fzq1Pli!rqTpAvP(jeHI_GRP|s8d{q%iJQ*kfG`Cs6P?kT6 z1R^&S91!nVB;qyMJ|B%tS?Izi!k_EZU$f z+Wg~mqiz4x=r28m!Wfh^Ybdz?>|r0h9dZw%@1>$OR3LQ-gws-xdjX8Svfb~w zP=L}FJbL{Dt4zY82@Q8dFPaWXwL5WIJG9PjBzg;?1mH<$Tt}h-5A9CyK1A*He;qMq zME(>*5aIjD0u;m=_{o1nLo7c%Ko&SdEF5KyH<;-IP%evjepE(AniUqN8&7JR_XWMO zwu4Ct2By@p0=K^8`a2dN8!oGO-WR<81q@zgTh;25J6=P|1)|?N3Q-8=VrYcQnOJTi zM(lpO_2}rN;I@C8P%Lj9y>2iiGFQc=V?re}YN2!^>oBcyp*<*Hb)u?eba;76-Q_M+ zo1e|UU1*-F4orP{|M3vj-Ce9P=l@eD9D{R>&8f5Bq=0B4HVA4roC2u0;6_EVZ6Nq-%!lw(H z?mo$&Dt|PMH6KkhN1N8QEtlSJ8d=+5Y(BxP_1T^?&IjYe^mt=>;ooP?Ifj?beVy3x zyRKz$mGLj4Dq^$3ap literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/hbm/structures/meteor/meteor-t.nbt b/src/main/resources/assets/hbm/structures/meteor/meteor-t.nbt new file mode 100644 index 0000000000000000000000000000000000000000..418d2c747ae9145385d6323a661841c7176d7e73 GIT binary patch literal 1905 zcmb`Hdr(qY9LH^2w^C8Zcx(-NTLHP8ezhA77rdZ6POW?~(KUcQ<~OZQ z5d^}z0temn#5YKNk#w-THg85U)lW-1>QY9d%q{q2P~5~l_nL;Pb(6%;{sFl<0YO-%JaBJwqeQmU`Iqli)Nm!$Pvc}%7^aIl<`%%WO0tHrzH7n=Ob{wj?s3JrxOZ&?OiLNsUeXvYGFYrqMU@g+fey*_~d!w zUQcgm;T@~qxGWVnC^_tIL)FvaQ|DRG8;1MoYQpZ$Ozq!goG1wvk(yr*W1h4&E5|sV ze*z|r_096=&6lF5i`tp^9v6BHw`iWOv=w@W1xI5z%Gred_TpTnE&Ln-mmBJ54KKC? z2-x80)E4XDS+ye&&FG{t0GYF?UDxMLUe2weU$TSQ6J}*6cdxb!GF= zmEEjtD<uL?V1ckI1dqa@8ft|6h8jMrbU>A*F#Q~NGRw5a2y z$Z=#lf?yP9^qG{u5Z$YFa-lp5K|lyWqFjusoI%hujCB8*IN?3#=+YarND12 z0o^8Y_p}YrIRP8sy$?yG#=Xpcc4D+!;iSzBv)`N9h)D86iQ#qE+Y7sAv}8fd56r$l zqmHw$psTFl^?Uz2PzgeJfKE?+uCQIq9cvp%=R!9Lg`6rMgcmDLfX%A_mp2_JXs_$w z2iJhpAT6t{w7KIG($O_rz_a{p!AlVva;e6Fknsh**Jo&3RIE_ON{Gk}m270pw(SZ) zly{=E+34@H)+D=(Ueknw{;@Oo_uN>H77^ax7FYu)(mRf zh-E@o#=68H669P@u5vcqH)6t#dC`tud=6~?`b%cLa(K_Z6;ezzjhTRG0*+=~B1U{V zINHrWUz(HD48n93U^9V>RY9CTcsfb<%Xp_NXx=xN#_MDu&IZ#s7cHrR0EJb8Gq&*_ z;KAT*KpNR4A8Qu0G4U5nPeg~N?KT26fzQs4+}Fu9)$F4@nvuQOF?}POc71=3_PNGz zkf))|$;MoY8O}>bjFQ9Jq0xQuqq^Vq#_2tB!+eJ_)d0g}4BqBD@@ZsYD+#4Mbnh^0 fPSHy47i;gAi{7cZO#p|PN3%$@{_Ux2u!Y6HG0x*9 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/hbm/structures/meteor/room10/headloot/loot-chest.nbt b/src/main/resources/assets/hbm/structures/meteor/room10/headloot/loot-chest.nbt new file mode 100644 index 0000000000000000000000000000000000000000..b24269fcac0bd657787981df77f9076ec777da5a GIT binary patch literal 829 zcmb2|=3sz;-WhlEE;|Uc9*?_ScxZmhsq?`KD(|X}yXsA72vLo3_uG^y_Qqn@&W7LU54=y%bMp07g)5P zZnnJ2#U{ZxXsF}d;%r9@$yr;1yWBzQp z9`Dn3?-`nbY)3x%Tj}kK+sd9X0=c$t1=*hh>DL^e9PPGL$?=?G|2aYO3Gb7`Cl0rt z*|BAYW7PlO1x`uZuQa(VEPKZ9`C03CW}K~xV%irVo#rX$!@jsWUN^?3LIyLvp(=6@mxj`$g zl`IU^<7ZzO-@Q9$d)$-MmFz)wy8b2y=4{`4S8TaO)M?+c*{>TGtvd5rVW~^{)!r-L z`XskSJu6xox-&aF#k_vs)7UVN-KX+Co;)mO9J*Dy=H}f8=B2^u^pfiolS8~>i8_A1i z7G@eYZ@Hk(ZM@E3EG?!q?O5pZ8=%1Wbq*9d2H!p?8f(ZuaRzEV(SAlDUqN0?&MxKH z(xW_=oPhLGXQ-YdNP0eE=;^buImXk~{O@x5u~7N6n6HvwD;E26S2jy7x%#$xzSt{k zV-N1Hb0x3nU-`aexwtb>>AsywY)4;SE9iK6ta8Z~opqaHvVJeWxUcqhP5N}7jH1w~ z)sd$6UoJg9Ir+mjOTD_hzHa?(ryp&yn?`;De+Rl zH4l!{?q{`;Gh@<~qE(yYnTdVIwXzXnEwaJ<(Www(yw>i@-Ic9HsT*so(Ss1@8>?N_ z?tcy&_u=naq+L5;(D;|QOQs?ptg`xbM2JZlMn=Su5pmLpI4Kh+LERC|ZLW<-o1HC% zGzanCno6JN^7nS%tKBdY;kuF}z$6isOjkk9Fe$^xh+NZ^N@tjqVbX|P)76}d!{y2% za%GG;U?_8B(47CV0ukhm6-y#eUP<`JJj>L*sWV_G_rOr@Nz~2MGxc-2)?g@Sz);S} z*Z*8SQ-|l`aP@Ew%Ls?TP!5Bk9QM2RVu$^Hz1U&DQxgvRJ(PJC&SAf2MKF}ZzW11V zIETHX5e(&wpGT%1&S9S~g5m1n90o%<42E(zyW3$zSne<)P!4Ai4uhc_26O8$s?EB# ztweFqNA*(KL}YziRY@sUR`t)?`a5pL23_gBHEnY#Dyy|s=ZO?W{c=23`XF4qM%CJn zDn))iA&R%PX|$V(qkUASzf97{t4TVk=CJ)?o(FYunYv2tb?t6lGOZ7$_nD{a;PI}f zG7B(V`+=c!2Se!&hSEKYXg@GqJzV>N;p*Yq4-D0QV5s)X?`}UtSl)h!K(${U(SBg4 z_5(xxgn*%bLh=ZQ!BEbCp_~CjIg>{?42G+Ra~KR)59cr#%3&~+!>hX;Mug=KBLd~{ zD#Bqfl*3>shrv(|uOb`ok1svT*E4VOWjyG98xOi4zVGVC zu?If8JG$++yWY6tE;sDcblA|TQ=@x!;5$Fib(<@h<8RO1Gx%4JKlt!h2XZ%Y#V_3t Rm-BZb{sFUc-#{W30053jfs+6L literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/hbm/structures/meteor/room10/headloot/loot-tesla.nbt b/src/main/resources/assets/hbm/structures/meteor/room10/headloot/loot-tesla.nbt new file mode 100644 index 0000000000000000000000000000000000000000..5a4e4f802b38247e125f4a1da3defb5c2e446f92 GIT binary patch literal 886 zcmb2|=3sz;-kGs^vmHcQ^$l3wtg6kr6&o`3*EH9Vn~kk+3%$6HHF+*B@xGh#^P{Ao z_`8`NpC5cM{ND54GMWEgSI&`=r}DEqP8gW|^=RKX@y@*1mtMC!d&J*;3oZU}HTSo8 zz4@e=S$yWa^?~+}TrQmxJs0;rB54xCF#$Ec6{74{x|p+68MjVqh~iu+>KM$h_$t%k ztX}1YnXfy;W~ek6wsbOox$~_yS8mz!ZSTE(gcdx%CY}A+z;^q+h$No|IpGKLK;-;K zINo;IOUA`ubofipKK=xyr?qU0zl!u+3pR-IPhQiTvG45BTQ)w%r&%SIS#n;enLT%F z<&3mxvIamQK8a_cK-R4Azt3YB7Qg&BUz?HV^5IR7zZX8O{Z^gLu=wkh_l_-zH$PhP z%xKR{yZLdiI?w68`1%7N^Z3{4E*w4iH?>UrFb-=(@$2#HO zw-W7>mG6~KzIuLngy-!|BUbs#xC&{uuLhlF#js&?%?qYTr_S{by?3wR2(L9-Mk+v-akdYof{a&t4lm zU$pJtx|mBJZz#Nf{V9h(x3Gxc^`_tHzb4V|ybJB#)lKt{{dg&SSIE(W*ZwYDdFffi zwtb&&eR?+6h@0oO;em{o%!`-u_e`@hi2Bv@L6({4@|iLoV5r0%X^+v}GHHoR#_oE2Giz~HQo^~w)O9OlFDu(`T> z^?Xy?1QRftAqNcbDF1^QwyfY-y4;v}lku?0W{B2zE$Qq)cL22lLt9b;sPxQgU{IQ@ zPYbut-g+Qo>wyhXZ!+a1)`}-=iEFr6HBt9Rr6>PqV~J($KP{s_yqYBUEY!e<|8thu zgHVGr_GeZnnEZdjeJ>(;OH@LH?zb;;Jgbk+yZ4;iHa0n8?d^GdXLdgf_!bdz?Pq=J z^p{URNPF&@`ZoD?Opf)Rwn_2+-WRVw?D$e^p>+5EjqCh}IbV3!A2oZMcYoSn$IiRo zzA3nVJpVsbv#Rl}_TG=p`wMM4*L}Ee^Z(-K&5L9HA4}bzd)rriyT?C9hJL&9LMa9Y E0PfzuJ^%m! literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/hbm/structures/meteor/room10/headloot/loot-trap.nbt b/src/main/resources/assets/hbm/structures/meteor/room10/headloot/loot-trap.nbt new file mode 100644 index 0000000000000000000000000000000000000000..c8486d48e0b6055537b585ae022f672f9aa08dd7 GIT binary patch literal 1038 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 Jza5`5=l=kvvB&@b literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/hbm/structures/meteor/room10/room-base-end.nbt b/src/main/resources/assets/hbm/structures/meteor/room10/room-base-end.nbt new file mode 100644 index 0000000000000000000000000000000000000000..c77647792da82454a7513fbbfec80450eff55b3c GIT binary patch literal 1675 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 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/hbm/structures/meteor/room10/room-basic.nbt b/src/main/resources/assets/hbm/structures/meteor/room10/room-basic.nbt new file mode 100644 index 0000000000000000000000000000000000000000..0eb650e0620c96fd90fe0dbf18c3ec6bca809243 GIT binary patch literal 1092 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 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/hbm/structures/meteor/room10/room-ladder.nbt b/src/main/resources/assets/hbm/structures/meteor/room10/room-ladder.nbt new file mode 100644 index 0000000000000000000000000000000000000000..50bfc2523b960ec80bcb0b12790a9ac736cf2a21 GIT binary patch literal 2173 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 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/hbm/structures/meteor/room10/room-split.nbt b/src/main/resources/assets/hbm/structures/meteor/room10/room-split.nbt new file mode 100644 index 0000000000000000000000000000000000000000..9ce05bb0fe93aaa72faa5849f91fcf67f0914aa7 GIT binary patch literal 2786 zcma)83s6&68U|U!2PST{B(y6`7n?O*2p18MM@V;^S(|#15mX4uBgBA-ik3%^AjZck zvrE>@8Vwh-fliHJL&I)YSy!iD{4Rv%;8ftqJ;izU#3}62N3Y`Iv-yjODJ;K-D%KYJ;cBbz{|A~f&NCnrc z9^YGgm!0BM_Y8MP?L{bmHGXSz5j{c;$&!$RzHqquv5uBS?lf2&g>y~>D;74mBYhMo z50gY3o}vXXt(=+x!U-j5wEcQ0J-)iW#10rM7>hEUT_8%*pOzCb4XAFYoT5k#>Y4%GVWW!GA_v9p2Kp(>k5u#8`?ho=IME-uC8-Hgy0$IW#GlAn|7- zbt!p1JWnyb%UzWO9;tR!F3@f?c?a5}?vy@^c8NK!h;||E({wPrRkN3^;kRy=I*LHZbwtn*rS6~@RJdymhmKY0l(6^1S)A;xByYVf@&4GxT9uS~%8 zQGp{EMS>A?18{`{H68aRiLoL_=+s@Z#s9u&9aj?O6KtTu8=SWePC+w@Ygs zgaa6OSlcdjyZmD=1|LQHql^s$Ow0*)c(bmjI00--z*|Z*#fQn00_GM_l%ZdNqM*(; zvJ1-5)gY=G*xGo=Kgvs-0OwC&;9K3=iS%=Z@C@(q5njuviPJjR%nvb~3m!MO%5z?` zn{r-scMD?7Hgn1=vE0nloce2R?4yO(Td|u6l0+o^FZ3SS#i~fgll4N8KO8d*u~-V} zolRiURkH6pUiSQSsc3$}^reJ-JIJcr!oL&Bm&EML!3Woh<{%E+%S!J_my-(Tzn@Xe`o0t@RJ^IAeMN{ItUjoQkUAcqxl0B{M&lrfFm4( zgIKX`(hPfavLcEe48W14Xj2_K~YC&1Yf$H+#5=W(Cn(P}$o%@LP2gd^X$ zSy?k;bp(AAh-D0)((vLI8ts(qI#&$CZ^YT%6?J&iJgqxQJXYT~>7<0~97MW}z{>S8 zawKbnwgV8$-BCCI#O@H%R|?6Z=n<9I_^~A*^}znqu~2ObmxPt;P(6La;?8Q;vFRYR z!KStX=FV&cqXo2m0G4!Ga=Bc)($Y|aFb}ZsnLU&X)dq{Mp4tt@>vnHplQl)zG_FDiU$&;?GDBWg)^&{A@2k8Tn zgx#y$i2>wLwj&(XZt!uC{PYG#wi>hoZN~8G5VN_4#KzCM^Im17URS$S=1Z@V& z1lk4xQml?sZAErvw|bU%^g9R*7pc~^XtIsw0SB2^7;C`@HNjxw!6^E52SO4*hl*86 zyZQQiy0ko>SpOo>_3C8M-bIgrc8Z%(t2eMFC*@UH(Qg*v!2IcNr)r-jMvx(y8@{yj z{Kpujp=$om^s+*(u?AmS5*O@+0(TS2+~n~t#TB{-YWm{8)NFa^-V22wmeO-CP4VLgc#Bj4 ucV6gbjsF8LgkpG2nv~-LOq}}q5v#@Z>xEA4@;3qF%MQd?xLm`rv->xdOT2Xe literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/hbm/structures/meteor/room10/room-stairs.nbt b/src/main/resources/assets/hbm/structures/meteor/room10/room-stairs.nbt new file mode 100644 index 0000000000000000000000000000000000000000..635f3d95efe29b441c3537b34b14ad8abe05a840 GIT binary patch literal 1797 zcmai!2~bl<7{>uciw8P9l_-*Qti%xn6R>#Dz-ZG_?W3qjzynBp6Cw};%H^{tirAEz zF~vblh(O6$w15YP2Sm{r4N3?R0|sIdFT!xVU=1%2(WDz`r^j^cn{RgZ+x_0|Z~yy! zOFH(E!^C&_bQsSgboQ5$h1T^OGS(NaUiahVt(Mt`lRw`0@Lq|?&H2Rf{DrIfzK_2X zde8Tp8+wt0`@9}lr;EW4T;e}sFLh^M8Mf}0Y~EnAHjadNv(Zfq>_u5n8rE3wjDJj` zHk-B9nu7b;?mwe?WBs}8u;y2Mi}g})U6W5M6=Id=jl-gFwVfCF?C1&%3 z-K4l_rL;Oeu3EdC6x`F3te3scy4i$(zCE6#lc+0N_+;;%kTfBN@eX9~yK2m+^v8_N z;e4Lfl{TuuPvI}R@wjgOyEiJ6f4BtSJ^t!#o66rkv)foV#HBwTG>MK=OczH=IrD0S zraQ5ko*^8KFJx93P^saIe;QkA_`5|$Y6!@aYVYby`1p>Oo|ODdxOqG2;$;Qw2B*a; z`tmL(UL+yh^J`|ccAsrMLM7KS(u|b0dPQfwPQ2%WVNHONpv40NS_9g$j?G z_+W?tzmBdFB&?jpr(%X@G=%7id@A89qSgQ9)N+Zz`^rWF;C7AnInfnDoxtAq9+D*H zE9e|YsMuLhe6-hD&|h=?5PH6HJ}cfOzJw_)A(@w#b^ANV7cr$MKhNMvF3KcmV>!+B zH?{Q1pP&e)56>u$SyI3DoVL(ucg3et?~5Rm2$czy@>P6 z+4Z}U-SiT-Z^!zJnTx`odZJFrT3**oMDHtO!7}zrLBiD`qMf$J10ZB500IxNfe0)2 zudqzpm7(tdm5c?bjMm*?W-GIcHg*2gNQ^^CRtVfXE*T;T-FR)HkE?DOzrM$bw4M@Pa4J2rmOa3q7nQ6l~0U`3Xx*)_@ zPA>sM$9`I$CZEvZ{q8NghDL0(<=TKpR!5a}LDz$I9r^8Xp-1wRGsp`9M7vs;QtE_L z%Ua=$^%;@sY2e@tz;)Lfa77=bV)H5i*Uq_stICy8_<;Ap2)`eiyajiK;AeXS@H z&GG^=z-OkDA38(*In)?)RIun=6iXU=G;jZ0@<8N-<4K&l_>cS}+b@4Iz>qM3JP^R( z<^XxZ6d{gY9||GWau*Pc!FLS4`r1jUlo1${=|GK2YQZWYJ zpz%paQrFO}&TZ!Ox0TOR9g(Dt)IB`kL6opvWgY)55`C;eKrQtYuO6i;jmXW4$x35H zsg8h*R>zT?B6|8Ng6d`s>m=rsH*K%`dxeUzxI)#a42zHrX3uXK7#m4{on*U*YpnT$ zLQ*pE2_C*B8?~P4HeN{1=*G_OJayn5Gh?#tMXoJnTW<&SIKT2>Pz-MBuP8e=h^ZT8 ngO7wdjmHDb{E5!yR~g8*WXc}j{A^xHfz8o!JN8j%sDs1rgqEgM literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/hbm/structures/meteor/room10/room-triple.nbt b/src/main/resources/assets/hbm/structures/meteor/room10/room-triple.nbt new file mode 100644 index 0000000000000000000000000000000000000000..b1aa16ff443b8ea9284a8b2d2fa5ea1528fcd6ec GIT binary patch literal 2339 zcmaJ>2~d;Q7PeD-ue_!zq{5G~NLUqFeoS4SK&pWUmesnXr4ei_o5&JTL&7$-5(7yU zDk=$^PzYjJlr;i@DoL;)ga<{6A`~J)2&(~N5|(!(Rj6;K|9tb!J>T4O{(H{7=NQpH zTDS5&&wPGmtIMXuXGaW|!?+(Be)z%tR_v|%124wg|ACyM1nk#{{wSN7^{b&(NVN#3 zJ!F0Zl{QVTt@S#eb-KCNbGy_YGqJQKFU@{QDVgaxyD(K-OjXGy>$iFZ#Fn%UO)Nz& zE>&(XP{o`W8jS4B5cU*%G>&?YOpv1~%~2jXCv`LfH9c<93f=i#W<#UeGtQ`NH$E~c z8l@$2cnkd@=5_Z!9&w}j06q@q9YtFn@0`gbUmQh-T5CVHe^9(FTRH9^&$PKG2T&ra zpXBj+g6;}B`lV6Iz9`f^x!X9;X{w|ucxsLu0awavEx>LvVM@mDm-cu1(&zo;H*~Nu zQyg9mG=_;ATjN$T22He}k$#R?*zLI2f6IT`_ZaKy*BS z*l#%S$w+y#k9$sIFx9nPql@VhSWRjZabzSpfaq>ph z#9XBOb)!=Wx1ra-R_izI(2SfyUZ`E#h0`iRpeEbBc=$>ZMDpNsPoabcNO&^+Tw=)q z#Bibei_7C!#PFZ=v(*_Rf+Z&P(Z;VCP|Kh6I6nx5sS;EIp*Q6nbsTL?T9`c+?<*o6 zHxqt+9U5cOcSu;wcITgnDsAyOUGcn)aN-2xS>1TwsF|?4BHiYJGs+MrBjDTU#LsMn z-SrSocE`BInA}p}Y5}zvE82(8m_EtV|7nVr3kW~!W|!9F_QFnkAH#WrN$SedG(sD@ zub5XP@Y(QdBmW(lJ0kZLFLDGvITlxu*tl$m@H-Dq`&$bYJxBeg^d9XQ{`v8EDwHSCnTzRi>neB-N6G43AszpvtRtN7nNIjhhT zzcLYa-+^!(0=^`f$a7(Eg5c6@0hf|JR@uoZ#jY4SVhTN-e39t4O-TM88d*;`t{Iqh za<`^r$AkKHo*{-vEUVMOoQf_Pxu^4&BaQ(*q^_E(I=a9``$Fl_shsg3Lzx>Wj$KWgyxHL5i#G! zeH&1LeRy#6sMqDwYU^)PU%Q_R$|i{fMOYj7>YCro>GvlyB{`H05iokW1H=y8%4%|@ z0v|LT1QNF8abC@SVP|6q12CgACkbz0f{kKBBpW_A3bg0P@Fbo_^(Sarmx>(V8i)aH z9Vf*h6zf+xRGp_hqZS}bTI1Pr>h7> zk$N7!qqrL=us^4Ofl%CnTE3n5p`_}zNS>&Q_2-JN;gX3LYCWhFHD2A=#qnb>@svA;Uwq0Ua~D=da_NIm(Ft);^1o+rL( zM&(}c8p?V4?{7j6$3M~$_^i@1i&ms~r#E8Gqr86Q9s^+;014+|oFAjL0>Yglysb|< zFifzHc*I1OvI2U#e=Z2FB#nu1iK;i2pW5OPf~S6qaivnq)EkbeC5~Fcxw0oY)>P$2 zbxD`&Ete-T)co&2qVEb;>KOOsIeyaTRI7AdFH z8MWWU_&UWZC(yoUS|oEb({}pJIoXYr+T6By{jz{YMo;-j#J7q4^TUm;A%9>_Oh?#q fVlQNb)=Pt;acRR-O*8pc1DH|a!Rfsx*RA^>P>`jU literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/hbm/structures/test-jigsaw-core.nbt b/src/main/resources/assets/hbm/structures/test-jigsaw-core.nbt new file mode 100644 index 0000000000000000000000000000000000000000..a73962172e3d7a5fd672778f86f0e20178fb12c9 GIT binary patch literal 479 zcmV<50U-V#iwFP!000001HG2vPNXmp#|K(m;Bw!Li7#O;-rW};;^G@@x-e?BP*SSq ze0u5bwm}1(W)mghL&i?yBHyr*!i)*3;rw z1#Hlx5As*Wpct*Nc#K$L@&twvOtyz;h7(MlkS9;b!xHkaggiWvy&UK4`6A)8d_YR&L#k z4rl9Jws2vk!u_}UfBP!>cKayrNAb#_9E{XvdVG*uwbEc?rS9EpOE|N_+@lTIGT=rl zHHof9RDpDngAxsP(>vU{gkpaZz|T(h*cfqVZ-g`qc!yT3Nc{ZC=3g(7oi1^vWkv0Z z#Q83=1%`64XJQTxCuIT?b8tA}5}25S!>L0sly=X=^6&&*o{8!5OiUMtrAhPUwk^KV zwqD}AReXh^wuKs|o}uzk!_+fW9%`6+hO)`hF#RDdcDF*I4Uaa%Vd;L4iW=%$qX#tZ z_o+PYN_IW%3jgP9a`~|9Zk#!;8r?SrEp8jFw80jZL;r-(^AI|7)JoL#Nm0K~iuy}L VG1$DI84u3Q;2ol9n;m)z004<|?uq~a literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/hbm/structures/test-jigsaw-hall.nbt b/src/main/resources/assets/hbm/structures/test-jigsaw-hall.nbt new file mode 100644 index 0000000000000000000000000000000000000000..1676ffa914b8a642370a64b1be6a31e6568c6c8b GIT binary patch literal 555 zcmb2|=3oE==A+XO_RThsXsO@e*|2K+s-XBq)9=Q8Q(P4quTa!c{`y)%%AIw$mg}qi zR$e01@1Lu}r*_|7vaOIsH_*ArX#ZA)MHMEW1CK6V7{z~(WwH9Ar`?Bd?t1t8%DHZR z-p-4@Hb>?=1(>pmetCUFE;!AA$>1nc?#yXN3iwPiX=`Oua95 z604_Y|1PZxJpA;_SsVXXt^u}HkN?#C(z+khb3N7|Z^raZ%bWxLMYe~oRd_jf>t|Q< z$=kFg)!kQH-95iw@VaTJchQ$^=FRW+RB`d2s&L$N-BDGqP&%}*d7{FqPwQ8FlU$-~ zRN~UscV7?Tq=3^8%00aI{*H zd`3a`ieXwn+lu7Z@nLL}KW%<@m`Clnzn1*WhhV)yb<=(`d`e`ibdybHd%2*`u(>1v zs8e!LU+59XWF!kLQ+`0~n|}hN%4RW4DaeuqJb}miP}Q%5J1FJfVdeC%{PLDRg|-Jy zHJ2!fzF?LFv@7=r&n3s(9g-oF_vU^%#&XwQYxUu(R~B*8KiYb3xnfsko+W>O@vG}U zx_3wV*Y%nH{P6XT{gI-YH+L>n%6?f{e66x};opnDOTXN;+Ld{wccp)V*M*PEzg^zy Q%lenGKluQMI3EK80N)N0zW@LL literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/hbm/structures/test-jigsaw.nbt b/src/main/resources/assets/hbm/structures/test-jigsaw.nbt new file mode 100644 index 0000000000000000000000000000000000000000..aa2bdf7ea55fba4a64036d5aa3b421b965426ddf GIT binary patch literal 470 zcmV;{0V)0;iwFP!000001HG0}PTVjMh9|L?O;YiOkhnxEXnElfh#RcD$w1vYapahy za{9)*JJt%a9t)&K%ELt8Kbn8+8KnWJK~DM=1ptJ1MQ;ri4qkhW6NIORv#qi1@2Q!C zZ#9U~P9&nI5U`rO@_0}zF=YlL7^c`k$4moa*!l|OXsv;DhmY#ngm_Rr9>t~Z;L>Y@ zJ8yqCFKXyEzx30jUIbL5)7H(O_v!0SJ8ZqS!yL*A&b)F@=wr5-n9xKbC`O}N?C0De zu3)w67@YTdz}Bfpf2Xt)Aba#`??XCkOmV{EajQ--l4(`>u2stnmq%pe5gB=8#x;={ z*F-Ycq=O%mIm(g zqq|`7?N%xm818t9NgZ$8lo?Fwc;onIFsb8>BgrtFcVbd`WQH$dQoe{u`H~A~dWzv{ z=GHJVTpn%>6T{`<)-W+#50}>P7wxfsPzHVcv>x|i_;*+}&^$Ohq6_~P)nTNH>v`zp zeHi_#pWFT}4E)#D4y{9vo7NiZu!Cjkk0`x}(xWYLLUr>Y)%OpnZW)z;^&fQ8ej63= M4-Mp`>X!)s0O^bCRsaA1 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/hbm/structures/test-rot.nbt b/src/main/resources/assets/hbm/structures/test-rot.nbt new file mode 100644 index 0000000000000000000000000000000000000000..7150435df86a414d6ad9522b579b1c2b0aa4a770 GIT binary patch literal 4860 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 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/hbm/structures/vertibird.nbt b/src/main/resources/assets/hbm/structures/vertibird.nbt new file mode 100644 index 0000000000000000000000000000000000000000..da4bc38d9adb8e37a389fc3fab579abf57b7f97b GIT binary patch literal 1918 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 P00000NkvXXu0mjfynF-i literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/hbm/textures/blocks/wand_jigsaw_top.png b/src/main/resources/assets/hbm/textures/blocks/wand_jigsaw_top.png new file mode 100644 index 0000000000000000000000000000000000000000..2c47fc86b06b2b34b9a5f10b06aa8a7d898c52d7 GIT binary patch literal 625 zcmV-%0*?KOP)EX>4Tx04R}tkv&MmKpe$iQ;Q-M2Mc~6lA$`;MMWG-6^me@v=v%)FuC*#nlvOS zE{=k0!NHHks)LKOt`4q(Aou~|E;uQ=NQwVT3N2zhIPS;0dyl(!fY7Kg)$ED_s%9Cf zcudUZR>kgD2nb*h!x)p8sVCBl8F-Gbd-(Wz7vWjn=l&dhO5S9EPb7{q-LQx^h-Wt~ zo%23%h?OLT_?&pspbHW|a$R=$jdRgqfoFz{OlqDuL@X9NSngm}GF0Lj;;^D>lrLmm zRyc2QRx35ux+i~OFt4qoxlVHwaV#N$Bt*!lp^OSFL}=AWF_EJEn1_GF@h8b8ldB9y zjs;YqLUR1zfAG6ovoJm7CIw?a;KjB-#)0l#pjo%=?_=9;o&f%5;7V)zs|{f8lk|F9 z3m*af+rY(jTa)*I%N=0oNtX=Ck^D4;LIHR`qi@Oq1Ghl$n%i4zAEysMhPqn50S*p< zi6UjMd%U}+v$ucGwEFu2lz?)yYI>P~00006VoOIv0RI4(006)zmAe1{010qNS#tmY z3ljhU3ljkVnw%H_000McNliru=>i289x*I;$*2GT02y>eSad^gZEa<4bO1wgWnpw> zWFU8GbZ8()Nlj2!fese{002ozL_t(I%VYe%_5XhcWZ=bsA8bS8|KIwbe6aQZeEX>4Tx04R}tkv&MmKp2MKrb+0Yt2!cN#?t+t|i4rtTK|Hr< z>74h8L#!+*#OK7523?T&k?XR{Z=6dG3p_JqWYclt5V2V5V!4Z1*-(jRiNlJjQNECK zS>e3JS*_Mt`=0!T!GgAu;X17`B(Q`eQV=1djtZ)<5TRWo#YCFUV;=rd$DbmXOs)zT zITlcZ3d!+<|H1Fxn#GxEHz^ncdS7h&V;l(V0jdyW16NwdUuy#MpQJZB zTKEVU+y*YLJDR))TfPA-VSk)M>m_e~4|+VT6d7Slq`ag*LuR_44~KY1flC h63YH+1mE77dS8z)YVaZnr8ocp002ovPDHLkV1k#h0xtjn literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/hbm/textures/blocks/wand_loot_top.png b/src/main/resources/assets/hbm/textures/blocks/wand_loot_top.png new file mode 100644 index 0000000000000000000000000000000000000000..5378ae6919eddfe34bdddfc0e3cd2d5fba8f072c GIT binary patch literal 4264 zcmeHKYj6|S6_y}_9bq2DwZ|nqmW5E;VYN@m(pG}llEGq-BV-lqyztfTmAtj27235W zJDAWACj?Ion1o3}CS+{zDpd*8yr}pu`C-?uO^i5gr zepPJVncl*_b6($mDDA>C{i}L*g^sday$kpMyWq~i<$Jd2Kl!w5k&tM})9Lg(C5OY~ zayUlIK}Eb$x6fX5=D|gsTS|^JXQVXjvWTx2R}alT>+Qr#v%~e97H=@#ern|$*Y1Xv z-iM=u!m)q$_Pzbq&bP4C?K|3M7w%&J?!UU$~gGrNbX<}KZF6}NTWyl|*x%LfP32A_LxW9xmHL$ijy zY(1j%{CMuMro;0Or9YIV=J%~T+GRYs)yS_JJim9J>%;VCcXj$xx)z^b|IB)ud(kG} zFRsUx-hcS(&&ae(Z7*uH6{f{Y6 zR1RGHN`KC?xht>Z)H3Sv!(UeIiGQu$xN-HRO;4_AIS~6@|BBvasOzdF)Lo_S4ZI+S zjX;$B(3l8EQQPTswl#?;5GtXH`C(9s*zv0;PU4s(+VRaMH|35xV1-mv8-pda#Xh07 zQm~5nn$-qdf=2*hr~)hz4n-6`VaJoWJi6D!B#tFb)Ji*E>h@p`IR-J#$Qdc3Fds&hmfu8Jmg{nq*l8ndW#yD$~V?mO(TCF6-kPJg03qq-hs31W^l;s-4 zFoqKx zNJ8K0q4>~{l3u9DRWSh;R>O$8d?JJ>jQK~aVxeR?qCmnB3?owoMWrW&T<3Co#ym6% zf>Jn|^g?7$vQ(wOI9Zc&(=^F)CMJU1$8aZEkJg?vMpkY&@05iqEj^dhj%)FGQ5GbT zPu@~~zrb1rir^T(pWsYpfdCePB>=Ec3}uF97yuKXToFYD5dmsY2;3+k9Ko6g7>mV1 zSVRut*?i%q$^LG)-_;lYl@? zEWy&iY_*#F3`Gk`C{f_o%CRs&$0>zD5R%bIFsaZ8=kq--JI)xXafv4c)BtioGayAo zIj)SWd{P*es6gYB&SNcRhGnc4mNg?T#*H??n1XsyL!~Jr%Oy41!SJXYL@m%d6#*pW zs2bi8gFuyIK3NXgaV;rK^BhyV(Ljkn1x}zs1WGX`o?>{4^HEmb#PO!Q2WXn7CfLiO z6sY-s*4p@Bw&6oBk`xrbCMg=8sS>z#_-XhtBqfIl!;)jc17WxX1yn;ZnJ2;;RtXg# z5`<`fj5O@1T>6$~FbQmcvoL^wtUo|-g6Jmz7oZ3+V4_&7#m@u;%Vcy#4ybVugZV+k zBjO4*Xp$=|d*rBcCfmm=pmq+3GJ;}=amp+>IZ`aCZH&=sZRG#(VM`iJSTV?NScX;? z+JxlTDjeZUTRPw4XXG5d#|Q{|I>?mxou+G=t|>7vCFAMtnx<UHj^FFTaw7gej`aU6^ut#>`AJe|lpBK%$__ zneWT)Zu92P?Z8qW5N}?%)3E2yj(F*THyq6=Pkiimo!U)b?5s~;vfxi~I#7J(#f*m1 z%v9I28T#G>Hy-);qYs3Y Date: Mon, 10 Feb 2025 09:59:06 +1100 Subject: [PATCH 07/12] Add access transformer for mojang being a stupid butt --- src/main/resources/META-INF/HBM_at.cfg | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/resources/META-INF/HBM_at.cfg b/src/main/resources/META-INF/HBM_at.cfg index 65926b7ac..9a2ecc5a5 100644 --- a/src/main/resources/META-INF/HBM_at.cfg +++ b/src/main/resources/META-INF/HBM_at.cfg @@ -35,6 +35,9 @@ public net.minecraft.world.gen.ChunkProviderFlat field_82702_h # ha # ChunkProviderServer public net.minecraft.world.gen.ChunkProviderServer field_73248_b # chunksToUnload +# NBTTagList +public net.minecraft.nbt.NBTTagList * # Mojang makes a format use LISTS of INTs, what the fuck + # ItemRenderer public net.minecraft.client.renderer.ItemRenderer field_78453_b # itemToRender From 7f0c483cb18f6a8bf12a7bb23e62f39ba099dc83 Mon Sep 17 00:00:00 2001 From: George Paton Date: Mon, 10 Feb 2025 11:36:31 +1100 Subject: [PATCH 08/12] improved meteor dungeon stair piece, added loot fallback, and prevent structures generating too far horizontally from the start point --- .../java/com/hbm/main/StructureManager.java | 1 + .../java/com/hbm/world/gen/NBTStructure.java | 18 +++++++++-- .../com/hbm/world/gen/NTMWorldGenerator.java | 30 ++++++++++-------- .../meteor/room10/headloot/loot-fallback.nbt | Bin 0 -> 496 bytes .../structures/meteor/room10/room-stairs.nbt | Bin 1797 -> 3381 bytes 5 files changed, 33 insertions(+), 16 deletions(-) create mode 100644 src/main/resources/assets/hbm/structures/meteor/room10/headloot/loot-fallback.nbt diff --git a/src/main/java/com/hbm/main/StructureManager.java b/src/main/java/com/hbm/main/StructureManager.java index 2456533ff..d7881ba66 100644 --- a/src/main/java/com/hbm/main/StructureManager.java +++ b/src/main/java/com/hbm/main/StructureManager.java @@ -48,6 +48,7 @@ public class StructureManager { public static final NBTStructure meteor_dragon_tesla = new NBTStructure(new ResourceLocation(RefStrings.MODID, "structures/meteor/room10/headloot/loot-tesla.nbt")); public static final NBTStructure meteor_dragon_trap = new NBTStructure(new ResourceLocation(RefStrings.MODID, "structures/meteor/room10/headloot/loot-trap.nbt")); public static final NBTStructure meteor_dragon_crate_crab = new NBTStructure(new ResourceLocation(RefStrings.MODID, "structures/meteor/room10/headloot/loot-crate-crab.nbt")); + public static final NBTStructure meteor_dragon_fallback = new NBTStructure(new ResourceLocation(RefStrings.MODID, "structures/meteor/room10/headloot/loot-fallback.nbt")); diff --git a/src/main/java/com/hbm/world/gen/NBTStructure.java b/src/main/java/com/hbm/world/gen/NBTStructure.java index 43625a627..6ec619378 100644 --- a/src/main/java/com/hbm/world/gen/NBTStructure.java +++ b/src/main/java/com/hbm/world/gen/NBTStructure.java @@ -650,6 +650,10 @@ public class NBTStructure { // Maximum amount of components in this structure public int sizeLimit = 8; + // How far the structure can extend horizontally from the center, maximum of 128 + // This could be increased by changing GenStructure:range from 8, but this is already quite reasonably large + public int rangeLimit = 128; + // Height modifiers, will clamp height that the start generates at, allowing for: // * Submarines that must spawn under the ocean surface // * Bunkers that sit underneath the ground @@ -967,7 +971,8 @@ public class NBTStructure { if(fromComponent.piece.structure.fromConnections == null) continue; - boolean fallbacksOnly = this.components.size() >= spawn.sizeLimit; + int distance = getDistanceTo(fromComponent.getBoundingBox()); + boolean fallbacksOnly = this.components.size() >= spawn.sizeLimit || distance >= spawn.rangeLimit; for(List unshuffledList : fromComponent.piece.structure.fromConnections) { List connectionList = new ArrayList<>(unshuffledList); @@ -1013,7 +1018,7 @@ public class NBTStructure { } if(GeneralConfig.enableDebugMode) { - MainRegistry.logger.info("[Debug] Spawning NBT structure at: " + chunkX * 16 + ", " + chunkZ * 16); + MainRegistry.logger.info("[Debug] Spawning NBT structure with " + components.size() + " piece(s) at: " + chunkX * 16 + ", " + chunkZ * 16); String componentList = "[Debug] Components: "; for(Object component : this.components) { componentList += ((Component) component).piece.structure.name + " "; @@ -1070,6 +1075,13 @@ public class NBTStructure { return nextPiece.structure.toHorizontalConnections.get(fromConnection.targetName); } + private int getDistanceTo(StructureBoundingBox box) { + int x = box.getCenterX(); + int z = box.getCenterZ(); + + return Math.max(Math.abs(x - (func_143019_e() << 4)), Math.abs(z - (func_143018_f() << 4))); + } + // post loading, update parent reference for loaded components @Override public void func_143017_b(NBTTagCompound nbt) { @@ -1152,4 +1164,4 @@ public class NBTStructure { } -} \ No newline at end of file +} diff --git a/src/main/java/com/hbm/world/gen/NTMWorldGenerator.java b/src/main/java/com/hbm/world/gen/NTMWorldGenerator.java index 3d9306b28..f68921cb3 100644 --- a/src/main/java/com/hbm/world/gen/NTMWorldGenerator.java +++ b/src/main/java/com/hbm/world/gen/NTMWorldGenerator.java @@ -50,23 +50,23 @@ public class NTMWorldGenerator implements IWorldGenerator { }}); Map bricks = new HashMap() {{ - put(ModBlocks.meteor_brick, new MeteorBricks()); - }}; - Map crates = new HashMap() {{ - put(ModBlocks.meteor_brick, new MeteorBricks()); - put(ModBlocks.crate, new SupplyCrates()); - put(ModBlocks.meteor_spawner, new CrabSpawners()); - }}; - Map ooze = new HashMap() {{ - put(ModBlocks.meteor_brick, new MeteorBricks()); - put(ModBlocks.concrete_colored, new GreenOoze()); - }}; + put(ModBlocks.meteor_brick, new MeteorBricks()); + }}; + Map crates = new HashMap() {{ + put(ModBlocks.meteor_brick, new MeteorBricks()); + put(ModBlocks.crate, new SupplyCrates()); + put(ModBlocks.meteor_spawner, new CrabSpawners()); + }}; + Map ooze = new HashMap() {{ + put(ModBlocks.meteor_brick, new MeteorBricks()); + put(ModBlocks.concrete_colored, new GreenOoze()); + }}; - NBTStructure.registerStructure(0, new SpawnCondition() {{ + NBTStructure.registerStructure(0, new SpawnCondition() {{ minHeight = 32; maxHeight = 32; sizeLimit = 128; - canSpawn = biome -> biome.rootHeight >= 0; + canSpawn = biome -> biome.rootHeight >= 0; startPool = "start"; pools = new HashMap() {{ put("start", new JigsawPool() {{ @@ -116,6 +116,7 @@ public class NTMWorldGenerator implements IWorldGenerator { add(new JigsawPiece("meteor_dragon_tesla", StructureManager.meteor_dragon_tesla) {{ blockTable = crates; }}, 1); add(new JigsawPiece("meteor_dragon_trap", StructureManager.meteor_dragon_trap) {{ blockTable = crates; }}, 1); add(new JigsawPiece("meteor_dragon_crate_crab", StructureManager.meteor_dragon_crate_crab) {{ blockTable = crates; }}, 1); + fallback = "headback"; }}); put("fallback", new JigsawPool() {{ add(new JigsawPiece("meteor_fallback", StructureManager.meteor_fallback) {{ blockTable = bricks; }}, 1); @@ -123,6 +124,9 @@ public class NTMWorldGenerator implements IWorldGenerator { put("roomback", new JigsawPool() {{ add(new JigsawPiece("meteor_room_fallback", StructureManager.meteor_room_fallback) {{ blockTable = bricks; }}, 1); }}); + put("headback", new JigsawPool() {{ + add(new JigsawPiece("meteor_loot_fallback", StructureManager.meteor_dragon_fallback) {{ blockTable = crates; }}, 1); + }}); }}; }}); } diff --git a/src/main/resources/assets/hbm/structures/meteor/room10/headloot/loot-fallback.nbt b/src/main/resources/assets/hbm/structures/meteor/room10/headloot/loot-fallback.nbt new file mode 100644 index 0000000000000000000000000000000000000000..2ce40e05361be4b5b18f5027d05340eb569c0e16 GIT binary patch literal 496 zcmVU$UhE7Y1=fjMqyW(O*mh=nkV1lu5k_DKeM=$Q zNmc&nGCO&b0&P_{291qS2s^_K-bXyf5D!e?fuRc+;=zY_@F5<2hzFm*gHJH>KEh-` zo1LLRYth(g)Q|WtJ9QnJK-{z~$ z$8BD0H~IUo-!^#y;axr9x!oE|&G+V_yu!{T5QqxSjF5O|fZxRpZ>mBnWo9TJ9*az1 zf`5)RjXB&Wn7}N_>}y{y6{2|K9L8X$b(Ph!6%yG^F$b| z*Ic4;pW=3y_D>kgAX{tIqVAu#%3!fFuzMBNSd0)f95q;QVg2LJ$qLiRfV literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/hbm/structures/meteor/room10/room-stairs.nbt b/src/main/resources/assets/hbm/structures/meteor/room10/room-stairs.nbt index 635f3d95efe29b441c3537b34b14ad8abe05a840..7cef44a647d8591ef5d7eaaabf85f928829c0cf4 100644 GIT binary patch literal 3381 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 literal 1797 zcmai!2~bl<7{>uciw8P9l_-*Qti%xn6R>#Dz-ZG_?W3qjzynBp6Cw};%H^{tirAEz zF~vblh(O6$w15YP2Sm{r4N3?R0|sIdFT!xVU=1%2(WDz`r^j^cn{RgZ+x_0|Z~yy! zOFH(E!^C&_bQsSgboQ5$h1T^OGS(NaUiahVt(Mt`lRw`0@Lq|?&H2Rf{DrIfzK_2X zde8Tp8+wt0`@9}lr;EW4T;e}sFLh^M8Mf}0Y~EnAHjadNv(Zfq>_u5n8rE3wjDJj` zHk-B9nu7b;?mwe?WBs}8u;y2Mi}g})U6W5M6=Id=jl-gFwVfCF?C1&%3 z-K4l_rL;Oeu3EdC6x`F3te3scy4i$(zCE6#lc+0N_+;;%kTfBN@eX9~yK2m+^v8_N z;e4Lfl{TuuPvI}R@wjgOyEiJ6f4BtSJ^t!#o66rkv)foV#HBwTG>MK=OczH=IrD0S zraQ5ko*^8KFJx93P^saIe;QkA_`5|$Y6!@aYVYby`1p>Oo|ODdxOqG2;$;Qw2B*a; z`tmL(UL+yh^J`|ccAsrMLM7KS(u|b0dPQfwPQ2%WVNHONpv40NS_9g$j?G z_+W?tzmBdFB&?jpr(%X@G=%7id@A89qSgQ9)N+Zz`^rWF;C7AnInfnDoxtAq9+D*H zE9e|YsMuLhe6-hD&|h=?5PH6HJ}cfOzJw_)A(@w#b^ANV7cr$MKhNMvF3KcmV>!+B zH?{Q1pP&e)56>u$SyI3DoVL(ucg3et?~5Rm2$czy@>P6 z+4Z}U-SiT-Z^!zJnTx`odZJFrT3**oMDHtO!7}zrLBiD`qMf$J10ZB500IxNfe0)2 zudqzpm7(tdm5c?bjMm*?W-GIcHg*2gNQ^^CRtVfXE*T;T-FR)HkE?DOzrM$bw4M@Pa4J2rmOa3q7nQ6l~0U`3Xx*)_@ zPA>sM$9`I$CZEvZ{q8NghDL0(<=TKpR!5a}LDz$I9r^8Xp-1wRGsp`9M7vs;QtE_L z%Ua=$^%;@sY2e@tz;)Lfa77=bV)H5i*Uq_stICy8_<;Ap2)`eiyajiK;AeXS@H z&GG^=z-OkDA38(*In)?)RIun=6iXU=G;jZ0@<8N-<4K&l_>cS}+b@4Iz>qM3JP^R( z<^XxZ6d{gY9||GWau*Pc!FLS4`r1jUlo1${=|GK2YQZWYJ zpz%paQrFO}&TZ!Ox0TOR9g(Dt)IB`kL6opvWgY)55`C;eKrQtYuO6i;jmXW4$x35H zsg8h*R>zT?B6|8Ng6d`s>m=rsH*K%`dxeUzxI)#a42zHrX3uXK7#m4{on*U*YpnT$ zLQ*pE2_C*B8?~P4HeN{1=*G_OJayn5Gh?#tMXoJnTW<&SIKT2>Pz-MBuP8e=h^ZT8 ngO7wdjmHDb{E5!yR~g8*WXc}j{A^xHfz8o!JN8j%sDs1rgqEgM From c1a2f8d27084c38499c61d74f887b20fbf767641 Mon Sep 17 00:00:00 2001 From: George Paton Date: Mon, 10 Feb 2025 11:43:30 +1100 Subject: [PATCH 09/12] stack jetpack tanks to 16, and don't consume them if jetpack is already full --- src/main/java/com/hbm/items/ModItems.java | 4 +- .../com/hbm/items/special/ItemSyringe.java | 37 +++++++++---------- 2 files changed, 20 insertions(+), 21 deletions(-) diff --git a/src/main/java/com/hbm/items/ModItems.java b/src/main/java/com/hbm/items/ModItems.java index 2d5e828bc..cbb86e51d 100644 --- a/src/main/java/com/hbm/items/ModItems.java +++ b/src/main/java/com/hbm/items/ModItems.java @@ -3076,7 +3076,7 @@ public class ModItems { gas_mask_filter_combo = new ItemFilter().setUnlocalizedName("gas_mask_filter_combo").setTextureName(RefStrings.MODID + ":gas_mask_filter_combo"); gas_mask_filter_rag = new ItemFilter().setUnlocalizedName("gas_mask_filter_rag").setTextureName(RefStrings.MODID + ":gas_mask_filter_rag"); gas_mask_filter_piss = new ItemFilter().setUnlocalizedName("gas_mask_filter_piss").setTextureName(RefStrings.MODID + ":gas_mask_filter_piss"); - jetpack_tank = new ItemSyringe().setUnlocalizedName("jetpack_tank").setMaxStackSize(1).setCreativeTab(MainRegistry.consumableTab).setTextureName(RefStrings.MODID + ":jetpack_tank"); + jetpack_tank = new ItemSyringe().setUnlocalizedName("jetpack_tank").setMaxStackSize(16).setCreativeTab(MainRegistry.consumableTab).setTextureName(RefStrings.MODID + ":jetpack_tank"); gun_kit_1 = new ItemRepairKit(10).setUnlocalizedName("gun_kit_1").setCreativeTab(MainRegistry.consumableTab).setTextureName(RefStrings.MODID + ":gun_kit_1"); gun_kit_2 = new ItemRepairKit(100).setUnlocalizedName("gun_kit_2").setCreativeTab(MainRegistry.consumableTab).setTextureName(RefStrings.MODID + ":gun_kit_2"); cbt_device = new ItemSyringe().setUnlocalizedName("cbt_device").setMaxStackSize(1).setCreativeTab(null).setTextureName(RefStrings.MODID + ":cbt_device"); @@ -6229,7 +6229,7 @@ public class ModItems { GameRegistry.registerItem(plastic_bag, plastic_bag.getUnlocalizedName()); GameRegistry.registerItem(casing_bag, casing_bag.getUnlocalizedName()); - + //Keys and Locks GameRegistry.registerItem(key, key.getUnlocalizedName()); GameRegistry.registerItem(key_red, key_red.getUnlocalizedName()); diff --git a/src/main/java/com/hbm/items/special/ItemSyringe.java b/src/main/java/com/hbm/items/special/ItemSyringe.java index 48b6e928b..b8aad87e1 100644 --- a/src/main/java/com/hbm/items/special/ItemSyringe.java +++ b/src/main/java/com/hbm/items/special/ItemSyringe.java @@ -48,7 +48,7 @@ public class ItemSyringe extends Item { if(!player.inventory.addItemStackToInventory(new ItemStack(ModItems.syringe_empty))) { player.dropPlayerItemWithRandomChoice(new ItemStack(ModItems.syringe_empty, 1, 0), false); } - + VersatileConfig.applyPotionSickness(player, 5); } } @@ -77,7 +77,7 @@ public class ItemSyringe extends Item { if(!player.inventory.addItemStackToInventory(new ItemStack(ModItems.syringe_empty))) { player.dropPlayerItemWithRandomChoice(new ItemStack(ModItems.syringe_empty, 1, 0), false); } - + VersatileConfig.applyPotionSickness(player, 50); } } @@ -116,7 +116,7 @@ public class ItemSyringe extends Item { if(!player.inventory.addItemStackToInventory(new ItemStack(ModItems.syringe_metal_empty))) { player.dropPlayerItemWithRandomChoice(new ItemStack(ModItems.syringe_metal_empty, 1, 0), false); } - + VersatileConfig.applyPotionSickness(player, 5); } } @@ -135,7 +135,7 @@ public class ItemSyringe extends Item { if(!player.inventory.addItemStackToInventory(new ItemStack(ModItems.syringe_metal_empty))) { player.dropPlayerItemWithRandomChoice(new ItemStack(ModItems.syringe_metal_empty, 1, 0), false); } - + VersatileConfig.applyPotionSickness(player, 5); } } @@ -155,7 +155,7 @@ public class ItemSyringe extends Item { if(!player.inventory.addItemStackToInventory(new ItemStack(ModItems.syringe_metal_empty))) { player.dropPlayerItemWithRandomChoice(new ItemStack(ModItems.syringe_metal_empty, 1, 0), false); } - + VersatileConfig.applyPotionSickness(player, 5); } } @@ -175,7 +175,7 @@ public class ItemSyringe extends Item { if(!player.inventory.addItemStackToInventory(new ItemStack(ModItems.syringe_metal_empty))) { player.dropPlayerItemWithRandomChoice(new ItemStack(ModItems.syringe_metal_empty, 1, 0), false); } - + VersatileConfig.applyPotionSickness(player, 15); } } @@ -193,7 +193,7 @@ public class ItemSyringe extends Item { player.removePotionEffect(Potion.weakness.id); player.removePotionEffect(Potion.wither.id); player.removePotionEffect(HbmPotion.radiation.id); - + VersatileConfig.applyPotionSickness(player, 15); stack.stackSize--; @@ -283,18 +283,17 @@ public class ItemSyringe extends Item { return stack; IFillableItem fillable = (IFillableItem) jetpack.getItem(); - + if(!fillable.acceptsFluid(Fluids.KEROSENE, jetpack)) return stack; - - fillable.tryFill(Fluids.KEROSENE, 1000, jetpack); - + + if(fillable.tryFill(Fluids.KEROSENE, 1000, jetpack) < 1000) { + world.playSoundAtEntity(player, "hbm:item.jetpackTank", 1.0F, 1.0F); + stack.stackSize--; + } + if(jetpack.getItem() != player.inventory.armorInventory[2].getItem()) ArmorModHandler.applyMod(player.inventory.armorInventory[2], jetpack); - - world.playSoundAtEntity(player, "hbm:item.jetpackTank", 1.0F, 1.0F); - - stack.stackSize--; } } @@ -386,11 +385,11 @@ public class ItemSyringe extends Item { if(this == ModItems.syringe_awesome && !VersatileConfig.hasPotionSickness(entity)) { if(!world.isRemote) { - + if(entity instanceof EntityCow) { - + entity.addPotionEffect(new PotionEffect(HbmPotion.bang.id, 40, 0)); - + } else { entity.addPotionEffect(new PotionEffect(Potion.regeneration.id, 50 * 20, 9)); entity.addPotionEffect(new PotionEffect(Potion.resistance.id, 50 * 20, 9)); @@ -592,7 +591,7 @@ public class ItemSyringe extends Item { if(this == ModItems.gun_kit_2) { list.add("Repairs all weapons in hotbar by 50%"); } - + if(this == ModItems.syringe_mkunicorn) { list.add(EnumChatFormatting.RED + "?"); } From 8994d2e0b17df4e19444d0ca00c5a93ee1767ecd Mon Sep 17 00:00:00 2001 From: George Paton Date: Mon, 10 Feb 2025 12:21:17 +1100 Subject: [PATCH 10/12] add nbt vertibird spawning and remove unused meteor dungeon code --- src/main/java/com/hbm/config/WorldConfig.java | 16 +- src/main/java/com/hbm/lib/HbmWorldGen.java | 18 - .../hbm/world/dungeon/CrashedVertibird.java | 426 --------------- .../java/com/hbm/world/dungeon/Vertibird.java | 514 ------------------ .../com/hbm/world/gen/NTMWorldGenerator.java | 12 + .../generator/CellularDungeonFactory.java | 16 +- .../com/hbm/world/generator/TestDungeon.java | 19 - .../generator/room/TestDungeonRoom1.java | 39 -- .../generator/room/TestDungeonRoom2.java | 34 -- .../generator/room/TestDungeonRoom3.java | 33 -- .../generator/room/TestDungeonRoom4.java | 43 -- .../generator/room/TestDungeonRoom5.java | 40 -- .../generator/room/TestDungeonRoom6.java | 54 -- .../generator/room/TestDungeonRoom7.java | 28 - .../generator/room/TestDungeonRoom8.java | 225 -------- 15 files changed, 19 insertions(+), 1498 deletions(-) delete mode 100644 src/main/java/com/hbm/world/dungeon/CrashedVertibird.java delete mode 100644 src/main/java/com/hbm/world/dungeon/Vertibird.java delete mode 100644 src/main/java/com/hbm/world/generator/TestDungeon.java delete mode 100644 src/main/java/com/hbm/world/generator/room/TestDungeonRoom1.java delete mode 100644 src/main/java/com/hbm/world/generator/room/TestDungeonRoom2.java delete mode 100644 src/main/java/com/hbm/world/generator/room/TestDungeonRoom3.java delete mode 100644 src/main/java/com/hbm/world/generator/room/TestDungeonRoom4.java delete mode 100644 src/main/java/com/hbm/world/generator/room/TestDungeonRoom5.java delete mode 100644 src/main/java/com/hbm/world/generator/room/TestDungeonRoom6.java delete mode 100644 src/main/java/com/hbm/world/generator/room/TestDungeonRoom7.java delete mode 100644 src/main/java/com/hbm/world/generator/room/TestDungeonRoom8.java diff --git a/src/main/java/com/hbm/config/WorldConfig.java b/src/main/java/com/hbm/config/WorldConfig.java index fbf08bc63..7bb0faf58 100644 --- a/src/main/java/com/hbm/config/WorldConfig.java +++ b/src/main/java/com/hbm/config/WorldConfig.java @@ -7,7 +7,7 @@ public class WorldConfig { public static boolean overworldOre = true; public static boolean netherOre = true; public static boolean endOre = true; - + public static int uraniumSpawn = 6; public static int thoriumSpawn = 7; public static int titaniumSpawn = 8; @@ -77,7 +77,6 @@ public class WorldConfig { public static int radioStructure = 500; public static int antennaStructure = 250; public static int atomStructure = 500; - public static int vertibirdStructure = 500; public static int dungeonStructure = 64; public static int relayStructure = 500; public static int satelliteStructure = 500; @@ -88,7 +87,6 @@ public class WorldConfig { public static int geyserWater = 3000; public static int geyserChlorine = 3000; public static int geyserVapor = 500; - public static int meteorStructure = 15000; public static int capsuleStructure = 100; public static int arcticStructure = 500; public static int jungleStructure = 2000; @@ -115,15 +113,15 @@ public class WorldConfig { public static float craterBiomeInnerRad = 25F; public static float craterBiomeOuterRad = 0.5F; public static float craterBiomeWaterMult = 5F; - + public static void loadFromConfig(Configuration config) { final String CATEGORY_OREGEN = CommonConfig.CATEGORY_ORES; - + overworldOre = CommonConfig.createConfigBool(config, CATEGORY_OREGEN, "2.D00_overworldOres", "General switch for whether overworld ores should be generated. Does not include special structures like oil.", true); netherOre = CommonConfig.createConfigBool(config, CATEGORY_OREGEN, "2.D01_netherOres", "General switch for whether nether ores should be generated.", true); endOre = CommonConfig.createConfigBool(config, CATEGORY_OREGEN, "2.D02_endOres", "General switch for whether end ores should be generated. Does not include special structures like trixite crystals.", true); - + uraniumSpawn = CommonConfig.createConfigInt(config, CATEGORY_OREGEN, "2.00_uraniumSpawnrate", "Amount of uranium ore veins per chunk", 7); titaniumSpawn = CommonConfig.createConfigInt(config, CATEGORY_OREGEN, "2.01_titaniumSpawnrate", "Amount of titanium ore veins per chunk", 8); sulfurSpawn = CommonConfig.createConfigInt(config, CATEGORY_OREGEN, "2.02_sulfurSpawnrate", "Amount of sulfur ore veins per chunk", 5); @@ -195,7 +193,6 @@ public class WorldConfig { radioStructure = CommonConfig.createConfigInt(config, CATEGORY_DUNGEON, "4.00_radioSpawn", "Spawn radio station on every nTH chunk", 500); antennaStructure = CommonConfig.createConfigInt(config, CATEGORY_DUNGEON, "4.01_antennaSpawn", "Spawn antenna on every nTH chunk", 250); atomStructure = CommonConfig.createConfigInt(config, CATEGORY_DUNGEON, "4.02_atomSpawn", "Spawn power plant on every nTH chunk", 500); - vertibirdStructure = CommonConfig.createConfigInt(config, CATEGORY_DUNGEON, "4.03_vertibirdSpawn", "Spawn vertibird on every nTH chunk", 500); dungeonStructure = CommonConfig.createConfigInt(config, CATEGORY_DUNGEON, "4.04_dungeonSpawn", "Spawn library dungeon on every nTH chunk", 64); relayStructure = CommonConfig.createConfigInt(config, CATEGORY_DUNGEON, "4.05_relaySpawn", "Spawn relay on every nTH chunk", 500); satelliteStructure = CommonConfig.createConfigInt(config, CATEGORY_DUNGEON, "4.06_satelliteSpawn", "Spawn satellite dish on every nTH chunk", 500); @@ -210,7 +207,6 @@ public class WorldConfig { geyserWater = CommonConfig.createConfigInt(config, CATEGORY_DUNGEON, "4.17_geyserWaterSpawn", "Spawn water geyser on every nTH chunk", 3000); geyserChlorine = CommonConfig.createConfigInt(config, CATEGORY_DUNGEON, "4.18_geyserChlorineSpawn", "Spawn poison geyser on every nTH chunk", 3000); geyserVapor = CommonConfig.createConfigInt(config, CATEGORY_DUNGEON, "4.19_geyserVaporSpawn", "Spawn vapor geyser on every nTH chunk", 500); - meteorStructure = CommonConfig.createConfigInt(config, CATEGORY_DUNGEON, "4.20_meteorSpawn", "Spawn meteor dungeon on every nTH chunk", 15000); capsuleStructure = CommonConfig.createConfigInt(config, CATEGORY_DUNGEON, "4.21_capsuleSpawn", "Spawn landing capsule on every nTH chunk", 100); arcticStructure = CommonConfig.createConfigInt(config, CATEGORY_DUNGEON, "4.22_arcticVaultSpawn", "Spawn arctic code vault on every nTH chunk", 500); jungleStructure = CommonConfig.createConfigInt(config, CATEGORY_DUNGEON, "4.23_jungleDungeonSpawn", "Spawn jungle dungeon on every nTH chunk", 2000); @@ -238,7 +234,6 @@ public class WorldConfig { radioStructure = CommonConfig.setDefZero(radioStructure, 1000); antennaStructure = CommonConfig.setDefZero(antennaStructure, 1000); atomStructure = CommonConfig.setDefZero(atomStructure, 1000); - vertibirdStructure = CommonConfig.setDefZero(vertibirdStructure, 1000); dungeonStructure = CommonConfig.setDefZero(dungeonStructure, 1000); relayStructure = CommonConfig.setDefZero(relayStructure, 1000); satelliteStructure = CommonConfig.setDefZero(satelliteStructure, 1000); @@ -253,11 +248,10 @@ public class WorldConfig { minefreq = CommonConfig.setDefZero(minefreq, 1000); radfreq = CommonConfig.setDefZero(radfreq, 1000); vaultfreq = CommonConfig.setDefZero(vaultfreq, 1000); - meteorStructure = CommonConfig.setDefZero(meteorStructure, 15000); jungleStructure = CommonConfig.setDefZero(jungleStructure, 1000); capsuleStructure = CommonConfig.setDefZero(capsuleStructure, 100); arcticStructure = CommonConfig.setDefZero(arcticStructure, 500); - + meteorStrikeChance = CommonConfig.setDef(meteorStrikeChance, 1000); meteorShowerChance = CommonConfig.setDef(meteorShowerChance, 1000); } diff --git a/src/main/java/com/hbm/lib/HbmWorldGen.java b/src/main/java/com/hbm/lib/HbmWorldGen.java index c78fe7219..42f7e616a 100644 --- a/src/main/java/com/hbm/lib/HbmWorldGen.java +++ b/src/main/java/com/hbm/lib/HbmWorldGen.java @@ -28,7 +28,6 @@ import net.minecraft.block.Block; import net.minecraft.init.Blocks; import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntityChest; -import net.minecraft.tileentity.TileEntitySkull; import net.minecraft.util.WeightedRandom; import net.minecraft.util.WeightedRandomChestContent; import net.minecraft.world.World; @@ -260,23 +259,6 @@ public class HbmWorldGen implements IWorldGenerator { } } - if(!biome.canSpawnLightningBolt() && biome.temperature >= 2F) { - if(WorldConfig.vertibirdStructure > 0 && rand.nextInt(WorldConfig.vertibirdStructure) == 0) { - for(int a = 0; a < 1; a++) { - int x = i + rand.nextInt(16); - int z = j + rand.nextInt(16); - int y = world.getHeightValue(x, z); - - if(rand.nextInt(2) == 0) { - new Vertibird().generate(world, rand, x, y, z); - } else { - new CrashedVertibird().generate(world, rand, x, y, z); - } - - } - } - } - if(WorldConfig.dungeonStructure > 0 && rand.nextInt(WorldConfig.dungeonStructure) == 0) { int x = i + rand.nextInt(16); int y = rand.nextInt(256); diff --git a/src/main/java/com/hbm/world/dungeon/CrashedVertibird.java b/src/main/java/com/hbm/world/dungeon/CrashedVertibird.java deleted file mode 100644 index 68b8f2cbb..000000000 --- a/src/main/java/com/hbm/world/dungeon/CrashedVertibird.java +++ /dev/null @@ -1,426 +0,0 @@ -//Schematic to java Structure by jajo_11 | inspired by "MITHION'S .SCHEMATIC TO JAVA CONVERTINGTOOL" - -package com.hbm.world.dungeon; - -import java.util.Random; - -import com.hbm.blocks.ModBlocks; -import com.hbm.config.GeneralConfig; -import com.hbm.itempool.ItemPool; -import com.hbm.itempool.ItemPoolsLegacy; -import net.minecraft.block.Block; -import net.minecraft.block.material.Material; -import net.minecraft.init.Blocks; -import net.minecraft.tileentity.TileEntityChest; -import net.minecraft.util.WeightedRandomChestContent; -import net.minecraft.world.World; -import net.minecraft.world.gen.feature.WorldGenerator; - -public class CrashedVertibird extends WorldGenerator -{ - Block Block1 = ModBlocks.deco_steel; - Block Block2 = ModBlocks.deco_tungsten; - Block Block3 = ModBlocks.reinforced_glass; - Block Block4 = ModBlocks.deco_titanium; - - protected Block[] GetValidSpawnBlocks() - { - return new Block[] - { - Blocks.sand, - Blocks.sandstone, - }; - } - - public boolean LocationIsValidSpawn(World world, int x, int y, int z) - { - - Block checkBlock = world.getBlock(x, y - 1, z); - Block blockAbove = world.getBlock(x, y , z); - Block blockBelow = world.getBlock(x, y - 2, z); - - for (Block i : GetValidSpawnBlocks()) - { - if (blockAbove != Blocks.air) - { - return false; - } - if (checkBlock == i) - { - return true; - } - else if (checkBlock == Blocks.snow_layer && blockBelow == i) - { - return true; - } - else if (checkBlock.getMaterial() == Material.plants && blockBelow == i) - { - return true; - } - } - return false; - } - - @Override - public boolean generate(World world, Random rand, int x, int y, int z) - { - int i = rand.nextInt(1); - - if(i == 0) - { - generate_r0(world, rand, x, y, z); - } - - return true; - - } - - public boolean generate_r0(World world, Random rand, int x, int y, int z) - { - int yOffset = 8 + rand.nextInt(4); - - if(!LocationIsValidSpawn(world, x + 9, y, z + 9)) - { - return false; - } - - world.setBlock(x + 4, y + 0 - yOffset, z + 1, Block1, 0, 3); - world.setBlock(x + 5, y + 0 - yOffset, z + 1, Block1, 0, 3); - world.setBlock(x + 6, y + 0 - yOffset, z + 1, Block1, 0, 3); - world.setBlock(x + 5, y + 0 - yOffset, z + 2, Block2, 0, 3); - world.setBlock(x + 4, y + 1 - yOffset, z + 0, Block1, 0, 3); - world.setBlock(x + 5, y + 1 - yOffset, z + 0, Block1, 0, 3); - world.setBlock(x + 6, y + 1 - yOffset, z + 0, Block1, 0, 3); - world.setBlock(x + 3, y + 1 - yOffset, z + 1, Block1, 0, 3); - world.setBlock(x + 7, y + 1 - yOffset, z + 1, Block1, 0, 3); - world.setBlock(x + 4, y + 1 - yOffset, z + 2, Block1, 0, 3); - world.setBlock(x + 5, y + 1 - yOffset, z + 2, Block1, 0, 3); - world.setBlock(x + 6, y + 1 - yOffset, z + 2, Block1, 0, 3); - world.setBlock(x + 3, y + 1 - yOffset, z + 3, Block2, 0, 3); - world.setBlock(x + 4, y + 1 - yOffset, z + 3, Block1, 0, 3); - world.setBlock(x + 5, y + 1 - yOffset, z + 3, Block1, 0, 3); - world.setBlock(x + 6, y + 1 - yOffset, z + 3, Block1, 0, 3); - world.setBlock(x + 7, y + 1 - yOffset, z + 3, Block2, 0, 3); - world.setBlock(x + 4, y + 2 - yOffset, z + 0, Block3, 0, 3); - world.setBlock(x + 5, y + 2 - yOffset, z + 0, Block3, 0, 3); - world.setBlock(x + 3, y + 2 - yOffset, z + 1, Block3, 0, 3); - world.setBlock(x + 7, y + 2 - yOffset, z + 1, Block3, 0, 3); - world.setBlock(x + 3, y + 2 - yOffset, z + 2, Block1, 0, 3); - world.setBlock(x + 4, y + 2 - yOffset, z + 2, Blocks.stone_stairs, 2, 3); - world.setBlock(x + 6, y + 2 - yOffset, z + 2, Blocks.stone_stairs, 2, 3); - world.setBlock(x + 7, y + 2 - yOffset, z + 2, Block1, 0, 3); - world.setBlock(x + 7, y + 2 - yOffset, z + 3, Block4, 0, 3); - world.setBlock(x + 3, y + 2 - yOffset, z + 4, Block2, 0, 3); - world.setBlock(x + 4, y + 2 - yOffset, z + 4, Block1, 0, 3); - world.setBlock(x + 5, y + 2 - yOffset, z + 4, Block1, 0, 3); - world.setBlock(x + 6, y + 2 - yOffset, z + 4, Block1, 0, 3); - world.setBlock(x + 7, y + 2 - yOffset, z + 4, Block2, 0, 3); - world.setBlock(x + 3, y + 2 - yOffset, z + 5, Block2, 0, 3); - world.setBlock(x + 4, y + 2 - yOffset, z + 5, Block1, 0, 3); - world.setBlock(x + 5, y + 2 - yOffset, z + 5, Block1, 0, 3); - world.setBlock(x + 6, y + 2 - yOffset, z + 5, Block1, 0, 3); - world.setBlock(x + 7, y + 2 - yOffset, z + 5, Block2, 0, 3); - world.setBlock(x + 4, y + 2 - yOffset, z + 7, Block2, 0, 3); - world.setBlock(x + 6, y + 2 - yOffset, z + 7, Block2, 0, 3); - world.setBlock(x + 4, y + 3 - yOffset, z + 0, Block1, 0, 3); - world.setBlock(x + 5, y + 3 - yOffset, z + 0, Block1, 0, 3); - world.setBlock(x + 6, y + 3 - yOffset, z + 0, Block1, 0, 3); - world.setBlock(x + 3, y + 3 - yOffset, z + 1, Block3, 0, 3); - world.setBlock(x + 4, y + 3 - yOffset, z + 1, Block1, 0, 3); - world.setBlock(x + 5, y + 3 - yOffset, z + 1, Block1, 0, 3); - world.setBlock(x + 6, y + 3 - yOffset, z + 1, Block1, 0, 3); - world.setBlock(x + 7, y + 3 - yOffset, z + 1, Block3, 0, 3); - world.setBlock(x + 3, y + 3 - yOffset, z + 2, Block1, 0, 3); - world.setBlock(x + 7, y + 3 - yOffset, z + 2, Block1, 0, 3); - world.setBlock(x + 3, y + 3 - yOffset, z + 3, Block1, 0, 3); - world.setBlock(x + 7, y + 3 - yOffset, z + 3, Block1, 0, 3); - world.setBlock(x + 7, y + 3 - yOffset, z + 4, Block4, 0, 3); - world.setBlock(x + 2, y + 3 - yOffset, z + 5, Block4, 0, 3); - world.setBlock(x + 7, y + 3 - yOffset, z + 5, Block4, 0, 3); - world.setBlock(x + 4, y + 3 - yOffset, z + 6, Block1, 0, 3); - world.setBlock(x + 5, y + 3 - yOffset, z + 6, Block1, 0, 3); - world.setBlock(x + 6, y + 3 - yOffset, z + 6, Block1, 0, 3); - world.setBlock(x + 4, y + 3 - yOffset, z + 7, Block1, 0, 3); - world.setBlock(x + 5, y + 3 - yOffset, z + 7, Block1, 0, 3); - world.setBlock(x + 6, y + 3 - yOffset, z + 7, Block1, 0, 3); - world.setBlock(x + 5, y + 3 - yOffset, z + 9, Block2, 0, 3); - world.setBlock(x + 4, y + 4 - yOffset, z + 1, Block1, 0, 3); - world.setBlock(x + 5, y + 4 - yOffset, z + 1, Block1, 0, 3); - world.setBlock(x + 6, y + 4 - yOffset, z + 1, Block1, 0, 3); - world.setBlock(x + 3, y + 4 - yOffset, z + 2, Block3, 0, 3); - world.setBlock(x + 3, y + 4 - yOffset, z + 3, Block1, 0, 3); - world.setBlock(x + 7, y + 4 - yOffset, z + 3, Block1, 0, 3); - world.setBlock(x + 7, y + 4 - yOffset, z + 5, Block4, 0, 3); - world.setBlock(x + 2, y + 4 - yOffset, z + 6, Block4, 0, 3); - world.setBlock(x + 3, y + 4 - yOffset, z + 6, Block1, 0, 3); - world.setBlock(x + 7, y + 4 - yOffset, z + 6, Block1, 0, 3); - world.setBlock(x + 2, y + 4 - yOffset, z + 7, Block4, 0, 3); - world.setBlock(x + 3, y + 4 - yOffset, z + 7, Block1, 0, 3); - world.setBlock(x + 6, y + 4 - yOffset, z + 7, Blocks.chest, 2, 3); - if(world.getBlock(x + 6, y + 4 - yOffset, z + 7) == Blocks.chest) - { - WeightedRandomChestContent.generateChestContents(rand, ItemPool.getPool(ItemPoolsLegacy.POOL_VERTIBIRD), (TileEntityChest)world.getTileEntity(x + 6, y + 4 - yOffset, z + 7), 8); - } - world.setBlock(x + 7, y + 4 - yOffset, z + 7, Block1, 0, 3); - world.setBlock(x + 4, y + 4 - yOffset, z + 8, Block1, 0, 3); - world.setBlock(x + 5, y + 4 - yOffset, z + 8, Block1, 0, 3); - world.setBlock(x + 6, y + 4 - yOffset, z + 8, Block1, 0, 3); - world.setBlock(x + 4, y + 4 - yOffset, z + 9, Block1, 0, 3); - world.setBlock(x + 5, y + 4 - yOffset, z + 9, Block1, 0, 3); - world.setBlock(x + 6, y + 4 - yOffset, z + 9, Block1, 0, 3); - world.setBlock(x + 6, y + 5 - yOffset, z + 1, Block2, 0, 3); - world.setBlock(x + 4, y + 5 - yOffset, z + 2, Block1, 0, 3); - world.setBlock(x + 5, y + 5 - yOffset, z + 2, Block1, 0, 3); - world.setBlock(x + 6, y + 5 - yOffset, z + 2, Block1, 0, 3); - world.setBlock(x + 4, y + 5 - yOffset, z + 3, Block1, 0, 3); - world.setBlock(x + 5, y + 5 - yOffset, z + 3, Block1, 0, 3); - world.setBlock(x + 6, y + 5 - yOffset, z + 3, Block1, 0, 3); - world.setBlock(x + 7, y + 5 - yOffset, z + 3, Block1, 0, 3); - world.setBlock(x + 3, y + 5 - yOffset, z + 4, Block1, 0, 3); - world.setBlock(x + 7, y + 5 - yOffset, z + 4, Block1, 0, 3); - world.setBlock(x + 3, y + 5 - yOffset, z + 5, Block1, 0, 3); - world.setBlock(x + 7, y + 5 - yOffset, z + 5, Block1, 0, 3); - world.setBlock(x + 2, y + 5 - yOffset, z + 6, Block4, 0, 3); - world.setBlock(x + 3, y + 5 - yOffset, z + 6, Block1, 0, 3); - world.setBlock(x + 7, y + 5 - yOffset, z + 6, Block1, 0, 3); - world.setBlock(x + 2, y + 5 - yOffset, z + 7, Block4, 0, 3); - world.setBlock(x + 3, y + 5 - yOffset, z + 7, Block1, 0, 3); - world.setBlock(x + 7, y + 5 - yOffset, z + 7, Block1, 0, 3); - world.setBlock(x + 4, y + 5 - yOffset, z + 8, Block1, 0, 3); - world.setBlock(x + 5, y + 5 - yOffset, z + 8, Block1, 0, 3); - world.setBlock(x + 6, y + 5 - yOffset, z + 8, Block1, 0, 3); - world.setBlock(x + 4, y + 5 - yOffset, z + 9, Block1, 0, 3); - world.setBlock(x + 5, y + 5 - yOffset, z + 9, Block4, 0, 3); - world.setBlock(x + 6, y + 5 - yOffset, z + 9, Block1, 0, 3); - world.setBlock(x + 5, y + 6 - yOffset, z + 3, Block1, 0, 3); - world.setBlock(x + 6, y + 6 - yOffset, z + 3, Block1, 0, 3); - world.setBlock(x + 4, y + 6 - yOffset, z + 4, Block1, 0, 3); - world.setBlock(x + 5, y + 6 - yOffset, z + 4, Block1, 0, 3); - world.setBlock(x + 6, y + 6 - yOffset, z + 4, Block1, 0, 3); - world.setBlock(x + 7, y + 6 - yOffset, z + 4, Block1, 0, 3); - world.setBlock(x + 14, y + 6 - yOffset, z + 4, Block1, 0, 3); - world.setBlock(x + 0, y + 6 - yOffset, z + 5, Block1, 0, 3); - world.setBlock(x + 1, y + 6 - yOffset, z + 5, Block1, 0, 3); - world.setBlock(x + 2, y + 6 - yOffset, z + 5, Block1, 0, 3); - world.setBlock(x + 3, y + 6 - yOffset, z + 5, Block1, 0, 3); - world.setBlock(x + 4, y + 6 - yOffset, z + 5, Block1, 0, 3); - world.setBlock(x + 5, y + 6 - yOffset, z + 5, Block1, 0, 3); - world.setBlock(x + 6, y + 6 - yOffset, z + 5, Block1, 0, 3); - world.setBlock(x + 7, y + 6 - yOffset, z + 5, Block1, 0, 3); - world.setBlock(x + 8, y + 6 - yOffset, z + 5, Block1, 0, 3); - world.setBlock(x + 9, y + 6 - yOffset, z + 5, Block1, 0, 3); - world.setBlock(x + 10, y + 6 - yOffset, z + 5, Block1, 0, 3); - world.setBlock(x + 13, y + 6 - yOffset, z + 5, Block1, 0, 3); - world.setBlock(x + 3, y + 6 - yOffset, z + 6, Block1, 0, 3); - world.setBlock(x + 4, y + 6 - yOffset, z + 6, Block1, 0, 3); - world.setBlock(x + 6, y + 6 - yOffset, z + 6, Block1, 0, 3); - world.setBlock(x + 7, y + 6 - yOffset, z + 6, Block1, 0, 3); - world.setBlock(x + 3, y + 6 - yOffset, z + 7, Block1, 0, 3); - world.setBlock(x + 4, y + 6 - yOffset, z + 7, Block1, 0, 3); - world.setBlock(x + 5, y + 6 - yOffset, z + 7, Block1, 0, 3); - world.setBlock(x + 6, y + 6 - yOffset, z + 7, Block1, 0, 3); - world.setBlock(x + 7, y + 6 - yOffset, z + 7, Block1, 0, 3); - world.setBlock(x + 4, y + 6 - yOffset, z + 8, Block1, 0, 3); - world.setBlock(x + 5, y + 6 - yOffset, z + 8, ModBlocks.machine_battery, 2, 3); - world.setBlock(x + 6, y + 6 - yOffset, z + 8, Block1, 0, 3); - world.setBlock(x + 4, y + 6 - yOffset, z + 9, Block1, 0, 3); - world.setBlock(x + 5, y + 6 - yOffset, z + 9, ModBlocks.red_wire_coated, 0, 3); - world.setBlock(x + 6, y + 6 - yOffset, z + 9, Block1, 0, 3); - world.setBlock(x + 4, y + 6 - yOffset, z + 10, Block1, 0, 3); - world.setBlock(x + 5, y + 6 - yOffset, z + 10, Block1, 0, 3); - world.setBlock(x + 6, y + 6 - yOffset, z + 10, Block1, 0, 3); - world.setBlock(x + 5, y + 6 - yOffset, z + 11, Block1, 0, 3); - world.setBlock(x + 6, y + 6 - yOffset, z + 11, Block1, 0, 3); - world.setBlock(x + 4, y + 7 - yOffset, z + 4, Block1, 0, 3); - world.setBlock(x + 5, y + 7 - yOffset, z + 4, Block1, 0, 3); - world.setBlock(x + 6, y + 7 - yOffset, z + 4, Block1, 0, 3); - world.setBlock(x + 7, y + 7 - yOffset, z + 4, Block1, 0, 3); - world.setBlock(x + 14, y + 7 - yOffset, z + 4, Block1, 0, 3); - world.setBlock(x + 1, y + 7 - yOffset, z + 5, Block1, 0, 3); - world.setBlock(x + 2, y + 7 - yOffset, z + 5, Block1, 0, 3); - world.setBlock(x + 3, y + 7 - yOffset, z + 5, Block1, 0, 3); - world.setBlock(x + 4, y + 7 - yOffset, z + 5, Block1, 0, 3); - world.setBlock(x + 5, y + 7 - yOffset, z + 5, Block1, 0, 3); - world.setBlock(x + 6, y + 7 - yOffset, z + 5, Block1, 0, 3); - world.setBlock(x + 7, y + 7 - yOffset, z + 5, Block1, 0, 3); - world.setBlock(x + 8, y + 7 - yOffset, z + 5, Block1, 0, 3); - world.setBlock(x + 9, y + 7 - yOffset, z + 5, Block1, 0, 3); - world.setBlock(x + 10, y + 7 - yOffset, z + 5, Block1, 0, 3); - world.setBlock(x + 11, y + 7 - yOffset, z + 5, Block1, 0, 3); - world.setBlock(x + 12, y + 7 - yOffset, z + 5, Block1, 0, 3); - world.setBlock(x + 13, y + 7 - yOffset, z + 5, Block1, 0, 3); - world.setBlock(x + 14, y + 7 - yOffset, z + 5, Block2, 0, 3); - world.setBlock(x + 3, y + 7 - yOffset, z + 6, Block1, 0, 3); - world.setBlock(x + 4, y + 7 - yOffset, z + 6, Block1, 0, 3); - world.setBlock(x + 5, y + 7 - yOffset, z + 6, Block1, 0, 3); - world.setBlock(x + 6, y + 7 - yOffset, z + 6, Block1, 0, 3); - world.setBlock(x + 7, y + 7 - yOffset, z + 6, Block1, 0, 3); - world.setBlock(x + 14, y + 7 - yOffset, z + 6, Block1, 0, 3); - world.setBlock(x + 3, y + 7 - yOffset, z + 7, Block1, 0, 3); - world.setBlock(x + 4, y + 7 - yOffset, z + 7, Block1, 0, 3); - world.setBlock(x + 5, y + 7 - yOffset, z + 7, Block1, 0, 3); - world.setBlock(x + 6, y + 7 - yOffset, z + 7, Block1, 0, 3); - world.setBlock(x + 7, y + 7 - yOffset, z + 7, Block1, 0, 3); - world.setBlock(x + 3, y + 7 - yOffset, z + 8, Block1, 0, 3); - world.setBlock(x + 4, y + 7 - yOffset, z + 8, Block1, 0, 3); - world.setBlock(x + 5, y + 7 - yOffset, z + 8, Block1, 0, 3); - world.setBlock(x + 6, y + 7 - yOffset, z + 8, Block1, 0, 3); - world.setBlock(x + 7, y + 7 - yOffset, z + 8, Block1, 0, 3); - world.setBlock(x + 3, y + 7 - yOffset, z + 9, Block1, 0, 3); - world.setBlock(x + 4, y + 7 - yOffset, z + 9, ModBlocks.block_electrical_scrap, 0, 3); - world.setBlock(x + 5, y + 7 - yOffset, z + 9, ModBlocks.red_wire_coated, 0, 3); - world.setBlock(x + 6, y + 7 - yOffset, z + 9, ModBlocks.block_electrical_scrap, 0, 3); - world.setBlock(x + 7, y + 7 - yOffset, z + 9, Block1, 0, 3); - world.setBlock(x + 5, y + 7 - yOffset, z + 10, Block4, 0, 3); - world.setBlock(x + 6, y + 7 - yOffset, z + 10, Block1, 0, 3); - world.setBlock(x + 5, y + 7 - yOffset, z + 11, Block4, 0, 3); - world.setBlock(x + 6, y + 7 - yOffset, z + 11, Block1, 0, 3); - world.setBlock(x + 5, y + 8 - yOffset, z + 4, Block1, 0, 3); - world.setBlock(x + 14, y + 8 - yOffset, z + 4, Block1, 0, 3); - world.setBlock(x + 4, y + 8 - yOffset, z + 5, Block1, 0, 3); - world.setBlock(x + 5, y + 8 - yOffset, z + 5, Block1, 0, 3); - world.setBlock(x + 6, y + 8 - yOffset, z + 5, Block1, 0, 3); - world.setBlock(x + 13, y + 8 - yOffset, z + 5, Block1, 0, 3); - world.setBlock(x + 14, y + 8 - yOffset, z + 5, Block2, 0, 3); - world.setBlock(x + 15, y + 8 - yOffset, z + 5, Block1, 0, 3); - world.setBlock(x + 3, y + 8 - yOffset, z + 6, Block1, 0, 3); - world.setBlock(x + 4, y + 8 - yOffset, z + 6, Block1, 0, 3); - world.setBlock(x + 5, y + 8 - yOffset, z + 6, Blocks.chest, 2, 3); - if(world.getBlock(x + 5, y + 8 - yOffset, z + 6) == Blocks.chest) - { - WeightedRandomChestContent.generateChestContents(rand, ItemPool.getPool(ItemPoolsLegacy.POOL_EXPENSIVE), (TileEntityChest)world.getTileEntity(x + 5, y + 8 - yOffset, z + 6), 8); - } - world.setBlock(x + 6, y + 8 - yOffset, z + 6, Block1, 0, 3); - world.setBlock(x + 7, y + 8 - yOffset, z + 6, Block1, 0, 3); - world.setBlock(x + 14, y + 8 - yOffset, z + 6, Block1, 0, 3); - world.setBlock(x + 3, y + 8 - yOffset, z + 7, Block1, 0, 3); - world.setBlock(x + 4, y + 8 - yOffset, z + 7, Block1, 0, 3); - world.setBlock(x + 5, y + 8 - yOffset, z + 7, Block1, 0, 3); - world.setBlock(x + 6, y + 8 - yOffset, z + 7, Block1, 0, 3); - world.setBlock(x + 7, y + 8 - yOffset, z + 7, Block1, 0, 3); - world.setBlock(x + 3, y + 8 - yOffset, z + 8, Block1, 0, 3); - world.setBlock(x + 4, y + 8 - yOffset, z + 8, Block1, 0, 3); - world.setBlock(x + 5, y + 8 - yOffset, z + 8, Block1, 0, 3); - world.setBlock(x + 6, y + 8 - yOffset, z + 8, Block1, 0, 3); - world.setBlock(x + 7, y + 8 - yOffset, z + 8, Block1, 0, 3); - world.setBlock(x + 3, y + 8 - yOffset, z + 9, Block1, 0, 3); - world.setBlock(x + 4, y + 8 - yOffset, z + 9, ModBlocks.block_electrical_scrap, 0, 3); - world.setBlock(x + 5, y + 8 - yOffset, z + 9, ModBlocks.red_wire_coated, 0, 3); - world.setBlock(x + 6, y + 8 - yOffset, z + 9, ModBlocks.block_electrical_scrap, 0, 3); - world.setBlock(x + 7, y + 8 - yOffset, z + 9, Block1, 0, 3); - world.setBlock(x + 4, y + 8 - yOffset, z + 10, ModBlocks.block_electrical_scrap, 0, 3); - world.setBlock(x + 5, y + 8 - yOffset, z + 10, ModBlocks.red_wire_coated, 0, 3); - world.setBlock(x + 6, y + 8 - yOffset, z + 10, ModBlocks.block_electrical_scrap, 0, 3); - world.setBlock(x + 7, y + 8 - yOffset, z + 10, Block1, 0, 3); - world.setBlock(x + 5, y + 8 - yOffset, z + 11, Block4, 0, 3); - world.setBlock(x + 6, y + 8 - yOffset, z + 11, Block1, 0, 3); - world.setBlock(x + 7, y + 8 - yOffset, z + 11, Block1, 0, 3); - world.setBlock(x + 6, y + 8 - yOffset, z + 12, Block1, 0, 3); - world.setBlock(x + 14, y + 9 - yOffset, z + 4, Block1, 0, 3); - world.setBlock(x + 13, y + 9 - yOffset, z + 5, Block1, 0, 3); - world.setBlock(x + 14, y + 9 - yOffset, z + 5, Block2, 0, 3); - world.setBlock(x + 15, y + 9 - yOffset, z + 5, Block1, 0, 3); - world.setBlock(x + 4, y + 9 - yOffset, z + 6, Block1, 0, 3); - world.setBlock(x + 5, y + 9 - yOffset, z + 6, Block1, 0, 3); - world.setBlock(x + 6, y + 9 - yOffset, z + 6, Block1, 0, 3); - world.setBlock(x + 14, y + 9 - yOffset, z + 6, Block1, 0, 3); - world.setBlock(x + 4, y + 9 - yOffset, z + 7, Block1, 0, 3); - world.setBlock(x + 5, y + 9 - yOffset, z + 7, Block1, 0, 3); - world.setBlock(x + 6, y + 9 - yOffset, z + 7, Block1, 0, 3); - world.setBlock(x + 3, y + 9 - yOffset, z + 8, Block1, 0, 3); - world.setBlock(x + 4, y + 9 - yOffset, z + 8, Block1, 0, 3); - world.setBlock(x + 5, y + 9 - yOffset, z + 8, Block1, 0, 3); - world.setBlock(x + 6, y + 9 - yOffset, z + 8, Block1, 0, 3); - world.setBlock(x + 7, y + 9 - yOffset, z + 8, Block1, 0, 3); - world.setBlock(x + 4, y + 9 - yOffset, z + 9, Block1, 0, 3); - world.setBlock(x + 5, y + 9 - yOffset, z + 9, Block4, 0, 3); - world.setBlock(x + 6, y + 9 - yOffset, z + 9, Block1, 0, 3); - world.setBlock(x + 4, y + 9 - yOffset, z + 10, ModBlocks.block_electrical_scrap, 0, 3); - world.setBlock(x + 5, y + 9 - yOffset, z + 10, ModBlocks.red_wire_coated, 0, 3); - world.setBlock(x + 6, y + 9 - yOffset, z + 10, ModBlocks.block_electrical_scrap, 0, 3); - world.setBlock(x + 7, y + 9 - yOffset, z + 10, Block1, 0, 3); - world.setBlock(x + 5, y + 9 - yOffset, z + 11, ModBlocks.red_wire_coated, 0, 3); - world.setBlock(x + 6, y + 9 - yOffset, z + 11, Block1, 0, 3); - world.setBlock(x + 5, y + 9 - yOffset, z + 12, Block4, 0, 3); - world.setBlock(x + 6, y + 9 - yOffset, z + 12, Block1, 0, 3); - world.setBlock(x + 7, y + 9 - yOffset, z + 12, Block1, 0, 3); - world.setBlock(x + 5, y + 9 - yOffset, z + 13, Block1, 0, 3); - world.setBlock(x + 6, y + 9 - yOffset, z + 13, Block1, 0, 3); - world.setBlock(x + 14, y + 10 - yOffset, z + 5, Block2, 0, 3); - world.setBlock(x + 4, y + 10 - yOffset, z + 8, Block1, 0, 3); - world.setBlock(x + 5, y + 10 - yOffset, z + 8, Block1, 0, 3); - world.setBlock(x + 6, y + 10 - yOffset, z + 8, Block1, 0, 3); - world.setBlock(x + 5, y + 10 - yOffset, z + 9, Block1, 0, 3); - world.setBlock(x + 4, y + 10 - yOffset, z + 10, Block1, 0, 3); - world.setBlock(x + 5, y + 10 - yOffset, z + 10, Block4, 0, 3); - world.setBlock(x + 6, y + 10 - yOffset, z + 10, Block1, 0, 3); - world.setBlock(x + 4, y + 10 - yOffset, z + 11, Block1, 0, 3); - world.setBlock(x + 5, y + 10 - yOffset, z + 11, Block1, 0, 3); - world.setBlock(x + 6, y + 10 - yOffset, z + 11, Block1, 0, 3); - world.setBlock(x + 4, y + 10 - yOffset, z + 12, Block1, 0, 3); - world.setBlock(x + 5, y + 10 - yOffset, z + 12, ModBlocks.red_wire_coated, 0, 3); - world.setBlock(x + 6, y + 10 - yOffset, z + 12, Block1, 0, 3); - world.setBlock(x + 4, y + 10 - yOffset, z + 13, Block1, 0, 3); - world.setBlock(x + 5, y + 10 - yOffset, z + 13, ModBlocks.red_wire_coated, 0, 3); - world.setBlock(x + 6, y + 10 - yOffset, z + 13, Block1, 0, 3); - world.setBlock(x + 5, y + 10 - yOffset, z + 14, Block1, 0, 3); - world.setBlock(x + 5, y + 10 - yOffset, z + 15, Block1, 0, 3); - world.setBlock(x + 5, y + 10 - yOffset, z + 17, Block1, 0, 3); - world.setBlock(x + 5, y + 10 - yOffset, z + 18, Block1, 0, 3); - world.setBlock(x + 14, y + 11 - yOffset, z + 4, Block4, 0, 3); - world.setBlock(x + 12, y + 11 - yOffset, z + 5, Block4, 0, 3); - world.setBlock(x + 13, y + 11 - yOffset, z + 5, Block4, 0, 3); - world.setBlock(x + 14, y + 11 - yOffset, z + 5, Block2, 0, 3); - world.setBlock(x + 15, y + 11 - yOffset, z + 5, Block4, 0, 3); - world.setBlock(x + 16, y + 11 - yOffset, z + 5, Block4, 0, 3); - world.setBlock(x + 17, y + 11 - yOffset, z + 5, Block4, 0, 3); - world.setBlock(x + 14, y + 11 - yOffset, z + 6, Block4, 0, 3); - world.setBlock(x + 14, y + 11 - yOffset, z + 7, Block4, 0, 3); - world.setBlock(x + 5, y + 11 - yOffset, z + 10, Block1, 0, 3); - world.setBlock(x + 5, y + 11 - yOffset, z + 11, Block1, 0, 3); - world.setBlock(x + 4, y + 11 - yOffset, z + 12, Block1, 0, 3); - world.setBlock(x + 5, y + 11 - yOffset, z + 12, Block1, 0, 3); - world.setBlock(x + 6, y + 11 - yOffset, z + 12, Block1, 0, 3); - world.setBlock(x + 5, y + 11 - yOffset, z + 13, Block1, 0, 3); - world.setBlock(x + 4, y + 11 - yOffset, z + 14, Block1, 0, 3); - world.setBlock(x + 5, y + 11 - yOffset, z + 14, ModBlocks.red_wire_coated, 0, 3); - world.setBlock(x + 6, y + 11 - yOffset, z + 14, Block1, 0, 3); - world.setBlock(x + 4, y + 11 - yOffset, z + 15, Block1, 0, 3); - world.setBlock(x + 5, y + 11 - yOffset, z + 15, ModBlocks.red_wire_coated, 0, 3); - world.setBlock(x + 6, y + 11 - yOffset, z + 15, Block1, 0, 3); - world.setBlock(x + 5, y + 11 - yOffset, z + 16, Block1, 0, 3); - world.setBlock(x + 5, y + 11 - yOffset, z + 17, Block1, 0, 3); - world.setBlock(x + 5, y + 11 - yOffset, z + 18, Block1, 0, 3); - world.setBlock(x + 5, y + 12 - yOffset, z + 14, Block1, 0, 3); - world.setBlock(x + 3, y + 12 - yOffset, z + 16, Block1, 0, 3); - world.setBlock(x + 4, y + 12 - yOffset, z + 16, Block1, 0, 3); - world.setBlock(x + 5, y + 12 - yOffset, z + 16, ModBlocks.red_wire_coated, 0, 3); - world.setBlock(x + 6, y + 12 - yOffset, z + 16, Block1, 0, 3); - world.setBlock(x + 7, y + 12 - yOffset, z + 16, Block1, 0, 3); - world.setBlock(x + 8, y + 12 - yOffset, z + 16, Block1, 0, 3); - world.setBlock(x + 9, y + 12 - yOffset, z + 16, Block1, 0, 3); - world.setBlock(x + 4, y + 12 - yOffset, z + 17, Block1, 0, 3); - world.setBlock(x + 5, y + 12 - yOffset, z + 17, ModBlocks.red_wire_coated, 0, 3); - world.setBlock(x + 6, y + 12 - yOffset, z + 17, Block1, 0, 3); - world.setBlock(x + 7, y + 12 - yOffset, z + 17, Block1, 0, 3); - world.setBlock(x + 8, y + 12 - yOffset, z + 17, Block1, 0, 3); - world.setBlock(x + 9, y + 12 - yOffset, z + 17, Block1, 0, 3); - world.setBlock(x + 10, y + 12 - yOffset, z + 17, Block1, 0, 3); - world.setBlock(x + 5, y + 13 - yOffset, z + 17, Block1, 0, 3); - - generate_r02_last(world, rand, x, y, z, yOffset); - return true; - - } - public boolean generate_r02_last(World world, Random rand, int x, int y, int z, int yOffset) - { - - world.setBlock(x + 4, y + 1 - yOffset, z + 1, Blocks.lever, 3, 3); - world.setBlock(x + 6, y + 1 - yOffset, z + 1, Blocks.lever, 3, 3); - if(GeneralConfig.enableDebugMode) - System.out.print("[Debug] Successfully spawned crashed Vertibird at " + x + " " + y +" " + z + "\n"); - return true; - - } - -} \ No newline at end of file diff --git a/src/main/java/com/hbm/world/dungeon/Vertibird.java b/src/main/java/com/hbm/world/dungeon/Vertibird.java deleted file mode 100644 index 67b34f015..000000000 --- a/src/main/java/com/hbm/world/dungeon/Vertibird.java +++ /dev/null @@ -1,514 +0,0 @@ -//Schematic to java Structure by jajo_11 | inspired by "MITHION'S .SCHEMATIC TO JAVA CONVERTINGTOOL" - -package com.hbm.world.dungeon; - -import java.util.Random; - -import com.hbm.blocks.ModBlocks; -import com.hbm.config.GeneralConfig; -import com.hbm.itempool.ItemPool; -import com.hbm.itempool.ItemPoolsLegacy; -import net.minecraft.block.Block; -import net.minecraft.block.material.Material; -import net.minecraft.init.Blocks; -import net.minecraft.tileentity.TileEntityChest; -import net.minecraft.util.WeightedRandomChestContent; -import net.minecraft.world.World; -import net.minecraft.world.gen.feature.WorldGenerator; - -public class Vertibird extends WorldGenerator -{ - Block Block2 = ModBlocks.deco_steel; - Block Block1 = ModBlocks.deco_tungsten; - Block Block4 = ModBlocks.reinforced_glass; - Block Block3 = ModBlocks.deco_titanium; - - protected Block[] GetValidSpawnBlocks() - { - return new Block[] - { - Blocks.sand, - Blocks.sandstone, - }; - } - - public boolean LocationIsValidSpawn(World world, int x, int y, int z) - { - - Block checkBlock = world.getBlock(x, y - 1, z); - Block blockAbove = world.getBlock(x, y , z); - Block blockBelow = world.getBlock(x, y - 2, z); - - for (Block i : GetValidSpawnBlocks()) - { - if (blockAbove != Blocks.air) - { - return false; - } - if (checkBlock == i) - { - return true; - } - else if (checkBlock == Blocks.snow_layer && blockBelow == i) - { - return true; - } - else if (checkBlock.getMaterial() == Material.plants && blockBelow == i) - { - return true; - } - } - return false; - } - - @Override - public boolean generate(World world, Random rand, int x, int y, int z) - { - int i = rand.nextInt(1); - - if(i == 0) - { - generate_r0(world, rand, x, y, z); - } - - return true; - - } - - public boolean generate_r0(World world, Random rand, int x, int y, int z) - { - int yOffset = 3 + rand.nextInt(4); - - if(!LocationIsValidSpawn(world, x + 13, y, z + 10)) - { - return false; - } - - world.setBlock(x + 13, y + 0 - yOffset, z + 2, Block1, 0, 3); - world.setBlock(x + 12, y + 0 - yOffset, z + 7, Block1, 0, 3); - world.setBlock(x + 14, y + 0 - yOffset, z + 7, Block1, 0, 3); - world.setBlock(x + 13, y + 0 - yOffset, z + 9, Block1, 0, 3); - world.setBlock(x + 12, y + 1 - yOffset, z + 1, Block2, 0, 3); - world.setBlock(x + 13, y + 1 - yOffset, z + 1, Block2, 0, 3); - world.setBlock(x + 14, y + 1 - yOffset, z + 1, Block2, 0, 3); - world.setBlock(x + 12, y + 1 - yOffset, z + 2, Block2, 0, 3); - world.setBlock(x + 13, y + 1 - yOffset, z + 2, Block2, 0, 3); - world.setBlock(x + 14, y + 1 - yOffset, z + 2, Block2, 0, 3); - world.setBlock(x + 11, y + 1 - yOffset, z + 3, Block1, 0, 3); - world.setBlock(x + 12, y + 1 - yOffset, z + 3, Block2, 0, 3); - world.setBlock(x + 13, y + 1 - yOffset, z + 3, Block2, 0, 3); - world.setBlock(x + 14, y + 1 - yOffset, z + 3, Block2, 0, 3); - world.setBlock(x + 15, y + 1 - yOffset, z + 3, Block1, 0, 3); - world.setBlock(x + 11, y + 1 - yOffset, z + 4, Block1, 0, 3); - world.setBlock(x + 12, y + 1 - yOffset, z + 4, Block2, 0, 3); - world.setBlock(x + 13, y + 1 - yOffset, z + 4, Block2, 0, 3); - world.setBlock(x + 14, y + 1 - yOffset, z + 4, Block2, 0, 3); - world.setBlock(x + 15, y + 1 - yOffset, z + 4, Block1, 0, 3); - world.setBlock(x + 11, y + 1 - yOffset, z + 5, Block1, 0, 3); - world.setBlock(x + 12, y + 1 - yOffset, z + 5, Block2, 0, 3); - world.setBlock(x + 13, y + 1 - yOffset, z + 5, Block2, 0, 3); - world.setBlock(x + 14, y + 1 - yOffset, z + 5, Block2, 0, 3); - world.setBlock(x + 15, y + 1 - yOffset, z + 5, Block1, 0, 3); - world.setBlock(x + 12, y + 1 - yOffset, z + 6, Block2, 0, 3); - world.setBlock(x + 13, y + 1 - yOffset, z + 6, Block2, 0, 3); - world.setBlock(x + 14, y + 1 - yOffset, z + 6, Block2, 0, 3); - world.setBlock(x + 12, y + 1 - yOffset, z + 7, Block2, 0, 3); - world.setBlock(x + 13, y + 1 - yOffset, z + 7, Block2, 0, 3); - world.setBlock(x + 14, y + 1 - yOffset, z + 7, Block2, 0, 3); - world.setBlock(x + 12, y + 1 - yOffset, z + 8, Block2, 0, 3); - world.setBlock(x + 13, y + 1 - yOffset, z + 8, Block2, 0, 3); - world.setBlock(x + 14, y + 1 - yOffset, z + 8, Block2, 0, 3); - world.setBlock(x + 12, y + 1 - yOffset, z + 9, Block2, 0, 3); - world.setBlock(x + 13, y + 1 - yOffset, z + 9, Block2, 0, 3); - world.setBlock(x + 14, y + 1 - yOffset, z + 9, Block2, 0, 3); - world.setBlock(x + 12, y + 2 - yOffset, z + 0, Block2, 0, 3); - world.setBlock(x + 13, y + 2 - yOffset, z + 0, Block2, 0, 3); - world.setBlock(x + 14, y + 2 - yOffset, z + 0, Block2, 0, 3); - world.setBlock(x + 11, y + 2 - yOffset, z + 1, Block2, 0, 3); - world.setBlock(x + 15, y + 2 - yOffset, z + 1, Block2, 0, 3); - world.setBlock(x + 11, y + 2 - yOffset, z + 2, Block2, 0, 3); - world.setBlock(x + 12, y + 2 - yOffset, z + 2, Blocks.stone_stairs, 2, 3); - world.setBlock(x + 14, y + 2 - yOffset, z + 2, Blocks.stone_stairs, 2, 3); - world.setBlock(x + 15, y + 2 - yOffset, z + 2, Block2, 0, 3); - world.setBlock(x + 15, y + 2 - yOffset, z + 3, Block3, 0, 3); - world.setBlock(x + 15, y + 2 - yOffset, z + 4, Block3, 0, 3); - world.setBlock(x + 10, y + 2 - yOffset, z + 5, Block3, 0, 3); - world.setBlock(x + 15, y + 2 - yOffset, z + 5, Block3, 0, 3); - world.setBlock(x + 10, y + 2 - yOffset, z + 6, Block3, 0, 3); - world.setBlock(x + 11, y + 2 - yOffset, z + 6, Block2, 0, 3); - world.setBlock(x + 15, y + 2 - yOffset, z + 6, Block2, 0, 3); - world.setBlock(x + 10, y + 2 - yOffset, z + 7, Block3, 0, 3); - world.setBlock(x + 11, y + 2 - yOffset, z + 7, Block2, 0, 3); - world.setBlock(x + 14, y + 2 - yOffset, z + 7, Blocks.chest, 2, 3); - if(world.getBlock(x + 14, y + 2 - yOffset, z + 7) == Blocks.chest) - { - WeightedRandomChestContent.generateChestContents(rand, ItemPool.getPool(ItemPoolsLegacy.POOL_VERTIBIRD), (TileEntityChest)world.getTileEntity(x + 14, y + 2 - yOffset, z + 7), 8); - } - world.setBlock(x + 15, y + 2 - yOffset, z + 7, Block2, 0, 3); - world.setBlock(x + 12, y + 2 - yOffset, z + 8, Block2, 0, 3); - world.setBlock(x + 13, y + 2 - yOffset, z + 8, Block2, 0, 3); - world.setBlock(x + 14, y + 2 - yOffset, z + 8, Block2, 0, 3); - world.setBlock(x + 12, y + 2 - yOffset, z + 9, Block2, 0, 3); - world.setBlock(x + 13, y + 2 - yOffset, z + 9, Block3, 0, 3); - world.setBlock(x + 14, y + 2 - yOffset, z + 9, Block2, 0, 3); - world.setBlock(x + 12, y + 2 - yOffset, z + 10, Block2, 0, 3); - world.setBlock(x + 13, y + 2 - yOffset, z + 10, Block2, 0, 3); - world.setBlock(x + 14, y + 2 - yOffset, z + 10, Block2, 0, 3); - world.setBlock(x + 12, y + 2 - yOffset, z + 11, Block2, 0, 3); - world.setBlock(x + 13, y + 2 - yOffset, z + 11, Block2, 0, 3); - world.setBlock(x + 14, y + 2 - yOffset, z + 11, Block2, 0, 3); - world.setBlock(x + 13, y + 2 - yOffset, z + 18, Block2, 0, 3); - world.setBlock(x + 12, y + 3 - yOffset, z + 0, Block4, 0, 3); - world.setBlock(x + 13, y + 3 - yOffset, z + 0, Block4, 0, 3); - world.setBlock(x + 14, y + 3 - yOffset, z + 0, Block4, 0, 3); - world.setBlock(x + 11, y + 3 - yOffset, z + 1, Block4, 0, 3); - world.setBlock(x + 15, y + 3 - yOffset, z + 1, Block4, 0, 3); - world.setBlock(x + 11, y + 3 - yOffset, z + 2, Block2, 0, 3); - world.setBlock(x + 15, y + 3 - yOffset, z + 2, Block2, 0, 3); - world.setBlock(x + 11, y + 3 - yOffset, z + 3, Block2, 0, 3); - world.setBlock(x + 15, y + 3 - yOffset, z + 3, Block2, 0, 3); - world.setBlock(x + 15, y + 3 - yOffset, z + 4, Block3, 0, 3); - world.setBlock(x + 15, y + 3 - yOffset, z + 5, Block3, 0, 3); - world.setBlock(x + 10, y + 3 - yOffset, z + 6, Block3, 0, 3); - world.setBlock(x + 11, y + 3 - yOffset, z + 6, Block2, 0, 3); - world.setBlock(x + 15, y + 3 - yOffset, z + 6, Block2, 0, 3); - world.setBlock(x + 10, y + 3 - yOffset, z + 7, Block3, 0, 3); - world.setBlock(x + 11, y + 3 - yOffset, z + 7, Block2, 0, 3); - world.setBlock(x + 15, y + 3 - yOffset, z + 7, Block2, 0, 3); - world.setBlock(x + 12, y + 3 - yOffset, z + 8, Block2, 0, 3); - world.setBlock(x + 13, y + 3 - yOffset, z + 8, ModBlocks.machine_battery, 2, 3); - world.setBlock(x + 14, y + 3 - yOffset, z + 8, Block2, 0, 3); - world.setBlock(x + 12, y + 3 - yOffset, z + 9, Block2, 0, 3); - world.setBlock(x + 13, y + 3 - yOffset, z + 9, ModBlocks.red_wire_coated, 0, 3); - world.setBlock(x + 14, y + 3 - yOffset, z + 9, Block2, 0, 3); - world.setBlock(x + 12, y + 3 - yOffset, z + 10, Block2, 0, 3); - world.setBlock(x + 13, y + 3 - yOffset, z + 10, Block3, 0, 3); - world.setBlock(x + 14, y + 3 - yOffset, z + 10, Block2, 0, 3); - world.setBlock(x + 12, y + 3 - yOffset, z + 11, Block2, 0, 3); - world.setBlock(x + 13, y + 3 - yOffset, z + 11, Block3, 0, 3); - world.setBlock(x + 14, y + 3 - yOffset, z + 11, Block2, 0, 3); - world.setBlock(x + 12, y + 3 - yOffset, z + 12, Block2, 0, 3); - world.setBlock(x + 13, y + 3 - yOffset, z + 12, Block2, 0, 3); - world.setBlock(x + 14, y + 3 - yOffset, z + 12, Block2, 0, 3); - world.setBlock(x + 13, y + 3 - yOffset, z + 17, Block2, 0, 3); - world.setBlock(x + 13, y + 3 - yOffset, z + 18, Block2, 0, 3); - world.setBlock(x + 12, y + 4 - yOffset, z + 0, Block2, 0, 3); - world.setBlock(x + 13, y + 4 - yOffset, z + 0, Block2, 0, 3); - world.setBlock(x + 14, y + 4 - yOffset, z + 0, Block2, 0, 3); - world.setBlock(x + 11, y + 4 - yOffset, z + 1, Block4, 0, 3); - world.setBlock(x + 12, y + 4 - yOffset, z + 1, Block2, 0, 3); - world.setBlock(x + 13, y + 4 - yOffset, z + 1, Block2, 0, 3); - world.setBlock(x + 14, y + 4 - yOffset, z + 1, Block2, 0, 3); - world.setBlock(x + 15, y + 4 - yOffset, z + 1, Block4, 0, 3); - world.setBlock(x + 11, y + 4 - yOffset, z + 2, Block4, 0, 3); - world.setBlock(x + 15, y + 4 - yOffset, z + 2, Block4, 0, 3); - world.setBlock(x + 11, y + 4 - yOffset, z + 3, Block2, 0, 3); - world.setBlock(x + 15, y + 4 - yOffset, z + 3, Block2, 0, 3); - world.setBlock(x + 11, y + 4 - yOffset, z + 4, Block2, 0, 3); - world.setBlock(x + 15, y + 4 - yOffset, z + 4, Block2, 0, 3); - world.setBlock(x + 4, y + 4 - yOffset, z + 5, Block1, 0, 3); - world.setBlock(x + 11, y + 4 - yOffset, z + 5, Block2, 0, 3); - world.setBlock(x + 15, y + 4 - yOffset, z + 5, Block2, 0, 3); - world.setBlock(x + 22, y + 4 - yOffset, z + 5, Block1, 0, 3); - world.setBlock(x + 11, y + 4 - yOffset, z + 6, Block2, 0, 3); - world.setBlock(x + 12, y + 4 - yOffset, z + 6, Block2, 0, 3); - world.setBlock(x + 14, y + 4 - yOffset, z + 6, Block2, 0, 3); - world.setBlock(x + 15, y + 4 - yOffset, z + 6, Block2, 0, 3); - world.setBlock(x + 11, y + 4 - yOffset, z + 7, Block2, 0, 3); - world.setBlock(x + 12, y + 4 - yOffset, z + 7, Block2, 0, 3); - world.setBlock(x + 13, y + 4 - yOffset, z + 7, Block2, 0, 3); - world.setBlock(x + 14, y + 4 - yOffset, z + 7, Block2, 0, 3); - world.setBlock(x + 15, y + 4 - yOffset, z + 7, Block2, 0, 3); - world.setBlock(x + 11, y + 4 - yOffset, z + 8, Block2, 0, 3); - world.setBlock(x + 12, y + 4 - yOffset, z + 8, Block2, 0, 3); - world.setBlock(x + 13, y + 4 - yOffset, z + 8, Block2, 0, 3); - world.setBlock(x + 14, y + 4 - yOffset, z + 8, Block2, 0, 3); - world.setBlock(x + 15, y + 4 - yOffset, z + 8, Block2, 0, 3); - world.setBlock(x + 11, y + 4 - yOffset, z + 9, Block2, 0, 3); - world.setBlock(x + 12, y + 4 - yOffset, z + 9, ModBlocks.block_electrical_scrap, 0, 3); - world.setBlock(x + 13, y + 4 - yOffset, z + 9, ModBlocks.red_wire_coated, 0, 3); - world.setBlock(x + 14, y + 4 - yOffset, z + 9, ModBlocks.block_electrical_scrap, 0, 3); - world.setBlock(x + 15, y + 4 - yOffset, z + 9, Block2, 0, 3); - world.setBlock(x + 11, y + 4 - yOffset, z + 10, Block2, 0, 3); - world.setBlock(x + 12, y + 4 - yOffset, z + 10, ModBlocks.block_electrical_scrap, 0, 3); - world.setBlock(x + 13, y + 4 - yOffset, z + 10, ModBlocks.red_wire_coated, 0, 3); - world.setBlock(x + 14, y + 4 - yOffset, z + 10, ModBlocks.block_electrical_scrap, 0, 3); - world.setBlock(x + 15, y + 4 - yOffset, z + 10, Block2, 0, 3); - world.setBlock(x + 11, y + 4 - yOffset, z + 11, Block2, 0, 3); - world.setBlock(x + 12, y + 4 - yOffset, z + 11, Block2, 0, 3); - world.setBlock(x + 13, y + 4 - yOffset, z + 11, Block3, 0, 3); - world.setBlock(x + 14, y + 4 - yOffset, z + 11, Block2, 0, 3); - world.setBlock(x + 15, y + 4 - yOffset, z + 11, Block2, 0, 3); - world.setBlock(x + 11, y + 4 - yOffset, z + 12, Block2, 0, 3); - world.setBlock(x + 12, y + 4 - yOffset, z + 12, Block2, 0, 3); - world.setBlock(x + 13, y + 4 - yOffset, z + 12, Block3, 0, 3); - world.setBlock(x + 14, y + 4 - yOffset, z + 12, Block2, 0, 3); - world.setBlock(x + 15, y + 4 - yOffset, z + 12, Block2, 0, 3); - world.setBlock(x + 12, y + 4 - yOffset, z + 13, Block2, 0, 3); - world.setBlock(x + 13, y + 4 - yOffset, z + 13, Block2, 0, 3); - world.setBlock(x + 14, y + 4 - yOffset, z + 13, Block2, 0, 3); - world.setBlock(x + 13, y + 4 - yOffset, z + 14, Block2, 0, 3); - world.setBlock(x + 13, y + 4 - yOffset, z + 15, Block2, 0, 3); - world.setBlock(x + 13, y + 4 - yOffset, z + 16, Block2, 0, 3); - world.setBlock(x + 13, y + 4 - yOffset, z + 17, Block2, 0, 3); - world.setBlock(x + 13, y + 4 - yOffset, z + 18, Block2, 0, 3); - world.setBlock(x + 12, y + 5 - yOffset, z + 1, Block2, 0, 3); - world.setBlock(x + 13, y + 5 - yOffset, z + 1, Block2, 0, 3); - world.setBlock(x + 14, y + 5 - yOffset, z + 1, Block2, 0, 3); - world.setBlock(x + 12, y + 5 - yOffset, z + 2, Block2, 0, 3); - world.setBlock(x + 13, y + 5 - yOffset, z + 2, Block2, 0, 3); - world.setBlock(x + 14, y + 5 - yOffset, z + 2, Block2, 0, 3); - world.setBlock(x + 11, y + 5 - yOffset, z + 3, Block2, 0, 3); - world.setBlock(x + 12, y + 5 - yOffset, z + 3, Block2, 0, 3); - world.setBlock(x + 13, y + 5 - yOffset, z + 3, Block2, 0, 3); - world.setBlock(x + 14, y + 5 - yOffset, z + 3, Block2, 0, 3); - world.setBlock(x + 15, y + 5 - yOffset, z + 3, Block2, 0, 3); - world.setBlock(x + 4, y + 5 - yOffset, z + 4, Block2, 0, 3); - world.setBlock(x + 11, y + 5 - yOffset, z + 4, Block2, 0, 3); - world.setBlock(x + 12, y + 5 - yOffset, z + 4, Block2, 0, 3); - world.setBlock(x + 13, y + 5 - yOffset, z + 4, Block2, 0, 3); - world.setBlock(x + 14, y + 5 - yOffset, z + 4, Block2, 0, 3); - world.setBlock(x + 15, y + 5 - yOffset, z + 4, Block2, 0, 3); - world.setBlock(x + 22, y + 5 - yOffset, z + 4, Block2, 0, 3); - world.setBlock(x + 3, y + 5 - yOffset, z + 5, Block2, 0, 3); - world.setBlock(x + 4, y + 5 - yOffset, z + 5, Block1, 0, 3); - world.setBlock(x + 5, y + 5 - yOffset, z + 5, Block2, 0, 3); - world.setBlock(x + 8, y + 5 - yOffset, z + 5, Block2, 0, 3); - world.setBlock(x + 9, y + 5 - yOffset, z + 5, Block2, 0, 3); - world.setBlock(x + 10, y + 5 - yOffset, z + 5, Block2, 0, 3); - world.setBlock(x + 11, y + 5 - yOffset, z + 5, Block2, 0, 3); - world.setBlock(x + 12, y + 5 - yOffset, z + 5, Block2, 0, 3); - world.setBlock(x + 13, y + 5 - yOffset, z + 5, Block2, 0, 3); - world.setBlock(x + 14, y + 5 - yOffset, z + 5, Block2, 0, 3); - world.setBlock(x + 15, y + 5 - yOffset, z + 5, Block2, 0, 3); - world.setBlock(x + 16, y + 5 - yOffset, z + 5, Block2, 0, 3); - world.setBlock(x + 17, y + 5 - yOffset, z + 5, Block2, 0, 3); - world.setBlock(x + 18, y + 5 - yOffset, z + 5, Block2, 0, 3); - world.setBlock(x + 21, y + 5 - yOffset, z + 5, Block2, 0, 3); - world.setBlock(x + 22, y + 5 - yOffset, z + 5, Block1, 0, 3); - world.setBlock(x + 23, y + 5 - yOffset, z + 5, Block2, 0, 3); - world.setBlock(x + 4, y + 5 - yOffset, z + 6, Block2, 0, 3); - world.setBlock(x + 11, y + 5 - yOffset, z + 6, Block2, 0, 3); - world.setBlock(x + 12, y + 5 - yOffset, z + 6, Block2, 0, 3); - world.setBlock(x + 13, y + 5 - yOffset, z + 6, Block2, 0, 3); - world.setBlock(x + 14, y + 5 - yOffset, z + 6, Block2, 0, 3); - world.setBlock(x + 15, y + 5 - yOffset, z + 6, Block2, 0, 3); - world.setBlock(x + 22, y + 5 - yOffset, z + 6, Block2, 0, 3); - world.setBlock(x + 11, y + 5 - yOffset, z + 7, Block2, 0, 3); - world.setBlock(x + 12, y + 5 - yOffset, z + 7, Block2, 0, 3); - world.setBlock(x + 13, y + 5 - yOffset, z + 7, Block2, 0, 3); - world.setBlock(x + 14, y + 5 - yOffset, z + 7, Block2, 0, 3); - world.setBlock(x + 15, y + 5 - yOffset, z + 7, Block2, 0, 3); - world.setBlock(x + 11, y + 5 - yOffset, z + 8, Block2, 0, 3); - world.setBlock(x + 12, y + 5 - yOffset, z + 8, Block2, 0, 3); - world.setBlock(x + 13, y + 5 - yOffset, z + 8, Block2, 0, 3); - world.setBlock(x + 14, y + 5 - yOffset, z + 8, Block2, 0, 3); - world.setBlock(x + 15, y + 5 - yOffset, z + 8, Block2, 0, 3); - world.setBlock(x + 11, y + 5 - yOffset, z + 9, Block2, 0, 3); - world.setBlock(x + 12, y + 5 - yOffset, z + 9, ModBlocks.block_electrical_scrap, 0, 3); - world.setBlock(x + 13, y + 5 - yOffset, z + 9, ModBlocks.red_wire_coated, 0, 3); - world.setBlock(x + 14, y + 5 - yOffset, z + 9, ModBlocks.block_electrical_scrap, 0, 3); - world.setBlock(x + 15, y + 5 - yOffset, z + 9, Block2, 0, 3); - world.setBlock(x + 11, y + 5 - yOffset, z + 10, Block2, 0, 3); - world.setBlock(x + 12, y + 5 - yOffset, z + 10, ModBlocks.block_electrical_scrap, 0, 3); - world.setBlock(x + 13, y + 5 - yOffset, z + 10, ModBlocks.red_wire_coated, 0, 3); - world.setBlock(x + 14, y + 5 - yOffset, z + 10, ModBlocks.block_electrical_scrap, 0, 3); - world.setBlock(x + 15, y + 5 - yOffset, z + 10, Block2, 0, 3); - world.setBlock(x + 12, y + 5 - yOffset, z + 11, Block2, 0, 3); - world.setBlock(x + 13, y + 5 - yOffset, z + 11, ModBlocks.red_wire_coated, 0, 3); - world.setBlock(x + 14, y + 5 - yOffset, z + 11, Block2, 0, 3); - world.setBlock(x + 12, y + 5 - yOffset, z + 12, Block2, 0, 3); - world.setBlock(x + 13, y + 5 - yOffset, z + 12, ModBlocks.red_wire_coated, 0, 3); - world.setBlock(x + 14, y + 5 - yOffset, z + 12, Block2, 0, 3); - world.setBlock(x + 12, y + 5 - yOffset, z + 13, Block2, 0, 3); - world.setBlock(x + 13, y + 5 - yOffset, z + 13, ModBlocks.red_wire_coated, 0, 3); - world.setBlock(x + 14, y + 5 - yOffset, z + 13, Block2, 0, 3); - world.setBlock(x + 12, y + 5 - yOffset, z + 14, Block2, 0, 3); - world.setBlock(x + 13, y + 5 - yOffset, z + 14, ModBlocks.red_wire_coated, 0, 3); - world.setBlock(x + 14, y + 5 - yOffset, z + 14, Block2, 0, 3); - world.setBlock(x + 12, y + 5 - yOffset, z + 15, Block2, 0, 3); - world.setBlock(x + 13, y + 5 - yOffset, z + 15, ModBlocks.red_wire_coated, 0, 3); - world.setBlock(x + 14, y + 5 - yOffset, z + 15, Block2, 0, 3); - world.setBlock(x + 9, y + 5 - yOffset, z + 16, Block2, 0, 3); - world.setBlock(x + 10, y + 5 - yOffset, z + 16, Block2, 0, 3); - world.setBlock(x + 11, y + 5 - yOffset, z + 16, Block2, 0, 3); - world.setBlock(x + 12, y + 5 - yOffset, z + 16, Block2, 0, 3); - world.setBlock(x + 13, y + 5 - yOffset, z + 16, ModBlocks.red_wire_coated, 0, 3); - world.setBlock(x + 14, y + 5 - yOffset, z + 16, Block2, 0, 3); - world.setBlock(x + 15, y + 5 - yOffset, z + 16, Block2, 0, 3); - world.setBlock(x + 16, y + 5 - yOffset, z + 16, Block2, 0, 3); - world.setBlock(x + 17, y + 5 - yOffset, z + 16, Block2, 0, 3); - world.setBlock(x + 8, y + 5 - yOffset, z + 17, Block2, 0, 3); - world.setBlock(x + 9, y + 5 - yOffset, z + 17, Block2, 0, 3); - world.setBlock(x + 10, y + 5 - yOffset, z + 17, Block2, 0, 3); - world.setBlock(x + 11, y + 5 - yOffset, z + 17, Block2, 0, 3); - world.setBlock(x + 12, y + 5 - yOffset, z + 17, Block2, 0, 3); - world.setBlock(x + 13, y + 5 - yOffset, z + 17, ModBlocks.red_wire_coated, 0, 3); - world.setBlock(x + 14, y + 5 - yOffset, z + 17, Block2, 0, 3); - world.setBlock(x + 15, y + 5 - yOffset, z + 17, Block2, 0, 3); - world.setBlock(x + 16, y + 5 - yOffset, z + 17, Block2, 0, 3); - world.setBlock(x + 17, y + 5 - yOffset, z + 17, Block2, 0, 3); - world.setBlock(x + 18, y + 5 - yOffset, z + 17, Block2, 0, 3); - world.setBlock(x + 12, y + 5 - yOffset, z + 18, Block2, 0, 3); - world.setBlock(x + 13, y + 5 - yOffset, z + 18, ModBlocks.red_wire_coated, 0, 3); - world.setBlock(x + 14, y + 5 - yOffset, z + 18, Block2, 0, 3); - world.setBlock(x + 13, y + 5 - yOffset, z + 19, Block1, 0, 3); - world.setBlock(x + 12, y + 6 - yOffset, z + 1, Block1, 0, 3); - world.setBlock(x + 14, y + 6 - yOffset, z + 1, Block1, 0, 3); - world.setBlock(x + 12, y + 6 - yOffset, z + 3, Block2, 0, 3); - world.setBlock(x + 13, y + 6 - yOffset, z + 3, Block2, 0, 3); - world.setBlock(x + 14, y + 6 - yOffset, z + 3, Block2, 0, 3); - world.setBlock(x + 4, y + 6 - yOffset, z + 4, Block2, 0, 3); - world.setBlock(x + 11, y + 6 - yOffset, z + 4, Block2, 0, 3); - world.setBlock(x + 12, y + 6 - yOffset, z + 4, Block2, 0, 3); - world.setBlock(x + 13, y + 6 - yOffset, z + 4, Block2, 0, 3); - world.setBlock(x + 14, y + 6 - yOffset, z + 4, Block2, 0, 3); - world.setBlock(x + 15, y + 6 - yOffset, z + 4, Block2, 0, 3); - world.setBlock(x + 22, y + 6 - yOffset, z + 4, Block2, 0, 3); - world.setBlock(x + 3, y + 6 - yOffset, z + 5, Block2, 0, 3); - world.setBlock(x + 4, y + 6 - yOffset, z + 5, Block1, 0, 3); - world.setBlock(x + 5, y + 6 - yOffset, z + 5, Block2, 0, 3); - world.setBlock(x + 6, y + 6 - yOffset, z + 5, Block2, 0, 3); - world.setBlock(x + 7, y + 6 - yOffset, z + 5, Block2, 0, 3); - world.setBlock(x + 8, y + 6 - yOffset, z + 5, Block2, 0, 3); - world.setBlock(x + 9, y + 6 - yOffset, z + 5, Block2, 0, 3); - world.setBlock(x + 10, y + 6 - yOffset, z + 5, Block2, 0, 3); - world.setBlock(x + 11, y + 6 - yOffset, z + 5, Block2, 0, 3); - world.setBlock(x + 12, y + 6 - yOffset, z + 5, Block2, 0, 3); - world.setBlock(x + 13, y + 6 - yOffset, z + 5, Block2, 0, 3); - world.setBlock(x + 14, y + 6 - yOffset, z + 5, Block2, 0, 3); - world.setBlock(x + 15, y + 6 - yOffset, z + 5, Block2, 0, 3); - world.setBlock(x + 16, y + 6 - yOffset, z + 5, Block2, 0, 3); - world.setBlock(x + 17, y + 6 - yOffset, z + 5, Block2, 0, 3); - world.setBlock(x + 18, y + 6 - yOffset, z + 5, Block2, 0, 3); - world.setBlock(x + 19, y + 6 - yOffset, z + 5, Block2, 0, 3); - world.setBlock(x + 20, y + 6 - yOffset, z + 5, Block2, 0, 3); - world.setBlock(x + 21, y + 6 - yOffset, z + 5, Block2, 0, 3); - world.setBlock(x + 22, y + 6 - yOffset, z + 5, Block1, 0, 3); - world.setBlock(x + 23, y + 6 - yOffset, z + 5, Block2, 0, 3); - world.setBlock(x + 4, y + 6 - yOffset, z + 6, Block2, 0, 3); - world.setBlock(x + 11, y + 6 - yOffset, z + 6, Block2, 0, 3); - world.setBlock(x + 12, y + 6 - yOffset, z + 6, Block2, 0, 3); - world.setBlock(x + 13, y + 6 - yOffset, z + 6, Blocks.chest, 2, 3); - if(world.getBlock(x + 13, y + 6 - yOffset, z + 6) == Blocks.chest) - { - WeightedRandomChestContent.generateChestContents(rand, ItemPool.getPool(ItemPoolsLegacy.POOL_VERTIBIRD), (TileEntityChest)world.getTileEntity(x + 13, y + 6 - yOffset, z + 6), 8); - } - world.setBlock(x + 14, y + 6 - yOffset, z + 6, Block2, 0, 3); - world.setBlock(x + 15, y + 6 - yOffset, z + 6, Block2, 0, 3); - world.setBlock(x + 22, y + 6 - yOffset, z + 6, Block2, 0, 3); - world.setBlock(x + 11, y + 6 - yOffset, z + 7, Block2, 0, 3); - world.setBlock(x + 12, y + 6 - yOffset, z + 7, Block2, 0, 3); - world.setBlock(x + 13, y + 6 - yOffset, z + 7, Block2, 0, 3); - world.setBlock(x + 14, y + 6 - yOffset, z + 7, Block2, 0, 3); - world.setBlock(x + 15, y + 6 - yOffset, z + 7, Block2, 0, 3); - world.setBlock(x + 11, y + 6 - yOffset, z + 8, Block2, 0, 3); - world.setBlock(x + 12, y + 6 - yOffset, z + 8, Block2, 0, 3); - world.setBlock(x + 13, y + 6 - yOffset, z + 8, Block2, 0, 3); - world.setBlock(x + 14, y + 6 - yOffset, z + 8, Block2, 0, 3); - world.setBlock(x + 15, y + 6 - yOffset, z + 8, Block2, 0, 3); - world.setBlock(x + 12, y + 6 - yOffset, z + 9, Block2, 0, 3); - world.setBlock(x + 13, y + 6 - yOffset, z + 9, Block3, 0, 3); - world.setBlock(x + 14, y + 6 - yOffset, z + 9, Block2, 0, 3); - world.setBlock(x + 12, y + 6 - yOffset, z + 10, Block2, 0, 3); - world.setBlock(x + 13, y + 6 - yOffset, z + 10, Block3, 0, 3); - world.setBlock(x + 14, y + 6 - yOffset, z + 10, Block2, 0, 3); - world.setBlock(x + 12, y + 6 - yOffset, z + 11, Block2, 0, 3); - world.setBlock(x + 13, y + 6 - yOffset, z + 11, Block2, 0, 3); - world.setBlock(x + 14, y + 6 - yOffset, z + 11, Block2, 0, 3); - world.setBlock(x + 12, y + 6 - yOffset, z + 12, Block2, 0, 3); - world.setBlock(x + 13, y + 6 - yOffset, z + 12, Block2, 0, 3); - world.setBlock(x + 14, y + 6 - yOffset, z + 12, Block2, 0, 3); - world.setBlock(x + 13, y + 6 - yOffset, z + 13, Block2, 0, 3); - world.setBlock(x + 13, y + 6 - yOffset, z + 14, Block2, 0, 3); - world.setBlock(x + 13, y + 6 - yOffset, z + 17, Block2, 0, 3); - world.setBlock(x + 13, y + 6 - yOffset, z + 18, Block2, 0, 3); - world.setBlock(x + 4, y + 7 - yOffset, z + 4, Block2, 0, 3); - world.setBlock(x + 13, y + 7 - yOffset, z + 4, Block2, 0, 3); - world.setBlock(x + 22, y + 7 - yOffset, z + 4, Block2, 0, 3); - world.setBlock(x + 3, y + 7 - yOffset, z + 5, Block2, 0, 3); - world.setBlock(x + 4, y + 7 - yOffset, z + 5, Block1, 0, 3); - world.setBlock(x + 5, y + 7 - yOffset, z + 5, Block2, 0, 3); - world.setBlock(x + 12, y + 7 - yOffset, z + 5, Block2, 0, 3); - world.setBlock(x + 13, y + 7 - yOffset, z + 5, Block2, 0, 3); - world.setBlock(x + 14, y + 7 - yOffset, z + 5, Block2, 0, 3); - world.setBlock(x + 21, y + 7 - yOffset, z + 5, Block2, 0, 3); - world.setBlock(x + 22, y + 7 - yOffset, z + 5, Block1, 0, 3); - world.setBlock(x + 23, y + 7 - yOffset, z + 5, Block2, 0, 3); - world.setBlock(x + 4, y + 7 - yOffset, z + 6, Block2, 0, 3); - world.setBlock(x + 12, y + 7 - yOffset, z + 6, Block2, 0, 3); - world.setBlock(x + 13, y + 7 - yOffset, z + 6, Block2, 0, 3); - world.setBlock(x + 14, y + 7 - yOffset, z + 6, Block2, 0, 3); - world.setBlock(x + 22, y + 7 - yOffset, z + 6, Block2, 0, 3); - world.setBlock(x + 12, y + 7 - yOffset, z + 7, Block2, 0, 3); - world.setBlock(x + 13, y + 7 - yOffset, z + 7, Block2, 0, 3); - world.setBlock(x + 14, y + 7 - yOffset, z + 7, Block2, 0, 3); - world.setBlock(x + 12, y + 7 - yOffset, z + 8, Block2, 0, 3); - world.setBlock(x + 13, y + 7 - yOffset, z + 8, Block2, 0, 3); - world.setBlock(x + 14, y + 7 - yOffset, z + 8, Block2, 0, 3); - world.setBlock(x + 13, y + 7 - yOffset, z + 9, Block2, 0, 3); - world.setBlock(x + 13, y + 7 - yOffset, z + 10, Block2, 0, 3); - world.setBlock(x + 13, y + 7 - yOffset, z + 11, Block2, 0, 3); - world.setBlock(x + 4, y + 8 - yOffset, z + 4, Block2, 0, 3); - world.setBlock(x + 22, y + 8 - yOffset, z + 4, Block2, 0, 3); - world.setBlock(x + 3, y + 8 - yOffset, z + 5, Block2, 0, 3); - world.setBlock(x + 4, y + 8 - yOffset, z + 5, Block1, 0, 3); - world.setBlock(x + 5, y + 8 - yOffset, z + 5, Block2, 0, 3); - world.setBlock(x + 21, y + 8 - yOffset, z + 5, Block2, 0, 3); - world.setBlock(x + 22, y + 8 - yOffset, z + 5, Block1, 0, 3); - world.setBlock(x + 23, y + 8 - yOffset, z + 5, Block2, 0, 3); - world.setBlock(x + 4, y + 8 - yOffset, z + 6, Block2, 0, 3); - world.setBlock(x + 22, y + 8 - yOffset, z + 6, Block2, 0, 3); - world.setBlock(x + 4, y + 9 - yOffset, z + 5, Block1, 0, 3); - world.setBlock(x + 22, y + 9 - yOffset, z + 5, Block1, 0, 3); - world.setBlock(x + 4, y + 10 - yOffset, z + 1, Block3, 0, 3); - world.setBlock(x + 22, y + 10 - yOffset, z + 1, Block3, 0, 3); - world.setBlock(x + 4, y + 10 - yOffset, z + 2, Block3, 0, 3); - world.setBlock(x + 22, y + 10 - yOffset, z + 2, Block3, 0, 3); - world.setBlock(x + 4, y + 10 - yOffset, z + 3, Block3, 0, 3); - world.setBlock(x + 22, y + 10 - yOffset, z + 3, Block3, 0, 3); - world.setBlock(x + 4, y + 10 - yOffset, z + 4, Block3, 0, 3); - world.setBlock(x + 22, y + 10 - yOffset, z + 4, Block3, 0, 3); - world.setBlock(x + 0, y + 10 - yOffset, z + 5, Block3, 0, 3); - world.setBlock(x + 1, y + 10 - yOffset, z + 5, Block3, 0, 3); - world.setBlock(x + 2, y + 10 - yOffset, z + 5, Block3, 0, 3); - world.setBlock(x + 3, y + 10 - yOffset, z + 5, Block3, 0, 3); - world.setBlock(x + 4, y + 10 - yOffset, z + 5, Block1, 0, 3); - world.setBlock(x + 5, y + 10 - yOffset, z + 5, Block3, 0, 3); - world.setBlock(x + 6, y + 10 - yOffset, z + 5, Block3, 0, 3); - world.setBlock(x + 7, y + 10 - yOffset, z + 5, Block3, 0, 3); - world.setBlock(x + 8, y + 10 - yOffset, z + 5, Block3, 0, 3); - world.setBlock(x + 18, y + 10 - yOffset, z + 5, Block3, 0, 3); - world.setBlock(x + 19, y + 10 - yOffset, z + 5, Block3, 0, 3); - world.setBlock(x + 20, y + 10 - yOffset, z + 5, Block3, 0, 3); - world.setBlock(x + 21, y + 10 - yOffset, z + 5, Block3, 0, 3); - world.setBlock(x + 22, y + 10 - yOffset, z + 5, Block1, 0, 3); - world.setBlock(x + 23, y + 10 - yOffset, z + 5, Block3, 0, 3); - world.setBlock(x + 24, y + 10 - yOffset, z + 5, Block3, 0, 3); - world.setBlock(x + 25, y + 10 - yOffset, z + 5, Block3, 0, 3); - world.setBlock(x + 26, y + 10 - yOffset, z + 5, Block3, 0, 3); - world.setBlock(x + 4, y + 10 - yOffset, z + 6, Block3, 0, 3); - world.setBlock(x + 22, y + 10 - yOffset, z + 6, Block3, 0, 3); - world.setBlock(x + 4, y + 10 - yOffset, z + 7, Block3, 0, 3); - world.setBlock(x + 22, y + 10 - yOffset, z + 7, Block3, 0, 3); - world.setBlock(x + 4, y + 10 - yOffset, z + 8, Block3, 0, 3); - world.setBlock(x + 22, y + 10 - yOffset, z + 8, Block3, 0, 3); - world.setBlock(x + 4, y + 10 - yOffset, z + 9, Block3, 0, 3); - world.setBlock(x + 22, y + 10 - yOffset, z + 9, Block3, 0, 3); - - generate_r02_last(world, rand, x, y, z, yOffset); - return true; - - } - public boolean generate_r02_last(World world, Random rand, int x, int y, int z, int yOffset) - { - - world.setBlock(x + 12, y + 2 - yOffset, z + 1, Blocks.lever, 3, 3); - world.setBlock(x + 14, y + 2 - yOffset, z + 1, Blocks.lever, 3, 3); - if(GeneralConfig.enableDebugMode) - System.out.print("[Debug] Successfully spawned Vertibird at " + x + " " + y +" " + z + "\n"); - return true; - - } - -} \ No newline at end of file diff --git a/src/main/java/com/hbm/world/gen/NTMWorldGenerator.java b/src/main/java/com/hbm/world/gen/NTMWorldGenerator.java index f68921cb3..3e0ebc963 100644 --- a/src/main/java/com/hbm/world/gen/NTMWorldGenerator.java +++ b/src/main/java/com/hbm/world/gen/NTMWorldGenerator.java @@ -49,6 +49,18 @@ public class NTMWorldGenerator implements IWorldGenerator { spawnWeight = 1; }}); + NBTStructure.registerStructure(0, new SpawnCondition() {{ + canSpawn = biome -> !biome.canSpawnLightningBolt() && biome.temperature >= 2F; + structure = new JigsawPiece("vertibird", StructureManager.vertibird); + spawnWeight = 3; + }}); + + NBTStructure.registerStructure(0, new SpawnCondition() {{ + canSpawn = biome -> !biome.canSpawnLightningBolt() && biome.temperature >= 2F; + structure = new JigsawPiece("crashed_vertibird", StructureManager.crashed_vertibird); + spawnWeight = 3; + }}); + Map bricks = new HashMap() {{ put(ModBlocks.meteor_brick, new MeteorBricks()); }}; diff --git a/src/main/java/com/hbm/world/generator/CellularDungeonFactory.java b/src/main/java/com/hbm/world/generator/CellularDungeonFactory.java index e58e88ae3..f6cd5f152 100644 --- a/src/main/java/com/hbm/world/generator/CellularDungeonFactory.java +++ b/src/main/java/com/hbm/world/generator/CellularDungeonFactory.java @@ -2,24 +2,12 @@ package com.hbm.world.generator; import com.hbm.world.generator.room.*; -import net.minecraftforge.common.util.ForgeDirection; - public class CellularDungeonFactory { - public static CellularDungeon meteor; public static CellularDungeon jungle; - + public static void init() { - - meteor = new TestDungeon(11, 7, 11, 11, 150, 3); - meteor.rooms.add(new TestDungeonRoom1(meteor)); - meteor.rooms.add(new TestDungeonRoom2(meteor)); - meteor.rooms.add(new TestDungeonRoom3(meteor)); - meteor.rooms.add(new TestDungeonRoom4(meteor, new TestDungeonRoom5(meteor), ForgeDirection.NORTH)); - meteor.rooms.add(new TestDungeonRoom6(meteor)); - meteor.rooms.add(new TestDungeonRoom7(meteor)); - meteor.rooms.add(new TestDungeonRoom8(meteor)); - + jungle = new JungleDungeon(5, 5, 25, 25, 700, 6); for(int i = 0; i < 10; i++) jungle.rooms.add(new JungleDungeonRoom(jungle)); jungle.rooms.add(new JungleDungeonRoomArrow(jungle)); diff --git a/src/main/java/com/hbm/world/generator/TestDungeon.java b/src/main/java/com/hbm/world/generator/TestDungeon.java deleted file mode 100644 index 14ae78cf7..000000000 --- a/src/main/java/com/hbm/world/generator/TestDungeon.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.hbm.world.generator; - -import com.hbm.blocks.ModBlocks; -import com.hbm.inventory.RecipesCommon.MetaBlock; - -public class TestDungeon extends CellularDungeon { - - public TestDungeon(int width, int height, int dimX, int dimZ, int tries, int branches) { - super(width, height, dimX, dimZ, tries, branches); - - this.floor.add(new MetaBlock(ModBlocks.meteor_polished)); - this.wall.add(new MetaBlock(ModBlocks.meteor_brick)); - this.wall.add(new MetaBlock(ModBlocks.meteor_brick)); - this.wall.add(new MetaBlock(ModBlocks.meteor_brick_mossy)); - this.wall.add(new MetaBlock(ModBlocks.meteor_brick_cracked)); - this.ceiling.add(new MetaBlock(ModBlocks.block_meteor_broken)); - } - -} diff --git a/src/main/java/com/hbm/world/generator/room/TestDungeonRoom1.java b/src/main/java/com/hbm/world/generator/room/TestDungeonRoom1.java deleted file mode 100644 index 77f2f257b..000000000 --- a/src/main/java/com/hbm/world/generator/room/TestDungeonRoom1.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.hbm.world.generator.room; - -import com.hbm.blocks.ModBlocks; -import com.hbm.world.generator.CellularDungeon; -import com.hbm.world.generator.CellularDungeonRoom; -import com.hbm.world.generator.DungeonToolbox; - -import net.minecraft.init.Blocks; -import net.minecraft.world.World; - -public class TestDungeonRoom1 extends CellularDungeonRoom { - - public TestDungeonRoom1(CellularDungeon parent) { - super(parent); - } - - public void generateMain(World world, int x, int y, int z) { - - super.generateMain(world, x, y, z); - DungeonToolbox.generateBox(world, x + parent.width / 2 - 3, y + 1, z + parent.width / 2 - 3, 1, parent.height - 2, 1, ModBlocks.meteor_pillar); - DungeonToolbox.generateBox(world, x + parent.width / 2 + 3, y + 1, z + parent.width / 2 - 3, 1, parent.height - 2, 1, ModBlocks.meteor_pillar); - DungeonToolbox.generateBox(world, x + parent.width / 2 + 3, y + 1, z + parent.width / 2 + 3, 1, parent.height - 2, 1, ModBlocks.meteor_pillar); - DungeonToolbox.generateBox(world, x + parent.width / 2 - 3, y + 1, z + parent.width / 2 + 3, 1, parent.height - 2, 1, ModBlocks.meteor_pillar); - world.setBlock(x + parent.width / 2 - 3, y + 3, z + parent.width / 2 - 3, ModBlocks.meteor_brick_chiseled, 0, 2); - world.setBlock(x + parent.width / 2 + 3, y + 3, z + parent.width / 2 - 3, ModBlocks.meteor_brick_chiseled, 0, 2); - world.setBlock(x + parent.width / 2 + 3, y + 3, z + parent.width / 2 + 3, ModBlocks.meteor_brick_chiseled, 0, 2); - world.setBlock(x + parent.width / 2 - 3, y + 3, z + parent.width / 2 + 3, ModBlocks.meteor_brick_chiseled, 0, 2); - world.setBlock(x + parent.width / 2, y + 1, z + parent.width / 2, ModBlocks.meteor_pillar, 0, 2); - world.setBlock(x + parent.width / 2, y + 2, z + parent.width / 2, Blocks.glowstone, 0, 3); - - /*world.setBlock(x + parent.width / 2, y, z + parent.width / 2, Blocks.mob_spawner, 0, 2); - TileEntityMobSpawner tileentitymobspawner2 = (TileEntityMobSpawner)world.getTileEntity(x + parent.width / 2, y, z + parent.width / 2); - - if (tileentitymobspawner2 != null) - { - tileentitymobspawner2.func_145881_a().setEntityName("entity_cyber_crab"); - }*/ - } -} diff --git a/src/main/java/com/hbm/world/generator/room/TestDungeonRoom2.java b/src/main/java/com/hbm/world/generator/room/TestDungeonRoom2.java deleted file mode 100644 index 60c15b6e3..000000000 --- a/src/main/java/com/hbm/world/generator/room/TestDungeonRoom2.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.hbm.world.generator.room; - -import com.hbm.blocks.ModBlocks; -import com.hbm.world.generator.CellularDungeon; -import com.hbm.world.generator.CellularDungeonRoom; - -import net.minecraft.world.World; - -public class TestDungeonRoom2 extends CellularDungeonRoom { - - public TestDungeonRoom2(CellularDungeon parent) { - super(parent); - } - - public void generateMain(World world, int x, int y, int z) { - - super.generateMain(world, x, y, z); - - int j = world.rand.nextInt(2) + 2; - int k = world.rand.nextInt(3) + 2; - - for(int i = 0; i < j; i++) { - int dx = world.rand.nextInt(parent.width - 6) + 3; - int dz = world.rand.nextInt(parent.width - 6) + 3; - world.setBlock(x + dx, y + 1, z + dz, ModBlocks.crate_ammo, 0, 2); - } - - for(int i = 0; i < k; i++) { - int dx = world.rand.nextInt(parent.width - 6) + 3; - int dz = world.rand.nextInt(parent.width - 6) + 3; - world.setBlock(x + dx, y + 1, z + dz, ModBlocks.crate_can, 0, 2); - } - } -} diff --git a/src/main/java/com/hbm/world/generator/room/TestDungeonRoom3.java b/src/main/java/com/hbm/world/generator/room/TestDungeonRoom3.java deleted file mode 100644 index dbb6f7366..000000000 --- a/src/main/java/com/hbm/world/generator/room/TestDungeonRoom3.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.hbm.world.generator.room; - -import com.hbm.blocks.ModBlocks; -import com.hbm.world.generator.CellularDungeon; -import com.hbm.world.generator.CellularDungeonRoom; -import com.hbm.world.generator.DungeonToolbox; - -import net.minecraft.init.Blocks; -import net.minecraft.tileentity.TileEntityMobSpawner; -import net.minecraft.world.World; - -public class TestDungeonRoom3 extends CellularDungeonRoom { - - public TestDungeonRoom3(CellularDungeon parent) { - super(parent); - } - - public void generateMain(World world, int x, int y, int z) { - - super.generateMain(world, x, y, z); - DungeonToolbox.generateBox(world, x + parent.width / 2 - 2, y + 1, z + parent.width / 2 - 2, 5, 4, 5, ModBlocks.deco_lead); - DungeonToolbox.generateBox(world, x + parent.width / 2 - 1, y + 1, z + parent.width / 2 - 1, 3, 3, 3, ModBlocks.toxic_block); - DungeonToolbox.generateBox(world, x + parent.width / 2 - 1, y + 4, z + parent.width / 2 - 1, 3, 1, 3, Blocks.air); - - world.setBlock(x + parent.width / 2, y + 1, z + parent.width / 2, Blocks.mob_spawner, 0, 2); - TileEntityMobSpawner tileentitymobspawner2 = (TileEntityMobSpawner)world.getTileEntity(x + parent.width / 2, y + 1, z + parent.width / 2); - - if (tileentitymobspawner2 != null) - { - tileentitymobspawner2.func_145881_a().setEntityName("entity_cyber_crab"); - } - } -} diff --git a/src/main/java/com/hbm/world/generator/room/TestDungeonRoom4.java b/src/main/java/com/hbm/world/generator/room/TestDungeonRoom4.java deleted file mode 100644 index 815f26330..000000000 --- a/src/main/java/com/hbm/world/generator/room/TestDungeonRoom4.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.hbm.world.generator.room; - -import java.util.ArrayList; - -import com.hbm.blocks.ModBlocks; -import com.hbm.inventory.RecipesCommon.MetaBlock; -import com.hbm.world.generator.CellularDungeon; -import com.hbm.world.generator.CellularDungeonRoom; -import com.hbm.world.generator.DungeonToolbox; - -import net.minecraft.init.Blocks; -import net.minecraft.world.World; -import net.minecraftforge.common.util.ForgeDirection; - -public class TestDungeonRoom4 extends CellularDungeonRoom { - - public TestDungeonRoom4(CellularDungeon parent, CellularDungeonRoom daisyChain, ForgeDirection dir) { - super(parent); - this.daisyChain = daisyChain; - this.daisyDirection = dir; - } - - public void generateMain(World world, int x, int y, int z) { - - super.generateMain(world, x, y, z); - DungeonToolbox.generateBox(world, x, y + parent.height - 2, z, parent.width, 1, parent.width, new ArrayList() {{ add(new MetaBlock(Blocks.air)); add(new MetaBlock(Blocks.web)); }}); - - DungeonToolbox.generateBox(world, x + 1, y, z + 1, parent.width - 2, 1, parent.width - 2, new ArrayList() {{ - add(new MetaBlock(ModBlocks.meteor_polished)); - add(new MetaBlock(ModBlocks.meteor_polished)); - add(new MetaBlock(ModBlocks.meteor_polished)); - add(new MetaBlock(ModBlocks.meteor_polished)); - add(new MetaBlock(ModBlocks.meteor_polished)); - add(new MetaBlock(ModBlocks.meteor_spawner)); - }}); - } - - public void generateWall(World world, int x, int y, int z, ForgeDirection wall, boolean door) { - - if(wall != ForgeDirection.NORTH) - super.generateWall(world, x, y, z, wall, door); - } -} \ No newline at end of file diff --git a/src/main/java/com/hbm/world/generator/room/TestDungeonRoom5.java b/src/main/java/com/hbm/world/generator/room/TestDungeonRoom5.java deleted file mode 100644 index e02be0c7d..000000000 --- a/src/main/java/com/hbm/world/generator/room/TestDungeonRoom5.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.hbm.world.generator.room; - -import java.util.ArrayList; - -import com.hbm.blocks.ModBlocks; -import com.hbm.inventory.RecipesCommon.MetaBlock; -import com.hbm.world.generator.CellularDungeon; -import com.hbm.world.generator.CellularDungeonRoom; -import com.hbm.world.generator.DungeonToolbox; - -import net.minecraft.init.Blocks; -import net.minecraft.world.World; -import net.minecraftforge.common.util.ForgeDirection; - -public class TestDungeonRoom5 extends CellularDungeonRoom { - - public TestDungeonRoom5(CellularDungeon parent) { - super(parent); - } - - public void generateMain(World world, int x, int y, int z) { - - super.generateMain(world, x, y, z); - DungeonToolbox.generateBox(world, x, y + parent.height - 2, z, parent.width, 1, parent.width, new ArrayList() {{ add(new MetaBlock(Blocks.air)); add(new MetaBlock(Blocks.web)); }}); - - DungeonToolbox.generateBox(world, x + 1, y, z + 1, parent.width - 2, 1, parent.width - 2, new ArrayList() {{ - add(new MetaBlock(ModBlocks.meteor_polished)); - add(new MetaBlock(ModBlocks.meteor_polished)); - add(new MetaBlock(ModBlocks.meteor_polished)); - add(new MetaBlock(ModBlocks.meteor_polished)); - add(new MetaBlock(ModBlocks.meteor_polished)); - add(new MetaBlock(ModBlocks.meteor_spawner)); }}); - } - - public void generateWall(World world, int x, int y, int z, ForgeDirection wall, boolean door) { - - if(wall != ForgeDirection.SOUTH) - super.generateWall(world, x, y, z, wall, door); - } -} \ No newline at end of file diff --git a/src/main/java/com/hbm/world/generator/room/TestDungeonRoom6.java b/src/main/java/com/hbm/world/generator/room/TestDungeonRoom6.java deleted file mode 100644 index e04f552cc..000000000 --- a/src/main/java/com/hbm/world/generator/room/TestDungeonRoom6.java +++ /dev/null @@ -1,54 +0,0 @@ -package com.hbm.world.generator.room; - -import com.hbm.blocks.ModBlocks; -import com.hbm.world.generator.CellularDungeon; -import com.hbm.world.generator.CellularDungeonRoom; -import com.hbm.world.generator.DungeonToolbox; - -import net.minecraft.world.World; -import net.minecraftforge.common.util.ForgeDirection; - -public class TestDungeonRoom6 extends CellularDungeonRoom { - - public TestDungeonRoom6(CellularDungeon parent) { - super(parent); - } - - public void generateMain(World world, int x, int y, int z) { - - super.generateMain(world, x, y, z); - DungeonToolbox.generateBox(world, x + 1, y, z + 1, parent.width - 2, 1, parent.width - 2, ModBlocks.toxic_block); - DungeonToolbox.generateBox(world, x + parent.width / 2 - 1, y, z + parent.width / 2 - 1, 3, 1, 3, ModBlocks.meteor_brick_chiseled); - world.setBlock(x + parent.width / 2, y, z + parent.width / 2, ModBlocks.meteor_polished); - - world.setBlock(x + 1, y, z + parent.width / 2, ModBlocks.meteor_polished); - world.setBlock(x + parent.width / 2, y, z + 1, ModBlocks.meteor_polished); - - world.setBlock(x + parent.width - 2, y, z + parent.width / 2, ModBlocks.meteor_polished); - world.setBlock(x + parent.width / 2, y, z + parent.width - 2, ModBlocks.meteor_polished); - } - - public void generateWall(World world, int x, int y, int z, ForgeDirection wall, boolean door) { - - super.generateWall(world, x, y, z, wall, door); - - if(!door) - return; - - if(wall == ForgeDirection.NORTH) { - DungeonToolbox.generateBox(world, x + parent.width / 2, y, z + 1, 1, 1, parent.width / 2 - 2, ModBlocks.meteor_polished); - } - - if(wall == ForgeDirection.SOUTH) { - DungeonToolbox.generateBox(world, x + parent.width / 2, y, z + parent.width / 2 + 2, 1, 1, parent.width / 2 - 2, ModBlocks.meteor_polished); - } - - if(wall == ForgeDirection.WEST) { - DungeonToolbox.generateBox(world, x + 1, y, z + parent.width / 2, parent.width / 2 - 2, 1, 1, ModBlocks.meteor_polished); - } - - if(wall == ForgeDirection.EAST) { - DungeonToolbox.generateBox(world, x + parent.width / 2 + 2, y, z + parent.width / 2, parent.width / 2 - 2, 1, 1, ModBlocks.meteor_polished); - } - } -} diff --git a/src/main/java/com/hbm/world/generator/room/TestDungeonRoom7.java b/src/main/java/com/hbm/world/generator/room/TestDungeonRoom7.java deleted file mode 100644 index 57909caa2..000000000 --- a/src/main/java/com/hbm/world/generator/room/TestDungeonRoom7.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.hbm.world.generator.room; - -import com.hbm.blocks.ModBlocks; -import com.hbm.world.generator.CellularDungeon; -import com.hbm.world.generator.CellularDungeonRoom; -import com.hbm.world.generator.DungeonToolbox; - -import net.minecraft.world.World; - -public class TestDungeonRoom7 extends CellularDungeonRoom { - - public TestDungeonRoom7(CellularDungeon parent) { - super(parent); - } - - public void generateMain(World world, int x, int y, int z) { - - super.generateMain(world, x, y, z); - - DungeonToolbox.generateBox(world, x, y, z, parent.width, 1, parent.width, ModBlocks.meteor_polished); - DungeonToolbox.generateBox(world, x + 2, y, z + 2, parent.width - 4, 1, parent.width - 4, ModBlocks.deco_red_copper); - DungeonToolbox.generateBox(world, x + 3, y, z + 3, parent.width - 6, 1, parent.width - 6, ModBlocks.meteor_polished); - DungeonToolbox.generateBox(world, x + 4, y, z + 4, parent.width - 8, 1, parent.width - 8, ModBlocks.deco_red_copper); - - world.setBlock(x + parent.width / 2, y, z + parent.width / 2, ModBlocks.meteor_battery); - world.setBlock(x + parent.width / 2, y + 1, z + parent.width / 2, ModBlocks.tesla); - } -} diff --git a/src/main/java/com/hbm/world/generator/room/TestDungeonRoom8.java b/src/main/java/com/hbm/world/generator/room/TestDungeonRoom8.java deleted file mode 100644 index e69db5214..000000000 --- a/src/main/java/com/hbm/world/generator/room/TestDungeonRoom8.java +++ /dev/null @@ -1,225 +0,0 @@ -package com.hbm.world.generator.room; - -import com.hbm.blocks.ModBlocks; -import com.hbm.crafting.handlers.MKUCraftingHandler; -import com.hbm.items.ModItems; -import com.hbm.items.special.ItemBookLore; -import com.hbm.tileentity.machine.storage.TileEntitySafe; -import com.hbm.world.generator.CellularDungeon; -import com.hbm.world.generator.CellularDungeonRoom; -import com.hbm.world.generator.DungeonToolbox; - -import net.minecraft.init.Items; -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; -import net.minecraft.world.World; - -public class TestDungeonRoom8 extends CellularDungeonRoom { - - public TestDungeonRoom8(CellularDungeon parent) { - super(parent); - } - - public void generateMain(World world, int x, int y, int z) { - - super.generateMain(world, x, y, z); - DungeonToolbox.generateBox(world, x + parent.width / 2 - 3, y + 1, z + parent.width / 2 - 3, 1, parent.height - 2, 1, ModBlocks.meteor_pillar); - DungeonToolbox.generateBox(world, x + parent.width / 2 + 3, y + 1, z + parent.width / 2 - 3, 1, parent.height - 2, 1, ModBlocks.meteor_pillar); - DungeonToolbox.generateBox(world, x + parent.width / 2 + 3, y + 1, z + parent.width / 2 + 3, 1, parent.height - 2, 1, ModBlocks.meteor_pillar); - DungeonToolbox.generateBox(world, x + parent.width / 2 - 3, y + 1, z + parent.width / 2 + 3, 1, parent.height - 2, 1, ModBlocks.meteor_pillar); - world.setBlock(x + parent.width / 2 - 3, y + 3, z + parent.width / 2 - 3, ModBlocks.meteor_brick_chiseled, 0, 2); - world.setBlock(x + parent.width / 2 + 3, y + 3, z + parent.width / 2 - 3, ModBlocks.meteor_brick_chiseled, 0, 2); - world.setBlock(x + parent.width / 2 + 3, y + 3, z + parent.width / 2 + 3, ModBlocks.meteor_brick_chiseled, 0, 2); - world.setBlock(x + parent.width / 2 - 3, y + 3, z + parent.width / 2 + 3, ModBlocks.meteor_brick_chiseled, 0, 2); - - DungeonToolbox.generateBox(world, x + 4, y + 1, z + 4, parent.width - 8, 1, parent.width - 8, ModBlocks.meteor_polished); - - int i = world.rand.nextInt(8); - - switch(i) { - case 0: world.setBlock(x + parent.width / 2, y + 2, z + parent.width / 2, ModBlocks.meteor_brick_chiseled, 0, 3); break; - case 1: world.setBlock(x + parent.width / 2, y + 2, z + parent.width / 2, ModBlocks.ntm_dirt, 0, 3); break; - case 2: world.setBlock(x + parent.width / 2, y + 2, z + parent.width / 2, ModBlocks.block_starmetal, 0, 3); break; - case 3: world.setBlock(x + parent.width / 2, y + 2, z + parent.width / 2, ModBlocks.statue_elb_f, 0, 3); break; - case 4: world.setBlock(x + parent.width / 2, y + 2, z + parent.width / 2, ModBlocks.crate_red, 0, 3); break; - case 5: world.setBlock(x + parent.width / 2, y + 2, z + parent.width / 2, ModBlocks.balefire, 0, 3); break; - case 6: world.setBlock(x + parent.width / 2, y + 2, z + parent.width / 2, ModBlocks.block_meteor, 0, 3); break; - case 7: - world.setBlock(x + parent.width / 2, y + 2, z + parent.width / 2, ModBlocks.safe, 0, 3); - if(world.getTileEntity(x + parent.width / 2, y + 2, z + parent.width / 2) instanceof TileEntitySafe) { - - int r = world.rand.nextInt(10); - - if(r == 0) { - ((TileEntitySafe)world.getTileEntity(x + parent.width / 2, y + 2, z + parent.width / 2)).setInventorySlotContents(7, new ItemStack(ModItems.book_of_)); - } else if(r < 4) { - TileEntitySafe safe = (TileEntitySafe) world.getTileEntity(x + parent.width / 2, y + 2, z + parent.width / 2); - safe.setInventorySlotContents(5, generateBook(world)); - safe.setInventorySlotContents(7, new ItemStack(ModItems.stamp_book, 1, world.rand.nextInt(8))); - safe.setInventorySlotContents(9, new ItemStack(ModItems.stamp_book, 1, world.rand.nextInt(8))); - } else { - TileEntitySafe safe = (TileEntitySafe) world.getTileEntity(x + parent.width / 2, y + 2, z + parent.width / 2); - safe.setInventorySlotContents(5, new ItemStack(Items.book)); - safe.setInventorySlotContents(7, new ItemStack(ModItems.stamp_book, 1, world.rand.nextInt(8))); - safe.setInventorySlotContents(9, new ItemStack(ModItems.stamp_book, 1, world.rand.nextInt(8))); - } - } - break; - } - } - - public static ItemStack generateBook(World world) { - MKUCraftingHandler.generateRecipe(world); - ItemStack[] recipe = MKUCraftingHandler.MKURecipe; - - if(recipe == null) return new ItemStack(ModItems.flame_pony); - - String key; - int pages; - Item item; - switch(world.rand.nextInt(6)) { - case 0: - key = "book_iodine"; pages = 3; - item = ModItems.powder_iodine; break; - case 1: - key = "book_phosphorous"; pages = 2; - item = ModItems.powder_fire; break; - case 2: - key = "book_dust"; pages = 3; - item = ModItems.dust; break; - case 3: - key = "book_mercury"; pages = 2; - item = ModItems.ingot_mercury; break; - case 4: - key = "book_flower"; pages = 2; - item = ModItems.morning_glory; break; - case 5: - key = "book_syringe"; pages = 2; - item = ModItems.syringe_metal_empty; break; - default: - return new ItemStack(ModItems.flame_pony); - } - - int s = 1; - for(int i = 0; i < 9; i++) { - if(recipe[i] != null && recipe[i].getItem() == item) { - s = i + 1; break; - } - } - - ItemStack book = ItemBookLore.createBook(key, pages, 0x271E44, 0xFBFFF4); - ItemBookLore.addArgs(book, pages - 1, String.valueOf(s)); - - return book; - } - - /*public static ItemStack genetateMKU(World world) { - - ItemStack book = new ItemStack(Items.written_book); - book.stackTagCompound = new NBTTagCompound(); - book.stackTagCompound.setString("author", "Dave"); - book.stackTagCompound.setString("title", "Note"); - NBTTagList nbt = new NBTTagList(); - - String[] pages = generatePages(world); - - for(String s : pages) { - nbt.appendTag(new NBTTagString(s)); - } - - book.stackTagCompound.setTag("pages", nbt); - - return book; - } - - private static String[] bookIodine = new String[] { - "alright you will not believe this, but old man weathervane finally managed to show up again since he left two weeks ago", - "and what's more surprising is the fact that he actually decided to spill the beans on what they were doing in the canyon:", - "apparently the morons form R&D discovered a compound that is mostly inorganic, pretty much like a toxin in nature, but get", - "this: the dying cells will reproduce said toxin and excete it through the skin, creating an aerosol that is highly contageous.", - "it's just like a virus, but not a virus. the composition is weird, you can mix it in any household bottle but you do have to", - "get the order right. the doc told me that the first ingredient which is just powdered iodine crystals goes into slot #" - }; - private static String[] bookPhosphorous = new String[] { - "heyo, it's me again. i assume you got my last memo, the doc wasn't too happy about it. i'll have to do this quick, the", - "dunderheads from R&D are currently moaning again, probably over money. again. anyway, doc weathervane found that the second", - "ingredient is red phosphorous, whihc has to be mixed into slot #" - }; - private static String[] bookDust = new String[] { - "the doc was furious when he found out that the R&D dorks kept the one remaining sample, ranting about gross negligence this", - "and a doomsday scenario that. i told him to chill for a minute, getting all worked up isn't good for his blood pressure, not", - "that he has much blood left to begin with. one of the R&D morons slipped some more info into last week's circular, they call their", - "little concoction \"MKU\" whatever that means, and that it contains actual household lint. can you believe that? one of the most", - "dangerous inventions of theirs and it contains dust. strangely they also mentioned that it goes into slot #" - }; - private static String[] bookMercury = new String[] { - "well that settles that. not counting the vomitting blood part, the toxicological report mostly resembles that of mercury", - "poisoning. why? because our little mix also contains mercury! i just wonder where all that stuff comes from when being", - "replicated by the body? whatever, the mercury goes into slot #" - }; - private static String[] bookFlower = new String[] { - "remember when i mentioned in my first memo that the compound is mostly anorganic? well guess what, the old man shared the fourth", - "ingredient: ipomoea nil, a genus of flower. morning glory! it might be due to its low sulfur content, whatever might be the case,", - "it does not work with other flowers. the morning glory goes into slot #" - }; - private static String[] bookSyringe = new String[] { - "a little addendum to my fifth message, obviously you have to store this MKU stuff in a container. the R&D nuts used regular", - "metal syringes that they got from medical. surplus ware i presume, they got thousands of needles just lying around. the metal", - "syringe goes into slot #" - }; - - public static String[] generatePages(World world) { - - String[] orig; - Item ingred; - int r = world.rand.nextInt(6); - - if(r == 0) { - orig = bookIodine; - ingred = ModItems.powder_iodine; - } else if(r == 1) { - orig = bookPhosphorous; - ingred = ModItems.powder_fire; - } else if(r == 2) { - orig = bookDust; - ingred = ModItems.dust; - } else if(r == 3) { - orig = bookMercury; - ingred = ModItems.ingot_mercury; - } else if(r == 4) { - orig = bookFlower; - ingred = ModItems.morning_glory; - } else { - orig = bookSyringe; - ingred = ModItems.syringe_metal_empty; - } - - String[] copy = new String[orig.length]; - - for(int i = 0; i < orig.length; i++) { - copy[i] = orig[i] + ""; //Strings are reference types and i'm really not counting on my luck here - } - - copy[copy.length - 1] += getSlot(world, ingred); - - return copy; - } - - public static int getSlot(World world, Item item) { - - MKUCraftingHandler.generateRecipe(world); - ItemStack[] recipe = MKUCraftingHandler.MKURecipe; - - if(recipe == null) //take no chances - return -2; - - for(int i = 0; i < 9; i++) { - - if(recipe[i] != null && recipe[i].getItem() == item) { - return i + 1; - } - } - - return -1; - }*/ -} From 0dea47ff873a2aaab71ae58e9ea51a0ad766223d Mon Sep 17 00:00:00 2001 From: George Paton Date: Mon, 10 Feb 2025 12:21:45 +1100 Subject: [PATCH 11/12] add glowstone loot and force 3x3loot to always spawn, even at size limit --- src/main/java/com/hbm/main/StructureManager.java | 1 + .../java/com/hbm/world/gen/NTMWorldGenerator.java | 2 ++ .../structures/meteor/loot3x3/meteor-3-glow.nbt | Bin 0 -> 318 bytes 3 files changed, 3 insertions(+) create mode 100644 src/main/resources/assets/hbm/structures/meteor/loot3x3/meteor-3-glow.nbt diff --git a/src/main/java/com/hbm/main/StructureManager.java b/src/main/java/com/hbm/main/StructureManager.java index d7881ba66..eca4c4853 100644 --- a/src/main/java/com/hbm/main/StructureManager.java +++ b/src/main/java/com/hbm/main/StructureManager.java @@ -30,6 +30,7 @@ public class StructureManager { public static final NBTStructure meteor_3_book = new NBTStructure(new ResourceLocation(RefStrings.MODID, "structures/meteor/loot3x3/meteor-3-book.nbt")); public static final NBTStructure meteor_3_mku = new NBTStructure(new ResourceLocation(RefStrings.MODID, "structures/meteor/loot3x3/meteor-3-mku.nbt")); public static final NBTStructure meteor_3_statue = new NBTStructure(new ResourceLocation(RefStrings.MODID, "structures/meteor/loot3x3/meteor-3-statue.nbt")); + public static final NBTStructure meteor_3_glow = new NBTStructure(new ResourceLocation(RefStrings.MODID, "structures/meteor/loot3x3/meteor-3-glow.nbt")); public static final NBTStructure meteor_room_base_end = new NBTStructure(new ResourceLocation(RefStrings.MODID, "structures/meteor/room10/room-base-end.nbt")); public static final NBTStructure meteor_room_base_thru = new NBTStructure(new ResourceLocation(RefStrings.MODID, "structures/meteor/room10/room-base-thru.nbt")); diff --git a/src/main/java/com/hbm/world/gen/NTMWorldGenerator.java b/src/main/java/com/hbm/world/gen/NTMWorldGenerator.java index 3e0ebc963..e56c3e0eb 100644 --- a/src/main/java/com/hbm/world/gen/NTMWorldGenerator.java +++ b/src/main/java/com/hbm/world/gen/NTMWorldGenerator.java @@ -122,6 +122,8 @@ public class NTMWorldGenerator implements IWorldGenerator { add(new JigsawPiece("meteor_3_book", StructureManager.meteor_3_book), 1); add(new JigsawPiece("meteor_3_mku", StructureManager.meteor_3_mku), 1); add(new JigsawPiece("meteor_3_statue", StructureManager.meteor_3_statue), 1); + add(new JigsawPiece("meteor_3_glow", StructureManager.meteor_3_glow), 1); + fallback = "3x3loot"; // generate loot even if we're at the size limit }}); put("headloot", new JigsawPool() {{ add(new JigsawPiece("meteor_dragon_chest", StructureManager.meteor_dragon_chest) {{ blockTable = crates; }}, 1); diff --git a/src/main/resources/assets/hbm/structures/meteor/loot3x3/meteor-3-glow.nbt b/src/main/resources/assets/hbm/structures/meteor/loot3x3/meteor-3-glow.nbt new file mode 100644 index 0000000000000000000000000000000000000000..b496b06d91748fd868ada466538210c7faa76bfb GIT binary patch literal 318 zcmV-E0m1$siwFP!000001C3H!PQx$|949Gx@Cibk0`c8Lpx&TzlTB;zBeJ(taC+jV z302jXCCggx%X%XgwKNOEGa$Cpp0+cQ`m=t~oejPUm@4OlBc9@pP4U zLm2;4TA^Ba*O8C^tvHw=-lGE_(SeJC;}-LIVjekhll5ejrP|Au=WFeDft{uPf%!N2 QFt{b~2QT3lNIe4p0F}y-WB>pF literal 0 HcmV?d00001 From 98a334575dee3b61dc3342284fda94ce3c4a9434 Mon Sep 17 00:00:00 2001 From: George Paton Date: Mon, 10 Feb 2025 15:57:03 +1100 Subject: [PATCH 12/12] forgot the jigsaw block side rotating code --- .../render/block/RenderBlockSideRotation.java | 26 ++++++++++++++----- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/hbm/render/block/RenderBlockSideRotation.java b/src/main/java/com/hbm/render/block/RenderBlockSideRotation.java index 785cac0ea..036bbd914 100644 --- a/src/main/java/com/hbm/render/block/RenderBlockSideRotation.java +++ b/src/main/java/com/hbm/render/block/RenderBlockSideRotation.java @@ -14,13 +14,13 @@ public class RenderBlockSideRotation implements ISimpleBlockRenderingHandler { @Override public void renderInventoryBlock(Block block, int metadata, int modelId, RenderBlocks renderer) { - + Tessellator tessellator = Tessellator.instance; block.setBlockBoundsForItemRender(); renderer.setRenderBoundsFromBlock(block); GL11.glRotatef(90.0F, 0.0F, 1.0F, 0.0F); GL11.glTranslatef(-0.5F, -0.5F, -0.5F); - + tessellator.startDrawingQuads(); tessellator.setNormal(0.0F, -1.0F, 0.0F); renderer.renderFaceYNeg(block, 0.0D, 0.0D, 0.0D, renderer.getBlockIconFromSideAndMetadata(block, 0, metadata)); @@ -45,7 +45,7 @@ public class RenderBlockSideRotation implements ISimpleBlockRenderingHandler { tessellator.setNormal(1.0F, 0.0F, 0.0F); renderer.renderFaceXPos(block, 0.0D, 0.0D, 0.0D, renderer.getBlockIconFromSideAndMetadata(block, 5, metadata)); tessellator.draw(); - + GL11.glTranslatef(0.5F, 0.5F, 0.5F); } @@ -55,20 +55,32 @@ public class RenderBlockSideRotation implements ISimpleBlockRenderingHandler { Tessellator tessellator = Tessellator.instance; tessellator.setBrightness(block.getMixedBrightnessForBlock(world, x, y, z)); - + if(!(block instanceof IBlockSideRotation)) { renderer.renderStandardBlock(block, x, y, z); return true; } - + IBlockSideRotation rot = (IBlockSideRotation) block; - + + // I'm almost entirely convinced that MCP mistranslated these properties because north/south and west/east are fucking SWAPPED + // YEP, they fucking did, god fucking damn it. I manually figured out the correct side for each uv face property to resolve YAYY + renderer.uvRotateBottom = rot.getRotationFromSide(world, x, y, z, 0); renderer.uvRotateTop = rot.getRotationFromSide(world, x, y, z, 1); + renderer.uvRotateNorth = rot.getRotationFromSide(world, x, y, z, 5); + renderer.uvRotateSouth = rot.getRotationFromSide(world, x, y, z, 4); + renderer.uvRotateWest = rot.getRotationFromSide(world, x, y, z, 2); + renderer.uvRotateEast = rot.getRotationFromSide(world, x, y, z, 3); renderer.setRenderBounds(0.0, 0.0, 0.0, 1.0, 1.0, 1.0); renderer.renderStandardBlock(block, x, y, z); - + + renderer.uvRotateBottom = 0; renderer.uvRotateTop = 0; + renderer.uvRotateNorth = 0; + renderer.uvRotateSouth = 0; + renderer.uvRotateWest = 0; + renderer.uvRotateEast = 0; return true; }