SEE LAST POST FOR SOLUTION
I ran into this issue a bit ago with a different set of armor. If you implement ISpecialAmor, then when overriding getProperties, which returns an ArmorProperties object which determines damage absorption, you get either full invincibility or no protection at all. I got it working, but looking back at the code, I can't tell what exactly is different from what I have now.
For the curious, I'm trying to make mid-game powered armor.
Code for WORKING armorset (a rather unrealistic Hazmat Suit):
Code for the NOT WORKING armorset:
To be more exact - when I wear the power armor, one of two things happens. If it has any amount of charge, I take zero damage from all blockable sources (mobs, cacti, lava, etc.). When it has zero charge, I take full damage from all sources, including blockable ones (the second part - full damage at zero charge - is intended). All other bits of code for the armor are working, including the dynamic armor bar change (which I find charming) and the charging.
[Reply to side questions in spoilers so the moderators don't eat me ^^]
Side Question - How would I specify "CoFH Core OR CoFH Lib" as a requirement in my main mod code? I understand hard and soft dependencies, but don't know how to do an "either or" sort of thing.
Second Side Question - How would I do the power bar? I'll figure it out myself later if I need to.
Thanks!
I ran into this issue a bit ago with a different set of armor. If you implement ISpecialAmor, then when overriding getProperties, which returns an ArmorProperties object which determines damage absorption, you get either full invincibility or no protection at all. I got it working, but looking back at the code, I can't tell what exactly is different from what I have now.
For the curious, I'm trying to make mid-game powered armor.
Code for WORKING armorset (a rather unrealistic Hazmat Suit):
Code:
//Imports 'n' stuff
public class ItemHazmatArmor extends ItemArmorXF implements ISpecialArmor {
public static ArmorMaterial HAZMATARMOR = EnumHelper.addArmorMaterial("HAZMATARMOR", 12, new int[] {25, 25, 25, 25}, 7);
public ItemHazmatArmor(String unlocalizedName, ArmorMaterial material, int armorSetNumber, int armorPiece) {
super(unlocalizedName, HAZMATARMOR, armorSetNumber, armorPiece);
}
@Override
public void onArmorTick(World world, EntityPlayer player, ItemStack armor) {
//Helmet gives you water breathing
if (ModItems.itemHazmatHelmet == armor.getItem()) {
player.addPotionEffect(new PotionEffect(Potion.waterBreathing.id, 1, 0));
}
}
//Different armor pieces give different amounts of protection against different damage types
//The armor properties is returned as (1 - use this armor first, (1-(percent damage taken)), Integer.MAX_VALUE)
@Override
public ArmorProperties getProperties(EntityLivingBase player,
ItemStack armor, DamageSource source, double damage, int slot) {
//Take damage first; damageArmor is derpy in how it is called
if (source == source.inFire || source == source.lava || source == source.onFire || source == source.fall || source == source.cactus || source == source.wither || source == source.magic || !source.isUnblockable()) {
damageArmor(player, armor, source, 1, slot);
}
//Chestplate protects against fire/lava
if (ModItems.itemHazmatChestplate == armor.getItem() && (source == source.inFire || source == source.lava || source == source.onFire)) {
//Take 1/3 fire/lava damage
return new ArmorProperties(1, .67, Integer.MAX_VALUE);
//Boots protect against fall damage
} else if (ModItems.itemHazmatBoots == armor.getItem() && source == source.fall) {
//Take 2/3 fall damage
return new ArmorProperties(1, .34, Integer.MAX_VALUE);
//Leggings protect against cactus, wither, and "magic"
} else if (ModItems.itemHazmatLeggings == armor.getItem() && (source == source.cactus || source == source.wither || source == source.magic)){
//Take 1/3 cactus/wither/magic damage
return new ArmorProperties(1, .67, Integer.MAX_VALUE);
} else if (!source.isUnblockable()){
return new ArmorProperties(1, 0, 0);
} else {
return new ArmorProperties(0, 0, 0);
}
}
@Override
public int getArmorDisplay(EntityPlayer player, ItemStack armor, int slot) {
//Always return zero 'cause it's just a hazmat suit; no protection offered. :P
return 0;
}
@Override
public void damageArmor(EntityLivingBase entity, ItemStack stack,
DamageSource source, int damage, int slot) {
stack.damageItem(1, entity);
}
}
Code:
//Imports 'n' stuff
public class ItemPoweredArmor extends ItemArmorXF implements ISpecialArmor, IEnergyContainerItem {
//Armor material
public static ArmorMaterial POWEREDARMOR = EnumHelper.addArmorMaterial("POWEREDARMOR", 12, new int[] {3, 7, 5, 2}, 10);
public static double maxProtect = .75;
public static double minProtect = .1;
public static int capacity = 10000;
public static int maxTransfer = 100;
public static int durability = 300;
public static int energyPerHit = capacity / durability;
public ItemPoweredArmor(String unlocalizedName, ArmorMaterial material, int armorSetNumber, int armorPiece) {
super(unlocalizedName, POWEREDARMOR, armorSetNumber, armorPiece);
}
//Set tooltip
@Override
public void addInformation(ItemStack stack, EntityPlayer player, List list, boolean par4) {
String str = "";
int storedEnergy = getEnergyStored(stack);
str = String.valueOf(storedEnergy) + "/" + getMaxEnergyStored(stack) + " RF";
list.add(str);
}
public double getEnergyStoredPercent(ItemStack stack) {
double energyStored = getEnergyStored(stack);
double maxEnergyStored = getMaxEnergyStored(stack);
double percentStored = energyStored / maxEnergyStored;
return (percentStored);
}
//Pasted from KingLemming's ItemEnergyContainer code, with minor adjustments as needed
@Override
public int receiveEnergy(ItemStack container, int maxReceive,
boolean simulate) {
if (container.stackTagCompound == null) {
container.stackTagCompound = new NBTTagCompound();
}
int energy = container.stackTagCompound.getInteger("Energy");
int energyReceived = Math.min(capacity - energy, Math.min(this.maxTransfer, maxReceive));
if (!simulate) {
energy += energyReceived;
container.stackTagCompound.setInteger("Energy", energy);
}
return energyReceived;
}
//Pasted from KingLemming's ItemEnergyContainer code, with minor adjustments as needed
@Override
public int extractEnergy(ItemStack container, int maxExtract,
boolean simulate) {
if (container.stackTagCompound == null || !container.stackTagCompound.hasKey("Energy")) {
return 0;
}
int energy = container.stackTagCompound.getInteger("Energy");
int energyExtracted = Math.min(energy, Math.min(this.maxTransfer, maxExtract));
if (!simulate) {
energy -= energyExtracted;
container.stackTagCompound.setInteger("Energy", energy);
}
return energyExtracted;
}
//Pasted from KingLemming's ItemEnergyContainer code, with minor adjustments as needed
@Override
public int getEnergyStored(ItemStack container) {
if (container.stackTagCompound == null || !container.stackTagCompound.hasKey("Energy")) {
return 0;
}
return container.stackTagCompound.getInteger("Energy");
}
@Override
public int getMaxEnergyStored(ItemStack container) {
return capacity;
}
@Override
public ArmorProperties getProperties(EntityLivingBase player,
ItemStack armor, DamageSource source, double damage, int slot) {
if (!source.isUnblockable()) {
double absorbRatio = getEnergyStoredPercent(armor);
LogHelper.info(absorbRatio);
//Make sure that the absorb ratio is always at least the minimum protect if there is energy left
//but also that it is never above the max
if (getEnergyStored(armor) != 0) {
absorbRatio += minProtect;
}
if (absorbRatio > maxProtect) {
absorbRatio = maxProtect;
}
LogHelper.info(absorbRatio);
return new ArmorProperties(1, absorbRatio, Integer.MAX_VALUE);
} else {
return new ArmorProperties(0, 0, 0);
}
}
@Override
public int getArmorDisplay(EntityPlayer player, ItemStack armor, int slot) {
//Armor bars - each "half shirt" above the health bar
double absorbRatio = getEnergyStoredPercent(armor);
//Make sure that the absorb ratio is always at least the minimum protect if there is energy left
//but also that it is never above the max
if (getEnergyStored(armor) != 0) {
absorbRatio += minProtect;
}
if (absorbRatio > maxProtect) {
absorbRatio = maxProtect;
}
//Multiply by 25 to get amount/25
//Divide by 4 (multiply by .25) to get amount per armor piece
double armorBars = absorbRatio * 25 * .25;
//Make sure that SOME bars are displayed as long as the protection is greater than 0
if (armorBars > 0 && armorBars < 1) {
armorBars = 1;
}
return MathHelper.floor(armorBars);
}
@Override
public void damageArmor(EntityLivingBase entity, ItemStack stack,
DamageSource source, int damage, int slot) {
extractEnergy(stack, energyPerHit, false);
}
//TODO - POWER BAR
}
[Reply to side questions in spoilers so the moderators don't eat me ^^]
Side Question - How would I specify "CoFH Core OR CoFH Lib" as a requirement in my main mod code? I understand hard and soft dependencies, but don't know how to do an "either or" sort of thing.
Second Side Question - How would I do the power bar? I'll figure it out myself later if I need to.
Thanks!
Last edited: