matteroverdrive.entity.monster.EntityRougeAndroidMob.java Source code

Java tutorial

Introduction

Here is the source code for matteroverdrive.entity.monster.EntityRougeAndroidMob.java

Source

/*
 * This file is part of Matter Overdrive
 * Copyright (c) 2015., Simeon Radivoev, All rights reserved.
 *
 * Matter Overdrive is free software: 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.
 *
 * Matter Overdrive 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 Matter Overdrive.  If not, see <http://www.gnu.org/licenses>.
 */

package matteroverdrive.entity.monster;

import cpw.mods.fml.common.network.ByteBufUtils;
import cpw.mods.fml.common.registry.IEntityAdditionalSpawnData;
import io.netty.buffer.ByteBuf;
import matteroverdrive.Reference;
import matteroverdrive.api.entity.IPathableMob;
import matteroverdrive.data.BlockPos;
import matteroverdrive.init.MatterOverdriveItems;
import matteroverdrive.tile.TileEntityAndroidSpawner;
import matteroverdrive.util.MOStringHelper;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.SharedMonsterAttributes;
import net.minecraft.entity.monster.EntityMob;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.potion.PotionEffect;
import net.minecraft.scoreboard.ScorePlayerTeam;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.*;
import net.minecraft.world.EnumDifficulty;
import net.minecraft.world.World;
import net.minecraft.world.chunk.Chunk;
import net.minecraftforge.common.util.Constants;
import net.minecraftforge.common.util.ForgeDirection;

/**
 * Created by Simeon on 11/15/2015.
 */
