diff --git a/src/main/java/com/zivilon/cinder_loe/CinderEventHandler.java b/src/main/java/com/zivilon/cinder_loe/CinderEventHandler.java index ef588f6..5443109 100644 --- a/src/main/java/com/zivilon/cinder_loe/CinderEventHandler.java +++ b/src/main/java/com/zivilon/cinder_loe/CinderEventHandler.java @@ -7,14 +7,20 @@ import cpw.mods.fml.common.IFuelHandler; import cpw.mods.fml.common.eventhandler.SubscribeEvent; import cpw.mods.fml.common.registry.GameRegistry; import lotr.common.LOTRMod; +import lotr.common.enchant.LOTREnchantment; +import lotr.common.enchant.LOTREnchantmentHelper; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.IEntityLivingData; import net.minecraft.entity.player.EntityPlayerMP; -import net.minecraft.init.Items; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; +import net.minecraft.nbt.NBTTagString; import net.minecraft.potion.Potion; import net.minecraft.potion.PotionEffect; +import net.minecraft.util.ChatComponentText; +import net.minecraft.util.EnumChatFormatting; import net.minecraft.world.World; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.event.entity.living.LivingHurtEvent; @@ -24,22 +30,43 @@ import java.util.Random; public class CinderEventHandler implements IFuelHandler { private static final Random random = new Random(); public CinderEventHandler() { - FMLCommonHandler.instance().bus().register((Object)this); - MinecraftForge.EVENT_BUS.register((Object)this); - MinecraftForge.TERRAIN_GEN_BUS.register((Object)this); - GameRegistry.registerFuelHandler((IFuelHandler)this); + FMLCommonHandler.instance().bus().register(this); + MinecraftForge.EVENT_BUS.register(this); + MinecraftForge.TERRAIN_GEN_BUS.register(this); + GameRegistry.registerFuelHandler(this); } @SubscribeEvent public void onLivingHurt(LivingHurtEvent event) { EntityLivingBase entity = event.entityLiving; - EntityLivingBase attacker = event.source.getEntity() instanceof EntityLivingBase ? (EntityLivingBase)event.source.getEntity() : null; + EntityLivingBase attacker = event.source.getEntity() instanceof EntityLivingBase ? (EntityLivingBase) event.source.getEntity() : null; World world = entity.worldObj; + // Negative Arrow Protection Handler + if (event.source.isProjectile() && entity instanceof EntityPlayerMP) { + EntityPlayerMP player = (EntityPlayerMP) entity; + for (int i = 0; i < 4; i++) { + ItemStack armor = entity.getEquipmentInSlot(i + 1); + + if (armor != null) { + LOTREnchantment enchantment = LOTREnchantment.getEnchantmentByName("protectRangedWeak1"); + if (LOTREnchantmentHelper.hasEnchant(armor, enchantment)) { + float level = enchantment.getValueModifier(); + if (level > 0) { + float additionalDamage = level * 0.2f; // 20% more damage per level + event.ammount += additionalDamage; + player.addChatMessage(new ChatComponentText(EnumChatFormatting.RED + "Your armor has received a negative modifier!")); + } + } + } + } + } + + // Broken Halo Event handler if (attacker != null && event.source.getSourceOfDamage() == attacker) { ItemStack helmet = entity.getEquipmentInSlot(4); if (helmet != null && helmet.getItem() instanceof BrokenHalo) { - if (random.nextDouble() <= 0.25 ) { + if (random.nextDouble() <= 0.25) { // Summon Corrupt Civilian NPC CorruptMan spawnedEntity = new CorruptMan(world); spawnedEntity.copyLocationAndAnglesFrom(attacker); @@ -59,8 +86,78 @@ public class CinderEventHandler implements IFuelHandler { } } } + // Smithing Rework event handler + if (entity != null && entity instanceof EntityPlayerMP) { + EntityPlayerMP player = (EntityPlayerMP) entity; + for (int i = 0; i < 4; ++i) { + ItemStack armor = entity.getEquipmentInSlot(i + 1); + if (armor != null && armor.isItemStackDamageable()) { + float durabilityPercent = (float) (armor.getMaxDamage() - armor.getItemDamage()) / armor.getMaxDamage(); + if (durabilityPercent <= 0.6) { + if (random.nextDouble() <= 1.02) { + addNegativeModifier(armor); + sendNegativeModifierMessage(player); + playNegativeModifierSound(player.worldObj, player.posX, player.posY, player.posZ); + } + if (durabilityPercent <= 0.50) { + if (random.nextDouble() <= 1.05) { + addNegativeModifier(armor); + sendNegativeModifierMessage(player); + playNegativeModifierSound(player.worldObj, player.posX, player.posY, player.posZ); + } + if (durabilityPercent <= 0.4) { + if (random.nextDouble() <= 1.1) { + addNegativeModifier(armor); + sendNegativeModifierMessage(player); + playNegativeModifierSound(player.worldObj, player.posX, player.posY, player.posZ); + } + } + } + } + } + } + } + } + private void sendNegativeModifierMessage(EntityPlayerMP player) { + player.addChatMessage(new ChatComponentText(EnumChatFormatting.RED + "Your armor has received a negative modifier!")); + } + + private void playNegativeModifierSound(World world, double x, double y, double z) { + world.playSoundEffect(x, y, z, "mob.irongolem.hit", 1.0F, 2.0F); + } + private void addNegativeModifier(ItemStack armor) { + NBTTagCompound tag = armor.getTagCompound(); + if (tag == null) { + tag = new NBTTagCompound(); + armor.setTagCompound(tag); + } + + if (!tag.hasKey("LOTREnch")) { + tag.setTag("LOTREnch", new NBTTagList()); + } + + NBTTagList enchList = tag.getTagList("LOTREnch", 8); // 8 is the type for strings + + String[] negativeArmorModifiers = {"protectWeak1", "protectWeak2"}; + String newArmorModifier = negativeArmorModifiers[random.nextInt(negativeArmorModifiers.length)]; + + boolean hasModifier = false; + for (int i = 0; i < enchList.tagCount(); i++) { + String ench = enchList.getStringTagAt(i); + if (ench.equals(newArmorModifier)) { + hasModifier = true; + break; + } + } + + if (!hasModifier) { + enchList.appendTag(new NBTTagString(newArmorModifier)); + } + + tag.setTag("LOTREnch", enchList); } + private ItemStack getRandomWeapon() { Item[] weapons = new Item[]{LOTRMod.blacksmithHammer, LOTRMod.daggerIron, LOTRMod.dunlendingTrident, LOTRMod.battleaxeBronze, CinderLoE.cleaver}; return new ItemStack(weapons[random.nextInt(weapons.length)]); diff --git a/src/main/java/com/zivilon/cinder_loe/client/render/RenderNex.java b/src/main/java/com/zivilon/cinder_loe/client/render/RenderNex.java index 286829b..c660d0b 100644 --- a/src/main/java/com/zivilon/cinder_loe/client/render/RenderNex.java +++ b/src/main/java/com/zivilon/cinder_loe/client/render/RenderNex.java @@ -1,7 +1,8 @@ -package lotr.client.render.entity; +package com.zivilon.cinder_loe.client.render; import com.zivilon.cinder_loe.client.model.ModelNex; import com.zivilon.cinder_loe.entity.Nex; +import lotr.client.render.entity.LOTRRandomSkins; import lotr.common.entity.LOTRRandomSkinEntity; import lotr.common.entity.npc.LOTREntityBalrog; import net.minecraft.client.model.ModelBase; diff --git a/src/main/java/com/zivilon/cinder_loe/enchants/LOTREnchantmentWeakProtectionRanged.java b/src/main/java/com/zivilon/cinder_loe/enchants/LOTREnchantmentWeakProtectionRanged.java new file mode 100644 index 0000000..44dfd5b --- /dev/null +++ b/src/main/java/com/zivilon/cinder_loe/enchants/LOTREnchantmentWeakProtectionRanged.java @@ -0,0 +1,51 @@ +package com.zivilon.cinder_loe.enchants; + +import lotr.common.enchant.LOTREnchantmentProtectionRanged; +import lotr.common.enchant.LOTREnchantmentProtectionSpecial; +import lotr.common.item.LOTRMaterial; +import net.minecraft.item.Item; +import net.minecraft.item.ItemArmor; +import net.minecraft.item.ItemStack; +import net.minecraft.util.DamageSource; +import net.minecraft.util.StatCollector; + +public class LOTREnchantmentWeakProtectionRanged extends LOTREnchantmentProtectionSpecial { + + public LOTREnchantmentWeakProtectionRanged(String s, int level) { + super(s, level); + } + @Override + protected boolean protectsAgainst(DamageSource source) { + // Check if the damage source is a projectile + return source.isProjectile(); + } + + @Override + public String getDescription(ItemStack itemstack) { + return StatCollector.translateToLocalFormatted((String)"lotr.enchant.protectRanged.desc", (Object[])new Object[]{this.formatAdditiveInt(this.calcIntProtection())}); + } + + @Override + public boolean canApply(ItemStack itemstack, boolean considering) { + if (super.canApply(itemstack, considering)) { + Item item = itemstack.getItem(); + return !(item instanceof ItemArmor) || ((ItemArmor)item).getArmorMaterial() != LOTRMaterial.GALVORN.toArmorMaterial(); + } + return false; + } + + // Redundant because it doesnt work, instead we will be using CinderEventHandler + @Override + protected int calcIntProtection() { + // Implement the logic to calculate protection level + return -(this.protectLevel); + } + + @Override + public boolean isBeneficial() { + // This enchantment is detrimental, so return false + return false; + } +} + + diff --git a/src/main/java/com/zivilon/cinder_loe/mixins/MixinLOTREnchantment.java b/src/main/java/com/zivilon/cinder_loe/mixins/MixinLOTREnchantment.java new file mode 100644 index 0000000..1640e42 --- /dev/null +++ b/src/main/java/com/zivilon/cinder_loe/mixins/MixinLOTREnchantment.java @@ -0,0 +1,41 @@ +package com.zivilon.cinder_loe.mixins; + +import com.zivilon.cinder_loe.enchants.LOTREnchantmentWeakProtectionRanged; +import lotr.common.enchant.LOTREnchantment; +import lotr.common.enchant.LOTREnchantmentDamage; +import lotr.common.enchant.LOTREnchantmentProtectionRanged; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import java.lang.reflect.Field; +import java.util.Map; + +@Mixin(LOTREnchantment.class) +public class MixinLOTREnchantment { + @Inject(method = "", at = @At("TAIL")) + private static void onStaticInit(CallbackInfo ci) { + // Add your new enchantments here + try { + LOTREnchantment protectRangedWeak1 = new LOTREnchantmentWeakProtectionRanged("protectRangedWeak1", 10).setEnchantWeight(0); + LOTREnchantment weak4 = new LOTREnchantmentDamage("weak4", -3.0f).setEnchantWeight(0); + + LOTREnchantment.allEnchantments.add(protectRangedWeak1); + LOTREnchantment.allEnchantments.add(weak4); + + Field enchantsByNameField = LOTREnchantment.class.getDeclaredField("enchantsByName"); + enchantsByNameField.setAccessible(true); + @SuppressWarnings("unchecked") + Map enchantsByName = (Map) enchantsByNameField.get(null); + + enchantsByName.put(protectRangedWeak1.enchantName, protectRangedWeak1); + enchantsByName.put(weak4.enchantName, weak4); + + } catch (NoSuchFieldException | IllegalAccessException e) { + e.printStackTrace(); + } + } + +} + diff --git a/src/main/java/com/zivilon/cinder_loe/mixins/overrides/MixinLOTRHiredNPCInfo.java b/src/main/java/com/zivilon/cinder_loe/mixins/overrides/MixinLOTRHiredNPCInfo.java new file mode 100644 index 0000000..94ab98f --- /dev/null +++ b/src/main/java/com/zivilon/cinder_loe/mixins/overrides/MixinLOTRHiredNPCInfo.java @@ -0,0 +1,95 @@ +package com.zivilon.cinder_loe.mixins.overrides; + +import lotr.common.entity.npc.LOTREntityNPC; +import lotr.common.entity.npc.LOTRHiredNPCInfo; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.SharedMonsterAttributes; +import net.minecraft.entity.ai.attributes.IAttributeInstance; +import net.minecraft.entity.item.EntityFireworkRocket; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.init.Items; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTBase; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; +import net.minecraft.util.ChatComponentTranslation; +import net.minecraft.util.IChatComponent; +import net.minecraft.world.World; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Overwrite; +import org.spongepowered.asm.mixin.Shadow; + +import java.util.UUID; + +@Mixin(LOTRHiredNPCInfo.class) +public class MixinLOTRHiredNPCInfo { + @Shadow + private LOTREntityNPC theEntity; + @Shadow + private UUID hiringPlayerUUID; + @Shadow + public int xpLevel = 1; + + @Overwrite(remap = false) + private void onLevelUp() { + EntityPlayer hirer; + if (this.theEntity.getMaxHealth() >= 60) { + this.addLevelUpHealthGain((EntityLivingBase) this.theEntity); + } + Entity mount = this.theEntity.ridingEntity; + if (mount instanceof EntityLivingBase && !(mount instanceof LOTREntityNPC)) { + this.addLevelUpHealthGain((EntityLivingBase)mount); + } + if ((hirer = this.getHiringPlayer()) != null) { + hirer.addChatMessage((IChatComponent)new ChatComponentTranslation("lotr.hiredNPC.levelUp", new Object[]{this.theEntity.getCommandSenderName(), this.xpLevel})); + } + this.spawnLevelUpFireworks(); + } + + @Overwrite(remap = false) + private void addLevelUpHealthGain(EntityLivingBase gainingEntity) { + float healthBoost = 1.0f; + IAttributeInstance attrHealth = gainingEntity.getEntityAttribute(SharedMonsterAttributes.maxHealth); + attrHealth.setBaseValue(attrHealth.getBaseValue() + (double)healthBoost); + gainingEntity.heal(healthBoost); + } + + @Overwrite(remap = false) + public EntityPlayer getHiringPlayer() { + if (this.hiringPlayerUUID == null) { + return null; + } + return this.theEntity.worldObj.func_152378_a(this.hiringPlayerUUID); + } + + private void spawnLevelUpFireworks() { + boolean bigLvlUp = this.xpLevel % 5 == 0; + World world = this.theEntity.worldObj; + ItemStack itemstack = new ItemStack(Items.fireworks); + NBTTagCompound itemData = new NBTTagCompound(); + NBTTagCompound fireworkData = new NBTTagCompound(); + NBTTagList explosionsList = new NBTTagList(); + int explosions = 1; + for (int l = 0; l < explosions; ++l) { + NBTTagCompound explosionData = new NBTTagCompound(); + explosionData.setBoolean("Flicker", true); + explosionData.setBoolean("Trail", bigLvlUp); + int[] colors = new int[]{0xFF5500, this.theEntity.getFaction().getFactionColor()}; + explosionData.setIntArray("Colors", colors); + boolean effectType = bigLvlUp; + explosionData.setByte("Type", (byte)(effectType ? 1 : 0)); + explosionsList.appendTag((NBTBase)explosionData); + } + fireworkData.setTag("Explosions", (NBTBase)explosionsList); + itemData.setTag("Fireworks", (NBTBase)fireworkData); + itemstack.setTagCompound(itemData); + EntityFireworkRocket firework = new EntityFireworkRocket(world, this.theEntity.posX, this.theEntity.boundingBox.minY + (double)this.theEntity.height, this.theEntity.posZ, itemstack); + NBTTagCompound fireworkNBT = new NBTTagCompound(); + firework.writeEntityToNBT(fireworkNBT); + fireworkNBT.setInteger("LifeTime", bigLvlUp ? 20 : 15); + firework.readEntityFromNBT(fireworkNBT); + world.spawnEntityInWorld((Entity)firework); + } + +} diff --git a/src/main/java/com/zivilon/cinder_loe/mixins/overrides/MixinLOTRReplacedMethods.java b/src/main/java/com/zivilon/cinder_loe/mixins/overrides/MixinLOTRReplacedMethods.java new file mode 100644 index 0000000..772d827 --- /dev/null +++ b/src/main/java/com/zivilon/cinder_loe/mixins/overrides/MixinLOTRReplacedMethods.java @@ -0,0 +1,25 @@ +package com.zivilon.cinder_loe.mixins.overrides; + +import lotr.common.coremod.LOTRReplacedMethods; +import lotr.common.enchant.LOTREnchantmentHelper; +import net.minecraft.item.ItemStack; +import net.minecraft.util.DamageSource; +import net.minecraft.util.MathHelper; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Overwrite; + +@Mixin(LOTRReplacedMethods.Enchants.class) +public class MixinLOTRReplacedMethods { + + /** + * @author Keylime + * @reason because Mixins complains + */ + @Overwrite(remap = false) + public static int getSpecialArmorProtection(int base, ItemStack[] armor, DamageSource source) { + int i = base; + i += LOTREnchantmentHelper.calcSpecialArmorSetProtection(armor, source); + //i = MathHelper.clamp_int(i, -25, 25); + return i; + } +} diff --git a/src/main/resources/assets/cinder_loe/lang/en_US.lang b/src/main/resources/assets/cinder_loe/lang/en_US.lang index 2f8da6d..f87a009 100644 --- a/src/main/resources/assets/cinder_loe/lang/en_US.lang +++ b/src/main/resources/assets/cinder_loe/lang/en_US.lang @@ -213,3 +213,8 @@ lotr.unit.Bree_Horse=Bree-land Outrider entity.cinder_loe.LOTREntitySauron.name=Sauron entity.cinder_loe.UtumnoSlaveTrader.bound.name=Slave Mule entity.cinder_loe.UtumnoSlaveTrader.name=Freed Utumno Trader + +lotr.enchant.protectWeak1=Dented +lotr.enchant.protectWeak2=Defective +lotr.enchant.protectRangedWeak1=Pierced +lotr.enchant.weak4=Bent \ No newline at end of file diff --git a/src/main/resources/mixins.cinder_loe.json b/src/main/resources/mixins.cinder_loe.json index c33d57e..c142dce 100644 --- a/src/main/resources/mixins.cinder_loe.json +++ b/src/main/resources/mixins.cinder_loe.json @@ -7,6 +7,9 @@ "compatibilityLevel": "JAVA_8", "mixins": [ "MixinItemRenderer", + "overrides.MixinLOTRReplacedMethods", + "overrides.MixinLOTRHiredNPCInfo", + "MixinLOTREnchantment", "MixinLOTRArmorModels", "MixinLOTRClientProxy", "MixinLOTRContainerAnvil",