Skip to content

Instantly share code, notes, and snippets.

@joeyemery
Created August 21, 2017 10:44
Show Gist options
  • Save joeyemery/9c4ca0bcc2f8cd9666734ad22705d91e to your computer and use it in GitHub Desktop.
Save joeyemery/9c4ca0bcc2f8cd9666734ad22705d91e to your computer and use it in GitHub Desktop.
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