Skip to content

Commit

Permalink
reinstate metaArmor classes (GregTechCEu#79)
Browse files Browse the repository at this point in the history
  • Loading branch information
BraggestSage833 authored Aug 15, 2021
1 parent 11ecde2 commit 757264a
Show file tree
Hide file tree
Showing 8 changed files with 457 additions and 0 deletions.
22 changes: 22 additions & 0 deletions src/main/java/gregtech/api/items/armor/ArmorHooks.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package gregtech.api.items.armor;

import net.minecraft.entity.EntityLivingBase;
import net.minecraft.item.ItemStack;
import net.minecraft.util.DamageSource;
import net.minecraft.util.NonNullList;

public class ArmorHooks {

public static void damageArmor(float damage, EntityLivingBase entity, NonNullList<ItemStack> inventory, DamageSource damageSource) {
double armorDamage = Math.max(1.0F, damage / 4.0F);
for (int i = 0; i < inventory.size(); i++) {
ItemStack itemStack = inventory.get(i);
if (itemStack.getItem() instanceof IArmorItem) {
((IArmorItem) itemStack.getItem()).damageArmor(entity, itemStack, damageSource, (int) armorDamage, i);
if (inventory.get(i).getCount() == 0) {
inventory.set(i, ItemStack.EMPTY);
}
}
}
}
}
192 changes: 192 additions & 0 deletions src/main/java/gregtech/api/items/armor/ArmorMetaItem.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
package gregtech.api.items.armor;

import com.google.common.base.Preconditions;
import com.google.common.collect.Multimap;
import com.google.common.collect.Streams;
import gregtech.api.items.metaitem.MetaItem;
import gregtech.api.items.metaitem.stats.IEnchantabilityHelper;
import gregtech.api.items.metaitem.stats.IItemComponent;
import net.minecraft.client.gui.ScaledResolution;
import net.minecraft.client.model.ModelBiped;
import net.minecraft.enchantment.Enchantment;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.ai.attributes.AttributeModifier;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Items;
import net.minecraft.inventory.EntityEquipmentSlot;
import net.minecraft.item.ItemStack;
import net.minecraft.util.DamageSource;
import net.minecraft.world.World;
import net.minecraftforge.common.ISpecialArmor;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;

public class ArmorMetaItem<T extends ArmorMetaItem<?>.ArmorMetaValueItem> extends MetaItem<T> implements IArmorItem, ISpecialArmor, IEnchantabilityHelper {

public ArmorMetaItem() {
super((short) 0);
}

@SuppressWarnings("unchecked")
@Override
protected T constructMetaValueItem(short metaValue, String unlocalizedName) {
return (T) new ArmorMetaValueItem(metaValue, unlocalizedName);
}

@Nonnull
private IArmorLogic getArmorLogic(ItemStack itemStack) {
T metaValueItem = getItem(itemStack);
return metaValueItem == null ? new DummyArmorLogic() : metaValueItem.getArmorLogic();
}

@Override
public Multimap<String, AttributeModifier> getAttributeModifiers(EntityEquipmentSlot slot, ItemStack stack) {
Multimap<String, AttributeModifier> multimap = super.getAttributeModifiers(slot, stack);
IArmorLogic armorLogic = getArmorLogic(stack);
multimap.putAll(armorLogic.getAttributeModifiers(slot, stack));
return multimap;
}

@Override
public ArmorProperties getProperties(EntityLivingBase player, @Nonnull ItemStack armor, DamageSource source, double damage, int slot) {
IArmorLogic armorLogic = getArmorLogic(armor);
if (armorLogic instanceof ISpecialArmorLogic) {
return ((ISpecialArmorLogic) armorLogic).getProperties(player, armor, source, damage, getSlotByIndex(slot));
}
return new ArmorProperties(0, 0, Integer.MAX_VALUE);
}

@Override
public int getArmorDisplay(EntityPlayer player, @Nonnull ItemStack armor, int slot) {
IArmorLogic armorLogic = getArmorLogic(armor);
if (armorLogic instanceof ISpecialArmorLogic) {
return ((ISpecialArmorLogic) armorLogic).getArmorDisplay(player, armor, slot);
}
return 0;
}

@Override
public void damageArmor(EntityLivingBase entity, @Nonnull ItemStack stack, DamageSource source, int damage, int slot) {
IArmorLogic armorLogic = getArmorLogic(stack);
armorLogic.damageArmor(entity, stack, source, damage, getSlotByIndex(slot));
}

@Override
public boolean handleUnblockableDamage(EntityLivingBase entity, @Nonnull ItemStack armor, DamageSource source, double damage, int slot) {
IArmorLogic armorLogic = getArmorLogic(armor);
if (armorLogic instanceof ISpecialArmorLogic) {
return ((ISpecialArmorLogic) armorLogic).handleUnblockableDamage(entity, armor, source, damage, getSlotByIndex(slot));
}
return false;
}

@Override
public void onArmorTick(World world, EntityPlayer player, ItemStack itemStack) {
IArmorLogic armorLogic = getArmorLogic(itemStack);
armorLogic.onArmorTick(world, player, itemStack);
}

@Override
public boolean isValidArmor(ItemStack stack, EntityEquipmentSlot armorType, Entity entity) {
IArmorLogic armorLogic = getArmorLogic(stack);
return super.isValidArmor(stack, armorType, entity) &&
armorLogic.isValidArmor(stack, entity, armorType);
}

@Nullable
@Override
public EntityEquipmentSlot getEquipmentSlot(ItemStack stack) {
IArmorLogic armorLogic = getArmorLogic(stack);
return armorLogic.getEquipmentSlot(stack);
}

@Nullable
@Override
public String getArmorTexture(ItemStack stack, Entity entity, EntityEquipmentSlot slot, String type) {
IArmorLogic armorLogic = getArmorLogic(stack);
return armorLogic.getArmorTexture(stack, entity, slot, type);
}

@Nullable
@Override
@SideOnly(Side.CLIENT)
public ModelBiped getArmorModel(EntityLivingBase entityLiving, ItemStack itemStack, EntityEquipmentSlot armorSlot, ModelBiped _default) {
IArmorLogic armorLogic = getArmorLogic(itemStack);
return armorLogic.getArmorModel(entityLiving, itemStack, armorSlot, _default);
}

@Override
public int getArmorLayersAmount(ItemStack itemStack) {
IArmorLogic armorLogic = getArmorLogic(itemStack);
return armorLogic.getArmorLayersAmount(itemStack);
}

@Override
public int getArmorLayerColor(ItemStack itemStack, int layerIndex) {
IArmorLogic armorLogic = getArmorLogic(itemStack);
return armorLogic.getArmorLayerColor(itemStack, layerIndex);
}

@Override
public void renderHelmetOverlay(ItemStack stack, EntityPlayer player, ScaledResolution resolution, float partialTicks) {
IArmorLogic armorLogic = getArmorLogic(stack);
armorLogic.renderHelmetOverlay(stack, player, resolution, partialTicks);
}

private static EntityEquipmentSlot getSlotByIndex(int index) {
switch (index) {
case 0: return EntityEquipmentSlot.FEET;
case 1: return EntityEquipmentSlot.LEGS;
case 2: return EntityEquipmentSlot.CHEST;
default: return EntityEquipmentSlot.HEAD;
}
}

public class ArmorMetaValueItem extends MetaValueItem {

private IArmorLogic armorLogic = new DummyArmorLogic();

protected ArmorMetaValueItem(int metaValue, String unlocalizedName) {
super(metaValue, unlocalizedName);
setMaxStackSize(1);
}

@Nonnull
public IArmorLogic getArmorLogic() {
return armorLogic;
}

public ArmorMetaValueItem setArmorLogic(IArmorLogic armorLogic) {
Preconditions.checkNotNull(armorLogic, "Cannot set armorLogic to null");
this.armorLogic = armorLogic;
this.armorLogic.addToolComponents(this);
return this;
}


@Override
public ArmorMetaValueItem addComponents(IItemComponent... stats) {
super.addComponents(stats);
return this;
}
}
@Override
public boolean isEnchantable(ItemStack stack) {
return true;
}

@Override
public int getItemEnchantability(ItemStack stack) {

return 50;
}
//TODO add Enchantability list by armor type
@Override
public boolean canApplyAtEnchantingTable(ItemStack stack, Enchantment enchantment) {
return enchantment.isAllowedOnBooks();
}
}
72 changes: 72 additions & 0 deletions src/main/java/gregtech/api/items/armor/ArmorRenderHooks.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package gregtech.api.items.armor;

import net.minecraft.client.model.ModelBase;
import net.minecraft.client.model.ModelBiped;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.GlStateManager.DestFactor;
import net.minecraft.client.renderer.GlStateManager.SourceFactor;
import net.minecraft.client.renderer.entity.layers.LayerArmorBase;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.inventory.EntityEquipmentSlot;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.client.ForgeHooksClient;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;

@SideOnly(Side.CLIENT)
public class ArmorRenderHooks {

public static boolean shouldNotRenderHeadItem(EntityLivingBase entityLivingBase) {
ItemStack itemStack = entityLivingBase.getItemStackFromSlot(EntityEquipmentSlot.HEAD);
return isArmorItem(itemStack, EntityEquipmentSlot.HEAD);
}

public static boolean isArmorItem(ItemStack itemStack, EntityEquipmentSlot slot) {
return (itemStack.getItem() instanceof IArmorItem && itemStack.getItem().getEquipmentSlot(itemStack) == slot);
}

public static void renderArmorLayer(LayerArmorBase<ModelBase> layer, EntityLivingBase entity, float limbSwing, float limbSwingAmount, float partialTicks, float ageInTicks, float netHeadYaw, float headPitch, float scale, EntityEquipmentSlot slotIn) {
ItemStack itemStack = entity.getItemStackFromSlot(slotIn);

if (isArmorItem(itemStack, slotIn)) {
IArmorItem armorItem = (IArmorItem) itemStack.getItem();
ModelBase armorModel = layer.getModelFromSlot(slotIn);
if (armorModel instanceof ModelBiped) {
armorModel = ForgeHooksClient.getArmorModel(entity, itemStack, slotIn, (ModelBiped) armorModel);
}
armorModel.setModelAttributes(layer.renderer.getMainModel());
armorModel.setLivingAnimations(entity, limbSwing, limbSwingAmount, partialTicks);
layer.setModelSlotVisible(armorModel, slotIn);

GlStateManager.enableBlend();
GlStateManager.blendFunc(SourceFactor.ONE, DestFactor.ONE_MINUS_SRC_ALPHA);

int layers = armorItem.getArmorLayersAmount(itemStack);
for (int layerIndex = 0; layerIndex < layers; layerIndex++) {
int i = armorItem.getArmorLayerColor(itemStack, layerIndex);
float f = (float) (i >> 16 & 255) / 255.0F;
float f1 = (float) (i >> 8 & 255) / 255.0F;
float f2 = (float) (i & 255) / 255.0F;
GlStateManager.color(f, f1, f2, 1.0f);
String type = layerIndex == 0 ? null : "layer_" + layerIndex;
layer.renderer.bindTexture(getArmorTexture(entity, itemStack, slotIn, type));
armorModel.render(entity, limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch, scale);
}
if (itemStack.hasEffect()) {
LayerArmorBase.renderEnchantedGlint(layer.renderer, entity, armorModel, limbSwing, limbSwingAmount, partialTicks, ageInTicks, netHeadYaw, headPitch, scale);
}
}
}

private static boolean isLegSlot(EntityEquipmentSlot equipmentSlot) {
return equipmentSlot == EntityEquipmentSlot.LEGS;
}

private static ResourceLocation getArmorTexture(EntityLivingBase entity, ItemStack itemStack, EntityEquipmentSlot slot, String type) {
ResourceLocation registryName = itemStack.getItem().getRegistryName();
String s1 = String.format("%s:textures/models/armor/%s_layer_%d%s.png", registryName.getNamespace(), registryName.getPath(),
(isLegSlot(slot) ? 2 : 1), type == null ? "" : String.format("_%s", type));
return new ResourceLocation(ForgeHooksClient.getArmorTexture(entity, itemStack, s1, slot, type));
}
}
36 changes: 36 additions & 0 deletions src/main/java/gregtech/api/items/armor/DummyArmorLogic.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package gregtech.api.items.armor;

import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.Multimap;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.ai.attributes.AttributeModifier;
import net.minecraft.inventory.EntityEquipmentSlot;
import net.minecraft.item.ItemStack;
import net.minecraft.util.DamageSource;

class DummyArmorLogic implements IArmorLogic {
@Override
public EntityEquipmentSlot getEquipmentSlot(ItemStack itemStack) {
return EntityEquipmentSlot.HEAD;
}

@Override
public void damageArmor(EntityLivingBase entity, ItemStack itemStack, DamageSource source, int damage, EntityEquipmentSlot equipmentSlot) {
}

@Override
public Multimap<String, AttributeModifier> getAttributeModifiers(EntityEquipmentSlot slot, ItemStack stack) {
return ImmutableMultimap.of();
}

@Override
public boolean isValidArmor(ItemStack itemStack, Entity entity, EntityEquipmentSlot equipmentSlot) {
return false;
}

@Override
public String getArmorTexture(ItemStack stack, Entity entity, EntityEquipmentSlot slot, String type) {
return "minecraft:textures/models/armor/diamond_layer_0.png";
}
}
18 changes: 18 additions & 0 deletions src/main/java/gregtech/api/items/armor/IArmorItem.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package gregtech.api.items.armor;

import net.minecraft.entity.EntityLivingBase;
import net.minecraft.item.ItemStack;
import net.minecraft.util.DamageSource;

public interface IArmorItem {

default int getArmorLayersAmount(ItemStack itemStack) {
return 1;
}

default int getArmorLayerColor(ItemStack itemStack, int layerIndex) {
return 0xFFFFFF;
}

void damageArmor(EntityLivingBase entity, ItemStack itemStack, DamageSource source, int damage, int slot);
}
Loading

0 comments on commit 757264a

Please sign in to comment.