Initial framework for Anointments

None added yet, but the registration is working now.
This commit is contained in:
WayofTime 2021-01-10 16:50:19 -05:00
parent b3af1b8e77
commit b86595beaa
13 changed files with 506 additions and 5 deletions

View file

@ -0,0 +1,165 @@
package wayoftime.bloodmagic.anointment;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.function.Consumer;
import com.google.common.collect.Maps;
import com.google.common.collect.Multimap;
import com.google.common.reflect.TypeToken;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import com.google.gson.annotations.JsonAdapter;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.ai.attributes.Attribute;
import net.minecraft.entity.ai.attributes.AttributeModifier;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.registries.ForgeRegistryEntry;
import wayoftime.bloodmagic.core.living.LivingStats;
import wayoftime.bloodmagic.core.living.LivingUpgrade;
import wayoftime.bloodmagic.core.living.LivingUpgrade.Level;
@JsonAdapter(Anointment.Deserializer.class)
public class Anointment extends ForgeRegistryEntry<Anointment>
{
public static final Anointment DUMMY = new Anointment(new ResourceLocation("dummy"));
private final ResourceLocation key;
// private final Set<ResourceLocation> incompatible;
private final Map<String, Bonus> bonuses;
private IAttributeProvider attributeProvider;
private IDamageProvider damageProvider;
public Anointment(ResourceLocation key)
{
this.key = key;
this.bonuses = Maps.newHashMap();
}
public Anointment withBonusSet(String id, Consumer<List<Number>> modifiers)
{
// List<Number> values = DefaultedList.of();
List<Number> values = new ArrayList<Number>();
modifiers.accept(values);
bonuses.put(id, new Bonus(id, values));
return this;
}
public Number getBonusValue(String id, int level)
{
List<Number> modifiers = bonuses.getOrDefault(id, Bonus.DEFAULT).modifiers;
if (modifiers.isEmpty() || level == 0)
return 0;
return modifiers.get(level - 1);
}
public ResourceLocation getKey()
{
return key;
}
@Override
public String toString()
{
return key.toString();
}
public Anointment withAttributeProvider(IAttributeProvider attributeProvider)
{
this.attributeProvider = attributeProvider;
return this;
}
public IAttributeProvider getAttributeProvider()
{
return attributeProvider;
}
public Anointment withDamageProvider(IDamageProvider damageProvider)
{
this.damageProvider = damageProvider;
return this;
}
public IDamageProvider getDamageProvider()
{
return damageProvider;
}
public interface IAttributeProvider
{
void handleAttributes(AnointmentHolder holder, Multimap<Attribute, AttributeModifier> modifiers, UUID uuid, Anointment anoint, int level);
}
public interface IDamageProvider
{
double getAdditionalDamage(PlayerEntity player, ItemStack weapon, double damage, LivingStats stats, LivingEntity attacked, LivingUpgrade upgrade, int level);
}
public static class Bonus
{
private static final Bonus DEFAULT = new Bonus("null", Collections.emptyList());
private final String id;
private final List<Number> modifiers;
public Bonus(String id, List<Number> modifiers)
{
this.id = id;
this.modifiers = modifiers;
}
public String getId()
{
return id;
}
}
public static class Deserializer implements JsonDeserializer<Anointment>
{
@Override
public Anointment deserialize(JsonElement element, Type typeOfT, JsonDeserializationContext context)
throws JsonParseException
{
JsonObject json = element.getAsJsonObject();
ResourceLocation id = new ResourceLocation(json.getAsJsonPrimitive("id").getAsString());
List<Level> levels = context.deserialize(json.getAsJsonArray("levels"), new TypeToken<List<Level>>()
{
}.getType());
boolean negative = json.has("negative") && json.getAsJsonPrimitive("negative").getAsBoolean();
Anointment upgrade = new Anointment(id);
// if (negative)
// upgrade.asDowngrade();
// if (json.has("incompatibilities"))
// {
// String[] incompatibilities = context.deserialize(json.getAsJsonArray("incompatibilities"), String[].class);
// for (String incompatible : incompatibilities)
// upgrade.addIncompatibility(new ResourceLocation(incompatible));
// }
if (json.has("bonuses"))
{
Map<String, Number[]> bonuses = context.deserialize(json.getAsJsonObject("bonuses"), new TypeToken<Map<String, Number[]>>()
{
}.getType());
bonuses.forEach((k, v) -> upgrade.withBonusSet(k, numbers -> Collections.addAll(numbers, v)));
}
return upgrade;
}
}
}

View file

@ -0,0 +1,147 @@
package wayoftime.bloodmagic.anointment;
import java.util.Map;
import com.google.common.collect.Maps;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.nbt.ListNBT;
import net.minecraft.util.Hand;
import net.minecraft.util.ResourceLocation;
import wayoftime.bloodmagic.core.AnointmentRegistrar;
import wayoftime.bloodmagic.util.Constants;
public class AnointmentHolder
{
private final Map<Anointment, AnointmentData> anointments;
public AnointmentHolder(Map<Anointment, AnointmentData> anointments)
{
this.anointments = anointments;
}
public AnointmentHolder()
{
this(Maps.newHashMap());
}
public CompoundNBT serialize()
{
CompoundNBT compound = new CompoundNBT();
ListNBT statList = new ListNBT();
anointments.forEach((k, v) -> {
CompoundNBT anoint = new CompoundNBT();
anoint.putString("key", k.getKey().toString());
anoint.putInt("level", v.getLevel());
anoint.putInt("damage", v.getDamage());
anoint.putInt("max_damage", v.getMaxDamage());
statList.add(anoint);
});
compound.put("upgrades", statList);
//
// compound.putInt("maxPoints", maxPoints);
return compound;
}
public void deserialize(CompoundNBT nbt)
{
ListNBT statList = nbt.getList("anointments", 10);
statList.forEach(tag -> {
if (!(tag instanceof CompoundNBT))
return;
Anointment anoint = AnointmentRegistrar.ANOINTMENT_MAP.getOrDefault(new ResourceLocation(((CompoundNBT) tag).getString("key")), Anointment.DUMMY);
// LivingUpgrade upgrade = LivingArmorRegistrar.UPGRADE_MAP.getOrDefault(new ResourceLocation(((CompoundNBT) tag).getString("key")), LivingUpgrade.DUMMY);
if (anoint == Anointment.DUMMY)
return;
// double experience = ((CompoundNBT) tag).getDouble("exp");
AnointmentData data = new AnointmentData(((CompoundNBT) tag).getInt("level"), ((CompoundNBT) tag).getInt("damage"), ((CompoundNBT) tag).getInt("max_damage"));
anointments.put(anoint, data);
});
//
// maxPoints = nbt.getInt("maxPoints");
}
public static AnointmentHolder fromNBT(CompoundNBT holderTag)
{
AnointmentHolder holder = new AnointmentHolder();
holder.deserialize(holderTag);
return holder;
}
public static AnointmentHolder fromItemStack(ItemStack stack)
{
CompoundNBT nbtTag = stack.getTag();
if (nbtTag == null)
{
return null;
}
CompoundNBT holderTag = nbtTag.getCompound(Constants.NBT.ANOINTMENTS);
if (holderTag != null)
{
return fromNBT(holderTag);
}
return null;
}
public void toItemStack(ItemStack stack)
{
CompoundNBT nbtTag = stack.getOrCreateTag();
CompoundNBT childTag = this.serialize();
nbtTag.put(Constants.NBT.ANOINTMENTS, childTag);
}
public static AnointmentHolder fromPlayer(PlayerEntity player, Hand hand)
{
return fromPlayer(player, hand, false);
}
public static AnointmentHolder fromPlayer(PlayerEntity player, Hand hand, boolean createNew)
{
ItemStack heldItem = player.getHeldItem(hand);
AnointmentHolder holder = fromItemStack(heldItem);
return holder == null && createNew ? new AnointmentHolder() : holder;
}
public static void toPlayer(PlayerEntity player, Hand hand, AnointmentHolder holder)
{
ItemStack heldItem = player.getHeldItem(hand);
holder.toItemStack(heldItem);
}
public static class AnointmentData
{
private int level;
private int damage;
private int maxDamage;
public AnointmentData(int level, int damage, int maxDamage)
{
this.level = level;
this.damage = damage;
this.maxDamage = maxDamage;
}
public int getLevel()
{
return this.level;
}
public int getDamage()
{
return this.damage;
}
public int getMaxDamage()
{
return this.maxDamage;
}
}
}

View file

@ -0,0 +1,6 @@
package wayoftime.bloodmagic.anointment;
public class AnointmentUtil
{
}