2018-09-12 01:29:49 +02:00
|
|
|
package com.minelittlepony.unicopia.spell;
|
|
|
|
|
|
|
|
import java.util.HashMap;
|
2019-02-04 19:29:37 +01:00
|
|
|
import java.util.HashSet;
|
2018-09-12 01:29:49 +02:00
|
|
|
import java.util.Map;
|
2019-02-04 19:29:37 +01:00
|
|
|
import java.util.Optional;
|
2018-09-20 22:49:10 +02:00
|
|
|
import java.util.Set;
|
2018-09-12 01:29:49 +02:00
|
|
|
import java.util.concurrent.Callable;
|
|
|
|
|
2019-01-10 18:46:40 +01:00
|
|
|
import javax.annotation.Nonnull;
|
2019-01-22 17:39:30 +01:00
|
|
|
import javax.annotation.Nullable;
|
2019-02-04 19:29:37 +01:00
|
|
|
import javax.annotation.concurrent.Immutable;
|
2019-01-10 18:46:40 +01:00
|
|
|
|
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");
|
|
|
|
}
|
|
|
|
|
2019-02-04 19:29:37 +01:00
|
|
|
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() {
|
2019-01-22 17:39:30 +01:00
|
|
|
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);
|
2019-02-02 17:50:15 +01:00
|
|
|
registerSpell(SpellDisguise::new);
|
2019-02-04 20:24:10 +01:00
|
|
|
registerSpell(SpellNecromancy::new);
|
2018-09-12 01:29:49 +02:00
|
|
|
}
|
|
|
|
|
2019-02-04 19:29:37 +01: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;
|
|
|
|
}
|
|
|
|
|
2018-09-21 17:53:33 +02:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2018-09-21 17:53:33 +02:00
|
|
|
public NBTTagCompound serializeEffectToNBT(IMagicEffect effect) {
|
|
|
|
NBTTagCompound compound = effect.toNBT();
|
|
|
|
|
|
|
|
compound.setString("effect_id", effect.getName());
|
|
|
|
|
|
|
|
return compound;
|
|
|
|
}
|
|
|
|
|
2019-02-04 19:29:37 +01:00
|
|
|
private Optional<Entry<?>> getEntryFromStack(ItemStack stack) {
|
|
|
|
return Optional.ofNullable(entries.get(getKeyFromStack(stack)));
|
|
|
|
}
|
|
|
|
|
2019-01-22 17:39:30 +01:00
|
|
|
@Nullable
|
2018-09-20 22:49:10 +02:00
|
|
|
public IDispenceable getDispenseActionFrom(ItemStack stack) {
|
2019-02-04 19:29:37 +01:00
|
|
|
return getEntryFromStack(stack).map(Entry::dispensable).orElse(null);
|
2018-09-20 22:49:10 +02:00
|
|
|
}
|
|
|
|
|
2019-01-22 17:39:30 +01:00
|
|
|
@Nullable
|
|
|
|
public IUseAction getUseActionFrom(ItemStack stack) {
|
2019-02-04 19:29:37 +01:00
|
|
|
return getEntryFromStack(stack).map(Entry::useable).orElse(null);
|
2019-01-22 17:39:30 +01:00
|
|
|
}
|
|
|
|
|
2019-02-04 19:29:37 +01:00
|
|
|
@Nullable
|
2018-09-20 22:49:10 +02:00
|
|
|
public IMagicEffect getSpellFromItemStack(ItemStack stack) {
|
|
|
|
return getSpellFromName(getKeyFromStack(stack));
|
|
|
|
}
|
|
|
|
|
2019-02-04 19:29:37 +01:00
|
|
|
public <T extends IMagicEffect> void registerSpell(Callable<T> factory) {
|
2018-09-20 22:49:10 +02:00
|
|
|
try {
|
2019-02-04 19:29:37 +01:00
|
|
|
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
|
|
|
}
|
|
|
|
|
2019-01-10 18:46:40 +01:00
|
|
|
public ItemStack disenchantStack(ItemStack stack) {
|
|
|
|
if (stackHasEnchantment(stack)) {
|
|
|
|
stack.getTagCompound().removeTag("spell");
|
2019-01-13 21:06:54 +01:00
|
|
|
|
|
|
|
if (stack.getTagCompound().isEmpty()) {
|
|
|
|
stack.setTagCompound(null);
|
|
|
|
}
|
2019-01-10 18:46:40 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return stack;
|
|
|
|
}
|
|
|
|
|
|
|
|
public ItemStack enchantStack(ItemStack stack, ItemStack from) {
|
2019-02-04 19:29:37 +01:00
|
|
|
return enchantStack(stack, getKeyFromStack(from));
|
2019-01-10 18:46:40 +01:00
|
|
|
}
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2019-01-10 18:46:40 +01:00
|
|
|
@Nonnull
|
2018-09-21 17:53:33 +02:00
|
|
|
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
|
|
|
|
2019-02-04 19:29:37 +01:00
|
|
|
public Set<String> getAllNames(SpellAffinity affinity) {
|
|
|
|
return keysByAffinity.get(affinity);
|
2018-09-12 01:29:49 +02:00
|
|
|
}
|
|
|
|
|
2019-02-04 19:29:37 +01:00
|
|
|
@Immutable
|
|
|
|
class Entry<T extends IMagicEffect> {
|
|
|
|
final Callable<T> factory;
|
2018-09-20 22:49:10 +02:00
|
|
|
|
2019-02-04 19:29:37 +01:00
|
|
|
final int color;
|
2018-09-20 22:49:10 +02:00
|
|
|
|
2019-02-04 19:29:37 +01:00
|
|
|
final boolean canDispense;
|
|
|
|
final boolean canUse;
|
2019-01-22 17:39:30 +01:00
|
|
|
|
2019-02-04 19:29:37 +01:00
|
|
|
final SpellAffinity affinity;
|
|
|
|
|
|
|
|
Entry(Callable<T> factory) throws Exception {
|
|
|
|
T inst = factory.call();
|
2018-09-20 22:49:10 +02:00
|
|
|
|
|
|
|
this.factory = factory;
|
2019-01-22 17:39:30 +01:00
|
|
|
this.color = inst.getTint();
|
|
|
|
this.canDispense = inst instanceof IDispenceable;
|
|
|
|
this.canUse = inst instanceof IUseAction;
|
2019-02-04 19:29:37 +01:00
|
|
|
this.affinity = inst.getAffinity();
|
|
|
|
|
|
|
|
if (inst.isCraftable()) {
|
|
|
|
for (SpellAffinity affinity : affinity.getImplicators()) {
|
|
|
|
keysByAffinity.computeIfAbsent(affinity, a -> new HashSet<>()).add(inst.getName());
|
|
|
|
}
|
|
|
|
}
|
2019-01-22 17:39:30 +01:00
|
|
|
|
|
|
|
entries.put(inst.getName(), this);
|
2018-09-20 22:49:10 +02:00
|
|
|
}
|
|
|
|
|
2019-02-04 19:29:37 +01: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-04 19:29:37 +01:00
|
|
|
return factory.call();
|
2018-09-20 22:49:10 +02:00
|
|
|
} catch (Exception e) {
|
|
|
|
e.printStackTrace();
|
|
|
|
}
|
|
|
|
|
|
|
|
return null;
|
|
|
|
}
|
2018-09-12 01:29:49 +02:00
|
|
|
}
|
|
|
|
}
|