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