PageRenderTime 210ms CodeModel.GetById 27ms RepoModel.GetById 1ms app.codeStats 0ms

/newcode/src/com/prupe/mcpatcher/mal/biome/ColorMap.java

https://bitbucket.org/prupe/mcpatcher
Java | 732 lines | 610 code | 122 blank | 0 comment | 89 complexity | da2832d35fc5787e6cdcf20a4849f214 MD5 | raw file
  1. package com.prupe.mcpatcher.mal.biome;
  2. import com.prupe.mcpatcher.Config;
  3. import com.prupe.mcpatcher.MCLogger;
  4. import com.prupe.mcpatcher.MCPatcherUtils;
  5. import com.prupe.mcpatcher.mal.resource.PropertiesFile;
  6. import com.prupe.mcpatcher.mal.resource.ResourceList;
  7. import com.prupe.mcpatcher.mal.resource.TexturePackAPI;
  8. import com.prupe.mcpatcher.mal.util.WeightedIndex;
  9. import net.minecraft.src.BiomeGenBase;
  10. import net.minecraft.src.IBlockAccess;
  11. import net.minecraft.src.ResourceLocation;
  12. import java.awt.image.BufferedImage;
  13. import java.util.*;
  14. abstract public class ColorMap implements IColorMap {
  15. private static final MCLogger logger = MCLogger.getLogger(MCPatcherUtils.CUSTOM_COLORS);
  16. public static final boolean useSwampColors = Config.getBoolean(MCPatcherUtils.CUSTOM_COLORS, "swamp", true);
  17. private static final int FIXED = 0;
  18. private static final int TEMPERATURE_HUMIDITY = 1;
  19. private static final int BIOME_HEIGHT = 2;
  20. private static final int COLORMAP_WIDTH = 256;
  21. private static final int COLORMAP_HEIGHT = 256;
  22. public static final String BLOCK_COLORMAP_DIR = TexturePackAPI.MCPATCHER_SUBDIR + "colormap/blocks";
  23. public static final List<ResourceLocation> unusedPNGs = new ArrayList<ResourceLocation>();
  24. private static final String VANILLA_TYPE = "_vanillaType";
  25. private static final String ALT_SOURCE = "_altSource";
  26. private static int defaultColorMapFormat;
  27. private static boolean defaultFlipY;
  28. private static float defaultYVariance;
  29. protected final ResourceLocation resource;
  30. protected final int[] map;
  31. protected final int width;
  32. protected final int height;
  33. protected final float maxX;
  34. protected final float maxY;
  35. private final float[] xy = new float[2];
  36. private final float[] lastColor = new float[3];
  37. public static IColorMap loadVanillaColorMap(ResourceLocation vanillaImage, ResourceLocation swampImage) {
  38. Properties properties = new Properties();
  39. properties.setProperty("format", "1");
  40. properties.setProperty("source", vanillaImage.toString());
  41. if (!TexturePackAPI.hasCustomResource(vanillaImage)) {
  42. if (vanillaImage.getPath().contains("grass")) {
  43. properties.setProperty(VANILLA_TYPE, "grass");
  44. } else if (vanillaImage.getPath().contains("foliage")) {
  45. properties.setProperty(VANILLA_TYPE, "foliage");
  46. }
  47. }
  48. if (swampImage != null) {
  49. properties.setProperty(ALT_SOURCE, swampImage.toString());
  50. }
  51. return loadColorMap(true, vanillaImage, properties);
  52. }
  53. public static IColorMap loadFixedColorMap(boolean useCustom, ResourceLocation resource) {
  54. return loadColorMap(useCustom, resource, null);
  55. }
  56. public static IColorMap loadColorMap(boolean useCustom, ResourceLocation resource, Properties properties) {
  57. IColorMap map = loadColorMap1(useCustom, resource, properties);
  58. if (map != null) {
  59. map.claimResources(unusedPNGs);
  60. }
  61. return map;
  62. }
  63. private static IColorMap loadColorMap1(boolean useCustom, ResourceLocation resource, Properties properties) {
  64. if (!useCustom || resource == null) {
  65. return null;
  66. }
  67. ResourceLocation propertiesResource;
  68. ResourceLocation imageResource;
  69. if (resource.toString().endsWith(".png")) {
  70. propertiesResource = TexturePackAPI.transformResourceLocation(resource, ".png", ".properties");
  71. imageResource = resource;
  72. } else if (resource.toString().endsWith(".properties")) {
  73. propertiesResource = resource;
  74. imageResource = TexturePackAPI.transformResourceLocation(resource, ".properties", ".png");
  75. } else {
  76. return null;
  77. }
  78. if (properties == null) {
  79. properties = TexturePackAPI.getProperties(propertiesResource);
  80. if (properties == null) {
  81. properties = new Properties();
  82. }
  83. }
  84. int format = parseFormat(MCPatcherUtils.getStringProperty(properties, "format", ""));
  85. if (format == FIXED) {
  86. int color = MCPatcherUtils.getHexProperty(properties, "color", 0xffffff);
  87. return new Fixed(color);
  88. }
  89. String path = MCPatcherUtils.getStringProperty(properties, "source", "");
  90. if (!MCPatcherUtils.isNullOrEmpty(path)) {
  91. imageResource = TexturePackAPI.parseResourceLocation(resource, path);
  92. }
  93. BufferedImage image = TexturePackAPI.getImage(imageResource);
  94. if (image == null) {
  95. return null;
  96. }
  97. switch (format) {
  98. case TEMPERATURE_HUMIDITY:
  99. String vanillaSource = MCPatcherUtils.getStringProperty(properties, VANILLA_TYPE, "");
  100. IColorMap defaultMap;
  101. if ("grass".equals(vanillaSource)) {
  102. defaultMap = new Grass(image);
  103. } else if ("foliage".equals(vanillaSource)) {
  104. defaultMap = new Foliage(image);
  105. } else {
  106. defaultMap = new TempHumidity(imageResource, properties, image);
  107. }
  108. path = MCPatcherUtils.getStringProperty(properties, ALT_SOURCE, "");
  109. if (useSwampColors && !MCPatcherUtils.isNullOrEmpty(path)) {
  110. ResourceLocation swampResource = TexturePackAPI.parseResourceLocation(resource, path);
  111. image = TexturePackAPI.getImage(swampResource);
  112. if (image != null) {
  113. IColorMap swampMap = new TempHumidity(swampResource, properties, image);
  114. return new Swamp(defaultMap, swampMap);
  115. }
  116. }
  117. return defaultMap;
  118. case BIOME_HEIGHT:
  119. Grid grid = new Grid(imageResource, properties, image);
  120. if (grid.isInteger()) {
  121. return new IntegerGrid(grid);
  122. } else {
  123. return grid;
  124. }
  125. default:
  126. logger.error("%s: unknown format %d", resource, format);
  127. return null;
  128. }
  129. }
  130. public static void reset() {
  131. unusedPNGs.clear();
  132. defaultColorMapFormat = TEMPERATURE_HUMIDITY;
  133. defaultFlipY = false;
  134. defaultYVariance = Config.getInt(MCPatcherUtils.CUSTOM_COLORS, "yVariance", 0);
  135. }
  136. public static void reloadColorMapSettings(PropertiesFile properties) {
  137. unusedPNGs.addAll(ResourceList.getInstance().listResources(BLOCK_COLORMAP_DIR, ".png", false));
  138. defaultColorMapFormat = parseFormat(properties.getString("palette.format", ""));
  139. defaultFlipY = properties.getBoolean("palette.flipY", false);
  140. defaultYVariance = properties.getFloat("palette.yVariance", 0.0f);
  141. }
  142. private static int parseFormat(String value) {
  143. if (MCPatcherUtils.isNullOrEmpty(value)) {
  144. return defaultColorMapFormat;
  145. }
  146. value = value.toLowerCase();
  147. if (value.matches("^\\d+$")) {
  148. try {
  149. return Integer.parseInt(value);
  150. } catch (NumberFormatException e) {
  151. e.printStackTrace();
  152. }
  153. } else if (value.equals("fixed")) {
  154. return FIXED;
  155. } else if (value.equals("temperature+humidity") || value.equals("t+h") || value.equals("vanilla")) {
  156. return TEMPERATURE_HUMIDITY;
  157. } else if (value.equals("biome+height") || value.equals("b+h") || value.equals("grid")) {
  158. return BIOME_HEIGHT;
  159. }
  160. return defaultColorMapFormat;
  161. }
  162. ColorMap(ResourceLocation resource, Properties properties, BufferedImage image) {
  163. this(resource, MCPatcherUtils.getImageRGB(image), image.getWidth(), image.getHeight());
  164. }
  165. ColorMap(ResourceLocation resource, int[] map, int width, int height) {
  166. this.resource = resource;
  167. this.map = map;
  168. this.width = width;
  169. this.height = height;
  170. for (int i = 0; i < map.length; i++) {
  171. map[i] &= 0xffffff;
  172. }
  173. maxX = width - 1.0f;
  174. maxY = height - 1.0f;
  175. }
  176. abstract protected void computeXY(BiomeGenBase biome, int i, int j, int k, float[] f);
  177. @Override
  178. public String toString() {
  179. return getClass().getSimpleName() + "{" + resource + "}";
  180. }
  181. @Override
  182. public final int getColorMultiplier(IBlockAccess blockAccess, int i, int j, int k) {
  183. computeXY(BiomeAPI.getBiomeGenAt(blockAccess, i, j, k), i, j, k, xy);
  184. return getRGB(xy[0], xy[1]);
  185. }
  186. @Override
  187. public final float[] getColorMultiplierF(IBlockAccess blockAccess, int i, int j, int k) {
  188. int rgb = getColorMultiplier(blockAccess, i, j, k);
  189. ColorUtils.intToFloat3(rgb, lastColor);
  190. return lastColor;
  191. }
  192. @Override
  193. public void claimResources(Collection<ResourceLocation> resources) {
  194. resources.remove(resource);
  195. }
  196. protected int getRGB(float x, float y) {
  197. x = clamp(x, 0.0f, maxX);
  198. y = clamp(y, 0.0f, maxY);
  199. int x0 = (int) x;
  200. int dx = (int) (256.0f * (x - (float) x0));
  201. int x1 = x0 + 1;
  202. int y0 = (int) y;
  203. int dy = (int) (256.0f * (y - (float) y0));
  204. int y1 = y0 + 1;
  205. if (dx == 0 && dy == 0) {
  206. return getRGB(x0, y0);
  207. } else if (dx == 0) {
  208. return interpolate(x0, y0, x0, y1, dy);
  209. } else if (dy == 0) {
  210. return interpolate(x0, y0, x1, y0, dx);
  211. } else {
  212. return interpolate(
  213. interpolate(x0, y0, x1, y0, dx),
  214. interpolate(x0, y1, x1, y1, dx),
  215. dy
  216. );
  217. }
  218. }
  219. private int getRGB(int x, int y) {
  220. return map[x + width * y];
  221. }
  222. private int interpolate(int x1, int y1, int x2, int y2, int a2) {
  223. return interpolate(getRGB(x1, y1), getRGB(x2, y2), a2);
  224. }
  225. private static int interpolate(int rgb1, int rgb2, int a2) {
  226. int a1 = 256 - a2;
  227. int r1 = (rgb1 >> 16) & 0xff;
  228. int g1 = (rgb1 >> 8) & 0xff;
  229. int b1 = rgb1 & 0xff;
  230. int r2 = (rgb2 >> 16) & 0xff;
  231. int g2 = (rgb2 >> 8) & 0xff;
  232. int b2 = rgb2 & 0xff;
  233. int r = (a1 * r1 + a2 * r2) >> 8;
  234. int g = (a1 * g1 + a2 * g2) >> 8;
  235. int b = (a1 * b1 + a2 * b2) >> 8;
  236. return (r << 16) | (g << 8) | b;
  237. }
  238. protected static float noise0to1(int i, int j, int k, int l) {
  239. int hash = (int) WeightedIndex.hash128To64(i, j, k, l) & Integer.MAX_VALUE;
  240. return (float) ((double) hash / (double) Integer.MAX_VALUE);
  241. }
  242. protected static float noiseMinus1to1(int i, int j, int k, int l) {
  243. int hash = (int) WeightedIndex.hash128To64(i, j, k, l);
  244. return (float) ((double) hash / (double) Integer.MIN_VALUE);
  245. }
  246. protected static float clamp(float i, float min, float max) {
  247. if (i < min) {
  248. return min;
  249. } else if (i > max) {
  250. return max;
  251. } else {
  252. return i;
  253. }
  254. }
  255. protected static int clamp(int i, int min, int max) {
  256. if (i < min) {
  257. return min;
  258. } else if (i > max) {
  259. return max;
  260. } else {
  261. return i;
  262. }
  263. }
  264. public static final class Fixed implements IColorMap {
  265. private final int colorI;
  266. private final float[] colorF = new float[3];
  267. public Fixed(int color) {
  268. colorI = color;
  269. ColorUtils.intToFloat3(colorI, colorF);
  270. }
  271. @Override
  272. public String toString() {
  273. return String.format("Fixed{%06x}", colorI);
  274. }
  275. @Override
  276. public boolean isHeightDependent() {
  277. return false;
  278. }
  279. @Override
  280. public int getColorMultiplier() {
  281. return colorI;
  282. }
  283. @Override
  284. public int getColorMultiplier(IBlockAccess blockAccess, int i, int j, int k) {
  285. return colorI;
  286. }
  287. @Override
  288. public float[] getColorMultiplierF(IBlockAccess blockAccess, int i, int j, int k) {
  289. return colorF;
  290. }
  291. @Override
  292. public void claimResources(Collection<ResourceLocation> resources) {
  293. }
  294. @Override
  295. public IColorMap copy() {
  296. return this;
  297. }
  298. }
  299. public static final class Water implements IColorMap {
  300. private final float[] lastColor = new float[3];
  301. @Override
  302. public String toString() {
  303. return String.format("Water{%06x}", getColorMultiplier());
  304. }
  305. @Override
  306. public boolean isHeightDependent() {
  307. return false;
  308. }
  309. @Override
  310. public int getColorMultiplier() {
  311. return BiomeAPI.getWaterColorMultiplier(BiomeAPI.findBiomeByName("Ocean"));
  312. }
  313. @Override
  314. public int getColorMultiplier(IBlockAccess blockAccess, int i, int j, int k) {
  315. return BiomeAPI.getWaterColorMultiplier(BiomeAPI.getBiomeGenAt(blockAccess, i, j, k));
  316. }
  317. @Override
  318. public float[] getColorMultiplierF(IBlockAccess blockAccess, int i, int j, int k) {
  319. ColorUtils.intToFloat3(getColorMultiplier(blockAccess, i, j, k), lastColor);
  320. return lastColor;
  321. }
  322. @Override
  323. public void claimResources(Collection<ResourceLocation> resources) {
  324. }
  325. @Override
  326. public IColorMap copy() {
  327. return new Water();
  328. }
  329. }
  330. public abstract static class Vanilla implements IColorMap {
  331. protected final int defaultColor;
  332. protected final float[] lastColor = new float[3];
  333. Vanilla(BufferedImage image) {
  334. this(image.getRGB(127, 127));
  335. }
  336. Vanilla(int defaultColor) {
  337. this.defaultColor = defaultColor & 0xffffff;
  338. }
  339. @Override
  340. public String toString() {
  341. return String.format("%s{%06x}", getClass().getSimpleName(), defaultColor);
  342. }
  343. @Override
  344. final public boolean isHeightDependent() {
  345. return BiomeAPI.isColorHeightDependent;
  346. }
  347. @Override
  348. final public int getColorMultiplier() {
  349. return defaultColor;
  350. }
  351. @Override
  352. final public int getColorMultiplier(IBlockAccess blockAccess, int i, int j, int k) {
  353. return getColorMultiplier(BiomeAPI.getBiomeGenAt(blockAccess, i, j, k), i, j, k);
  354. }
  355. @Override
  356. final public float[] getColorMultiplierF(IBlockAccess blockAccess, int i, int j, int k) {
  357. ColorUtils.intToFloat3(getColorMultiplier(blockAccess, i, j, k), lastColor);
  358. return lastColor;
  359. }
  360. @Override
  361. final public void claimResources(Collection<ResourceLocation> resources) {
  362. }
  363. abstract int getColorMultiplier(BiomeGenBase biome, int i, int j, int k);
  364. }
  365. public static final class Grass extends Vanilla {
  366. Grass(BufferedImage image) {
  367. super(image);
  368. }
  369. Grass(int defaultColor) {
  370. super(defaultColor);
  371. }
  372. @Override
  373. public IColorMap copy() {
  374. return new Grass(defaultColor);
  375. }
  376. @Override
  377. int getColorMultiplier(BiomeGenBase biome, int i, int j, int k) {
  378. return BiomeAPI.getGrassColor(biome, i, j, k);
  379. }
  380. }
  381. public static final class Foliage extends Vanilla {
  382. Foliage(BufferedImage image) {
  383. super(image);
  384. }
  385. Foliage(int defaultColor) {
  386. super(defaultColor);
  387. }
  388. @Override
  389. public IColorMap copy() {
  390. return new Foliage(defaultColor);
  391. }
  392. @Override
  393. int getColorMultiplier(BiomeGenBase biome, int i, int j, int k) {
  394. return BiomeAPI.getFoliageColor(biome, i, j, k);
  395. }
  396. }
  397. public static final class Swamp implements IColorMap {
  398. private final IColorMap defaultMap;
  399. private final IColorMap swampMap;
  400. private final BiomeGenBase swampBiome;
  401. Swamp(IColorMap defaultMap, IColorMap swampMap) {
  402. this.defaultMap = defaultMap;
  403. this.swampMap = swampMap;
  404. swampBiome = BiomeAPI.findBiomeByName("Swampland");
  405. }
  406. @Override
  407. public String toString() {
  408. return defaultMap.toString();
  409. }
  410. @Override
  411. public boolean isHeightDependent() {
  412. return defaultMap.isHeightDependent() || swampMap.isHeightDependent();
  413. }
  414. @Override
  415. public int getColorMultiplier() {
  416. return defaultMap.getColorMultiplier();
  417. }
  418. @Override
  419. public int getColorMultiplier(IBlockAccess blockAccess, int i, int j, int k) {
  420. IColorMap map = BiomeAPI.getBiomeGenAt(blockAccess, i, j, k) == swampBiome ? swampMap : defaultMap;
  421. return map.getColorMultiplier(blockAccess, i, j, k);
  422. }
  423. @Override
  424. public float[] getColorMultiplierF(IBlockAccess blockAccess, int i, int j, int k) {
  425. IColorMap map = BiomeAPI.getBiomeGenAt(blockAccess, i, j, k) == swampBiome ? swampMap : defaultMap;
  426. return map.getColorMultiplierF(blockAccess, i, j, k);
  427. }
  428. @Override
  429. public void claimResources(Collection<ResourceLocation> resources) {
  430. defaultMap.claimResources(resources);
  431. swampMap.claimResources(resources);
  432. }
  433. @Override
  434. public IColorMap copy() {
  435. return new Swamp(defaultMap.copy(), swampMap.copy());
  436. }
  437. }
  438. public static final class TempHumidity extends ColorMap {
  439. private final int defaultColor;
  440. private TempHumidity(ResourceLocation resource, Properties properties, BufferedImage image) {
  441. super(resource, properties, image);
  442. defaultColor = MCPatcherUtils.getHexProperty(properties, "color", getRGB(maxX * 0.5f, maxY * 0.5f));
  443. }
  444. private TempHumidity(ResourceLocation resource, int[] map, int width, int height, int defaultColor) {
  445. super(resource, map, width, height);
  446. this.defaultColor = defaultColor;
  447. }
  448. @Override
  449. public boolean isHeightDependent() {
  450. return BiomeAPI.isColorHeightDependent;
  451. }
  452. @Override
  453. public int getColorMultiplier() {
  454. return defaultColor;
  455. }
  456. @Override
  457. public IColorMap copy() {
  458. return new TempHumidity(resource, map, width, height, defaultColor);
  459. }
  460. @Override
  461. protected void computeXY(BiomeGenBase biome, int i, int j, int k, float[] f) {
  462. float temperature = ColorUtils.clamp(BiomeAPI.getTemperature(biome, i, j, k));
  463. float rainfall = ColorUtils.clamp(BiomeAPI.getRainfall(biome, i, j, k));
  464. f[0] = maxX * (1.0f - temperature);
  465. f[1] = maxY * (1.0f - temperature * rainfall);
  466. }
  467. }
  468. public static final class Grid extends ColorMap {
  469. private final float[] biomeX = new float[BiomeGenBase.biomeList.length];
  470. private final float yVariance;
  471. private final float yOffset;
  472. private final int defaultColor;
  473. private Grid(ResourceLocation resource, Properties properties, BufferedImage image) {
  474. super(resource, properties, image);
  475. if (MCPatcherUtils.getBooleanProperty(properties, "flipY", defaultFlipY)) {
  476. int[] temp = new int[width];
  477. for (int i = 0; i < map.length / 2; i += width) {
  478. int j = map.length - width - i;
  479. System.arraycopy(map, i, temp, 0, width);
  480. System.arraycopy(map, j, map, i, width);
  481. System.arraycopy(temp, 0, map, j, width);
  482. }
  483. }
  484. yVariance = Math.max(MCPatcherUtils.getFloatProperty(properties, "yVariance", defaultYVariance), 0.0f);
  485. yOffset = MCPatcherUtils.getFloatProperty(properties, "yOffset", 0.0f);
  486. for (int i = 0; i < biomeX.length; i++) {
  487. biomeX[i] = i % width;
  488. }
  489. for (Map.Entry<Object, Object> entry : properties.entrySet()) {
  490. String key = (String) entry.getKey();
  491. String value = (String) entry.getValue();
  492. if (key.endsWith(".x") && !MCPatcherUtils.isNullOrEmpty(value)) {
  493. key = key.substring(0, key.length() - 2);
  494. BiomeGenBase biome = BiomeAPI.findBiomeByName(key);
  495. if (biome != null && biome.biomeID >= 0 && biome.biomeID < BiomeGenBase.biomeList.length) {
  496. try {
  497. biomeX[biome.biomeID] = Float.parseFloat(value);
  498. } catch (NumberFormatException e) {
  499. e.printStackTrace();
  500. }
  501. }
  502. }
  503. }
  504. defaultColor = MCPatcherUtils.getHexProperty(properties, "color", getRGB(biomeX[1], getY(ColorMapBase.DEFAULT_HEIGHT)));
  505. }
  506. private Grid(ResourceLocation resource, int[] map, int width, int height, float[] biomeX, float yVariance, float yOffset, int defaultColor) {
  507. super(resource, map, width, height);
  508. System.arraycopy(biomeX, 0, this.biomeX, 0, biomeX.length);
  509. this.yVariance = yVariance;
  510. this.yOffset = yOffset;
  511. this.defaultColor = defaultColor;
  512. }
  513. boolean isInteger() {
  514. if (yVariance != 0.0f || Math.floor(yOffset) != yOffset) {
  515. return false;
  516. }
  517. for (int i = 0; i < biomeX.length; i++) {
  518. if (biomeX[i] != i % width) {
  519. return false;
  520. }
  521. }
  522. return true;
  523. }
  524. @Override
  525. public boolean isHeightDependent() {
  526. return true;
  527. }
  528. @Override
  529. public int getColorMultiplier() {
  530. return defaultColor;
  531. }
  532. @Override
  533. public IColorMap copy() {
  534. return new Grid(resource, map, width, height, biomeX, yVariance, yOffset, defaultColor);
  535. }
  536. @Override
  537. protected void computeXY(BiomeGenBase biome, int i, int j, int k, float[] f) {
  538. f[0] = getX(biome, i, j, k);
  539. f[1] = getY(biome, i, j, k);
  540. }
  541. private float getX(BiomeGenBase biome, int i, int j, int k) {
  542. return biomeX[biome.biomeID];
  543. }
  544. private float getY(int j) {
  545. return (float) j - yOffset;
  546. }
  547. private float getY(BiomeGenBase biome, int i, int j, int k) {
  548. float y = getY(j);
  549. if (yVariance != 0.0f) {
  550. y += yVariance * noiseMinus1to1(k, -j, i, ~biome.biomeID);
  551. }
  552. return y;
  553. }
  554. }
  555. public static final class IntegerGrid implements IColorMap {
  556. private final ResourceLocation resource;
  557. private final int[] map;
  558. private final int width;
  559. private final int maxHeight;
  560. private final int yOffset;
  561. private final int defaultColor;
  562. private final float[] lastColor = new float[3];
  563. IntegerGrid(Grid grid) {
  564. this(grid.resource, grid.map, grid.width, grid.height - 1, (int) grid.yOffset, grid.defaultColor);
  565. }
  566. IntegerGrid(ResourceLocation resource, int[] map, int width, int maxHeight, int yOffset, int defaultColor) {
  567. this.resource = resource;
  568. this.map = map;
  569. this.width = width;
  570. this.maxHeight = maxHeight;
  571. this.yOffset = yOffset;
  572. this.defaultColor = defaultColor;
  573. }
  574. @Override
  575. public String toString() {
  576. return getClass().getSimpleName() + "{" + resource + "}";
  577. }
  578. @Override
  579. public boolean isHeightDependent() {
  580. return true;
  581. }
  582. @Override
  583. public int getColorMultiplier() {
  584. return defaultColor;
  585. }
  586. @Override
  587. public int getColorMultiplier(IBlockAccess blockAccess, int i, int j, int k) {
  588. return getRGB(BiomeAPI.getBiomeIDAt(blockAccess, i, j, k), j);
  589. }
  590. @Override
  591. public float[] getColorMultiplierF(IBlockAccess blockAccess, int i, int j, int k) {
  592. int rgb = getColorMultiplier(blockAccess, i, j, k);
  593. ColorUtils.intToFloat3(rgb, lastColor);
  594. return lastColor;
  595. }
  596. @Override
  597. public void claimResources(Collection<ResourceLocation> resources) {
  598. resources.remove(resource);
  599. }
  600. @Override
  601. public IColorMap copy() {
  602. return new IntegerGrid(resource, map, width, maxHeight, yOffset, defaultColor);
  603. }
  604. private int getRGB(int x, int y) {
  605. x = clamp(x, 0, COLORMAP_WIDTH - 1) % width;
  606. y = clamp(y - yOffset, 0, maxHeight);
  607. return map[y * width + x];
  608. }
  609. }
  610. }