package joshie.harvest.npcs.entity;
import joshie.harvest.api.HFApi;
import joshie.harvest.api.npc.NPC;
import joshie.harvest.api.npc.task.TaskElement;
import joshie.harvest.core.HFTrackers;
import joshie.harvest.npcs.entity.ai.EntityAIPathing;
import joshie.harvest.npcs.entity.ai.EntityAISchedule;
import joshie.harvest.npcs.entity.ai.EntityAITalkingTo;
import joshie.harvest.town.TownHelper;
import joshie.harvest.town.data.TownDataServer;
import joshie.harvest.town.tracker.TownTrackerServer;
import net.minecraft.entity.SharedMonsterAttributes;
import net.minecraft.entity.ai.EntityAIOpenDoor;
import net.minecraft.entity.ai.EntityAISwimming;
import net.minecraft.entity.ai.EntityAIWatchClosest;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.MobEffects;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.pathfinding.PathNavigateGround;
import net.minecraft.potion.PotionEffect;
import net.minecraft.util.DamageSource;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import javax.annotation.Nonnull;
import static joshie.harvest.npcs.HFNPCs.NPC_AI_DISTANCE;
public abstract class EntityNPCHuman<E extends EntityNPCHuman> extends EntityNPC<E> {
private EntityAIPathing pathing;
@SuppressWarnings("WeakerAccess")
private TownDataServer homeTown;
private int nullChecker;
EntityNPCHuman(World world) {
super(world);
}
EntityNPCHuman(World world, NPC npc) {
super(world, npc);
}
EntityNPCHuman(E entity) {
super(entity);
}
@Override
protected void initEntityAI() {
((PathNavigateGround) getNavigator()).setEnterDoors(true);
((PathNavigateGround) getNavigator()).setBreakDoors(true);
tasks.addTask(0, new EntityAISwimming(this));
tasks.addTask(1, new EntityAITalkingTo(this));
tasks.addTask(1, new EntityAIWatchClosest(this, EntityPlayer.class, 8.0F));
tasks.addTask(4, new EntityAIOpenDoor(this, true));
pathing = new EntityAIPathing(this);
tasks.addTask(5, pathing);
tasks.addTask(6, new EntityAISchedule(this));
tasks.addTask(9, new EntityAIWatchClosest(this, EntityPlayer.class, 3.0F, 1.0F));
tasks.addTask(9, new EntityAIWatchClosest(this, EntityNPC.class, 5.0F, 0.02F));
}
@Override
protected void applyEntityAttributes() {
super.applyEntityAttributes();
getEntityAttribute(SharedMonsterAttributes.FOLLOW_RANGE).setBaseValue(NPC_AI_DISTANCE);
}
public EntityAIPathing getPathing() {
return pathing;
}
@SuppressWarnings("unchecked")
public TownDataServer getHomeTown() {
if (homeTown == null) {
homeTown = TownHelper.getClosestTownToEntity(this, false);
} else if (homeTown == TownTrackerServer.NULL_TOWN) {
nullChecker++;
if (nullChecker %200 == 0) {
homeTown = TownHelper.getClosestTownToEntity(this, false);
}
}
return homeTown;
}
@Override
public void setPath(TaskElement... tasks) {
pathing.setPath(tasks);
}
@Override
public void onDeath(@Nonnull DamageSource cause) {
if (!worldObj.isRemote) {
//Respawn a new bugger
if (npc.respawns()) {
this.<TownDataServer>getHomeTown().markNPCDead(getNPC().getResource(), new BlockPos(this));
HFTrackers.markTownsDirty(); //Mark this npc as dead, ready for tomorrow to be reborn
}
}
super.onDeath(cause);
}
@Override
public boolean attackEntityFrom(@Nonnull DamageSource source, float amount) {
if (source != DamageSource.outOfWorld) {
addPotionEffect(new PotionEffect(MobEffects.REGENERATION, 200, 0, true, false));
if (source.getSourceOfDamage() instanceof EntityPlayer) {
HFApi.player.getRelationsForPlayer(((EntityPlayer) source.getSourceOfDamage())).affectRelationship(npc, -10);
}
if (source == DamageSource.inWall) {
attemptTeleport(posX + worldObj.rand.nextInt(20) - 10D, posY + worldObj.rand.nextInt(3), posZ + worldObj.rand.nextInt(20) - 10D);
}
}
return super.attackEntityFrom(source, amount);
}
@Override
public void readEntityFromNBT(NBTTagCompound nbt) {
super.readEntityFromNBT(nbt);
if (pathing != null) {
pathing.readFromNBT(nbt.getCompoundTag("Pathing"));
}
}
@Override
public void writeEntityToNBT(NBTTagCompound nbt) {
super.writeEntityToNBT(nbt);
if (pathing != null) {
nbt.setTag("Pathing", pathing.writeToNBT(new NBTTagCompound()));
}
}
}