public class EntityRougeAndroidMob extends EntityMob
        implements IEntityAdditionalSpawnData, IPathableMob<EntityRougeAndroidMob> {
    private static ResourceLocation androidNames = new ResourceLocation(Reference.PATH_INFO + "android_names.txt");
    private static String[] names = MOStringHelper.readTextFile(androidNames).split(",");
    boolean fromSpawner;
    private BlockPos spawnerPosition;
    private int currentPathIndex;
    private Vec3[] path;
    private int maxPathTargetRangeSq;
    private int visorColor;
    private ScorePlayerTeam team;
    private boolean legendary;
    private int level;

    public EntityRougeAndroidMob(World world) {
        super(world);
        if (!world.isRemote) {
            setAndroidLevel((int) (MathHelper.clamp_double(
                    Math.abs(rand.nextGaussian() * (1 + world.difficultySetting.getDifficultyId() * 0.25)), 0, 3)));
            boolean isLegendary = rand.nextDouble() < 0.05 * getAndroidLevel();
            setLegendary(isLegendary);
            init();
            getNavigator().setAvoidsWater(true);
            getNavigator().setCanSwim(false);
        }
    }

    public EntityRougeAndroidMob(World world, int level, boolean legendary) {
        super(world);
        setAndroidLevel(level);
        setLegendary(legendary);
        init();
    }

    private void init() {
        String name;
        if (getIsLegendary()) {
            name = EnumChatFormatting.GOLD.toString();
        } else {
            switch (getAndroidLevel()) {
            case 0:
                name = EnumChatFormatting.GRAY.toString();
                break;
            case 1:
                name = EnumChatFormatting.DARK_AQUA.toString();
                break;
            case 2:
                name = EnumChatFormatting.DARK_PURPLE.toString();
                break;
            default:
                name = "";
            }

        }
        name += getIsLegendary() ? EnumChatFormatting.GOLD + String.format("%s %s ", Reference.UNICODE_LEGENDARY,
                MOStringHelper.translateToLocal("rarity.legendary")) : "";
        name += String.format("[%s] ", getAndroidLevel());
        name += names[rand.nextInt(names.length)];
        setCustomNameTag(name);
        this.getEntityAttribute(SharedMonsterAttributes.maxHealth)
                .setBaseValue(getIsLegendary() ? 128 : getAndroidLevel() * 10 + 32);
        this.setHealth(this.getMaxHealth());

        if (fromSpawner) {
            if (!addToSpawner(spawnerPosition)) {
                setDead();
            }
        }

        if (getIsLegendary()) {
            setVisorColor(Reference.COLOR_HOLO_RED.getColor());
        } else {
            switch (getAndroidLevel()) {
            case 0:
                setVisorColor(Reference.COLOR_HOLO.getColor());
                break;
            case 1:
                setVisorColor(Reference.COLOR_HOLO_YELLOW.getColor());
                break;
            case 2:
                setVisorColor(Reference.COLOR_HOLO_PURPLE.getColor());
                break;
            default:
                setVisorColor(0xFFFFFFFF);
            }
        }
    }

    @Override
    public void readEntityFromNBT(NBTTagCompound nbtTagCompound) {
        super.readEntityFromNBT(nbtTagCompound);
        setLegendary(nbtTagCompound.getBoolean("Legendary"));
        setAndroidLevel(nbtTagCompound.getByte("Level"));
        setVisorColor(nbtTagCompound.getInteger("VisorColor"));
        if (nbtTagCompound.hasKey("Team", Constants.NBT.TAG_STRING)) {
            ScorePlayerTeam team = worldObj.getScoreboard().getTeam(nbtTagCompound.getString("Team"));
            if (team != null) {
                setTeam(team);
            } else {
                setDead();
            }
        }
        if (nbtTagCompound.hasKey("SpawnerPos", Constants.NBT.TAG_COMPOUND)) {
            spawnerPosition = new BlockPos(nbtTagCompound.getCompoundTag("SpawnerPos"));
            this.fromSpawner = true;
        }
        currentPathIndex = nbtTagCompound.getInteger("CurrentPathIndex");
    }

    @Override
    public void writeEntityToNBT(NBTTagCompound nbtTagCompound) {
        super.writeEntityToNBT(nbtTagCompound);
        nbtTagCompound.setByte("Level", (byte) getAndroidLevel());
        nbtTagCompound.setBoolean("Legendary", getIsLegendary());
        nbtTagCompound.setInteger("VisorColor", getVisorColor());
        if (getTeam() != null) {
            nbtTagCompound.setString("Team", getTeam().getRegisteredName());
        }
        if (spawnerPosition != null) {
            NBTTagCompound spawnerPos = new NBTTagCompound();
            spawnerPosition.writeToNBT(spawnerPos);
            nbtTagCompound.setTag("SpawnerPos", spawnerPos);
        }
        nbtTagCompound.setInteger("CurrentPathIndex", currentPathIndex);
    }

    private boolean addToSpawner(BlockPos position) {
        this.spawnerPosition = position;
        TileEntityAndroidSpawner spawnerEntity = position.getTileEntity(worldObj, TileEntityAndroidSpawner.class);
        if (spawnerEntity != null) {
            spawnerEntity.addSpawnedAndroid(this);
            return true;
        }
        return false;
    }

    public void setAttackTarget(EntityLivingBase target) {
        if (target != null && target.getTeam() != null) {
            if (!target.getTeam().isSameTeam(getTeam()))
                super.setAttackTarget(target);
        } else {
            super.setAttackTarget(target);
        }
    }

    @Override
    public boolean isPotionApplicable(PotionEffect potion) {
        return false;
    }

    @Override
    public boolean getCanSpawnHere() {
        return getCanSpawnHere(false, false, false) && !hasToManyAndroids();
    }

    public boolean hasToManyAndroids() {
        Chunk chunk = worldObj.getChunkFromChunkCoords(chunkCoordX, chunkCoordZ);
        int androidCount = 0;
        for (int i = 0; i < chunk.entityLists.length; i++) {
            for (int c = 0; i < chunk.entityLists[i].size(); i++) {
                if (chunk.entityLists[i].get(c) instanceof EntityRougeAndroidMob) {
                    androidCount++;
                    if (androidCount > EntityRogueAndroid.MAX_ANDROIDS_PER_CHUNK)
                        return true;
                }
            }

        }
        return false;
    }

    public boolean getCanSpawnHere(boolean ignoreEntityCollision, boolean ignoreLight, boolean ignoreDimension) {
        if (!ignoreDimension) {
            if (EntityRogueAndroid.dimensionWhitelist.size() > 0) {
                return EntityRogueAndroid.dimensionWhitelist.contains(worldObj.provider.dimensionId)
                        && inDimensionBlacklist();
            }
            if (inDimensionBlacklist()) {
                return false;
            }
        }
        boolean light = ignoreLight ? true : isValidLightLevel();
        boolean entityCollison = ignoreEntityCollision ? true
                : this.worldObj.checkNoEntityCollision(this.boundingBox);
        return this.worldObj.difficultySetting != EnumDifficulty.PEACEFUL && light && entityCollison
                && this.worldObj.getCollidingBoundingBoxes(this, this.boundingBox).isEmpty()
                && !this.worldObj.isAnyLiquid(this.boundingBox);
    }

    public float getBlockPathWeight(int p_70783_1_, int p_70783_2_, int p_70783_3_) {
        float weight = 1 - this.worldObj.getLightBrightness(p_70783_1_, p_70783_2_, p_70783_3_);
        weight *= this.worldObj.isSideSolid(p_70783_1_, p_70783_2_, p_70783_3_, ForgeDirection.UP) ? 0 : 1;
        weight /= Math.abs(p_70783_2_ - posX);
        return weight;
    }

    protected void addRandomArmor() {
        if (this.rand.nextFloat() < 0.15F) {
            int i = this.rand.nextInt(2);
            float f = this.worldObj.difficultySetting == EnumDifficulty.HARD ? 0.1F : 0.25F;

            if (this.rand.nextFloat() < 0.095F) {
                ++i;
            }

            if (this.rand.nextFloat() < 0.095F) {
                ++i;
            }

            if (this.rand.nextFloat() < 0.095F) {
                ++i;
            }

            for (int j = 3; j >= 0; --j) {
                ItemStack itemstack = this.func_130225_q(j);

                if (j < 3 && this.rand.nextFloat() < f) {
                    break;
                }

                if (itemstack == null) {
                    Item item = null;

                    if (i == 3) {
                        if (rand.nextBoolean()) {
                            switch (j + 1) {
                            case 4:
                                item = MatterOverdriveItems.tritaniumHelemet;
                                break;
                            case 3:
                                item = MatterOverdriveItems.tritaniumChestplate;
                                break;
                            case 2:
                                item = MatterOverdriveItems.tritaniumLeggings;
                                break;
                            case 1:
                                item = MatterOverdriveItems.tritaniumBoots;
                                break;
                            }
                        } else {
                            item = getArmorItemForSlot(j + 1, i);
                        }
                    } else {
                        item = getArmorItemForSlot(j + 1, i);
                    }

                    if (item != null) {
                        this.setCurrentItemOrArmor(j + 1, new ItemStack(item));
                    }
                }
            }
        }
    }

    @Override
    public boolean isWithinHomeDistance(int p_110176_1_, int p_110176_2_, int p_110176_3_) {
        return true;
    }

    @Override
    public boolean hasHome() {

        return getCurrentTarget() != null;
    }

    @Override
    public ChunkCoordinates getHomePosition() {
        Vec3 currentTarget = getCurrentTarget();
        return new ChunkCoordinates((int) currentTarget.xCoord, (int) currentTarget.yCoord,
                (int) currentTarget.zCoord);
    }

    private boolean inDimensionBlacklist() {
        return EntityRogueAndroid.dimensionBlacklist.contains(worldObj.provider.dimensionId);
    }

    public void setAndroidLevel(int level) {
        this.level = level;
    }

    public int getAndroidLevel() {
        return this.level;
    }

    public void setLegendary(boolean legendary) {
        this.legendary = legendary;
        if (legendary) {
            this.height = 1.8f * 1.6f;
        } else {
            this.height = 1.8f;
        }
    }

    public boolean getIsLegendary() {
        return legendary;
    }

    public void setTeam(ScorePlayerTeam team) {
        this.team = team;
    }

    @Override
    public String getCustomNameTag() {
        if (hasTeam()) {
            return getTeam().formatString(this.dataWatcher.getWatchableObjectString(10));
        }
        return this.dataWatcher.getWatchableObjectString(10);
    }

    @Override
    public ScorePlayerTeam getTeam() {
        return team;
    }

    public boolean hasTeam() {
        return getTeam() != null;
    }

    public boolean wasSpawnedFrom(TileEntityAndroidSpawner spawner) {
        if (spawnerPosition != null) {
            TileEntity tileEntity = spawnerPosition.getTileEntity(worldObj);
            return tileEntity == spawner;
        }
        return false;
    }

    public void setSpawnerPosition(BlockPos position) {
        this.spawnerPosition = position;
        this.fromSpawner = true;
    }

    @Override
    public void setDead() {
        if (spawnerPosition != null) {
            TileEntityAndroidSpawner spawner = spawnerPosition.getTileEntity(worldObj,
                    TileEntityAndroidSpawner.class);
            if (spawner != null) {
                spawner.removeAndroid(this);
            }
        }
        this.isDead = true;
    }

    public int getVisorColor() {
        return visorColor;
    }

    public void setVisorColor(int color) {
        visorColor = color;
    }

    @Override
    public void writeSpawnData(ByteBuf buffer) {
        buffer.writeByte(level);
        buffer.writeBoolean(legendary);
        buffer.writeInt(visorColor);
        buffer.writeBoolean(hasTeam());
        if (hasTeam()) {
            ByteBufUtils.writeUTF8String(buffer, getTeam().getRegisteredName());
        }
    }

    @Override
    public void readSpawnData(ByteBuf additionalData) {
        setAndroidLevel(additionalData.readByte());
        setLegendary(additionalData.readBoolean());
        setVisorColor(additionalData.readInt());
        if (additionalData.readBoolean()) {
            String teamName = ByteBufUtils.readUTF8String(additionalData);
            ScorePlayerTeam team = worldObj.getScoreboard().getTeam(teamName);
            if (team != null)
                setTeam(team);
        }
    }

    @Override
    public Vec3 getCurrentTarget() {
        if (path != null && currentPathIndex < path.length) {
            return path[currentPathIndex];
        }
        return null;
    }

    @Override
    public void onTargetReached(Vec3 pos) {
        if (currentPathIndex < path.length - 1) {
            currentPathIndex++;
        }
    }

    @Override
    public boolean isNearTarget(Vec3 pos) {
        return pos.squareDistanceTo(posX, posY, posZ) < maxPathTargetRangeSq;
    }

    @Override
    public EntityRougeAndroidMob getEntity() {
        return this;
    }

    public void setPath(Vec3[] path, int range) {
        this.path = path;
        maxPathTargetRangeSq = range * range;
    }

    @Override
    protected String getLivingSound() {
        return Reference.MOD_ID + ":" + "rogue_android_say";
    }

    @Override
    protected String getDeathSound() {
        return Reference.MOD_ID + ":" + "rogue_android_death";
    }

    @Override
    protected float getSoundVolume() {
        return 0.5f;
    }

    public int getTalkInterval() {
        return 20 * 24;
    }
}