Advertisement
Guest User

Untitled

a guest
Aug 15th, 2017
110
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 31.09 KB | None | 0 0
  1. package com.minecolonies.structures.helpers;
  2.  
  3. import com.minecolonies.api.configuration.Configurations;
  4. import com.minecolonies.api.util.BlockUtils;
  5. import com.minecolonies.api.util.Log;
  6. import com.minecolonies.api.util.constant.Constants;
  7. import com.minecolonies.coremod.MineColonies;
  8. import com.minecolonies.coremod.blocks.ModBlocks;
  9. import com.minecolonies.coremod.colony.ColonyManager;
  10. import com.minecolonies.coremod.colony.Structures;
  11. import com.minecolonies.structures.fake.FakeEntity;
  12. import com.minecolonies.structures.fake.FakeWorld;
  13. import com.minecolonies.structures.lib.ModelHolder;
  14. import net.minecraft.block.Block;
  15. import net.minecraft.block.state.IBlockState;
  16. import net.minecraft.client.Minecraft;
  17. import net.minecraft.client.renderer.GlStateManager;
  18. import net.minecraft.client.renderer.RenderHelper;
  19. import net.minecraft.client.renderer.Tessellator;
  20. import net.minecraft.client.renderer.VertexBuffer;
  21. import net.minecraft.client.renderer.block.model.BakedQuad;
  22. import net.minecraft.client.renderer.block.model.IBakedModel;
  23. import net.minecraft.client.renderer.texture.TextureMap;
  24. import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
  25. import net.minecraft.entity.Entity;
  26. import net.minecraft.entity.EntityList;
  27. import net.minecraft.entity.player.EntityPlayer;
  28. import net.minecraft.nbt.CompressedStreamTools;
  29. import net.minecraft.nbt.NBTTagCompound;
  30. import net.minecraft.server.MinecraftServer;
  31. import net.minecraft.tileentity.TileEntity;
  32. import net.minecraft.util.*;
  33. import net.minecraft.util.math.BlockPos;
  34. import net.minecraft.util.math.Vec3d;
  35. import net.minecraft.world.World;
  36. import net.minecraft.world.gen.structure.template.PlacementSettings;
  37. import net.minecraft.world.gen.structure.template.Template;
  38. import net.minecraftforge.client.ForgeHooksClient;
  39. import net.minecraftforge.client.MinecraftForgeClient;
  40. import net.minecraftforge.client.model.pipeline.LightUtil;
  41. import net.minecraftforge.fml.common.FMLCommonHandler;
  42. import org.apache.commons.io.IOUtils;
  43. import org.jetbrains.annotations.NotNull;
  44. import org.lwjgl.opengl.GL11;
  45.  
  46. import javax.annotation.Nullable;
  47. import javax.xml.bind.DatatypeConverter;
  48. import java.io.*;
  49. import java.security.MessageDigest;
  50. import java.security.NoSuchAlgorithmException;
  51. import java.util.List;
  52. import java.util.zip.GZIPInputStream;
  53. import java.util.zip.GZIPOutputStream;
  54.  
  55. import static com.minecolonies.api.util.constant.Suppression.RESOURCES_SHOULD_BE_CLOSED;
  56.  
  57. /**
  58. * Structure class, used to store, create, get structures.
  59. */
  60. public class Structure
  61. {
  62. /**
  63. * Rotation by 90°.
  64. */
  65. private static final double NINETY_DEGREES = 90D;
  66.  
  67. /**
  68. * Rotation by 270°.
  69. */
  70. private static final double TWO_HUNDRED_SEVENTY_DEGREES = 270D;
  71.  
  72. /**
  73. * Rotation by 180°.
  74. */
  75. private static final double ONE_HUNDED_EIGHTY_DEGREES = 270D;
  76.  
  77. /**
  78. * Used for scale.
  79. */
  80. private static final double SCALE = 1.001;
  81.  
  82. /**
  83. * Size of the buffer.
  84. */
  85. private static final int BUFFER_SIZE = 1024;
  86.  
  87. /**
  88. * Template of the structure.
  89. */
  90. private Template template;
  91. private Minecraft mc;
  92. private PlacementSettings settings;
  93. private String md5;
  94.  
  95. /**
  96. * Constuctor of Structure, tries to create a new structure.
  97. *
  98. * @param world with world.
  99. * @param structureName name of the structure (at stored location).
  100. * @param settings it's settings.
  101. */
  102. public Structure(@Nullable final World world, final String structureName, final PlacementSettings settings)
  103. {
  104. String correctStructureName = structureName;
  105. if (world == null || world.isRemote)
  106. {
  107. this.settings = settings;
  108. this.mc = Minecraft.getMinecraft();
  109. }
  110.  
  111. InputStream inputStream = null;
  112. try
  113. {
  114.  
  115. //Try the cache first
  116. if (Structures.hasMD5(correctStructureName))
  117. {
  118. inputStream = Structure.getStream(Structures.SCHEMATICS_CACHE + '/' + Structures.getMD5(correctStructureName));
  119. if (inputStream != null)
  120. {
  121. correctStructureName = Structures.SCHEMATICS_CACHE + '/' + Structures.getMD5(correctStructureName);
  122. }
  123. }
  124.  
  125. if (inputStream == null)
  126. {
  127. inputStream = Structure.getStream(correctStructureName);
  128. }
  129.  
  130. if (inputStream == null)
  131. {
  132. Log.getLogger().warn(String.format("Failed to load template %s", correctStructureName));
  133. return;
  134. }
  135.  
  136. try
  137. {
  138. this.md5 = Structure.calculateMD5(Structure.getStream(correctStructureName));
  139. this.template = readTemplateFromStream(inputStream);
  140. }
  141. catch (final IOException e)
  142. {
  143. Log.getLogger().warn(String.format("Failed to load template %s", correctStructureName), e);
  144. }
  145. }
  146. finally
  147. {
  148. IOUtils.closeQuietly(inputStream);
  149. }
  150. }
  151.  
  152. /**
  153. * Get the file representation of the cached schematics' folder.
  154. *
  155. * @return the folder for the cached schematics
  156. */
  157. @Nullable
  158. public static File getCachedSchematicsFolder()
  159. {
  160. if (FMLCommonHandler.instance().getMinecraftServerInstance() == null)
  161. {
  162. if (ColonyManager.getServerUUID() != null)
  163. {
  164. return new File(Minecraft.getMinecraft().mcDataDir, Constants.MOD_ID + "/" + ColonyManager.getServerUUID());
  165. }
  166. else
  167. {
  168. Log.getLogger().error("ColonyManager.getServerUUID() => null this should not happen");
  169. return null;
  170. }
  171. }
  172. return new File(FMLCommonHandler.instance().getMinecraftServerInstance().getEntityWorld().getSaveHandler().getWorldDirectory()
  173. + "/" + Constants.MOD_ID);
  174. }
  175.  
  176. /**
  177. * get the schematic folder for the client.
  178. *
  179. * @return the client folder.
  180. */
  181. public static File getClientSchematicsFolder()
  182. {
  183. return new File(Minecraft.getMinecraft().mcDataDir, Constants.MOD_ID);
  184. }
  185.  
  186. /**
  187. * get a InputStream for a give structureName.
  188. * <p>
  189. * Look into the following director (in order):
  190. * - scan
  191. * - cache
  192. * - schematics folder
  193. * - jar
  194. * It should be the exact opposite that the way used to build the list.
  195. *
  196. * Suppressing Sonar Rule squid:S2095
  197. * This rule enforces "Close this InputStream"
  198. * But in this case the rule does not apply because
  199. * We are returning the stream and that is reasonable
  200. *
  201. * @param structureName name of the structure to load
  202. * @return the input stream or null
  203. */
  204. @SuppressWarnings(RESOURCES_SHOULD_BE_CLOSED)
  205. @Nullable
  206. public static InputStream getStream(final String structureName)
  207. {
  208. final Structures.StructureName sn = new Structures.StructureName(structureName);
  209. InputStream inputstream = null;
  210. if (Structures.SCHEMATICS_CACHE.equals(sn.getPrefix()))
  211. {
  212. return Structure.getStreamFromFolder(Structure.getCachedSchematicsFolder(), structureName);
  213. }
  214. else if (Structures.SCHEMATICS_SCAN.equals(sn.getPrefix()))
  215. {
  216. return Structure.getStreamFromFolder(Structure.getClientSchematicsFolder(), structureName);
  217. }
  218. else if (!Structures.SCHEMATICS_PREFIX.equals(sn.getPrefix()))
  219. {
  220. return null;
  221. }
  222. else
  223. {
  224. //Look in the folder first
  225. inputstream = Structure.getStreamFromFolder(MineColonies.proxy.getSchematicsFolder(), structureName);
  226. if (inputstream == null && !Configurations.gameplay.ignoreSchematicsFromJar)
  227. {
  228. inputstream = Structure.getStreamFromJar(structureName);
  229. }
  230. }
  231.  
  232. if (inputstream == null)
  233. {
  234. Log.getLogger().warn("Structure: Couldn't find any structure with this name " + structureName);
  235. }
  236.  
  237. return inputstream;
  238. }
  239.  
  240. /**
  241. * get a input stream for a schematic within a specif folder.
  242. *
  243. * @param folder where to load it from.
  244. * @param structureName name of the structure to load.
  245. * @return the input stream or null
  246. */
  247. @Nullable
  248. private static InputStream getStreamFromFolder(@Nullable final File folder, final String structureName)
  249. {
  250. if (folder == null)
  251. {
  252. return null;
  253. }
  254. final File nbtFile = new File(folder.getPath() + "/" + structureName + ".nbt");
  255. try
  256. {
  257. if (folder.exists())
  258. {
  259. //We need to check that we stay within the correct folder
  260. if (!nbtFile.toURI().normalize().getPath().startsWith(folder.toURI().normalize().getPath()))
  261. {
  262. Log.getLogger().error("Structure: Illegal structure name \"" + structureName + "\"");
  263. return null;
  264. }
  265. if (nbtFile.exists())
  266. {
  267. return new FileInputStream(nbtFile);
  268. }
  269. }
  270. }
  271. catch (final FileNotFoundException e)
  272. {
  273. //we should will never go here
  274. Log.getLogger().error("Structure.getStreamFromFolder", e);
  275. }
  276. return null;
  277. }
  278.  
  279. /**
  280. * get a input stream for a schematic from jar.
  281. *
  282. * @param structureName name of the structure to load from the jar.
  283. * @return the input stream or null
  284. */
  285. @Nullable
  286. private static InputStream getStreamFromJar(final String structureName)
  287. {
  288. return MinecraftServer.class.getResourceAsStream("/assets/" + Constants.MOD_ID + '/' + structureName + ".nbt");
  289. }
  290.  
  291. /**
  292. * get the Template from the structure.
  293. *
  294. * @return The templae for the structure
  295. */
  296. public Template getTemplate()
  297. {
  298. return this.template;
  299. }
  300.  
  301. /**
  302. * Convert an InputStream into and array of bytes.
  303. *
  304. * @param stream to be converted to bytes array
  305. * @return the array of bytes, array is size 0 when the stream is null
  306. */
  307. public static byte[] getStreamAsByteArray(final InputStream stream)
  308. {
  309. if (stream == null)
  310. {
  311. Log.getLogger().info("Structure.getStreamAsByteArray: stream is null this should not happen");
  312. return new byte[0];
  313. }
  314. try
  315. {
  316. final ByteArrayOutputStream buffer = new ByteArrayOutputStream();
  317.  
  318. int nRead;
  319. final byte[] data = new byte[BUFFER_SIZE];
  320.  
  321. while ((nRead = stream.read(data, 0, data.length)) != -1)
  322. {
  323. buffer.write(data, 0, nRead);
  324. }
  325. return buffer.toByteArray();
  326. }
  327. catch (@NotNull final IOException e)
  328. {
  329. Log.getLogger().trace(e);
  330. }
  331. return new byte[0];
  332. }
  333.  
  334. /**
  335. * Calculate the MD5 hash for a template from an inputstream.
  336. *
  337. * @param stream to which we want the MD5 hash
  338. * @return the MD5 hash string or null
  339. */
  340. public static String calculateMD5(final InputStream stream)
  341. {
  342. if (stream == null)
  343. {
  344. Log.getLogger().error("Structure.calculateMD5: stream is null, this should not happen");
  345. return null;
  346. }
  347. return calculateMD5(getStreamAsByteArray(stream));
  348. }
  349.  
  350. /**
  351. * Calculate the MD5 hash of a byte array
  352. *
  353. * @param bytes array
  354. * @return the MD5 hash string or null
  355. */
  356. public static String calculateMD5(final byte[] bytes)
  357. {
  358. try
  359. {
  360. final MessageDigest md = MessageDigest.getInstance("MD5");
  361. return DatatypeConverter.printHexBinary(md.digest(bytes));
  362. }
  363. catch (@NotNull final NoSuchAlgorithmException e)
  364. {
  365. Log.getLogger().trace(e);
  366. }
  367.  
  368. return null;
  369. }
  370.  
  371. /**
  372. * Compare the md5 from the structure with an other md5 hash.
  373. *
  374. * @param otherMD5 to compare with
  375. * @return whether the otherMD5 match, return false if md5 is null
  376. */
  377. public boolean isCorrectMD5(final String otherMD5)
  378. {
  379. Log.getLogger().info("isCorrectMD5: md5:" + md5 + " other:" + otherMD5);
  380. if (md5 == null || otherMD5 == null)
  381. {
  382. return false;
  383. }
  384. return md5.compareTo(otherMD5) == 0;
  385. }
  386.  
  387. public static byte[] compress(final byte[] data)
  388. {
  389. final ByteArrayOutputStream byteStream = new ByteArrayOutputStream(data.length);
  390. try (GZIPOutputStream zipStream = new GZIPOutputStream(byteStream))
  391. {
  392. zipStream.write(data);
  393. }
  394. catch (@NotNull final IOException e)
  395. {
  396. Log.getLogger().error("Could not compress the data", e);
  397. }
  398. return byteStream.toByteArray();
  399. }
  400.  
  401. public static byte[] uncompress(final byte[] data)
  402. {
  403. final byte[] buffer = new byte[BUFFER_SIZE];
  404. final ByteArrayOutputStream out = new ByteArrayOutputStream();
  405. try (ByteArrayInputStream byteStream = new ByteArrayInputStream(data);
  406. GZIPInputStream zipStream = new GZIPInputStream(byteStream))
  407. {
  408. int len;
  409. while ((len = zipStream.read(buffer)) > 0)
  410. {
  411. out.write(buffer, 0, len);
  412. }
  413. }
  414. catch (@NotNull final IOException e)
  415. {
  416. Log.getLogger().warn("Could not uncompress data", e);
  417. }
  418.  
  419. return out.toByteArray();
  420. }
  421.  
  422. /**
  423. * Reads a template from an inputstream.
  424. */
  425. private static Template readTemplateFromStream(final InputStream stream) throws IOException
  426. {
  427. final NBTTagCompound nbttagcompound = CompressedStreamTools.readCompressed(stream);
  428. final Template template = new Template();
  429. template.read(nbttagcompound);
  430. return template;
  431. }
  432.  
  433. /**
  434. * Checks if the template is null.
  435. *
  436. * @return true if the template is null.
  437. */
  438. public boolean isTemplateMissing()
  439. {
  440. return template == null;
  441. }
  442.  
  443. public Template.BlockInfo[] getBlockInfo()
  444. {
  445. Template.BlockInfo[] blockList = new Template.BlockInfo[template.blocks.size()];
  446. blockList = template.blocks.toArray(blockList);
  447. return blockList;
  448. }
  449.  
  450. /**
  451. * Get entity array at position in world.
  452. *
  453. * @param world the world.
  454. * @param pos the position.
  455. * @return the entity array.
  456. */
  457. public Entity[] getEntityInfo(final World world, final BlockPos pos)
  458. {
  459. Template.EntityInfo[] entityInfoList = new Template.EntityInfo[template.entities.size()];
  460. entityInfoList = template.blocks.toArray(entityInfoList);
  461.  
  462. final Entity[] entityList = null;
  463.  
  464. for (int i = 0; i < entityInfoList.length; i++)
  465. {
  466. final Entity finalEntity = EntityList.createEntityFromNBT(entityInfoList[i].entityData, world);
  467. final Vec3d entityVec = entityInfoList[i].pos.add(new Vec3d(pos));
  468. finalEntity.setPosition(entityVec.xCoord, entityVec.yCoord, entityVec.zCoord);
  469. }
  470.  
  471. return entityList;
  472. }
  473.  
  474. /**
  475. * Get size of structure.
  476. *
  477. * @param rotation with rotation.
  478. * @return size as blockPos (x = length, z = width, y = height).
  479. */
  480. public BlockPos getSize(final Rotation rotation)
  481. {
  482. return this.template.transformedSize(rotation);
  483. }
  484.  
  485. public void setPlacementSettings(final PlacementSettings settings)
  486. {
  487. this.settings = settings;
  488. }
  489.  
  490. /**
  491. * Renders the structure.
  492. *
  493. * @param startingPos the start pos to render.
  494. * @param clientWorld the world of the client.
  495. * @param player the player object.
  496. * @param partialTicks the partial ticks.
  497. */
  498. public void renderStructure(@NotNull final BlockPos startingPos, @NotNull final World clientWorld, @NotNull final EntityPlayer player, final float partialTicks)
  499. {
  500. final Template.BlockInfo[] blockList = this.getBlockInfoWithSettings(this.settings);
  501. final Entity[] entityList = this.getEntityInfoWithSettings(clientWorld, startingPos, this.settings);
  502.  
  503. for (final Template.BlockInfo aBlockList : blockList)
  504. {
  505. Block block = aBlockList.blockState.getBlock();
  506. IBlockState iblockstate = aBlockList.blockState;
  507.  
  508. if (block == ModBlocks.blockSubstitution)
  509. {
  510. continue;
  511. }
  512.  
  513. if (block == ModBlocks.blockSolidSubstitution)
  514. {
  515. iblockstate = BlockUtils.getSubstitutionBlockAtWorld(clientWorld, startingPos);
  516. block = iblockstate.getBlock();
  517. }
  518.  
  519. final BlockPos blockpos = aBlockList.pos.add(startingPos);
  520. final IBlockState iBlockExtendedState = block.getExtendedState(iblockstate, clientWorld, blockpos);
  521. final IBakedModel ibakedmodel = Minecraft.getMinecraft().getBlockRendererDispatcher().getModelForState(iblockstate);
  522. TileEntity tileentity = null;
  523. if (block.hasTileEntity(iblockstate) && aBlockList.tileentityData != null)
  524. {
  525. tileentity = block.createTileEntity(clientWorld, iblockstate);
  526. tileentity.readFromNBT(aBlockList.tileentityData);
  527. }
  528. final ModelHolder models = new ModelHolder(blockpos, iblockstate, iBlockExtendedState, tileentity, ibakedmodel);
  529. getQuads(models, models.quads);
  530. this.renderGhost(clientWorld, models, player, partialTicks);
  531. }
  532.  
  533. for (final Entity anEntityList : entityList)
  534. {
  535. if (anEntityList != null)
  536. {
  537. Minecraft.getMinecraft().getRenderManager().renderEntityStatic(anEntityList, 0.0F, true);
  538. }
  539. }
  540. }
  541.  
  542. /**
  543. * Get blockInfo of structure with a specific setting.
  544. *
  545. * @param settings the setting.
  546. * @return the block info array.
  547. */
  548. public Template.BlockInfo[] getBlockInfoWithSettings(final PlacementSettings settings)
  549. {
  550. Template.BlockInfo[] blockList = new Template.BlockInfo[template.blocks.size()];
  551. blockList = template.blocks.toArray(blockList);
  552.  
  553. for (int i = 0; i < blockList.length; i++)
  554. {
  555. final IBlockState finalState = blockList[i].blockState.withMirror(settings.getMirror()).withRotation(settings.getRotation());
  556. final BlockPos finalPos = Template.transformedBlockPos(settings, blockList[i].pos);
  557. final Template.BlockInfo finalInfo = new Template.BlockInfo(finalPos, finalState, blockList[i].tileentityData);
  558. blockList[i] = finalInfo;
  559. }
  560. return blockList;
  561. }
  562.  
  563. /**
  564. * Get entity info with specific setting.
  565. *
  566. * @param world world the entity is in.
  567. * @param pos the position it is at.
  568. * @param settings the settings.
  569. * @return the entity info aray.
  570. */
  571. public Entity[] getEntityInfoWithSettings(final World world, final BlockPos pos, final PlacementSettings settings)
  572. {
  573. Template.EntityInfo[] entityInfoList = new Template.EntityInfo[template.entities.size()];
  574. entityInfoList = template.entities.toArray(entityInfoList);
  575.  
  576. final Entity[] entityList = new Entity[entityInfoList.length];
  577.  
  578. for (int i = 0; i < entityInfoList.length; i++)
  579. {
  580. final Entity finalEntity = EntityList.createEntityFromNBT(entityInfoList[i].entityData, world);
  581. final Vec3d entityVec = Structure.transformedVec3d(settings, entityInfoList[i].pos).add(new Vec3d(pos));
  582.  
  583. if (finalEntity != null)
  584. {
  585. finalEntity.prevRotationYaw = (float) (finalEntity.getMirroredYaw(settings.getMirror()) - NINETY_DEGREES);
  586. final double rotation =
  587. (double) finalEntity.getMirroredYaw(settings.getMirror()) + ((double) finalEntity.rotationYaw - finalEntity.getRotatedYaw(settings.getRotation()));
  588. finalEntity.setLocationAndAngles(entityVec.xCoord, entityVec.yCoord, entityVec.zCoord, (float) rotation, finalEntity.rotationPitch);
  589. }
  590. entityList[i] = finalEntity;
  591. }
  592.  
  593. return entityList;
  594. }
  595.  
  596. public static void getQuads(final ModelHolder holder, final List<BakedQuad> quads)
  597. {
  598. if (holder.actualState.getRenderType() == EnumBlockRenderType.MODEL)
  599. {
  600. final BlockRenderLayer originalLayer = MinecraftForgeClient.getRenderLayer();
  601.  
  602. for (final BlockRenderLayer layer : BlockRenderLayer.values())
  603. {
  604. if (holder.actualState.getBlock().canRenderInLayer(holder.actualState, layer))
  605. {
  606. ForgeHooksClient.setRenderLayer(layer);
  607.  
  608. for (final EnumFacing facing : EnumFacing.values())
  609. {
  610. quads.addAll(holder.model.getQuads(holder.extendedState, facing, 0));
  611. }
  612.  
  613. quads.addAll(holder.model.getQuads(holder.extendedState, null, 0));
  614. }
  615. }
  616.  
  617. ForgeHooksClient.setRenderLayer(originalLayer);
  618. }
  619. }
  620.  
  621. public void renderGhost(final World world, final ModelHolder holder, final EntityPlayer player, final float partialTicks)
  622. {
  623. final boolean existingModel = !this.mc.world.isAirBlock(holder.pos);
  624.  
  625. final IBlockState actualState = holder.actualState;
  626. final Block block = actualState.getBlock();
  627.  
  628. if (actualState.getRenderType() == EnumBlockRenderType.MODEL)
  629. {
  630. final BlockRenderLayer originalLayer = MinecraftForgeClient.getRenderLayer();
  631.  
  632. for (final BlockRenderLayer layer : BlockRenderLayer.values())
  633. {
  634. if (block.canRenderInLayer(actualState, layer))
  635. {
  636. this.mc.getTextureManager().bindTexture(TextureMap.LOCATION_BLOCKS_TEXTURE);
  637. ForgeHooksClient.setRenderLayer(layer);
  638. this.renderGhostBlock(world, holder, player, layer, existingModel, partialTicks);
  639. holder.setRendered(true);
  640. }
  641. }
  642.  
  643. ForgeHooksClient.setRenderLayer(originalLayer);
  644. }
  645.  
  646. if (holder.te != null && !holder.isRendered())
  647. {
  648. final TileEntity te = holder.te;
  649. te.setPos(holder.pos);
  650. final FakeWorld fakeWorld = new FakeWorld(holder.actualState, world.getSaveHandler(), world.getWorldInfo(), world.provider, world.profiler, true);
  651. te.setWorld(fakeWorld);
  652. final int pass = 0;
  653.  
  654. if (te.shouldRenderInPass(pass))
  655. {
  656. final TileEntityRendererDispatcher terd = TileEntityRendererDispatcher.instance;
  657. terd.prepare(fakeWorld,
  658. Minecraft.getMinecraft().renderEngine,
  659. Minecraft.getMinecraft().fontRenderer,
  660. new FakeEntity(fakeWorld),
  661. null,
  662. 0.0F);
  663. GL11.glPushMatrix();
  664. terd.renderEngine = Minecraft.getMinecraft().renderEngine;
  665. terd.preDrawBatch();
  666. GL11.glColor4f(1F, 1F, 1F, 1F);
  667. terd.renderTileEntity(te, partialTicks, -1);
  668. terd.drawBatch(pass);
  669. GL11.glPopMatrix();
  670. }
  671. }
  672. }
  673.  
  674. /**
  675. * Transform a Vec3d with placement settings.
  676. *
  677. * @param settings the settings.
  678. * @param vec the vector.
  679. * @return the new vector.
  680. */
  681. public static Vec3d transformedVec3d(final PlacementSettings settings, final Vec3d vec)
  682. {
  683. final Mirror mirrorIn = settings.getMirror();
  684. final Rotation rotationIn = settings.getRotation();
  685. double xCoord = vec.xCoord;
  686. final double yCoord = vec.yCoord;
  687. double zCoord = vec.zCoord;
  688. boolean flag = true;
  689.  
  690. switch (mirrorIn)
  691. {
  692. case LEFT_RIGHT:
  693. zCoord = 1.0D - zCoord;
  694. break;
  695. case FRONT_BACK:
  696. xCoord = 1.0D - xCoord;
  697. break;
  698. default:
  699. flag = false;
  700. }
  701.  
  702. switch (rotationIn)
  703. {
  704. case COUNTERCLOCKWISE_90:
  705. return new Vec3d(zCoord, yCoord, 1.0D - xCoord);
  706. case CLOCKWISE_90:
  707. return new Vec3d(1.0D - zCoord, yCoord, xCoord);
  708. case CLOCKWISE_180:
  709. return new Vec3d(1.0D - xCoord, yCoord, 1.0D - zCoord);
  710. default:
  711. return flag ? new Vec3d(xCoord, yCoord, zCoord) : vec;
  712. }
  713. }
  714.  
  715. private void renderGhostBlock(
  716. final World world,
  717. final ModelHolder holder,
  718. final EntityPlayer player,
  719. final BlockRenderLayer layer,
  720. final boolean existingModel,
  721. final float partialTicks)
  722. {
  723. final double dx = player.lastTickPosX + (player.posX - player.lastTickPosX) * partialTicks;
  724. final double dy = player.lastTickPosY + (player.posY - player.lastTickPosY) * partialTicks;
  725. final double dz = player.lastTickPosZ + (player.posZ - player.lastTickPosZ) * partialTicks;
  726. final BlockPos pos = holder.pos;
  727.  
  728. GlStateManager.pushMatrix();
  729. GlStateManager.translate(pos.getX() - dx, pos.getY() - dy, pos.getZ() - dz);
  730.  
  731. if (existingModel)
  732. {
  733. GlStateManager.scale(SCALE, SCALE, SCALE);
  734. }
  735.  
  736. RenderHelper.disableStandardItemLighting();
  737.  
  738. if (layer == BlockRenderLayer.CUTOUT)
  739. {
  740. this.mc.getTextureManager().getTexture(TextureMap.LOCATION_BLOCKS_TEXTURE).setBlurMipmap(false, false);
  741. }
  742.  
  743. GlStateManager.color(1F, 1F, 1F, 1F);
  744.  
  745. final int alpha = ((int) (1.0D * 0xFF)) << 24;
  746.  
  747. GlStateManager.enableBlend();
  748. GlStateManager.enableTexture2D();
  749.  
  750. GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
  751. GlStateManager.colorMask(false, false, false, false);
  752. this.renderModel(world, holder, pos, alpha);
  753.  
  754. GlStateManager.colorMask(true, true, true, true);
  755. GlStateManager.depthFunc(GL11.GL_LEQUAL);
  756. this.renderModel(world, holder, pos, alpha);
  757.  
  758. GlStateManager.disableBlend();
  759.  
  760. if (layer == BlockRenderLayer.CUTOUT)
  761. {
  762. this.mc.getTextureManager().getTexture(TextureMap.LOCATION_BLOCKS_TEXTURE).restoreLastBlurMipmap();
  763. }
  764.  
  765. GlStateManager.popMatrix();
  766. }
  767.  
  768. private void renderModel(final World world, final ModelHolder holder, final BlockPos pos, final int alpha)
  769. {
  770. for (final EnumFacing facing : EnumFacing.values())
  771. {
  772. this.renderQuads(world, holder.actualState, pos, holder.model.getQuads(holder.extendedState, facing, 0), alpha);
  773. }
  774.  
  775. this.renderQuads(world, holder.actualState, pos, holder.model.getQuads(holder.extendedState, null, 0), alpha);
  776. }
  777.  
  778. private void renderQuads(final World world, final IBlockState actualState, final BlockPos pos, final List<BakedQuad> quads, final int alpha)
  779. {
  780. final Tessellator tessellator = Tessellator.getInstance();
  781. final VertexBuffer buffer = tessellator.getBuffer();
  782.  
  783. for (final BakedQuad quad : quads)
  784. {
  785. buffer.begin(GL11.GL_QUADS, quad.getFormat());
  786.  
  787. final int color = quad.hasTintIndex() ? this.getTint(world, actualState, pos, alpha, quad.getTintIndex()) : (alpha | 0xffffff);
  788.  
  789. LightUtil.renderQuadColor(buffer, quad, color);
  790.  
  791. tessellator.draw();
  792. }
  793. }
  794.  
  795. private int getTint(final World world, final IBlockState actualState, final BlockPos pos, final int alpha, final int tintIndex)
  796. {
  797. return alpha | this.mc.getBlockColors().colorMultiplier(actualState, world, pos, tintIndex);
  798. }
  799.  
  800. /**
  801. * Get entity info with specific setting.
  802. *
  803. * @param entityInfo the entity to transform.
  804. * @param world world the entity is in.
  805. * @param pos the position it is at.
  806. * @param settings the settings.
  807. * @return the entity info aray.
  808. */
  809. public Template.EntityInfo transformEntityInfoWithSettings(final Template.EntityInfo entityInfo, final World world, final BlockPos pos, final PlacementSettings settings)
  810. {
  811. final Entity finalEntity = EntityList.createEntityFromNBT(entityInfo.entityData, world);
  812.  
  813. //err might be here? only use pos? or don't add?
  814. final Vec3d entityVec = Structure.transformedVec3d(settings, entityInfo.pos).add(new Vec3d(pos));
  815.  
  816. if (finalEntity != null)
  817. {
  818. finalEntity.prevRotationYaw = (float) (finalEntity.getMirroredYaw(settings.getMirror()) - NINETY_DEGREES);
  819. final double rotationYaw
  820. = (double) finalEntity.getMirroredYaw(settings.getMirror()) + ((double) finalEntity.rotationYaw - (double) finalEntity.getRotatedYaw(settings.getRotation()));
  821.  
  822. finalEntity.setLocationAndAngles(entityVec.xCoord, entityVec.yCoord, entityVec.zCoord,
  823. (float) rotationYaw, finalEntity.rotationPitch);
  824.  
  825. final NBTTagCompound nbttagcompound = new NBTTagCompound();
  826. finalEntity.writeToNBTOptional(nbttagcompound);
  827. return new Template.EntityInfo(entityInfo.pos, entityInfo.blockPos, nbttagcompound);
  828. }
  829.  
  830. return null;
  831. }
  832.  
  833. /**
  834. * Transforms the entity's current yaw with the given Rotation and returns it. This does not have a side-effect.
  835. *
  836. * @param transformRotation the incoming rotation.
  837. * @param previousYaw the previous rotation yaw.
  838. * @return the new rotation yaw.
  839. */
  840. public double getRotatedYaw(final Rotation transformRotation, final double previousYaw)
  841. {
  842. switch (transformRotation)
  843. {
  844. case CLOCKWISE_180:
  845. return previousYaw + NINETY_DEGREES;
  846. case COUNTERCLOCKWISE_90:
  847. return previousYaw + TWO_HUNDRED_SEVENTY_DEGREES;
  848. case CLOCKWISE_90:
  849. return previousYaw + ONE_HUNDED_EIGHTY_DEGREES;
  850. default:
  851. return previousYaw;
  852. }
  853. }
  854.  
  855. /**
  856. * Get all additional entities.
  857. *
  858. * @return list of entities.
  859. */
  860. public List<Template.EntityInfo> getTileEntities()
  861. {
  862. return template.entities;
  863. }
  864.  
  865. /**
  866. * Get the Placement settings of the structure.
  867. *
  868. * @return the settings.
  869. */
  870. public PlacementSettings getSettings()
  871. {
  872. return settings;
  873. }
  874. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement