Created
August 21, 2017 10:44
-
-
Save joeyemery/9c4ca0bcc2f8cd9666734ad22705d91e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.curiouslyodd.mineclash.events; | |
import java.util.List; | |
import java.util.Set; | |
import com.curiouslyodd.mineclash.items.ItemMiscBloodDiamond; | |
import net.minecraft.enchantment.Enchantment; | |
import net.minecraft.entity.Entity; | |
import net.minecraft.entity.item.EntityItem; | |
import net.minecraft.entity.monster.EntityZombie; | |
import net.minecraft.entity.player.EntityPlayer; | |
import net.minecraft.init.Enchantments; | |
import net.minecraft.init.Items; | |
import net.minecraft.init.MobEffects; | |
import net.minecraft.item.ItemStack; | |
import net.minecraft.item.ItemSword; | |
import net.minecraft.nbt.NBTTagCompound; | |
import net.minecraft.nbt.NBTTagList; | |
import net.minecraft.potion.PotionEffect; | |
import net.minecraft.util.DamageSource; | |
import net.minecraft.util.EnumHand; | |
import net.minecraft.util.text.TextComponentTranslation; | |
import net.minecraftforge.event.entity.living.LivingDropsEvent; | |
import net.minecraftforge.event.entity.living.LivingEntityUseItemEvent; | |
import net.minecraftforge.event.entity.living.LivingHurtEvent; | |
import net.minecraftforge.event.entity.player.AttackEntityEvent; | |
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; | |
public class CommonEventHandler { | |
public long actionStarted = -1; | |
public ItemStack actionItem = null; | |
public int currentSwordSouls = 0; | |
/** | |
* useItemStart | |
* Stores a timestamp and the used item publically against our class. | |
*/ | |
@SubscribeEvent | |
public void useItemStart(LivingEntityUseItemEvent.Start e) { | |
if(e.getEntity() instanceof EntityPlayer) { | |
// Get the current item and time in milliseconds to compare later. | |
this.actionStarted = System.currentTimeMillis(); | |
this.actionItem = e.getItem(); | |
} | |
} | |
/** | |
* useItemStop | |
* When an item stops being used the timestamp is set to -1. | |
* | |
*/ | |
@SubscribeEvent | |
public void useItemStop(LivingEntityUseItemEvent.Stop e) { | |
if(e.getEntity() instanceof EntityPlayer) { | |
// Nullify our timestamp (or close enough). | |
this.actionStarted = -1; | |
this.actionItem = null; | |
} | |
} | |
/** | |
* entityDamaged | |
* Used to calculate the time since the player started blocking and taking damage | |
* (in milliseconds). | |
*/ | |
@SubscribeEvent | |
public void entityDamaged(LivingHurtEvent e) { | |
// Get the source of the damage. | |
DamageSource source = e.getSource(); | |
Entity enemy = source.getTrueSource(); | |
// Check if the hurt entity was the player, the damage can be blocked, | |
// that we're definitely blocking in the first place (this is more a sanity check) | |
// and if we've 100% got an item equipped (again, for my sanity). | |
if( | |
e.getEntity() instanceof EntityPlayer | |
&& !source.isUnblockable() | |
&& this.actionStarted != -1 | |
&& this.actionItem != null | |
) { | |
e.getEntity().sendMessage(new TextComponentTranslation("\n" + this.actionItem.getUnlocalizedName() + "\n")); | |
// Get the current player entity so we can apply our potion effects etc. | |
EntityPlayer player = (EntityPlayer) e.getEntity(); | |
// Create 2 new longs to store the current time and the difference between | |
// when we used our actionItem. | |
long current = System.currentTimeMillis(), | |
difference = current - this.actionStarted; | |
// Check the item is a shield and our custom "timed block" threshold. | |
if( | |
this.actionItem.getUnlocalizedName().equals("item.shield") | |
&& difference >= 250 | |
&& difference <= 450 | |
) { | |
// Now we check the damage source to apply different effects. | |
if(source.isProjectile()) { | |
// Add the potion effect (Speed) | |
player.addPotionEffect(new PotionEffect(MobEffects.SPEED, 100)); | |
// Send a chat message as confirmation. | |
player.sendMessage(new TextComponentTranslation("\nPerfect block!\nUse the momentum to rush down your enemy!\n")); | |
} else { | |
// Add the potion effect (Damage) | |
player.addPotionEffect(new PotionEffect(MobEffects.STRENGTH, 40)); | |
// Send a chat message as confirmation. | |
player.sendMessage(new TextComponentTranslation("\nPerfect block!\nQuickly counterstrike for extra damage!\n")); | |
} | |
} | |
// If we've been blocking too long. | |
else if( | |
difference >= 1200 | |
&& this.actionItem.getUnlocalizedName().equals("item.shield") | |
) { | |
// Check if they're a Zombie and get disarmed. | |
if(enemy != null && enemy instanceof EntityZombie) { | |
// Send a message to notify the player of what's going on. | |
player.sendMessage(new TextComponentTranslation("\nAwful block!\nThe Zombie took the bloody shield off you!\n")); | |
// Create a new shield ItemStack and give it to the Zombie. | |
((EntityZombie) enemy).setHeldItem(EnumHand.OFF_HAND, this.actionItem); | |
// Add a tag to flag the Zombie has a shield to drop on death. | |
enemy.addTag("has_shield"); | |
// Set the players off hand to "air". | |
ItemStack airStack = new ItemStack(Items.AIR); | |
player.setHeldItem(EnumHand.OFF_HAND, airStack); | |
// We also need to set the actionStarted to false so it invalidates further | |
// checks for if we're blocking (which we clearly aren't anymore :p) | |
this.actionStarted = -1; | |
} | |
} | |
} | |
// The player was damaged with no shield active. | |
else if( | |
e.getEntity() instanceof EntityPlayer | |
&& this.actionItem != null | |
&& !this.actionItem.getUnlocalizedName().equals("item.shield") | |
) { | |
System.out.print("Reset bloodsouls\n"); | |
} | |
} | |
/** | |
* entityDrops | |
* Here we change the drops for certain mobs (primarily to undo things we did before | |
* like disarming). | |
*/ | |
@SubscribeEvent | |
public void entityDrops(LivingDropsEvent e) { | |
Entity entity = e.getEntity(); | |
// Check if its a Zombie. | |
if(entity instanceof EntityZombie) { | |
Set<String> tags = entity.getTags(); | |
// Get the Zombie's drops. | |
List<EntityItem> drops = e.getDrops(); | |
// Get the source of the damage. | |
Entity damageSource = e.getSource().getTrueSource(); | |
// Check if it was the player. | |
if(e.getSource().getTrueSource() instanceof EntityPlayer) { | |
Iterable<ItemStack> heldItems = damageSource.getHeldEquipment(); | |
// Loop through the players currently equipped items to find the sword. | |
for(ItemStack heldItem : heldItems) { | |
if(heldItem.getUnlocalizedName().equals("item.mineclash.sword_bloodlust")) { | |
NBTTagCompound weaponNbt = (heldItem.hasTagCompound()) ? heldItem.getTagCompound() : new NBTTagCompound(); | |
// If we've got counted hits and they're greater than 5. | |
if( | |
weaponNbt.hasKey("entity_hits") | |
&& weaponNbt.getInteger("entity_hits") >= 5 | |
) { | |
ItemMiscBloodDiamond bloodDiamond = new ItemMiscBloodDiamond(); | |
//EntityItem bloodDiamondEntity = new EntityItem(entity.world, entity.posX, entity.posY, entity.posZ, bloodDiamondStack); | |
//drops.add(bloodDiamondEntity); | |
} | |
} | |
} | |
} | |
// See if it has our "has_shield" flag. | |
if(tags.contains("has_shield")) { | |
// New ItemStack and EntityItem for our shield. | |
EntityItem playerShieldEntity = new EntityItem(entity.world, entity.posX, entity.posY, entity.posZ, ((EntityZombie) entity).getHeldItemOffhand()); | |
// Remove and then re-add the EntityItem to our drops (Sometimes the Zombie will drop the shield already | |
// by default, this overrides this behaviour entirely. | |
drops.remove(playerShieldEntity); | |
drops.add(playerShieldEntity); | |
} | |
} | |
} | |
/** | |
* playerAttack | |
* Deals with any action relating to the player attacking, mostly our evolving weapons stuff. | |
*/ | |
@SubscribeEvent | |
public void playerAttack(AttackEntityEvent e) { | |
// Get the player and the enemy. | |
EntityPlayer player = e.getEntityPlayer(); | |
Entity enemy = e.getTarget(); | |
// Get the players held weapon. | |
ItemStack playerWeapon = player.getHeldItemMainhand(); | |
// If the player is using a sword. | |
if(playerWeapon.getItem() instanceof ItemSword) { | |
// Get or create an NBT for the current weapon. | |
NBTTagCompound weaponNbt = (playerWeapon.hasTagCompound()) ? playerWeapon.getTagCompound() : new NBTTagCompound(); | |
// Set the default level. | |
if(!weaponNbt.hasKey("bloodsouls_level")) | |
weaponNbt.setInteger("bloodsouls_level", 0); | |
// Set the default threshold. | |
if(!weaponNbt.hasKey("bloodsouls_threshold")) | |
weaponNbt.setInteger("bloodsouls_threshold", 5); | |
// Increment the weapons bloodsouls or start it at 1. | |
weaponNbt.setInteger("bloodsouls", | |
(weaponNbt.hasKey("bloodsouls") ? weaponNbt.getInteger("bloodsouls") + 1 : 1) | |
); | |
// If we've hit our current threshold increment the level. | |
if(weaponNbt.getInteger("bloodsouls") == weaponNbt.getInteger("bloodsouls_threshold")) { | |
weaponNbt.setInteger("bloodsouls_level", weaponNbt.getInteger("bloodsouls_level") + 1); | |
} | |
//player.sendMessage(new TextComponentTranslation("Souls: " + weaponNbt.getInteger("bloodsouls") + "\n")); | |
//player.sendMessage(new TextComponentTranslation("Level: " + weaponNbt.getInteger("bloodsouls_level") + "\n")); | |
//player.sendMessage(new TextComponentTranslation("Threshold: " + weaponNbt.getInteger("bloodsouls_threshold") + "\n")); | |
// Apply the changes. | |
playerWeapon.setTagCompound(weaponNbt); | |
// Get the enchant_id for the enchantment we want (instead of hardcoded IDs) | |
// and a NBTTagList of the current enchantments on the active weapon. | |
int enchant_id = Enchantment.getEnchantmentID(Enchantments.SHARPNESS); | |
NBTTagList enchantments = playerWeapon.getEnchantmentTagList(); | |
// Bool to store if we have the enchant or not. | |
boolean hasEnchantment = false; | |
int enchantmentIndex = 0; | |
// Loop through this list (in the worst way possible to determine | |
// if the enchantment has already been applied. | |
for (int i = 0; i < enchantments.tagCount(); i++) { | |
System.out.print(enchantments.getCompoundTagAt(i).getInteger("lvl")); | |
if( | |
enchantments.getCompoundTagAt(i).getInteger("id") == enchant_id | |
&& enchantments.getCompoundTagAt(i).getInteger("lvl") == weaponNbt.getInteger("bloodsouls_level") | |
) { | |
hasEnchantment = true; | |
enchantmentIndex = i; | |
} | |
} | |
// If the soul count hits certain thresholds, enchant it. | |
if( | |
!hasEnchantment | |
&& weaponNbt.getInteger("bloodsouls") == weaponNbt.getInteger("bloodsouls_threshold") | |
) { | |
// Remove the previous enchantment. | |
if(enchantmentIndex > 0) { | |
enchantments.removeTag(enchantmentIndex); | |
} | |
// Add the enchantment | |
playerWeapon.addEnchantment(Enchantments.SHARPNESS, weaponNbt.getInteger("bloodsouls_level")); | |
// Increase our threshold and reset our bloodsouls. | |
weaponNbt.setInteger("bloodsouls_threshold", weaponNbt.getInteger("bloodsouls_threshold") * 2); | |
weaponNbt.setInteger("bloodsouls", 0); | |
playerWeapon.setTagCompound(weaponNbt); | |
// Client only we send a message. | |
if(player.world.isRemote) { | |
player.sendMessage(new TextComponentTranslation("The bloodlust has driven your Sword to evolve...\n")); | |
} | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment