mirror of
https://github.com/HbmMods/Hbm-s-Nuclear-Tech-GIT.git
synced 2026-01-25 10:32:49 +00:00
the great over-engineered vanilla-like explosion code
This commit is contained in:
parent
949ca4010e
commit
53264514f4
@ -0,0 +1,76 @@
|
||||
package com.hbm.explosion.vanillant;
|
||||
|
||||
import java.util.HashSet;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.material.Material;
|
||||
import net.minecraft.util.MathHelper;
|
||||
import net.minecraft.world.ChunkPosition;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class BlockAllocatorStandard implements IBlockAllocator {
|
||||
|
||||
protected int resolution;
|
||||
|
||||
public BlockAllocatorStandard() {
|
||||
this(16);
|
||||
}
|
||||
|
||||
public BlockAllocatorStandard(int resolution) {
|
||||
this.resolution = resolution;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HashSet<ChunkPosition> allocate(ExplosionVNT explosion, World world, double x, double y, double z, float size) {
|
||||
|
||||
HashSet<ChunkPosition> affectedBlocks = new HashSet();
|
||||
|
||||
for(int i = 0; i < this.resolution; ++i) {
|
||||
for(int j = 0; j < this.resolution; ++j) {
|
||||
for(int k = 0; k < this.resolution; ++k) {
|
||||
|
||||
if(i == 0 || i == this.resolution - 1 || j == 0 || j == this.resolution - 1 || k == 0 || k == this.resolution - 1) {
|
||||
|
||||
double d0 = (double) ((float) i / ((float) this.resolution - 1.0F) * 2.0F - 1.0F);
|
||||
double d1 = (double) ((float) j / ((float) this.resolution - 1.0F) * 2.0F - 1.0F);
|
||||
double d2 = (double) ((float) k / ((float) this.resolution - 1.0F) * 2.0F - 1.0F);
|
||||
double d3 = Math.sqrt(d0 * d0 + d1 * d1 + d2 * d2);
|
||||
|
||||
d0 /= d3;
|
||||
d1 /= d3;
|
||||
d2 /= d3;
|
||||
|
||||
float powerRemaining = size * (0.7F + world.rand.nextFloat() * 0.6F);
|
||||
double currentX = x;
|
||||
double currentY = y;
|
||||
double currentZ = z;
|
||||
|
||||
for(float stepSize = 0.3F; powerRemaining > 0.0F; powerRemaining -= stepSize * 0.75F) {
|
||||
|
||||
int blockX = MathHelper.floor_double(currentX);
|
||||
int blockY = MathHelper.floor_double(currentY);
|
||||
int blockZ = MathHelper.floor_double(currentZ);
|
||||
|
||||
Block block = world.getBlock(blockX, blockY, blockZ);
|
||||
|
||||
if(block.getMaterial() != Material.air) {
|
||||
float blockResistance = block.getExplosionResistance(explosion.exploder, world, blockX, blockY, blockZ, x, y, z);
|
||||
powerRemaining -= (blockResistance + 0.3F) * stepSize;
|
||||
}
|
||||
|
||||
if(powerRemaining > 0.0F) {
|
||||
affectedBlocks.add(new ChunkPosition(blockX, blockY, blockZ));
|
||||
}
|
||||
|
||||
currentX += d0 * (double) stepSize;
|
||||
currentY += d1 * (double) stepSize;
|
||||
currentZ += d2 * (double) stepSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return affectedBlocks;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,58 @@
|
||||
package com.hbm.explosion.vanillant;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.material.Material;
|
||||
import net.minecraft.util.MathHelper;
|
||||
import net.minecraft.world.ChunkPosition;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class BlockProcessorStandard implements IBlockProcessor {
|
||||
|
||||
protected IDropChanceMutator chance;
|
||||
|
||||
public BlockProcessorStandard() { }
|
||||
|
||||
public BlockProcessorStandard(IDropChanceMutator chance) {
|
||||
this.chance = chance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void process(ExplosionVNT explosion, World world, double x, double y, double z, HashSet<ChunkPosition> affectedBlocks) {
|
||||
|
||||
Iterator iterator = affectedBlocks.iterator();
|
||||
float dropChance = 1.0F / explosion.size;
|
||||
|
||||
while(iterator.hasNext()) {
|
||||
ChunkPosition chunkposition = (ChunkPosition) iterator.next();
|
||||
int blockX = chunkposition.chunkPosX;
|
||||
int blockY = chunkposition.chunkPosY;
|
||||
int blockZ = chunkposition.chunkPosZ;
|
||||
Block block = world.getBlock(blockX, blockY, blockZ);
|
||||
|
||||
if(block.getMaterial() != Material.air) {
|
||||
if(block.canDropFromExplosion(null)) {
|
||||
|
||||
if(chance != null) {
|
||||
dropChance = chance.mutateDropChance(explosion, block, blockX, blockY, blockZ, dropChance);
|
||||
}
|
||||
|
||||
block.dropBlockAsItemWithChance(world, blockX, blockY, blockZ, world.getBlockMetadata(blockX, blockY, blockZ), dropChance, 0);
|
||||
}
|
||||
|
||||
block.onBlockExploded(world, blockX, blockY, blockZ, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public BlockProcessorStandard setNoDrop() {
|
||||
this.chance = new DropChanceNever();
|
||||
return this;
|
||||
}
|
||||
public BlockProcessorStandard setAllDrop() {
|
||||
this.chance = new DropChanceAlways();
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,16 @@
|
||||
package com.hbm.explosion.vanillant;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
|
||||
/**
|
||||
* Now it's getting ridiculously over-engineered
|
||||
* @author hbm
|
||||
*
|
||||
*/
|
||||
public class DropChanceAlways implements IDropChanceMutator {
|
||||
|
||||
@Override
|
||||
public float mutateDropChance(ExplosionVNT explosion, Block block, int x, int y, int z, float chance) {
|
||||
return 1F;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
package com.hbm.explosion.vanillant;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
|
||||
public class DropChanceNever implements IDropChanceMutator {
|
||||
|
||||
@Override
|
||||
public float mutateDropChance(ExplosionVNT explosion, Block block, int x, int y, int z, float chance) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,87 @@
|
||||
package com.hbm.explosion.vanillant;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.util.Vec3;
|
||||
import net.minecraft.world.ChunkPosition;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
/**
|
||||
* Time to over-engineer this into fucking oblivion so that I never have to write a vanilla-esque explosion class ever again
|
||||
* @author hbm
|
||||
*
|
||||
*/
|
||||
public class ExplosionVNT {
|
||||
|
||||
//explosions only need one of these, in the unlikely event that we do need to combine different types we can just write a wrapper that acts as a chainloader
|
||||
private IBlockAllocator blockAllocator;
|
||||
private IEntityAllocator entityAllocator;
|
||||
private IBlockProcessor blockProcessor;
|
||||
private IEntityProcessor entityProcessor;
|
||||
//since we want to reduce each effect to the bare minimum (sound, particles, etc. being separate) we definitely need multiple most of the time
|
||||
private IExplosionSFX[] sfx;
|
||||
|
||||
protected World world;
|
||||
protected double posX;
|
||||
protected double posY;
|
||||
protected double posZ;
|
||||
protected float size;
|
||||
public Entity exploder;
|
||||
|
||||
public ExplosionVNT(World world, double x, double y, double z, float size) {
|
||||
this(world, x, y, z, size, null);
|
||||
}
|
||||
|
||||
public ExplosionVNT(World world, double x, double y, double z, float size, Entity exploder) {
|
||||
this.world = world;
|
||||
this.posX = x;
|
||||
this.posY = y;
|
||||
this.posZ = z;
|
||||
this.size = size;
|
||||
this.exploder = exploder;
|
||||
}
|
||||
|
||||
public void explode() {
|
||||
|
||||
boolean processBlocks = blockAllocator != null && blockProcessor != null;
|
||||
boolean processEntities = entityAllocator != null && entityProcessor != null;
|
||||
|
||||
HashSet<ChunkPosition> affectedBlocks = null;
|
||||
HashMap<Entity, Vec3> affectedEntities = null;
|
||||
|
||||
if(processBlocks) affectedBlocks = blockAllocator.allocate(this, world, posX, posY, posZ, size);
|
||||
if(processEntities) affectedEntities = entityAllocator.allocate(this, world, posX, posY, posZ, size);
|
||||
|
||||
if(processBlocks) blockProcessor.process(this, world, posX, posY, posZ, affectedBlocks);
|
||||
if(processEntities) entityProcessor.process(this, world, posX, posY, posZ, affectedEntities);
|
||||
|
||||
if(sfx != null) {
|
||||
for(IExplosionSFX fx : sfx) {
|
||||
fx.doEffect(this, world, posX, posY, posZ, size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public ExplosionVNT setBlockAllocator(IBlockAllocator blockAllocator) {
|
||||
this.blockAllocator = blockAllocator;
|
||||
return this;
|
||||
}
|
||||
public ExplosionVNT setEntityAllocator(IEntityAllocator entityAllocator) {
|
||||
this.entityAllocator = entityAllocator;
|
||||
return this;
|
||||
}
|
||||
public ExplosionVNT setBlockProcessor(IBlockProcessor blockProcessor) {
|
||||
this.blockProcessor = blockProcessor;
|
||||
return this;
|
||||
}
|
||||
public ExplosionVNT setEntityprocessor(IEntityProcessor entityProcessor) {
|
||||
this.entityProcessor = entityProcessor;
|
||||
return this;
|
||||
}
|
||||
public ExplosionVNT setSFX(IExplosionSFX... sfx) {
|
||||
this.sfx = sfx;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,11 @@
|
||||
package com.hbm.explosion.vanillant;
|
||||
|
||||
import java.util.HashSet;
|
||||
|
||||
import net.minecraft.world.ChunkPosition;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public interface IBlockAllocator {
|
||||
|
||||
public HashSet<ChunkPosition> allocate(ExplosionVNT explosion, World world, double x, double y, double z, float size);
|
||||
}
|
||||
|
||||
@ -0,0 +1,11 @@
|
||||
package com.hbm.explosion.vanillant;
|
||||
|
||||
import java.util.HashSet;
|
||||
|
||||
import net.minecraft.world.ChunkPosition;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public interface IBlockProcessor {
|
||||
|
||||
public void process(ExplosionVNT explosion, World world, double x, double y, double z, HashSet<ChunkPosition> affectedBlocks);
|
||||
}
|
||||
@ -0,0 +1,8 @@
|
||||
package com.hbm.explosion.vanillant;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
|
||||
public interface IDropChanceMutator {
|
||||
|
||||
public float mutateDropChance(ExplosionVNT explosion, Block block, int x, int y, int z, float chance);
|
||||
}
|
||||
@ -0,0 +1,12 @@
|
||||
package com.hbm.explosion.vanillant;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.util.Vec3;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public interface IEntityAllocator {
|
||||
|
||||
public HashMap<Entity, Vec3> allocate(ExplosionVNT explosion, World world, double x, double y, double z, float size);
|
||||
}
|
||||
@ -0,0 +1,14 @@
|
||||
package com.hbm.explosion.vanillant;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.util.Vec3;
|
||||
import net.minecraft.world.ChunkPosition;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public interface IEntityProcessor {
|
||||
|
||||
public void process(ExplosionVNT explosion, World world, double x, double y, double z, HashMap<Entity, Vec3> affectedBlocks);
|
||||
}
|
||||
11
src/main/java/com/hbm/explosion/vanillant/IExplosionSFX.java
Normal file
11
src/main/java/com/hbm/explosion/vanillant/IExplosionSFX.java
Normal file
@ -0,0 +1,11 @@
|
||||
package com.hbm.explosion.vanillant;
|
||||
|
||||
import java.util.HashSet;
|
||||
|
||||
import net.minecraft.world.ChunkPosition;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public interface IExplosionSFX {
|
||||
|
||||
public void doEffect(ExplosionVNT explosion, World world, double x, double y, double z, float size);
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user