Implemented projector LUA API (wip)

Fixed SMP support
Fixed CME when changing shape parameters
Improved projector guide messages
Fixed server lag issue (wip)
This commit is contained in:
LemADEC 2016-06-27 03:22:23 +02:00
parent d1de099e3a
commit 03f284948e
5 changed files with 100 additions and 39 deletions

View file

@ -18,19 +18,19 @@ import net.minecraft.world.World;
public class BlockForceFieldRelay extends BlockAbstractForceField {
@SideOnly(Side.CLIENT)
private final IIcon[] icons;
private IIcon[] icons;
public BlockForceFieldRelay(final byte tier) {
super(tier, Material.iron);
isRotating = false;
setBlockName("warpdrive.forcefield.relay" + tier);
setBlockTextureName("warpdrive:forcefield/relay");
icons = new IIcon[EnumForceFieldUpgrade.length + 1];
}
@Override
public void registerBlockIcons(IIconRegister iconRegister) {
icons = new IIcon[EnumForceFieldUpgrade.length + 1];
for (EnumForceFieldUpgrade enumForceFieldUpgrade : EnumForceFieldUpgrade.values()) {
if (enumForceFieldUpgrade.maxCountOnRelay > 0) {
icons[enumForceFieldUpgrade.ordinal()] = iconRegister.registerIcon("warpdrive:forcefield/relay" + "_" + enumForceFieldUpgrade.unlocalizedName);

View file

@ -112,8 +112,8 @@ public class TileEntityAbstractForceField extends TileEntityAbstractEnergy imple
public String getStatus() {
String strEnergyStatus = getEnergyStatus();
return (worldObj != null ? StatCollector.translateToLocalFormatted("warpdrive.guide.prefix", getBlockType().getLocalizedName()) : "")
+ getBeamFrequencyStatus()
+ (strEnergyStatus.isEmpty() ? "" : "\n" + strEnergyStatus);
+ (strEnergyStatus.isEmpty() ? "" : "\n" + strEnergyStatus
+ "\n" + getBeamFrequencyStatus());
}
@Override

View file

@ -6,6 +6,11 @@ import cr0s.warpdrive.api.IForceFieldShape;
import cr0s.warpdrive.config.*;
import cr0s.warpdrive.config.Dictionary;
import cr0s.warpdrive.data.*;
import dan200.computercraft.api.lua.ILuaContext;
import dan200.computercraft.api.peripheral.IComputerAccess;
import li.cil.oc.api.machine.Arguments;
import li.cil.oc.api.machine.Callback;
import li.cil.oc.api.machine.Context;
import net.minecraft.block.Block;
import net.minecraft.block.BlockLiquid;
import net.minecraft.block.BlockStaticLiquid;
@ -29,7 +34,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
public class TileEntityForceFieldProjector extends TileEntityAbstractForceField {
private static final int PROJECTOR_MAX_ENERGY_STORED = 10000;
private static final int PROJECTOR_COOLDOWN_TICKS = 20;
private static final int PROJECTOR_COOLDOWN_TICKS = 100;
public static final int PROJECTOR_PROJECTION_UPDATE_TICKS = 8;
private static final int PROJECTOR_SETUP_TICKS = 20;
private static final int PROJECTOR_SOUND_UPDATE_TICKS = 100;
@ -76,7 +81,8 @@ public class TileEntityForceFieldProjector extends TileEntityAbstractForceField
peripheralName = "warpdriveForceFieldProjector";
addMethods(new String[] {
"status" // isConnected, isPowered, shape
"rotation",
"state"
});
for (EnumForceFieldUpgrade enumForceFieldUpgrade : EnumForceFieldUpgrade.values()) {
@ -243,11 +249,15 @@ public class TileEntityForceFieldProjector extends TileEntityAbstractForceField
return calculated_forceField.contains(vector);
}
private Set<VectorI> getInteriorPoints() {
if (!isCalculated()) {
throw new ConcurrentModificationException("Calculation ongoing...");
private boolean isPartOfInterior(VectorI vector) {
if (!isEnabled || !isValid()) {
return false;
}
return calculated_interiorField;
if (!isCalculated()) {
return false;
}
// only consider the forcefield interior
return calculated_interiorField.contains(vector);
}
private void projectForceField() {
@ -296,7 +306,7 @@ public class TileEntityForceFieldProjector extends TileEntityAbstractForceField
// skip if fusion upgrade is present and it's inside another projector area
if (forceFieldSetup.hasFusion) {
for (TileEntityForceFieldProjector projector : forceFieldSetup.projectors) {
if (projector.getInteriorPoints().contains(vector)) {
if (projector.isPartOfInterior(vector)) {
doProjectThisBlock = false;
break;
}
@ -359,7 +369,7 @@ public class TileEntityForceFieldProjector extends TileEntityAbstractForceField
if (doProjectThisBlock) {
if (forceFieldSetup.breaking_maxHardness > 0) {
doProjectThisBlock = ! isBlockBreakCanceled(null, worldObj, vector.x, vector.y, vector.z);
} else {
} else if (!(block instanceof BlockForceField)) {
doProjectThisBlock = ! isBlockPlaceCanceled(null, worldObj, vector.x, vector.y, vector.z, WarpDrive.blockForceFields[tier - 1], metadataForceField);
}
}
@ -571,6 +581,23 @@ public class TileEntityForceFieldProjector extends TileEntityAbstractForceField
}
}
public EnumForceFieldShape getShape() {
if (shape == null) {
return EnumForceFieldShape.NONE;
}
return shape;
}
void setShape(EnumForceFieldShape shape) {
this.shape = shape;
cache_forceFieldSetup = null;
isDirty.set(true);
markDirty();
if (worldObj != null) {
destroyForceField(false);
}
}
@Override
public boolean mountUpgrade(Object upgrade) {
if (super.mountUpgrade(upgrade)) {
@ -693,21 +720,55 @@ public class TileEntityForceFieldProjector extends TileEntityAbstractForceField
return true;
}
public EnumForceFieldShape getShape() {
if (shape == null) {
return EnumForceFieldShape.NONE;
}
return shape;
// OpenComputer callback methods
@Callback
@cpw.mods.fml.common.Optional.Method(modid = "OpenComputers")
public Object[] state(Context context, Arguments arguments) {
return state();
}
void setShape(EnumForceFieldShape shape) {
this.shape = shape;
cache_forceFieldSetup = null;
isDirty.set(true);
markDirty();
if (worldObj != null) {
destroyForceField(false);
@Callback
@cpw.mods.fml.common.Optional.Method(modid = "OpenComputers")
public Object[] rotation(Context context, Arguments arguments) {
if (arguments.count() == 1) {
setRotation((float)arguments.checkDouble(0), rotationPitch, rotationRoll);
} else if (arguments.count() == 2) {
setRotation((float)arguments.checkDouble(0), (float)arguments.checkDouble(1), rotationRoll);
} else if (arguments.count() == 3) {
setRotation((float)arguments.checkDouble(0), (float)arguments.checkDouble(1), (float)arguments.checkDouble(2));
}
return new Float[] { rotationYaw, rotationPitch, rotationRoll };
}
// Common OC/CC methods
private Object[] state() { // isConnected, isPowered, shape
int energy = getEnergyStored();
String status = getStatus();
return new Object[] { status, isEnabled, isConnected, isPowered, getShape().name(), energy };
}
// ComputerCraft IPeripheral methods implementation
@Override
@cpw.mods.fml.common.Optional.Method(modid = "ComputerCraft")
public Object[] callMethod(IComputerAccess computer, ILuaContext context, int method, Object[] arguments) {
String methodName = getMethodName(method);
switch (methodName) {
case "rotation":
if (arguments.length == 1) {
setRotation(toFloat(arguments[0]), rotationPitch, rotationRoll);
} else if (arguments.length == 2) {
setRotation(toFloat(arguments[0]), toFloat(arguments[1]), rotationRoll);
} else if (arguments.length == 3) {
setRotation(toFloat(arguments[0]), toFloat(arguments[1]), toFloat(arguments[2]));
}
return new Float[] { rotationYaw, rotationPitch, rotationRoll };
case "state":
return state();
}
return super.callMethod(computer, context, method, arguments);
}
private class ThreadCalculation extends Thread {

View file

@ -15,20 +15,20 @@ public enum EnumForceFieldUpgrade implements IForceFieldUpgrade, IForceFieldUpgr
// Upgrade - Compatibility - ----- Value ----- -- Scan speed -- -- Place speed -- ------- Energy costs ------- comment
// name projector relay incr. cap minimum maximum minimum maximum startup scan place entity
NONE ("none" , 0, 0, 0.0F, 0.0F, 0.000F, 0.000F, 0.000F, 0.000F, 0.0F, 0.000F, 0.000F, 0.0F, ""),
BREAKING ("breaking" , 0, 1, 1.0F, 25.0F, 0.400F, 0.500F, 0.010F, 0.100F, 70.0F, 0.020F, 1.000F, 0.0F, "value is hardness level"),
CAMOUFLAGE ("camouflage" , 0, 1, 1.0F, 3.0F, 0.600F, 0.850F, 0.700F, 0.950F, 100.0F, 0.100F, 0.300F, 0.0F, "value is boolean"),
COOLING ("cooling" , 3, 1, 30.0F, 300.0F, 0.000F, 0.000F, 0.900F, 0.900F, 15.0F, 0.020F, 0.500F, 10.0F, "value is heat units"),
FUSION ("fusion" , 1, 1, 1.0F, 1.0F, 0.000F, 0.000F, 0.000F, 0.000F, 100.0F, 0.050F, 0.050F, 0.0F, "value is boolean"),
HEATING ("heating" , 3, 1, 100.0F, 10000.0F, 0.000F, 0.000F, 0.900F, 0.900F, 15.0F, 0.100F, 1.000F, 5.0F, "value is heat units"),
INVERSION ("inversion" , 1, 0, 1.0F, 1.0F, 0.250F, 0.250F, 0.000F, 0.000F, 150.0F, 0.050F, 0.050F, 1.0F, "value is boolean"),
PUMPING ("pumping" , 0, 1, 1000.0F, 50000.0F, 0.800F, 1.000F, 0.400F, 1.000F, 80.0F, 0.010F, 0.500F, 0.0F, "value is viscosity"),
RANGE ("range" , 4, 1, 8.0F, 56.0F, 1.100F, 0.800F, 1.100F, 0.800F, 1.0F, 0.100F, 0.250F, 4.0F, "value is bonus blocks"),
BREAKING ("breaking" , 0, 1, 1.0F, 25.0F, 0.400F, 0.500F, 0.010F, 0.100F, 70.0F, 0.080F, 4.000F, 0.0F, "value is hardness level"),
CAMOUFLAGE ("camouflage" , 0, 1, 1.0F, 3.0F, 0.600F, 0.850F, 0.700F, 0.950F, 100.0F, 0.400F, 1.200F, 0.0F, "value is boolean"),
COOLING ("cooling" , 3, 1, 30.0F, 300.0F, 0.000F, 0.000F, 0.900F, 0.900F, 15.0F, 0.060F, 1.500F, 100.0F, "value is heat units"),
FUSION ("fusion" , 1, 1, 1.0F, 1.0F, 0.000F, 0.000F, 0.000F, 0.000F, 100.0F, 0.150F, 0.150F, 0.0F, "value is boolean"),
HEATING ("heating" , 3, 1, 100.0F, 10000.0F, 0.000F, 0.000F, 0.900F, 0.900F, 15.0F, 0.300F, 3.000F, 50.0F, "value is heat units"),
INVERSION ("inversion" , 1, 0, 1.0F, 1.0F, 0.250F, 0.250F, 0.000F, 0.000F, 150.0F, 0.150F, 0.150F, 10.0F, "value is boolean"),
PUMPING ("pumping" , 0, 1, 1000.0F, 50000.0F, 0.800F, 1.000F, 0.400F, 1.000F, 80.0F, 0.050F, 1.500F, 0.0F, "value is viscosity"),
RANGE ("range" , 4, 1, 8.0F, 56.0F, 1.100F, 0.800F, 1.100F, 0.800F, 1.0F, 0.300F, 0.750F, 40.0F, "value is bonus blocks"),
ROTATION ("rotation" , 1, 0, 1.0F, 1.0F, 0.000F, 0.000F, 0.000F, 0.000F, 10.0F, 0.000F, 0.000F, 0.0F, "value is boolean"),
SHOCK ("shock" , 3, 1, 1.0F, 10.0F, 0.800F, 0.800F, 0.800F, 0.800F, 30.0F, 0.100F, 2.000F, 30.0F, "value is damage points"),
SILENCER ("silencer" , 1, 0, 1.0F, 1.0F, 0.000F, 0.000F, 0.000F, 0.000F, 0.0F, 0.010F, 0.020F, 0.0F, "value is boolean"),
SPEED ("speed" , 4, 1, 1.0F, 20.0F, 1.250F, 6.000F, 1.200F, 5.000F, 20.0F, 0.100F, 1.000F, 5.0F, "value is not used (just a counter)"),
STABILIZATION("stabilization", 0, 1, 1.0F, 6.0F, 0.450F, 0.550F, 0.050F, 0.150F, 40.0F, 0.100F, 1.000F, 0.0F, "value is boolean"),
THICKNESS ("thickness" , 5, 1, 0.2F, 1.0F, 0.800F, 1.600F, 0.000F, 0.000F, 10.0F, 0.100F, 1.000F, 1.0F, "value is bonus ratio"),
SHOCK ("shock" , 3, 1, 1.0F, 10.0F, 0.800F, 0.800F, 0.800F, 0.800F, 30.0F, 0.300F, 4.000F, 300.0F, "value is damage points"),
SILENCER ("silencer" , 1, 0, 1.0F, 1.0F, 0.000F, 0.000F, 0.000F, 0.000F, 0.0F, 0.030F, 0.060F, 0.0F, "value is boolean"),
SPEED ("speed" , 4, 1, 1.0F, 20.0F, 1.250F, 6.000F, 1.200F, 5.000F, 20.0F, 0.100F, 1.000F, 50.0F, "value is not used (just a counter)"),
STABILIZATION("stabilization", 0, 1, 1.0F, 6.0F, 0.450F, 0.550F, 0.050F, 0.150F, 40.0F, 0.250F, 3.200F, 0.0F, "value is boolean"),
THICKNESS ("thickness" , 5, 1, 0.2F, 1.0F, 0.800F, 1.600F, 0.000F, 0.000F, 10.0F, 0.450F, 2.400F, 10.0F, "value is bonus ratio"),
TRANSLATION ("translation" , 1, 0, 1.0F, 1.0F, 0.000F, 0.000F, 0.000F, 0.000F, 10.0F, 0.000F, 0.000F, 0.0F, "value is boolean"),
;

View file

@ -184,7 +184,7 @@ public class ForceFieldSetup extends GlobalPosition {
if (isValidCamouflage(blockCandidate)) {
blockCamouflage = blockCandidate;
metadataCamouflage = tileEntity.getWorldObj().getBlockMetadata(tileEntity.xCoord, tileEntity.yCoord + 1, tileEntity.zCoord);
colorMultiplierCamouflage = blockCandidate.colorMultiplier(tileEntity.getWorldObj(), tileEntity.xCoord, tileEntity.yCoord + 1, tileEntity.zCoord);
colorMultiplierCamouflage = 0x808080; // blockCandidate.colorMultiplier(tileEntity.getWorldObj(), tileEntity.xCoord, tileEntity.yCoord + 1, tileEntity.zCoord);
lightCamouflage = blockCandidate.getLightValue(tileEntity.getWorldObj(), tileEntity.xCoord, tileEntity.yCoord + 1, tileEntity.zCoord);
}
}