Merge remote-tracking branch 'origin/MC1.7' into MC1.12
This commit is contained in:
commit
63158a6aaf
14 changed files with 607 additions and 68 deletions
|
@ -109,6 +109,7 @@ import net.minecraft.creativetab.CreativeTabs;
|
|||
import net.minecraft.enchantment.Enchantment;
|
||||
import net.minecraft.init.SoundEvents;
|
||||
import net.minecraft.inventory.EntityEquipmentSlot;
|
||||
import net.minecraft.item.EnumDyeColor;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemArmor;
|
||||
import net.minecraft.item.ItemArmor.ArmorMaterial;
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
package cr0s.warpdrive.api;
|
||||
|
||||
import cr0s.warpdrive.api.computer.IShipController;
|
||||
|
||||
import net.minecraft.util.math.AxisAlignedBB;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.fml.common.eventhandler.Cancelable;
|
||||
|
@ -17,26 +20,30 @@ public abstract class EventWarpDrive extends Event {
|
|||
public final World worldCurrent;
|
||||
public final BlockPos posCurrent;
|
||||
|
||||
// ship stats
|
||||
public final int mass;
|
||||
// ship access
|
||||
public final IShipController shipController;
|
||||
|
||||
// movement description
|
||||
public final String jumpType;
|
||||
public final int distance;
|
||||
// movement description, see EnumShipMovementType
|
||||
public final String movementType;
|
||||
|
||||
public Ship(final World world, final BlockPos blockPos,
|
||||
final int mass, final String jumpType, final int distance) {
|
||||
final IShipController shipController, final String movementType) {
|
||||
super();
|
||||
|
||||
this.worldCurrent = world;
|
||||
this.posCurrent = blockPos;
|
||||
this.mass = mass;
|
||||
this.jumpType = jumpType;
|
||||
this.distance = distance;
|
||||
|
||||
this.shipController = shipController;
|
||||
|
||||
this.movementType = movementType;
|
||||
}
|
||||
|
||||
// event used to update movement costs for display or an actual jump
|
||||
public static class MovementCosts extends Ship {
|
||||
|
||||
public final int mass;
|
||||
public final int distance;
|
||||
|
||||
// original values for reference
|
||||
public final int warmup_seconds_initial;
|
||||
public final int energyRequired_initial;
|
||||
|
@ -52,13 +59,18 @@ public abstract class EventWarpDrive extends Event {
|
|||
private int cooldown_seconds;
|
||||
|
||||
public MovementCosts(final World world, final BlockPos blockPos,
|
||||
final int mass, final String jumpType, final int distance,
|
||||
final IShipController shipController, final String movementType,
|
||||
final int mass,
|
||||
final int distance,
|
||||
final int maximumDistance_blocks,
|
||||
final int energyRequired,
|
||||
final int warmup_seconds,
|
||||
final int sickness_seconds,
|
||||
final int cooldown_seconds) {
|
||||
super(world, blockPos, mass, jumpType, distance);
|
||||
super(world, blockPos, shipController, movementType);
|
||||
|
||||
this.mass = mass;
|
||||
this.distance = distance;
|
||||
|
||||
this.warmup_seconds_initial = warmup_seconds;
|
||||
this.warmup_seconds = warmup_seconds;
|
||||
|
@ -113,6 +125,7 @@ public abstract class EventWarpDrive extends Event {
|
|||
}
|
||||
}
|
||||
|
||||
// event for canceling a jump by broad permissions, called prior to jump
|
||||
@Cancelable
|
||||
public static class PreJump extends Ship {
|
||||
|
||||
|
@ -120,8 +133,8 @@ public abstract class EventWarpDrive extends Event {
|
|||
private final StringBuilder reason;
|
||||
|
||||
public PreJump(final World world, final BlockPos blockPos,
|
||||
final int mass, final String jumpType, final int distance) {
|
||||
super(world, blockPos, mass, jumpType, distance);
|
||||
final IShipController shipController, final String movementType) {
|
||||
super(world, blockPos, shipController, movementType);
|
||||
|
||||
this.reason = new StringBuilder();
|
||||
}
|
||||
|
@ -138,11 +151,63 @@ public abstract class EventWarpDrive extends Event {
|
|||
}
|
||||
}
|
||||
|
||||
public static class PostJump extends Ship {
|
||||
// event for checking collision at target location, called during jump until a valid location is found
|
||||
@Cancelable
|
||||
public static class TargetCheck extends Ship {
|
||||
|
||||
public PostJump(final World world, final BlockPos blockPos,
|
||||
final int mass, final String jumpType, final int distance) {
|
||||
super(world, blockPos, mass, jumpType, distance);
|
||||
// movement vector
|
||||
public final int moveX;
|
||||
public final int moveY;
|
||||
public final int moveZ;
|
||||
|
||||
// target position
|
||||
public final World worldTarget;
|
||||
public final AxisAlignedBB aabbTarget;
|
||||
|
||||
// cancellation message
|
||||
private final StringBuilder reason;
|
||||
|
||||
public TargetCheck(final World worldCurrent, final BlockPos blockPos,
|
||||
final IShipController shipController, final String movementType,
|
||||
final int moveX, final int moveY, final int moveZ,
|
||||
final World worldTarget, final AxisAlignedBB aabbTarget) {
|
||||
super(worldCurrent, blockPos, shipController, movementType);
|
||||
|
||||
this.moveX = moveX;
|
||||
this.moveY = moveY;
|
||||
this.moveZ = moveZ;
|
||||
|
||||
this.worldTarget = worldTarget;
|
||||
this.aabbTarget = aabbTarget;
|
||||
|
||||
this.reason = new StringBuilder();
|
||||
}
|
||||
|
||||
public String getReason() {
|
||||
return reason.toString();
|
||||
}
|
||||
|
||||
public void appendReason(final String reasonAdded) {
|
||||
if (reason.length() > 0) {
|
||||
reason.append("\n");
|
||||
}
|
||||
reason.append(reasonAdded);
|
||||
}
|
||||
}
|
||||
|
||||
// event reporting when a jump is cancelled or successful
|
||||
public static class JumpResult extends Ship {
|
||||
|
||||
public final boolean isSuccessful;
|
||||
public final String reason;
|
||||
|
||||
public JumpResult(final World world, final BlockPos blockPos,
|
||||
final IShipController shipController, final String jumpType,
|
||||
final boolean isSuccessful, final String reason) {
|
||||
super(world, blockPos, shipController, jumpType);
|
||||
|
||||
this.isSuccessful = isSuccessful;
|
||||
this.reason = reason;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,5 +21,5 @@ public interface IDamageReceiver {
|
|||
* Returns the remaining damage level or 0 if it was fully absorbed.
|
||||
*/
|
||||
int applyDamage(final IBlockState blockState, final World world, final BlockPos blockPos,
|
||||
final DamageSource damageSource, final int damageParameter, final Vector3 damageDirection, final int damageLevel);
|
||||
final DamageSource damageSource, final int damageParameter, final Vector3 damageDirection, final int damageLevel);
|
||||
}
|
||||
|
|
|
@ -4,9 +4,12 @@ import cr0s.warpdrive.Commons;
|
|||
import cr0s.warpdrive.WarpDrive;
|
||||
import cr0s.warpdrive.api.IBeamFrequency;
|
||||
import cr0s.warpdrive.api.IDamageReceiver;
|
||||
import cr0s.warpdrive.block.forcefield.BlockForceField;
|
||||
import cr0s.warpdrive.block.forcefield.TileEntityForceField;
|
||||
import cr0s.warpdrive.config.Dictionary;
|
||||
import cr0s.warpdrive.config.WarpDriveConfig;
|
||||
import cr0s.warpdrive.data.CelestialObjectManager;
|
||||
import cr0s.warpdrive.data.ForceFieldSetup;
|
||||
import cr0s.warpdrive.data.SoundEvents;
|
||||
import cr0s.warpdrive.data.Vector3;
|
||||
import cr0s.warpdrive.network.PacketHandler;
|
||||
|
@ -22,19 +25,25 @@ import java.util.List;
|
|||
import java.util.Map.Entry;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.material.Material;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityList;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.util.SoundCategory;
|
||||
import net.minecraft.util.DamageSource;
|
||||
import net.minecraft.util.math.AxisAlignedBB;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.BlockPos.MutableBlockPos;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.util.math.RayTraceResult;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import net.minecraftforge.fml.common.Optional;
|
||||
|
||||
|
@ -112,15 +121,198 @@ public class TileEntityLaser extends TileEntityAbstractLaser implements IBeamFre
|
|||
if (isEmitting) {
|
||||
energyFromOtherBeams += amount;
|
||||
if (WarpDriveConfig.LOGGING_WEAPON) {
|
||||
WarpDrive.logger.info(this + " Added energy " + amount);
|
||||
WarpDrive.logger.info(String.format("%s Added boosting energy %d for a total accumulation of %d",
|
||||
this, amount, energyFromOtherBeams));
|
||||
}
|
||||
} else {
|
||||
if (WarpDriveConfig.LOGGING_WEAPON) {
|
||||
WarpDrive.logger.info(this + " Ignored energy " + amount);
|
||||
WarpDrive.logger.warn(String.format("%s Ignored boosting energy %d",
|
||||
this, amount));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// loosely based on World.rayTraceBlocks
|
||||
// - replaced byte b0 with EnumFacing
|
||||
// - inverted 2nd flag
|
||||
// - added force field pass through based on beamFrequency
|
||||
// - increased max range from 200 to laser limit
|
||||
// - code cleanup
|
||||
public static RayTraceResult rayTraceBlocks(final World world, final Vec3d vSource, final Vec3d vTarget, final int beamFrequency,
|
||||
final boolean stopOnLiquid, final boolean checkBlockWithoutBoundingBox, final boolean returnLastUncollidableBlock) {
|
||||
// validate parameters
|
||||
if (Double.isNaN(vSource.x) || Double.isNaN(vSource.y) || Double.isNaN(vSource.z)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (Double.isNaN(vTarget.x) || Double.isNaN(vTarget.y) || Double.isNaN(vTarget.z)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// check collision at source
|
||||
final int xSource = MathHelper.floor(vSource.x);
|
||||
final int ySource = MathHelper.floor(vSource.y);
|
||||
final int zSource = MathHelper.floor(vSource.z);
|
||||
final MutableBlockPos mutableBlockPos = new MutableBlockPos(xSource, ySource, zSource);
|
||||
final IBlockState blockStateSource = world.getBlockState(mutableBlockPos);
|
||||
|
||||
if ( (checkBlockWithoutBoundingBox || blockStateSource.getCollisionBoundingBox(world, mutableBlockPos) != Block.NULL_AABB)
|
||||
&& blockStateSource.getBlock().canCollideCheck(blockStateSource, stopOnLiquid)) {
|
||||
final RayTraceResult rayTraceResult = blockStateSource.collisionRayTrace(world, mutableBlockPos, vSource, vTarget);
|
||||
if (rayTraceResult != null) {
|
||||
return rayTraceResult;
|
||||
}
|
||||
}
|
||||
|
||||
// loop positions along trajectory
|
||||
final int xTarget = MathHelper.floor(vTarget.x);
|
||||
final int yTarget = MathHelper.floor(vTarget.y);
|
||||
final int zTarget = MathHelper.floor(vTarget.z);
|
||||
|
||||
final Vector3 v3Current = new Vector3(vSource.x, vSource.y, vSource.z);
|
||||
int xCurrent = xSource;
|
||||
int yCurrent = ySource;
|
||||
int zCurrent = zSource;
|
||||
RayTraceResult rayTraceResultMissed = null;
|
||||
|
||||
int countLoop = WarpDriveConfig.LASER_CANNON_RANGE_MAX * 2;
|
||||
while (countLoop-- >= 0) {
|
||||
// sanity check
|
||||
if (Double.isNaN(v3Current.x) || Double.isNaN(v3Current.y) || Double.isNaN(v3Current.z)) {
|
||||
WarpDrive.logger.error(String.format("Critical error while ray tracing blocks from %s to %s in %s",
|
||||
vSource, vTarget, Commons.format(world)));
|
||||
return null;
|
||||
}
|
||||
|
||||
// check arrival
|
||||
if (xCurrent == xTarget && yCurrent == yTarget && zCurrent == zTarget) {
|
||||
return returnLastUncollidableBlock ? rayTraceResultMissed : null;
|
||||
}
|
||||
|
||||
// propose 1 block step along each axis
|
||||
boolean hasOffsetX = true;
|
||||
boolean hasOffsetY = true;
|
||||
boolean hasOffsetZ = true;
|
||||
double xProposed = 999.0D;
|
||||
double yProposed = 999.0D;
|
||||
double zProposed = 999.0D;
|
||||
|
||||
if (xTarget > xCurrent) {
|
||||
xProposed = xCurrent + 1.0D;
|
||||
} else if (xTarget < xCurrent) {
|
||||
xProposed = xCurrent + 0.0D;
|
||||
} else {
|
||||
hasOffsetX = false;
|
||||
}
|
||||
|
||||
if (yTarget > yCurrent) {
|
||||
yProposed = yCurrent + 1.0D;
|
||||
} else if (yTarget < yCurrent) {
|
||||
yProposed = yCurrent + 0.0D;
|
||||
} else {
|
||||
hasOffsetY = false;
|
||||
}
|
||||
|
||||
if (zTarget > zCurrent) {
|
||||
zProposed = zCurrent + 1.0D;
|
||||
} else if (zTarget < zCurrent) {
|
||||
zProposed = zCurrent + 0.0D;
|
||||
} else {
|
||||
hasOffsetZ = false;
|
||||
}
|
||||
|
||||
// compute normalized movement
|
||||
double xDeltaNormalized = 999.0D;
|
||||
double yDeltaNormalized = 999.0D;
|
||||
double zDeltaNormalized = 999.0D;
|
||||
final double xDeltaToTarget = vTarget.x - v3Current.x;
|
||||
final double yDeltaToTarget = vTarget.y - v3Current.y;
|
||||
final double zDeltaToTarget = vTarget.z - v3Current.z;
|
||||
|
||||
if (hasOffsetX) {
|
||||
xDeltaNormalized = (xProposed - v3Current.x) / xDeltaToTarget;
|
||||
if (xDeltaNormalized == -0.0D) {
|
||||
xDeltaNormalized = -1.0E-4D;
|
||||
}
|
||||
}
|
||||
|
||||
if (hasOffsetY) {
|
||||
yDeltaNormalized = (yProposed - v3Current.y) / yDeltaToTarget;
|
||||
if (yDeltaNormalized == -0.0D) {
|
||||
yDeltaNormalized = -1.0E-4D;
|
||||
}
|
||||
}
|
||||
|
||||
if (hasOffsetZ) {
|
||||
zDeltaNormalized = (zProposed - v3Current.z) / zDeltaToTarget;
|
||||
if (zDeltaNormalized == -0.0D) {
|
||||
zDeltaNormalized = -1.0E-4D;
|
||||
}
|
||||
}
|
||||
|
||||
// move along shortest axis
|
||||
final EnumFacing enumFacing;
|
||||
if (xDeltaNormalized < yDeltaNormalized && xDeltaNormalized < zDeltaNormalized) {
|
||||
enumFacing = xTarget > xSource ? EnumFacing.WEST : EnumFacing.EAST;
|
||||
v3Current.x = xProposed;
|
||||
v3Current.y = v3Current.y + yDeltaToTarget * xDeltaNormalized;
|
||||
v3Current.z = v3Current.z + zDeltaToTarget * xDeltaNormalized;
|
||||
} else if (yDeltaNormalized < zDeltaNormalized) {
|
||||
enumFacing = yTarget > ySource ? EnumFacing.DOWN : EnumFacing.UP;
|
||||
v3Current.x = v3Current.x + xDeltaToTarget * yDeltaNormalized;
|
||||
v3Current.y = yProposed;
|
||||
v3Current.z = v3Current.z + zDeltaToTarget * yDeltaNormalized;
|
||||
} else {
|
||||
enumFacing = zTarget > zSource ? EnumFacing.NORTH : EnumFacing.SOUTH;
|
||||
v3Current.x = v3Current.x + xDeltaToTarget * zDeltaNormalized;
|
||||
v3Current.y = v3Current.y + yDeltaToTarget * zDeltaNormalized;
|
||||
v3Current.z = zProposed;
|
||||
}
|
||||
|
||||
// round to block position
|
||||
xCurrent = MathHelper.floor(v3Current.x) - (enumFacing == EnumFacing.EAST ? 1 : 0);
|
||||
yCurrent = MathHelper.floor(v3Current.y) - (enumFacing == EnumFacing.UP ? 1 : 0);
|
||||
zCurrent = MathHelper.floor(v3Current.z) - (enumFacing == EnumFacing.SOUTH ? 1 : 0);
|
||||
|
||||
// get current block
|
||||
final IBlockState blockStateCurrent = world.getBlockState(mutableBlockPos.setPos(xCurrent, yCurrent, zCurrent));
|
||||
|
||||
// allow passing through force fields with same beam frequency
|
||||
if (blockStateCurrent.getBlock() instanceof BlockForceField) {
|
||||
final TileEntity tileEntity = world.getTileEntity(mutableBlockPos);
|
||||
if (tileEntity instanceof TileEntityForceField) {
|
||||
final ForceFieldSetup forceFieldSetup = ((TileEntityForceField) tileEntity).getForceFieldSetup();
|
||||
if (forceFieldSetup == null) {
|
||||
// projector not loaded yet, consider it jammed by default
|
||||
WarpDrive.logger.warn(String.format("Laser beam stopped by non-loaded force field projector at %s", tileEntity));
|
||||
} else {
|
||||
if (forceFieldSetup.beamFrequency == beamFrequency) {// pass-through force field
|
||||
if (WarpDriveConfig.LOGGING_WEAPON) {
|
||||
WarpDrive.logger.info(String.format("Laser beam passing through force field %s", tileEntity));
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( checkBlockWithoutBoundingBox
|
||||
|| blockStateCurrent.getMaterial() == Material.PORTAL
|
||||
|| blockStateCurrent.getCollisionBoundingBox(world, mutableBlockPos) != null) {
|
||||
if (blockStateCurrent.getBlock().canCollideCheck(blockStateCurrent, stopOnLiquid)) {
|
||||
final RayTraceResult rayTraceResult = blockStateCurrent.collisionRayTrace(world, mutableBlockPos, v3Current.toVec3d(), vTarget);
|
||||
if (rayTraceResult != null) {
|
||||
return rayTraceResult;
|
||||
}
|
||||
} else {
|
||||
rayTraceResultMissed = new RayTraceResult(RayTraceResult.Type.MISS, v3Current.toVec3d(), enumFacing, mutableBlockPos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return returnLastUncollidableBlock ? rayTraceResultMissed : null;
|
||||
}
|
||||
|
||||
private void emitBeam(final int beamEnergy) {
|
||||
int energy = beamEnergy;
|
||||
|
||||
|
@ -153,7 +345,8 @@ public class TileEntityLaser extends TileEntityAbstractLaser implements IBeamFre
|
|||
|
||||
// This is a scanning beam, do not deal damage to block nor entity
|
||||
if (beamFrequency == BEAM_FREQUENCY_SCANNING) {
|
||||
final RayTraceResult mopResult = world.rayTraceBlocks(vSource.toVec3d(), vReachPoint.toVec3d());
|
||||
final RayTraceResult mopResult = rayTraceBlocks(world, vSource.toVec3d(), vReachPoint.toVec3d(), beamFrequency,
|
||||
false, true, false);
|
||||
|
||||
scanResult_blockUnlocalizedName = null;
|
||||
scanResult_blockMetadata = 0;
|
||||
|
@ -196,7 +389,8 @@ public class TileEntityLaser extends TileEntityAbstractLaser implements IBeamFre
|
|||
double distanceTravelled = 0.0D; // distance traveled from beam sender to previous hit if there were any
|
||||
for (int passedBlocks = 0; passedBlocks < beamLengthBlocks; passedBlocks++) {
|
||||
// Get next block hit
|
||||
final RayTraceResult blockHit = world.rayTraceBlocks(vSource.toVec3d(), vReachPoint.toVec3d());
|
||||
final RayTraceResult blockHit = rayTraceBlocks(world, vSource.toVec3d(), vReachPoint.toVec3d(), beamFrequency,
|
||||
false, true, false);
|
||||
double blockHitDistance = beamLengthBlocks + 0.1D;
|
||||
if (blockHit != null) {
|
||||
blockHitDistance = blockHit.hitVec.distanceTo(vSource.toVec3d());
|
||||
|
@ -300,7 +494,7 @@ public class TileEntityLaser extends TileEntityAbstractLaser implements IBeamFre
|
|||
if (WarpDriveConfig.LOGGING_WEAPON) {
|
||||
WarpDrive.logger.info(String.format("Block collision found %s with block %s of hardness %.2f",
|
||||
Commons.format(world, blockHit.getBlockPos()),
|
||||
blockState.getBlock(), hardness));
|
||||
blockState.getBlock().getRegistryName(), hardness));
|
||||
}
|
||||
|
||||
// check area protection
|
||||
|
@ -341,10 +535,16 @@ public class TileEntityLaser extends TileEntityAbstractLaser implements IBeamFre
|
|||
Math.round(hardness * WarpDriveConfig.LASER_CANNON_BLOCK_HIT_ENERGY_PER_BLOCK_HARDNESS));
|
||||
final double absorptionChance = Commons.clamp(0.0D, WarpDriveConfig.LASER_CANNON_BLOCK_HIT_ABSORPTION_MAX,
|
||||
hardness * WarpDriveConfig.LASER_CANNON_BLOCK_HIT_ABSORPTION_PER_BLOCK_HARDNESS);
|
||||
if (WarpDriveConfig.LOGGING_WEAPON) {
|
||||
WarpDrive.logger.info(String.format("Block energy cost is %d with %.1f %% of absorption",
|
||||
energyCost, absorptionChance * 100.0D));
|
||||
}
|
||||
|
||||
// apply environmental absorption
|
||||
energy *= getTransmittance(blockHitDistance - distanceTravelled);
|
||||
|
||||
do {
|
||||
// Consume energy
|
||||
energy *= getTransmittance(blockHitDistance - distanceTravelled);
|
||||
energy -= energyCost;
|
||||
distanceTravelled = blockHitDistance;
|
||||
vHitPoint = new Vector3(blockHit.hitVec);
|
||||
|
@ -381,8 +581,8 @@ public class TileEntityLaser extends TileEntityAbstractLaser implements IBeamFre
|
|||
|
||||
// apply custom damages
|
||||
if (blockState.getBlock() instanceof IDamageReceiver) {
|
||||
energy = ((IDamageReceiver)blockState.getBlock()).applyDamage(blockState, world, blockHit.getBlockPos(),
|
||||
WarpDrive.damageLaser, beamFrequency, vDirection, energy);
|
||||
energy = ((IDamageReceiver) blockState.getBlock()).applyDamage(blockState, world, blockHit.getBlockPos(),
|
||||
WarpDrive.damageLaser, beamFrequency, vDirection, energy);
|
||||
if (WarpDriveConfig.LOGGING_WEAPON) {
|
||||
WarpDrive.logger.info(String.format("IDamageReceiver damage applied, remaining energy is %d", energy));
|
||||
}
|
||||
|
|
|
@ -228,7 +228,7 @@ public class TileEntityForceFieldProjector extends TileEntityAbstractForceField
|
|||
}
|
||||
|
||||
if (damagesEnergyCost > 0.0D) {
|
||||
if (WarpDriveConfig.LOGGING_FORCE_FIELD) {
|
||||
if (WarpDriveConfig.LOGGING_WEAPON) {
|
||||
WarpDrive.logger.info(String.format("%s damages received, energy lost: %.6f", toString(), damagesEnergyCost));
|
||||
}
|
||||
consumeEnergy(damagesEnergyCost, false);
|
||||
|
|
|
@ -3,6 +3,7 @@ package cr0s.warpdrive.block.movement;
|
|||
import cr0s.warpdrive.Commons;
|
||||
import cr0s.warpdrive.TileEntitySecurityStation;
|
||||
import cr0s.warpdrive.WarpDrive;
|
||||
import cr0s.warpdrive.api.EventWarpDrive.Ship.PreJump;
|
||||
import cr0s.warpdrive.api.IStarMapRegistryTileEntity;
|
||||
import cr0s.warpdrive.config.Dictionary;
|
||||
import cr0s.warpdrive.config.ShipMovementCosts;
|
||||
|
@ -48,6 +49,7 @@ import net.minecraft.util.text.ITextComponent;
|
|||
import net.minecraft.util.text.TextComponentString;
|
||||
import net.minecraft.util.text.TextComponentTranslation;
|
||||
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.fml.client.FMLClientHandler;
|
||||
import net.minecraftforge.fml.relauncher.Side;
|
||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
||||
|
@ -719,7 +721,19 @@ public class TileEntityShipCore extends TileEntityAbstractShipController impleme
|
|||
}
|
||||
|
||||
// compute movement costs
|
||||
shipMovementCosts = new ShipMovementCosts(world, pos, shipMass, shipMovementType, (int) Math.ceil(Math.sqrt(distanceSquared)));
|
||||
shipMovementCosts = new ShipMovementCosts(world, pos,
|
||||
this, shipMovementType,
|
||||
shipMass, (int) Math.ceil(Math.sqrt(distanceSquared)));
|
||||
|
||||
// allow other mods to validate too
|
||||
final PreJump preJump;
|
||||
preJump = new PreJump(world, pos, this, shipMovementType.getName());
|
||||
MinecraftForge.EVENT_BUS.post(preJump);
|
||||
if (preJump.isCanceled()) {
|
||||
reason.append(preJump.getReason());
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -732,7 +746,9 @@ public class TileEntityShipCore extends TileEntityAbstractShipController impleme
|
|||
}
|
||||
|
||||
// compute movement costs
|
||||
final ShipMovementCosts shipMovementCosts = new ShipMovementCosts(world, pos, shipMass, shipMovementType, (int) Math.ceil(Math.sqrt(distanceSquared)));
|
||||
final ShipMovementCosts shipMovementCosts = new ShipMovementCosts(world, pos,
|
||||
this, shipMovementType,
|
||||
shipMass, (int) Math.ceil(Math.sqrt(distanceSquared)));
|
||||
return shipMovementCosts.maximumDistance_blocks;
|
||||
}
|
||||
|
||||
|
@ -744,7 +760,9 @@ public class TileEntityShipCore extends TileEntityAbstractShipController impleme
|
|||
}
|
||||
|
||||
// compute movement costs
|
||||
final ShipMovementCosts shipMovementCosts = new ShipMovementCosts(world, pos, shipMass, shipMovementType, (int) Math.ceil(Math.sqrt(distanceSquared)));
|
||||
final ShipMovementCosts shipMovementCosts = new ShipMovementCosts(world, pos,
|
||||
this, shipMovementType,
|
||||
shipMass, (int) Math.ceil(Math.sqrt(distanceSquared)));
|
||||
return shipMovementCosts.energyRequired;
|
||||
}
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ package cr0s.warpdrive.config;
|
|||
import cr0s.warpdrive.Commons;
|
||||
import cr0s.warpdrive.WarpDrive;
|
||||
import cr0s.warpdrive.api.EventWarpDrive.Ship.MovementCosts;
|
||||
import cr0s.warpdrive.api.computer.IShipController;
|
||||
import cr0s.warpdrive.data.EnumShipMovementType;
|
||||
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
|
@ -20,7 +21,8 @@ public class ShipMovementCosts {
|
|||
public final int cooldown_seconds;
|
||||
|
||||
public ShipMovementCosts(final World world, final BlockPos blockPos,
|
||||
final int mass, final EnumShipMovementType shipMovementType, final int distance) {
|
||||
final IShipController shipController, final EnumShipMovementType shipMovementType,
|
||||
final int mass, final int distance) {
|
||||
final Factors factorsForJumpParameters = WarpDriveConfig.SHIP_MOVEMENT_COSTS_FACTORS[shipMovementType.ordinal()];
|
||||
final int maximumDistance_blocks = Commons.clamp(0, 30000000, evaluate(mass, distance, factorsForJumpParameters.maximumDistance));
|
||||
final int energyRequired = Commons.clamp(0, Integer.MAX_VALUE, evaluate(mass, distance, factorsForJumpParameters.energyRequired));
|
||||
|
@ -30,7 +32,7 @@ public class ShipMovementCosts {
|
|||
|
||||
// post event allowing other mods to adjust it
|
||||
final MovementCosts movementCosts = new MovementCosts(world, blockPos,
|
||||
mass, shipMovementType.getName(), distance,
|
||||
shipController, shipMovementType.getName(), mass, distance,
|
||||
maximumDistance_blocks, energyRequired, warmup_seconds, sickness_seconds, cooldown_seconds);
|
||||
MinecraftForge.EVENT_BUS.post(movementCosts);
|
||||
|
||||
|
@ -52,9 +54,9 @@ public class ShipMovementCosts {
|
|||
return Integer.MAX_VALUE;
|
||||
}
|
||||
final double value = factors[0]
|
||||
+ factors[1] * mass
|
||||
+ factors[2] * distance
|
||||
+ factors[3] * Math.log(Math.max(1.0D, mass)) * (factors[4] != 0.0D ? Math.exp(distance / factors[4]) : 1.0D);
|
||||
+ factors[1] * mass
|
||||
+ factors[2] * distance
|
||||
+ factors[3] * Math.log(Math.max(1.0D, mass)) * (factors[4] != 0.0D ? Math.exp(distance / factors[4]) : 1.0D);
|
||||
return (int) Math.ceil(value);
|
||||
}
|
||||
|
||||
|
|
|
@ -142,6 +142,7 @@ public class WarpDriveConfig {
|
|||
public static int G_LUA_SCRIPTS = LUA_SCRIPTS_ALL;
|
||||
public static String G_SCHEMALOCATION = "warpDrive_schematics";
|
||||
public static int G_BLOCKS_PER_TICK = 3500;
|
||||
public static boolean G_ENABLE_PROTECTION_CHECKS = true;
|
||||
|
||||
// Client
|
||||
public static float CLIENT_LOCATION_SCALE = 1.0F;
|
||||
|
@ -613,6 +614,7 @@ public class WarpDriveConfig {
|
|||
G_BLOCKS_PER_TICK = Commons.clamp(100, 100000,
|
||||
config.get("general", "blocks_per_tick", G_BLOCKS_PER_TICK,
|
||||
"Number of blocks to move per ticks, too high will cause lag spikes on ship jumping or deployment, too low may break the ship wirings").getInt());
|
||||
G_ENABLE_PROTECTION_CHECKS = config.get("general", "enable_protection_checks", G_ENABLE_PROTECTION_CHECKS, "Enable area protection checks from other mods or plugins, disable if you use the event system exclusively").getBoolean(G_ENABLE_PROTECTION_CHECKS);
|
||||
|
||||
// Client
|
||||
CLIENT_LOCATION_SCALE = Commons.clamp(0.25F, 4.0F, (float) config.get("client", "location_scale", CLIENT_LOCATION_SCALE,
|
||||
|
|
|
@ -37,7 +37,7 @@ public abstract class XmlFileManager {
|
|||
final String result = XmlPreprocessor.checkModRequirements(document.getDocumentElement());
|
||||
if (!result.isEmpty()) {
|
||||
WarpDrive.logger.info(String.format("Skipping configuration file %s due to %s", file.getName(), result));
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
|
||||
XmlPreprocessor.doModReqSanitation(document);
|
||||
|
|
|
@ -186,7 +186,9 @@ public class AcceleratorSetup extends GlobalPosition {
|
|||
break;
|
||||
}
|
||||
}
|
||||
if (WarpDriveConfig.LOGGING_ACCELERATOR) {
|
||||
WarpDrive.logger.info(String.format("First void shell is %s", firstVoidShell));
|
||||
}
|
||||
if (firstVoidShell == null) {
|
||||
WarpDrive.logger.warn("No void shell connection found");
|
||||
return;
|
||||
|
|
188
src/main/java/cr0s/warpdrive/data/ExtendedProperties.java
Normal file
188
src/main/java/cr0s/warpdrive/data/ExtendedProperties.java
Normal file
|
@ -0,0 +1,188 @@
|
|||
package cr0s.warpdrive.data;
|
||||
|
||||
import cr0s.warpdrive.WarpDrive;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
public class ExtendedProperties {
|
||||
|
||||
public static final String IDENTIFIER = WarpDrive.MODID;
|
||||
|
||||
private EntityLivingBase entityLivingBase;
|
||||
|
||||
private GlobalPosition globalPositionHome;
|
||||
|
||||
private static final byte UPDATE_FLAG_ALL = 0x7F;
|
||||
private static final byte UPDATE_FLAG_HOME = 0x01;
|
||||
private byte updateFlags;
|
||||
|
||||
private static final int SYNC_DELAY_TICKS = 200; // 10 seconds
|
||||
private int ticksToSync;
|
||||
|
||||
public ExtendedProperties() {
|
||||
}
|
||||
|
||||
public static ExtendedProperties For(final EntityLivingBase entityLivingBase) {
|
||||
return null; // (ExtendedProperties) entityLivingBase.getExtendedProperties(IDENTIFIER);
|
||||
}
|
||||
|
||||
public void saveNBTData(final NBTTagCompound tagCompound) {
|
||||
if (globalPositionHome != null) {
|
||||
final NBTTagCompound nbtHome = new NBTTagCompound();
|
||||
globalPositionHome.writeToNBT(nbtHome);
|
||||
tagCompound.setTag("home", nbtHome);
|
||||
}
|
||||
}
|
||||
|
||||
public void loadNBTData(final NBTTagCompound tagCompound) {
|
||||
if (tagCompound.hasKey("home")) {
|
||||
final NBTTagCompound nbtHome = tagCompound.getCompoundTag("home");
|
||||
globalPositionHome = new GlobalPosition(nbtHome);
|
||||
}
|
||||
}
|
||||
|
||||
public void init(final Entity entity, final World world) {
|
||||
if ( world == null
|
||||
|| !(entity instanceof EntityLivingBase)
|
||||
|| entity.world == null ) {
|
||||
WarpDrive.logger.error(String.format("Invalid parameters to ExtendedProperty.init(%s, %s)",
|
||||
entity, world));
|
||||
return;
|
||||
}
|
||||
|
||||
entityLivingBase = (EntityLivingBase) entity;
|
||||
|
||||
globalPositionHome = null;
|
||||
|
||||
updateFlags = UPDATE_FLAG_ALL;
|
||||
ticksToSync = world.rand.nextInt(SYNC_DELAY_TICKS);
|
||||
}
|
||||
|
||||
|
||||
// home
|
||||
|
||||
public void setHome(final int dimensionId, final int x, final int y, final int z) {
|
||||
setHome(new GlobalPosition(dimensionId, x, y, z));
|
||||
}
|
||||
|
||||
public void setHome(final GlobalPosition globalPosition) {
|
||||
globalPositionHome = globalPosition;
|
||||
setUpdateFlag(UPDATE_FLAG_HOME);
|
||||
}
|
||||
|
||||
public GlobalPosition getHome() {
|
||||
return globalPositionHome;
|
||||
}
|
||||
|
||||
|
||||
// synchronization
|
||||
|
||||
private void setUpdateFlag(final int flag) {
|
||||
updateFlags |= flag;
|
||||
}
|
||||
|
||||
public void requestFullSyncWithDelay(final int delay) {
|
||||
setUpdateFlag(UPDATE_FLAG_ALL);
|
||||
ticksToSync = delay;
|
||||
}
|
||||
|
||||
public void requestFullSync() {
|
||||
requestFullSyncWithDelay(0);
|
||||
}
|
||||
|
||||
public byte[] getUpdateData() {
|
||||
final byte updateFlags_save = updateFlags;
|
||||
updateFlags = 0;
|
||||
|
||||
final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
|
||||
final DataOutputStream dataOutputStream = new DataOutputStream(byteArrayOutputStream);
|
||||
|
||||
try {
|
||||
dataOutputStream.writeInt(entityLivingBase.getEntityId());
|
||||
dataOutputStream.writeByte(updateFlags_save);
|
||||
|
||||
if ((updateFlags_save & UPDATE_FLAG_HOME) != 0) {
|
||||
dataOutputStream.writeBoolean(globalPositionHome != null);
|
||||
if (globalPositionHome != null) {
|
||||
dataOutputStream.writeInt(globalPositionHome.dimensionId);
|
||||
dataOutputStream.writeInt(globalPositionHome.x);
|
||||
dataOutputStream.writeInt(globalPositionHome.y);
|
||||
dataOutputStream.writeInt(globalPositionHome.z);
|
||||
}
|
||||
}
|
||||
|
||||
return byteArrayOutputStream.toByteArray();
|
||||
} catch (final IOException exception) {
|
||||
exception.printStackTrace();
|
||||
WarpDrive.logger.error(String.format("Exception while saving extended properties for entity %s",
|
||||
entityLivingBase));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean handleDataPacket(final byte[] data) {
|
||||
final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(data);
|
||||
final DataInputStream dataInputStream = new DataInputStream(byteArrayInputStream);
|
||||
|
||||
try {
|
||||
final int entityId = dataInputStream.readInt();
|
||||
if (entityId != entityLivingBase.getEntityId()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final int updateFlags_read = dataInputStream.readByte();
|
||||
|
||||
if ((updateFlags_read & UPDATE_FLAG_HOME) != 0) {
|
||||
final boolean isHomeSet = dataInputStream.readBoolean();
|
||||
if (isHomeSet) {
|
||||
final int dimensionId = dataInputStream.readInt();
|
||||
final int x = dataInputStream.readInt();
|
||||
final int y = dataInputStream.readInt();
|
||||
final int z = dataInputStream.readInt();
|
||||
globalPositionHome = new GlobalPosition(dimensionId, x, y, z);
|
||||
} else {
|
||||
globalPositionHome = null;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
} catch (final IOException exception) {
|
||||
exception.printStackTrace();
|
||||
WarpDrive.logger.error(String.format("Exception while reading extended properties for entity %s of %d bytes",
|
||||
entityLivingBase, data.length));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public void handleSynchronization() {
|
||||
if (entityLivingBase.world.isRemote) {
|
||||
return;
|
||||
}
|
||||
|
||||
ticksToSync--;
|
||||
if (ticksToSync <= 0) {
|
||||
ticksToSync = SYNC_DELAY_TICKS;
|
||||
if (updateFlags != 0) {
|
||||
final byte[] data = this.getUpdateData();
|
||||
// @TODO PacketHandler.sendExtendedProperties(entity, data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
try {
|
||||
return hashCode() + " " + entityLivingBase;
|
||||
} catch (final Exception exception) {
|
||||
return hashCode() + " (error)";
|
||||
}
|
||||
}
|
||||
}
|
|
@ -322,8 +322,17 @@ public class ForceFieldSetup extends GlobalPosition {
|
|||
assert damageSource != null;
|
||||
final TileEntity tileEntity = world.getTileEntity(new BlockPos(x, y, z));
|
||||
if (tileEntity instanceof TileEntityForceFieldProjector) {
|
||||
final double scaledDamage = damageLevel * entityEnergyCost / 2000.0D;
|
||||
((TileEntityForceFieldProjector)tileEntity).onEnergyDamage(scaledDamage);
|
||||
final double scaledDamage;
|
||||
if (damageSource.damageType.contains("explosion")) {
|
||||
scaledDamage = damageLevel / 1000.0D + entityEnergyCost * 0.1D;
|
||||
} else if (damageSource.damageType.contains("laser")) {
|
||||
scaledDamage = damageLevel / 500.0D + entityEnergyCost * 5.0D;
|
||||
} else {
|
||||
WarpDrive.logger.warn(String.format("%s Unknown damage source %s '%s' %.1f",
|
||||
this, damageSource, damageSource.getDamageType(), damageLevel));
|
||||
scaledDamage = Commons.clamp(0, 10000, damageLevel);
|
||||
}
|
||||
((TileEntityForceFieldProjector) tileEntity).onEnergyDamage(scaledDamage);
|
||||
return 0.0D;
|
||||
}
|
||||
return damageLevel;
|
||||
|
|
|
@ -42,8 +42,8 @@ public class DeploySequencer extends JumpSequencer {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void disableAndMessage(final ITextComponent reason) {
|
||||
super.disableAndMessage(reason);
|
||||
public void disable(final boolean isSuccessful, final ITextComponent reason) {
|
||||
super.disable(isSuccessful, reason);
|
||||
callback.sequencer_finished();
|
||||
}
|
||||
|
||||
|
|
|
@ -4,8 +4,11 @@ import cr0s.warpdrive.CommonProxy;
|
|||
import cr0s.warpdrive.Commons;
|
||||
import cr0s.warpdrive.LocalProfiler;
|
||||
import cr0s.warpdrive.WarpDrive;
|
||||
import cr0s.warpdrive.api.EventWarpDrive.Ship.JumpResult;
|
||||
import cr0s.warpdrive.api.EventWarpDrive.Ship.TargetCheck;
|
||||
import cr0s.warpdrive.api.IBlockTransformer;
|
||||
import cr0s.warpdrive.api.ITransformation;
|
||||
import cr0s.warpdrive.api.computer.IShipController;
|
||||
import cr0s.warpdrive.block.movement.TileEntityShipCore;
|
||||
import cr0s.warpdrive.data.CelestialObjectManager;
|
||||
import cr0s.warpdrive.config.Dictionary;
|
||||
|
@ -56,17 +59,25 @@ import net.minecraft.world.World;
|
|||
import net.minecraftforge.common.ForgeChunkManager;
|
||||
import net.minecraftforge.common.ForgeChunkManager.Ticket;
|
||||
import net.minecraftforge.common.ForgeChunkManager.Type;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
|
||||
public class JumpSequencer extends AbstractSequencer {
|
||||
|
||||
// Jump vector
|
||||
protected Transformation transformation;
|
||||
|
||||
// movement parameters
|
||||
private final EnumShipMovementType shipMovementType;
|
||||
private int moveX, moveY, moveZ;
|
||||
private final byte rotationSteps;
|
||||
private final String nameTarget;
|
||||
protected final int destX;
|
||||
protected final int destY;
|
||||
protected final int destZ;
|
||||
|
||||
// effect source
|
||||
private Vector3 v3Source;
|
||||
|
||||
private int blocksPerTick = WarpDriveConfig.G_BLOCKS_PER_TICK;
|
||||
private static final boolean enforceEntitiesPosition = false;
|
||||
|
||||
|
@ -89,10 +100,6 @@ public class JumpSequencer extends AbstractSequencer {
|
|||
private boolean isPluginCheckDone = false;
|
||||
private String firstAdjustmentReason = "";
|
||||
|
||||
protected final int destX;
|
||||
protected final int destY;
|
||||
protected final int destZ;
|
||||
|
||||
private long msCounter = 0;
|
||||
private int ticks = 0;
|
||||
|
||||
|
@ -166,25 +173,41 @@ public class JumpSequencer extends AbstractSequencer {
|
|||
register();
|
||||
}
|
||||
|
||||
public void disableAndMessage(final ITextComponent textComponent) {
|
||||
disable(textComponent);
|
||||
public void disableAndMessage(final boolean isSuccessful, final ITextComponent textComponent) {
|
||||
disable(isSuccessful, textComponent);
|
||||
ship.messageToAllPlayersOnShip(textComponent);
|
||||
}
|
||||
public void disable(final ITextComponent textComponent) {
|
||||
public void disable(final boolean isSuccessful, final ITextComponent textComponent) {
|
||||
if (!isEnabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
isEnabled = false;
|
||||
|
||||
final String formattedText = textComponent == null ? "" : textComponent.getFormattedText();
|
||||
if (WarpDriveConfig.LOGGING_JUMP) {
|
||||
if (textComponent == null || textComponent.getFormattedText().isEmpty()) {
|
||||
WarpDrive.logger.info(this + " Killing jump sequencer...");
|
||||
if (formattedText.isEmpty()) {
|
||||
WarpDrive.logger.info(String.format("%s Killing jump sequencer...",
|
||||
this));
|
||||
} else {
|
||||
WarpDrive.logger.info(this + " Killing jump sequencer... (" + textComponent.getFormattedText() + ")");
|
||||
WarpDrive.logger.info(String.format("%s Killing jump sequencer... (%s)",
|
||||
this, formattedText));
|
||||
}
|
||||
}
|
||||
|
||||
final JumpResult jumpResult;
|
||||
if (!isSuccessful) {
|
||||
jumpResult = new JumpResult(sourceWorld, ship.core,
|
||||
ship.shipCore, shipMovementType.getName(), false, formattedText);
|
||||
} else {
|
||||
final BlockPos blockPosCoreTarget = transformation.apply(ship.core);
|
||||
final TileEntity tileEntity = targetWorld.getTileEntity(blockPosCoreTarget);
|
||||
final IShipController shipController = tileEntity instanceof TileEntityShipCore ? ((TileEntityShipCore) tileEntity) : null;
|
||||
jumpResult = new JumpResult(targetWorld, blockPosCoreTarget,
|
||||
shipController, shipMovementType.getName(), true, formattedText);
|
||||
}
|
||||
MinecraftForge.EVENT_BUS.post(jumpResult);
|
||||
|
||||
releaseChunks();
|
||||
unregister();
|
||||
}
|
||||
|
@ -205,7 +228,7 @@ public class JumpSequencer extends AbstractSequencer {
|
|||
|
||||
if (ship.minY < 0 || ship.maxY > 255) {
|
||||
final TextComponentBase msg = new TextComponentString("Invalid Y coordinate(s), check ship dimensions...");
|
||||
disableAndMessage(msg);
|
||||
disableAndMessage(false, msg);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -327,7 +350,7 @@ public class JumpSequencer extends AbstractSequencer {
|
|||
|
||||
default:
|
||||
final TextComponentBase msg = new TextComponentString("Invalid state, aborting jump...");
|
||||
disableAndMessage(msg);
|
||||
disableAndMessage(false, msg);
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
|
@ -452,7 +475,7 @@ public class JumpSequencer extends AbstractSequencer {
|
|||
|
||||
if (!forceSourceChunks(reason)) {
|
||||
final TextComponentBase msg = new TextComponentString(reason.toString());
|
||||
disableAndMessage(msg);
|
||||
disableAndMessage(false, msg);
|
||||
LocalProfiler.stop();
|
||||
return;
|
||||
}
|
||||
|
@ -470,7 +493,7 @@ public class JumpSequencer extends AbstractSequencer {
|
|||
|
||||
if (!ship.save(reason)) {
|
||||
final ITextComponent msg = new TextComponentString(reason.toString());
|
||||
disableAndMessage(msg);
|
||||
disableAndMessage(false, msg);
|
||||
LocalProfiler.stop();
|
||||
return;
|
||||
}
|
||||
|
@ -489,7 +512,7 @@ public class JumpSequencer extends AbstractSequencer {
|
|||
|
||||
if (!ship.checkBorders(reason)) {
|
||||
final ITextComponent msg = new TextComponentString(reason.toString());
|
||||
disableAndMessage(msg);
|
||||
disableAndMessage(false, msg);
|
||||
LocalProfiler.stop();
|
||||
return;
|
||||
}
|
||||
|
@ -565,7 +588,7 @@ public class JumpSequencer extends AbstractSequencer {
|
|||
final boolean isTargetWorldFound = computeTargetWorld(celestialObjectSource, shipMovementType, reason);
|
||||
if (!isTargetWorldFound) {
|
||||
LocalProfiler.stop();
|
||||
disableAndMessage(new TextComponentString(reason.toString()));
|
||||
disableAndMessage(false, new TextComponentString(reason.toString()));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -578,7 +601,7 @@ public class JumpSequencer extends AbstractSequencer {
|
|||
LocalProfiler.stop();
|
||||
final ITextComponent message = new TextComponentString(String.format("Ship is too big for a planet (max is %d blocks while ship is %d blocks)",
|
||||
WarpDriveConfig.SHIP_VOLUME_MAX_ON_PLANET_SURFACE, ship.actualMass));
|
||||
disableAndMessage(message);
|
||||
disableAndMessage(false, message);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -680,7 +703,7 @@ public class JumpSequencer extends AbstractSequencer {
|
|||
} else {
|
||||
msg = new TextComponentString(firstAdjustmentReason + "\nNot enough space after adjustment, jump aborted!");
|
||||
}
|
||||
disableAndMessage(msg);
|
||||
disableAndMessage(false, msg);
|
||||
LocalProfiler.stop();
|
||||
return;
|
||||
}
|
||||
|
@ -703,16 +726,17 @@ public class JumpSequencer extends AbstractSequencer {
|
|||
(int) axisAlignedBB.minX, (int) axisAlignedBB.minY, (int) axisAlignedBB.minZ,
|
||||
(int) axisAlignedBB.maxX, (int) axisAlignedBB.maxY, (int) axisAlignedBB.maxZ );
|
||||
LocalProfiler.stop();
|
||||
disableAndMessage(message);
|
||||
disableAndMessage(false, message);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!isPluginCheckDone) {
|
||||
final CheckMovementResult checkMovementResult = checkCollisionAndProtection(transformation, true, "target");
|
||||
final CheckMovementResult checkMovementResult = checkCollisionAndProtection(transformation, true,
|
||||
"target", new VectorI(0, 0, 0));
|
||||
if (checkMovementResult != null) {
|
||||
final TextComponentBase msg = new TextComponentString(checkMovementResult.reason + "\nJump aborted!");
|
||||
disableAndMessage(msg);
|
||||
disableAndMessage(false, msg);
|
||||
LocalProfiler.stop();
|
||||
return;
|
||||
}
|
||||
|
@ -731,7 +755,7 @@ public class JumpSequencer extends AbstractSequencer {
|
|||
|
||||
if (!forceTargetChunks(reason)) {
|
||||
final ITextComponent msg = new TextComponentString(reason.toString());
|
||||
disableAndMessage(msg);
|
||||
disableAndMessage(false, msg);
|
||||
LocalProfiler.stop();
|
||||
return;
|
||||
}
|
||||
|
@ -752,7 +776,7 @@ public class JumpSequencer extends AbstractSequencer {
|
|||
&& shipMovementType != EnumShipMovementType.RESTORE ) {
|
||||
if (!ship.saveEntities(reason)) {
|
||||
final ITextComponent msg = new TextComponentString(reason.toString());
|
||||
disableAndMessage(msg);
|
||||
disableAndMessage(false, msg);
|
||||
LocalProfiler.stop();
|
||||
return;
|
||||
}
|
||||
|
@ -1117,7 +1141,8 @@ public class JumpSequencer extends AbstractSequencer {
|
|||
final JumpBlock jumpBlock = ship.jumpBlocks[ship.jumpBlocks.length - actualIndexInShip - 1];
|
||||
if (jumpBlock == null) {
|
||||
if (WarpDriveConfig.LOGGING_JUMP) {
|
||||
WarpDrive.logger.info(String.format("%s Moving ship externals: unexpected null found at ship[%d]", actualIndexInShip));
|
||||
WarpDrive.logger.info(String.format("%s Moving ship externals: unexpected null found at ship[%d]",
|
||||
this, actualIndexInShip));
|
||||
}
|
||||
actualIndexInShip++;
|
||||
continue;
|
||||
|
@ -1282,6 +1307,7 @@ public class JumpSequencer extends AbstractSequencer {
|
|||
try {
|
||||
// @TODO MC1.10 still leaking tile entities?
|
||||
// targetWorld.loadedTileEntityList = removeDuplicates(targetWorld.loadedTileEntityList);
|
||||
removeDuplicates(targetWorld.loadedTileEntityList);
|
||||
} catch (final Exception exception) {
|
||||
if (WarpDriveConfig.LOGGING_JUMP) {
|
||||
WarpDrive.logger.info(String.format("TE Duplicates removing exception: %s", exception.getMessage()));
|
||||
|
@ -1291,7 +1317,7 @@ public class JumpSequencer extends AbstractSequencer {
|
|||
|
||||
doCollisionDamage(true);
|
||||
|
||||
disable(new TextComponentString("Jump done"));
|
||||
disable(true, new TextComponentString("Jump done"));
|
||||
final int countAfter = targetWorld.loadedTileEntityList.size();
|
||||
if (WarpDriveConfig.LOGGING_JUMP && countBefore != countAfter) {
|
||||
WarpDrive.logger.info(String.format("Removing TE duplicates: tileEntities in target world after jump, cleanup %d -> %d",
|
||||
|
@ -1489,12 +1515,14 @@ public class JumpSequencer extends AbstractSequencer {
|
|||
isCollision = isCollision || pisCollision;
|
||||
reason = preason;
|
||||
if (WarpDriveConfig.LOGGING_JUMPBLOCKS) {
|
||||
WarpDrive.logger.info(String.format("CheckMovementResult (%d %d %d) -> (%d %d %d) %s '%s'", sx, sy, sz, tx, ty, tz, isCollision, reason));
|
||||
WarpDrive.logger.info(String.format("CheckMovementResult (%.1f %.1f %.1f) -> (%.1f %.1f %.1f) %s '%s'",
|
||||
sx, sy, sz, tx, ty, tz, isCollision, reason));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private CheckMovementResult checkCollisionAndProtection(final ITransformation transformation, final boolean fullCollisionDetails, final String context) {
|
||||
private CheckMovementResult checkCollisionAndProtection(final ITransformation transformation, final boolean fullCollisionDetails,
|
||||
final String context, final VectorI vMovement) {
|
||||
final CheckMovementResult result = new CheckMovementResult();
|
||||
final VectorI offset = new VectorI((int) Math.signum(moveX), (int) Math.signum(moveY), (int) Math.signum(moveZ));
|
||||
|
||||
|
@ -1502,6 +1530,29 @@ public class JumpSequencer extends AbstractSequencer {
|
|||
MutableBlockPos mutableBlockPosSource = new MutableBlockPos(0, 0, 0);
|
||||
BlockPos blockPosTarget;
|
||||
final BlockPos blockPosCoreAtTarget = transformation.apply(ship.core.getX(), ship.core.getY(), ship.core.getZ());
|
||||
|
||||
// post event allowing other mods to do their own checks
|
||||
final BlockPos blockPosMinAtTarget = transformation.apply(ship.minX, ship.minY, ship.minZ);
|
||||
final BlockPos blockPosMaxAtTarget = transformation.apply(ship.maxX, ship.maxY, ship.maxZ);
|
||||
final AxisAlignedBB targetAABB = new AxisAlignedBB(
|
||||
blockPosMinAtTarget.getX(), blockPosMinAtTarget.getY(), blockPosMinAtTarget.getZ(),
|
||||
blockPosMaxAtTarget.getX(), blockPosMaxAtTarget.getY(), blockPosMaxAtTarget.getZ() );
|
||||
final TargetCheck targetCheck = new TargetCheck(sourceWorld, ship.core,
|
||||
ship.shipCore, shipMovementType.getName(),
|
||||
vMovement.x, vMovement.y, vMovement.z,
|
||||
targetWorld, targetAABB);
|
||||
MinecraftForge.EVENT_BUS.post(targetCheck);
|
||||
if (targetCheck.isCanceled()) {
|
||||
result.add(ship.core.getX(), ship.core.getY(), ship.core.getZ(),
|
||||
blockPosCoreAtTarget.getX(),
|
||||
blockPosCoreAtTarget.getY(),
|
||||
blockPosCoreAtTarget.getZ(),
|
||||
false,
|
||||
targetCheck.getReason() );
|
||||
return result;
|
||||
}
|
||||
|
||||
// scan target location
|
||||
IBlockState blockStateSource;
|
||||
IBlockState blockStateTarget;
|
||||
for (y = ship.minY; y <= ship.maxY; y++) {
|
||||
|
@ -1545,6 +1596,7 @@ public class JumpSequencer extends AbstractSequencer {
|
|||
}
|
||||
|
||||
if ( blockStateSource.getBlock() != Blocks.AIR
|
||||
&& WarpDriveConfig.G_ENABLE_PROTECTION_CHECKS
|
||||
&& CommonProxy.isBlockPlaceCanceled(null, blockPosCoreAtTarget, targetWorld, blockPosTarget, blockStateSource)) {
|
||||
result.add(x, y, z,
|
||||
blockPosTarget.getX(),
|
||||
|
@ -1588,7 +1640,7 @@ public class JumpSequencer extends AbstractSequencer {
|
|||
}
|
||||
|
||||
final ITransformation testTransformation = new Transformation(ship, targetWorld, testMovement.x, testMovement.y, testMovement.z, rotationSteps);
|
||||
return checkCollisionAndProtection(testTransformation, fullCollisionDetails, "ratio " + ratio + " testMovement " + testMovement);
|
||||
return checkCollisionAndProtection(testTransformation, fullCollisionDetails, String.format("ratio %.3f movement %s", ratio, testMovement), testMovement);
|
||||
}
|
||||
|
||||
private VectorI getMovementVector(final double ratio) {
|
||||
|
|
Loading…
Reference in a new issue