/**
Copyright (C) <2015> <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.entity.passive;
import java.util.UUID;
import net.minecraft.entity.Entity;
import net.minecraft.entity.IEntityOwnable;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.BlockPos;
import net.minecraft.util.MathHelper;
import net.minecraft.util.Vec3;
import net.minecraft.world.World;
import net.minecraftforge.common.util.Constants;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import zeldaswordskills.block.BlockSecretStone;
import zeldaswordskills.ref.Config;
import zeldaswordskills.ref.Sounds;
import zeldaswordskills.util.PlayerUtils;
public class EntityNavi extends EntityFairy implements IEntityOwnable
{
/** Datawatcher index for owner's UUID */
private static final int OWNER_INDEX = 17;
private EntityPlayer owner;
public EntityNavi(World world) {
super(world);
enablePersistence();
}
@Override
protected void entityInit() {
super.entityInit();
dataWatcher.addObject(OWNER_INDEX, "");
}
@Override
public void setFairyHome(BlockPos pos) {
super.setFairyHome(pos);
home = null;
}
@Override
public boolean canDespawn() {
return false;
}
@Override
protected void collideWithEntity(Entity entity) {}
@Override
public void onUpdate() {
super.onUpdate();
if (!worldObj.isRemote) {
if (getOwner() == null && ticksExisted > 10) {
setDead();
} else if (Config.getNaviRange() > 0 && ticksExisted % Config.getNaviFrequency() == 0) {
detectDungeons();
}
}
}
@Override
@SideOnly(Side.CLIENT)
public boolean getAlwaysRenderNameTagForRender() {
return true;
}
@Override
protected void updateAITasks() {
if (getOwner() != null && (ticksExisted % 30) == 0) {
Vec3 look = owner.getLookVec();
int x = MathHelper.floor_double(owner.posX - look.xCoord);
int y = MathHelper.floor_double(owner.posY + owner.getEyeHeight());
int z = MathHelper.floor_double(owner.posZ - look.zCoord);
home = new BlockPos(x, y + 1, z);
if (owner.getDistanceSqToEntity(this) > 144.0D) {
setLocationAndAngles(owner.posX + look.xCoord, owner.posY + owner.getEyeHeight(), owner.posZ + look.zCoord, rotationYaw, rotationPitch);
}
}
super.updateAITasks();
}
@Override
public String getOwnerId() {
return dataWatcher.getWatchableObjectString(OWNER_INDEX);
}
/**
* Updates datawatcher with the owner's UUID
*/
public void setOwnerUUID(String uuid) {
this.dataWatcher.updateObject(OWNER_INDEX, uuid);
}
@Override
public EntityPlayer getOwner() {
if (owner != null) {
return owner;
}
try {
UUID uuid = UUID.fromString(getOwnerId());
if (uuid != null) {
owner = worldObj.getPlayerEntityByUUID(uuid);
}
return owner;
} catch (IllegalArgumentException e) {
return null;
}
}
/**
* Sets the owner of this fairy; without an owner, Navi will perish...
*/
public void setOwner(EntityPlayer player) {
this.owner = player;
setOwnerUUID(player.getUniqueID().toString());
}
/**
* Checks nearby for any secret rooms; requires owner to be valid
*/
private void detectDungeons() {
int range = Config.getNaviRange();
double r2 = (range * range);
int r = range + (range / 2);
int ry = MathHelper.ceiling_float_int((float) r / 2.0F);
int x = MathHelper.floor_double(owner.posX + 0.5D);
int y = MathHelper.floor_double(owner.posY + owner.getEyeHeight());
int z = MathHelper.floor_double(owner.posZ + 0.5D);
boolean search = true;
for (int i = x - r; i <= x + r && search; ++i) {
for (int j = y - ry; j <= y + ry && search; ++j) {
for (int k = z - r; k <= z + r && search; ++k) {
if (worldObj.getBlockState(new BlockPos(i, j, k)).getBlock() instanceof BlockSecretStone) {
double d = owner.getDistanceSq((double) i + 0.5D, (double) j + 0.5D, (double) k + 0.5D);
if (d <= r2) {
float f = (float)(Math.sqrt(d) / (double) r);
// play sound only on the client side - not everyone needs to hear each other's annoying fairies
PlayerUtils.playSound(owner, Sounds.FAIRY_LAUGH, 0.6F - (f / 2.0F), 1.0F);
search = false;
}
}
}
}
}
}
@Override
public void writeEntityToNBT(NBTTagCompound compound) {
super.writeEntityToNBT(compound);
String uuid = getOwnerId();
if (uuid != null && uuid.length() > 0) {
compound.setString("OwnerUUID", uuid);
}
}
@Override
public void readEntityFromNBT(NBTTagCompound compound) {
super.readEntityFromNBT(compound);
String s = (compound.hasKey("OwnerUUID", Constants.NBT.TAG_STRING) ? compound.getString("OwnerUUID") : "");
if (s.length() > 0) {
setOwnerUUID(s);
}
}
}