Unicopia/src/main/java/com/minelittlepony/unicopia/spell/SpellRegistry.java

215 lines
5.8 KiB
Java
Raw Normal View History

2018-09-12 01:29:49 +02:00
package com.minelittlepony.unicopia.spell;
import java.util.HashMap;
import java.util.HashSet;
2018-09-12 01:29:49 +02:00
import java.util.Map;
import java.util.Optional;
2018-09-20 22:49:10 +02:00
import java.util.Set;
2019-02-07 18:18:51 +01:00
import java.util.function.Supplier;
2018-09-12 01:29:49 +02:00
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.annotation.concurrent.Immutable;
2018-09-20 22:49:10 +02:00
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
2018-09-12 01:29:49 +02:00
public class SpellRegistry {
private static final SpellRegistry instance = new SpellRegistry();
public static SpellRegistry instance() {
return instance;
}
2018-09-20 22:49:10 +02:00
public static boolean stackHasEnchantment(ItemStack stack) {
return stack.hasTagCompound() && stack.getTagCompound().hasKey("spell");
}
private final Map<String, Entry<?>> entries = new HashMap<>();
private final Map<SpellAffinity, Set<String>> keysByAffinity = new HashMap<>();
2018-09-12 01:29:49 +02:00
private SpellRegistry() {
registerSpell(SpellShield::new);
registerSpell(SpellCharge::new);
registerSpell(SpellFire::new);
registerSpell(SpellIce::new);
2019-01-26 18:28:21 +01:00
registerSpell(SpellPortal::new);
2019-02-01 00:07:51 +01:00
registerSpell(SpellVortex::new);
registerSpell(SpellDisguise::new);
2019-02-04 20:24:10 +01:00
registerSpell(SpellNecromancy::new);
2019-02-04 21:05:37 +01:00
registerSpell(SpellAwkward::new);
registerSpell(SpellInferno::new);
registerSpell(SpellDrake::new);
2019-02-07 18:18:51 +01:00
registerSpell(GenericSpell.factory("light", 0xf0ff0f, SpellAffinity.GOOD));
2018-09-12 01:29:49 +02:00
}
@Nullable
2018-09-20 22:49:10 +02:00
public IMagicEffect getSpellFromName(String name) {
if (entries.containsKey(name)) {
return entries.get(name).create();
}
return null;
}
@SuppressWarnings("unchecked")
public <T extends IMagicEffect> T copyInstance(T effect) {
return (T)createEffectFromNBT(serializeEffectToNBT(effect));
}
public IMagicEffect createEffectFromNBT(NBTTagCompound compound) {
if (compound.hasKey("effect_id")) {
2018-09-20 22:49:10 +02:00
IMagicEffect effect = getSpellFromName(compound.getString("effect_id"));
if (effect != null) {
2019-01-26 18:27:24 +01:00
effect.readFromNBT(compound);
2018-09-12 01:29:49 +02:00
}
2018-09-20 22:49:10 +02:00
return effect;
}
return null;
}
public NBTTagCompound serializeEffectToNBT(IMagicEffect effect) {
NBTTagCompound compound = effect.toNBT();
compound.setString("effect_id", effect.getName());
return compound;
}
private Optional<Entry<?>> getEntryFromStack(ItemStack stack) {
return Optional.ofNullable(entries.get(getKeyFromStack(stack)));
}
@Nullable
2018-09-20 22:49:10 +02:00
public IDispenceable getDispenseActionFrom(ItemStack stack) {
return getEntryFromStack(stack).map(Entry::dispensable).orElse(null);
2018-09-20 22:49:10 +02:00
}
@Nullable
public IUseAction getUseActionFrom(ItemStack stack) {
return getEntryFromStack(stack).map(Entry::useable).orElse(null);
}
@Nullable
2018-09-20 22:49:10 +02:00
public IMagicEffect getSpellFromItemStack(ItemStack stack) {
return getSpellFromName(getKeyFromStack(stack));
}
2019-02-07 18:18:51 +01:00
public <T extends IMagicEffect> void registerSpell(Supplier<T> factory) {
2018-09-20 22:49:10 +02:00
try {
new Entry<T>(factory);
2018-09-12 01:29:49 +02:00
} catch (Exception e) {
e.printStackTrace();
}
2018-09-20 22:49:10 +02:00
}
public ItemStack disenchantStack(ItemStack stack) {
if (stackHasEnchantment(stack)) {
stack.getTagCompound().removeTag("spell");
if (stack.getTagCompound().isEmpty()) {
stack.setTagCompound(null);
}
}
return stack;
}
public ItemStack enchantStack(ItemStack stack, ItemStack from) {
return enchantStack(stack, getKeyFromStack(from));
}
2018-09-20 22:49:10 +02:00
public ItemStack enchantStack(ItemStack stack, String name) {
stack.setTagCompound(new NBTTagCompound());
stack.getTagCompound().setString("spell", name);
return stack;
}
@Nonnull
public static String getKeyFromStack(ItemStack stack) {
2018-09-20 22:49:10 +02:00
if (stack.isEmpty() || !stack.hasTagCompound() || !stack.getTagCompound().hasKey("spell")) {
return "";
}
return stack.getTagCompound().getString("spell");
}
public int getSpellTintFromStack(ItemStack stack) {
return getSpellTint(getKeyFromStack(stack));
}
public int getSpellTint(String key) {
if (entries.containsKey(key)) {
return entries.get(key).color;
}
return 0xffffff;
}
2018-09-12 01:29:49 +02:00
public Set<String> getAllNames(SpellAffinity affinity) {
return keysByAffinity.get(affinity);
2018-09-12 01:29:49 +02:00
}
@Immutable
class Entry<T extends IMagicEffect> {
2019-02-07 18:18:51 +01:00
final Supplier<T> factory;
2018-09-20 22:49:10 +02:00
final int color;
2018-09-20 22:49:10 +02:00
final boolean canDispense;
final boolean canUse;
final SpellAffinity affinity;
2019-02-07 18:18:51 +01:00
Entry(Supplier<T> factory) throws Exception {
T inst = factory.get();
2018-09-20 22:49:10 +02:00
this.factory = factory;
this.color = inst.getTint();
this.canDispense = inst instanceof IDispenceable;
this.canUse = inst instanceof IUseAction;
this.affinity = inst.getAffinity();
if (inst.isCraftable()) {
for (SpellAffinity affinity : affinity.getImplicators()) {
keysByAffinity.computeIfAbsent(affinity, a -> new HashSet<>()).add(inst.getName());
}
}
entries.put(inst.getName(), this);
2018-09-20 22:49:10 +02:00
}
IUseAction useable() {
if (!canUse) {
return null;
}
return (IUseAction)create();
}
IDispenceable dispensable() {
if (!canDispense) {
return null;
}
return (IDispenceable)create();
}
T create() {
2018-09-20 22:49:10 +02:00
try {
2019-02-07 18:18:51 +01:00
return factory.get();
2018-09-20 22:49:10 +02:00
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
2018-09-12 01:29:49 +02:00
}
}