package game.entity.npc; import java.util.List; import java.util.Map; import com.google.common.collect.BiMap; import com.google.common.collect.HashBiMap; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import game.block.Block; import game.init.SpeciesRegistry; import game.init.SpeciesRegistry.ModelType; import game.item.Item; import game.item.ItemArmor; import game.item.ItemBow; import game.item.ItemGunBase; import game.item.ItemHoe; import game.item.ItemShears; import game.item.ItemStack; import game.item.ItemSword; import game.item.ItemTool; import game.item.RngLoot; import game.properties.IStringSerializable; import game.rng.Random; import game.rng.WeightedList; public class SpeciesInfo { public final Map classmap; public final BiMap classnames; public final Class clazz; public final Class classEnum; public final ModelType renderer; public final float size; public final boolean prefix; public final String id; public final String origin; public final String name; public final int color1; public final int color2; public final CharacterInfo[] chars; public final ClassInfo[] classes; private final WeightedList[] items; private final int[] alignment = new int[Alignment.values().length]; private final int[] energies = new int[Energy.values().length]; private final int[] baseEnergy = new int[Energy.values().length]; public SpeciesInfo(String id, Class clazz, Class classEnum, boolean prefix, String origin, String name, ModelType renderer, float size, int color1, int color2, Object ... names) { this.classmap = classEnum == null ? null : Maps.newEnumMap(classEnum); this.classnames = classEnum == null ? null : HashBiMap.create(); this.clazz = clazz; // name.toLowerCase().replace(' ', '_'); this.classEnum = classEnum; this.renderer = renderer; this.size = size; this.prefix = prefix; this.id = id; // clazz.getSimpleName().substring(6); this.origin = origin; this.name = name; this.color1 = color1; this.color2 = color2; List chars = Lists.newArrayList(); List classes = Lists.newArrayList(); ClassInfo spclass = null; for(int z = 0; z < names.length; z++) { if(names[z] == null) { spclass = null; continue; } if(names[z] instanceof Enum) { classes.add(spclass = new ClassInfo(this, (Enum)names[z])); continue; } // String id = ((String)names[z]); // if(id.startsWith("$")) { // id = id.substring(1); // spclass = id.isEmpty() ? null : new ClassInfo(this, Enum.valueOf(this.classEnum, id.toUpperCase())); // if(spclass != null) // classes.add(spclass); // continue; // } String[] tok = ((String)names[z]).split(":", 3); int scolor1 = color1; int scolor2 = color2; if(z < names.length - 1 && names[z+1].getClass() == Integer.class) scolor2 = ((Integer)names[++z]).intValue(); if(z < names.length - 1 && names[z+1].getClass() == Integer.class) { scolor1 = scolor2; scolor2 = ((Integer)names[++z]).intValue(); } chars.add(new CharacterInfo(this, spclass, tok[0], tok.length > 1 && !tok[1].isEmpty() ? tok[1] : (tok[0].isEmpty() ? this.id : tok[0]).toLowerCase().replace(' ', '_'), tok.length > 2 ? tok[2] : "", scolor1, scolor2, names.length > 1)); } this.chars = chars.toArray(new CharacterInfo[chars.size()]); this.classes = classes.toArray(new ClassInfo[classes.size()]); this.items = new WeightedList[6]; for(int z = 0; z < this.items.length; z++) { this.items[z] = new WeightedList(); } // SpeciesRegistry.SPECIES.put(this.id, this); SpeciesRegistry.CLASSES.put(this.clazz, this); if(this.classEnum != null) { for(Enum type : this.classEnum.getEnumConstants()) { this.classnames.put(((IStringSerializable)type).getName(), type); } } } public CharacterInfo pickCharacter(Random rand) { return rand.pick(this.chars); } public WeightedList[] getItems() { return this.items; } public void addItems(Object[] items) { WeightedList[] lists = this.items; int curSlot = -1; ItemStack item; int chance = 1; int min = 1; int max = 1; for(int z = 0; z < items.length; z++) { Object stack = items[z]; if(stack == null) { item = null; } else if(stack instanceof String) { String name = (String)stack; if(name.isEmpty()) { lists = this.items; continue; } if(name.startsWith("$")) { name = name.substring(1); Enum type = this.classnames.get(name); if(type == null) { throw new IllegalArgumentException("Item [" + z + "/" + name + "] is not a known class"); } ClassInfo ci = this.classmap.get(type); // for(int c = 0; c < this.classes.length; c++) { // if(this.classnames.get(this.classes[c].type).equalsIgnoreCase(name)) { // ci = this.classes[c]; // } // } lists = ci.getItems(); continue; } CharacterInfo ch = null; for(int c = 0; c < this.chars.length; c++) { if(!this.chars[c].name.isEmpty() && this.chars[c].name.equals(name)) { ch = this.chars[c]; } } if(ch == null) { throw new IllegalArgumentException("Item [" + z + "/" + name + "] is not a known character"); } lists = ch.getItems(); continue; } else if(stack instanceof Integer) { int n = (Integer)stack; if(n <= 0) curSlot = -n; else chance = n; continue; } else if(stack instanceof ItemStack) { item = (ItemStack)stack; max = item.stackSize; item.stackSize = 1; } else if(stack instanceof Item) { item = new ItemStack((Item)stack); } else if(stack instanceof Block) { item = new ItemStack((Block)stack); } else { throw new IllegalArgumentException("Item [" + z + "] has to be a stack, item, block or null"); } int slot = curSlot; if(slot == -1 && item == null) { slot = 0; } else if(slot == -1) { slot = ItemArmor.getArmorPosition(item); if(slot == 0 && !(item.getItem() instanceof ItemTool || item.getItem() instanceof ItemSword || item.getItem() instanceof ItemBow || item.getItem() instanceof ItemHoe || item.getItem() instanceof ItemShears || item.getItem() instanceof ItemGunBase)) { slot = 5; } } lists[slot].add(new RngLoot(item, min, max, chance)); curSlot = -1; chance = 1; min = 1; max = 1; } } public SpeciesInfo setEnergy(Energy type, int affinity, int base) { this.energies[type.ordinal()] = affinity; this.baseEnergy[type.ordinal()] = base; return this; } public int getEnergyAffinity(Energy type) { return this.energies[type.ordinal()]; } public int getEnergyBase(Energy type) { return this.baseEnergy[type.ordinal()]; } public SpeciesInfo setAlignAffinity(Alignment type, int value) { this.alignment[type.ordinal()] = value; return this; } public int getAlignAffinity(Alignment type) { return this.alignment[type.ordinal()]; } }