package com.zivilon.cinder_loe; import com.zivilon.cinder_loe.entity.corrupt.CorruptMan; import com.zivilon.cinder_loe.items.BrokenHalo; import cpw.mods.fml.common.FMLCommonHandler; import cpw.mods.fml.common.IFuelHandler; import cpw.mods.fml.common.eventhandler.EventPriority; 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 lotr.common.item.*; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.DataWatcher; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.item.*; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; import net.minecraft.nbt.NBTTagString; import net.minecraft.network.Packet; import net.minecraft.network.play.server.S04PacketEntityEquipment; import net.minecraft.network.play.server.S09PacketHeldItemChange; import net.minecraft.network.play.server.S1CPacketEntityMetadata; import net.minecraft.network.play.server.S19PacketEntityStatus; import net.minecraft.potion.Potion; import net.minecraft.potion.PotionEffect; import net.minecraft.util.ChatComponentText; import net.minecraft.util.DamageSource; import net.minecraft.util.EnumChatFormatting; import net.minecraft.world.World; import net.minecraft.world.WorldServer; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.event.entity.living.LivingAttackEvent; import net.minecraftforge.event.entity.living.LivingHurtEvent; import net.minecraftforge.event.entity.player.ArrowLooseEvent; import java.util.Random; public class CinderEventHandler implements IFuelHandler { private static final Random random = new Random(); public CinderEventHandler() { FMLCommonHandler.instance().bus().register(this); MinecraftForge.EVENT_BUS.register(this); MinecraftForge.TERRAIN_GEN_BUS.register(this); GameRegistry.registerFuelHandler(this); } @SubscribeEvent public void onArrowLoose(ArrowLooseEvent event) { Entity attacker = event.entityLiving; if (attacker instanceof EntityPlayerMP player) { ItemStack bow = player.getHeldItem(); if (bow != null && bow.isItemStackDamageable() && (bow.getItem() instanceof LOTRItemBow || bow.getItem() instanceof ItemBow)) { float[] durabilityThresholds = {0.5f, 0.4f, 0.25f}; double[] probabilities = {0.0005, 0.001, 0.005}; // Corrected probabilities // Corrected durabilityPercent calculation float durabilityPercent = (float) (bow.getMaxDamage() - bow.getItemDamage()) / bow.getMaxDamage(); for (int j = 0; j < durabilityThresholds.length; j++) { if (durabilityPercent <= durabilityThresholds[j] && random.nextDouble() <= probabilities[j]) { addNegativeModifier(bow, player, "bow"); break; // Exit loop once a modifier is added } } } } } @SubscribeEvent public void onLivingAttack(LivingAttackEvent event) { Entity attacker = event.source.getEntity(); if (attacker instanceof EntityPlayerMP player) { ItemStack weapon = player.getHeldItem(); // smithing rework for melee if (weapon != null && (weapon.getItem() instanceof LOTRItemSpear || weapon.getItem() instanceof LOTRItemSword || weapon.getItem() instanceof LOTRItemDagger || weapon.getItem() instanceof LOTRItemBattleaxe || weapon.getItem() instanceof LOTRItemHammer || weapon.getItem() instanceof ItemSword)) { float[] durabilityThresholds = {0.5f, 0.4f, 0.25f}; double[] probabilities = {0.0005, 0.001, 0.005}; // Corrected probabilities if (weapon.isItemStackDamageable()) { // Corrected durabilityPercent calculation float durabilityPercent = (float) (weapon.getMaxDamage() - weapon.getItemDamage()) / weapon.getMaxDamage(); for (int j = 0; j < durabilityThresholds.length; j++) { if (durabilityPercent <= durabilityThresholds[j] && random.nextDouble() <= probabilities[j]) { addNegativeModifier(weapon, player, "weapon"); break; // Exit loop once a modifier is added } } } } } } @SubscribeEvent public void onLivingHurt(LivingHurtEvent event) { if (event.entityLiving == null || event.source.getEntity() == null) { return; } EntityLivingBase entity = event.entityLiving; EntityLivingBase attacker = event.source.getEntity() instanceof EntityLivingBase ? (EntityLivingBase) event.source.getEntity() : null; World world = entity.worldObj; DamageSource source = event.source; /* Blocking event handler removed and replaced with one in DamageEvent class. Temporarily stored for backup reasons. if (event.entity instanceof EntityPlayer && !source.isUnblockable()) { EntityPlayerMP player = (EntityPlayerMP) event.entity; ItemStack sword = player.getHeldItem(); float playerYaw = player.getRotationYawHead(); float attackerYaw = attacker.getRotationYawHead(); // Normalize both angles to be within 0 - 360 playerYaw = (playerYaw + 360) % 360; attackerYaw = (attackerYaw + 360) % 360; // Calculate the angle difference float angleDifference = Math.abs(playerYaw - attackerYaw); if (angleDifference > 180) { angleDifference = 360 - angleDifference; } ItemStack weapon = attacker.getHeldItem(); if (weapon != null) { if (player.isBlocking() && angleDifference >= 135 && angleDifference <=225) { float additionalDamage = 0.0f; if (weapon.getItem() instanceof ItemAxe || weapon.getItem() instanceof LOTRItemAxe || weapon.getItem() instanceof LOTRItemBattleaxe) { sword.damageItem((int) (event.ammount *1.5), player); // Axes deal 150% the Durability damage player.clearItemInUse(); world.playSoundAtEntity(player, "random.anvil_land", 1F, 2F); additionalDamage = 0.75f; // Only 25% Passes through } else if (weapon.getItem() instanceof LOTRItemHammer) { sword.damageItem((int) event.ammount, player); // Hammers bypass the block better, but only deal 100% of the durability damage player.clearItemInUse(); world.playSoundAtEntity(player, "random.anvil_land", 1F, 2F); additionalDamage = 0.5f; // Only 50% Passes through } else { additionalDamage = 0.0f; // 0% Damage Passes through sword.damageItem((int) (event.ammount/2), player); //Swords only deal 50% of durability damage player.clearItemInUse(); world.playSoundAtEntity(player, "random.anvil_land", 1F, 2F); } float newDamage = event.ammount * (additionalDamage); // Calculate new damage float newHealth = player.getHealth() - (newDamage - event.ammount); // Calculate health after applying extra damage if (newHealth > 0) { player.setHealth(newHealth); event.setCanceled(true); } else { event.ammount = player.getHealth(); // Ensure player dies if health reaches 0 or below } } } } */ // Negative Arrow Protection Handler if (!event.entityLiving.worldObj.isRemote && event.source.isProjectile() && event.entityLiving instanceof EntityPlayerMP player) { // player.addChatMessage(new ChatComponentText(EnumChatFormatting.RED + "DEBUG: Initial Damage: " + event.ammount)); float totalAdditionalDamage = 0.0f; // Initialize total additional damage for (int i = 0; i < 4; i++) { ItemStack armor = player.getEquipmentInSlot(i + 1); if (armor != null) { LOTREnchantment protectRangedWeak1 = LOTREnchantment.getEnchantmentByName("protectRangedWeak1"); LOTREnchantment protectRangedWeak2 = LOTREnchantment.getEnchantmentByName("protectRangedWeak2"); if (LOTREnchantmentHelper.hasEnchant(armor, protectRangedWeak1)) { float additionalDamage = 0.2f; // 20% more damage per piece totalAdditionalDamage += additionalDamage; // Accumulate damage increase } if (LOTREnchantmentHelper.hasEnchant(armor, protectRangedWeak2)) { float additionalDamage = 0.4f; // 40% more damage per piece totalAdditionalDamage += additionalDamage; // Accumulate damage increase } } } // Apply total additional damage if (totalAdditionalDamage > 0) { float newDamage = event.ammount * (1 + totalAdditionalDamage); // Calculate new damage float newHealth = player.getHealth() - (newDamage - event.ammount); // Calculate health after applying extra damage if (newHealth > 0) { player.setHealth(newHealth); event.setCanceled(true); } else { event.ammount = player.getHealth(); // Ensure player dies if health reaches 0 or below } // player.addChatMessage(new ChatComponentText(EnumChatFormatting.RED + "DEBUG: Total Additional Damage: " + newDamage)); } } // 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) { // Summon Corrupt Civilian NPC CorruptMan spawnedEntity = new CorruptMan(world); spawnedEntity.copyLocationAndAnglesFrom(attacker); // Randomly select main weapon ItemStack mainWeapon = getRandomWeapon(); spawnedEntity.npcItemsInv.setIdleItem(mainWeapon); spawnedEntity.npcItemsInv.setMeleeWeapon(mainWeapon); spawnedEntity.setHealth(10); spawnedEntity.addPotionEffect(new PotionEffect(Potion.regeneration.id, 9999, 0)); spawnedEntity.onSpawnWithEgg(null); world.spawnEntityInWorld(spawnedEntity); world.playAuxSFXAtEntity(null, 1016, (int) spawnedEntity.posX, (int) spawnedEntity.posY, (int) spawnedEntity.posZ, 0); world.playSoundAtEntity(entity, "mob.zombie.unfect", 1F, 1F); } } } // Smithing Rework event handler if (attacker instanceof EntityPlayerMP player) { ItemStack weapon = player.getHeldItem(); // smithing rework for melee if (weapon !=null && (weapon.getItem() instanceof LOTRItemSpear || weapon.getItem() instanceof LOTRItemSword || weapon.getItem() instanceof LOTRItemDagger || weapon.getItem() instanceof LOTRItemBattleaxe || weapon.getItem() instanceof LOTRItemHammer || weapon.getItem() instanceof ItemSword)) { float[] durabilityThresholds = {0.6f, 0.5f, 0.4f}; double[] probabilities = {0.02, 0.05, 0.1}; if (weapon.isItemStackDamageable()) { float durabilityPercent = (float) (weapon.getMaxDamage() - weapon.getItemDamage() / weapon.getMaxDamage()); for (int j = 0; j < durabilityThresholds.length; j++) { if (durabilityPercent <= durabilityThresholds[j] && random.nextDouble() <= probabilities[j]) { addNegativeModifier(weapon, player, "weapon"); break; // Exit loop once a modifier is added } } } } } if (entity instanceof EntityPlayerMP player) { // Durability thresholds and corresponding probabilities for adding a negative modifier float[] durabilityThresholds = {0.6f, 0.5f, 0.4f}; double[] probabilities = {0.02, 0.05, 0.1}; for (int i = 0; i < 4; ++i) { ItemStack armor = player.getEquipmentInSlot(i + 1); if (armor != null && armor.isItemStackDamageable()) { float durabilityPercent = (float) (armor.getMaxDamage() - armor.getItemDamage()) / armor.getMaxDamage(); // Check each threshold and apply negative modifier if conditions are met for (int j = 0; j < durabilityThresholds.length; j++) { if (durabilityPercent <= durabilityThresholds[j] && random.nextDouble() <= probabilities[j]) { addNegativeModifier(armor, player, "armor"); break; // Exit loop once a modifier is added } } } } } } private void sendNegativeModifierMessage(EntityPlayerMP player, String type) { player.addChatMessage(new ChatComponentText( EnumChatFormatting.RED + "Your " + EnumChatFormatting.GOLD + type + EnumChatFormatting.RED + " 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 item, EntityPlayerMP player, String type) { NBTTagCompound tag = item.getTagCompound(); if (tag == null) { tag = new NBTTagCompound(); item.setTagCompound(tag); } if (!tag.hasKey("LOTREnch")) { tag.setTag("LOTREnch", new NBTTagList()); } NBTTagList enchList = tag.getTagList("LOTREnch", 8); // 8 is the type for strings boolean protectWeakUpgraded = false; boolean protectRangedWeakUpgraded = false; boolean upgraded = false; boolean meleeSwift = false; boolean meleeReach = false; if (type.equals("armor")) { // First, iterate and upgrade if necessary for (int i = 0; i < enchList.tagCount(); i++) { String ench = enchList.getStringTagAt(i); switch (ench) { case "protectWeak1" -> { enchList.removeTag(i); enchList.appendTag(new NBTTagString("protectWeak2")); protectWeakUpgraded = true; i--; // Adjust index after removal playNegativeModifierSound(player.worldObj, player.posX, player.posY, player.posZ); sendNegativeModifierMessage(player, "Armor"); } case "protectRangedWeak1" -> { enchList.removeTag(i); enchList.appendTag(new NBTTagString("protectRangedWeak2")); protectRangedWeakUpgraded = true; i--; // Adjust index after removal playNegativeModifierSound(player.worldObj, player.posX, player.posY, player.posZ); sendNegativeModifierMessage(player, "Armor"); } case "protectWeak2" -> protectWeakUpgraded = true; case "protectRangedWeak2" -> protectRangedWeakUpgraded = true; } } // After upgrading, check if we need to add a new modifier if (!protectWeakUpgraded || !protectRangedWeakUpgraded) { // Separate conditions for adding new modifiers if (!protectWeakUpgraded && !protectRangedWeakUpgraded) { // Randomly add either protectWeak1 or protectRangedWeak1 String[] possibleModifiers = {"protectWeak1", "protectRangedWeak1"}; String newModifier = possibleModifiers[random.nextInt(possibleModifiers.length)]; enchList.appendTag(new NBTTagString(newModifier)); } else if (!protectWeakUpgraded) { // Only protectWeak1 is added enchList.appendTag(new NBTTagString("protectWeak1")); } else if (!protectRangedWeakUpgraded) { // Only protectRangedWeak1 is added enchList.appendTag(new NBTTagString("protectRangedWeak1")); } playNegativeModifierSound(player.worldObj, player.posX, player.posY, player.posZ); sendNegativeModifierMessage(player, "Armor"); } tag.setTag("LOTREnch", enchList); } else if (type.equals("bow")) { for (int i = 0; i < enchList.tagCount(); i++) { String ench = enchList.getStringTagAt(i); switch (ench) { case "rangedWeak1" -> { enchList.removeTag(i); enchList.appendTag(new NBTTagString("rangedWeak2")); upgraded = true; i--; // Adjust index after removal playNegativeModifierSound(player.worldObj, player.posX, player.posY, player.posZ); sendNegativeModifierMessage(player, "Bow"); } case "rangedWeak2" -> { enchList.removeTag(i); enchList.appendTag(new NBTTagString("rangedWeak3")); upgraded = true; i--; // Adjust index after removal playNegativeModifierSound(player.worldObj, player.posX, player.posY, player.posZ); sendNegativeModifierMessage(player, "Bow"); } case "rangedWeak3" -> upgraded = true; } } if (!upgraded) { // Randomly add either rangedWeak1... etc String[] possibleModifiers = {"rangedWeak1", "rangedWeak2", "rangedWeak3"}; String newModifier = possibleModifiers[random.nextInt(possibleModifiers.length)]; enchList.appendTag(new NBTTagString(newModifier)); playNegativeModifierSound(player.worldObj, player.posX, player.posY, player.posZ); sendNegativeModifierMessage(player, "Weapon"); } } else if (type.equals("weapon")) { // First, iterate and upgrade if necessary for (int i = 0; i < enchList.tagCount(); i++) { String ench = enchList.getStringTagAt(i); switch (ench) { case "weak1" -> { enchList.removeTag(i); enchList.appendTag(new NBTTagString("weak2")); upgraded = true; i--; // Adjust index after removal playNegativeModifierSound(player.worldObj, player.posX, player.posY, player.posZ); sendNegativeModifierMessage(player, "Weapon"); } case "weak3" -> { enchList.removeTag(i); enchList.appendTag(new NBTTagString("weak4")); upgraded = true; i--; // Adjust index after removal playNegativeModifierSound(player.worldObj, player.posX, player.posY, player.posZ); sendNegativeModifierMessage(player, "Weapon"); } case "weak4" -> upgraded = true; case "meleeSlow1" -> meleeSwift = true; case "meleeUnreach1" -> meleeReach = true; } } // After upgrading, check if we need to add a new modifier if (!upgraded || !meleeSwift || !meleeReach) { // Separate conditions for adding new modifiers if (!upgraded && !meleeSwift && !meleeReach) { // Randomly add one of the possible modifiers String[] possibleModifiers = {"weak1", "weak2", "weak3", "weak4", "meleeSlow1", "meleeUnreach1"}; String newModifier = possibleModifiers[random.nextInt(possibleModifiers.length)]; enchList.appendTag(new NBTTagString(newModifier)); } else if (!upgraded) { // Only weak modifier is added String[] weakModifiers = {"weak1", "weak2", "weak3", "weak4"}; String newModifier = weakModifiers[random.nextInt(weakModifiers.length)]; enchList.appendTag(new NBTTagString(newModifier)); } else if (!meleeSwift) { // Only meleeSlow1 is added enchList.appendTag(new NBTTagString("meleeSlow1")); } else if (!meleeReach) { // Only meleeUnreach1 is added enchList.appendTag(new NBTTagString("meleeUnreach1")); } playNegativeModifierSound(player.worldObj, player.posX, player.posY, player.posZ); sendNegativeModifierMessage(player, "Weapon"); } 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)]); } @Override public int getBurnTime(ItemStack fuel) { return 0; } }