Jacobs ladders cause damage when touched

applying salt to Jacobs ladder's colors the arc orange (due to sodium)
This commit is contained in:
malte0811 2017-03-03 17:52:22 +01:00
parent 7c9d8ff8fb
commit a15107025d
5 changed files with 166 additions and 29 deletions

View file

@ -56,5 +56,7 @@ public class IWConfig {
public static class HVStuff {
@Comment({"The amount of Eu a Jacobs Ladder uses per tick, sorted by size of the ladder"})
public static double[] jacobsUsageEU = {10, 20, 50};
@Comment({"The damage dealt by a small Jacobs Ladder. Normal Ladders deal twice this damage, huge ones 3 times as much"})
public static float jacobsBaseDmg = 5;
}
}

View file

@ -36,6 +36,7 @@ import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumFacing.AxisDirection;
import net.minecraft.util.EnumHand;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
@ -59,7 +60,7 @@ public class BlockJacobsLadder extends Block implements IMetaEnum {
String name = "jacobs_ladder";
GameRegistry.register(this, new ResourceLocation(IndustrialWires.MODID, name));
GameRegistry.register(new ItemBlockIW(this), new ResourceLocation(IndustrialWires.MODID, name));
setUnlocalizedName(name);
setUnlocalizedName(IndustrialWires.MODID+"."+name);
setCreativeTab(IndustrialWires.creativeTab);
}
@ -155,14 +156,14 @@ public class BlockJacobsLadder extends Block implements IMetaEnum {
@Override
public IBlockState getStateForPlacement(World world, BlockPos pos, EnumFacing facing, float hitX, float hitY, float hitZ, int meta, EntityLivingBase placer, ItemStack stack) {
EnumFacing f = facing;
EnumFacing f = facing.getOpposite();
if (facing.getAxis() == EnumFacing.Axis.Y) {
double dX = hitX - .5;
double dZ = hitZ - .5;
if (Math.abs(dX) > Math.abs(dZ)) {
f = EnumFacing.getFacingFromAxis(dX > 0 ? AxisDirection.NEGATIVE : AxisDirection.POSITIVE, EnumFacing.Axis.X);
f = EnumFacing.getFacingFromAxis(dX > 0 ? AxisDirection.POSITIVE : AxisDirection.NEGATIVE, EnumFacing.Axis.X);
} else {
f = EnumFacing.getFacingFromAxis(dZ > 0 ? AxisDirection.NEGATIVE : AxisDirection.POSITIVE, EnumFacing.Axis.Z);
f = EnumFacing.getFacingFromAxis(dZ > 0 ? AxisDirection.POSITIVE : AxisDirection.NEGATIVE, EnumFacing.Axis.Z);
}
}
return super.getStateForPlacement(world, pos, facing, hitX, hitY, hitZ, meta, placer, stack).withProperty(IEProperties.FACING_HORIZONTAL, f);
@ -230,5 +231,18 @@ public class BlockJacobsLadder extends Block implements IMetaEnum {
@Override
public void onEntityCollidedWithBlock(World worldIn, BlockPos pos, IBlockState state, Entity entityIn) {
super.onEntityCollidedWithBlock(worldIn, pos, state, entityIn);
TileEntity te = worldIn.getTileEntity(pos);
if (te instanceof TileEntityJacobsLadder) {
((TileEntityJacobsLadder) te).onEntityTouch(entityIn);
}
}
@Override
public boolean onBlockActivated(World worldIn, BlockPos pos, IBlockState state, EntityPlayer playerIn, EnumHand hand, @Nullable ItemStack heldItem, EnumFacing side, float hitX, float hitY, float hitZ) {
TileEntity te = worldIn.getTileEntity(pos);
if (te instanceof TileEntityJacobsLadder) {
return ((TileEntityJacobsLadder) te).onActivated(playerIn, hand, heldItem);
}
return super.onBlockActivated(worldIn, pos, state, playerIn, hand, heldItem, side, hitX, hitY, hitZ);
}
}

View file

@ -18,8 +18,10 @@
package malte0811.industrialWires.blocks;
import blusunrize.immersiveengineering.api.ApiUtils;
import blusunrize.immersiveengineering.common.blocks.IEBlockInterfaces;
import blusunrize.immersiveengineering.common.blocks.TileEntityIEBase;
import blusunrize.immersiveengineering.common.util.IELogger;
import ic2.api.energy.event.EnergyTileLoadEvent;
import ic2.api.energy.event.EnergyTileUnloadEvent;
import ic2.api.energy.tile.IEnergyEmitter;
@ -31,6 +33,10 @@ import malte0811.industrialWires.util.Beziers;
import malte0811.industrialWires.util.DualEnergyStorage;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.tileentity.TileEntity;
@ -42,6 +48,7 @@ import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.energy.CapabilityEnergy;
import net.minecraftforge.energy.IEnergyStorage;
import net.minecraftforge.oredict.OreDictionary;
import javax.annotation.Nullable;
@ -63,6 +70,7 @@ public class TileEntityJacobsLadder extends TileEntityIEBase implements ITickabl
private boolean addedToIC2Net = false;
private int soundPhase;
private Vec3d soundPos;
public double salt;
public TileEntityJacobsLadder(LadderSize s) {
size = s;
@ -131,7 +139,7 @@ public class TileEntityJacobsLadder extends TileEntityIEBase implements ITickabl
for (int i = 1; i < size.arcPoints - 1; i++) {
controlMovement[i] = Beziers.getPoint(t, controlControls[i - 1]).subtract(controls[i]);
}
if (soundPhase<0) {
if (soundPhase < 0) {
IndustrialWires.proxy.playJacobsLadderSound(this, 0, soundPos);
soundPhase = 0;
}
@ -150,10 +158,18 @@ public class TileEntityJacobsLadder extends TileEntityIEBase implements ITickabl
timeTillActive--;
} else if (timeTillActive == 0 && t < 1) {
t += tStep;
if (salt > 0) {
salt -= 1D/(20*20);//20 seconds per item of salt
} else if (salt < 0) {
salt = 0;
}
}
}
private void initArc(int delay) {
if (controlMovement == null) {
initControl();
}
controls[0] = new Vec3d(0, 0, 0);
controls[size.arcPoints - 1] = new Vec3d(size.bottomDistance, 0, 0);
controlMovement[0] = new Vec3d(-(size.topDistance - size.bottomDistance) / (2 * size.tickToTop), size.height / size.tickToTop, 0);
@ -169,9 +185,6 @@ public class TileEntityJacobsLadder extends TileEntityIEBase implements ITickabl
soundPos = new Vec3d(soundX, soundY, soundZ);
soundPhase = -1;
timeTillActive = delay;
if (controlMovement==null) {
initControl();
}
}
private double widthFromHeight(double h) {
@ -188,6 +201,7 @@ public class TileEntityJacobsLadder extends TileEntityIEBase implements ITickabl
dummy = nbt.getInteger("dummy");
energy = DualEnergyStorage.readFromNBT(nbt.getCompoundTag("energy"));
facing = EnumFacing.HORIZONTALS[nbt.getInteger("facing")];
salt = nbt.getDouble("salt");
}
@Override
@ -196,6 +210,7 @@ public class TileEntityJacobsLadder extends TileEntityIEBase implements ITickabl
nbt.setInteger("dummy", dummy);
energy.writeToNbt(nbt, "energy");
nbt.setInteger("facing", facing.getHorizontalIndex());
nbt.setDouble("salt", salt);
}
private NBTTagCompound writeArcStarter() {
@ -204,13 +219,14 @@ public class TileEntityJacobsLadder extends TileEntityIEBase implements ITickabl
nbt.setTag("ctrlCtrl", ctrlCtrl);
nbt.setInteger("timeTillActive", timeTillActive);
nbt.setDouble("tStep", tStep);
nbt.setBoolean("start", true);
return nbt;
}
private void readArcStarter(NBTTagCompound nbt) {
controlControls = read2DVecArray(nbt.getTagList("ctrlCtrl", 9));
tStep = nbt.getDouble("tStep");
Minecraft.getMinecraft().addScheduledTask(()->initArc(nbt.getInteger("timeTillActive")));
Minecraft.getMinecraft().addScheduledTask(() -> initArc(nbt.getInteger("timeTillActive")));
}
private Vec3d[][] read2DVecArray(NBTTagList nbt) {
@ -280,14 +296,71 @@ public class TileEntityJacobsLadder extends TileEntityIEBase implements ITickabl
@Override
public void onSync(NBTTagCompound nbt) {
if (nbt.hasKey("salt")) {
salt = nbt.getDouble("salt");
}
if (nbt.getBoolean("cancel")) {
timeTillActive = -1;
IndustrialWires.proxy.playJacobsLadderSound(this, -1, soundPos);
} else {
} else if (nbt.getBoolean("start")) {
readArcStarter(nbt);
}
}
public boolean isActive() {
return timeTillActive == 0 && t < 1;
}
public void onEntityTouch(Entity e) {
if (isDummy() && !worldObj.isRemote) {
TileEntity master = worldObj.getTileEntity(pos.down(dummy));
if (master instanceof TileEntityJacobsLadder && ((TileEntityJacobsLadder) master).isActive()) {
hurtEntity(e);
}
}
}
private void hurtEntity(Entity e) {
e.attackEntityFrom(new DamageSource("industrialwires.jacobs_ladder"), IWConfig.HVStuff.jacobsBaseDmg * (size.ordinal() + 1));
}
public boolean onActivated(EntityPlayer playerIn, EnumHand hand, ItemStack heldItem) {
TileEntity masterTE = dummy == 0 ? this : worldObj.getTileEntity(pos.down(dummy));
if (masterTE instanceof TileEntityJacobsLadder) {
TileEntityJacobsLadder master = (TileEntityJacobsLadder) masterTE;
if (master.isActive()) {
if (!worldObj.isRemote) {
hurtEntity(playerIn);
}
return true;
} else if (heldItem != null && ApiUtils.compareToOreName(heldItem, "itemSalt")) {
return master.salt(playerIn, hand, heldItem);
}
}
return false;
}
private boolean salt(EntityPlayer player, EnumHand hand, ItemStack held) {
IELogger.info("Salt: " + salt);
if (salt < 3) {
if (!worldObj.isRemote) {
salt++;
if (!player.isCreative()) {
held.stackSize--;
if (held.stackSize <= 0) {
player.setHeldItem(hand, null);
}
}
NBTTagCompound update = new NBTTagCompound();
update.setDouble("salt", salt);
markDirty();
IndustrialWires.packetHandler.sendToAll(new MessageTileSyncIW(this, update));
}
return true;
}
return false;
}
//ENERGY
@Override
public double getDemandedEnergy() {
@ -386,7 +459,7 @@ public class TileEntityJacobsLadder extends TileEntityIEBase implements ITickabl
public final float soundVolume;
LadderSize(int arcP, int movP, double height, double topD, double bottomD, int ttTop, double zMax, double extraH,
double iOff, double hOff, int dummies, int delay, int points, double renderDia, float volume) {
double iOff, double hOff, int dummies, int delay, int points, double renderDia, float volume) {
arcPoints = arcP;
movementPoints = movP;
this.height = height;

View file

@ -19,6 +19,7 @@
package malte0811.industrialWires.client.render;
import malte0811.industrialWires.blocks.TileEntityJacobsLadder;
import malte0811.industrialWires.blocks.TileEntityJacobsLadder.LadderSize;
import malte0811.industrialWires.util.Beziers;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.OpenGlHelper;
@ -54,7 +55,7 @@ public class TileRenderJacobsLadder extends TileEntitySpecialRenderer<TileEntity
Vec3d speed = tile.controlMovement[i];
controls[i] = tile.controls[i].addVector(speed.xCoord * partialTicks, speed.yCoord * partialTicks, speed.zCoord * partialTicks);
}
drawBezier(controls, tile.size.renderDiameter, tile.size.renderPoints);
drawBezier(controls, tile.salt, tile.size);
//DEBUG CODE
/*for (Vec3d[] c:tile.controlControls) {
drawBezier(c, .05, steps);
@ -79,34 +80,72 @@ public class TileRenderJacobsLadder extends TileEntitySpecialRenderer<TileEntity
}
}
private void drawBezier(Vec3d[] controls, double diameter, int steps) {
private void drawBezier(Vec3d[] controls, double salt, LadderSize size) {
int steps = size.renderPoints;
double diameter = size.renderDiameter;
Vec3d radY = new Vec3d(0, diameter / 2, 0);
Vec3d radZ = new Vec3d(0, 0, diameter / 2);
Tessellator tes = Tessellator.getInstance();
VertexBuffer vertBuffer = tes.getBuffer();
vertBuffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION);
float[][] colors = new float[steps+1][];
vertBuffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_COLOR);
Vec3d last = Beziers.getPoint(0, controls);
for (double d = 1D / steps; d < 1+1D/(2*steps); d += 1D / steps) {
colors[0] = getColor(0, salt, size);
for (int i = 1;i<=steps;i++) {
double d = i/(double)steps;
colors[i] = getColor(d, salt, size);
Vec3d pos = Beziers.getPoint(d, controls);
drawQuad(last, pos, radY, vertBuffer);
drawQuad(last, pos, radZ, vertBuffer);
drawQuad(last, pos, radY, colors[i-1], colors[i], vertBuffer);
drawQuad(last, pos, radZ, colors[i-1], colors[i], vertBuffer);
last = pos;
}
tes.draw();
}
private final float[] saltColor = {1, 190/255F, 50/255F};
private final float[] airColor = {1, .85F, 1};
private float[] getColor(double t, double salt, LadderSize size) {
salt = Math.min(salt, 1);
int factor = 20;
double smallMin = Math.exp(-.5);
double normalMin = Math.exp(-.25*factor);
double hugeMin = Math.exp(-.75*factor);
double saltyness = 0;
double t2 = t-.5;
switch (size) {
case SMALL:
saltyness = salt*(1-.9*(Math.exp(-Math.abs(t2))-smallMin));
break;
case NORMAL:
saltyness = salt*(1-.9*(Math.exp(-factor*t2*t2)-normalMin));
break;
case HUGE:
saltyness = salt*(1-.9*(Math.exp(-Math.abs(factor*t2*t2*t2))-hugeMin));
break;
}
return interpolate(saltyness, saltColor, 1-saltyness, airColor);
}
private float[] interpolate(double a, float[] cA, double b, float[] cB) {
float[] ret = new float[cA.length];
for (int i = 0;i<ret.length;i++) {
ret[i] = (float) (a*cA[i]+b*cB[i]);
}
return ret;
}
private void drawQuad(Vec3d v0, Vec3d v1, Vec3d rad, VertexBuffer vertexBuffer) {
TextureAtlasSprite tex = ModelLoader.White.INSTANCE;
vertexBuffer.pos(v1.xCoord - rad.xCoord, v1.yCoord - rad.yCoord, v1.zCoord - rad.zCoord).endVertex();
vertexBuffer.pos(v0.xCoord - rad.xCoord, v0.yCoord - rad.yCoord, v0.zCoord - rad.zCoord).endVertex();
vertexBuffer.pos(v0.xCoord + rad.xCoord, v0.yCoord + rad.yCoord, v0.zCoord + rad.zCoord).endVertex();
vertexBuffer.pos(v1.xCoord + rad.xCoord, v1.yCoord + rad.yCoord, v1.zCoord + rad.zCoord).endVertex();
private void drawQuad(Vec3d v0, Vec3d v1, Vec3d rad, float[] color0, float[] color1, VertexBuffer vertexBuffer) {
color(color1, vertexBuffer.pos(v1.xCoord - rad.xCoord, v1.yCoord - rad.yCoord, v1.zCoord - rad.zCoord)).endVertex();
color(color0, vertexBuffer.pos(v0.xCoord - rad.xCoord, v0.yCoord - rad.yCoord, v0.zCoord - rad.zCoord)).endVertex();
color(color0, vertexBuffer.pos(v0.xCoord + rad.xCoord, v0.yCoord + rad.yCoord, v0.zCoord + rad.zCoord)).endVertex();
color(color1, vertexBuffer.pos(v1.xCoord + rad.xCoord, v1.yCoord + rad.yCoord, v1.zCoord + rad.zCoord)).endVertex();
vertexBuffer.pos(v1.xCoord + rad.xCoord, v1.yCoord + rad.yCoord, v1.zCoord + rad.zCoord).endVertex();
vertexBuffer.pos(v0.xCoord + rad.xCoord, v0.yCoord + rad.yCoord, v0.zCoord + rad.zCoord).endVertex();
vertexBuffer.pos(v0.xCoord - rad.xCoord, v0.yCoord - rad.yCoord, v0.zCoord - rad.zCoord).endVertex();
vertexBuffer.pos(v1.xCoord - rad.xCoord, v1.yCoord - rad.yCoord, v1.zCoord - rad.zCoord).endVertex();
color(color1, vertexBuffer.pos(v1.xCoord + rad.xCoord, v1.yCoord + rad.yCoord, v1.zCoord + rad.zCoord)).endVertex();
color(color0, vertexBuffer.pos(v0.xCoord + rad.xCoord, v0.yCoord + rad.yCoord, v0.zCoord + rad.zCoord)).endVertex();
color(color0, vertexBuffer.pos(v0.xCoord - rad.xCoord, v0.yCoord - rad.yCoord, v0.zCoord - rad.zCoord)).endVertex();
color(color1, vertexBuffer.pos(v1.xCoord - rad.xCoord, v1.yCoord - rad.yCoord, v1.zCoord - rad.zCoord)).endVertex();
}
private VertexBuffer color(float[] color, VertexBuffer vb) {
vb.color(color[0], color[1], color[2], 1);
return vb;
}
}

View file

@ -13,6 +13,9 @@ tile.mechanical_converter.ie_motor.name=Rotational Motor
tile.mechanical_converter.ie_to_ic2.name=Converter: Rotational To Kinetic
tile.mechanical_converter.ic2_to_ie.name=Converter: Kinetic To Rotational
tile.industrialwires.jacobs_ladder.small.name=Small Jacob's ladder
tile.industrialwires.jacobs_ladder.normal.name=Jacob's ladder
tile.industrialwires.jacobs_ladder.huge.name=Huge Jacob's ladder
item.industrialwires.ic2wireCoil.tin.name=Tin Wire Coil
item.industrialwires.ic2wireCoil.copper.name=Copper Wire Coil
@ -27,6 +30,8 @@ industrialwires.desc.recipe=Please check the Engineer's manual for recipe detail
industrialwires.chat.tooLong=This coil does not contain enough wire for this connection
industrialwires.chat.stackSize=Linking is only possible with a stack of size 1
death.attack.industrialwires.jacobs_ladder=%1$s was electrocuted by a Jacob's Ladder
itemGroup.industrialwires=Industrial Wires
@ -42,4 +47,8 @@ ie.manual.entry.industrialWires.mechConv.name=Mechanical Converters
ie.manual.entry.industrialWires.mechConv.subtext=I made rotational energy for this!
ie.manual.entry.industrialWires.mechConv0=Both the IC2 and IE company produce products that run on kinetic energy of some sort. The new converters from IndustrialWires allow you to convert between these two forms of energy!<br>To use the "Converter: Rotational To Kinetic" attach a source of IE rotational energy
ie.manual.entry.industrialWires.mechConv1=like a waterwheel or a motor (see page 3) to the side marked with a gear and a consumer of IC2 kinetic energy to the opposite side. The "Converter: Kinetic To Rotational" is used in a similar way (Rotational and kinetic energy have to be swapped).<br>Unfortunately some energy is
ie.manual.entry.industrialWires.mechConv2=lost with each conversion.<br>As a little extra the "Mechanical converter" product series also contains a Rotational Motor: It consumes IF to produce IE rotational energy. As with the converters this is not a lossless process.
ie.manual.entry.industrialWires.mechConv2=lost with each conversion.<br>As a little extra the "Mechanical converter" product series also contains a Rotational Motor: It consumes IF to produce IE rotational energy. As with the converters this is not a lossless process.
ie.manual.entry.industrialWires.jacobs.name=Jacob's Ladders
ie.manual.entry.industrialWires.jacobs.subtext=Probably contain PCB's!
ie.manual.entry.industrialWires.jacobs0=By applying a high voltage between 2 electrodes forming a "V" one can create an arc travelling upwards. They don't serve a particular purpose apart from being a nice-looking waste of power.