Added electromagnetic cell unstability when dropped in the world

Fixed radiation damage to scale more realisticaly with distance
This commit is contained in:
LemADEC 2017-11-13 02:23:07 +01:00
parent 6938e1030d
commit e3dcd26b06
9 changed files with 223 additions and 10 deletions

View file

@ -119,6 +119,7 @@ import cr0s.warpdrive.data.StarMapRegistry;
import cr0s.warpdrive.event.ChunkHandler;
import cr0s.warpdrive.event.ClientHandler;
import cr0s.warpdrive.event.CommonWorldGenerator;
import cr0s.warpdrive.event.ItemHandler;
import cr0s.warpdrive.event.LivingHandler;
import cr0s.warpdrive.event.WorldHandler;
import cr0s.warpdrive.item.ItemAirTank;
@ -731,7 +732,7 @@ public class WarpDrive implements LoadingCallback {
// Event handlers
MinecraftForge.EVENT_BUS.register(new ClientHandler());
MinecraftForge.EVENT_BUS.register(new ItemHandler());
MinecraftForge.EVENT_BUS.register(new LivingHandler());
if (WarpDriveConfig.isComputerCraftLoaded) {

View file

@ -0,0 +1,10 @@
package cr0s.warpdrive.api;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.item.ItemStack;
public interface IItemBase {
// wrapper for Forge ItemExpireEvent
void onEntityExpireEvent(EntityItem entityItem, ItemStack itemStack);
}

View file

@ -1,11 +1,14 @@
package cr0s.warpdrive.api;
import cr0s.warpdrive.Commons;
import cr0s.warpdrive.WarpDrive;
import cr0s.warpdrive.data.Vector3;
import java.util.Locale;
import net.minecraft.item.EnumRarity;
import net.minecraft.util.StatCollector;
import net.minecraft.world.World;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
@ -17,6 +20,9 @@ public class Particle {
protected int colorIndex;
protected EnumRarity enumRarity = EnumRarity.common;
private int entityLifespan;
private float radiationLevel = 0.0F;
private float explosionStrength = 0.0F;
public Particle(final String registryName) {
this.registryName = registryName.toLowerCase(Locale.ENGLISH);
@ -42,6 +48,21 @@ public class Particle {
return this;
}
public Particle setEntityLifespan(final int entityLifespan) {
this.entityLifespan = entityLifespan;
return this;
}
public Particle setRadiationLevel(final float radiationLevel) {
this.radiationLevel = radiationLevel;
return this;
}
public Particle setExplosionStrength(final float explosionStrength) {
this.explosionStrength = explosionStrength;
return this;
}
public final String getRegistryName()
{
return this.registryName;
@ -80,5 +101,26 @@ public class Particle {
{
return color;
}
public int getEntityLifespan() {
return entityLifespan;
}
/* Effector */
public void onWorldEffect(final World world, final Vector3 v3Position, final int amount) {
if (world.isRemote) {
return;
}
if (radiationLevel > 0.0F) {
final float strength = radiationLevel * amount / 1000.0F;
WarpDrive.damageIrradiation.onWorldEffect(world, v3Position, strength);
}
if (explosionStrength > 0.0F) {
final float amountFactor = Math.max(1.25F, amount / 1000.0F);
world.newExplosion(null, v3Position.x, v3Position.y, v3Position.z, explosionStrength * amountFactor, true, true);
WarpDrive.logger.info("Particle caused explosion at " + v3Position.x + " " + v3Position.y + " " + v3Position.z + " with strength " + explosionStrength * amountFactor);
}
}
}

View file

@ -18,10 +18,14 @@ public class ParticleRegistry {
private static BiMap<String, Particle> particles = HashBiMap.create();
public static final Particle ION = new Particle("ion") { }.setColor(0xE5FF54).setRarity(EnumRarity.common).setColorIndex(0);
public static final Particle PROTON = new Particle("proton") { }.setColor(0xE5FF54).setRarity(EnumRarity.common).setColorIndex(1);
public static final Particle ANTIMATTER = new Particle("antimatter") { }.setColor(0x1C3CAF).setRarity(EnumRarity.uncommon).setColorIndex(2);
public static final Particle STRANGE_MATTER = new Particle("strange_matter") { }.setColor(0xE2414C).setRarity(EnumRarity.rare).setColorIndex(3);
public static final Particle ION = new Particle("ion") { }.setColor(0xE5FF54).setRarity(EnumRarity.common).setColorIndex(0)
.setEntityLifespan(200).setRadiationLevel(2.0F).setExplosionStrength(0.3F);
public static final Particle PROTON = new Particle("proton") { }.setColor(0xE5FF54).setRarity(EnumRarity.common).setColorIndex(1)
.setEntityLifespan(200).setRadiationLevel(4.0F).setExplosionStrength(0.5F);
public static final Particle ANTIMATTER = new Particle("antimatter") { }.setColor(0x1C3CAF).setRarity(EnumRarity.uncommon).setColorIndex(2)
.setEntityLifespan(60).setRadiationLevel(10.0F).setExplosionStrength(1.0F);
public static final Particle STRANGE_MATTER = new Particle("strange_matter") { }.setColor(0xE2414C).setRarity(EnumRarity.rare).setColorIndex(3)
.setEntityLifespan(40).setRadiationLevel(14.0F).setExplosionStrength(0.8F);
// public static final Particle TACHYONS = new Particle("tachyons") { }.setColor(0xE5FF54).setRarity(EnumRarity.epic).setColorIndex(4);
static {

View file

@ -1,9 +1,12 @@
package cr0s.warpdrive.api;
import cr0s.warpdrive.data.Vector3;
import javax.annotation.Nonnull;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.world.World;
import cpw.mods.fml.common.FMLLog;
@ -77,6 +80,20 @@ public class ParticleStack {
amount += amountAdded;
}
public int getEntityLifespan() {
if (particle == null) {
return -1;
}
return particle.getEntityLifespan();
}
public void onWorldEffect(@Nonnull final World world, @Nonnull final Vector3 v3Position) {
if (particle == null) {
return;
}
particle.onWorldEffect(world, v3Position, amount);
}
public String getLocalizedName() {
return this.getParticle().getLocalizedName();
}

View file

@ -1,6 +1,18 @@
package cr0s.warpdrive.damage;
import cr0s.warpdrive.Commons;
import cr0s.warpdrive.WarpDrive;
import cr0s.warpdrive.config.WarpDriveConfig;
import cr0s.warpdrive.data.Vector3;
import cr0s.warpdrive.network.PacketHandler;
import java.util.List;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.util.DamageSource;
import net.minecraft.world.World;
public class DamageIrradiation extends DamageSource {
@ -10,4 +22,54 @@ public class DamageIrradiation extends DamageSource {
setDamageIsAbsolute();
}
public void onWorldEffect(final World world, final Vector3 v3Position, final float strength) {
// only search up to distance where damage applied is 0.5
final double radius = Math.sqrt(2.0D * strength);
final AxisAlignedBB axisAlignedBB = AxisAlignedBB.getBoundingBox(
v3Position.x - radius, v3Position.y - radius, v3Position.z - radius,
v3Position.x + radius, v3Position.y + radius, v3Position.z + radius);
final List<EntityLivingBase> listEntityLivingBase = world.getEntitiesWithinAABB(EntityLivingBase.class, axisAlignedBB);
if (listEntityLivingBase != null) {
for (EntityLivingBase entityLivingBase : listEntityLivingBase) {
// cap damage below 1 m distance, since the entity is never really inside the source and damage tends to +INF
final float distance = Math.min(1.0F, (float) Math.sqrt(v3Position.distanceTo_square(entityLivingBase)));
onEntityEffect(strength / (distance * distance), world, v3Position, entityLivingBase);
}
}
}
public void onEntityEffect(final float strength, final World world, final Vector3 v3Source, final Entity entity) {
if ( strength <= 0.0F
|| !(entity instanceof EntityLivingBase)
|| entity.isDead ) {
return;
}
// common particle effects properties
final Vector3 v3Entity = new Vector3(entity);
final Vector3 v3Direction = new Vector3(entity).subtract(v3Source).normalize();
final Vector3 v3From = v3Source.clone();
v3From.translateFactor(v3Direction, 0.6D);
v3Entity.translateFactor(v3Direction, -0.6D);
final double speed = Math.abs(strength);
final Vector3 v3Motion = v3Direction.clone().scale(speed); // new Vector3(entity.motionX, entity.motionY, entity.motionZ);
if (WarpDriveConfig.LOGGING_ACCELERATOR && WarpDrive.isDev) {
PacketHandler.sendBeamPacket(world, v3From, v3Entity,
0.25F, 0.75F, 0.38F, 10, 0, 50);
WarpDrive.logger.info(String.format("%s strength %.1f speed %.3f entity %s source %s direction %s motion %s entity %s",
this, strength, speed, v3Entity, v3Source, v3Direction, v3Motion, entity));
}
// apply damages and particle effects
entity.attackEntityFrom(this, strength);
// visual effect
v3Direction.scale(0.20D);
PacketHandler.sendSpawnParticlePacket(world, "mobSpell", (byte) Commons.clamp(3, 10, strength), v3Entity, v3Direction,
0.20F + 0.10F * world.rand.nextFloat(),
0.90F + 0.10F * world.rand.nextFloat(),
0.40F + 0.15F * world.rand.nextFloat(),
0.0F, 0.0F, 0.0F, 32);
}
}

View file

@ -0,0 +1,28 @@
package cr0s.warpdrive.event;
import cr0s.warpdrive.api.IItemBase;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import cpw.mods.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.event.entity.item.ItemExpireEvent;
public class ItemHandler {
@SubscribeEvent
public static void onItemExpireEvent(final ItemExpireEvent event) {
if (event.entityItem == null) {
return;
}
final ItemStack itemStack = event.entityItem.getEntityItem();
if (itemStack == null) {
return;
}
final Item item = itemStack.getItem();
if (!(item instanceof IItemBase)) {
return;
}
((IItemBase) item).onEntityExpireEvent(event.entityItem, itemStack);
}
}

View file

@ -0,0 +1,20 @@
package cr0s.warpdrive.item;
import cr0s.warpdrive.WarpDrive;
import cr0s.warpdrive.api.IItemBase;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
public class ItemAbstractBase extends Item implements IItemBase {
public ItemAbstractBase() {
super();
setCreativeTab(WarpDrive.creativeTabWarpDrive);
}
@Override
public void onEntityExpireEvent(final EntityItem entityItem, final ItemStack itemStack) {
}
}

View file

@ -6,11 +6,13 @@ import cr0s.warpdrive.api.IParticleContainerItem;
import cr0s.warpdrive.api.Particle;
import cr0s.warpdrive.api.ParticleRegistry;
import cr0s.warpdrive.api.ParticleStack;
import cr0s.warpdrive.data.Vector3;
import java.util.List;
import net.minecraft.client.renderer.texture.IIconRegister;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Blocks;
import net.minecraft.item.Item;
@ -18,11 +20,12 @@ import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.IIcon;
import net.minecraft.util.StatCollector;
import net.minecraft.world.World;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
public class ItemElectromagneticCell extends Item implements IParticleContainerItem {
public class ItemElectromagneticCell extends ItemAbstractBase implements IParticleContainerItem {
private static final String AMOUNT_TO_CONSUME_TAG = "amountToConsume";
@ -150,7 +153,7 @@ public class ItemElectromagneticCell extends Item implements IParticleContainerI
}
private static int getDamageLevel(ItemStack itemStack, final ParticleStack particleStack) {
if (!(itemStack.getItem() instanceof ItemElectromagneticCell)) {
if (!(itemStack.getItem() instanceof ItemElectromagneticCell)) {
WarpDrive.logger.error("Invalid ItemStack passed, expecting ItemElectromagneticCell: " + itemStack);
return itemStack.getItemDamage();
}
@ -199,7 +202,7 @@ public class ItemElectromagneticCell extends Item implements IParticleContainerI
} else if (!particleStack.isParticleEqual(resource) || particleStack.getAmount() >= getCapacity(itemStack)) {
return 0;
}
int transfer = Math.min(resource.getAmount(), getCapacity(itemStack) - particleStack.getAmount());
final int transfer = Math.min(resource.getAmount(), getCapacity(itemStack) - particleStack.getAmount());
if (doFill) {
particleStack.fill(transfer);
@ -215,7 +218,7 @@ public class ItemElectromagneticCell extends Item implements IParticleContainerI
@Override
public ParticleStack drain(ItemStack itemStack, final ParticleStack resource, final boolean doDrain) {
ParticleStack particleStack = getParticleStack(itemStack);
final ParticleStack particleStack = getParticleStack(itemStack);
if (particleStack == null || particleStack.getParticle() == null) {
return null;
}
@ -226,7 +229,7 @@ public class ItemElectromagneticCell extends Item implements IParticleContainerI
if (doDrain) {
particleStack.fill(-transfer);
NBTTagCompound tagCompound = itemStack.hasTagCompound() ? itemStack.getTagCompound() : new NBTTagCompound();
final NBTTagCompound tagCompound = itemStack.hasTagCompound() ? itemStack.getTagCompound() : new NBTTagCompound();
tagCompound.setTag("particle", particleStack.writeToNBT(new NBTTagCompound()));
if (!itemStack.hasTagCompound()) {
itemStack.setTagCompound(tagCompound);
@ -236,6 +239,32 @@ public class ItemElectromagneticCell extends Item implements IParticleContainerI
return resource.copy(transfer);
}
@Override
public int getEntityLifespan(final ItemStack itemStack, final World world) {
final ParticleStack particleStack = getParticleStack(itemStack);
if ( particleStack == null
|| particleStack.isEmpty() ) {
return super.getEntityLifespan(itemStack, world);
}
final int lifespan = particleStack.getEntityLifespan();
if (lifespan < 0) {
return super.getEntityLifespan(itemStack, world);
}
// less content means more stable, so we scale lifespan with emptiness, up to doubling it
return (2 - particleStack.getAmount() / getCapacity(itemStack)) * lifespan;
}
@Override
public void onEntityExpireEvent(final EntityItem entityItem, final ItemStack itemStack) {
final ParticleStack particleStack = getParticleStack(itemStack);
if ( particleStack == null
|| particleStack.isEmpty() ) {
super.onEntityExpireEvent(entityItem, itemStack);
return;
}
particleStack.onWorldEffect(entityItem.worldObj, new Vector3(entityItem));
}
@Override
public void addInformation(ItemStack itemStack, EntityPlayer entityPlayer, List list, boolean advancedItemTooltips) {
super.addInformation(itemStack, entityPlayer, list, advancedItemTooltips);