actually working rocket artillery

This commit is contained in:
Bob 2022-10-15 20:00:25 +02:00
parent 0c5b2bcf57
commit 6363cf4b1a
16 changed files with 380 additions and 50 deletions

View File

@ -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;

View File

@ -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();

View File

@ -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);
}

View File

@ -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)));
}
}

View File

@ -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);
}

View File

@ -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;

View File

@ -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);
}
}

View File

@ -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); }};
}
}

View File

@ -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;
}
}

View File

@ -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()];

View File

@ -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);
}};
}
}

View File

@ -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;

View File

@ -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<ItemStack> 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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 924 B

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 543 B

After

Width:  |  Height:  |  Size: 909 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 KiB

After

Width:  |  Height:  |  Size: 4.0 KiB