PageRenderTime 47ms CodeModel.GetById 10ms RepoModel.GetById 0ms app.codeStats 1ms

/newcode/src/com/prupe/mcpatcher/ctm/TileOverride.java

https://bitbucket.org/Freso/mcpatcher
Java | 724 lines | 633 code | 75 blank | 16 comment | 190 complexity | aa1fc0a8624537d90f86f363c2975af6 MD5 | raw file
  1. package com.prupe.mcpatcher.ctm;
  2. import com.prupe.mcpatcher.MCLogger;
  3. import com.prupe.mcpatcher.MCPatcherUtils;
  4. import com.prupe.mcpatcher.TexturePackAPI;
  5. import com.prupe.mcpatcher.TileLoader;
  6. import net.minecraft.src.Block;
  7. import net.minecraft.src.IBlockAccess;
  8. import net.minecraft.src.Icon;
  9. import net.minecraft.src.ResourceLocation;
  10. import java.lang.reflect.Method;
  11. import java.util.*;
  12. import java.util.regex.Matcher;
  13. import java.util.regex.Pattern;
  14. abstract class TileOverride implements ITileOverride {
  15. private static final MCLogger logger = MCLogger.getLogger(MCPatcherUtils.CONNECTED_TEXTURES, "CTM");
  16. static final int BOTTOM_FACE = 0; // 0, -1, 0
  17. static final int TOP_FACE = 1; // 0, 1, 0
  18. static final int NORTH_FACE = 2; // 0, 0, -1
  19. static final int SOUTH_FACE = 3; // 0, 0, 1
  20. static final int WEST_FACE = 4; // -1, 0, 0
  21. static final int EAST_FACE = 5; // 1, 0, 0
  22. static final int REL_L = 0;
  23. static final int REL_DL = 1;
  24. static final int REL_D = 2;
  25. static final int REL_DR = 3;
  26. static final int REL_R = 4;
  27. static final int REL_UR = 5;
  28. static final int REL_U = 6;
  29. static final int REL_UL = 7;
  30. private static final int META_MASK = 0xffff;
  31. private static final int ORIENTATION_U_D = 0;
  32. private static final int ORIENTATION_E_W = 1 << 16;
  33. private static final int ORIENTATION_N_S = 2 << 16;
  34. private static final int ORIENTATION_E_W_2 = 3 << 16;
  35. private static final int ORIENTATION_N_S_2 = 4 << 16;
  36. private static final int[][] ROTATE_UV_MAP = new int[][]{
  37. {WEST_FACE, EAST_FACE, NORTH_FACE, SOUTH_FACE, TOP_FACE, BOTTOM_FACE, 2, -2, 2, -2, 0, 0},
  38. {NORTH_FACE, SOUTH_FACE, TOP_FACE, BOTTOM_FACE, WEST_FACE, EAST_FACE, 0, 0, 0, 0, -2, 2},
  39. {WEST_FACE, EAST_FACE, NORTH_FACE, SOUTH_FACE, TOP_FACE, BOTTOM_FACE, 2, -2, -2, -2, 0, 0},
  40. {NORTH_FACE, SOUTH_FACE, TOP_FACE, BOTTOM_FACE, WEST_FACE, EAST_FACE, 0, 0, 0, 0, -2, -2},
  41. };
  42. private static final int[] GO_DOWN = new int[]{0, -1, 0};
  43. private static final int[] GO_UP = new int[]{0, 1, 0};
  44. private static final int[] GO_NORTH = new int[]{0, 0, -1};
  45. private static final int[] GO_SOUTH = new int[]{0, 0, 1};
  46. private static final int[] GO_WEST = new int[]{-1, 0, 0};
  47. private static final int[] GO_EAST = new int[]{1, 0, 0};
  48. private static final int[][] NORMALS = new int[][]{
  49. GO_DOWN,
  50. GO_UP,
  51. GO_NORTH,
  52. GO_SOUTH,
  53. GO_WEST,
  54. GO_EAST,
  55. };
  56. // NEIGHBOR_OFFSETS[a][b][c] = offset from starting block
  57. // a: face 0-5
  58. // b: neighbor 0-7
  59. // 7 6 5
  60. // 0 * 4
  61. // 1 2 3
  62. // c: coordinate (x,y,z) 0-2
  63. protected static final int[][][] NEIGHBOR_OFFSET = new int[][][]{
  64. // BOTTOM_FACE
  65. {
  66. GO_WEST,
  67. add(GO_WEST, GO_SOUTH),
  68. GO_SOUTH,
  69. add(GO_EAST, GO_SOUTH),
  70. GO_EAST,
  71. add(GO_EAST, GO_NORTH),
  72. GO_NORTH,
  73. add(GO_WEST, GO_NORTH),
  74. },
  75. // TOP_FACE
  76. {
  77. GO_WEST,
  78. add(GO_WEST, GO_SOUTH),
  79. GO_SOUTH,
  80. add(GO_EAST, GO_SOUTH),
  81. GO_EAST,
  82. add(GO_EAST, GO_NORTH),
  83. GO_NORTH,
  84. add(GO_WEST, GO_NORTH),
  85. },
  86. // NORTH_FACE
  87. {
  88. GO_EAST,
  89. add(GO_EAST, GO_DOWN),
  90. GO_DOWN,
  91. add(GO_WEST, GO_DOWN),
  92. GO_WEST,
  93. add(GO_WEST, GO_UP),
  94. GO_UP,
  95. add(GO_EAST, GO_UP),
  96. },
  97. // SOUTH_FACE
  98. {
  99. GO_WEST,
  100. add(GO_WEST, GO_DOWN),
  101. GO_DOWN,
  102. add(GO_EAST, GO_DOWN),
  103. GO_EAST,
  104. add(GO_EAST, GO_UP),
  105. GO_UP,
  106. add(GO_WEST, GO_UP),
  107. },
  108. // WEST_FACE
  109. {
  110. GO_NORTH,
  111. add(GO_NORTH, GO_DOWN),
  112. GO_DOWN,
  113. add(GO_SOUTH, GO_DOWN),
  114. GO_SOUTH,
  115. add(GO_SOUTH, GO_UP),
  116. GO_UP,
  117. add(GO_NORTH, GO_UP),
  118. },
  119. // EAST_FACE
  120. {
  121. GO_SOUTH,
  122. add(GO_SOUTH, GO_DOWN),
  123. GO_DOWN,
  124. add(GO_NORTH, GO_DOWN),
  125. GO_NORTH,
  126. add(GO_NORTH, GO_UP),
  127. GO_UP,
  128. add(GO_SOUTH, GO_UP),
  129. },
  130. };
  131. private static final int CONNECT_BY_BLOCK = 0;
  132. private static final int CONNECT_BY_TILE = 1;
  133. private static final int CONNECT_BY_MATERIAL = 2;
  134. private static Method getBiomeNameAt;
  135. private final ResourceLocation propertiesFile;
  136. private final String texturesDirectory;
  137. private final String baseFilename;
  138. private final TileLoader tileLoader;
  139. private final int renderPass;
  140. private final int weight;
  141. private final Set<Integer> matchBlocks;
  142. private final Set<String> matchTiles;
  143. private final int faces;
  144. private final int metadata;
  145. private final int connectType;
  146. private final boolean innerSeams;
  147. private final Set<String> biomes;
  148. private final int minHeight;
  149. private final int maxHeight;
  150. private final List<ResourceLocation> tileNames = new ArrayList<ResourceLocation>();
  151. protected Icon[] icons;
  152. private boolean disabled;
  153. private int[] reorient;
  154. private int rotateUV;
  155. protected boolean rotateTop;
  156. static {
  157. try {
  158. Class<?> biomeHelperClass = Class.forName(MCPatcherUtils.BIOME_HELPER_CLASS);
  159. getBiomeNameAt = biomeHelperClass.getDeclaredMethod("getBiomeNameAt", Integer.TYPE, Integer.TYPE, Integer.TYPE);
  160. getBiomeNameAt.setAccessible(true);
  161. } catch (Throwable e) {
  162. }
  163. if (getBiomeNameAt == null) {
  164. logger.warning("biome integration failed");
  165. } else {
  166. logger.fine("biome integration active");
  167. }
  168. }
  169. static TileOverride create(ResourceLocation propertiesFile, TileLoader tileLoader) {
  170. if (propertiesFile == null) {
  171. return null;
  172. }
  173. Properties properties = TexturePackAPI.getProperties(propertiesFile);
  174. if (properties == null) {
  175. return null;
  176. }
  177. String method = properties.getProperty("method", "default").trim().toLowerCase();
  178. TileOverride override = null;
  179. if (method.equals("default") || method.equals("glass") || method.equals("ctm")) {
  180. override = new TileOverrideImpl.CTM(propertiesFile, properties, tileLoader);
  181. } else if (method.equals("random")) {
  182. override = new TileOverrideImpl.Random1(propertiesFile, properties, tileLoader);
  183. if (override.getNumberOfTiles() == 1) {
  184. override = new TileOverrideImpl.Fixed(propertiesFile, properties, tileLoader);
  185. }
  186. } else if (method.equals("fixed") || method.equals("static")) {
  187. override = new TileOverrideImpl.Fixed(propertiesFile, properties, tileLoader);
  188. } else if (method.equals("bookshelf") || method.equals("horizontal")) {
  189. override = new TileOverrideImpl.Horizontal(propertiesFile, properties, tileLoader);
  190. } else if (method.equals("horizontal+vertical") || method.equals("h+v")) {
  191. override = new TileOverrideImpl.HorizontalVertical(propertiesFile, properties, tileLoader);
  192. } else if (method.equals("vertical")) {
  193. override = new TileOverrideImpl.Vertical(propertiesFile, properties, tileLoader);
  194. } else if (method.equals("vertical+horizontal") || method.equals("v+h")) {
  195. override = new TileOverrideImpl.VerticalHorizontal(propertiesFile, properties, tileLoader);
  196. } else if (method.equals("sandstone") || method.equals("top")) {
  197. override = new TileOverrideImpl.Top(propertiesFile, properties, tileLoader);
  198. } else if (method.equals("repeat") || method.equals("pattern")) {
  199. override = new TileOverrideImpl.Repeat(propertiesFile, properties, tileLoader);
  200. } else {
  201. logger.error("%s: unknown method \"%s\"", propertiesFile, method);
  202. }
  203. if (override != null && !override.disabled) {
  204. String status = override.checkTileMap();
  205. if (status != null) {
  206. override.error("invalid %s tile map: %s", override.getMethod(), status);
  207. }
  208. }
  209. return override == null || override.disabled ? null : override;
  210. }
  211. protected TileOverride(ResourceLocation propertiesFile, Properties properties, TileLoader tileLoader) {
  212. this.propertiesFile = propertiesFile;
  213. texturesDirectory = propertiesFile.getPath().replaceFirst("/[^/]*$", "");
  214. baseFilename = propertiesFile.getPath().replaceFirst(".*/", "").replaceFirst("\\.properties$", "");
  215. this.tileLoader = tileLoader;
  216. loadIcons(properties);
  217. if (tileNames.isEmpty()) {
  218. error("no images found in %s/", texturesDirectory);
  219. }
  220. String[] mappings = new String[Block.blocksList.length];
  221. for (int i = 0; i < Block.blocksList.length; i++) {
  222. Block block = Block.blocksList[i];
  223. if (block != null) {
  224. mappings[i] = block.getShortName();
  225. }
  226. }
  227. matchBlocks = getIDList(properties, "matchBlocks", "block", mappings);
  228. matchTiles = getIDList(properties, "matchTiles");
  229. if (matchBlocks.isEmpty() && matchTiles.isEmpty()) {
  230. matchTiles.add(baseFilename);
  231. }
  232. int flags = 0;
  233. for (String val : properties.getProperty("faces", "all").trim().toLowerCase().split("\\s+")) {
  234. if (val.equals("bottom")) {
  235. flags |= (1 << BOTTOM_FACE);
  236. } else if (val.equals("top")) {
  237. flags |= (1 << TOP_FACE);
  238. } else if (val.equals("north")) {
  239. flags |= (1 << NORTH_FACE);
  240. } else if (val.equals("south")) {
  241. flags |= (1 << SOUTH_FACE);
  242. } else if (val.equals("east")) {
  243. flags |= (1 << EAST_FACE);
  244. } else if (val.equals("west")) {
  245. flags |= (1 << WEST_FACE);
  246. } else if (val.equals("side") || val.equals("sides")) {
  247. flags |= (1 << NORTH_FACE) | (1 << SOUTH_FACE) | (1 << EAST_FACE) | (1 << WEST_FACE);
  248. } else if (val.equals("all")) {
  249. flags = -1;
  250. }
  251. }
  252. faces = flags;
  253. int meta = 0;
  254. for (int i : MCPatcherUtils.parseIntegerList(properties.getProperty("metadata", "0-31"), 0, 31)) {
  255. meta |= (1 << i);
  256. }
  257. metadata = meta;
  258. String connectType1 = properties.getProperty("connect", "").trim().toLowerCase();
  259. if (connectType1.equals("")) {
  260. connectType = matchTiles.isEmpty() ? CONNECT_BY_BLOCK : CONNECT_BY_TILE;
  261. } else if (connectType1.equals("block")) {
  262. connectType = CONNECT_BY_BLOCK;
  263. } else if (connectType1.equals("tile")) {
  264. connectType = CONNECT_BY_TILE;
  265. } else if (connectType1.equals("material")) {
  266. connectType = CONNECT_BY_MATERIAL;
  267. } else {
  268. error("invalid connect type %s", connectType1);
  269. connectType = CONNECT_BY_BLOCK;
  270. }
  271. innerSeams = MCPatcherUtils.getBooleanProperty(properties, "innerSeams", false);
  272. Set<String> biomes = new HashSet<String>();
  273. String biomeList = properties.getProperty("biomes", "").trim().toLowerCase();
  274. if (!biomeList.equals("")) {
  275. Collections.addAll(biomes, biomeList.split("\\s+"));
  276. }
  277. if (biomes.isEmpty()) {
  278. biomes = null;
  279. }
  280. this.biomes = biomes;
  281. minHeight = MCPatcherUtils.getIntProperty(properties, "minHeight", -1);
  282. maxHeight = MCPatcherUtils.getIntProperty(properties, "maxHeight", Integer.MAX_VALUE);
  283. renderPass = MCPatcherUtils.getIntProperty(properties, "renderPass", -1);
  284. if (renderPass > 3) {
  285. error("renderPass must be 0-3");
  286. } else if (renderPass >= 0 && !matchTiles.isEmpty()) {
  287. error("renderPass=%d must be block-based not tile-based", renderPass);
  288. }
  289. weight = MCPatcherUtils.getIntProperty(properties, "weight", 0);
  290. }
  291. private boolean addIcon(ResourceLocation resource) {
  292. tileNames.add(resource);
  293. return tileLoader.preloadTile(resource, renderPass > 2);
  294. }
  295. private void loadIcons(Properties properties) {
  296. tileNames.clear();
  297. String tileList = properties.getProperty("tiles", "").trim();
  298. if (tileList.equals("")) {
  299. for (int i = 0; ; i++) {
  300. ResourceLocation resource = TileLoader.parseTileAddress(propertiesFile, String.valueOf(i));
  301. if (!TexturePackAPI.hasResource(resource)) {
  302. break;
  303. }
  304. if (!addIcon(resource)) {
  305. break;
  306. }
  307. }
  308. } else {
  309. Pattern range = Pattern.compile("(\\d+)-(\\d+)");
  310. for (String token : tileList.split("\\s+")) {
  311. Matcher matcher = range.matcher(token);
  312. if (token.equals("")) {
  313. // nothing
  314. } else if (matcher.matches()) {
  315. try {
  316. int from = Integer.parseInt(matcher.group(1));
  317. int to = Integer.parseInt(matcher.group(2));
  318. for (int i = from; i <= to; i++) {
  319. ResourceLocation resource = TileLoader.parseTileAddress(propertiesFile, String.valueOf(i));
  320. if (TexturePackAPI.hasResource(resource)) {
  321. addIcon(resource);
  322. } else {
  323. warn("could not find image %s", resource);
  324. }
  325. }
  326. } catch (NumberFormatException e) {
  327. e.printStackTrace();
  328. }
  329. } else {
  330. ResourceLocation resource = TileLoader.parseTileAddress(propertiesFile, token);
  331. if (resource == null) {
  332. tileNames.add(null);
  333. } else if (TexturePackAPI.hasResource(resource)) {
  334. addIcon(resource);
  335. } else {
  336. warn("could not find image %s", resource);
  337. }
  338. }
  339. }
  340. }
  341. }
  342. private Set<Integer> getIDList(Properties properties, String key, String type, String[] mappings) {
  343. Set<Integer> list = new HashSet<Integer>();
  344. String property = properties.getProperty(key, "");
  345. token:
  346. for (String token : property.split("\\s+")) {
  347. if (token.equals("")) {
  348. // nothing
  349. } else if (token.matches("\\d+")) {
  350. try {
  351. int id = Integer.parseInt(token);
  352. if (id >= 0 && id < mappings.length) {
  353. list.add(id);
  354. } else {
  355. warn("%s value %d is out of range", key, id);
  356. }
  357. } catch (NumberFormatException e) {
  358. e.printStackTrace();
  359. }
  360. } else {
  361. for (int i = 0; i < mappings.length; i++) {
  362. if (token.equals(mappings[i])) {
  363. list.add(i);
  364. continue token;
  365. }
  366. }
  367. warn("unknown %s value %s", key, token);
  368. }
  369. }
  370. if (list.isEmpty()) {
  371. Matcher m = Pattern.compile(type + "(\\d+)").matcher(baseFilename);
  372. if (m.find()) {
  373. try {
  374. list.add(Integer.parseInt(m.group(1)));
  375. } catch (NumberFormatException e) {
  376. e.printStackTrace();
  377. }
  378. }
  379. }
  380. return list;
  381. }
  382. private Set<String> getIDList(Properties properties, String key) {
  383. Set<String> list = new HashSet<String>();
  384. String property = properties.getProperty(key, "");
  385. for (String token : property.split("\\s+")) {
  386. if (token.equals("")) {
  387. // nothing
  388. } else if (token.contains("/")) {
  389. if (!token.endsWith(".png")) {
  390. token += ".png";
  391. }
  392. ResourceLocation resource = TexturePackAPI.parseResourceLocation(propertiesFile, token);
  393. if (resource != null) {
  394. list.add(resource.toString());
  395. }
  396. } else {
  397. list.add(token);
  398. }
  399. }
  400. return list;
  401. }
  402. private static int[] add(int[] a, int[] b) {
  403. if (a.length != b.length) {
  404. throw new RuntimeException("arrays to add are not same length");
  405. }
  406. int[] c = new int[a.length];
  407. for (int i = 0; i < c.length; i++) {
  408. c[i] = a[i] + b[i];
  409. }
  410. return c;
  411. }
  412. protected int getNumberOfTiles() {
  413. return tileNames.size();
  414. }
  415. String checkTileMap() {
  416. return null;
  417. }
  418. boolean requiresFace() {
  419. return false;
  420. }
  421. @Override
  422. public String toString() {
  423. return String.format("%s[%s]", getMethod(), propertiesFile);
  424. }
  425. public final void registerIcons() {
  426. icons = new Icon[tileNames.size()];
  427. for (int i = 0; i < icons.length; i++) {
  428. icons[i] = tileLoader.getIcon(tileNames.get(i));
  429. }
  430. }
  431. final void error(String format, Object... params) {
  432. if (propertiesFile != null) {
  433. logger.error(propertiesFile + ": " + format, params);
  434. }
  435. disabled = true;
  436. }
  437. final void warn(String format, Object... params) {
  438. if (propertiesFile != null) {
  439. logger.warning(propertiesFile + ": " + format, params);
  440. }
  441. }
  442. final public boolean isDisabled() {
  443. return disabled;
  444. }
  445. final public Set<Integer> getMatchingBlocks() {
  446. return matchBlocks;
  447. }
  448. final public Set<String> getMatchingTiles() {
  449. return matchTiles;
  450. }
  451. final public int getRenderPass() {
  452. return renderPass;
  453. }
  454. final public int getWeight() {
  455. return weight;
  456. }
  457. public int compareTo(ITileOverride o) {
  458. int result = o.getWeight() - getWeight();
  459. if (result != 0) {
  460. return result;
  461. }
  462. if (o instanceof TileOverride) {
  463. return baseFilename.compareTo(((TileOverride) o).baseFilename);
  464. } else {
  465. return -1;
  466. }
  467. }
  468. final boolean shouldConnect(IBlockAccess blockAccess, Block block, Icon icon, int i, int j, int k, int face, int[] offset) {
  469. int blockID = block.blockID;
  470. int metadata = blockAccess.getBlockMetadata(i, j, k);
  471. i += offset[0];
  472. j += offset[1];
  473. k += offset[2];
  474. int neighborID = blockAccess.getBlockId(i, j, k);
  475. int neighborMeta = blockAccess.getBlockMetadata(i, j, k);
  476. Block neighbor = Block.blocksList[neighborID];
  477. if (exclude(neighbor, face, neighborMeta)) {
  478. return false;
  479. }
  480. int orientation = getOrientationFromMetadata(blockID, metadata);
  481. int neighborOrientation = getOrientationFromMetadata(neighborID, neighborMeta);
  482. if ((orientation & ~META_MASK) != (neighborOrientation & ~META_MASK)) {
  483. return false;
  484. }
  485. if (this.metadata != -1) {
  486. if ((orientation & META_MASK) != (neighborOrientation & META_MASK)) {
  487. return false;
  488. }
  489. }
  490. if (face >= 0 && innerSeams) {
  491. int[] normal = NORMALS[face];
  492. if (!neighbor.shouldSideBeRendered(blockAccess, i + normal[0], j + normal[1], k + normal[2], face)) {
  493. return false;
  494. }
  495. }
  496. switch (connectType) {
  497. case CONNECT_BY_BLOCK:
  498. return neighborID == blockID;
  499. case CONNECT_BY_TILE:
  500. return neighbor.getBlockIcon(blockAccess, i, j, k, face) == icon;
  501. case CONNECT_BY_MATERIAL:
  502. return block.blockMaterial == neighbor.blockMaterial;
  503. default:
  504. return false;
  505. }
  506. }
  507. final int reorient(int face) {
  508. if (face < 0 || face > 5 || reorient == null) {
  509. return face;
  510. } else {
  511. return reorient[face];
  512. }
  513. }
  514. final int rotateUV(int neighbor) {
  515. return (neighbor + rotateUV) & 7;
  516. }
  517. final boolean exclude(Block block, int face, int metadata) {
  518. if (block == null) {
  519. return true;
  520. } else if ((faces & (1 << reorient(face))) == 0) {
  521. return true;
  522. } else if (this.metadata != -1 && metadata >= 0 && metadata < 32) {
  523. int altMetadata = getOrientationFromMetadata(block.blockID, metadata) & META_MASK;
  524. if ((this.metadata & ((1 << metadata) | (1 << altMetadata))) == 0) {
  525. return true;
  526. }
  527. }
  528. return false;
  529. }
  530. private static int getOrientationFromMetadata(int blockID, int metadata) {
  531. int newMeta = metadata;
  532. int orientation = ORIENTATION_U_D;
  533. switch (blockID) {
  534. case CTMUtils.BLOCK_ID_LOG:
  535. newMeta = metadata & ~0xc;
  536. switch (metadata & 0xc) {
  537. case 4:
  538. orientation = ORIENTATION_E_W;
  539. break;
  540. case 8:
  541. orientation = ORIENTATION_N_S;
  542. break;
  543. default:
  544. break;
  545. }
  546. break;
  547. case CTMUtils.BLOCK_ID_QUARTZ:
  548. switch (metadata) {
  549. case 3:
  550. newMeta = 2;
  551. orientation = ORIENTATION_E_W_2;
  552. break;
  553. case 4:
  554. newMeta = 2;
  555. orientation = ORIENTATION_N_S_2;
  556. break;
  557. default:
  558. break;
  559. }
  560. break;
  561. default:
  562. break;
  563. }
  564. return orientation | newMeta;
  565. }
  566. private void setupOrientation(int orientation, int face) {
  567. switch (orientation & ~META_MASK) {
  568. case ORIENTATION_E_W:
  569. reorient = ROTATE_UV_MAP[0];
  570. rotateUV = ROTATE_UV_MAP[0][face + 6];
  571. rotateTop = true;
  572. break;
  573. case ORIENTATION_N_S:
  574. reorient = ROTATE_UV_MAP[1];
  575. rotateUV = ROTATE_UV_MAP[1][face + 6];
  576. rotateTop = false;
  577. break;
  578. case ORIENTATION_E_W_2:
  579. reorient = ROTATE_UV_MAP[2];
  580. rotateUV = ROTATE_UV_MAP[2][face + 6];
  581. rotateTop = true;
  582. break;
  583. case ORIENTATION_N_S_2:
  584. reorient = ROTATE_UV_MAP[3];
  585. rotateUV = ROTATE_UV_MAP[3][face + 6];
  586. rotateTop = false;
  587. break;
  588. default:
  589. reorient = null;
  590. rotateUV = 0;
  591. rotateTop = false;
  592. break;
  593. }
  594. }
  595. public final Icon getTile(IBlockAccess blockAccess, Block block, Icon origIcon, int i, int j, int k, int face) {
  596. if (icons == null) {
  597. error("no images loaded, disabling");
  598. return null;
  599. }
  600. if (face < 0 && requiresFace()) {
  601. error("method=%s is not supported for non-standard blocks", getMethod());
  602. return null;
  603. }
  604. if (block == null || RenderPassAPI.instance.skipThisRenderPass(block, renderPass)) {
  605. return null;
  606. }
  607. int metadata = blockAccess.getBlockMetadata(i, j, k);
  608. setupOrientation(getOrientationFromMetadata(block.blockID, metadata), face);
  609. if (exclude(block, face, metadata)) {
  610. return null;
  611. }
  612. if (j < minHeight || j > maxHeight) {
  613. return null;
  614. }
  615. if (biomes != null && getBiomeNameAt != null) {
  616. try {
  617. if (!biomes.contains(getBiomeNameAt.invoke(null, i, j, k))) {
  618. return null;
  619. }
  620. } catch (Throwable e) {
  621. e.printStackTrace();
  622. getBiomeNameAt = null;
  623. }
  624. }
  625. return getTileImpl(blockAccess, block, origIcon, i, j, k, face);
  626. }
  627. public final Icon getTile(Block block, Icon origIcon, int face, int metadata) {
  628. if (icons == null) {
  629. error("no images loaded, disabling");
  630. return null;
  631. }
  632. if (face < 0 && requiresFace()) {
  633. error("method=%s is not supported for non-standard blocks", getMethod());
  634. return null;
  635. }
  636. if (minHeight >= 0 || maxHeight < Integer.MAX_VALUE || biomes != null) {
  637. return null;
  638. }
  639. setupOrientation(getOrientationFromMetadata(block.blockID, metadata), face);
  640. if (exclude(block, face, metadata)) {
  641. return null;
  642. } else {
  643. return getTileImpl(block, origIcon, face, metadata);
  644. }
  645. }
  646. abstract String getMethod();
  647. abstract Icon getTileImpl(IBlockAccess blockAccess, Block block, Icon origIcon, int i, int j, int k, int face);
  648. abstract Icon getTileImpl(Block block, Icon origIcon, int face, int metadata);
  649. }