Updated laser weapon balance
Fixed explosion never happening Fixed laser stopping on entities Added hull interaction with particle effect
This commit is contained in:
parent
43e9bc030a
commit
60d3016338
7 changed files with 326 additions and 56 deletions
7
src/main/java/cr0s/warpdrive/api/IHullBlock.java
Normal file
7
src/main/java/cr0s/warpdrive/api/IHullBlock.java
Normal file
|
@ -0,0 +1,7 @@
|
|||
package cr0s.warpdrive.api;
|
||||
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public interface IHullBlock {
|
||||
public void downgrade(World world, final int x, final int y, final int z);
|
||||
}
|
|
@ -24,6 +24,7 @@ import net.minecraft.util.Vec3;
|
|||
import cpw.mods.fml.common.Optional;
|
||||
import cr0s.warpdrive.WarpDrive;
|
||||
import cr0s.warpdrive.api.IBeamFrequency;
|
||||
import cr0s.warpdrive.api.IHullBlock;
|
||||
import cr0s.warpdrive.block.weapon.BlockLaserCamera;
|
||||
import cr0s.warpdrive.block.weapon.TileEntityLaserCamera;
|
||||
import cr0s.warpdrive.config.Dictionary;
|
||||
|
@ -146,10 +147,10 @@ public class TileEntityLaser extends TileEntityAbstractLaser implements IBeamFre
|
|||
|
||||
private void emitBeam(int beamEnergy) {
|
||||
int energy = beamEnergy;
|
||||
int beamLengthBlocks = clamp(0, WarpDriveConfig.LASER_CANNON_RANGE_MAX,
|
||||
energy / WarpDriveConfig.LASER_CANNON_RANGE_ENERGY_PER_BLOCK);
|
||||
|
||||
if (energy == 0 || beamLengthBlocks < 1 || beamFrequency > 65000 || beamFrequency <= 0) {
|
||||
int beamLengthBlocks = clamp(0, WarpDriveConfig.LASER_CANNON_RANGE_MAX, energy / 200);
|
||||
|
||||
if (energy == 0 || beamFrequency > 65000 || beamFrequency <= 0) {
|
||||
if (WarpDriveConfig.LOGGING_WEAPON) {
|
||||
WarpDrive.logger.info(this + " Beam canceled (energy " + energy + " over " + beamLengthBlocks + " blocks, beamFrequency " + beamFrequency + ")");
|
||||
}
|
||||
|
@ -246,6 +247,8 @@ public class TileEntityLaser extends TileEntityAbstractLaser implements IBeamFre
|
|||
if (WarpDriveConfig.LOGGING_WEAPON) {
|
||||
WarpDrive.logger.info("Entity is an invalid target (non-living " + entityId + ") " + mopEntity.entityHit);
|
||||
}
|
||||
// remove entity from hit list
|
||||
entityHits.put(entityHitDistance, null);
|
||||
continue;
|
||||
}
|
||||
if (WarpDriveConfig.LOGGING_WEAPON) {
|
||||
|
@ -254,9 +257,9 @@ public class TileEntityLaser extends TileEntityAbstractLaser implements IBeamFre
|
|||
}
|
||||
|
||||
// Consume energy
|
||||
energy -= WarpDriveConfig.LASER_CANNON_ENTITY_HIT_ENERGY
|
||||
+ ((blockHitDistance - distanceTravelled) * WarpDriveConfig.LASER_CANNON_ENERGY_LOSS_PER_BLOCK);
|
||||
distanceTravelled = blockHitDistance;
|
||||
energy *= getTransmittance(entityHitDistance - distanceTravelled);
|
||||
energy -= WarpDriveConfig.LASER_CANNON_ENTITY_HIT_ENERGY;
|
||||
distanceTravelled = entityHitDistance;
|
||||
vHitPoint = new Vector3(mopEntity.hitVec);
|
||||
if (energy <= 0) {
|
||||
break;
|
||||
|
@ -272,7 +275,7 @@ public class TileEntityLaser extends TileEntityAbstractLaser implements IBeamFre
|
|||
mopEntity.entityHit.setDead();
|
||||
}
|
||||
|
||||
if (energy > WarpDriveConfig.LASER_CANNON_ENTITY_HIT_ENERGY_THRESHOLD_FOR_EXPLOSION) {
|
||||
if (energy > WarpDriveConfig.LASER_CANNON_ENTITY_HIT_EXPLOSION_ENERGY_THRESHOLD) {
|
||||
float strength = (float)clamp(0.0D, WarpDriveConfig.LASER_CANNON_ENTITY_HIT_EXPLOSION_MAX_STRENGTH,
|
||||
WarpDriveConfig.LASER_CANNON_ENTITY_HIT_EXPLOSION_BASE_STRENGTH + energy / WarpDriveConfig.LASER_CANNON_ENTITY_HIT_EXPLOSION_ENERGY_PER_STRENGTH);
|
||||
worldObj.newExplosion(null, mopEntity.entityHit.posX, mopEntity.entityHit.posY, mopEntity.entityHit.posZ, strength, true, true);
|
||||
|
@ -288,15 +291,33 @@ public class TileEntityLaser extends TileEntityAbstractLaser implements IBeamFre
|
|||
|
||||
// Laser went too far or no block hit
|
||||
if (blockHitDistance >= beamLengthBlocks || blockHit == null) {
|
||||
if (WarpDriveConfig.LOGGING_WEAPON) {
|
||||
WarpDrive.logger.info("No more blocks to hit or too far: blockHitDistance is " + blockHitDistance + ", blockHit is " + blockHit);
|
||||
}
|
||||
vHitPoint = vReachPoint;
|
||||
break;
|
||||
}
|
||||
|
||||
Block block = worldObj.getBlock(blockHit.blockX, blockHit.blockY, blockHit.blockZ);
|
||||
// int blockMeta = worldObj.getBlockMetadata(hit.blockX, hit.blockY, hit.blockZ);
|
||||
float resistance = block.getExplosionResistance(null);
|
||||
// get hardness and blast resistance
|
||||
float hardness = -2.0F;
|
||||
if (WarpDrive.fieldBlockHardness != null) {
|
||||
// WarpDrive.fieldBlockHardness.setAccessible(true);
|
||||
try {
|
||||
hardness = (float)WarpDrive.fieldBlockHardness.get(block);
|
||||
} catch (IllegalArgumentException | IllegalAccessException exception) {
|
||||
exception.printStackTrace();
|
||||
WarpDrive.logger.error("Unable to access block hardness value of " + block);
|
||||
}
|
||||
}
|
||||
if (WarpDriveConfig.LOGGING_WEAPON) {
|
||||
WarpDrive.logger.info("Block collision found at " + blockHit.blockX + " " + blockHit.blockY + " " + blockHit.blockZ
|
||||
+ " with block " + block + " of hardness " + hardness);
|
||||
}
|
||||
|
||||
if (block.isAssociatedBlock(Blocks.bedrock)) { // FIXME: should check block hardness instead?
|
||||
// stop on unbreakable blocks
|
||||
if (hardness < 0.0F) {
|
||||
vHitPoint = new Vector3(blockHit.hitVec);
|
||||
break;
|
||||
}
|
||||
|
@ -311,24 +332,71 @@ public class TileEntityLaser extends TileEntityAbstractLaser implements IBeamFre
|
|||
}
|
||||
}
|
||||
|
||||
// instantly break glass
|
||||
if (block.getMaterial() == Material.glass) {
|
||||
worldObj.setBlockToAir(blockHit.blockX, blockHit.blockY, blockHit.blockZ);
|
||||
vHitPoint = new Vector3(blockHit.hitVec);
|
||||
}
|
||||
|
||||
// Consume energy
|
||||
energy -= WarpDriveConfig.LASER_CANNON_BLOCK_HIT_ENERGY
|
||||
+ (resistance * WarpDriveConfig.LASER_CANNON_BLOCK_HIT_ENERGY_PER_BLOCK_RESISTANCE)
|
||||
+ ((blockHitDistance - distanceTravelled) * WarpDriveConfig.LASER_CANNON_ENERGY_LOSS_PER_BLOCK);
|
||||
distanceTravelled = blockHitDistance;
|
||||
vHitPoint = new Vector3(blockHit.hitVec);
|
||||
// Compute parameters
|
||||
int energyCost = clamp(WarpDriveConfig.LASER_CANNON_BLOCK_HIT_ENERGY_MIN, WarpDriveConfig.LASER_CANNON_BLOCK_HIT_ENERGY_MAX,
|
||||
Math.round(hardness * WarpDriveConfig.LASER_CANNON_BLOCK_HIT_ENERGY_PER_BLOCK_HARDNESS));
|
||||
double absorptionChance = clamp(0.0D, WarpDriveConfig.LASER_CANNON_BLOCK_HIT_ABSORPTION_MAX,
|
||||
hardness * WarpDriveConfig.LASER_CANNON_BLOCK_HIT_ABSORPTION_PER_BLOCK_HARDNESS);
|
||||
|
||||
do {
|
||||
// Consume energy
|
||||
energy *= getTransmittance(blockHitDistance - distanceTravelled);
|
||||
energy -= energyCost;
|
||||
distanceTravelled = blockHitDistance;
|
||||
vHitPoint = new Vector3(blockHit.hitVec);
|
||||
if (energy <= 0) {
|
||||
if (WarpDriveConfig.LOGGING_WEAPON) {
|
||||
WarpDrive.logger.info("Beam died out of energy");
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (WarpDriveConfig.LOGGING_WEAPON) {
|
||||
WarpDrive.logger.info("Beam energy down to " + energy);
|
||||
}
|
||||
|
||||
// apply chance of absorption
|
||||
if (worldObj.rand.nextDouble() > absorptionChance) {
|
||||
break;
|
||||
}
|
||||
} while (true);
|
||||
if (energy <= 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (resistance >= WarpDriveConfig.LASER_CANNON_BLOCK_HIT_EXPLOSION_RESISTANCE_THRESHOLD) {
|
||||
// apply hull effect
|
||||
if (block instanceof IHullBlock) {
|
||||
((IHullBlock)block).downgrade(worldObj, blockHit.blockX, blockHit.blockY, blockHit.blockZ);
|
||||
// worldObj.newExplosion(null, blockHit.blockX, blockHit.blockY, blockHit.blockZ, 4, true, true);
|
||||
Vector3 origin = new Vector3(
|
||||
blockHit.blockX -0.93D * vDirection.x + worldObj.rand.nextFloat() - worldObj.rand.nextFloat(),
|
||||
blockHit.blockY -0.93D * vDirection.y + worldObj.rand.nextFloat() - worldObj.rand.nextFloat(),
|
||||
blockHit.blockZ -0.93D * vDirection.z + worldObj.rand.nextFloat() - worldObj.rand.nextFloat());
|
||||
Vector3 direction = null;
|
||||
direction = new Vector3(
|
||||
-0.2D * vDirection.x + 0.05 * (worldObj.rand.nextFloat() - worldObj.rand.nextFloat()),
|
||||
-0.2D * vDirection.y + 0.05 * (worldObj.rand.nextFloat() - worldObj.rand.nextFloat()),
|
||||
-0.2D * vDirection.z + 0.05 * (worldObj.rand.nextFloat() - worldObj.rand.nextFloat()));
|
||||
PacketHandler.sendSpawnParticlePacket(worldObj, "explode", origin, direction, r, g, b, 96);
|
||||
WarpDrive.logger.info("Effect: block " + blockHit.blockX + " " + blockHit.blockY + " " + blockHit.blockZ
|
||||
+ " effect at " + origin + " towards " + direction);
|
||||
if (WarpDriveConfig.LOGGING_WEAPON) {
|
||||
WarpDrive.logger.info("Hull absorbed remaining energy of " + energy);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (hardness >= WarpDriveConfig.LASER_CANNON_BLOCK_HIT_EXPLOSION_HARDNESS_THRESHOLD) {
|
||||
float strength = (float)clamp(0.0D, WarpDriveConfig.LASER_CANNON_BLOCK_HIT_EXPLOSION_MAX_STRENGTH,
|
||||
WarpDriveConfig.LASER_CANNON_BLOCK_HIT_EXPLOSION_BASE_STRENGTH + energy / WarpDriveConfig.LASER_CANNON_BLOCK_HIT_EXPLOSION_ENERGY_PER_STRENGTH);
|
||||
if (WarpDriveConfig.LOGGING_WEAPON) {
|
||||
WarpDrive.logger.info("Explosion triggered with strength " + strength);
|
||||
}
|
||||
worldObj.newExplosion(null, blockHit.blockX, blockHit.blockY, blockHit.blockZ, strength, true, true);
|
||||
worldObj.setBlock(blockHit.blockX, blockHit.blockY, blockHit.blockZ, (worldObj.rand.nextBoolean()) ? Blocks.fire : Blocks.air);
|
||||
} else {
|
||||
|
@ -340,6 +408,25 @@ public class TileEntityLaser extends TileEntityAbstractLaser implements IBeamFre
|
|||
beamLengthBlocks);
|
||||
}
|
||||
|
||||
private double getTransmittance(final double distance) {
|
||||
if (distance <= 0) {
|
||||
return 1.0D;
|
||||
}
|
||||
boolean isInSpace = (worldObj.provider.dimensionId == WarpDriveConfig.G_SPACE_DIMENSION_ID);
|
||||
boolean isInHyperSpace = (worldObj.provider.dimensionId == WarpDriveConfig.G_HYPERSPACE_DIMENSION_ID);
|
||||
double attenuation;
|
||||
if (isInSpace || isInHyperSpace) {
|
||||
attenuation = WarpDriveConfig.LASER_CANNON_ENERGY_ATTENUATION_PER_VOID_BLOCK;
|
||||
} else {
|
||||
attenuation = WarpDriveConfig.LASER_CANNON_ENERGY_ATTENUATION_PER_AIR_BLOCK;
|
||||
}
|
||||
double transmittance = Math.exp(- attenuation * distance);
|
||||
if (WarpDriveConfig.LOGGING_WEAPON) {
|
||||
WarpDrive.logger.info("Transmittance over " + distance + " blocks is " + transmittance);
|
||||
}
|
||||
return transmittance;
|
||||
}
|
||||
|
||||
public TreeMap<Double, MovingObjectPosition> raytraceEntities(Vector3 vSource, Vector3 vDirection, boolean collisionFlag, double reachDistance) {
|
||||
final double raytraceTolerance = 2.0D;
|
||||
|
||||
|
|
|
@ -5,13 +5,18 @@ import net.minecraft.block.BlockColored;
|
|||
import net.minecraft.block.BlockGlass;
|
||||
import net.minecraft.block.material.Material;
|
||||
import net.minecraft.world.IBlockAccess;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.common.util.ForgeDirection;
|
||||
import cr0s.warpdrive.WarpDrive;
|
||||
import cr0s.warpdrive.api.IHullBlock;
|
||||
import cr0s.warpdrive.config.WarpDriveConfig;
|
||||
|
||||
public class BlockHullGlass extends BlockColored {
|
||||
public class BlockHullGlass extends BlockColored implements IHullBlock {
|
||||
private int tier;
|
||||
|
||||
public BlockHullGlass(final int tier) {
|
||||
super(Material.glass);
|
||||
this.tier = tier;
|
||||
setHardness(WarpDriveConfig.HULL_HARDNESS[tier - 1]);
|
||||
setResistance(WarpDriveConfig.HULL_BLAST_RESISTANCE[tier - 1] * 5 / 3);
|
||||
setStepSound(Block.soundTypeGlass);
|
||||
|
@ -53,4 +58,14 @@ public class BlockHullGlass extends BlockColored {
|
|||
public boolean renderAsNormalBlock() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void downgrade(World world, int x, int y, int z) {
|
||||
int metadata = world.getBlockMetadata(x, y, z);
|
||||
if (tier == 1) {
|
||||
world.setBlockToAir(x, y, z);
|
||||
} else {
|
||||
world.setBlock(x, y, z, WarpDrive.blockHulls_plain[tier - 2], metadata, 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,15 +13,19 @@ import net.minecraft.item.Item;
|
|||
import net.minecraft.item.ItemDye;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.IIcon;
|
||||
import net.minecraft.world.World;
|
||||
import cr0s.warpdrive.WarpDrive;
|
||||
import cr0s.warpdrive.api.IHullBlock;
|
||||
import cr0s.warpdrive.config.WarpDriveConfig;
|
||||
|
||||
public class BlockHullPlain extends Block {
|
||||
public class BlockHullPlain extends Block implements IHullBlock {
|
||||
@SideOnly(Side.CLIENT)
|
||||
private IIcon[] icons;
|
||||
private int tier;
|
||||
|
||||
public BlockHullPlain(final int tier) {
|
||||
super(Material.iron);
|
||||
this.tier = tier;
|
||||
setHardness(WarpDriveConfig.HULL_HARDNESS[tier - 1]);
|
||||
setResistance(WarpDriveConfig.HULL_BLAST_RESISTANCE[tier - 1] * 5 / 3);
|
||||
setStepSound(Block.soundTypeMetal);
|
||||
|
@ -72,4 +76,14 @@ public class BlockHullPlain extends Block {
|
|||
public MapColor getMapColor(int metadata) {
|
||||
return MapColor.getMapColorForBlockColored(metadata);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void downgrade(World world, int x, int y, int z) {
|
||||
int metadata = world.getBlockMetadata(x, y, z);
|
||||
if (tier == 1) {
|
||||
world.setBlockToAir(x, y, z);
|
||||
} else {
|
||||
world.setBlock(x, y, z, WarpDrive.blockHulls_plain[tier - 2], metadata, 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -195,33 +195,39 @@ public class WarpDriveConfig {
|
|||
public static int LASER_MEDIUM_MAX_ENERGY_STORED = 100000;
|
||||
|
||||
// Laser Emitter
|
||||
public static int LASER_CANNON_MAX_MEDIUMS_COUNT = 10;
|
||||
public static int LASER_CANNON_MAX_LASER_ENERGY = 4000000;
|
||||
public static int LASER_CANNON_EMIT_FIRE_DELAY_TICKS = 5;
|
||||
public static int LASER_CANNON_EMIT_SCAN_DELAY_TICKS = 1;
|
||||
// 1 main laser + 4 boosting lasers = 10 * 100k + 0.6 * 40 * 100k = 3.4M
|
||||
public static int LASER_CANNON_MAX_MEDIUMS_COUNT = 10;
|
||||
public static int LASER_CANNON_MAX_LASER_ENERGY = 3400000;
|
||||
public static int LASER_CANNON_EMIT_FIRE_DELAY_TICKS = 5;
|
||||
public static int LASER_CANNON_EMIT_SCAN_DELAY_TICKS = 1;
|
||||
|
||||
public static double LASER_CANNON_BOOSTER_BEAM_ENERGY_EFFICIENCY = 0.60D;
|
||||
public static int LASER_CANNON_RANGE_ENERGY_PER_BLOCK = 5000;
|
||||
public static int LASER_CANNON_RANGE_MAX = 500;
|
||||
public static int LASER_CANNON_ENERGY_LOSS_PER_BLOCK = 500;
|
||||
public static double LASER_CANNON_ENERGY_ATTENUATION_PER_AIR_BLOCK = 0.000200D;
|
||||
public static double LASER_CANNON_ENERGY_ATTENUATION_PER_VOID_BLOCK = 0.000005D;
|
||||
public static double LASER_CANNON_ENERGY_ATTENUATION_PER_BROKEN_BLOCK = 0.23D;
|
||||
public static int LASER_CANNON_RANGE_MAX = 500;
|
||||
|
||||
public static int LASER_CANNON_ENTITY_HIT_SET_ON_FIRE_SECONDS = 20;
|
||||
public static int LASER_CANNON_ENTITY_HIT_ENERGY = 15000;
|
||||
public static int LASER_CANNON_ENTITY_HIT_BASE_DAMAGE = 3;
|
||||
public static int LASER_CANNON_ENTITY_HIT_ENERGY_PER_DAMAGE = 30000;
|
||||
public static int LASER_CANNON_ENTITY_HIT_MAX_DAMAGE = 100;
|
||||
public static int LASER_CANNON_ENTITY_HIT_SET_ON_FIRE_SECONDS = 20;
|
||||
public static int LASER_CANNON_ENTITY_HIT_ENERGY = 15000;
|
||||
public static int LASER_CANNON_ENTITY_HIT_BASE_DAMAGE = 3;
|
||||
public static int LASER_CANNON_ENTITY_HIT_ENERGY_PER_DAMAGE = 30000;
|
||||
public static int LASER_CANNON_ENTITY_HIT_MAX_DAMAGE = 100;
|
||||
|
||||
public static int LASER_CANNON_ENTITY_HIT_ENERGY_THRESHOLD_FOR_EXPLOSION = 1000000;
|
||||
public static float LASER_CANNON_ENTITY_HIT_EXPLOSION_BASE_STRENGTH = 4.0F;
|
||||
public static int LASER_CANNON_ENTITY_HIT_EXPLOSION_ENERGY_PER_STRENGTH = 125000;
|
||||
public static float LASER_CANNON_ENTITY_HIT_EXPLOSION_MAX_STRENGTH = 4.0F;
|
||||
public static int LASER_CANNON_ENTITY_HIT_EXPLOSION_ENERGY_THRESHOLD = 900000;
|
||||
public static float LASER_CANNON_ENTITY_HIT_EXPLOSION_BASE_STRENGTH = 4.0F;
|
||||
public static int LASER_CANNON_ENTITY_HIT_EXPLOSION_ENERGY_PER_STRENGTH = 125000;
|
||||
public static float LASER_CANNON_ENTITY_HIT_EXPLOSION_MAX_STRENGTH = 4.0F;
|
||||
|
||||
public static int LASER_CANNON_BLOCK_HIT_ENERGY = 70000;
|
||||
public static int LASER_CANNON_BLOCK_HIT_ENERGY_PER_BLOCK_RESISTANCE = 1000;
|
||||
public static double LASER_CANNON_BLOCK_HIT_EXPLOSION_RESISTANCE_THRESHOLD = 1200.0D; // obsidian is 2000 * 3 / 5 = 1200
|
||||
public static float LASER_CANNON_BLOCK_HIT_EXPLOSION_BASE_STRENGTH = 8.0F;
|
||||
public static int LASER_CANNON_BLOCK_HIT_EXPLOSION_ENERGY_PER_STRENGTH = 125000;
|
||||
public static float LASER_CANNON_BLOCK_HIT_EXPLOSION_MAX_STRENGTH = 100F;
|
||||
public static int LASER_CANNON_BLOCK_HIT_ENERGY_MIN = 75000;
|
||||
public static int LASER_CANNON_BLOCK_HIT_ENERGY_PER_BLOCK_HARDNESS = 150000;
|
||||
public static int LASER_CANNON_BLOCK_HIT_ENERGY_MAX = 750000;
|
||||
public static double LASER_CANNON_BLOCK_HIT_ABSORPTION_PER_BLOCK_HARDNESS = 0.01;
|
||||
public static double LASER_CANNON_BLOCK_HIT_ABSORPTION_MAX = 0.80;
|
||||
|
||||
public static float LASER_CANNON_BLOCK_HIT_EXPLOSION_HARDNESS_THRESHOLD = 5.0F;
|
||||
public static float LASER_CANNON_BLOCK_HIT_EXPLOSION_BASE_STRENGTH = 8.0F;
|
||||
public static int LASER_CANNON_BLOCK_HIT_EXPLOSION_ENERGY_PER_STRENGTH = 125000;
|
||||
public static float LASER_CANNON_BLOCK_HIT_EXPLOSION_MAX_STRENGTH = 50F;
|
||||
|
||||
// Mining laser
|
||||
// BuildCraft quarry values for reference
|
||||
|
@ -564,12 +570,14 @@ public class WarpDriveConfig {
|
|||
|
||||
LASER_CANNON_BOOSTER_BEAM_ENERGY_EFFICIENCY = clamp(0.01D, 10.0D,
|
||||
config.get("laser_cannon", "booster_beam_energy_efficiency", LASER_CANNON_BOOSTER_BEAM_ENERGY_EFFICIENCY, "Energy factor applied from boosting to main laser").getDouble(0.6D));
|
||||
LASER_CANNON_RANGE_ENERGY_PER_BLOCK = clamp(1, LASER_CANNON_MAX_LASER_ENERGY / 10,
|
||||
config.get("laser_cannon", "range_energy_per_block", LASER_CANNON_RANGE_ENERGY_PER_BLOCK, "Energy required per block distance").getInt());
|
||||
LASER_CANNON_ENERGY_ATTENUATION_PER_AIR_BLOCK = clamp(0.0D, 0.1D,
|
||||
config.get("laser_cannon", "energy_attenueation_per_air_block", LASER_CANNON_ENERGY_ATTENUATION_PER_AIR_BLOCK, "Energy attenuation when going through air blocks (on a planet or any gaz in space)").getDouble());
|
||||
LASER_CANNON_ENERGY_ATTENUATION_PER_VOID_BLOCK = clamp(0.0D, 0.1D,
|
||||
config.get("laser_cannon", "energy_attenueation_per_air_block", LASER_CANNON_ENERGY_ATTENUATION_PER_VOID_BLOCK, "Energy attenuation when going through void blocks (in space or hyperspace)").getDouble());
|
||||
LASER_CANNON_ENERGY_ATTENUATION_PER_BROKEN_BLOCK = clamp(0.0D, 1.0D,
|
||||
config.get("laser_cannon", "energy_attenueation_per_air_block", LASER_CANNON_ENERGY_ATTENUATION_PER_BROKEN_BLOCK, "Energy attenuation when going through a broken block").getDouble());
|
||||
LASER_CANNON_RANGE_MAX = clamp(64, 512,
|
||||
config.get("laser_cannon", "range_max", LASER_CANNON_RANGE_MAX, "Maximum distance travelled").getInt());
|
||||
LASER_CANNON_ENERGY_LOSS_PER_BLOCK = clamp(0, Integer.MAX_VALUE,
|
||||
config.get("laser_cannon", "energy_loss_per_block", LASER_CANNON_ENERGY_LOSS_PER_BLOCK, "Energy consummed per distance travelled").getInt());
|
||||
|
||||
LASER_CANNON_ENTITY_HIT_SET_ON_FIRE_SECONDS = clamp(0, 300,
|
||||
config.get("laser_cannon", "entity_hit_set_on_fire_seconds", LASER_CANNON_ENTITY_HIT_SET_ON_FIRE_SECONDS, "Duration of fire effect on entity hit (in seconds)").getInt());
|
||||
|
@ -583,8 +591,8 @@ public class WarpDriveConfig {
|
|||
LASER_CANNON_ENTITY_HIT_MAX_DAMAGE = clamp(0, Integer.MAX_VALUE,
|
||||
config.get("laser_cannon", "entity_hit_max_damage", LASER_CANNON_ENTITY_HIT_MAX_DAMAGE, "Maximum damage to entity hit, set to 0 to disable damage completly").getInt());
|
||||
|
||||
LASER_CANNON_ENTITY_HIT_ENERGY_THRESHOLD_FOR_EXPLOSION = clamp(0, Integer.MAX_VALUE,
|
||||
config.get("laser_cannon", "entity_hit_energy_threshold_for_explosion", LASER_CANNON_ENTITY_HIT_ENERGY_THRESHOLD_FOR_EXPLOSION, "Minimum energy to cause explosion effect").getInt());
|
||||
LASER_CANNON_ENTITY_HIT_EXPLOSION_ENERGY_THRESHOLD = clamp(0, Integer.MAX_VALUE,
|
||||
config.get("laser_cannon", "entity_hit_energy_threshold_for_explosion", LASER_CANNON_ENTITY_HIT_EXPLOSION_ENERGY_THRESHOLD, "Minimum energy to cause explosion effect").getInt());
|
||||
LASER_CANNON_ENTITY_HIT_EXPLOSION_BASE_STRENGTH = (float) clamp(0.0D, 100.0D,
|
||||
config.get("laser_cannon", "entity_hit_explosion_base_strength", LASER_CANNON_ENTITY_HIT_EXPLOSION_BASE_STRENGTH, "Explosion base strength, 4 is Vanilla TNT").getDouble());
|
||||
LASER_CANNON_ENTITY_HIT_EXPLOSION_ENERGY_PER_STRENGTH = clamp(1, Integer.MAX_VALUE,
|
||||
|
@ -592,14 +600,20 @@ public class WarpDriveConfig {
|
|||
LASER_CANNON_ENTITY_HIT_EXPLOSION_MAX_STRENGTH = (float) clamp(0.0D, 1000.0D,
|
||||
config.get("laser_cannon", "entity_hit_explosion_max_strength", LASER_CANNON_ENTITY_HIT_EXPLOSION_MAX_STRENGTH, "Maximum explosion strength, set to 0 to disable explosion completly").getDouble());
|
||||
|
||||
LASER_CANNON_BLOCK_HIT_ENERGY = clamp(0, Integer.MAX_VALUE,
|
||||
config.get("laser_cannon", "block_hit_energy", LASER_CANNON_BLOCK_HIT_ENERGY, "Base energy consummed from hitting a block").getInt());
|
||||
LASER_CANNON_BLOCK_HIT_ENERGY_PER_BLOCK_RESISTANCE = clamp(0, Integer.MAX_VALUE,
|
||||
config.get("laser_cannon", "block_hit_energy_per_block_resistance", LASER_CANNON_BLOCK_HIT_ENERGY_PER_BLOCK_RESISTANCE, "Energy consummed per explosive resistance points").getInt());
|
||||
LASER_CANNON_BLOCK_HIT_ENERGY_MIN = clamp(0, Integer.MAX_VALUE,
|
||||
config.get("laser_cannon", "block_hit_energy_min", LASER_CANNON_BLOCK_HIT_ENERGY_MIN, "Minimum energy required for breaking a block").getInt());
|
||||
LASER_CANNON_BLOCK_HIT_ENERGY_PER_BLOCK_HARDNESS = clamp(0, Integer.MAX_VALUE,
|
||||
config.get("laser_cannon", "block_hit_energy_per_block_hardness", LASER_CANNON_BLOCK_HIT_ENERGY_PER_BLOCK_HARDNESS, "Energy cost per block hardness for breaking a block").getInt());
|
||||
LASER_CANNON_BLOCK_HIT_ENERGY_MAX = clamp(0, Integer.MAX_VALUE,
|
||||
config.get("laser_cannon", "block_hit_energy_max", LASER_CANNON_BLOCK_HIT_ENERGY_MAX, "Maximum energy required for breaking a block").getInt());
|
||||
LASER_CANNON_BLOCK_HIT_ABSORPTION_PER_BLOCK_HARDNESS = clamp(0.0D, 1.0D,
|
||||
config.get("laser_cannon", "block_hit_absorption_per_block_hardness", LASER_CANNON_BLOCK_HIT_ABSORPTION_PER_BLOCK_HARDNESS, "Probability of energy absorption (i.e. block not breaking) per block hardness. Set to 1.0 to always break the block.").getDouble());
|
||||
LASER_CANNON_BLOCK_HIT_ABSORPTION_MAX = clamp(0.0D, 1.0D,
|
||||
config.get("laser_cannon", "block_hit_absorption_max", LASER_CANNON_BLOCK_HIT_ABSORPTION_MAX, "Maximum probability of energy absorption (i.e. block not breaking)").getDouble());
|
||||
|
||||
LASER_CANNON_BLOCK_HIT_EXPLOSION_RESISTANCE_THRESHOLD = clamp(0.0D, 1000000.0D,
|
||||
config.get("laser_cannon", "block_hit_explosion_resistance_threshold", LASER_CANNON_BLOCK_HIT_EXPLOSION_RESISTANCE_THRESHOLD,
|
||||
"Block explosion resistance threshold to cause an explosion").getDouble());
|
||||
LASER_CANNON_BLOCK_HIT_EXPLOSION_HARDNESS_THRESHOLD = (float) clamp(0.0D, 10000.0D,
|
||||
config.get("laser_cannon", "block_hit_explosion_hardness_threshold", LASER_CANNON_BLOCK_HIT_EXPLOSION_HARDNESS_THRESHOLD,
|
||||
"Minimum block hardness required to cause an explosion").getDouble());
|
||||
LASER_CANNON_BLOCK_HIT_EXPLOSION_BASE_STRENGTH = (float) clamp(0.0D, 1000.0D,
|
||||
config.get("laser_cannon", "block_hit_explosion_base_strength", LASER_CANNON_BLOCK_HIT_EXPLOSION_BASE_STRENGTH, "Explosion base strength, 4 is Vanilla TNT").getDouble());
|
||||
LASER_CANNON_BLOCK_HIT_EXPLOSION_ENERGY_PER_STRENGTH = clamp(1, Integer.MAX_VALUE,
|
||||
|
|
120
src/main/java/cr0s/warpdrive/network/MessageSpawnParticle.java
Normal file
120
src/main/java/cr0s/warpdrive/network/MessageSpawnParticle.java
Normal file
|
@ -0,0 +1,120 @@
|
|||
package cr0s.warpdrive.network;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.particle.EntityExplodeFX;
|
||||
import net.minecraft.client.particle.EntityFX;
|
||||
import net.minecraft.world.World;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import cpw.mods.fml.client.FMLClientHandler;
|
||||
import cpw.mods.fml.common.network.simpleimpl.IMessage;
|
||||
import cpw.mods.fml.common.network.simpleimpl.IMessageHandler;
|
||||
import cpw.mods.fml.common.network.simpleimpl.MessageContext;
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
import cr0s.warpdrive.WarpDrive;
|
||||
import cr0s.warpdrive.config.WarpDriveConfig;
|
||||
import cr0s.warpdrive.data.Vector3;
|
||||
|
||||
|
||||
public class MessageSpawnParticle implements IMessage, IMessageHandler<MessageSpawnParticle, IMessage> {
|
||||
|
||||
private String type;
|
||||
private Vector3 origin;
|
||||
private Vector3 direction;
|
||||
private float red;
|
||||
private float green;
|
||||
private float blue;
|
||||
|
||||
public MessageSpawnParticle() {
|
||||
// required on receiving side
|
||||
}
|
||||
|
||||
public MessageSpawnParticle(final String type, final Vector3 origin, final Vector3 direction, final float red, final float green, final float blue) {
|
||||
this.type = type;
|
||||
this.origin = origin;
|
||||
this.direction = direction;
|
||||
this.red = red;
|
||||
this.green = green;
|
||||
this.blue = blue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fromBytes(ByteBuf buffer) {
|
||||
int typeSize = buffer.readByte();
|
||||
WarpDrive.logger.info("1: " + buffer.readerIndex() + " typeSize " + typeSize);
|
||||
type = buffer.toString(buffer.readerIndex(), typeSize, StandardCharsets.US_ASCII);
|
||||
WarpDrive.logger.info("2: " + buffer.readerIndex() + " type " + type);
|
||||
buffer.skipBytes(typeSize);
|
||||
WarpDrive.logger.info("3: " + buffer.readerIndex());
|
||||
|
||||
double x = buffer.readDouble();
|
||||
double y = buffer.readDouble();
|
||||
double z = buffer.readDouble();
|
||||
origin = new Vector3(x, y, z);
|
||||
|
||||
x = buffer.readDouble();
|
||||
y = buffer.readDouble();
|
||||
z = buffer.readDouble();
|
||||
direction = new Vector3(x, y, z);
|
||||
|
||||
red = buffer.readFloat();
|
||||
green = buffer.readFloat();
|
||||
blue = buffer.readFloat();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toBytes(ByteBuf buffer) {
|
||||
buffer.writeByte(type.length());
|
||||
buffer.writeBytes(type.getBytes(StandardCharsets.US_ASCII), 0, type.length());
|
||||
buffer.writeDouble(origin.x);
|
||||
buffer.writeDouble(origin.y);
|
||||
buffer.writeDouble(origin.z);
|
||||
buffer.writeDouble(direction.x);
|
||||
buffer.writeDouble(direction.y);
|
||||
buffer.writeDouble(direction.z);
|
||||
buffer.writeFloat(red);
|
||||
buffer.writeFloat(green);
|
||||
buffer.writeFloat(blue);
|
||||
}
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
private void handle(World worldObj) {
|
||||
// Directly spawn particle as per RenderGlobal.doSpawnParticle, bypassing range check
|
||||
// adjust color as needed
|
||||
for (int i = 0; i < 5; i++) {
|
||||
direction = new Vector3(
|
||||
direction.x + 0.05 * (worldObj.rand.nextFloat() - worldObj.rand.nextFloat()),
|
||||
direction.y + 0.05 * (worldObj.rand.nextFloat() - worldObj.rand.nextFloat()),
|
||||
direction.z + 0.05 * (worldObj.rand.nextFloat() - worldObj.rand.nextFloat()));
|
||||
EntityFX effect = new EntityExplodeFX(worldObj, origin.x, origin.y, origin.z,
|
||||
direction.x, direction.y, direction.z); // TODO: implements other effects
|
||||
if (red >= 0.0F && green >= 0.0F && blue >= 0.0F) {
|
||||
effect.setRBGColorF(red, green, blue);
|
||||
}
|
||||
FMLClientHandler.instance().getClient().effectRenderer.addEffect(effect);
|
||||
}
|
||||
WarpDrive.logger.info("Executing particle effect '" + type + "' from " + origin + " toward " + direction
|
||||
+ " as RGB " + red + " " + green + " " + blue);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SideOnly(Side.CLIENT)
|
||||
public IMessage onMessage(MessageSpawnParticle messageSpawnParticle, MessageContext context) {
|
||||
// skip in case player just logged in
|
||||
if (Minecraft.getMinecraft().theWorld == null) {
|
||||
WarpDrive.logger.error("WorldObj is null, ignoring beam packet");
|
||||
return null;
|
||||
}
|
||||
|
||||
if (WarpDriveConfig.LOGGING_EFFECTS) {
|
||||
WarpDrive.logger.info("Received particle effect '" + messageSpawnParticle.type + "' from " + messageSpawnParticle.origin + " toward " + messageSpawnParticle.direction
|
||||
+ " as RGB " + messageSpawnParticle.red + " " + messageSpawnParticle.green + " " + messageSpawnParticle.blue);
|
||||
}
|
||||
|
||||
messageSpawnParticle.handle(Minecraft.getMinecraft().theWorld);
|
||||
|
||||
return null; // no response
|
||||
}
|
||||
}
|
|
@ -31,11 +31,12 @@ public class PacketHandler {
|
|||
|
||||
public static void init() {
|
||||
// Forge packets
|
||||
simpleNetworkManager.registerMessage(MessageBeamEffect.class, MessageBeamEffect.class, 0, Side.CLIENT);
|
||||
simpleNetworkManager.registerMessage(MessageBeamEffect.class , MessageBeamEffect.class , 0, Side.CLIENT);
|
||||
simpleNetworkManager.registerMessage(MessageVideoChannel.class , MessageVideoChannel.class , 1, Side.CLIENT);
|
||||
simpleNetworkManager.registerMessage(MessageCloak.class , MessageCloak.class , 2, Side.CLIENT);
|
||||
simpleNetworkManager.registerMessage(MessageCloak.class , MessageCloak.class , 2, Side.CLIENT);
|
||||
simpleNetworkManager.registerMessage(MessageSpawnParticle.class, MessageSpawnParticle.class, 3, Side.CLIENT);
|
||||
|
||||
simpleNetworkManager.registerMessage(MessageTargeting.class , MessageTargeting.class , 100, Side.SERVER);
|
||||
simpleNetworkManager.registerMessage(MessageTargeting.class , MessageTargeting.class , 100, Side.SERVER);
|
||||
|
||||
// Entity packets for 'uncloaking' entities
|
||||
try {
|
||||
|
@ -93,6 +94,18 @@ public class PacketHandler {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// Forced particle effect sent to client side
|
||||
public static void sendSpawnParticlePacket(World worldObj, final String type, Vector3 origin, Vector3 direction, float red, float green, float blue, int radius) {
|
||||
assert(!worldObj.isRemote);
|
||||
|
||||
MessageSpawnParticle beamSpawnParticle = new MessageSpawnParticle(type, origin, direction, red, green, blue);
|
||||
|
||||
// small beam are sent relative to beam center
|
||||
simpleNetworkManager.sendToAllAround(beamSpawnParticle, new TargetPoint(
|
||||
worldObj.provider.dimensionId, origin.x, origin.y, origin.z, radius));
|
||||
}
|
||||
|
||||
// Monitor/Laser/Camera updating its video channel to client side
|
||||
public static void sendVideoChannelPacket(int dimensionId, int xCoord, int yCoord, int zCoord, int videoChannel) {
|
||||
MessageVideoChannel videoChannelMessage = new MessageVideoChannel(xCoord, yCoord, zCoord, videoChannel);
|
||||
|
|
Loading…
Add table
Reference in a new issue