Java tutorial
/* * 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; } }