2025-03-11 00:23:54 +01:00
|
|
|
package game.entity.npc;
|
|
|
|
|
|
|
|
import java.util.List;
|
|
|
|
import java.util.Map;
|
|
|
|
|
2025-03-16 17:40:47 +01:00
|
|
|
import com.google.common.collect.BiMap;
|
|
|
|
import com.google.common.collect.HashBiMap;
|
|
|
|
import com.google.common.collect.Lists;
|
|
|
|
import com.google.common.collect.Maps;
|
|
|
|
|
2025-03-11 00:23:54 +01:00
|
|
|
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<Enum, ClassInfo> classmap;
|
|
|
|
public final BiMap<String, Enum> classnames;
|
|
|
|
public final Class<? extends EntityNPC> clazz;
|
|
|
|
public final Class<? extends Enum> 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<RngLoot>[] 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<? extends EntityNPC> clazz, Class<? extends Enum> 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<CharacterInfo> chars = Lists.<CharacterInfo>newArrayList();
|
|
|
|
List<ClassInfo> classes = Lists.<ClassInfo>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<RngLoot>[] getItems() {
|
|
|
|
return this.items;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void addItems(Object[] items) {
|
|
|
|
WeightedList<RngLoot>[] 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()];
|
|
|
|
}
|
|
|
|
}
|