package pneumaticCraft.client.render.pneumaticArmor;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.pathfinding.PathEntity;
import net.minecraft.pathfinding.PathPoint;
import net.minecraft.world.World;
import net.minecraftforge.common.config.Configuration;
import net.minecraftforge.common.util.ForgeDirection;
import net.minecraftforge.event.entity.player.PlayerInteractEvent;
import net.minecraftforge.event.entity.player.PlayerInteractEvent.Action;
import pneumaticCraft.api.client.pneumaticHelmet.IOptionPage;
import pneumaticCraft.api.client.pneumaticHelmet.IUpgradeRenderHandler;
import pneumaticCraft.client.gui.pneumaticHelmet.GuiCoordinateTrackerOptions;
import pneumaticCraft.client.gui.widget.GuiAnimatedStat;
import pneumaticCraft.common.NBTUtil;
import pneumaticCraft.common.ai.EntityPathNavigateDrone;
import pneumaticCraft.common.config.Config;
import pneumaticCraft.common.entity.living.EntityDrone;
import pneumaticCraft.common.item.ItemMachineUpgrade;
import pneumaticCraft.common.item.ItemPneumaticArmor;
import pneumaticCraft.common.item.Itemss;
import pneumaticCraft.common.network.NetworkHandler;
import pneumaticCraft.common.network.PacketCoordTrackUpdate;
import pneumaticCraft.lib.PneumaticValues;
import cpw.mods.fml.client.FMLClientHandler;
import cpw.mods.fml.common.eventhandler.SubscribeEvent;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
public class CoordTrackUpgradeHandler implements IUpgradeRenderHandler{
private RenderCoordWireframe coordTracker;
private RenderNavigator navigator;
public boolean isListeningToCoordTrackerSetting = false;
public boolean pathEnabled;
public boolean wirePath;
public boolean xRayEnabled;
private int noPathCooldown; //timer used to delay the client recalculating a path when it didn't last time. This prevents
//gigantic lag, as it uses much performance to find a path when it doesn't have anything cached.
private int pathCalculateCooldown;
public int pathUpdateSetting;
public static final int SEARCH_RANGE = 150;
public enum EnumNavigationResult{
NO_PATH, EASY_PATH, DRONE_PATH;
}
@Override
@SideOnly(Side.CLIENT)
public String getUpgradeName(){
return "coordinateTracker";
}
@Override
public void initConfig(Configuration config){
pathEnabled = config.get("Helmet_Options" + Configuration.CATEGORY_SPLITTER + "Coordinate_Tracker", "Path Enabled", true).getBoolean(true);
wirePath = config.get("Helmet_Options" + Configuration.CATEGORY_SPLITTER + "Coordinate_Tracker", "Wire Path", true).getBoolean(true);
xRayEnabled = config.get("Helmet_Options" + Configuration.CATEGORY_SPLITTER + "Coordinate_Tracker", "X-Ray", false).getBoolean(true);
pathUpdateSetting = config.get("Helmet_Options" + Configuration.CATEGORY_SPLITTER + "Coordinate_Tracker", "Path Update Rate", 1).getInt();
}
@Override
public void saveToConfig(){
Configuration config = Config.config;
config.load();
config.get("Helmet_Options" + Configuration.CATEGORY_SPLITTER + "Coordinate_Tracker", "Path Enabled", true).set(pathEnabled);
config.get("Helmet_Options" + Configuration.CATEGORY_SPLITTER + "Coordinate_Tracker", "Wire Path", true).set(wirePath);
config.get("Helmet_Options" + Configuration.CATEGORY_SPLITTER + "Coordinate_Tracker", "X-Ray", true).set(xRayEnabled);
config.get("Helmet_Options" + Configuration.CATEGORY_SPLITTER + "Coordinate_Tracker", "Path Update Rate", true).set(pathUpdateSetting);
config.save();
}
@Override
@SideOnly(Side.CLIENT)
public void update(EntityPlayer player, int rangeUpgrades){
if(coordTracker != null) coordTracker.ticksExisted++;
else {
coordTracker = ItemPneumaticArmor.getCoordTrackLocation(player.getCurrentArmor(3));
if(coordTracker != null) navigator = new RenderNavigator(coordTracker.worldObj, coordTracker.x, coordTracker.y, coordTracker.z);
}
if(noPathCooldown > 0) noPathCooldown--;
if(navigator != null && pathEnabled && noPathCooldown == 0 && --pathCalculateCooldown <= 0) {
navigator.updatePath();
if(!navigator.tracedToDestination()) noPathCooldown = 100;//wait 5 seconds before recalculating a path.
pathCalculateCooldown = pathUpdateSetting == 2 ? 1 : pathUpdateSetting == 1 ? 20 : 100;
}
}
@Override
@SideOnly(Side.CLIENT)
public void render3D(float partialTicks){
if(coordTracker != null) {
if(FMLClientHandler.instance().getClient().thePlayer.worldObj.provider.dimensionId != coordTracker.worldObj.provider.dimensionId) return;
coordTracker.render(partialTicks);
if(pathEnabled && navigator != null) {
navigator.render(wirePath, xRayEnabled, partialTicks);
}
}
}
@Override
@SideOnly(Side.CLIENT)
public void render2D(float partialTicks, boolean upgradeEnabled){}
@Override
public boolean isEnabled(ItemStack[] upgradeStacks){
for(ItemStack stack : upgradeStacks) {
if(stack != null && stack.getItem() == Itemss.machineUpgrade && stack.getItemDamage() == ItemMachineUpgrade.UPGRADE_COORDINATE_TRACKER_DAMAGE) return true;
}
return false;
}
@Override
public float getEnergyUsage(int rangeUpgrades, EntityPlayer player){
return PneumaticValues.USAGE_COORD_TRACKER;
}
@Override
@SideOnly(Side.CLIENT)
public void reset(){
coordTracker = null;
navigator = null;
}
@SubscribeEvent
public boolean onPlayerInteract(PlayerInteractEvent event){
if(event.action == Action.RIGHT_CLICK_BLOCK && isListeningToCoordTrackerSetting) {
isListeningToCoordTrackerSetting = false;
ForgeDirection dir = ForgeDirection.getOrientation(event.face);
reset();
ItemStack stack = event.entityPlayer.getCurrentArmor(3);
if(stack != null) {
NBTTagCompound tag = NBTUtil.getCompoundTag(stack, "CoordTracker");
tag.setInteger("dimID", event.entity.worldObj.provider.dimensionId);
tag.setInteger("x", event.x + dir.offsetX);
tag.setInteger("y", event.y + dir.offsetY);
tag.setInteger("z", event.z + dir.offsetZ);
}
NetworkHandler.sendToServer(new PacketCoordTrackUpdate(event.entity.worldObj, event.x + dir.offsetX, event.y + dir.offsetY, event.z + dir.offsetZ));
}
return false;
}
@SideOnly(Side.CLIENT)
public EnumNavigationResult navigateToSurface(EntityPlayer player){
World worldObj = player.worldObj;
int y = worldObj.getHeightValue((int)player.posX, (int)player.posZ);
PathEntity path = worldObj.getEntityPathToXYZ(player, (int)player.posX, y, (int)player.posZ, SEARCH_RANGE, true, true, false, true);
EnumNavigationResult result = path != null ? EnumNavigationResult.EASY_PATH : EnumNavigationResult.DRONE_PATH;
if(path != null) {
for(int i = 0; i < path.getCurrentPathLength(); i++) {
PathPoint pathPoint = path.getPathPointFromIndex(i);
if(worldObj.canBlockSeeTheSky(pathPoint.xCoord, pathPoint.yCoord, pathPoint.zCoord)) {
coordTracker = new RenderCoordWireframe(worldObj, pathPoint.xCoord, pathPoint.yCoord, pathPoint.zCoord);
navigator = new RenderNavigator(worldObj, pathPoint.xCoord, pathPoint.yCoord, pathPoint.zCoord);
return EnumNavigationResult.EASY_PATH;
}
}
}
path = getDronePath(player, (int)player.posX, y, (int)player.posZ);
if(path != null) {
for(int i = 0; i < path.getCurrentPathLength(); i++) {
PathPoint pathPoint = path.getPathPointFromIndex(i);
if(worldObj.canBlockSeeTheSky(pathPoint.xCoord, pathPoint.yCoord, pathPoint.zCoord)) {
coordTracker = new RenderCoordWireframe(worldObj, pathPoint.xCoord, pathPoint.yCoord, pathPoint.zCoord);
navigator = new RenderNavigator(worldObj, pathPoint.xCoord, pathPoint.yCoord, pathPoint.zCoord);
return EnumNavigationResult.DRONE_PATH;
}
}
}
return EnumNavigationResult.NO_PATH;
}
public static PathEntity getDronePath(EntityPlayer player, int x, int y, int z){
World worldObj = player.worldObj;
EntityDrone drone = new EntityDrone(worldObj);
drone.setPosition(player.posX, player.posY - 2, player.posZ);
return new EntityPathNavigateDrone(drone, worldObj).getEntityPathToXYZ(drone, x, y, z, SEARCH_RANGE, true, true, false, true);
}
@Override
@SideOnly(Side.CLIENT)
public IOptionPage getGuiOptionsPage(){
return new GuiCoordinateTrackerOptions();
}
@Override
@SideOnly(Side.CLIENT)
public GuiAnimatedStat getAnimatedStat(){
return null;
}
}