Admiral_Damage

Untitled

Aug 23rd, 2016
116
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 12.46 KB | None | 0 0
  1. package org.bitbucket.transitauthority.transitmod.multiblock;
  2.  
  3. import com.google.common.base.Optional;
  4. import com.google.common.collect.Lists;
  5. import com.google.common.collect.Maps;
  6. import eu.tetrabyte.contentmod.tileentity.TileEntityStructureDummy;
  7. import eu.tetrabyte.contentmod.util.mathsbumpf.Shroud;
  8. import net.minecraft.block.Block;
  9. import net.minecraft.block.BlockStructureVoid;
  10. import net.minecraft.block.ITileEntityProvider;
  11. import net.minecraft.block.properties.IProperty;
  12. import net.minecraft.block.state.IBlockState;
  13. import net.minecraft.client.renderer.texture.TextureUtil;
  14. import net.minecraft.entity.player.EntityPlayer;
  15. import net.minecraft.init.Blocks;
  16. import net.minecraft.item.ItemStack;
  17. import net.minecraft.nbt.NBTTagCompound;
  18. import net.minecraft.tileentity.TileEntity;
  19. import net.minecraft.util.EnumFacing;
  20. import net.minecraft.util.EnumHand;
  21. import net.minecraft.util.ResourceLocation;
  22. import net.minecraft.util.math.BlockPos;
  23. import net.minecraft.world.World;
  24. import net.minecraft.world.gen.structure.template.PlacementSettings;
  25. import org.apache.commons.lang3.builder.StandardToStringStyle;
  26. import org.apache.commons.lang3.builder.ToStringBuilder;
  27. import org.apache.logging.log4j.Level;
  28. import org.bitbucket.transitauthority.transitmod.TransitMod;
  29. import org.bitbucket.transitauthority.transitmod.util.StringHelper;
  30.  
  31. import java.awt.image.BufferedImage;
  32. import java.io.File;
  33. import java.io.FileInputStream;
  34. import java.io.IOException;
  35. import java.util.List;
  36. import java.util.Map;
  37.  
  38. public class StructureTemplate {
  39.     public static final StandardToStringStyle STYLE = new StandardToStringStyle();
  40.     public final ResourceLocation ID;
  41.     public List<BlockInfo> template = Lists.newArrayList();
  42.     public EnumFacing facing = EnumFacing.NORTH;
  43.     public BlockPos size = BlockPos.ORIGIN;
  44.     public BlockPos placementPoint = BlockPos.ORIGIN;
  45.     public PlacementSettings placement = new PlacementSettings();
  46.    
  47.     static {
  48.         STYLE.setUseShortClassName(true);
  49.         STYLE.setUseIdentityHashCode(false);
  50.         STYLE.setContentStart(":[{");
  51.         STYLE.setContentEnd("}]");
  52.         STYLE.setFieldNameValueSeparator(": ");
  53.         STYLE.setFieldSeparator(", ");
  54.         STYLE.setNullText("---");
  55.     }
  56.    
  57.     private StructureTemplate(ResourceLocation ID, BlockPos size, EnumFacing facing, BlockPos placementPoint) {
  58.         this.ID = ID;
  59.         this.size = size;
  60.         this.facing = facing;
  61.         this.placementPoint = placementPoint;
  62.     }
  63.    
  64.     //parse png file
  65.     //save png file (needed?)
  66.     /* build, destroy, activate, check */
  67.    
  68.     public boolean buildTemplateInWorld(World world, BlockPos worldPos, EnumFacing facing, boolean force) {
  69.         this.placement.setRotation(StructureUtils.getRotationFromDefault(this.facing, facing));
  70. //      BlockPos placementPointRotated = StructureUtils.getRotatedSize(this.placementPoint, this.placement.getRotation());
  71. //      BlockPos placementPointRotated = StructureUtils.getTransformedIndex(this.placementPoint, this.size, this.placement);
  72.         BlockPos placementPointRotated = Shroud.simpleRotate(this.placementPoint, this.placement.getRotation());
  73.         TransitMod.logger.printf(Level.INFO, "place point: %s, rotated: %s, world: %s, world - rotated: %s", StringHelper.get(this.placementPoint), StringHelper.get(placementPointRotated), StringHelper.get(worldPos), StringHelper.get(worldPos.subtract(placementPointRotated)));
  74.         StructureUtils.setRotatedBoundingBox(this.placement, this.size, worldPos.subtract(placementPointRotated));
  75.         BlockPos min = StructureUtils.getCorner(this.placement.getBoundingBox(), false);
  76.         for (BlockInfo info : this.template) {
  77.             if (info == null || info.checkedOnly || info.isWildcard) continue;
  78.             TransitMod.logger.printf(Level.INFO, "info: %s", info.toString(false));
  79. //          BlockPos index = StructureUtils.getTransformedPos(info.pos, this.placement);
  80. //          BlockPos index = StructureUtils.getTransformedIndex(info.pos, this.size, this.placement);
  81.             BlockPos index = Shroud.simpleRotate(info.pos, this.placement.getRotation());
  82.             BlockPos indexWorld = index.add(min);
  83.             TransitMod.logger.printf(Level.INFO, "index after rotation: %s, index world pos after rotation: %s", StringHelper.get(index), StringHelper.get(indexWorld));
  84.             TransitMod.logger.printf(Level.INFO, "rotated place point - index: %s", StringHelper.get(placementPointRotated.subtract(index)));
  85.             //TODO: indexWorld fails isVecInside check but works math-wise
  86. //          if (this.placement.getBoundingBox().isVecInside(indexWorld)) {
  87.                 if (force || world.getBlockState(indexWorld).getBlock().isReplaceable(world, indexWorld) || world.isAirBlock(indexWorld)) {
  88.                     IBlockState rotated = info.state.withRotation(this.placement.getRotation());
  89.                     if (world.setBlockState(indexWorld, rotated, 3)) {
  90.                         TileEntity tile = world.getTileEntity(indexWorld);
  91.                         if (tile != null) {
  92.                             if (info.tileData != null) {
  93.                                 info.tileData.setInteger("x", indexWorld.getX());
  94.                                 info.tileData.setInteger("y", indexWorld.getY());
  95.                                 info.tileData.setInteger("z", indexWorld.getZ());
  96.                                 tile.readFromNBT(info.tileData);
  97.                                 tile.func_189667_a(this.placement.getRotation());
  98.                                 tile.func_189668_a(this.placement.getMirror());
  99.                             }
  100.                             if (tile instanceof TileEntityStructureDummy) {
  101.                                 ((TileEntityStructureDummy) tile).structureId = this.ID;
  102.                                 ((TileEntityStructureDummy) tile).placePointOffset = placementPointRotated.subtract(index);
  103.                             }
  104.                         }
  105.                     }
  106.                 }
  107.             }
  108. //      }
  109.         return true;
  110.     }
  111.    
  112.     public boolean removeBlocksFromWorld(World world, BlockPos sourceWorldPos, boolean breakWildcards) {
  113.         for (BlockInfo info : this.template) {
  114.             if (info.checkedOnly || (!breakWildcards && info.isWildcard)) continue;
  115.             BlockPos worldPos = StructureUtils.getTransformedPos(info.pos, this.placement).add(StructureUtils.getCorner(this.placement.getBoundingBox(), false));
  116.             if (worldPos.equals(sourceWorldPos)) continue;
  117.             //TODO: worldPos fails isVecInside but works fine math-wise
  118. //          else if (this.placement.getBoundingBox().isVecInside(worldPos)) {
  119.             else {
  120.                 world.setBlockToAir(worldPos);
  121.                 world.removeTileEntity(worldPos);
  122.             }
  123.         }
  124.         return true;
  125.     }
  126.    
  127.     public boolean checkStructureCompleteness(World world, BlockPos worldPos, EnumFacing facing) {
  128.         this.placement.setRotation(StructureUtils.getRotationFromDefault(this.facing, facing));
  129.         StructureUtils.setRotatedBoundingBox(this.placement, this.size, worldPos.subtract(this.placementPoint));
  130.         BlockPos min = StructureUtils.getCorner(this.placement.getBoundingBox(), false);
  131.         for (BlockInfo info : this.template) {
  132.             BlockPos idx = StructureUtils.getTransformedPos(info.pos, this.placement).add(min);
  133.             if (info.state.getBlock() instanceof BlockStructureVoid) continue;
  134.             IBlockState worldState = world.getBlockState(idx);
  135.             if (!info.state.equals(worldState)) return false;
  136.         }
  137.         return true;
  138.     }
  139.    
  140.     public boolean activateStructure(World world, BlockPos masterWorldPos, EntityPlayer player, EnumHand hand, ItemStack stack, EnumFacing side, float hitX, float hitY, float hitZ) {
  141.         return world.getBlockState(masterWorldPos).getBlock().onBlockActivated(world, masterWorldPos, world.getBlockState(masterWorldPos), player, hand, stack, side, hitX, hitY, hitZ);
  142.     }
  143.    
  144.     @Override
  145.     public String toString() {
  146.         return this.toString(false);
  147.     }
  148.    
  149.     public String toString(boolean full) {
  150.         return this.appendData(new ToStringBuilder(this, STYLE), full).toString();
  151.     }
  152.    
  153.     public ToStringBuilder appendData(ToStringBuilder builder, boolean full) {
  154.         builder.append("ID", this.ID);
  155.         builder.append("length", this.template.size());
  156.         builder.append("size", StringHelper.get(this.size));
  157.         builder.append("facing", this.facing);
  158.         builder.append("point", StringHelper.get(this.placementPoint));
  159.         builder.append("box", StringHelper.get(this.placement.getBoundingBox()));
  160.         builder.append("rot", this.placement.getRotation());
  161.         builder.append("mir", this.placement.getMirror());
  162.         if (full) {
  163.             this.template.forEach(builder::append);
  164.             builder.appendToString(String.format("%n"));
  165.         }
  166.         return builder;
  167.     }
  168.    
  169.     public static class BlockInfo {
  170.         public final BlockPos pos;
  171.         public final IBlockState state;
  172.         public final NBTTagCompound tileData;
  173.         public final boolean isWildcard;
  174.         public boolean checkedOnly = false;
  175.        
  176.         public BlockInfo(BlockPos pos, IBlockState state, NBTTagCompound tileData, boolean checkedOnly) {
  177.             this.pos = pos;
  178.             this.state = state;
  179.             this.tileData = tileData;
  180.             this.isWildcard = state.getBlock() instanceof BlockStructureVoid;
  181.             this.checkedOnly = checkedOnly;
  182.         }
  183.        
  184.         @Override
  185.         public String toString() {
  186.             return this.toString(false);
  187.         }
  188.        
  189.         public String toString(boolean startWithNewline) {
  190.             StringBuilder builder = new StringBuilder(startWithNewline ? "%n    " : "");
  191.             builder.append(StringHelper.get(this.pos));
  192.             builder.append(String.format("%s, %s, ", this.state, this.tileData != null ? this.tileData : "---"));
  193.             builder.append(String.format("wild: %b, checked only: %b", this.isWildcard, this.checkedOnly));
  194.             return builder.toString();
  195.         }
  196.     }
  197.    
  198.     public static class Builder {
  199.         public ResourceLocation id;
  200.         public EnumFacing facing;
  201.         public BlockPos size = BlockPos.ORIGIN;
  202.         public BlockPos placementPoint = BlockPos.ORIGIN;
  203.         public Map<Integer, Map<String, String>> colorMap = Maps.newHashMap();
  204.         private List<BlockInfo> normalBlocks = Lists.newArrayList();
  205.         private List<BlockInfo> tileBlocks = Lists.newArrayList();
  206.         private List<BlockInfo> otherBlocks = Lists.newArrayList();
  207.         private List<BlockInfo> template = Lists.newArrayList();
  208.        
  209.         public Builder(ResourceLocation id, BlockPos size, EnumFacing facing, BlockPos placementPoint) {
  210.             this.id = id;
  211.             this.size = size;
  212.             this.facing = facing;
  213.             this.placementPoint = placementPoint;
  214.         }
  215.        
  216.         public StructureTemplate processImage(File pngFile) {
  217.             try {
  218.                 BufferedImage bufferedImage = TextureUtil.readBufferedImage(new FileInputStream(pngFile));
  219.                 if (bufferedImage.getHeight() % this.size.getY() != 0) return null;
  220.                 Map<Integer, Map<String, IProperty>> colorToPropertiesMap = Maps.newHashMap();
  221.                 Map<String, IProperty> propertyMap = Maps.newHashMap();
  222.                 Map<Integer, ResourceLocation> colorToIdMap = Maps.newHashMap();
  223.                 this.colorMap.forEach((integer, map) -> colorToIdMap.put(integer, new ResourceLocation(map.remove("block"))));
  224.                 IBlockState state;
  225.                 for (int y = 0; y < this.size.getY(); y++) {
  226.                     for (int x = 0; x < this.size.getX(); x++) {
  227.                         for (int z = 0; z < this.size.getZ(); z++) {
  228.                             int color = bufferedImage.getRGB(x, z + (y * this.size.getZ()));
  229.                             TransitMod.logger.printf(Level.INFO, "(%s, %s, %s)|(%s, %s): color: %s", x, y, z, x, z + (y * this.size.getZ()), Integer.toHexString(bufferedImage.getRGB(x, z + (y * this.size.getZ()))).toUpperCase());
  230.                             if ((color & 0xFF000000) == 0) {
  231.                                 this.addToCorrectList(new BlockInfo(new BlockPos(x, y, z), Blocks.STRUCTURE_VOID.getDefaultState(), null, false));
  232.                                 continue;
  233.                             } else state = Block.REGISTRY.getObject(colorToIdMap.get(color)).getDefaultState();
  234.                             if (!colorToPropertiesMap.containsKey(color)) {
  235.                                 propertyMap.clear();
  236.                                 state.getPropertyNames().forEach(iProperty -> propertyMap.put(iProperty.getName(), iProperty));
  237.                                 colorToPropertiesMap.put(color, propertyMap);
  238.                             }
  239.                             for (Map.Entry<String, String> entry : this.colorMap.get(color).entrySet()) {
  240.                                 Optional optional = colorToPropertiesMap.get(color).get(entry.getKey()).parseValue(entry.getValue());
  241.                                 if (optional.isPresent()) state = state.withProperty(colorToPropertiesMap.get(color).get(entry.getKey()), (Comparable) optional.get());
  242.                             }
  243.                             this.addToCorrectList(new BlockInfo(new BlockPos(x, y, z), state, null, false));
  244.                         }
  245.                     }
  246.                 }
  247.                 this.template.clear();
  248.                 this.template.addAll(this.normalBlocks);
  249.                 this.template.addAll(this.tileBlocks);
  250.                 this.template.addAll(this.otherBlocks);
  251.                 StructureTemplate ret = new StructureTemplate(this.id, this.size, this.facing, this.placementPoint);
  252.                 ret.template = Lists.newArrayList(this.template);
  253.                 return ret;
  254.             } catch (IOException e) {
  255.                 TransitMod.logger.printf(Level.ERROR, "Failed to parse png file '%s'.", pngFile.getAbsolutePath());
  256.                 return null;
  257.             }
  258.         }
  259.        
  260.         private void addToCorrectList(BlockInfo info) {
  261.             if (info.state.getBlock().hasTileEntity(info.state) || info.state.getBlock() instanceof ITileEntityProvider) this.tileBlocks.add(info);
  262.             else if (!info.state.isFullBlock() && !info.state.isFullCube()) this.otherBlocks.add(info);
  263.             else this.normalBlocks.add(info);
  264.         }
  265.     }
  266. }
Advertisement
Add Comment
Please, Sign In to add comment