diff --git a/src/main/java/com/hbm/entity/projectile/EntityArtilleryRocket.java b/src/main/java/com/hbm/entity/projectile/EntityArtilleryRocket.java index 7b69f6562..41f75310e 100644 --- a/src/main/java/com/hbm/entity/projectile/EntityArtilleryRocket.java +++ b/src/main/java/com/hbm/entity/projectile/EntityArtilleryRocket.java @@ -6,6 +6,8 @@ import java.util.List; import com.hbm.entity.logic.IChunkLoader; import com.hbm.entity.projectile.rocketbehavior.IRocketSteeringBehavior; import com.hbm.entity.projectile.rocketbehavior.IRocketTargetingBehavior; +import com.hbm.entity.projectile.rocketbehavior.RocketSteeringBallisticArc; +import com.hbm.entity.projectile.rocketbehavior.RocketTargetingPredictive; import com.hbm.items.weapon.ItemAmmoHIMARS; import com.hbm.items.weapon.ItemAmmoHIMARS.HIMARSRocket; import com.hbm.main.MainRegistry; @@ -14,6 +16,7 @@ import api.hbm.entity.IRadarDetectable; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; import net.minecraft.entity.Entity; +import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.MovingObjectPosition; import net.minecraft.util.Vec3; import net.minecraft.world.ChunkCoordIntPair; @@ -27,15 +30,18 @@ public class EntityArtilleryRocket extends EntityThrowableInterp implements IChu private Ticket loaderTicket; //TODO: find satisfying solution for when an entity is unloaded and reloaded, possibly a custom entity lookup using persistent UUIDs - private Entity targetEntity = null; - private Vec3 lastTargetPos; + public Entity targetEntity = null; + public Vec3 lastTargetPos; - private IRocketTargetingBehavior targeting; - private IRocketSteeringBehavior steering; + public IRocketTargetingBehavior targeting; + public IRocketSteeringBehavior steering; public EntityArtilleryRocket(World world) { super(world); this.ignoreFrustumCheck = true; + + this.targeting = new RocketTargetingPredictive(); + this.steering = new RocketSteeringBallisticArc(); } @Override @@ -84,8 +90,16 @@ public class EntityArtilleryRocket extends EntityThrowableInterp implements IChu if(!worldObj.isRemote) { - if(this.targetEntity != null) this.targeting.recalculateTargetPosition(this, this.targetEntity); - this.steering.adjustCourse(this); + if(this.targetEntity == null) { + Vec3 delta = Vec3.createVectorHelper(this.lastTargetPos.xCoord - this.posX, this.lastTargetPos.yCoord - this.posY, this.lastTargetPos.zCoord - this.posZ); + if(delta.lengthVector() <= 15D) { + this.targeting = null; + this.steering = null; + } + } + + if(this.targeting != null && this.targetEntity != null) this.targeting.recalculateTargetPosition(this, this.targetEntity); + if(this.steering != null) this.steering.adjustCourse(this, 25D, 15D); loadNeighboringChunks((int)Math.floor(posX / 16D), (int)Math.floor(posZ / 16D)); this.getType().onUpdate(this); @@ -120,8 +134,17 @@ public class EntityArtilleryRocket extends EntityThrowableInterp implements IChu clearChunkLoader(); loadedChunks.clear(); - loadedChunks.add(new ChunkCoordIntPair(newChunkX, newChunkZ)); - loadedChunks.add(new ChunkCoordIntPair(newChunkX + (int) Math.ceil((this.posX + this.motionX) / 16D), newChunkZ + (int) Math.ceil((this.posZ + this.motionZ) / 16D))); + + int minX = Math.min(newChunkX, newChunkX + (int) Math.ceil((this.posX + this.motionX) / 16D)); + int maxX = Math.max(newChunkX, newChunkX + (int) Math.ceil((this.posX + this.motionX) / 16D)); + int minZ = Math.min(newChunkX, newChunkX + (int) Math.ceil((this.posX + this.motionX) / 16D)); + int maxZ = Math.max(newChunkZ, newChunkZ + (int) Math.ceil((this.posZ + this.motionZ) / 16D)); + + for(int x = minX; x <= maxX; x++) { + for(int z = minZ; z <= maxZ; z++) { + loadedChunks.add(new ChunkCoordIntPair(x, z)); + } + } for(ChunkCoordIntPair chunk : loadedChunks) { ForgeChunkManager.forceChunk(loaderTicket, chunk); @@ -142,6 +165,32 @@ public class EntityArtilleryRocket extends EntityThrowableInterp implements IChu } } + @Override + public void writeEntityToNBT(NBTTagCompound nbt) { + super.writeEntityToNBT(nbt); + + nbt.setDouble("targetX", this.lastTargetPos.xCoord); + nbt.setDouble("targetY", this.lastTargetPos.yCoord); + nbt.setDouble("targetZ", this.lastTargetPos.zCoord); + } + + @Override + public void readEntityFromNBT(NBTTagCompound nbt) { + super.readEntityFromNBT(nbt); + + this.lastTargetPos = Vec3.createVectorHelper(nbt.getDouble("targetX"), nbt.getDouble("targetY"), nbt.getDouble("targetZ")); + } + + @Override + protected float getAirDrag() { + return 1.0F; + } + + @Override + public double getGravityVelocity() { + return this.steering != null ? 0D : 0.01D; + } + @Override public RadarTargetType getTargetType() { return RadarTargetType.ARTILLERY; diff --git a/src/main/java/com/hbm/entity/projectile/EntityThrowableNT.java b/src/main/java/com/hbm/entity/projectile/EntityThrowableNT.java index 608f999d5..86e57240b 100644 --- a/src/main/java/com/hbm/entity/projectile/EntityThrowableNT.java +++ b/src/main/java/com/hbm/entity/projectile/EntityThrowableNT.java @@ -226,8 +226,8 @@ public abstract class EntityThrowableNT extends Entity implements IProjectile { this.prevRotationYaw += 360.0F; } - this.rotationPitch = this.prevRotationPitch + (this.rotationPitch - this.prevRotationPitch) * 0.2F; - this.rotationYaw = this.prevRotationYaw + (this.rotationYaw - this.prevRotationYaw) * 0.2F; + //this.rotationPitch = this.prevRotationPitch + (this.rotationPitch - this.prevRotationPitch) * 0.2F; + //this.rotationYaw = this.prevRotationYaw + (this.rotationYaw - this.prevRotationYaw) * 0.2F; float drag = this.getAirDrag(); double gravity = this.getGravityVelocity(); diff --git a/src/main/java/com/hbm/entity/projectile/rocketbehavior/IRocketSteeringBehavior.java b/src/main/java/com/hbm/entity/projectile/rocketbehavior/IRocketSteeringBehavior.java index eb9ef1141..659bc5fa0 100644 --- a/src/main/java/com/hbm/entity/projectile/rocketbehavior/IRocketSteeringBehavior.java +++ b/src/main/java/com/hbm/entity/projectile/rocketbehavior/IRocketSteeringBehavior.java @@ -5,5 +5,5 @@ import com.hbm.entity.projectile.EntityArtilleryRocket; public interface IRocketSteeringBehavior { /** Modifies the motion to steer towards the set target. */ - public void adjustCourse(EntityArtilleryRocket rocket); + public void adjustCourse(EntityArtilleryRocket rocket, double speed, double turnSpeed); } diff --git a/src/main/java/com/hbm/entity/projectile/rocketbehavior/RocketSteeringBallisticArc.java b/src/main/java/com/hbm/entity/projectile/rocketbehavior/RocketSteeringBallisticArc.java index c6b494fb2..6a045d021 100644 --- a/src/main/java/com/hbm/entity/projectile/rocketbehavior/RocketSteeringBallisticArc.java +++ b/src/main/java/com/hbm/entity/projectile/rocketbehavior/RocketSteeringBallisticArc.java @@ -2,10 +2,86 @@ package com.hbm.entity.projectile.rocketbehavior; import com.hbm.entity.projectile.EntityArtilleryRocket; +import net.minecraft.util.Vec3; + public class RocketSteeringBallisticArc implements IRocketSteeringBehavior { @Override - public void adjustCourse(EntityArtilleryRocket rocket) { - //TBI + public void adjustCourse(EntityArtilleryRocket rocket, double speed, double maxTurn) { + + double turnSpeed = 45; + + Vec3 direction = Vec3.createVectorHelper(rocket.motionX, rocket.motionY, rocket.motionZ).normalize(); + double horizontalMomentum = Math.sqrt(rocket.motionX * rocket.motionX + rocket.motionZ * rocket.motionZ); + Vec3 targetPos = rocket.getLastTarget(); + double deltaX = targetPos.xCoord - rocket.posX; + double deltaZ = targetPos.zCoord - rocket.posZ; + double horizontalDelta = Math.sqrt(deltaX * deltaX + deltaZ * deltaZ); + double stepsRequired = horizontalDelta / horizontalMomentum; + Vec3 target = Vec3.createVectorHelper(targetPos.xCoord - rocket.posX, targetPos.yCoord - rocket.posY, targetPos.zCoord - rocket.posZ).normalize(); + + /* the entity's angles lack precision and i lack the nerve to figure out how they're oriented */ + double rocketYaw = yaw(direction); + double rocketPitch = pitch(direction); + double targetYaw = yaw(target); + double targetPitch = pitch(target); + + boolean debug = false; + + if(debug) { + System.out.println("=== INITIAL ==="); + System.out.println("Rocket Yaw: " + rocketYaw); + System.out.println("Rocket Pitch: " + rocketPitch); + System.out.println("Target Yaw: " + targetYaw); + System.out.println("Target Pitch: " + targetPitch); + } + + turnSpeed = Math.min(maxTurn, turnSpeed / stepsRequired); + + /* ...and then we just cheat */ + if(stepsRequired <= 1) { + turnSpeed = 180D; + } + + /*if(stepsRequired > 1) { + targetPitch = rocketPitch + ((targetPitch - rocketPitch) / stepsRequired); + }*/ + + if(debug) { + System.out.println("=== ADJUSTED ==="); + System.out.println("Target Pitch: " + targetPitch); + } + + /* shortest delta of α < 180° */ + double deltaYaw = ((targetYaw - rocketYaw) + 180D) % 360D - 180D; + double deltaPitch = ((targetPitch - rocketPitch) + 180D) % 360D - 180D; + + double turnYaw = Math.min(Math.abs(deltaYaw), turnSpeed) * Math.signum(deltaYaw); + double turnPitch = Math.min(Math.abs(deltaPitch), turnSpeed) * Math.signum(deltaPitch); + + if(debug) { + System.out.println("=== RESULTS ==="); + System.out.println("Delta Yaw: " + deltaYaw); + System.out.println("Delta Pitch: " + deltaPitch); + System.out.println("Turn Yaw: " + turnYaw); + System.out.println("Turn Pitch: " + turnPitch); + } + + Vec3 velocity = Vec3.createVectorHelper(speed, 0, 0); + velocity.rotateAroundZ((float) -Math.toRadians(rocketPitch + turnPitch)); + velocity.rotateAroundY((float) Math.toRadians(rocketYaw + turnYaw + 90)); + + rocket.motionX = velocity.xCoord; + rocket.motionY = velocity.yCoord; + rocket.motionZ = velocity.zCoord; + } + + private static double yaw(Vec3 vec) { + boolean pos = vec.zCoord >= 0; + return Math.toDegrees(Math.atan(vec.xCoord / vec.zCoord)) + (pos ? 180 : 0); + } + + private static double pitch(Vec3 vec) { + return Math.toDegrees(Math.atan(vec.yCoord / Math.sqrt(vec.xCoord * vec.xCoord + vec.zCoord * vec.zCoord))); } } diff --git a/src/main/java/com/hbm/entity/projectile/rocketbehavior/RocketTargetingPredictive.java b/src/main/java/com/hbm/entity/projectile/rocketbehavior/RocketTargetingPredictive.java index 76a6131b1..a5ca5e90f 100644 --- a/src/main/java/com/hbm/entity/projectile/rocketbehavior/RocketTargetingPredictive.java +++ b/src/main/java/com/hbm/entity/projectile/rocketbehavior/RocketTargetingPredictive.java @@ -3,6 +3,7 @@ package com.hbm.entity.projectile.rocketbehavior; import com.hbm.entity.projectile.EntityArtilleryRocket; import net.minecraft.entity.Entity; +import net.minecraft.util.Vec3; /** * Basic implementation of predictive targeting. @@ -23,6 +24,10 @@ public class RocketTargetingPredictive implements IRocketTargetingBehavior { @Override public void recalculateTargetPosition(EntityArtilleryRocket rocket, Entity target) { + Vec3 speed = Vec3.createVectorHelper(rocket.motionX, rocket.motionY, rocket.motionZ); + Vec3 delta = Vec3.createVectorHelper(target.posX - rocket.posX, target.posY - rocket.posY, target.posZ - rocket.posZ); + double eta = delta.lengthVector() - speed.lengthVector(); + /* initialize with the values we already know */ double motionX = target.motionX; double motionY = target.motionY; @@ -40,11 +45,16 @@ public class RocketTargetingPredictive implements IRocketTargetingBehavior { targetMotion[19][0] = target.motionX; targetMotion[19][1] = target.motionY; targetMotion[19][2] = target.motionZ; + + if(eta <= 1) { + rocket.setTarget(target.posX, target.posY - target.yOffset + target.height * 0.5D, target.posZ); + return; + } /* generate averages and predict a new position */ - double predX = target.posX + (motionX / 20D); - double predY = target.posY - target.yOffset + target.height * 0.5D + (motionY / 20D); - double predZ = target.posZ + (motionZ / 20D); + double predX = target.posX + (motionX / 20D) * eta; + double predY = target.posY - target.yOffset + target.height * 0.5D + (motionY / 20D) * eta; + double predZ = target.posZ + (motionZ / 20D) * eta; rocket.setTarget(predX, predY, predZ); } diff --git a/src/main/java/com/hbm/inventory/gui/GUITurretHIMARS.java b/src/main/java/com/hbm/inventory/gui/GUITurretHIMARS.java index eef8d19bb..1458112b9 100644 --- a/src/main/java/com/hbm/inventory/gui/GUITurretHIMARS.java +++ b/src/main/java/com/hbm/inventory/gui/GUITurretHIMARS.java @@ -1,8 +1,13 @@ package com.hbm.inventory.gui; import com.hbm.lib.RefStrings; +import com.hbm.packet.AuxButtonPacket; +import com.hbm.packet.PacketDispatcher; import com.hbm.tileentity.turret.TileEntityTurretBaseNT; +import com.hbm.tileentity.turret.TileEntityTurretHIMARS; +import com.hbm.util.I18nUtil; +import net.minecraft.client.audio.PositionedSoundRecord; import net.minecraft.entity.player.InventoryPlayer; import net.minecraft.util.ResourceLocation; @@ -14,6 +19,35 @@ public class GUITurretHIMARS extends GUITurretBase { super(invPlayer, tedf); } + @Override + public void drawScreen(int mouseX, int mouseY, float f) { + super.drawScreen(mouseX, mouseY, f); + + TileEntityTurretHIMARS arty = (TileEntityTurretHIMARS) turret; + String mode = arty.mode == arty.MODE_AUTO ? "artillery" : "manual"; + this.drawCustomInfoStat(mouseX, mouseY, guiLeft + 151, guiTop + 16, 18, 18, mouseX, mouseY, I18nUtil.resolveKeyArray("turret.arty." + mode)); + } + + @Override + protected void mouseClicked(int x, int y, int i) { + super.mouseClicked(x, y, i); + + if(guiLeft + 151 <= x && guiLeft + 151 + 18 > x && guiTop + 16 < y && guiTop + 16 + 18 >= y) { + + mc.getSoundHandler().playSound(PositionedSoundRecord.func_147674_a(new ResourceLocation("gui.button.press"), 1.0F)); + PacketDispatcher.wrapper.sendToServer(new AuxButtonPacket(turret.xCoord, turret.yCoord, turret.zCoord, 0, 5)); + return; + } + } + + @Override + protected void drawGuiContainerBackgroundLayer(float p_146976_1_, int mX, int mY) { + super.drawGuiContainerBackgroundLayer(p_146976_1_, mX, mY); + + short mode = ((TileEntityTurretHIMARS)turret).mode; + if(mode == TileEntityTurretHIMARS.MODE_MANUAL) drawTexturedModalRect(guiLeft + 151, guiTop + 16, 210, 0, 18, 18); + } + @Override protected ResourceLocation getTexture() { return texture; diff --git a/src/main/java/com/hbm/items/tool/ItemDesignatorArtyRange.java b/src/main/java/com/hbm/items/tool/ItemDesignatorArtyRange.java index b69f70150..fed462479 100644 --- a/src/main/java/com/hbm/items/tool/ItemDesignatorArtyRange.java +++ b/src/main/java/com/hbm/items/tool/ItemDesignatorArtyRange.java @@ -2,10 +2,9 @@ package com.hbm.items.tool; import java.util.List; -import com.hbm.blocks.ModBlocks; -import com.hbm.blocks.turret.TurretArty; +import com.hbm.blocks.BlockDummyable; import com.hbm.lib.Library; -import com.hbm.tileentity.turret.TileEntityTurretArty; +import com.hbm.tileentity.turret.TileEntityTurretBaseArtillery; import net.minecraft.block.Block; import net.minecraft.entity.player.EntityPlayer; @@ -38,15 +37,15 @@ public class ItemDesignatorArtyRange extends Item { Block b = world.getBlock(x, y, z); - if(b == ModBlocks.turret_arty) { - int pos[] = ((TurretArty) b).findCore(world, x, y, z); + if(b instanceof BlockDummyable) { + int pos[] = ((BlockDummyable) b).findCore(world, x, y, z); if(pos == null) return false; TileEntity te = world.getTileEntity(pos[0], pos[1], pos[2]); - if(te instanceof TileEntityTurretArty) { + if(te instanceof TileEntityTurretBaseArtillery) { if(world.isRemote) return true; @@ -79,12 +78,10 @@ public class ItemDesignatorArtyRange extends Item { if(!world.isRemote) { TileEntity te = world.getTileEntity(stack.stackTagCompound.getInteger("x"), stack.stackTagCompound.getInteger("y"), stack.stackTagCompound.getInteger("z")); - if(te instanceof TileEntityTurretArty) { - TileEntityTurretArty arty = (TileEntityTurretArty) te; - if(arty.mode == arty.MODE_MANUAL) { - arty.enqueueTarget(x + 0.5, y + 0.5, z + 0.5); - world.playSoundAtEntity(player, "hbm:item.techBoop", 1.0F, 1.0F); - } + if(te instanceof TileEntityTurretBaseArtillery) { + TileEntityTurretBaseArtillery arty = (TileEntityTurretBaseArtillery) te; + arty.enqueueTarget(x + 0.5, y + 0.5, z + 0.5); + world.playSoundAtEntity(player, "hbm:item.techBoop", 1.0F, 1.0F); } } diff --git a/src/main/java/com/hbm/items/weapon/ItemAmmoHIMARS.java b/src/main/java/com/hbm/items/weapon/ItemAmmoHIMARS.java index 4ef729c71..4809a7c80 100644 --- a/src/main/java/com/hbm/items/weapon/ItemAmmoHIMARS.java +++ b/src/main/java/com/hbm/items/weapon/ItemAmmoHIMARS.java @@ -42,14 +42,21 @@ public class ItemAmmoHIMARS extends Item { list.add(new ItemStack(item, 1, LARGE)); } + @Override + public String getUnlocalizedName(ItemStack stack) { + return "item.ammo_himars_" + itemTypes[Math.abs(stack.getItemDamage()) % itemTypes.length].name; + } + public abstract class HIMARSRocket { + public final String name; public final ResourceLocation texture; public final int amount; public final int modelType; /* 0 = sixfold/standard ; 1 = single */ - public HIMARSRocket(String name, int type, int amount) { - this.texture = new ResourceLocation(RefStrings.MODID + ":textures/models/projectiles/" + name + ".png"); + public HIMARSRocket(String name, String texture, int type, int amount) { + this.name = name; + this.texture = new ResourceLocation(RefStrings.MODID + ":textures/models/projectiles/" + texture + ".png"); this.amount = amount; this.modelType = type; } @@ -75,7 +82,7 @@ public class ItemAmmoHIMARS extends Item { private void init() { /* STANDARD ROCKETS */ - this.itemTypes[SMALL] = new HIMARSRocket("himars_standard", 0, 6) { public void onImpact(EntityArtilleryRocket rocket, MovingObjectPosition mop) { standardExplosion(rocket, mop, 25F, 3F, true); }}; - this.itemTypes[LARGE] = new HIMARSRocket("himars_single", 1, 1) { public void onImpact(EntityArtilleryRocket rocket, MovingObjectPosition mop) { standardExplosion(rocket, mop, 50F, 5F, true); }}; + this.itemTypes[SMALL] = new HIMARSRocket("standard", "himars_standard", 0, 6) { public void onImpact(EntityArtilleryRocket rocket, MovingObjectPosition mop) { standardExplosion(rocket, mop, 25F, 3F, true); }}; + this.itemTypes[LARGE] = new HIMARSRocket("single", "himars_single", 1, 1) { public void onImpact(EntityArtilleryRocket rocket, MovingObjectPosition mop) { standardExplosion(rocket, mop, 50F, 5F, true); }}; } } diff --git a/src/main/java/com/hbm/render/entity/projectile/RenderArtilleryRocket.java b/src/main/java/com/hbm/render/entity/projectile/RenderArtilleryRocket.java index 229a71e46..0b4b3d2d4 100644 --- a/src/main/java/com/hbm/render/entity/projectile/RenderArtilleryRocket.java +++ b/src/main/java/com/hbm/render/entity/projectile/RenderArtilleryRocket.java @@ -2,7 +2,9 @@ package com.hbm.render.entity.projectile; import org.lwjgl.opengl.GL11; +import com.hbm.entity.projectile.EntityArtilleryRocket; import com.hbm.items.weapon.ItemAmmoHIMARS; +import com.hbm.items.weapon.ItemAmmoHIMARS.HIMARSRocket; import com.hbm.main.ResourceManager; import net.minecraft.client.renderer.entity.Render; @@ -12,20 +14,25 @@ import net.minecraft.util.ResourceLocation; public class RenderArtilleryRocket extends Render { @Override - public void doRender(Entity shell, double x, double y, double z, float f0, float f1) { + public void doRender(Entity entity, double x, double y, double z, float f0, float f1) { GL11.glPushMatrix(); GL11.glTranslated(x, y, z); - GL11.glRotatef(shell.prevRotationYaw + (shell.rotationYaw - shell.prevRotationYaw) * f1 - 90.0F, 0.0F, 1.0F, 0.0F); - GL11.glRotatef(shell.prevRotationPitch + (shell.rotationPitch - shell.prevRotationPitch) * f1 - 90, 0.0F, 0.0F, 1.0F); + GL11.glRotatef(entity.prevRotationYaw + (entity.rotationYaw - entity.prevRotationYaw) * f1 - 90.0F, 0.0F, 1.0F, 0.0F); + GL11.glRotatef(entity.prevRotationPitch + (entity.rotationPitch - entity.prevRotationPitch) * f1 - 90, 0.0F, 0.0F, 1.0F); + GL11.glRotated(90, 0, 1, 0); + GL11.glRotated(90, 1, 0, 0); - this.bindEntityTexture(shell); + this.bindEntityTexture(entity); boolean fog = GL11.glIsEnabled(GL11.GL_FOG); if(fog) GL11.glDisable(GL11.GL_FOG); GL11.glShadeModel(GL11.GL_SMOOTH); - ResourceManager.turret_himars.renderPart("RocketStandard"); + EntityArtilleryRocket rocket = (EntityArtilleryRocket) entity; + HIMARSRocket type = rocket.getType(); + if(type.modelType == 0) ResourceManager.turret_himars.renderPart("RocketStandard"); + if(type.modelType == 1) ResourceManager.turret_himars.renderPart("RocketSingle"); GL11.glShadeModel(GL11.GL_FLAT); if(fog) GL11.glEnable(GL11.GL_FOG); @@ -34,6 +41,7 @@ public class RenderArtilleryRocket extends Render { @Override protected ResourceLocation getEntityTexture(Entity entity) { - return ItemAmmoHIMARS.itemTypes[0].texture; + EntityArtilleryRocket rocket = (EntityArtilleryRocket) entity; + return ItemAmmoHIMARS.itemTypes[rocket.getDataWatcher().getWatchableObjectInt(10)].texture; } } diff --git a/src/main/java/com/hbm/render/item/ItemRenderLibrary.java b/src/main/java/com/hbm/render/item/ItemRenderLibrary.java index 15378e952..56032d009 100644 --- a/src/main/java/com/hbm/render/item/ItemRenderLibrary.java +++ b/src/main/java/com/hbm/render/item/ItemRenderLibrary.java @@ -1360,10 +1360,12 @@ public class ItemRenderLibrary { renderers.put(ModItems.ammo_himars, new ItemRenderBase( ) { public void renderInventory() { - GL11.glTranslated(0, 2.5, 0); + GL11.glTranslated(0, -2.5, 0); GL11.glScaled(4, 4, 4); + GL11.glRotated(System.currentTimeMillis() % 3600 / 10D, 0, 1, 0); } public void renderCommonWithStack(ItemStack item) { + GL11.glTranslated(0, 1.5, 0); GL11.glRotated(-45, 0, 1, 0); GL11.glRotated(90, 1, 0, 0); HIMARSRocket type = ItemAmmoHIMARS.itemTypes[item.getItemDamage()]; diff --git a/src/main/java/com/hbm/render/tileentity/RenderTurretHIMARS.java b/src/main/java/com/hbm/render/tileentity/RenderTurretHIMARS.java index e5215764c..8acb27dac 100644 --- a/src/main/java/com/hbm/render/tileentity/RenderTurretHIMARS.java +++ b/src/main/java/com/hbm/render/tileentity/RenderTurretHIMARS.java @@ -3,6 +3,8 @@ package com.hbm.render.tileentity; import org.lwjgl.opengl.GL11; import com.hbm.blocks.ModBlocks; +import com.hbm.items.weapon.ItemAmmoHIMARS; +import com.hbm.items.weapon.ItemAmmoHIMARS.HIMARSRocket; import com.hbm.main.ResourceManager; import com.hbm.render.item.ItemRenderBase; import com.hbm.tileentity.turret.TileEntityTurretHIMARS; @@ -41,12 +43,33 @@ public class RenderTurretHIMARS extends TileEntitySpecialRenderer implements IIt GL11.glRotated(pitch, 1, 0, 0); GL11.glTranslated(0, -2.25, -2); ResourceManager.turret_himars.renderPart("Launcher"); + + double barrel = turret.lastCrane + (turret.crane - turret.lastCrane) * interp; + double length = -5D; + GL11.glTranslated(0, 0, barrel * length); ResourceManager.turret_himars.renderPart("Crane"); - bindTexture(ResourceManager.himars_standard_tex); - ResourceManager.turret_himars.renderPart("TubeStandard"); - /*ResourceManager.turret_himars.renderPart("CapStandard1"); - ResourceManager.turret_himars.renderPart("CapStandard2"); - ResourceManager.turret_himars.renderPart("CapStandard4");*/ + + if(turret.typeLoaded >= 0) { + HIMARSRocket type = ItemAmmoHIMARS.itemTypes[turret.typeLoaded]; + + if(type.modelType == 0) { + bindTexture(ResourceManager.himars_standard_tex); + ResourceManager.turret_himars.renderPart("TubeStandard"); + + for(int i = 0; i < turret.ammo; i++) { + ResourceManager.turret_himars.renderPart("CapStandard" + (5 - i + 1)); + } + } + + if(type.modelType == 1) { + bindTexture(ResourceManager.himars_single_tex); + ResourceManager.turret_himars.renderPart("TubeSingle"); + + if(turret.hasAmmo()) { + ResourceManager.turret_himars.renderPart("CapSingle"); + } + } + } GL11.glShadeModel(GL11.GL_FLAT); GL11.glPopMatrix(); @@ -67,6 +90,7 @@ public class RenderTurretHIMARS extends TileEntitySpecialRenderer implements IIt public void renderCommonWithStack(ItemStack item) { GL11.glRotatef(-90, 0F, 1F, 0F); GL11.glScaled(0.5, 0.5, 0.5); + GL11.glShadeModel(GL11.GL_SMOOTH); bindTexture(ResourceManager.turret_arty_tex); ResourceManager.turret_arty.renderPart("Base"); bindTexture(ResourceManager.turret_himars_tex); @@ -75,6 +99,7 @@ public class RenderTurretHIMARS extends TileEntitySpecialRenderer implements IIt ResourceManager.turret_himars.renderPart("Crane"); bindTexture(ResourceManager.himars_standard_tex); ResourceManager.turret_himars.renderPart("TubeStandard"); + GL11.glShadeModel(GL11.GL_FLAT); }}; } } diff --git a/src/main/java/com/hbm/tileentity/machine/TileEntityCrucible.java b/src/main/java/com/hbm/tileentity/machine/TileEntityCrucible.java index 071b5bc5b..2f6a15989 100644 --- a/src/main/java/com/hbm/tileentity/machine/TileEntityCrucible.java +++ b/src/main/java/com/hbm/tileentity/machine/TileEntityCrucible.java @@ -356,6 +356,12 @@ public class TileEntityCrucible extends TileEntityMachineBase implements IGUIPro //if no recipe is loaded, everything will land in the waste stack int recipeInputRequired = recipe != null ? getQuantaFromType(recipe.input, mat.material) : 0; + //this allows pouring the ouput material back into the crucible + if(recipe != null && getQuantaFromType(recipe.output, mat.material) > 0) { + recipeAmount += mat.amount; + continue; + } + if(recipeInputRequired == 0) { //if this type isn't required by the recipe, add it to the waste stack wasteAmount += mat.amount; diff --git a/src/main/java/com/hbm/tileentity/turret/TileEntityTurretHIMARS.java b/src/main/java/com/hbm/tileentity/turret/TileEntityTurretHIMARS.java index 1bb2d49c9..58c0afe31 100644 --- a/src/main/java/com/hbm/tileentity/turret/TileEntityTurretHIMARS.java +++ b/src/main/java/com/hbm/tileentity/turret/TileEntityTurretHIMARS.java @@ -3,9 +3,12 @@ package com.hbm.tileentity.turret; import java.util.ArrayList; import java.util.List; +import com.hbm.entity.projectile.EntityArtilleryRocket; import com.hbm.inventory.container.ContainerTurretBase; import com.hbm.inventory.gui.GUITurretHIMARS; import com.hbm.items.ModItems; +import com.hbm.items.weapon.ItemAmmoHIMARS; +import com.hbm.items.weapon.ItemAmmoHIMARS.HIMARSRocket; import com.hbm.lib.Library; import com.hbm.main.MainRegistry; import com.hbm.tileentity.IGUIProvider; @@ -17,15 +20,21 @@ import net.minecraft.entity.player.EntityPlayer; import net.minecraft.inventory.Container; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.MathHelper; import net.minecraft.util.Vec3; import net.minecraft.world.World; public class TileEntityTurretHIMARS extends TileEntityTurretBaseArtillery implements IGUIProvider { public short mode = 0; - public static final short MODE_AUOT = 0; + public static final short MODE_AUTO = 0; public static final short MODE_MANUAL = 1; + public int typeLoaded = -1; + public int ammo = 0; + public float crane; + public float lastCrane; + @Override @SideOnly(Side.CLIENT) public List getAmmoTypesForDisplay() { @@ -36,7 +45,7 @@ public class TileEntityTurretHIMARS extends TileEntityTurretBaseArtillery implem ammoStacks = new ArrayList(); List list = new ArrayList(); - ModItems.ammo_arty.getSubItems(ModItems.ammo_arty, MainRegistry.weaponTab, list); + ModItems.ammo_himars.getSubItems(ModItems.ammo_himars, MainRegistry.weaponTab, list); this.ammoStacks.addAll(list); return ammoStacks; @@ -109,9 +118,24 @@ public class TileEntityTurretHIMARS extends TileEntityTurretBaseArtillery implem this.turnTowardsAngle(targetPitch, targetYaw); } + public int getSpareRocket() { + + for(int i = 1; i < 10; i++) { + if(slots[i] != null) { + if(slots[i].getItem() == ModItems.ammo_himars) { + return slots[i].getItemDamage(); + } + } + } + + return -1; + } + @Override public void updateEntity() { + this.lastCrane = this.crane; + if(this.mode == this.MODE_MANUAL) { if(!this.targetQueue.isEmpty()) { this.tPos = this.targetQueue.get(0); @@ -156,8 +180,39 @@ public class TileEntityTurretHIMARS extends TileEntityTurretBaseArtillery implem if(isOn() && hasPower()) { - if(tPos != null) - this.alignTurret(); + if(!this.hasAmmo() || this.crane > 0) { + + this.turnTowardsAngle(0, this.rotationYaw); + + if(this.aligned) { + + if(this.hasAmmo()) { + this.crane -= 0.0125F; + } else { + this.crane += 0.0125F; + + if(this.crane >= 1F && !worldObj.isRemote) { + int available = this.getSpareRocket(); + + if(available != -1) { + HIMARSRocket type = ItemAmmoHIMARS.itemTypes[available]; + this.typeLoaded = available; + this.ammo = type.amount; + this.conusmeAmmo(ModItems.ammo_himars); + } + } + } + } + + this.crane = MathHelper.clamp_float(this.crane, 0F, 1F); + + } else { + + if(tPos != null) { + this.alignTurret(); + } + } + } else { this.target = null; @@ -187,7 +242,7 @@ public class TileEntityTurretHIMARS extends TileEntityTurretBaseArtillery implem searchTimer = 0; } - if(this.aligned) { + if(this.aligned && crane <= 0) { this.updateFiringTick(); } @@ -213,9 +268,70 @@ public class TileEntityTurretHIMARS extends TileEntityTurretBaseArtillery implem } } + @Override + protected NBTTagCompound writePacket() { + NBTTagCompound data = super.writePacket(); + data.setShort("mode", this.mode); + data.setInteger("type", this.typeLoaded); + data.setInteger("ammo", this.ammo); + return data; + } + + @Override + public void networkUnpack(NBTTagCompound nbt) { + super.networkUnpack(nbt); + this.mode = nbt.getShort("mode"); + this.typeLoaded = nbt.getShort("type"); + this.ammo = nbt.getInteger("ammo"); + } + + public boolean hasAmmo() { + return this.typeLoaded >= 0 && this.ammo > 0; + } + + int timer; + @Override public void updateFiringTick() { - // *chirp* *chirp* *chirp* + + timer++; + + int delay = 40; + + if(timer % delay == 0) { + + if(this.hasAmmo() && this.tPos != null) { + this.spawnShell(this.typeLoaded); + this.ammo--; + this.worldObj.playSoundEffect(xCoord, yCoord, zCoord, "hbm:turret.jeremy_fire", 25.0F, 1.0F); + } + + if(this.mode == this.MODE_MANUAL && !this.targetQueue.isEmpty()) { + this.targetQueue.remove(0); + this.tPos = null; + } + } + } + + public void spawnShell(int type) { + + Vec3 pos = this.getTurretPos(); + Vec3 vec = Vec3.createVectorHelper(this.getBarrelLength(), 0, 0); + vec.rotateAroundZ((float) -this.rotationPitch); + vec.rotateAroundY((float) -(this.rotationYaw + Math.PI * 0.5)); + + EntityArtilleryRocket proj = new EntityArtilleryRocket(worldObj); + proj.setPositionAndRotation(pos.xCoord + vec.xCoord, pos.yCoord + vec.yCoord, pos.zCoord + vec.zCoord, 0.0F, 0.0F); + proj.setThrowableHeading(vec.xCoord, vec.yCoord, vec.zCoord, 25F, 0.0F); + + if(this.target != null) + proj.setTarget(this.target); + else + proj.setTarget(tPos.xCoord, tPos.yCoord, tPos.zCoord); + + proj.setType(type); + + worldObj.spawnEntityInWorld(proj); } @Override diff --git a/src/main/resources/assets/hbm/textures/models/projectiles/himars_single.png b/src/main/resources/assets/hbm/textures/models/projectiles/himars_single.png index 2f97a307d..0e5dee8d7 100644 Binary files a/src/main/resources/assets/hbm/textures/models/projectiles/himars_single.png and b/src/main/resources/assets/hbm/textures/models/projectiles/himars_single.png differ diff --git a/src/main/resources/assets/hbm/textures/models/projectiles/himars_standard.png b/src/main/resources/assets/hbm/textures/models/projectiles/himars_standard.png index 79604841b..54a00f7df 100644 Binary files a/src/main/resources/assets/hbm/textures/models/projectiles/himars_standard.png and b/src/main/resources/assets/hbm/textures/models/projectiles/himars_standard.png differ diff --git a/src/main/resources/assets/hbm/textures/models/turrets/himars.png b/src/main/resources/assets/hbm/textures/models/turrets/himars.png index 55a0416c3..5b625e303 100644 Binary files a/src/main/resources/assets/hbm/textures/models/turrets/himars.png and b/src/main/resources/assets/hbm/textures/models/turrets/himars.png differ