mirror of
https://github.com/HbmMods/Hbm-s-Nuclear-Tech-GIT.git
synced 2026-01-25 10:32:49 +00:00
artillery rocket behavior
This commit is contained in:
parent
52a8c0df77
commit
00b6ef249e
@ -2901,7 +2901,7 @@ public class ModBlocks {
|
||||
GameRegistry.registerBlock(turret_fritz, turret_fritz.getUnlocalizedName());
|
||||
GameRegistry.registerBlock(turret_brandon, turret_brandon.getUnlocalizedName());
|
||||
GameRegistry.registerBlock(turret_arty, turret_arty.getUnlocalizedName());
|
||||
//GameRegistry.registerBlock(turret_himars, turret_himars.getUnlocalizedName());
|
||||
GameRegistry.registerBlock(turret_himars, turret_himars.getUnlocalizedName());
|
||||
|
||||
//Wall-mounted Explosives
|
||||
GameRegistry.registerBlock(charge_dynamite, ItemBlockBase.class, charge_dynamite.getUnlocalizedName());
|
||||
|
||||
@ -1,10 +1,21 @@
|
||||
package com.hbm.entity.projectile;
|
||||
|
||||
import java.util.ArrayList;
|
||||
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.items.weapon.ItemAmmoHIMARS;
|
||||
import com.hbm.items.weapon.ItemAmmoHIMARS.HIMARSRocket;
|
||||
import com.hbm.main.MainRegistry;
|
||||
|
||||
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.util.MovingObjectPosition;
|
||||
import net.minecraft.util.Vec3;
|
||||
import net.minecraft.world.ChunkCoordIntPair;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.common.ForgeChunkManager;
|
||||
@ -15,6 +26,13 @@ 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;
|
||||
|
||||
private IRocketTargetingBehavior targeting;
|
||||
private IRocketSteeringBehavior steering;
|
||||
|
||||
public EntityArtilleryRocket(World world) {
|
||||
super(world);
|
||||
this.ignoreFrustumCheck = true;
|
||||
@ -25,15 +43,61 @@ public class EntityArtilleryRocket extends EntityThrowableInterp implements IChu
|
||||
init(ForgeChunkManager.requestTicket(MainRegistry.instance, worldObj, Type.ENTITY));
|
||||
this.dataWatcher.addObject(10, new Integer(0));
|
||||
}
|
||||
|
||||
@Override
|
||||
@SideOnly(Side.CLIENT)
|
||||
public boolean isInRangeToRenderDist(double distance) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public EntityArtilleryRocket setType(int type) {
|
||||
this.dataWatcher.updateObject(10, type);
|
||||
return this;
|
||||
}
|
||||
|
||||
public HIMARSRocket getType() {
|
||||
try {
|
||||
return ItemAmmoHIMARS.itemTypes[this.dataWatcher.getWatchableObjectInt(10)];
|
||||
} catch(Exception ex) {
|
||||
return ItemAmmoHIMARS.itemTypes[0];
|
||||
}
|
||||
}
|
||||
|
||||
public EntityArtilleryRocket setTarget(Entity target) {
|
||||
this.targetEntity = target;
|
||||
setTarget(target.posX, target.posY - target.yOffset + target.height / 2D, target.posZ);
|
||||
return this;
|
||||
}
|
||||
|
||||
public EntityArtilleryRocket setTarget(double x, double y, double z) {
|
||||
this.lastTargetPos = Vec3.createVectorHelper(x, y, z);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Vec3 getLastTarget() {
|
||||
return this.lastTargetPos;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpdate() {
|
||||
super.onUpdate();
|
||||
|
||||
if(!worldObj.isRemote) {
|
||||
|
||||
if(this.targetEntity != null) this.targeting.recalculateTargetPosition(this, this.targetEntity);
|
||||
this.steering.adjustCourse(this);
|
||||
|
||||
loadNeighboringChunks((int)Math.floor(posX / 16D), (int)Math.floor(posZ / 16D));
|
||||
this.getType().onUpdate(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onImpact(MovingObjectPosition mop) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public RadarTargetType getTargetType() {
|
||||
return RadarTargetType.ARTILLERY;
|
||||
if(!worldObj.isRemote) {
|
||||
this.getType().onImpact(this, mop);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -47,4 +111,39 @@ public class EntityArtilleryRocket extends EntityThrowableInterp implements IChu
|
||||
ForgeChunkManager.forceChunk(loaderTicket, new ChunkCoordIntPair(chunkCoordX, chunkCoordZ));
|
||||
}
|
||||
}
|
||||
|
||||
List<ChunkCoordIntPair> loadedChunks = new ArrayList<ChunkCoordIntPair>();
|
||||
|
||||
public void loadNeighboringChunks(int newChunkX, int newChunkZ) {
|
||||
if(!worldObj.isRemote && loaderTicket != null) {
|
||||
|
||||
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)));
|
||||
|
||||
for(ChunkCoordIntPair chunk : loadedChunks) {
|
||||
ForgeChunkManager.forceChunk(loaderTicket, chunk);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void killAndClear() {
|
||||
this.setDead();
|
||||
this.clearChunkLoader();
|
||||
}
|
||||
|
||||
public void clearChunkLoader() {
|
||||
if(!worldObj.isRemote && loaderTicket != null) {
|
||||
for(ChunkCoordIntPair chunk : loadedChunks) {
|
||||
ForgeChunkManager.unforceChunk(loaderTicket, chunk);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public RadarTargetType getTargetType() {
|
||||
return RadarTargetType.ARTILLERY;
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,9 @@
|
||||
package com.hbm.entity.projectile.rocketbehavior;
|
||||
|
||||
import com.hbm.entity.projectile.EntityArtilleryRocket;
|
||||
|
||||
public interface IRocketSteeringBehavior {
|
||||
|
||||
/** Modifies the motion to steer towards the set target. */
|
||||
public void adjustCourse(EntityArtilleryRocket rocket);
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
package com.hbm.entity.projectile.rocketbehavior;
|
||||
|
||||
import com.hbm.entity.projectile.EntityArtilleryRocket;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
|
||||
public interface IRocketTargetingBehavior {
|
||||
|
||||
/** Recalculates the position that should be steered towards. */
|
||||
public void recalculateTargetPosition(EntityArtilleryRocket rocket, Entity target);
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
package com.hbm.entity.projectile.rocketbehavior;
|
||||
|
||||
import com.hbm.entity.projectile.EntityArtilleryRocket;
|
||||
|
||||
public class RocketSteeringBallisticArc implements IRocketSteeringBehavior {
|
||||
|
||||
@Override
|
||||
public void adjustCourse(EntityArtilleryRocket rocket) {
|
||||
//TBI
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,51 @@
|
||||
package com.hbm.entity.projectile.rocketbehavior;
|
||||
|
||||
import com.hbm.entity.projectile.EntityArtilleryRocket;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
|
||||
/**
|
||||
* Basic implementation of predictive targeting.
|
||||
* My current best guess for "smart" targeting
|
||||
* Keeps a buffer of the last second's velocity values and generates a predicted target based on the average speed.
|
||||
* @author hbm
|
||||
*/
|
||||
public class RocketTargetingPredictive implements IRocketTargetingBehavior {
|
||||
|
||||
/*
|
||||
* unlikely to work for things that move extremely erratically and quickly,
|
||||
* but there's barely any cases where that would apply.
|
||||
* a single second of prediction is good enough at long distances where there's
|
||||
* still room for error, like player vehicles or ICBMs.
|
||||
*/
|
||||
private double[][] targetMotion = new double[20][3];
|
||||
|
||||
@Override
|
||||
public void recalculateTargetPosition(EntityArtilleryRocket rocket, Entity target) {
|
||||
|
||||
/* initialize with the values we already know */
|
||||
double motionX = target.motionX;
|
||||
double motionY = target.motionY;
|
||||
double motionZ = target.motionZ;
|
||||
|
||||
/* shift the buffer and add the older values */
|
||||
for(int i = 1; i < 20; i++) {
|
||||
targetMotion[i - 1] = targetMotion[i];
|
||||
motionX += targetMotion[i][0];
|
||||
motionY += targetMotion[i][1];
|
||||
motionZ += targetMotion[i][2];
|
||||
}
|
||||
|
||||
/* push the new values to the buffer for future use */
|
||||
targetMotion[19][0] = target.motionX;
|
||||
targetMotion[19][1] = target.motionY;
|
||||
targetMotion[19][2] = target.motionZ;
|
||||
|
||||
/* 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);
|
||||
|
||||
rocket.setTarget(predX, predY, predZ);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,17 @@
|
||||
package com.hbm.entity.projectile.rocketbehavior;
|
||||
|
||||
import com.hbm.entity.projectile.EntityArtilleryRocket;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
|
||||
/**
|
||||
* "Stupid targeting for rockets, they move straight towards the target's current position"
|
||||
* @author hbm
|
||||
*/
|
||||
public class RocketTargetingSimple implements IRocketTargetingBehavior {
|
||||
|
||||
@Override
|
||||
public void recalculateTargetPosition(EntityArtilleryRocket rocket, Entity target) {
|
||||
rocket.setTarget(target.posX, target.posY - target.yOffset + target.height * 0.5D, target.posZ);
|
||||
}
|
||||
}
|
||||
@ -2,16 +2,24 @@ package com.hbm.items.weapon;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.hbm.entity.projectile.EntityArtilleryRocket;
|
||||
import com.hbm.explosion.vanillant.ExplosionVNT;
|
||||
import com.hbm.explosion.vanillant.standard.BlockAllocatorStandard;
|
||||
import com.hbm.explosion.vanillant.standard.BlockProcessorStandard;
|
||||
import com.hbm.explosion.vanillant.standard.EntityProcessorStandard;
|
||||
import com.hbm.explosion.vanillant.standard.ExplosionEffectStandard;
|
||||
import com.hbm.explosion.vanillant.standard.PlayerProcessorStandard;
|
||||
import com.hbm.lib.RefStrings;
|
||||
import com.hbm.main.MainRegistry;
|
||||
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
import net.minecraft.creativetab.CreativeTabs;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.MovingObjectPosition;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.Vec3;
|
||||
|
||||
public class ItemAmmoHIMARS extends Item {
|
||||
|
||||
@ -36,21 +44,40 @@ public class ItemAmmoHIMARS extends Item {
|
||||
|
||||
public abstract class HIMARSRocket {
|
||||
|
||||
String name;
|
||||
ResourceLocation texture;
|
||||
int amount;
|
||||
int modelType; /* 0 = sixfold/standard ; 1 = single */
|
||||
|
||||
public HIMARSRocket() { }
|
||||
|
||||
public HIMARSRocket(String name) {
|
||||
this.name = name;
|
||||
public HIMARSRocket(String name, int type, int amount) {
|
||||
this.texture = new ResourceLocation(RefStrings.MODID + ":textures/models/projectiles/" + name);
|
||||
this.amount = amount;
|
||||
this.modelType = type;
|
||||
}
|
||||
|
||||
public abstract void onImpact(Entity rocket, MovingObjectPosition mop);
|
||||
public void onUpdate(Entity rocket) { }
|
||||
public abstract void onImpact(EntityArtilleryRocket rocket, MovingObjectPosition mop);
|
||||
public void onUpdate(EntityArtilleryRocket rocket) { }
|
||||
}
|
||||
|
||||
public static void standardExplosion(EntityArtilleryRocket rocket, MovingObjectPosition mop, float size, float rangeMod, boolean breaksBlocks) {
|
||||
rocket.worldObj.playSoundEffect(rocket.posX, rocket.posY, rocket.posZ, "hbm:weapon.explosionMedium", 20.0F, 0.9F + rocket.worldObj.rand.nextFloat() * 0.2F);
|
||||
Vec3 vec = Vec3.createVectorHelper(rocket.motionX, rocket.motionY, rocket.motionZ).normalize();
|
||||
ExplosionVNT xnt = new ExplosionVNT(rocket.worldObj, mop.hitVec.xCoord - vec.xCoord, mop.hitVec.yCoord - vec.yCoord, mop.hitVec.zCoord - vec.zCoord, size);
|
||||
if(breaksBlocks) {
|
||||
xnt.setBlockAllocator(new BlockAllocatorStandard(48));
|
||||
xnt.setBlockProcessor(new BlockProcessorStandard().setNoDrop());
|
||||
}
|
||||
xnt.setEntityProcessor(new EntityProcessorStandard().withRangeMod(rangeMod));
|
||||
xnt.setPlayerProcessor(new PlayerProcessorStandard());
|
||||
xnt.setSFX(new ExplosionEffectStandard());
|
||||
xnt.explode();
|
||||
rocket.killAndClear();
|
||||
}
|
||||
|
||||
private void init() {
|
||||
/* STANDARD SHELLS */
|
||||
this.itemTypes[SMALL] = new HIMARSRocket("ammo_himars") { public void onImpact(Entity rocket, MovingObjectPosition mop) { }};
|
||||
this.itemTypes[LARGE] = new HIMARSRocket("ammo_himars_large") { public void onImpact(Entity rocket, MovingObjectPosition mop) { }};
|
||||
/* 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); }};
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user