mirror of
https://github.com/Creators-of-Create/Create.git
synced 2024-12-23 21:46:40 +01:00
Rotation validation
- Contraptions can no longer speed up themselves when connected in a loop - Components now validate from time to time if they still have a source - Some minor refactoring in KineticTileEntity - Empty networks are now being removed from the network space (fixes memory leak) - Waterwheels no longer differentiate between a slight side-ways flow and a straight flow of water
This commit is contained in:
parent
fed4df515a
commit
b89db104b8
20 changed files with 460 additions and 367 deletions
|
@ -10,6 +10,7 @@ public class CKinetics extends ConfigBase {
|
|||
public ConfigInt maxRotationSpeed = i(256, 64, "maxRotationSpeed", Comments.rpm, Comments.maxRotationSpeed);
|
||||
public ConfigEnum<DeployerAggroSetting> ignoreDeployerAttacks =
|
||||
e(DeployerAggroSetting.CREEPERS, "ignoreDeployerAttacks", Comments.ignoreDeployerAttacks);
|
||||
public ConfigInt kineticValidationFrequency = i(60, 5, "kineticValidationFrequency", Comments.kineticValidationFrequency);
|
||||
|
||||
public ConfigGroup fan = group(0, "encasedFan", "Encased Fan");
|
||||
public ConfigInt fanPushDistance = i(20, 5, "fanPushDistance", Comments.fanPushDistance);
|
||||
|
@ -71,6 +72,7 @@ public class CKinetics extends ConfigBase {
|
|||
static String ignoreDeployerAttacks = "Select what mobs should ignore Deployers when attacked by them.";
|
||||
static String waterWheelSpeed = "Rotation speed gained by a water wheel for each side with running water. (halved if not against blades)";
|
||||
static String disableStress = "Disable the Stress mechanic altogether.";
|
||||
static String kineticValidationFrequency = "Game ticks between Kinetic Blocks checking whether their source is still valid.";
|
||||
}
|
||||
|
||||
public static enum DeployerAggroSetting {
|
||||
|
|
|
@ -25,9 +25,9 @@ public class KineticNetwork {
|
|||
members = new HashMap<>();
|
||||
}
|
||||
|
||||
public void initFromTE(KineticTileEntity te) {
|
||||
unloadedStressCapacity = te.maxStress;
|
||||
unloadedStress = te.currentStress;
|
||||
public void initFromTE(float maxStress, float currentStress) {
|
||||
unloadedStressCapacity = maxStress;
|
||||
unloadedStress = currentStress;
|
||||
initialized = true;
|
||||
updateStress();
|
||||
updateStressCapacity();
|
||||
|
@ -42,16 +42,13 @@ public class KineticNetwork {
|
|||
sources.put(te, capacity);
|
||||
}
|
||||
float stressApplied = te.getStressApplied();
|
||||
unloadedStress -= stressApplied * getStressMultiplierForSpeed(te.speed);
|
||||
unloadedStress -= stressApplied * getStressMultiplierForSpeed(te.getTheoreticalSpeed());
|
||||
members.put(te, stressApplied);
|
||||
}
|
||||
|
||||
public void add(KineticTileEntity te) {
|
||||
if (members.containsKey(te))
|
||||
return;
|
||||
|
||||
// Debug.debugChatAndShowStack(te.getType().getRegistryName().getPath() + " added to Network", 5);
|
||||
|
||||
if (te.isSource()) {
|
||||
sources.put(te, te.getAddedStressCapacity());
|
||||
updateStressCapacity();
|
||||
|
@ -75,9 +72,6 @@ public class KineticNetwork {
|
|||
public void remove(KineticTileEntity te) {
|
||||
if (!members.containsKey(te))
|
||||
return;
|
||||
|
||||
// Debug.debugChat(te.getType().getRegistryName().getPath() + " removed from Network");
|
||||
|
||||
if (te.isSource()) {
|
||||
sources.remove(te);
|
||||
updateStressCapacity();
|
||||
|
@ -86,6 +80,9 @@ public class KineticNetwork {
|
|||
members.remove(te);
|
||||
updateStress();
|
||||
sync();
|
||||
|
||||
if (members.isEmpty())
|
||||
TorquePropagator.networks.get(te.getWorld()).remove(this.id);
|
||||
}
|
||||
|
||||
public void sync() {
|
||||
|
@ -101,21 +98,17 @@ public class KineticNetwork {
|
|||
if (maxStress != newMaxStress) {
|
||||
maxStress = newMaxStress;
|
||||
sync();
|
||||
// Debug.debugChatAndShowStack("Current Stress level: " + currentStress + "/" + maxStress, 5);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void updateStress() {
|
||||
float presentStress = 0;
|
||||
|
||||
for (KineticTileEntity te : members.keySet())
|
||||
presentStress += members.get(te) * getStressMultiplierForSpeed(te.speed);
|
||||
presentStress += members.get(te) * getStressMultiplierForSpeed(te.getTheoreticalSpeed());
|
||||
float newStress = presentStress + unloadedStress;
|
||||
if (currentStress != newStress) {
|
||||
currentStress = newStress;
|
||||
sync();
|
||||
// Debug.debugChatAndShowStack("Current Stress level: " + currentStress + "/" + maxStress, 5);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@ import com.simibubi.create.modules.contraptions.base.IRotate;
|
|||
import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
|
||||
import com.simibubi.create.modules.contraptions.relays.advanced.SpeedControllerTileEntity;
|
||||
import com.simibubi.create.modules.contraptions.relays.belt.BeltTileEntity;
|
||||
import com.simibubi.create.modules.contraptions.relays.encased.DirectionalShaftHalvesTileEntity;
|
||||
import com.simibubi.create.modules.contraptions.relays.encased.EncasedBeltBlock;
|
||||
import com.simibubi.create.modules.contraptions.relays.encased.SplitShaftTileEntity;
|
||||
import com.simibubi.create.modules.contraptions.relays.gearbox.GearboxTileEntity;
|
||||
|
@ -52,9 +53,9 @@ public class RotationPropagator {
|
|||
if (axis.getCoordinate(diff.getX(), diff.getY(), diff.getZ()) != 0)
|
||||
alignedAxes = false;
|
||||
|
||||
boolean connectedByAxis = alignedAxes
|
||||
&& definitionFrom.hasShaftTowards(world, from.getPos(), stateFrom, direction)
|
||||
&& definitionTo.hasShaftTowards(world, to.getPos(), stateTo, direction.getOpposite());
|
||||
boolean connectedByAxis =
|
||||
alignedAxes && definitionFrom.hasShaftTowards(world, from.getPos(), stateFrom, direction)
|
||||
&& definitionTo.hasShaftTowards(world, to.getPos(), stateTo, direction.getOpposite());
|
||||
|
||||
boolean connectedByGears = definitionFrom.hasCogsTowards(world, from.getPos(), stateFrom, direction)
|
||||
&& definitionTo.hasCogsTowards(world, to.getPos(), stateTo, direction.getOpposite());
|
||||
|
@ -130,9 +131,9 @@ public class RotationPropagator {
|
|||
}
|
||||
|
||||
private static float getAxisModifier(KineticTileEntity te, Direction direction) {
|
||||
if (!te.hasSource())
|
||||
if (!te.hasSource() || !(te instanceof DirectionalShaftHalvesTileEntity))
|
||||
return 1;
|
||||
Direction source = te.getSourceFacing();
|
||||
Direction source = ((DirectionalShaftHalvesTileEntity) te).getSourceFacing();
|
||||
|
||||
if (te instanceof GearboxTileEntity)
|
||||
return direction.getAxis() == source.getAxis() ? direction == source ? 1 : -1
|
||||
|
@ -180,7 +181,7 @@ public class RotationPropagator {
|
|||
return;
|
||||
if (!worldIn.isBlockPresent(pos))
|
||||
return;
|
||||
if (addedTE.speed != 0) {
|
||||
if (addedTE.getTheoreticalSpeed() != 0) {
|
||||
propagateNewSource(addedTE);
|
||||
return;
|
||||
}
|
||||
|
@ -188,16 +189,17 @@ public class RotationPropagator {
|
|||
for (KineticTileEntity neighbourTE : getConnectedNeighbours(addedTE)) {
|
||||
final float speedModifier = getRotationSpeedModifier(neighbourTE, addedTE);
|
||||
|
||||
if (neighbourTE.speed == 0)
|
||||
float neighbourSpeed = neighbourTE.getTheoreticalSpeed();
|
||||
if (neighbourSpeed == 0)
|
||||
continue;
|
||||
if (neighbourTE.hasSource() && neighbourTE.getSource().equals(addedTE.getPos())) {
|
||||
addedTE.setSpeed(neighbourTE.speed * speedModifier);
|
||||
addedTE.setSpeed(neighbourSpeed * speedModifier);
|
||||
addedTE.onSpeedChanged(0);
|
||||
addedTE.sendData();
|
||||
continue;
|
||||
}
|
||||
|
||||
addedTE.setSpeed(neighbourTE.speed * speedModifier);
|
||||
addedTE.setSpeed(neighbourSpeed * speedModifier);
|
||||
addedTE.setSource(neighbourTE.getPos());
|
||||
addedTE.onSpeedChanged(0);
|
||||
addedTE.sendData();
|
||||
|
@ -209,23 +211,25 @@ public class RotationPropagator {
|
|||
/**
|
||||
* Search for sourceless networks attached to the given entity and update them.
|
||||
*
|
||||
* @param updateTE
|
||||
* @param currentTE
|
||||
*/
|
||||
private static void propagateNewSource(KineticTileEntity updateTE) {
|
||||
BlockPos pos = updateTE.getPos();
|
||||
World world = updateTE.getWorld();
|
||||
private static void propagateNewSource(KineticTileEntity currentTE) {
|
||||
BlockPos pos = currentTE.getPos();
|
||||
World world = currentTE.getWorld();
|
||||
|
||||
for (KineticTileEntity neighbourTE : getConnectedNeighbours(updateTE)) {
|
||||
float modFromTo = getRotationSpeedModifier(updateTE, neighbourTE);
|
||||
float modToFrom = getRotationSpeedModifier(neighbourTE, updateTE);
|
||||
final float newSpeed = updateTE.speed * modFromTo;
|
||||
float oppositeSpeed = neighbourTE.speed * modToFrom;
|
||||
for (KineticTileEntity neighbourTE : getConnectedNeighbours(currentTE)) {
|
||||
float modFromTo = getRotationSpeedModifier(currentTE, neighbourTE);
|
||||
float modToFrom = getRotationSpeedModifier(neighbourTE, currentTE);
|
||||
float speedOfCurrent = currentTE.getTheoreticalSpeed();
|
||||
float speedOfNeighbour = neighbourTE.getTheoreticalSpeed();
|
||||
float newSpeed = speedOfCurrent * modFromTo;
|
||||
float oppositeSpeed = speedOfNeighbour * modToFrom;
|
||||
|
||||
boolean incompatible = Math.signum(newSpeed) != Math.signum(neighbourTE.speed)
|
||||
&& (newSpeed != 0 && neighbourTE.speed != 0);
|
||||
boolean incompatible =
|
||||
Math.signum(newSpeed) != Math.signum(speedOfNeighbour) && (newSpeed != 0 && speedOfNeighbour != 0);
|
||||
|
||||
boolean tooFast = Math.abs(newSpeed) > AllConfigs.SERVER.kinetics.maxRotationSpeed.get();
|
||||
boolean speedChangedTooOften = updateTE.speedChangeCounter > MAX_FLICKER_SCORE;
|
||||
boolean speedChangedTooOften = currentTE.getFlickerScore() > MAX_FLICKER_SCORE;
|
||||
if (tooFast || speedChangedTooOften) {
|
||||
world.destroyBlock(pos, true);
|
||||
return;
|
||||
|
@ -238,43 +242,45 @@ public class RotationPropagator {
|
|||
|
||||
} else {
|
||||
// Same direction: overpower the slower speed
|
||||
if (Math.abs(oppositeSpeed) > Math.abs(updateTE.speed)) {
|
||||
if (Math.abs(oppositeSpeed) > Math.abs(speedOfCurrent)) {
|
||||
// Neighbour faster, overpower the incoming tree
|
||||
updateTE.setSource(neighbourTE.getPos());
|
||||
float prevSpeed = updateTE.getSpeed();
|
||||
updateTE.setSpeed(neighbourTE.speed * getRotationSpeedModifier(neighbourTE, updateTE));
|
||||
updateTE.onSpeedChanged(prevSpeed);
|
||||
updateTE.sendData();
|
||||
currentTE.setSource(neighbourTE.getPos());
|
||||
float prevSpeed = currentTE.getSpeed();
|
||||
currentTE.setSpeed(speedOfNeighbour * getRotationSpeedModifier(neighbourTE, currentTE));
|
||||
currentTE.onSpeedChanged(prevSpeed);
|
||||
currentTE.sendData();
|
||||
|
||||
propagateNewSource(updateTE);
|
||||
propagateNewSource(currentTE);
|
||||
return;
|
||||
}
|
||||
if (Math.abs(newSpeed) >= Math.abs(neighbourTE.speed)) {
|
||||
if (Math.abs(newSpeed) > Math.abs(neighbourTE.speed) || updateTE.newNetworkID != null
|
||||
&& !updateTE.newNetworkID.equals(neighbourTE.newNetworkID)) {
|
||||
// Current faster, overpower the neighbours' tree
|
||||
|
||||
if (updateTE.hasSource() && updateTE.getSource().equals(neighbourTE.getPos())) {
|
||||
updateTE.removeSource();
|
||||
}
|
||||
|
||||
neighbourTE.setSource(updateTE.getPos());
|
||||
float prevSpeed = neighbourTE.getSpeed();
|
||||
neighbourTE.setSpeed(updateTE.speed * getRotationSpeedModifier(updateTE, neighbourTE));
|
||||
neighbourTE.onSpeedChanged(prevSpeed);
|
||||
neighbourTE.sendData();
|
||||
propagateNewSource(neighbourTE);
|
||||
// Current faster, overpower the neighbours' tree
|
||||
if (Math.abs(newSpeed) >= Math.abs(speedOfNeighbour)) {
|
||||
if (!currentTE.canOverPower(neighbourTE)) {
|
||||
if (Math.abs(newSpeed) > Math.abs(speedOfNeighbour))
|
||||
world.destroyBlock(pos, true);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (currentTE.hasSource() && currentTE.getSource().equals(neighbourTE.getPos()))
|
||||
currentTE.removeSource();
|
||||
|
||||
neighbourTE.setSource(currentTE.getPos());
|
||||
float prevSpeed = neighbourTE.getSpeed();
|
||||
neighbourTE.setSpeed(speedOfCurrent * getRotationSpeedModifier(currentTE, neighbourTE));
|
||||
neighbourTE.onSpeedChanged(prevSpeed);
|
||||
neighbourTE.sendData();
|
||||
propagateNewSource(neighbourTE);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (neighbourTE.speed == newSpeed)
|
||||
if (neighbourTE.getTheoreticalSpeed() == newSpeed)
|
||||
continue;
|
||||
|
||||
float prevSpeed = neighbourTE.getSpeed();
|
||||
neighbourTE.setSpeed(newSpeed);
|
||||
neighbourTE.setSource(updateTE.getPos());
|
||||
neighbourTE.setSource(currentTE.getPos());
|
||||
neighbourTE.onSpeedChanged(prevSpeed);
|
||||
neighbourTE.sendData();
|
||||
propagateNewSource(neighbourTE);
|
||||
|
@ -294,7 +300,7 @@ public class RotationPropagator {
|
|||
return;
|
||||
if (removedTE == null)
|
||||
return;
|
||||
if (removedTE.speed == 0)
|
||||
if (removedTE.getTheoreticalSpeed() == 0)
|
||||
return;
|
||||
|
||||
for (BlockPos neighbourPos : getPotentialNeighbourLocations(removedTE)) {
|
||||
|
|
|
@ -27,22 +27,15 @@ public class TorquePropagator {
|
|||
UUID id = te.getNetworkID();
|
||||
KineticNetwork network;
|
||||
Map<UUID, KineticNetwork> map = networks.get(te.getWorld());
|
||||
if (id == null) {
|
||||
if (id == null)
|
||||
return null;
|
||||
|
||||
if (!map.containsKey(id)) {
|
||||
network = new KineticNetwork();
|
||||
|
||||
// Debug.debugChatAndShowStack(te.getType().getRegistryName().getPath() + " created new Network", 5);
|
||||
|
||||
te.newNetworkID = network.id;
|
||||
te.updateNetwork = true;
|
||||
network.id = te.getNetworkID();
|
||||
map.put(id, network);
|
||||
} else {
|
||||
if (!map.containsKey(id)) {
|
||||
network = new KineticNetwork();
|
||||
network.id = te.getNetworkID();
|
||||
map.put(id, network);
|
||||
}
|
||||
network = map.get(id);
|
||||
}
|
||||
network = map.get(id);
|
||||
return network;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,14 +1,17 @@
|
|||
package com.simibubi.create.modules.contraptions.base;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
import com.simibubi.create.modules.contraptions.KineticNetwork;
|
||||
import com.simibubi.create.modules.contraptions.base.IRotate.SpeedLevel;
|
||||
|
||||
import net.minecraft.tileentity.TileEntityType;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
|
||||
public abstract class GeneratingKineticTileEntity extends KineticTileEntity {
|
||||
|
||||
public boolean reActivateSource;
|
||||
|
||||
public GeneratingKineticTileEntity(TileEntityType<?> typeIn) {
|
||||
super(typeIn);
|
||||
}
|
||||
|
@ -18,68 +21,108 @@ public abstract class GeneratingKineticTileEntity extends KineticTileEntity {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void reActivateSource() {
|
||||
updateGeneratedRotation();
|
||||
public void removeSource() {
|
||||
if (hasSource() && isSource())
|
||||
reActivateSource = true;
|
||||
super.removeSource();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSource(BlockPos source) {
|
||||
super.setSource(source);
|
||||
KineticTileEntity sourceTe = (KineticTileEntity) world.getTileEntity(source);
|
||||
if (reActivateSource && sourceTe != null && Math.abs(sourceTe.getSpeed()) >= Math.abs(getGeneratedSpeed()))
|
||||
reActivateSource = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
super.tick();
|
||||
if (reActivateSource) {
|
||||
updateGeneratedRotation();
|
||||
reActivateSource = false;
|
||||
}
|
||||
}
|
||||
|
||||
public void updateGeneratedRotation() {
|
||||
float speed = getGeneratedSpeed();
|
||||
float prevSpeed = this.speed;
|
||||
|
||||
if (this.speed != speed) {
|
||||
if (world.isRemote)
|
||||
return;
|
||||
|
||||
if (!world.isRemote) {
|
||||
if (prevSpeed != speed) {
|
||||
if (!hasSource()) {
|
||||
SpeedLevel levelBefore = SpeedLevel.of(this.speed);
|
||||
SpeedLevel levelafter = SpeedLevel.of(speed);
|
||||
if (levelBefore != levelafter)
|
||||
queueRotationIndicators();
|
||||
effects.queueRotationIndicators();
|
||||
}
|
||||
|
||||
if (speed == 0) {
|
||||
if (hasSource())
|
||||
notifyStressCapacityChange(0);
|
||||
else {
|
||||
detachKinetics();
|
||||
setSpeed(speed);
|
||||
newNetworkID = null;
|
||||
updateNetwork = true;
|
||||
}
|
||||
} else if (this.speed == 0) {
|
||||
setSpeed(speed);
|
||||
newNetworkID = UUID.randomUUID();
|
||||
updateNetwork = true;
|
||||
attachKinetics();
|
||||
} else {
|
||||
if (hasSource()) {
|
||||
if (Math.abs(this.speed) >= Math.abs(speed)) {
|
||||
if (Math.signum(this.speed) == Math.signum(speed))
|
||||
notifyStressCapacityChange(getAddedStressCapacity());
|
||||
else
|
||||
world.destroyBlock(pos, true);
|
||||
} else {
|
||||
detachKinetics();
|
||||
setSpeed(speed);
|
||||
source = Optional.empty();
|
||||
newNetworkID = UUID.randomUUID();
|
||||
updateNetwork = true;
|
||||
attachKinetics();
|
||||
}
|
||||
} else {
|
||||
detachKinetics();
|
||||
setSpeed(speed);
|
||||
attachKinetics();
|
||||
}
|
||||
}
|
||||
applyNewSpeed(prevSpeed, speed);
|
||||
}
|
||||
|
||||
if (hasNetwork() && speed != 0) {
|
||||
getNetwork().updateCapacityFor(this, getAddedStressCapacity());
|
||||
getNetwork().updateStressCapacity();
|
||||
getNetwork().updateStress();
|
||||
KineticNetwork network = getNetwork();
|
||||
network.updateCapacityFor(this, getAddedStressCapacity());
|
||||
network.updateStress();
|
||||
}
|
||||
|
||||
onSpeedChanged(prevSpeed);
|
||||
sendData();
|
||||
}
|
||||
|
||||
public void applyNewSpeed(float prevSpeed, float speed) {
|
||||
|
||||
// Speed changed to 0
|
||||
if (speed == 0) {
|
||||
if (hasSource() && hasNetwork()) {
|
||||
getNetwork().updateCapacityFor(this, 0);
|
||||
return;
|
||||
}
|
||||
detachKinetics();
|
||||
setSpeed(speed);
|
||||
newNetworkID = null;
|
||||
updateNetwork = true;
|
||||
return;
|
||||
}
|
||||
|
||||
// Now turning - create a new Network
|
||||
if (prevSpeed == 0) {
|
||||
setSpeed(speed);
|
||||
newNetworkID = UUID.randomUUID();
|
||||
updateNetwork = true;
|
||||
attachKinetics();
|
||||
return;
|
||||
}
|
||||
|
||||
// Change speed when overpowered by other generator
|
||||
if (hasSource() && hasNetwork()) {
|
||||
|
||||
// Staying below Overpowered speed
|
||||
if (Math.abs(prevSpeed) >= Math.abs(speed)) {
|
||||
if (Math.signum(prevSpeed) != Math.signum(speed)) {
|
||||
world.destroyBlock(pos, true);
|
||||
return;
|
||||
}
|
||||
getNetwork().updateCapacityFor(this, getAddedStressCapacity());
|
||||
return;
|
||||
}
|
||||
|
||||
// Faster than attached network -> become the new source
|
||||
detachKinetics();
|
||||
setSpeed(speed);
|
||||
source = null;
|
||||
newNetworkID = UUID.randomUUID();
|
||||
updateNetwork = true;
|
||||
attachKinetics();
|
||||
return;
|
||||
}
|
||||
|
||||
// Reapply source
|
||||
detachKinetics();
|
||||
setSpeed(speed);
|
||||
attachKinetics();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -112,7 +112,7 @@ public abstract class KineticBlock extends Block implements IRotate {
|
|||
return;
|
||||
|
||||
KineticTileEntity kte = (KineticTileEntity) tileEntity;
|
||||
kte.queueRotationIndicators();
|
||||
kte.effects.queueRotationIndicators();
|
||||
}
|
||||
|
||||
public float getParticleTargetRadius() {
|
||||
|
|
|
@ -0,0 +1,116 @@
|
|||
package com.simibubi.create.modules.contraptions.base;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import com.simibubi.create.foundation.advancement.AllTriggers;
|
||||
import com.simibubi.create.foundation.utility.VecHelper;
|
||||
import com.simibubi.create.modules.contraptions.base.IRotate.SpeedLevel;
|
||||
import com.simibubi.create.modules.contraptions.particle.RotationIndicatorParticleData;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.particles.IParticleData;
|
||||
import net.minecraft.particles.ParticleTypes;
|
||||
import net.minecraft.util.Direction.Axis;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.server.ServerWorld;
|
||||
|
||||
public class KineticEffectHandler {
|
||||
|
||||
int overStressedTime;
|
||||
float overStressedEffect;
|
||||
int particleSpawnCountdown;
|
||||
KineticTileEntity kte;
|
||||
|
||||
public KineticEffectHandler(KineticTileEntity kte) {
|
||||
this.kte = kte;
|
||||
}
|
||||
|
||||
public void tick() {
|
||||
World world = kte.getWorld();
|
||||
|
||||
if (world.isRemote) {
|
||||
if (overStressedTime > 0)
|
||||
if (--overStressedTime == 0)
|
||||
if (kte.overStressed) {
|
||||
overStressedEffect = 1;
|
||||
spawnEffect(ParticleTypes.SMOKE, 0.2f, 5);
|
||||
} else {
|
||||
overStressedEffect = -1;
|
||||
spawnEffect(ParticleTypes.CLOUD, .075f, 2);
|
||||
}
|
||||
|
||||
if (overStressedEffect != 0) {
|
||||
overStressedEffect -= overStressedEffect * .1f;
|
||||
if (Math.abs(overStressedEffect) < 1 / 128f)
|
||||
overStressedEffect = 0;
|
||||
}
|
||||
|
||||
} else if (particleSpawnCountdown > 0) {
|
||||
if (--particleSpawnCountdown == 0)
|
||||
spawnRotationIndicators();
|
||||
}
|
||||
}
|
||||
|
||||
public void queueRotationIndicators() {
|
||||
particleSpawnCountdown = 2;
|
||||
}
|
||||
|
||||
public void spawnEffect(IParticleData particle, float maxMotion, int amount) {
|
||||
World world = kte.getWorld();
|
||||
if (world == null)
|
||||
return;
|
||||
if (!world.isRemote)
|
||||
return;
|
||||
Random r = world.rand;
|
||||
for (int i = 0; i < amount; i++) {
|
||||
Vec3d motion = VecHelper.offsetRandomly(Vec3d.ZERO, r, maxMotion);
|
||||
Vec3d position = VecHelper.getCenterOf(kte.getPos());
|
||||
world.addParticle(particle, position.x, position.y, position.z, motion.x, motion.y, motion.z);
|
||||
}
|
||||
}
|
||||
|
||||
public void spawnRotationIndicators() {
|
||||
float speed = kte.getSpeed();
|
||||
if (speed == 0)
|
||||
return;
|
||||
|
||||
BlockState state = kte.getBlockState();
|
||||
Block block = state.getBlock();
|
||||
if (!(block instanceof KineticBlock))
|
||||
return;
|
||||
|
||||
KineticBlock kb = (KineticBlock) block;
|
||||
float radius1 = kb.getParticleInitialRadius();
|
||||
float radius2 = kb.getParticleTargetRadius();
|
||||
|
||||
Axis axis = kb.getRotationAxis(state);
|
||||
BlockPos pos = kte.getPos();
|
||||
World world = kte.getWorld();
|
||||
if (axis == null)
|
||||
return;
|
||||
if (world == null)
|
||||
return;
|
||||
|
||||
char axisChar = axis.name().charAt(0);
|
||||
Vec3d vec = VecHelper.getCenterOf(pos);
|
||||
SpeedLevel speedLevel = SpeedLevel.of(speed);
|
||||
int color = speedLevel.getColor();
|
||||
int particleSpeed = speedLevel.getParticleSpeed();
|
||||
particleSpeed *= Math.signum(speed);
|
||||
|
||||
if (world instanceof ServerWorld) {
|
||||
AllTriggers.triggerForNearbyPlayers(AllTriggers.ROTATION, world, pos, 5);
|
||||
RotationIndicatorParticleData particleData =
|
||||
new RotationIndicatorParticleData(color, particleSpeed, radius1, radius2, 10, axisChar);
|
||||
((ServerWorld) world).spawnParticle(particleData, vec.x, vec.y, vec.z, 20, 0, 0, 0, 1);
|
||||
}
|
||||
}
|
||||
|
||||
public void triggerOverStressedEffect() {
|
||||
overStressedTime = overStressedTime == 0 ? 2 : 0;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,12 +1,7 @@
|
|||
package com.simibubi.create.modules.contraptions.base;
|
||||
|
||||
import static net.minecraft.util.text.TextFormatting.GREEN;
|
||||
import static net.minecraft.util.text.TextFormatting.WHITE;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Random;
|
||||
import java.util.UUID;
|
||||
|
||||
import com.simibubi.create.Create;
|
||||
|
@ -14,60 +9,113 @@ import com.simibubi.create.config.AllConfigs;
|
|||
import com.simibubi.create.foundation.advancement.AllTriggers;
|
||||
import com.simibubi.create.foundation.behaviour.base.SmartTileEntity;
|
||||
import com.simibubi.create.foundation.behaviour.base.TileEntityBehaviour;
|
||||
import com.simibubi.create.foundation.utility.VecHelper;
|
||||
import com.simibubi.create.modules.contraptions.KineticNetwork;
|
||||
import com.simibubi.create.modules.contraptions.RotationPropagator;
|
||||
import com.simibubi.create.modules.contraptions.base.IRotate.SpeedLevel;
|
||||
import com.simibubi.create.modules.contraptions.base.IRotate.StressImpact;
|
||||
import com.simibubi.create.modules.contraptions.particle.RotationIndicatorParticleData;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
import net.minecraft.nbt.NBTUtil;
|
||||
import net.minecraft.particles.IParticleData;
|
||||
import net.minecraft.particles.ParticleTypes;
|
||||
import net.minecraft.tileentity.ITickableTileEntity;
|
||||
import net.minecraft.tileentity.TileEntityType;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.Direction.Axis;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.world.server.ServerWorld;
|
||||
import net.minecraftforge.common.ForgeConfigSpec.ConfigValue;
|
||||
|
||||
public abstract class KineticTileEntity extends SmartTileEntity implements ITickableTileEntity {
|
||||
|
||||
int particleSpawnCountdown;
|
||||
protected UUID networkID;
|
||||
protected UUID newNetworkID;
|
||||
protected float maxStress;
|
||||
protected float currentStress;
|
||||
protected boolean updateNetwork;
|
||||
|
||||
// Speed related
|
||||
public float speed;
|
||||
protected Optional<BlockPos> source;
|
||||
public boolean reActivateSource;
|
||||
public int speedChangeCounter;
|
||||
|
||||
// Torque related
|
||||
public float maxStress;
|
||||
public float currentStress;
|
||||
protected KineticEffectHandler effects;
|
||||
protected BlockPos source;
|
||||
protected float speed;
|
||||
protected boolean overStressed;
|
||||
public UUID networkID;
|
||||
public UUID newNetworkID;
|
||||
public boolean updateNetwork;
|
||||
protected boolean initNetwork;
|
||||
|
||||
// Client
|
||||
int overStressedTime;
|
||||
float overStressedEffect;
|
||||
private int flickerTally;
|
||||
private int validationCountdown;
|
||||
|
||||
public KineticTileEntity(TileEntityType<?> typeIn) {
|
||||
super(typeIn);
|
||||
speed = 0;
|
||||
source = Optional.empty();
|
||||
effects = new KineticEffectHandler(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addBehaviours(List<TileEntityBehaviour> behaviours) {
|
||||
public void tick() {
|
||||
super.tick();
|
||||
effects.tick();
|
||||
|
||||
if (world.isRemote)
|
||||
return;
|
||||
|
||||
if (validationCountdown-- <= 0) {
|
||||
validationCountdown = AllConfigs.SERVER.kinetics.kineticValidationFrequency.get();
|
||||
validateKinetics();
|
||||
}
|
||||
|
||||
if (getFlickerScore() > 0)
|
||||
flickerTally = getFlickerScore() - 1;
|
||||
|
||||
if (initNetwork) {
|
||||
initNetwork = false;
|
||||
|
||||
KineticNetwork network = getNetwork();
|
||||
if (!network.initialized)
|
||||
network.initFromTE(maxStress, currentStress);
|
||||
network.addSilently(this);
|
||||
}
|
||||
|
||||
if (updateNetwork) {
|
||||
updateNetwork = false;
|
||||
|
||||
if (hasNetwork() && !networkID.equals(newNetworkID)) {
|
||||
getNetwork().remove(this);
|
||||
networkID = null;
|
||||
maxStress = currentStress = 0;
|
||||
overStressed = false;
|
||||
}
|
||||
|
||||
if (newNetworkID != null) {
|
||||
networkID = newNetworkID;
|
||||
KineticNetwork network = getNetwork();
|
||||
network.initialized = true;
|
||||
network.add(this);
|
||||
}
|
||||
|
||||
sendData();
|
||||
}
|
||||
}
|
||||
|
||||
private void validateKinetics() {
|
||||
if (hasSource()) {
|
||||
if (!world.isBlockPresent(source))
|
||||
return;
|
||||
|
||||
KineticTileEntity sourceTe = (KineticTileEntity) world.getTileEntity(source);
|
||||
if (sourceTe == null || sourceTe.speed == 0) {
|
||||
removeSource();
|
||||
detachKinetics();
|
||||
return;
|
||||
}
|
||||
|
||||
if (hasNetwork() && maxStress == 0) {
|
||||
for (KineticTileEntity kineticTileEntity : getNetwork().members.keySet())
|
||||
kineticTileEntity.removeSource();
|
||||
return;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (speed != 0) {
|
||||
if (getGeneratedSpeed() == 0)
|
||||
setSpeed(0);
|
||||
}
|
||||
}
|
||||
|
||||
public void sync(float maxStress, float currentStress) {
|
||||
|
@ -100,46 +148,35 @@ public abstract class KineticTileEntity extends SmartTileEntity implements ITick
|
|||
return stressEntries.get(path).get().floatValue();
|
||||
}
|
||||
|
||||
protected void notifyStressChange(float stress) {
|
||||
getNetwork().updateStressFor(this, stress);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasFastRenderer() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public void onSpeedChanged(float previousSpeed) {
|
||||
boolean fromOrToZero = (previousSpeed == 0) != (getSpeed() == 0);
|
||||
boolean directionSwap = !fromOrToZero && Math.signum(previousSpeed) != Math.signum(getSpeed());
|
||||
if (fromOrToZero || directionSwap) {
|
||||
speedChangeCounter += 5;
|
||||
flickerTally = getFlickerScore() + 5;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
if (world.isRemote) {
|
||||
super.remove();
|
||||
return;
|
||||
if (!world.isRemote) {
|
||||
if (hasNetwork())
|
||||
getNetwork().remove(this);
|
||||
detachKinetics();
|
||||
}
|
||||
if (hasNetwork()) {
|
||||
getNetwork().remove(this);
|
||||
}
|
||||
RotationPropagator.handleRemoved(getWorld(), getPos(), this);
|
||||
super.remove();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundNBT write(CompoundNBT compound) {
|
||||
compound.putFloat("Speed", speed);
|
||||
|
||||
if (hasSource())
|
||||
compound.put("Source", NBTUtil.writeBlockPos(getSource()));
|
||||
compound.put("Source", NBTUtil.writeBlockPos(source));
|
||||
|
||||
if (hasNetwork()) {
|
||||
compound.putFloat("MaxStress", maxStress);
|
||||
compound.putFloat("Stress", currentStress);
|
||||
compound.put("Id", NBTUtil.writeUniqueId(getNetworkID()));
|
||||
compound.put("Id", NBTUtil.writeUniqueId(networkID));
|
||||
}
|
||||
|
||||
return super.write(compound);
|
||||
|
@ -147,23 +184,21 @@ public abstract class KineticTileEntity extends SmartTileEntity implements ITick
|
|||
|
||||
@Override
|
||||
public void read(CompoundNBT compound) {
|
||||
setSpeed(compound.getFloat("Speed"));
|
||||
setSource(null);
|
||||
if (compound.contains("Source")) {
|
||||
CompoundNBT tagSource = compound.getCompound("Source");
|
||||
setSource(NBTUtil.readBlockPos(tagSource));
|
||||
}
|
||||
speed = compound.getFloat("Speed");
|
||||
source = null;
|
||||
networkID = newNetworkID = null;
|
||||
overStressed = false;
|
||||
|
||||
if (compound.contains("Source"))
|
||||
source = NBTUtil.readBlockPos(compound.getCompound("Source"));
|
||||
|
||||
if (compound.contains("Id")) {
|
||||
maxStress = compound.getFloat("MaxStress");
|
||||
currentStress = compound.getFloat("Stress");
|
||||
overStressed = maxStress < currentStress && StressImpact.isEnabled();
|
||||
setNetworkID(NBTUtil.readUniqueId(compound.getCompound("Id")));
|
||||
networkID = NBTUtil.readUniqueId(compound.getCompound("Id"));
|
||||
newNetworkID = networkID;
|
||||
initNetwork = true;
|
||||
} else {
|
||||
networkID = newNetworkID = null;
|
||||
overStressed = false;
|
||||
}
|
||||
|
||||
super.read(compound);
|
||||
|
@ -174,7 +209,7 @@ public abstract class KineticTileEntity extends SmartTileEntity implements ITick
|
|||
boolean overStressedBefore = overStressed;
|
||||
super.readClientUpdate(tag);
|
||||
if (overStressedBefore != overStressed && speed != 0)
|
||||
overStressedTime = overStressedTime == 0 ? 2 : 0;
|
||||
effects.triggerOverStressedEffect();
|
||||
}
|
||||
|
||||
public boolean isSource() {
|
||||
|
@ -184,6 +219,10 @@ public abstract class KineticTileEntity extends SmartTileEntity implements ITick
|
|||
public float getSpeed() {
|
||||
if (overStressed)
|
||||
return 0;
|
||||
return getTheoreticalSpeed();
|
||||
}
|
||||
|
||||
public float getTheoreticalSpeed() {
|
||||
return speed;
|
||||
}
|
||||
|
||||
|
@ -196,31 +235,22 @@ public abstract class KineticTileEntity extends SmartTileEntity implements ITick
|
|||
}
|
||||
|
||||
public boolean hasSource() {
|
||||
return source.isPresent();
|
||||
return source != null;
|
||||
}
|
||||
|
||||
public BlockPos getSource() {
|
||||
return source.get();
|
||||
}
|
||||
|
||||
public Direction getSourceFacing() {
|
||||
BlockPos source = getSource().subtract(getPos());
|
||||
return Direction.getFacingFromVector(source.getX(), source.getY(), source.getZ());
|
||||
return source;
|
||||
}
|
||||
|
||||
public void setSource(BlockPos source) {
|
||||
this.source = Optional.ofNullable(source);
|
||||
|
||||
this.source = source;
|
||||
if (world == null || world.isRemote)
|
||||
return;
|
||||
if (source == null)
|
||||
return;
|
||||
KineticTileEntity sourceTe = (KineticTileEntity) world.getTileEntity(source);
|
||||
if (sourceTe == null)
|
||||
return;
|
||||
|
||||
if (reActivateSource && Math.abs(sourceTe.getSpeed()) >= Math.abs(getGeneratedSpeed())) {
|
||||
reActivateSource = false;
|
||||
KineticTileEntity sourceTe = (KineticTileEntity) world.getTileEntity(source);
|
||||
if (sourceTe == null) {
|
||||
removeSource();
|
||||
return;
|
||||
}
|
||||
|
||||
newNetworkID = sourceTe.newNetworkID;
|
||||
|
@ -228,10 +258,7 @@ public abstract class KineticTileEntity extends SmartTileEntity implements ITick
|
|||
}
|
||||
|
||||
public void removeSource() {
|
||||
if (hasSource() && isSource())
|
||||
reActivateSource = true;
|
||||
|
||||
this.source = Optional.empty();
|
||||
source = null;
|
||||
newNetworkID = null;
|
||||
updateNetwork = true;
|
||||
float prevSpeed = getSpeed();
|
||||
|
@ -247,10 +274,8 @@ public abstract class KineticTileEntity extends SmartTileEntity implements ITick
|
|||
return networkID != null;
|
||||
}
|
||||
|
||||
public void applyNewSpeed(float speed) {
|
||||
detachKinetics();
|
||||
this.speed = speed;
|
||||
attachKinetics();
|
||||
public boolean canOverPower(KineticTileEntity other) {
|
||||
return newNetworkID != null && !newNetworkID.equals(other.newNetworkID);
|
||||
}
|
||||
|
||||
public void attachKinetics() {
|
||||
|
@ -269,79 +294,6 @@ public abstract class KineticTileEntity extends SmartTileEntity implements ITick
|
|||
this.networkID = networkID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for source blocks to re-apply their speed when an overpowering
|
||||
* source is removed
|
||||
*/
|
||||
public void reActivateSource() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
super.tick();
|
||||
|
||||
if (world.isRemote) {
|
||||
if (overStressedTime > 0)
|
||||
if (--overStressedTime == 0)
|
||||
if (overStressed) {
|
||||
overStressedEffect = 1;
|
||||
spawnEffect(ParticleTypes.SMOKE, 0.2f, 5);
|
||||
} else {
|
||||
overStressedEffect = -1;
|
||||
spawnEffect(ParticleTypes.CLOUD, .075f, 2);
|
||||
}
|
||||
|
||||
if (overStressedEffect != 0) {
|
||||
overStressedEffect -= overStressedEffect * .1f;
|
||||
if (Math.abs(overStressedEffect) < 1 / 128f)
|
||||
overStressedEffect = 0;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (speedChangeCounter > 0)
|
||||
speedChangeCounter--;
|
||||
|
||||
if (particleSpawnCountdown > 0)
|
||||
if (--particleSpawnCountdown == 0)
|
||||
spawnRotationIndicators();
|
||||
|
||||
if (initNetwork) {
|
||||
initNetwork = false;
|
||||
|
||||
KineticNetwork network = getNetwork();
|
||||
if (!network.initialized)
|
||||
network.initFromTE(this);
|
||||
network.addSilently(this);
|
||||
}
|
||||
|
||||
if (updateNetwork) {
|
||||
updateNetwork = false;
|
||||
|
||||
if (hasNetwork() && !networkID.equals(newNetworkID)) {
|
||||
getNetwork().remove(this);
|
||||
networkID = null;
|
||||
maxStress = currentStress = 0;
|
||||
overStressed = false;
|
||||
}
|
||||
|
||||
if (newNetworkID != null) {
|
||||
networkID = newNetworkID;
|
||||
KineticNetwork network = getNetwork();
|
||||
network.initialized = true;
|
||||
network.add(this);
|
||||
}
|
||||
|
||||
sendData();
|
||||
}
|
||||
|
||||
if (reActivateSource) {
|
||||
reActivateSource();
|
||||
reActivateSource = false;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isSpeedRequirementFulfilled() {
|
||||
BlockState state = getBlockState();
|
||||
if (!(getBlockState().getBlock() instanceof IRotate))
|
||||
|
@ -357,60 +309,17 @@ public abstract class KineticTileEntity extends SmartTileEntity implements ITick
|
|||
return true;
|
||||
}
|
||||
|
||||
public void addDebugInformation(List<String> lines) {
|
||||
lines.add("Speed: " + GREEN + speed);
|
||||
lines.add("Cost: " + GREEN + getStressApplied() + WHITE + "/" + GREEN + getAddedStressCapacity());
|
||||
lines.add("Stress: " + GREEN + currentStress + WHITE + "/" + GREEN + maxStress);
|
||||
@Override
|
||||
public void addBehaviours(List<TileEntityBehaviour> behaviours) {
|
||||
}
|
||||
|
||||
public void queueRotationIndicators() {
|
||||
// wait a few ticks for network jamming etc
|
||||
particleSpawnCountdown = 2;
|
||||
@Override
|
||||
public boolean hasFastRenderer() {
|
||||
return true;
|
||||
}
|
||||
|
||||
protected void spawnEffect(IParticleData particle, float maxMotion, int amount) {
|
||||
if (!hasWorld())
|
||||
return;
|
||||
if (!world.isRemote)
|
||||
return;
|
||||
Random r = getWorld().rand;
|
||||
for (int i = 0; i < amount; i++) {
|
||||
Vec3d motion = VecHelper.offsetRandomly(Vec3d.ZERO, r, maxMotion);
|
||||
Vec3d position = VecHelper.getCenterOf(pos);
|
||||
this.getWorld().addParticle(particle, position.x, position.y, position.z, motion.x, motion.y, motion.z);
|
||||
}
|
||||
}
|
||||
|
||||
protected void spawnRotationIndicators() {
|
||||
if (getSpeed() == 0)
|
||||
return;
|
||||
|
||||
BlockState state = getBlockState();
|
||||
Block block = state.getBlock();
|
||||
if (!(block instanceof KineticBlock))
|
||||
return;
|
||||
|
||||
KineticBlock kb = (KineticBlock) block;
|
||||
float radius1 = kb.getParticleInitialRadius();
|
||||
float radius2 = kb.getParticleTargetRadius();
|
||||
|
||||
Axis axis = kb.getRotationAxis(state);
|
||||
if (axis == null)
|
||||
return;
|
||||
char axisChar = axis.name().charAt(0);
|
||||
Vec3d vec = VecHelper.getCenterOf(pos);
|
||||
|
||||
SpeedLevel speedLevel = SpeedLevel.of(getSpeed());
|
||||
int color = speedLevel.getColor();
|
||||
int particleSpeed = speedLevel.getParticleSpeed();
|
||||
particleSpeed *= Math.signum(getSpeed());
|
||||
|
||||
if (getWorld() instanceof ServerWorld) {
|
||||
AllTriggers.triggerForNearbyPlayers(AllTriggers.ROTATION, world, pos, 5);
|
||||
RotationIndicatorParticleData particleData =
|
||||
new RotationIndicatorParticleData(color, particleSpeed, radius1, radius2, 10, axisChar);
|
||||
((ServerWorld) getWorld()).spawnParticle(particleData, vec.x, vec.y, vec.z, 20, 0, 0, 0, 1);
|
||||
}
|
||||
public int getFlickerScore() {
|
||||
return flickerTally;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -24,8 +24,8 @@ public class KineticTileEntityRenderer extends SafeTileEntityRendererFast<Kineti
|
|||
public static boolean rainbowMode = false;
|
||||
|
||||
@Override
|
||||
public void renderFast(KineticTileEntity te, double x, double y, double z, float partialTicks,
|
||||
int destroyStage, BufferBuilder buffer) {
|
||||
public void renderFast(KineticTileEntity te, double x, double y, double z, float partialTicks, int destroyStage,
|
||||
BufferBuilder buffer) {
|
||||
renderRotatingBuffer(te, getWorld(), getRotatedModel(te), x, y, z, buffer);
|
||||
}
|
||||
|
||||
|
@ -34,7 +34,7 @@ public class KineticTileEntityRenderer extends SafeTileEntityRendererFast<Kineti
|
|||
SuperByteBuffer superByteBuffer = CreateClient.bufferCache.renderBlockIn(KINETIC_TILE, renderedState);
|
||||
renderRotatingBuffer(te, world, superByteBuffer, x, y, z, buffer);
|
||||
}
|
||||
|
||||
|
||||
public static void renderRotatingBuffer(KineticTileEntity te, World world, SuperByteBuffer superBuffer, double x,
|
||||
double y, double z, BufferBuilder buffer) {
|
||||
buffer.putBulkData(standardKineticRotationTransform(superBuffer, te, world).translate(x, y, z).build());
|
||||
|
@ -68,11 +68,12 @@ public class KineticTileEntityRenderer extends SafeTileEntityRendererFast<Kineti
|
|||
else
|
||||
buffer.color(white);
|
||||
} else {
|
||||
if (te.overStressedEffect != 0)
|
||||
if (te.overStressedEffect > 0)
|
||||
buffer.color(ColorHelper.mixColors(white, 0xFF0000, te.overStressedEffect));
|
||||
float overStressedEffect = te.effects.overStressedEffect;
|
||||
if (overStressedEffect != 0)
|
||||
if (overStressedEffect > 0)
|
||||
buffer.color(ColorHelper.mixColors(white, 0xFF0000, overStressedEffect));
|
||||
else
|
||||
buffer.color(ColorHelper.mixColors(white, 0x00FFBB, -te.overStressedEffect));
|
||||
buffer.color(ColorHelper.mixColors(white, 0x00FFBB, -overStressedEffect));
|
||||
else
|
||||
buffer.color(white);
|
||||
}
|
||||
|
@ -97,5 +98,5 @@ public class KineticTileEntityRenderer extends SafeTileEntityRendererFast<Kineti
|
|||
protected SuperByteBuffer getRotatedModel(KineticTileEntity te) {
|
||||
return CreateClient.bufferCache.renderBlockIn(KINETIC_TILE, getRenderedBlockState(te));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -63,7 +63,7 @@ public class DeployerTileEntityRenderer extends SafeTileEntityRenderer<DeployerT
|
|||
|
||||
float yRot = AngleHelper.horizontalAngle(facing) + 180;
|
||||
float zRot = facing == Direction.UP ? 90 : facing == Direction.DOWN ? 270 : 0;
|
||||
boolean displayMode = facing == Direction.UP && te.speed == 0 && !punching;
|
||||
boolean displayMode = facing == Direction.UP && te.getSpeed() == 0 && !punching;
|
||||
|
||||
GlStateManager.rotatef(yRot, 0, 1, 0);
|
||||
if (!displayMode) {
|
||||
|
|
|
@ -86,7 +86,7 @@ public class SawBlock extends DirectionalAxisKineticBlock implements IWithTileEn
|
|||
withTileEntityDo(worldIn, pos, te -> {
|
||||
if (te.getSpeed() == 0)
|
||||
return;
|
||||
entityIn.attackEntityFrom(damageSourceSaw, MathHelper.clamp(Math.abs(te.speed / 512f) + 1, 0, 20));
|
||||
entityIn.attackEntityFrom(damageSourceSaw, MathHelper.clamp(Math.abs(te.getSpeed() / 512f) + 1, 0, 20));
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -68,7 +68,7 @@ public class WaterWheelBlock extends HorizontalKineticBlock {
|
|||
public void onBlockAdded(BlockState state, World worldIn, BlockPos pos, BlockState oldState, boolean isMoving) {
|
||||
updateAllSides(state, worldIn, pos);
|
||||
}
|
||||
|
||||
|
||||
public void updateAllSides(BlockState state, World worldIn, BlockPos pos) {
|
||||
for (Direction d : Direction.values())
|
||||
updateFlowAt(state, worldIn, pos, d);
|
||||
|
@ -88,7 +88,8 @@ public class WaterWheelBlock extends HorizontalKineticBlock {
|
|||
|
||||
flowVec = flowVec.scale(f.getAxisDirection().getOffset());
|
||||
boolean clockwise = wf.getAxisDirection() == AxisDirection.POSITIVE;
|
||||
int clockwiseMultiplier = 2;
|
||||
int clockwiseMultiplier = 2;
|
||||
flowVec = new Vec3d(Math.signum(flowVec.x), Math.signum(flowVec.y), Math.signum(flowVec.z));
|
||||
|
||||
if (wf.getAxis() == Axis.Z) {
|
||||
if (f.getAxis() == Axis.Y)
|
||||
|
@ -149,10 +150,10 @@ public class WaterWheelBlock extends HorizontalKineticBlock {
|
|||
public float getParticleInitialRadius() {
|
||||
return 1f;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean hideStressImpact() {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -65,12 +65,13 @@ public class SpeedControllerTileEntity extends KineticTileEntity {
|
|||
|
||||
if (targetSpeed == 0)
|
||||
return 0;
|
||||
if (targetingController && cogWheel.speed == 0)
|
||||
float wheelSpeed = cogWheel.getTheoreticalSpeed();
|
||||
if (targetingController && wheelSpeed == 0)
|
||||
return 1;
|
||||
|
||||
if (!speedController.hasSource()) {
|
||||
if (targetingController)
|
||||
return targetSpeed / cogWheel.speed;
|
||||
return targetSpeed / wheelSpeed;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -78,8 +79,8 @@ public class SpeedControllerTileEntity extends KineticTileEntity {
|
|||
|
||||
if (wheelPowersController) {
|
||||
if (targetingController)
|
||||
return targetSpeed / cogWheel.speed;
|
||||
return cogWheel.speed / targetSpeed;
|
||||
return targetSpeed / wheelSpeed;
|
||||
return wheelSpeed / targetSpeed;
|
||||
}
|
||||
|
||||
if (targetingController)
|
||||
|
|
|
@ -347,7 +347,7 @@ public class BeltBlock extends HorizontalKineticBlock implements IHaveNoBlockIte
|
|||
return;
|
||||
BeltTileEntity beltEntity = (BeltTileEntity) tileEntity;
|
||||
BlockPos controller = beltEntity.getController();
|
||||
beltEntity.setSource(null);
|
||||
beltEntity.removeSource();
|
||||
beltEntity.remove();
|
||||
|
||||
int limit = 1000;
|
||||
|
@ -368,7 +368,7 @@ public class BeltBlock extends HorizontalKineticBlock implements IHaveNoBlockIte
|
|||
inv.eject(stack);
|
||||
}
|
||||
|
||||
te.setSource(null);
|
||||
te.removeSource();
|
||||
te.remove();
|
||||
|
||||
if (destroyedBlock.get(CASING))
|
||||
|
|
|
@ -194,8 +194,8 @@ public class BeltConnectorItem extends BlockItem implements IAddedByOther {
|
|||
if (axis != world.getBlockState(second).get(BlockStateProperties.AXIS))
|
||||
return false;
|
||||
|
||||
float speed1 = ((KineticTileEntity) world.getTileEntity(first)).speed;
|
||||
float speed2 = ((KineticTileEntity) world.getTileEntity(second)).speed;
|
||||
float speed1 = ((KineticTileEntity) world.getTileEntity(first)).getTheoreticalSpeed();
|
||||
float speed2 = ((KineticTileEntity) world.getTileEntity(second)).getTheoreticalSpeed();
|
||||
if (Math.signum(speed1) != Math.signum(speed2) && speed1 != 0 && speed2 != 0)
|
||||
return false;
|
||||
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
package com.simibubi.create.modules.contraptions.relays.encased;
|
||||
|
||||
import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
|
||||
|
||||
import net.minecraft.tileentity.TileEntityType;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
|
||||
public class DirectionalShaftHalvesTileEntity extends KineticTileEntity {
|
||||
|
||||
public DirectionalShaftHalvesTileEntity(TileEntityType<?> typeIn) {
|
||||
super(typeIn);
|
||||
}
|
||||
|
||||
public Direction getSourceFacing() {
|
||||
BlockPos source = getSource().subtract(getPos());
|
||||
return Direction.getFacingFromVector(source.getX(), source.getY(), source.getZ());
|
||||
}
|
||||
|
||||
}
|
|
@ -1,11 +1,9 @@
|
|||
package com.simibubi.create.modules.contraptions.relays.encased;
|
||||
|
||||
import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
|
||||
|
||||
import net.minecraft.tileentity.TileEntityType;
|
||||
import net.minecraft.util.Direction;
|
||||
|
||||
public abstract class SplitShaftTileEntity extends KineticTileEntity {
|
||||
public abstract class SplitShaftTileEntity extends DirectionalShaftHalvesTileEntity {
|
||||
|
||||
public SplitShaftTileEntity(TileEntityType<?> typeIn) {
|
||||
super(typeIn);
|
||||
|
|
|
@ -133,13 +133,14 @@ public class GaugeInformationRenderer {
|
|||
String _generatorStatsTitle = Lang.translate("gui.goggles.generator_stats");
|
||||
String _capacityProvided = Lang.translate("tooltip.capacityProvided");
|
||||
|
||||
if (te.speed != te.getGeneratedSpeed() && te.speed != 0)
|
||||
addedStressCapacity *= (te.getGeneratedSpeed() / te.speed);
|
||||
float speed = te.getTheoreticalSpeed();
|
||||
if (speed != te.getGeneratedSpeed() && speed != 0)
|
||||
addedStressCapacity *= (te.getGeneratedSpeed() / speed);
|
||||
|
||||
tooltip.add(spacing + _generatorStatsTitle);
|
||||
tooltip.add(spacing + GRAY + _capacityProvided);
|
||||
|
||||
float actualSpeed = Math.abs(te.speed);
|
||||
float actualSpeed = Math.abs(speed);
|
||||
float relativeCap = 0;
|
||||
if (actualSpeed != 0)
|
||||
relativeCap = addedStressCapacity * actualSpeed;
|
||||
|
@ -176,8 +177,8 @@ public class GaugeInformationRenderer {
|
|||
}
|
||||
StressGaugeTileEntity stressGauge = (StressGaugeTileEntity) te;
|
||||
List<String> stressLevels = Lang.translatedOptions("tooltip.stressImpact", "low", "medium", "high");
|
||||
double stress = stressGauge.currentStress;
|
||||
double cap = stressGauge.maxStress;
|
||||
double stress = stressGauge.getNetworkStress();
|
||||
double cap = stressGauge.getNetworkCapacity();
|
||||
double relStress = stress / (cap == 0 ? 1 : cap);
|
||||
StressImpact impactId = relStress > 1 ? null
|
||||
: (relStress > .75f) ? StressImpact.HIGH
|
||||
|
@ -199,17 +200,17 @@ public class GaugeInformationRenderer {
|
|||
|
||||
level += " (" + (int) (relStress * 100) + "%)";
|
||||
|
||||
float actualSpeed = stressGauge.speed;
|
||||
if (actualSpeed == 0)
|
||||
float theoreticalSpeed = stressGauge.getTheoreticalSpeed();
|
||||
if (theoreticalSpeed == 0)
|
||||
level = DARK_GRAY + ItemDescription.makeProgressBar(3, -1) + _noRotation;
|
||||
|
||||
tooltip.add(spacing + GRAY + _stressGaugeTitle);
|
||||
tooltip.add(spacing + level);
|
||||
|
||||
if (actualSpeed != 0) {
|
||||
if (theoreticalSpeed != 0) {
|
||||
tooltip.add(spacing + GRAY + _capacity);
|
||||
|
||||
String capacity = color + "" + format((cap - stress) / Math.abs(actualSpeed)) + _stressUnit + " "
|
||||
String capacity = color + "" + format((cap - stress) / Math.abs(theoreticalSpeed)) + _stressUnit + " "
|
||||
+ DARK_GRAY + _atCurrentSpeed;
|
||||
String capacityAtBase = GRAY + "" + format(cap - stress) + _stressUnit + " " + DARK_GRAY + _baseValue;
|
||||
tooltip.add(spacing + " " + capacity);
|
||||
|
@ -221,9 +222,10 @@ public class GaugeInformationRenderer {
|
|||
if (!(te instanceof SpeedGaugeTileEntity))
|
||||
return;
|
||||
SpeedGaugeTileEntity speedGauge = (SpeedGaugeTileEntity) te;
|
||||
boolean overstressed = speedGauge.currentStress > speedGauge.maxStress && speedGauge.speed != 0;
|
||||
float speed = speedGauge.getTheoreticalSpeed();
|
||||
boolean overstressed = speedGauge.getSpeed() == 0 && speed != 0;
|
||||
|
||||
SpeedLevel speedLevel = SpeedLevel.of(speedGauge.speed);
|
||||
SpeedLevel speedLevel = SpeedLevel.of(speed);
|
||||
String color = speedLevel.getTextColor() + "";
|
||||
if (overstressed)
|
||||
color = DARK_GRAY + "" + TextFormatting.STRIKETHROUGH;
|
||||
|
@ -232,7 +234,7 @@ public class GaugeInformationRenderer {
|
|||
int index = speedLevel.ordinal();
|
||||
String level = color + ItemDescription.makeProgressBar(3, index)
|
||||
+ (speedLevel != SpeedLevel.NONE ? speedLevels.get(index) : "");
|
||||
level += " (" + format(Math.abs(speedGauge.speed)) + "" + _rpmUnit + ") ";
|
||||
level += " (" + format(Math.abs(speed)) + "" + _rpmUnit + ") ";
|
||||
|
||||
tooltip.add(spacing + GRAY + _speedGaugeTitle);
|
||||
tooltip.add(spacing + level);
|
||||
|
|
|
@ -43,5 +43,13 @@ public class StressGaugeTileEntity extends GaugeTileEntity {
|
|||
else
|
||||
sync(maxStress, currentStress);
|
||||
}
|
||||
|
||||
public float getNetworkStress() {
|
||||
return currentStress;
|
||||
}
|
||||
|
||||
public float getNetworkCapacity() {
|
||||
return maxStress;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
package com.simibubi.create.modules.contraptions.relays.gearbox;
|
||||
|
||||
import com.simibubi.create.AllTileEntities;
|
||||
import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
|
||||
import com.simibubi.create.modules.contraptions.relays.encased.DirectionalShaftHalvesTileEntity;
|
||||
|
||||
public class GearboxTileEntity extends KineticTileEntity {
|
||||
public class GearboxTileEntity extends DirectionalShaftHalvesTileEntity {
|
||||
|
||||
public GearboxTileEntity() {
|
||||
super(AllTileEntities.GEARBOX.type);
|
||||
|
|
Loading…
Reference in a new issue