mirror of
https://github.com/HbmMods/Hbm-s-Nuclear-Tech-GIT.git
synced 2026-01-25 10:32:49 +00:00
Gun firing AI improvements and skeletons are only given guns when soot is high enough, higher soot adds more powerful weapons
This commit is contained in:
parent
b6bab36c7f
commit
5103577f1d
@ -13,72 +13,124 @@ import net.minecraft.item.ItemStack;
|
||||
|
||||
public class EntityAIFireGun extends EntityAIBase {
|
||||
|
||||
private final EntityLiving host;
|
||||
private final EntityLiving host;
|
||||
|
||||
private double attackMoveSpeed = 1.0D;
|
||||
private double attackMoveSpeed = 1.0D; // how fast we move while in this state
|
||||
private double maxRange = 20; // how far our target can be before we stop shooting
|
||||
private int burstTime = 6; // maximum number of ticks in a burst (for automatic weapons)
|
||||
private int minWait = 10; // minimum number of ticks to wait between bursts/shots
|
||||
private int maxWait = 60; // maximum number of ticks to wait between bursts/shots
|
||||
private float inaccuracy = 30; // how many degrees of inaccuracy does the AI have
|
||||
|
||||
private int attackTimer = 0;
|
||||
private double maxRange = 20;
|
||||
|
||||
public EntityAIFireGun(EntityLiving host) {
|
||||
this.host = host;
|
||||
}
|
||||
// state timers
|
||||
private int attackTimer = 0;
|
||||
private FireState state = FireState.IDLE;
|
||||
private int stateTimer = 0;
|
||||
|
||||
@Override
|
||||
public boolean shouldExecute() {
|
||||
return host.getAttackTarget() != null && getYerGun() != null;
|
||||
}
|
||||
private static enum FireState {
|
||||
IDLE,
|
||||
WAIT,
|
||||
FIRING,
|
||||
RELOADING,
|
||||
}
|
||||
|
||||
public EntityAIFireGun(EntityLiving host) {
|
||||
this.host = host;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateTask() {
|
||||
EntityLivingBase target = host.getAttackTarget();
|
||||
ItemStack stack = host.getHeldItem();
|
||||
ItemGunBaseNT gun = getYerGun();
|
||||
@Override
|
||||
public boolean shouldExecute() {
|
||||
return host.getAttackTarget() != null && getYerGun() != null;
|
||||
}
|
||||
|
||||
gun.onUpdate(stack, host.worldObj, host, 0, true);
|
||||
@Override
|
||||
public void updateTask() {
|
||||
EntityLivingBase target = host.getAttackTarget();
|
||||
ItemStack stack = host.getHeldItem();
|
||||
ItemGunBaseNT gun = getYerGun();
|
||||
|
||||
double distanceToTargetSquared = host.getDistanceSq(target.posX, target.posY, target.posZ);
|
||||
boolean canSeeTarget = host.getEntitySenses().canSee(target);
|
||||
gun.onUpdate(stack, host.worldObj, host, 0, true);
|
||||
|
||||
if(canSeeTarget) {
|
||||
attackTimer++;
|
||||
} else {
|
||||
attackTimer = 0;
|
||||
}
|
||||
double distanceToTargetSquared = host.getDistanceSq(target.posX, target.posY, target.posZ);
|
||||
boolean canSeeTarget = host.getEntitySenses().canSee(target);
|
||||
|
||||
if(distanceToTargetSquared < maxRange * maxRange && attackTimer > 20) {
|
||||
host.getNavigator().clearPathEntity();
|
||||
} else {
|
||||
host.getNavigator().tryMoveToEntityLiving(target, attackMoveSpeed);
|
||||
}
|
||||
if(canSeeTarget) {
|
||||
attackTimer++;
|
||||
} else {
|
||||
attackTimer = 0;
|
||||
}
|
||||
|
||||
host.getLookHelper().setLookPositionWithEntity(target, 30.0F, 30.0F);
|
||||
if(distanceToTargetSquared < maxRange * maxRange && attackTimer > 20) {
|
||||
host.getNavigator().clearPathEntity();
|
||||
} else {
|
||||
host.getNavigator().tryMoveToEntityLiving(target, attackMoveSpeed);
|
||||
}
|
||||
|
||||
if(canSeeTarget && distanceToTargetSquared < maxRange * maxRange) {
|
||||
GunConfig config = gun.getConfig(stack, 0);
|
||||
Receiver rec = config.getReceivers(stack)[0];
|
||||
if(rec.getMagazine(stack).getAmount(stack) <= 0) {
|
||||
gun.handleKeybind(host, null, stack, EnumKeybind.GUN_PRIMARY, false);
|
||||
gun.handleKeybind(host, null, stack, EnumKeybind.RELOAD, true);
|
||||
} else if(ItemGunBaseNT.getState(stack, 0) == GunState.IDLE) {
|
||||
gun.handleKeybind(host, null, stack, EnumKeybind.GUN_PRIMARY, true);
|
||||
gun.handleKeybind(host, null, stack, EnumKeybind.RELOAD, false);
|
||||
} else {
|
||||
gun.handleKeybind(host, null, stack, EnumKeybind.GUN_PRIMARY, false);
|
||||
gun.handleKeybind(host, null, stack, EnumKeybind.RELOAD, false);
|
||||
}
|
||||
} else {
|
||||
gun.handleKeybind(host, null, stack, EnumKeybind.GUN_PRIMARY, false);
|
||||
gun.handleKeybind(host, null, stack, EnumKeybind.RELOAD, false);
|
||||
}
|
||||
}
|
||||
host.getLookHelper().setLookPositionWithEntity(target, 30.0F, 30.0F);
|
||||
|
||||
public ItemGunBaseNT getYerGun() {
|
||||
ItemStack stack = host.getHeldItem();
|
||||
stateTimer--;
|
||||
if(stateTimer < 0) {
|
||||
stateTimer = 0;
|
||||
|
||||
if(stack == null || !(stack.getItem() instanceof ItemGunBaseNT)) return null;
|
||||
if(state == FireState.WAIT) {
|
||||
updateState(FireState.IDLE, 0, gun, stack);
|
||||
} else if(state != FireState.IDLE) {
|
||||
updateState(FireState.WAIT, host.worldObj.rand.nextInt(maxWait - minWait) + minWait, gun, stack);
|
||||
}
|
||||
} else if(state == FireState.FIRING) {
|
||||
// Keep the trigger held throughout the duration of firing
|
||||
updateKeybind(gun, stack, EnumKeybind.GUN_PRIMARY);
|
||||
}
|
||||
|
||||
return (ItemGunBaseNT) stack.getItem();
|
||||
}
|
||||
|
||||
if(canSeeTarget && distanceToTargetSquared < maxRange * maxRange) {
|
||||
if(state == FireState.IDLE) {
|
||||
GunConfig config = gun.getConfig(stack, 0);
|
||||
Receiver rec = config.getReceivers(stack)[0];
|
||||
if(rec.getMagazine(stack).getAmount(stack) <= 0) {
|
||||
updateState(FireState.RELOADING, 40, gun, stack);
|
||||
} else if(ItemGunBaseNT.getState(stack, 0) == GunState.IDLE) {
|
||||
updateState(FireState.FIRING, host.worldObj.rand.nextInt(burstTime), gun, stack);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void updateState(FireState toState, int time, ItemGunBaseNT gun, ItemStack stack) {
|
||||
state = toState;
|
||||
stateTimer = time;
|
||||
|
||||
switch(state) {
|
||||
case FIRING: updateKeybind(gun, stack, EnumKeybind.GUN_PRIMARY);
|
||||
case RELOADING: updateKeybind(gun, stack, EnumKeybind.RELOAD);
|
||||
default: clearKeybinds(gun, stack); break;
|
||||
}
|
||||
}
|
||||
|
||||
private void clearKeybinds(ItemGunBaseNT gun, ItemStack stack) {
|
||||
updateKeybind(gun, stack, null);
|
||||
}
|
||||
|
||||
private void updateKeybind(ItemGunBaseNT gun, ItemStack stack, EnumKeybind bind) {
|
||||
// Turn body to face firing direction, since the gun is attached to that, not the head
|
||||
// Also apply accuracy debuff just before firing
|
||||
if(bind != null && bind != EnumKeybind.RELOAD) {
|
||||
host.rotationYawHead += (host.worldObj.rand.nextFloat() - 0.5F) * 2 * inaccuracy;
|
||||
host.rotationPitch += (host.worldObj.rand.nextFloat() - 0.5F) * 2 * inaccuracy;
|
||||
host.rotationYaw = host.rotationYawHead;
|
||||
}
|
||||
|
||||
gun.handleKeybind(host, null, stack, EnumKeybind.GUN_PRIMARY, bind == EnumKeybind.GUN_PRIMARY);
|
||||
gun.handleKeybind(host, null, stack, EnumKeybind.GUN_SECONDARY, bind == EnumKeybind.GUN_SECONDARY);
|
||||
gun.handleKeybind(host, null, stack, EnumKeybind.GUN_TERTIARY, bind == EnumKeybind.GUN_TERTIARY);
|
||||
gun.handleKeybind(host, null, stack, EnumKeybind.RELOAD, bind == EnumKeybind.RELOAD);
|
||||
}
|
||||
|
||||
public ItemGunBaseNT getYerGun() {
|
||||
ItemStack stack = host.getHeldItem();
|
||||
|
||||
if(stack == null || !(stack.getItem() instanceof ItemGunBaseNT)) return null;
|
||||
|
||||
return (ItemGunBaseNT) stack.getItem();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -54,6 +54,7 @@ import com.hbm.items.armor.ItemModShackles;
|
||||
import com.hbm.items.food.ItemConserve.EnumFoodType;
|
||||
import com.hbm.items.tool.ItemGuideBook.BookType;
|
||||
import com.hbm.items.weapon.ItemGunBase;
|
||||
import com.hbm.items.weapon.sedna.ItemGunBaseNT;
|
||||
import com.hbm.lib.HbmCollection;
|
||||
import com.hbm.lib.ModDamageSource;
|
||||
import com.hbm.lib.RefStrings;
|
||||
@ -65,14 +66,7 @@ import com.hbm.saveddata.AuxSavedData;
|
||||
import com.hbm.tileentity.machine.TileEntityMachineRadarNT;
|
||||
import com.hbm.tileentity.network.RTTYSystem;
|
||||
import com.hbm.tileentity.network.RequestNetwork;
|
||||
import com.hbm.util.AchievementHandler;
|
||||
import com.hbm.util.ArmorRegistry;
|
||||
import com.hbm.util.ArmorUtil;
|
||||
import com.hbm.util.ContaminationUtil;
|
||||
import com.hbm.util.EnchantmentUtil;
|
||||
import com.hbm.util.EnumUtil;
|
||||
import com.hbm.util.InventoryUtil;
|
||||
import com.hbm.util.ShadyUtil;
|
||||
import com.hbm.util.*;
|
||||
import com.hbm.util.ArmorRegistry.HazardClass;
|
||||
import com.hbm.world.generator.TimedGenerator;
|
||||
|
||||
@ -89,8 +83,10 @@ import net.minecraft.block.Block;
|
||||
import net.minecraft.enchantment.Enchantment;
|
||||
import net.minecraft.enchantment.EnchantmentHelper;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityLiving;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.entity.SharedMonsterAttributes;
|
||||
import net.minecraft.entity.ai.EntityAITasks;
|
||||
import net.minecraft.entity.ai.attributes.AttributeModifier;
|
||||
import net.minecraft.entity.item.EntityItem;
|
||||
import net.minecraft.entity.monster.EntityCaveSpider;
|
||||
@ -116,13 +112,7 @@ import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.potion.Potion;
|
||||
import net.minecraft.potion.PotionEffect;
|
||||
import net.minecraft.tileentity.TileEntitySign;
|
||||
import net.minecraft.util.ChatComponentText;
|
||||
import net.minecraft.util.ChatStyle;
|
||||
import net.minecraft.util.EntityDamageSource;
|
||||
import net.minecraft.util.EnumChatFormatting;
|
||||
import net.minecraft.util.FoodStats;
|
||||
import net.minecraft.util.MathHelper;
|
||||
import net.minecraft.util.Vec3;
|
||||
import net.minecraft.util.*;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.common.util.FakePlayer;
|
||||
import net.minecraftforge.common.util.ForgeDirection;
|
||||
@ -423,12 +413,48 @@ public class ModEventHandler {
|
||||
}
|
||||
if(rand.nextInt(64) == 0)
|
||||
entity.setCurrentItemOrArmor(3, new ItemStack(ModItems.steel_plate, 1, world.rand.nextInt(ModItems.steel_plate.getMaxDamage())));
|
||||
|
||||
// Give them a gun and the AI task to fire it
|
||||
entity.setCurrentItemOrArmor(0, new ItemStack(ModItems.gun_am180));
|
||||
|
||||
float soot = PollutionHandler.getPollution(entity.worldObj, MathHelper.floor_double(event.x), MathHelper.floor_double(event.y), MathHelper.floor_double(event.z), PollutionType.SOOT);
|
||||
ItemStack bowReplacement = getSkelegun(soot, entity.worldObj.rand);
|
||||
if(bowReplacement != null) {
|
||||
entity.setCurrentItemOrArmor(0, bowReplacement);
|
||||
addFireTask((EntityLiving) entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EntitySkeleton skeleton = (EntitySkeleton) entity;
|
||||
skeleton.tasks.addTask(3, new EntityAIFireGun(skeleton));
|
||||
private static ItemStack getSkelegun(float soot, Random rand) {
|
||||
if(rand.nextDouble() > Math.log(soot) * 0.25) return null;
|
||||
|
||||
ArrayList<WeightedRandomObject> pool = new ArrayList<WeightedRandomObject>();
|
||||
pool.add(new WeightedRandomObject(new ItemStack(ModItems.gun_heavy_revolver), 12));
|
||||
|
||||
if(soot > 8) pool.add(new WeightedRandomObject(new ItemStack(ModItems.gun_am180), 4));
|
||||
|
||||
WeightedRandomObject selected = (WeightedRandomObject) WeightedRandom.getRandomItem(rand, pool);
|
||||
|
||||
return selected.asStack();
|
||||
}
|
||||
|
||||
// these fucking tasks keep stacking on top of themselves
|
||||
private static void addFireTask(EntityLiving entity) {
|
||||
for(Object entry : entity.tasks.taskEntries) {
|
||||
EntityAITasks.EntityAITaskEntry task = (EntityAITasks.EntityAITaskEntry) entry;
|
||||
if(task.action instanceof EntityAIFireGun) return;
|
||||
}
|
||||
|
||||
entity.tasks.addTask(3, new EntityAIFireGun(entity));
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void addAITasks(EntityJoinWorldEvent event) {
|
||||
if(event.world.isRemote || !(event.entity instanceof EntityLiving)) return;
|
||||
|
||||
EntityLiving living = (EntityLiving) event.entity;
|
||||
ItemStack held = living.getHeldItem();
|
||||
|
||||
if(held != null && held.getItem() instanceof ItemGunBaseNT) {
|
||||
addFireTask(living);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user