diff --git a/src/main/java/com/hbm/entity/EntityMappings.java b/src/main/java/com/hbm/entity/EntityMappings.java index 797097dfc..04499718a 100644 --- a/src/main/java/com/hbm/entity/EntityMappings.java +++ b/src/main/java/com/hbm/entity/EntityMappings.java @@ -238,6 +238,7 @@ public class EntityMappings { addMob(EntitySiegeSkeleton.class, "entity_meme_skeleton", 0x303030, 0x000080); addMob(EntitySiegeUFO.class, "entity_meme_ufo", 0x303030, 0x800000); addMob(EntitySiegeCraft.class, "entity_meme_craft", 0x303030, 0x808000); + addMob(EntityGlyphid.class, "entity_glyphid", 0x724A21, 0xD2BB72); addSpawn(EntityCreeperPhosgene.class, 5, 1, 1, EnumCreatureType.monster, BiomeGenBase.getBiomeGenArray()); addSpawn(EntityCreeperVolatile.class, 10, 1, 1, EnumCreatureType.monster, BiomeGenBase.getBiomeGenArray()); diff --git a/src/main/java/com/hbm/entity/mob/EntityGlyphid.java b/src/main/java/com/hbm/entity/mob/EntityGlyphid.java new file mode 100644 index 000000000..416b316b7 --- /dev/null +++ b/src/main/java/com/hbm/entity/mob/EntityGlyphid.java @@ -0,0 +1,164 @@ +package com.hbm.entity.mob; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import net.minecraft.entity.Entity; +import net.minecraft.entity.EnumCreatureAttribute; +import net.minecraft.entity.SharedMonsterAttributes; +import net.minecraft.entity.ai.EntityAIAttackOnCollide; +import net.minecraft.entity.ai.EntityAIHurtByTarget; +import net.minecraft.entity.ai.EntityAILookIdle; +import net.minecraft.entity.ai.EntityAIMoveTowardsRestriction; +import net.minecraft.entity.ai.EntityAINearestAttackableTarget; +import net.minecraft.entity.ai.EntityAISwimming; +import net.minecraft.entity.ai.EntityAIWander; +import net.minecraft.entity.ai.EntityAIWatchClosest; +import net.minecraft.entity.monster.EntityMob; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.util.DamageSource; +import net.minecraft.world.World; + +public class EntityGlyphid extends EntityMob { + + public EntityGlyphid(World world) { + super(world); + this.tasks.addTask(0, new EntityAISwimming(this)); + this.tasks.addTask(2, new EntityAIAttackOnCollide(this, EntityPlayer.class, 1.0D, false)); + this.tasks.addTask(5, new EntityAIMoveTowardsRestriction(this, 1.0D)); + this.tasks.addTask(7, new EntityAIWander(this, 1.0D)); + this.tasks.addTask(8, new EntityAIWatchClosest(this, EntityPlayer.class, 8.0F)); + this.tasks.addTask(8, new EntityAILookIdle(this)); + this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, true)); + this.targetTasks.addTask(2, new EntityAINearestAttackableTarget(this, EntityPlayer.class, 0, true)); + this.setSize(2F, 1F); + } + + @Override + protected void entityInit() { + super.entityInit(); + this.dataWatcher.addObject(16, new Byte((byte) 0)); //wall climbing + this.dataWatcher.addObject(17, new Byte((byte) 0b11111)); //armor + } + + @Override + protected void applyEntityAttributes() { + super.applyEntityAttributes(); + this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(32D); + this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(0.8D); + } + + @Override + public boolean attackEntityFrom(DamageSource source, float amount) { + + if(!source.isDamageAbsolute() && !source.isUnblockable() && !worldObj.isRemote) { + byte armor = this.dataWatcher.getWatchableObjectByte(17); + + if(armor != 0) { //if at least one bit of armor is present + int chance = amount < 10 ? 5 : amount < 20 ? 3 : 2; //chances of armor being broken off + if(this.rand.nextInt(chance) == 0) { + List indices = Arrays.asList(0, 1, 2, 3, 4); + Collections.shuffle(indices); + + for(Integer i : indices) { + byte bit = (byte) (1 << i); + if((armor & bit) > 0) { //if this bit is present... + armor &= ~bit; //...remove it + armor = (byte) (armor & 0b11111); + this.dataWatcher.updateObject(17, armor); + return false; + } + } + } + + amount -= 0.5; + } + + int divisor = 1; + + for(int i = 0; i < 5; i++) { + if((armor & (1 << i)) > 0) { + divisor++; + } + } + + System.out.println("" + divisor); + + amount /= divisor; + } + + return super.attackEntityFrom(source, amount); + } + + @Override + public boolean attackEntityAsMob(Entity victum) { + if(this.isSwingInProgress) return false; + this.swingItem(); + return super.attackEntityAsMob(victum); + } + + @Override + public void onUpdate() { + super.onUpdate(); + + if(!this.worldObj.isRemote) { + this.setBesideClimbableBlock(this.isCollidedHorizontally); + + if(worldObj.getTotalWorldTime() % 100 == 0) { + this.swingItem(); + } + } + } + + @Override + protected void updateArmSwingProgress() { + int i = this.swingDuration(); + + if(this.isSwingInProgress) { + ++this.swingProgressInt; + + if(this.swingProgressInt >= i) { + this.swingProgressInt = 0; + this.isSwingInProgress = false; + } + } else { + this.swingProgressInt = 0; + } + + this.swingProgress = (float) this.swingProgressInt / (float) i; + } + + public int swingDuration() { + return 15; + } + + @Override + public void setInWeb() { } + + @Override + public boolean isOnLadder() { + return this.isBesideClimbableBlock(); + } + + public boolean isBesideClimbableBlock() { + return (this.dataWatcher.getWatchableObjectByte(16) & 1) != 0; + } + + public void setBesideClimbableBlock(boolean climbable) { + byte watchable = this.dataWatcher.getWatchableObjectByte(16); + + if(climbable) { + watchable = (byte) (watchable | 1); + } else { + watchable &= -2; + } + + this.dataWatcher.updateObject(16, Byte.valueOf(watchable)); + } + + @Override + public EnumCreatureAttribute getCreatureAttribute() { + return EnumCreatureAttribute.ARTHROPOD; + } +} diff --git a/src/main/java/com/hbm/handler/pollution/PollutionHandler.java b/src/main/java/com/hbm/handler/pollution/PollutionHandler.java index bbc4e7099..d62fd28e6 100644 --- a/src/main/java/com/hbm/handler/pollution/PollutionHandler.java +++ b/src/main/java/com/hbm/handler/pollution/PollutionHandler.java @@ -122,14 +122,15 @@ public class PollutionHandler { if(!event.world.isRemote) { WorldServer world = (WorldServer) event.world; String dirPath = getDataDir(world); + File pollutionFile = new File(dirPath, fileName); try { - File pollutionFile = new File(dirPath, fileName); if(!pollutionFile.getParentFile().exists()) pollutionFile.getParentFile().mkdirs(); if(!pollutionFile.exists()) pollutionFile.createNewFile(); NBTTagCompound data = perWorld.get(world).writeToNBT(); CompressedStreamTools.writeCompressed(data, new FileOutputStream(pollutionFile)); } catch(Exception ex) { + System.out.println("Failed to write " + pollutionFile.getAbsolutePath()); ex.printStackTrace(); } } diff --git a/src/main/java/com/hbm/main/ClientProxy.java b/src/main/java/com/hbm/main/ClientProxy.java index 492673357..ab05362d0 100644 --- a/src/main/java/com/hbm/main/ClientProxy.java +++ b/src/main/java/com/hbm/main/ClientProxy.java @@ -721,6 +721,7 @@ public class ClientProxy extends ServerProxy { RenderingRegistry.registerEntityRenderingHandler(EntitySiegeSkeleton.class, new RenderSiegeSkeleton()); RenderingRegistry.registerEntityRenderingHandler(EntitySiegeTunneler.class, new RenderSiegeTunneler()); RenderingRegistry.registerEntityRenderingHandler(EntityGhost.class, new RenderGhost()); + RenderingRegistry.registerEntityRenderingHandler(EntityGlyphid.class, new RenderGlyphid()); //"particles" RenderingRegistry.registerEntityRenderingHandler(EntitySmokeFX.class, new MultiCloudRenderer(new Item[] { ModItems.smoke1, ModItems.smoke2, ModItems.smoke3, ModItems.smoke4, ModItems.smoke5, ModItems.smoke6, ModItems.smoke7, ModItems.smoke8 })); RenderingRegistry.registerEntityRenderingHandler(EntityBSmokeFX.class, new MultiCloudRenderer(new Item[] { ModItems.b_smoke1, ModItems.b_smoke2, ModItems.b_smoke3, ModItems.b_smoke4, ModItems.b_smoke5, ModItems.b_smoke6, ModItems.b_smoke7, ModItems.b_smoke8 })); diff --git a/src/main/java/com/hbm/render/entity/mob/RenderGlyphid.java b/src/main/java/com/hbm/render/entity/mob/RenderGlyphid.java new file mode 100644 index 000000000..30915068e --- /dev/null +++ b/src/main/java/com/hbm/render/entity/mob/RenderGlyphid.java @@ -0,0 +1,167 @@ +package com.hbm.render.entity.mob; + +import org.lwjgl.opengl.GL11; + +import com.hbm.main.ResourceManager; + +import net.minecraft.client.model.ModelBase; +import net.minecraft.client.renderer.entity.RenderLiving; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.util.MathHelper; +import net.minecraft.util.ResourceLocation; + +public class RenderGlyphid extends RenderLiving { + + public RenderGlyphid() { + super(new ModelGlyphid(), 1.0F); + this.shadowOpaque = 0.0F; + } + + @Override + protected ResourceLocation getEntityTexture(Entity p_110775_1_) { + return ResourceManager.glyphid_tex; + } + + public static class ModelGlyphid extends ModelBase { + + double bite = 0; + + @Override + public void setLivingAnimations(EntityLivingBase entity, float limbSwing, float limbSwingAmount, float interp) { + bite = entity.getSwingProgress(interp); + } + + @Override + public void render(Entity entity, float limbSwing, float limbSwingAmount, float rotationYaw, float rotationHeadYaw, float rotationPitch, float scale) { + GL11.glPushMatrix(); + + GL11.glRotatef(180, 1, 0, 0); + GL11.glTranslatef(0, -1.5F, 0); + GL11.glEnable(GL11.GL_LIGHTING); + GL11.glDisable(GL11.GL_CULL_FACE); + + EntityLivingBase living = (EntityLivingBase) entity; + byte armor = living.getDataWatcher().getWatchableObjectByte(17); + //MainRegistry.proxy.displayTooltip("" + limbSwingAmount, 999); + + double walkCycle = limbSwing; + + double speed = 100000D; + double chewing = 200000D; + double cy0 = Math.sin(walkCycle % (Math.PI * 2)); + double cy1 = Math.sin(walkCycle % (Math.PI * 2) - Math.PI * 0.5); + double cy2 = Math.sin(walkCycle % (Math.PI * 2) - Math.PI); + double cy3 = Math.sin(walkCycle % (Math.PI * 2) - Math.PI * 0.75); + + double bite = MathHelper.clamp_double(Math.sin(this.bite * Math.PI * 2 - Math.PI * 0.5), 0, 1) * 20; + double headTilt = Math.sin(this.bite * Math.PI) * 30; + + ResourceManager.glyphid.renderPart("Body"); + if((armor & (1 << 0)) > 0) ResourceManager.glyphid.renderPart("ArmorFront"); + if((armor & (1 << 1)) > 0) ResourceManager.glyphid.renderPart("ArmorLeft"); + if((armor & (1 << 2)) > 0) ResourceManager.glyphid.renderPart("ArmorRight"); + + /// LEFT ARM /// + GL11.glPushMatrix(); + GL11.glTranslated(0.25, 0.625, 0.0625); + GL11.glRotated(10, 0, 1, 0); + GL11.glRotated(35 + cy1 * 20, 1, 0, 0); + GL11.glTranslated(-0.25, -0.625, -0.0625); + ResourceManager.glyphid.renderPart("ArmLeftUpper"); + GL11.glTranslated(0.25, 0.625, 0.4375); + GL11.glRotated(-75 - cy1 * 20 + cy0 * 20, 1, 0, 0); + GL11.glTranslated(-0.25, -0.625, -0.4375); + ResourceManager.glyphid.renderPart("ArmLeftMid"); + GL11.glTranslated(0.25, 0.625, 0.9375); + GL11.glRotated(90 - cy0 * 45, 1, 0, 0); + GL11.glTranslated(-0.25, -0.625, -0.9375); + ResourceManager.glyphid.renderPart("ArmLeftLower"); + if((armor & (1 << 3)) > 0) ResourceManager.glyphid.renderPart("ArmLeftArmor"); + GL11.glPopMatrix(); + + /// RIGHT ARM /// + GL11.glPushMatrix(); + GL11.glTranslated(-0.25, 0.625, 0.0625); + GL11.glRotated(-10, 0, 1, 0); + GL11.glRotated(35 + cy2 * 20, 1, 0, 0); + GL11.glTranslated(0.25, -0.625, -0.0625); + ResourceManager.glyphid.renderPart("ArmRightUpper"); + GL11.glTranslated(-0.25, 0.625, 0.4375); + GL11.glRotated(-75 - cy2 * 20 + cy3 * 20, 1, 0, 0); + GL11.glTranslated(0.25, -0.625, -0.4375); + ResourceManager.glyphid.renderPart("ArmRightMid"); + GL11.glTranslated(-0.25, 0.625, 0.9375); + GL11.glRotated(90 - cy3 * 45, 1, 0, 0); + GL11.glTranslated(0.25, -0.625, -0.9375); + ResourceManager.glyphid.renderPart("ArmRightLower"); + if((armor & (1 << 4)) > 0) ResourceManager.glyphid.renderPart("ArmRightArmor"); + GL11.glPopMatrix(); + + GL11.glPushMatrix(); + + GL11.glTranslated(0, 0.5, 0.25); + GL11.glRotated(headTilt, 0, 0, 1); + GL11.glTranslated(0, -0.5, -0.25); + + GL11.glPushMatrix(); + GL11.glTranslated(0, 0.5, 0.25); + GL11.glRotated(-bite, 1, 0, 0); + GL11.glTranslated(0, -0.5, -0.25); + ResourceManager.glyphid.renderPart("JawTop"); + GL11.glPopMatrix(); + + GL11.glPushMatrix(); + GL11.glTranslated(0, 0.5, 0.25); + GL11.glRotated(bite, 0, 1, 0); + GL11.glRotated(bite, 1, 0, 0); + GL11.glTranslated(0, -0.5, -0.25); + ResourceManager.glyphid.renderPart("JawLeft"); + GL11.glPopMatrix(); + + GL11.glPushMatrix(); + GL11.glTranslated(0, 0.5, 0.25); + GL11.glRotated(-bite, 0, 1, 0); + GL11.glRotated(bite, 1, 0, 0); + GL11.glTranslated(0, -0.5, -0.25); + ResourceManager.glyphid.renderPart("JawRight"); + GL11.glPopMatrix(); + GL11.glPopMatrix(); + + double steppy = 15; + double bend = 60; + + for(int i = 0; i < 3; i++) { + + double c0 = cy0 * (i == 1 ? -1 : 1); + double c1 = cy1 * (i == 1 ? -1 : 1); + + GL11.glPushMatrix(); + GL11.glTranslated(0, 0.25, 0); + GL11.glRotated(i * 30 - 15 + c0 * 7.5, 0, 1, 0); + GL11.glRotated(steppy + c1 * steppy, 0, 0, 1); + GL11.glTranslated(0, -0.25, 0); + ResourceManager.glyphid.renderPart("LegLeftUpper"); + GL11.glTranslated(0.5625, 0.25, 0); + GL11.glRotated(-bend - c1 * steppy, 0, 0, 1); + GL11.glTranslated(-0.5625, -0.25, 0); + ResourceManager.glyphid.renderPart("LegLeftLower"); + GL11.glPopMatrix(); + + GL11.glPushMatrix(); + GL11.glTranslated(0, 0.25, 0); + GL11.glRotated(i * 30 - 45 + c0 * 7.5, 0, 1, 0); + GL11.glRotated(-steppy + c1 * steppy, 0, 0, 1); + GL11.glTranslated(0, -0.25, 0); + ResourceManager.glyphid.renderPart("LegRightUpper"); + GL11.glTranslated(-0.5625, 0.25, 0); + GL11.glRotated(bend - c1 * steppy, 0, 0, 1); + GL11.glTranslated(0.5625, -0.25, 0); + ResourceManager.glyphid.renderPart("LegRightLower"); + GL11.glPopMatrix(); + } + + GL11.glPopMatrix(); + } + } +}