/**
Copyright (C) <2017> <coolAlias>
This file is part of coolAlias' Zelda Sword Skills Minecraft Mod; as such,
you can redistribute it and/or modify it under the terms of the GNU
General Public License as published by the Free Software Foundation,
either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package zeldaswordskills.handler;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.EnumCreatureAttribute;
import net.minecraft.entity.INpc;
import net.minecraft.entity.boss.EntityWither;
import net.minecraft.entity.monster.EntityGolem;
import net.minecraft.entity.monster.EntityWitch;
import net.minecraft.entity.passive.EntityCow;
import net.minecraft.entity.passive.EntityVillager;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.init.Items;
import net.minecraft.item.ItemStack;
import net.minecraftforge.event.entity.EntityEvent.EntityConstructing;
import net.minecraftforge.event.entity.EntityJoinWorldEvent;
import net.minecraftforge.event.entity.living.LivingEvent.LivingJumpEvent;
import net.minecraftforge.event.entity.living.LivingEvent.LivingUpdateEvent;
import net.minecraftforge.event.entity.living.LivingFallEvent;
import net.minecraftforge.event.entity.player.EntityInteractEvent;
import net.minecraftforge.event.entity.player.PlayerEvent;
import net.minecraftforge.event.entity.player.PlayerFlyableFallEvent;
import net.minecraftforge.fml.common.eventhandler.Event.Result;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.common.gameevent.PlayerEvent.PlayerLoggedInEvent;
import zeldaswordskills.api.entity.NpcHelper;
import zeldaswordskills.api.item.ArmorIndex;
import zeldaswordskills.api.item.IRightClickEntity;
import zeldaswordskills.entity.ZSSEntityInfo;
import zeldaswordskills.entity.ZSSVillagerInfo;
import zeldaswordskills.entity.ai.EntityAITeleport;
import zeldaswordskills.entity.ai.IEntityTeleport;
import zeldaswordskills.entity.buff.Buff;
import zeldaswordskills.entity.npc.EntityGoron;
import zeldaswordskills.entity.player.ZSSPlayerInfo;
import zeldaswordskills.entity.player.ZSSPlayerSkills;
import zeldaswordskills.entity.player.ZSSPlayerSongs;
import zeldaswordskills.item.ItemMask;
import zeldaswordskills.item.ZSSItems;
import zeldaswordskills.network.PacketDispatcher;
import zeldaswordskills.network.client.SyncConfigPacket;
import zeldaswordskills.ref.Config;
import zeldaswordskills.skills.SkillBase;
import zeldaswordskills.skills.sword.LeapingBlow;
import zeldaswordskills.util.PlayerUtils;
/**
*
* Event handler for non-combat related entity events
*
*/
public class ZSSEntityEvents
{
/**
* NOTE: LivingFallEvent is not called in Creative mode, so must
* also listen for {@link PlayerFlyableFallEvent}
* Should receive canceled to make sure LeapingBlow triggers/deactivates
*/
@SubscribeEvent(receiveCanceled=true)
public void onFall(LivingFallEvent event) {
if (event.entity instanceof EntityPlayer) {
EntityPlayer player = (EntityPlayer) event.entity;
ZSSPlayerInfo info = ZSSPlayerInfo.get(player);
ZSSPlayerSkills skills = info.getPlayerSkills();
if (skills.isSkillActive(SkillBase.leapingBlow)) {
((LeapingBlow) skills.getPlayerSkill(SkillBase.leapingBlow)).onImpact(player, event.distance);
}
if (!event.isCanceled() && info.reduceFallAmount > 0.0F) {
event.distance -= info.reduceFallAmount;
info.reduceFallAmount = 0.0F;
}
}
}
@SubscribeEvent
public void onCreativeFall(PlayerFlyableFallEvent event) {
ZSSPlayerSkills skills = ZSSPlayerSkills.get(event.entityPlayer);
if (skills.isSkillActive(SkillBase.leapingBlow)) {
((LeapingBlow) skills.getPlayerSkill(SkillBase.leapingBlow)).onImpact(event.entityPlayer, event.distance);
}
}
@SubscribeEvent
public void onJump(LivingJumpEvent event) {
if (event.entityLiving.getHeldItem() != null && event.entityLiving.getHeldItem().getItem() == ZSSItems.rocsFeather) {
event.entityLiving.motionY += (event.entityLiving.isSprinting() ? 0.30D : 0.15D);
}
if (event.entityLiving.getEquipmentInSlot(ArmorIndex.EQUIPPED_BOOTS) != null && event.entityLiving.getEquipmentInSlot(ArmorIndex.EQUIPPED_BOOTS).getItem() == ZSSItems.bootsPegasus) {
event.entityLiving.motionY += 0.15D;
if (event.entity instanceof EntityPlayer) {
ZSSPlayerInfo.get((EntityPlayer) event.entity).reduceFallAmount += 1.0F;
}
}
ItemStack helm = event.entityLiving.getEquipmentInSlot(ArmorIndex.EQUIPPED_HELM);
if (helm != null) {
if (helm.getItem() == ZSSItems.maskBunny) {
event.entityLiving.motionY += 0.30D;
if (event.entity instanceof EntityPlayer) {
ZSSPlayerInfo.get((EntityPlayer) event.entity).reduceFallAmount += 5.0F;
}
} else if (helm.getItem() == ZSSItems.maskDeku) {
event.entityLiving.motionY += 0.30D;
}
}
}
/**
* This event fires on BOTH sides
*/
@SubscribeEvent
public void onInteract(EntityInteractEvent event) {
ItemStack stack = event.entityPlayer.getHeldItem();
if (event.target instanceof EntityVillager && Result.DEFAULT != NpcHelper.convertVillager(event.entityPlayer, (EntityVillager) event.target, true)) {
event.setCanceled(true);
}
// Check if the held item has any special interaction upon right-clicking an entity
if (!event.isCanceled() && stack != null && stack.getItem() instanceof IRightClickEntity) {
event.setCanceled(((IRightClickEntity) stack.getItem()).onRightClickEntity(stack, event.entityPlayer, event.target));
}
// If the event is not yet canceled, check for Mask interactions
if (!event.isCanceled() && event.target instanceof INpc) {
ItemStack helm = event.entityPlayer.getCurrentArmor(ArmorIndex.WORN_HELM);
if (helm != null && helm.getItem() instanceof ItemMask) {
event.setCanceled(((ItemMask) helm.getItem()).onInteract(helm, event.entityPlayer, event.target));
}
}
// Check for Lon Lon Milk cow interaction
if (!event.isCanceled() && stack != null && stack.getItem() == Items.glass_bottle && event.target.getClass() == EntityCow.class) {
event.setCanceled(ZSSPlayerSongs.get(event.entityPlayer).milkLonLonCow(event.entityPlayer, (EntityCow) event.target));
}
// Finally, check for interactions with the Cursed Man
if (!event.isCanceled() && event.target.getClass() == EntityVillager.class && ("Cursed Man").equals(event.target.getCustomNameTag())) {
EntityVillager villager = (EntityVillager) event.target;
if (stack == null || (stack.getItem() != ZSSItems.skulltulaToken && stack.getItem() != Items.name_tag)) {
int tokens = ZSSPlayerInfo.get(event.entityPlayer).getSkulltulaTokens();
if (villager.worldObj.isRemote) {
// don't send chat - will be sent from server
} else if (villager.isChild()) {
PlayerUtils.sendTranslatedChat(event.entityPlayer, "chat.zss.npc.cursed_man.child");
} else if (tokens > 0) {
PlayerUtils.sendTranslatedChat(event.entityPlayer, "chat.zss.npc.cursed_man.amount", tokens);
} else {
PlayerUtils.sendTranslatedChat(event.entityPlayer, "chat.zss.npc.cursed_man." + event.entity.worldObj.rand.nextInt(4));
}
event.setCanceled(true);
}
}
}
@SubscribeEvent
public void onLivingUpdate(LivingUpdateEvent event) {
if (event.entity instanceof EntityPlayer) {
EntityPlayer player = (EntityPlayer) event.entity;
ZSSPlayerInfo.get(player).onUpdate();
if (player.motionY < -0.25D) {
boolean flag = player.getHeldItem() != null && player.getHeldItem().getItem() == ZSSItems.rocsFeather;
if (flag || (player.getCurrentArmor(ArmorIndex.WORN_HELM) != null && player.getCurrentArmor(ArmorIndex.WORN_HELM).getItem() == ZSSItems.maskDeku)) {
player.motionY = -0.25D;
player.fallDistance = 0.0F;
}
}
}
if (event.entity instanceof EntityLivingBase) {
ZSSEntityInfo.get((EntityLivingBase) event.entity).onUpdate();
}
if (event.entity instanceof EntityVillager) {
ZSSVillagerInfo.get((EntityVillager) event.entity).onUpdate();
}
}
@SubscribeEvent
public void onClonePlayer(PlayerEvent.Clone event) {
// Can't send update packets from here - use EntityJoinWorldEvent
ZSSEntityInfo.get(event.entityPlayer).copy(ZSSEntityInfo.get(event.original));
ZSSPlayerInfo.get(event.entityPlayer).copy(ZSSPlayerInfo.get(event.original));
}
@SubscribeEvent
public void onPlayerLoggedIn(PlayerLoggedInEvent event) {
ZSSPlayerInfo.get(event.player).onPlayerLoggedIn();
if (event.player instanceof EntityPlayerMP) {
PacketDispatcher.sendTo(new SyncConfigPacket(), (EntityPlayerMP) event.player);
}
}
@SubscribeEvent
public void onEntityJoinWorld(EntityJoinWorldEvent event) {
if (event.entity instanceof EntityPlayer) {
ZSSEntityInfo.get((EntityPlayer) event.entity).onJoinWorld();
ZSSPlayerInfo.get((EntityPlayer) event.entity).onJoinWorld();
}
if (!event.entity.worldObj.isRemote) {
if (event.entity.getClass() == EntityVillager.class) {
EntityGoron.doVillagerSpawn((EntityVillager) event.entity, event.entity.worldObj);
}
if (!Config.areVanillaBuffsDisabled() && event.entity instanceof EntityLivingBase) {
initBuffs((EntityLivingBase) event.entity);
}
}
}
@SubscribeEvent
public void onEntityConstructing(EntityConstructing event) {
if (event.entity instanceof EntityLivingBase && ZSSEntityInfo.get((EntityLivingBase) event.entity) == null) {
ZSSEntityInfo.register((EntityLivingBase) event.entity);
}
if (event.entity instanceof EntityVillager && ZSSVillagerInfo.get((EntityVillager) event.entity) == null) {
ZSSVillagerInfo.register((EntityVillager) event.entity);
}
if (event.entity instanceof EntityPlayer && ZSSPlayerInfo.get((EntityPlayer) event.entity) == null) {
ZSSPlayerInfo.register((EntityPlayer) event.entity);
}
}
@SubscribeEvent
public void postTeleport(EntityAITeleport.PostEnderTeleport event) {
EntityAITeleport.disruptTargeting(event.entityLiving);
if (event.entity instanceof IEntityTeleport) {
((IEntityTeleport) event.entity).getTeleportAI().onPostTeleport(event.targetX, event.targetY, event.targetZ);
}
}
/**
* Applies permanent buffs / debuffs to vanilla mobs
*/
private void initBuffs(EntityLivingBase entity) {
ZSSEntityInfo info = ZSSEntityInfo.get(entity);
if (!info.getActiveBuffs().isEmpty()) {
return;
}
// double damage from cold effects, highly resistant to fire damage
if (entity.isImmuneToFire()) {
info.applyBuff(Buff.RESIST_FIRE, Integer.MAX_VALUE, 75);
info.applyBuff(Buff.WEAKNESS_COLD, Integer.MAX_VALUE, 100);
}
if (entity.getCreatureAttribute() == EnumCreatureAttribute.UNDEAD) {
if (!entity.isImmuneToFire()) {
info.applyBuff(Buff.WEAKNESS_FIRE, Integer.MAX_VALUE, 50);
}
info.applyBuff(Buff.WEAKNESS_HOLY, Integer.MAX_VALUE, 300);
info.applyBuff(Buff.RESIST_COLD, Integer.MAX_VALUE, 50);
info.applyBuff(Buff.RESIST_STUN, Integer.MAX_VALUE, 50);
}
if (entity instanceof EntityGolem) {
info.applyBuff(Buff.RESIST_COLD, Integer.MAX_VALUE, 100);
info.applyBuff(Buff.RESIST_STUN, Integer.MAX_VALUE, 100);
}
if (entity instanceof EntityWitch) {
info.applyBuff(Buff.RESIST_MAGIC, Integer.MAX_VALUE, 75);
}
if (entity instanceof EntityWither) {
info.removeBuff(Buff.WEAKNESS_COLD);
}
}
}