PageRenderTime 70ms CodeModel.GetById 39ms RepoModel.GetById 1ms app.codeStats 0ms

/newcode/src/com/prupe/mcpatcher/cit/OverrideBase.java

https://bitbucket.org/michael_rodrigues/mcpatcher
Java | 373 lines | 336 code | 37 blank | 0 comment | 115 complexity | f7a72f20c4becd0106e966d56a31bfbf MD5 | raw file
  1. package com.prupe.mcpatcher.cit;
  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.*;
  7. import java.io.File;
  8. import java.util.*;
  9. abstract class OverrideBase implements Comparable<OverrideBase> {
  10. static final MCLogger logger = MCLogger.getLogger(MCPatcherUtils.CUSTOM_ITEM_TEXTURES, "CIT");
  11. private static final int MAX_DAMAGE = 65535;
  12. private static final int MAX_STACK_SIZE = 65535;
  13. final ResourceLocation propertiesName;
  14. final ResourceLocation textureName;
  15. final Map<String, ResourceLocation> alternateTextures;
  16. final int weight;
  17. final BitSet itemsIDs;
  18. final BitSet damage;
  19. final int damageMask;
  20. final BitSet stackSize;
  21. final BitSet enchantmentIDs;
  22. final BitSet enchantmentLevels;
  23. final List<String[]> nbtRules = new ArrayList<String[]>();
  24. boolean error;
  25. int lastEnchantmentLevel;
  26. static OverrideBase create(ResourceLocation filename) {
  27. if (new File(filename.getPath()).getName().equals("cit.properties")) {
  28. return null;
  29. }
  30. Properties properties = TexturePackAPI.getProperties(filename);
  31. if (properties == null) {
  32. return null;
  33. }
  34. String type = MCPatcherUtils.getStringProperty(properties, "type", "item").toLowerCase();
  35. OverrideBase override;
  36. if (type.equals("item")) {
  37. if (!CITUtils.enableItems) {
  38. return null;
  39. }
  40. override = new ItemOverride(filename, properties);
  41. } else if (type.equals("enchantment") || type.equals("overlay")) {
  42. if (!CITUtils.enableEnchantments) {
  43. return null;
  44. }
  45. override = new Enchantment(filename, properties);
  46. } else if (type.equals("armor")) {
  47. if (!CITUtils.enableArmor) {
  48. return null;
  49. }
  50. override = new ArmorOverride(filename, properties);
  51. } else {
  52. logger.error("%s: unknown type '%s'", filename, type);
  53. return null;
  54. }
  55. return override.error ? null : override;
  56. }
  57. OverrideBase(ResourceLocation propertiesName, Properties properties) {
  58. this.propertiesName = propertiesName;
  59. String value = MCPatcherUtils.getStringProperty(properties, "source", "");
  60. ResourceLocation resource;
  61. if (value.equals("")) {
  62. value = MCPatcherUtils.getStringProperty(properties, "texture", "");
  63. }
  64. if (value.equals("")) {
  65. value = MCPatcherUtils.getStringProperty(properties, "tile", "");
  66. }
  67. if (value.equals("")) {
  68. resource = TileLoader.getDefaultAddress(propertiesName);
  69. if (!TexturePackAPI.hasResource(resource)) {
  70. resource = null;
  71. }
  72. } else {
  73. resource = TileLoader.parseTileAddress(propertiesName, value);
  74. if (!TexturePackAPI.hasResource(resource)) {
  75. error("source texture %s not found", value);
  76. resource = null;
  77. }
  78. }
  79. textureName = resource;
  80. alternateTextures = getAlternateTextures(properties);
  81. weight = MCPatcherUtils.getIntProperty(properties, "weight", 0);
  82. value = MCPatcherUtils.getStringProperty(properties, "items", "");
  83. if (value.equals("")) {
  84. value = MCPatcherUtils.getStringProperty(properties, "matchItems", "");
  85. }
  86. if (value.equals("")) {
  87. itemsIDs = null;
  88. } else {
  89. BitSet ids = parseBitSet(value, CITUtils.LOWEST_ITEM_ID, CITUtils.HIGHEST_ITEM_ID);
  90. boolean all = true;
  91. for (int i = CITUtils.LOWEST_ITEM_ID; i <= CITUtils.HIGHEST_ITEM_ID; i++) {
  92. if (Item.itemsList[i] != null && !ids.get(i)) {
  93. all = false;
  94. break;
  95. }
  96. }
  97. itemsIDs = all ? null : ids;
  98. }
  99. damage = parseBitSet(properties, "damage", 0, MAX_DAMAGE);
  100. damageMask = MCPatcherUtils.getIntProperty(properties, "damageMask", MAX_DAMAGE);
  101. stackSize = parseBitSet(properties, "stackSize", 0, MAX_STACK_SIZE);
  102. enchantmentIDs = parseBitSet(properties, "enchantmentIDs", 0, CITUtils.MAX_ENCHANTMENTS - 1);
  103. enchantmentLevels = parseBitSet(properties, "enchantmentLevels", 0, CITUtils.MAX_ENCHANTMENTS - 1);
  104. for (Map.Entry<Object, Object> entry : properties.entrySet()) {
  105. String name = (String) entry.getKey();
  106. value = (String) entry.getValue();
  107. if (name.startsWith("nbt.")) {
  108. String[] rule = name.split("\\.");
  109. if (rule.length > 1) {
  110. rule[0] = value;
  111. for (int i = 1; i < rule.length; i++) {
  112. if ("*".equals(rule[i])) {
  113. rule[i] = null;
  114. }
  115. }
  116. nbtRules.add(rule);
  117. }
  118. }
  119. }
  120. }
  121. public int compareTo(OverrideBase o) {
  122. int result = o.weight - weight;
  123. if (result != 0) {
  124. return result;
  125. }
  126. return propertiesName.toString().compareTo(o.propertiesName.toString());
  127. }
  128. boolean match(ItemStack itemStack, int[] itemEnchantmentLevels, boolean hasEffect) {
  129. return matchDamage(itemStack) &&
  130. matchStackSize(itemStack) &&
  131. matchEnchantment(itemEnchantmentLevels, hasEffect) &&
  132. matchNBT(itemStack);
  133. }
  134. private Map<String, ResourceLocation> getAlternateTextures(Properties properties) {
  135. Map<String, ResourceLocation> tmpMap = new HashMap<String, ResourceLocation>();
  136. for (Map.Entry<Object, Object> entry : properties.entrySet()) {
  137. String key = (String) entry.getKey();
  138. String value = (String) entry.getValue();
  139. String name;
  140. if (key.startsWith("source.")) {
  141. name = key.substring(7);
  142. } else if (key.startsWith("texture.")) {
  143. name = key.substring(8);
  144. } else if (key.startsWith("tile.")) {
  145. name = key.substring(5);
  146. } else {
  147. continue;
  148. }
  149. ResourceLocation resource = TileLoader.parseTileAddress(propertiesName, value);
  150. if (resource != null) {
  151. tmpMap.put(name, resource);
  152. }
  153. }
  154. return tmpMap.isEmpty() ? null : tmpMap;
  155. }
  156. private boolean matchDamage(ItemStack itemStack) {
  157. return damage == null || damage.get(itemStack.getItemDamage() & damageMask);
  158. }
  159. private boolean matchStackSize(ItemStack itemStack) {
  160. return stackSize == null || stackSize.get(itemStack.stackSize);
  161. }
  162. private boolean matchEnchantment(int[] itemEnchantmentLevels, boolean hasEffect) {
  163. if (enchantmentLevels == null && enchantmentIDs == null) {
  164. return true;
  165. } else if (itemEnchantmentLevels == null) {
  166. return (lastEnchantmentLevel = getEnchantmentLevelMatch(hasEffect)) >= 0;
  167. } else {
  168. return (lastEnchantmentLevel = getEnchantmentLevelMatch(itemEnchantmentLevels)) >= 0;
  169. }
  170. }
  171. private int getEnchantmentLevelMatch(boolean hasEffect) {
  172. if (hasEffect && enchantmentIDs == null && enchantmentLevels.get(1)) {
  173. return 1;
  174. } else {
  175. return -1;
  176. }
  177. }
  178. private int getEnchantmentLevelMatch(int[] itemEnchantmentLevels) {
  179. int matchLevel = -1;
  180. if (enchantmentIDs == null) {
  181. int sum = 0;
  182. for (int level : itemEnchantmentLevels) {
  183. sum += level;
  184. }
  185. if (enchantmentLevels.get(sum)) {
  186. return sum;
  187. }
  188. } else if (enchantmentLevels == null) {
  189. for (int id = enchantmentIDs.nextSetBit(0); id >= 0; id = enchantmentIDs.nextSetBit(id + 1)) {
  190. if (itemEnchantmentLevels[id] > 0) {
  191. matchLevel = Math.max(matchLevel, itemEnchantmentLevels[id]);
  192. }
  193. }
  194. } else {
  195. for (int id = enchantmentIDs.nextSetBit(0); id >= 0; id = enchantmentIDs.nextSetBit(id + 1)) {
  196. if (enchantmentLevels.get(itemEnchantmentLevels[id])) {
  197. matchLevel = Math.max(matchLevel, itemEnchantmentLevels[id]);
  198. }
  199. }
  200. }
  201. return matchLevel;
  202. }
  203. private boolean matchNBT(ItemStack itemStack) {
  204. for (String[] rule : nbtRules) {
  205. if (!matchNBTTagCompound(rule, 1, rule[0], itemStack.stackTagCompound)) {
  206. return false;
  207. }
  208. }
  209. return true;
  210. }
  211. abstract String getType();
  212. @Override
  213. public String toString() {
  214. return String.format("ItemOverride{%s, %s, %s}", getType(), propertiesName, textureName);
  215. }
  216. void error(String format, Object... o) {
  217. error = true;
  218. logger.error(propertiesName + ": " + format, o);
  219. }
  220. private static BitSet parseBitSet(Properties properties, String tag, int min, int max) {
  221. String value = MCPatcherUtils.getStringProperty(properties, tag, "");
  222. return parseBitSet(value, min, max);
  223. }
  224. private static BitSet parseBitSet(String value, int min, int max) {
  225. if (value.equals("")) {
  226. return null;
  227. }
  228. BitSet bits = new BitSet();
  229. for (int i : MCPatcherUtils.parseIntegerList(value, min, max)) {
  230. bits.set(i);
  231. }
  232. return bits;
  233. }
  234. private static boolean matchNBT(String[] rule, int index, String value, NBTBase nbt) {
  235. if (nbt instanceof NBTTagByte) {
  236. return matchNBTTagByte(rule, index, value, (NBTTagByte) nbt);
  237. } else if (nbt instanceof NBTTagCompound) {
  238. return matchNBTTagCompound(rule, index, value, (NBTTagCompound) nbt);
  239. } else if (nbt instanceof NBTTagList) {
  240. return matchNBTTagList(rule, index, value, (NBTTagList) nbt);
  241. } else if (nbt instanceof NBTTagDouble) {
  242. return matchNBTTagDouble(rule, index, value, (NBTTagDouble) nbt);
  243. } else if (nbt instanceof NBTTagFloat) {
  244. return matchNBTTagFloat(rule, index, value, (NBTTagFloat) nbt);
  245. } else if (nbt instanceof NBTTagInteger) {
  246. return matchNBTTagInteger(rule, index, value, (NBTTagInteger) nbt);
  247. } else if (nbt instanceof NBTTagLong) {
  248. return matchNBTTagLong(rule, index, value, (NBTTagLong) nbt);
  249. } else if (nbt instanceof NBTTagShort) {
  250. return matchNBTTagShort(rule, index, value, (NBTTagShort) nbt);
  251. } else if (nbt instanceof NBTTagString) {
  252. return matchNBTTagString(rule, index, value, (NBTTagString) nbt);
  253. } else {
  254. return false;
  255. }
  256. }
  257. private static boolean matchNBTTagCompound(String[] rule, int index, String value, NBTTagCompound nbt) {
  258. if (nbt == null || index >= rule.length) {
  259. return false;
  260. }
  261. if (rule[index] == null) {
  262. for (NBTBase nbtBase : nbt.getTags()) {
  263. if (matchNBT(rule, index + 1, value, nbtBase)) {
  264. return true;
  265. }
  266. }
  267. } else {
  268. return matchNBT(rule, index + 1, value, nbt.getTag(rule[index]));
  269. }
  270. return false;
  271. }
  272. private static boolean matchNBTTagList(String[] rule, int index, String value, NBTTagList nbt) {
  273. if (index >= rule.length) {
  274. return false;
  275. }
  276. if (rule[index] == null) {
  277. for (int i = 0; i < nbt.tagCount(); i++) {
  278. if (matchNBT(rule, index + 1, value, nbt.tagAt(i))) {
  279. return true;
  280. }
  281. }
  282. } else {
  283. try {
  284. int tagNum = Integer.parseInt(rule[index]);
  285. return tagNum >= 0 && tagNum < nbt.tagCount() && matchNBT(rule, index + 1, value, nbt.tagAt(tagNum));
  286. } catch (NumberFormatException e) {
  287. }
  288. }
  289. return false;
  290. }
  291. private static boolean matchNBTTagByte(String[] rule, int index, String value, NBTTagByte nbt) {
  292. try {
  293. return nbt.data == Byte.parseByte(value);
  294. } catch (NumberFormatException e) {
  295. return false;
  296. }
  297. }
  298. private static boolean matchNBTTagDouble(String[] rule, int index, String value, NBTTagDouble nbt) {
  299. try {
  300. return nbt.data == Double.parseDouble(value);
  301. } catch (NumberFormatException e) {
  302. return false;
  303. }
  304. }
  305. private static boolean matchNBTTagFloat(String[] rule, int index, String value, NBTTagFloat nbt) {
  306. try {
  307. return nbt.data == Float.parseFloat(value);
  308. } catch (NumberFormatException e) {
  309. return false;
  310. }
  311. }
  312. private static boolean matchNBTTagInteger(String[] rule, int index, String value, NBTTagInteger nbt) {
  313. try {
  314. return nbt.data == Integer.parseInt(value);
  315. } catch (NumberFormatException e) {
  316. return false;
  317. }
  318. }
  319. private static boolean matchNBTTagLong(String[] rule, int index, String value, NBTTagLong nbt) {
  320. try {
  321. return nbt.data == Long.parseLong(value);
  322. } catch (NumberFormatException e) {
  323. return false;
  324. }
  325. }
  326. private static boolean matchNBTTagShort(String[] rule, int index, String value, NBTTagShort nbt) {
  327. try {
  328. return nbt.data == Short.parseShort(value);
  329. } catch (NumberFormatException e) {
  330. return false;
  331. }
  332. }
  333. private static boolean matchNBTTagString(String[] rule, int index, String value, NBTTagString nbt) {
  334. return value.equals(nbt.data);
  335. }
  336. }