mirror of
https://github.com/Creators-of-Create/Create.git
synced 2025-02-10 12:25:00 +01:00
Send nodes
- Fixed incomplete track graph network packets at >1000 nodes - Fixed Metal girders having incorrect block properties - Trains getting abnormally high coupling stress now derail and stop moving - Fixed trains not always migrating graphs properly when track connections are severed - Motion applied to players run over by trains now caps at 60m/s - Fixed train relocation able to cause run-over damage - Fixed minecart contraption relocation sending nearby players to the moon - Fixed non-player entities not getting run over by trains - Trains can now reverse out of being stalled - Fixed train relocation not deactivating mounted actors - Fixed drill trains occasionally getting stuck breaking blocks at very low speeds
This commit is contained in:
parent
224c5d0426
commit
64bc8a3499
21 changed files with 215 additions and 54 deletions
|
@ -740,6 +740,7 @@ public class AllBlocks {
|
||||||
.register();
|
.register();
|
||||||
|
|
||||||
public static final BlockEntry<GirderBlock> METAL_GIRDER = REGISTRATE.block("metal_girder", GirderBlock::new)
|
public static final BlockEntry<GirderBlock> METAL_GIRDER = REGISTRATE.block("metal_girder", GirderBlock::new)
|
||||||
|
.initialProperties(SharedProperties::softMetal)
|
||||||
.blockstate(GirderBlockStateGenerator::blockState)
|
.blockstate(GirderBlockStateGenerator::blockState)
|
||||||
.properties(p -> p.color(MaterialColor.COLOR_GRAY))
|
.properties(p -> p.color(MaterialColor.COLOR_GRAY))
|
||||||
.properties(p -> p.sound(SoundType.NETHERITE_BLOCK))
|
.properties(p -> p.sound(SoundType.NETHERITE_BLOCK))
|
||||||
|
@ -751,6 +752,7 @@ public class AllBlocks {
|
||||||
|
|
||||||
public static final BlockEntry<GirderEncasedShaftBlock> METAL_GIRDER_ENCASED_SHAFT =
|
public static final BlockEntry<GirderEncasedShaftBlock> METAL_GIRDER_ENCASED_SHAFT =
|
||||||
REGISTRATE.block("metal_girder_encased_shaft", GirderEncasedShaftBlock::new)
|
REGISTRATE.block("metal_girder_encased_shaft", GirderEncasedShaftBlock::new)
|
||||||
|
.initialProperties(SharedProperties::softMetal)
|
||||||
.blockstate(GirderBlockStateGenerator::blockStateWithShaft)
|
.blockstate(GirderBlockStateGenerator::blockStateWithShaft)
|
||||||
.properties(p -> p.color(MaterialColor.COLOR_GRAY))
|
.properties(p -> p.color(MaterialColor.COLOR_GRAY))
|
||||||
.properties(p -> p.sound(SoundType.NETHERITE_BLOCK))
|
.properties(p -> p.sound(SoundType.NETHERITE_BLOCK))
|
||||||
|
|
|
@ -3,7 +3,9 @@ package com.simibubi.create.content.contraptions.components.actors;
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.AbstractContraptionEntity;
|
import com.simibubi.create.content.contraptions.components.structureMovement.AbstractContraptionEntity;
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.MovementBehaviour;
|
import com.simibubi.create.content.contraptions.components.structureMovement.MovementBehaviour;
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.MovementContext;
|
import com.simibubi.create.content.contraptions.components.structureMovement.MovementContext;
|
||||||
|
import com.simibubi.create.content.contraptions.components.structureMovement.OrientedContraptionEntity;
|
||||||
import com.simibubi.create.foundation.utility.BlockHelper;
|
import com.simibubi.create.foundation.utility.BlockHelper;
|
||||||
|
import com.simibubi.create.foundation.utility.Debug;
|
||||||
|
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.nbt.CompoundTag;
|
import net.minecraft.nbt.CompoundTag;
|
||||||
|
@ -47,6 +49,8 @@ public class BlockBreakingMovementBehaviour implements MovementBehaviour {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void damageEntities(MovementContext context, BlockPos pos, Level world) {
|
public void damageEntities(MovementContext context, BlockPos pos, Level world) {
|
||||||
|
if (context.contraption.entity instanceof OrientedContraptionEntity oce && oce.nonDamageTicks > 0)
|
||||||
|
return;
|
||||||
DamageSource damageSource = getDamageSource();
|
DamageSource damageSource = getDamageSource();
|
||||||
if (damageSource == null && !throwsEntities())
|
if (damageSource == null && !throwsEntities())
|
||||||
return;
|
return;
|
||||||
|
@ -69,9 +73,11 @@ public class BlockBreakingMovementBehaviour implements MovementBehaviour {
|
||||||
Vec3 motionBoost = context.motion.add(0, context.motion.length() / 4f, 0);
|
Vec3 motionBoost = context.motion.add(0, context.motion.length() / 4f, 0);
|
||||||
int maxBoost = 4;
|
int maxBoost = 4;
|
||||||
if (motionBoost.length() > maxBoost) {
|
if (motionBoost.length() > maxBoost) {
|
||||||
motionBoost = motionBoost.subtract(motionBoost.normalize().scale(motionBoost.length() - maxBoost));
|
motionBoost = motionBoost.subtract(motionBoost.normalize()
|
||||||
|
.scale(motionBoost.length() - maxBoost));
|
||||||
}
|
}
|
||||||
entity.setDeltaMovement(entity.getDeltaMovement().add(motionBoost));
|
entity.setDeltaMovement(entity.getDeltaMovement()
|
||||||
|
.add(motionBoost));
|
||||||
entity.hurtMarked = true;
|
entity.hurtMarked = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -86,7 +92,7 @@ public class BlockBreakingMovementBehaviour implements MovementBehaviour {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void stopMoving(MovementContext context) {
|
public void cancelStall(MovementContext context) {
|
||||||
CompoundTag data = context.data;
|
CompoundTag data = context.data;
|
||||||
if (context.world.isClientSide)
|
if (context.world.isClientSide)
|
||||||
return;
|
return;
|
||||||
|
@ -101,10 +107,15 @@ public class BlockBreakingMovementBehaviour implements MovementBehaviour {
|
||||||
data.remove("TicksUntilNextProgress");
|
data.remove("TicksUntilNextProgress");
|
||||||
data.remove("BreakingPos");
|
data.remove("BreakingPos");
|
||||||
|
|
||||||
context.stall = false;
|
MovementBehaviour.super.cancelStall(context);
|
||||||
world.destroyBlockProgress(id, breakingPos, -1);
|
world.destroyBlockProgress(id, breakingPos, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void stopMoving(MovementContext context) {
|
||||||
|
cancelStall(context);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void tick(MovementContext context) {
|
public void tick(MovementContext context) {
|
||||||
tickBreaker(context);
|
tickBreaker(context);
|
||||||
|
@ -165,7 +176,8 @@ public class BlockBreakingMovementBehaviour implements MovementBehaviour {
|
||||||
|
|
||||||
float breakSpeed = Mth.clamp(Math.abs(context.getAnimationSpeed()) / 500f, 1 / 128f, 16f);
|
float breakSpeed = Mth.clamp(Math.abs(context.getAnimationSpeed()) / 500f, 1 / 128f, 16f);
|
||||||
destroyProgress += Mth.clamp((int) (breakSpeed / blockHardness), 1, 10 - destroyProgress);
|
destroyProgress += Mth.clamp((int) (breakSpeed / blockHardness), 1, 10 - destroyProgress);
|
||||||
world.playSound(null, breakingPos, stateToBreak.getSoundType().getHitSound(), SoundSource.NEUTRAL, .25f, 1);
|
world.playSound(null, breakingPos, stateToBreak.getSoundType()
|
||||||
|
.getHitSound(), SoundSource.NEUTRAL, .25f, 1);
|
||||||
|
|
||||||
if (destroyProgress >= 10) {
|
if (destroyProgress >= 10) {
|
||||||
world.destroyBlockProgress(id, breakingPos, -1);
|
world.destroyBlockProgress(id, breakingPos, -1);
|
||||||
|
|
|
@ -2,6 +2,7 @@ package com.simibubi.create.content.contraptions.components.actors;
|
||||||
|
|
||||||
import com.simibubi.create.content.contraptions.components.actors.PloughBlock.PloughFakePlayer;
|
import com.simibubi.create.content.contraptions.components.actors.PloughBlock.PloughFakePlayer;
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.MovementContext;
|
import com.simibubi.create.content.contraptions.components.structureMovement.MovementContext;
|
||||||
|
import com.simibubi.create.content.contraptions.components.structureMovement.OrientedContraptionEntity;
|
||||||
import com.simibubi.create.foundation.utility.VecHelper;
|
import com.simibubi.create.foundation.utility.VecHelper;
|
||||||
|
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
|
|
|
@ -153,6 +153,11 @@ public class PortableStorageInterfaceMovement implements MovementBehaviour {
|
||||||
// reset(context);
|
// reset(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void cancelStall(MovementContext context) {
|
||||||
|
reset(context);
|
||||||
|
}
|
||||||
|
|
||||||
public void reset(MovementContext context) {
|
public void reset(MovementContext context) {
|
||||||
context.data.remove(_clientPrevPos_);
|
context.data.remove(_clientPrevPos_);
|
||||||
context.data.remove(_workingPos_);
|
context.data.remove(_workingPos_);
|
||||||
|
|
|
@ -186,6 +186,21 @@ public class DeployerMovementBehaviour implements MovementBehaviour {
|
||||||
context.stall = player.blockBreakingProgress != null;
|
context.stall = player.blockBreakingProgress != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void cancelStall(MovementContext context) {
|
||||||
|
if (context.world.isClientSide)
|
||||||
|
return;
|
||||||
|
|
||||||
|
MovementBehaviour.super.cancelStall(context);
|
||||||
|
DeployerFakePlayer player = getPlayer(context);
|
||||||
|
if (player == null)
|
||||||
|
return;
|
||||||
|
if (player.blockBreakingProgress == null)
|
||||||
|
return;
|
||||||
|
context.world.destroyBlockProgress(player.getId(), player.blockBreakingProgress.getKey(), -1);
|
||||||
|
player.blockBreakingProgress = null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void stopMoving(MovementContext context) {
|
public void stopMoving(MovementContext context) {
|
||||||
if (context.world.isClientSide)
|
if (context.world.isClientSide)
|
||||||
|
@ -195,6 +210,7 @@ public class DeployerMovementBehaviour implements MovementBehaviour {
|
||||||
if (player == null)
|
if (player == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
cancelStall(context);
|
||||||
context.tileData.put("Inventory", player.getInventory()
|
context.tileData.put("Inventory", player.getInventory()
|
||||||
.save(new ListTag()));
|
.save(new ListTag()));
|
||||||
player.discard();
|
player.discard();
|
||||||
|
|
|
@ -29,6 +29,8 @@ import com.simibubi.create.content.contraptions.components.structureMovement.int
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.mounted.MountedContraption;
|
import com.simibubi.create.content.contraptions.components.structureMovement.mounted.MountedContraption;
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.sync.ContraptionSeatMappingPacket;
|
import com.simibubi.create.content.contraptions.components.structureMovement.sync.ContraptionSeatMappingPacket;
|
||||||
import com.simibubi.create.content.logistics.trains.entity.CarriageContraption;
|
import com.simibubi.create.content.logistics.trains.entity.CarriageContraption;
|
||||||
|
import com.simibubi.create.content.logistics.trains.entity.CarriageContraptionEntity;
|
||||||
|
import com.simibubi.create.content.logistics.trains.entity.Train;
|
||||||
import com.simibubi.create.foundation.collision.Matrix3d;
|
import com.simibubi.create.foundation.collision.Matrix3d;
|
||||||
import com.simibubi.create.foundation.mixin.accessor.ServerLevelAccessor;
|
import com.simibubi.create.foundation.mixin.accessor.ServerLevelAccessor;
|
||||||
import com.simibubi.create.foundation.networking.AllPackets;
|
import com.simibubi.create.foundation.networking.AllPackets;
|
||||||
|
@ -440,6 +442,14 @@ public abstract class AbstractContraptionEntity extends Entity implements IEntit
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
context.motion = actorPosition.subtract(previousPosition);
|
context.motion = actorPosition.subtract(previousPosition);
|
||||||
|
if (!level.isClientSide() && context.contraption.entity instanceof CarriageContraptionEntity cce
|
||||||
|
&& cce.getCarriage() != null) {
|
||||||
|
Train train = cce.getCarriage().train;
|
||||||
|
double actualSpeed = train.speedBeforeStall != null ? train.speedBeforeStall : train.speed;
|
||||||
|
context.motion = context.motion.normalize()
|
||||||
|
.scale(actualSpeed);
|
||||||
|
}
|
||||||
|
|
||||||
Vec3 relativeMotion = context.motion;
|
Vec3 relativeMotion = context.motion;
|
||||||
relativeMotion = reverseRotation(relativeMotion, 1);
|
relativeMotion = reverseRotation(relativeMotion, 1);
|
||||||
context.relativeMotion = relativeMotion;
|
context.relativeMotion = relativeMotion;
|
||||||
|
|
|
@ -78,6 +78,8 @@ public class ContraptionCollider {
|
||||||
List<Entity> entitiesWithinAABB = world.getEntitiesOfClass(Entity.class, bounds.inflate(2)
|
List<Entity> entitiesWithinAABB = world.getEntitiesOfClass(Entity.class, bounds.inflate(2)
|
||||||
.expandTowards(0, 32, 0), contraptionEntity::canCollideWith);
|
.expandTowards(0, 32, 0), contraptionEntity::canCollideWith);
|
||||||
for (Entity entity : entitiesWithinAABB) {
|
for (Entity entity : entitiesWithinAABB) {
|
||||||
|
if (!entity.isAlive())
|
||||||
|
continue;
|
||||||
|
|
||||||
PlayerType playerType = getPlayerType(entity);
|
PlayerType playerType = getPlayerType(entity);
|
||||||
if (playerType == PlayerType.REMOTE)
|
if (playerType == PlayerType.REMOTE)
|
||||||
|
@ -116,7 +118,8 @@ public class ContraptionCollider {
|
||||||
|
|
||||||
// Use simplified bbs when present
|
// Use simplified bbs when present
|
||||||
final Vec3 motionCopy = motion;
|
final Vec3 motionCopy = motion;
|
||||||
List<AABB> collidableBBs = contraption.getSimplifiedEntityColliders().orElseGet(() -> {
|
List<AABB> collidableBBs = contraption.getSimplifiedEntityColliders()
|
||||||
|
.orElseGet(() -> {
|
||||||
|
|
||||||
// Else find 'nearby' individual block shapes to collide with
|
// Else find 'nearby' individual block shapes to collide with
|
||||||
List<AABB> bbs = new ArrayList<>();
|
List<AABB> bbs = new ArrayList<>();
|
||||||
|
@ -308,25 +311,36 @@ public class ContraptionCollider {
|
||||||
entityPosition.z + allowedMovement.z);
|
entityPosition.z + allowedMovement.z);
|
||||||
entityPosition = entity.position();
|
entityPosition = entity.position();
|
||||||
|
|
||||||
if (contraptionEntity instanceof CarriageContraptionEntity cce && entity.isOnGround()) {
|
if (contraptionEntity instanceof CarriageContraptionEntity cce && entity.isOnGround()
|
||||||
if (AllConfigs.SERVER.trains.trainsCauseDamage.get()) {
|
&& !(entity instanceof ItemEntity) && cce.nonDamageTicks == 0
|
||||||
|
&& AllConfigs.SERVER.trains.trainsCauseDamage.get()) {
|
||||||
|
|
||||||
Vec3 diffMotion = contraptionMotion.subtract(entity.getDeltaMovement());
|
Vec3 diffMotion = contraptionMotion.subtract(entity.getDeltaMovement());
|
||||||
if (diffMotion.length() > 0.35f && contraptionMotion.length() > 0.35f) {
|
if (diffMotion.length() > 0.35f && contraptionMotion.length() > 0.35f) {
|
||||||
|
|
||||||
EntityDamageSource pSource = new EntityDamageSource("create.run_over", contraptionEntity);
|
EntityDamageSource pSource = new EntityDamageSource("create.run_over", contraptionEntity);
|
||||||
double damage = diffMotion.length();
|
double damage = diffMotion.length();
|
||||||
if (playerType == PlayerType.CLIENT)
|
|
||||||
|
if (!(entity instanceof Player p) || !p.isCreative() && !p.isSpectator()) {
|
||||||
|
if (playerType == PlayerType.CLIENT) {
|
||||||
AllPackets.channel
|
AllPackets.channel
|
||||||
.sendToServer(new TrainCollisionPacket((int) (damage * 16), contraptionEntity.getId()));
|
.sendToServer(new TrainCollisionPacket((int) (damage * 16), contraptionEntity.getId()));
|
||||||
else
|
world.playSound((Player) entity, entity.blockPosition(), SoundEvents.PLAYER_ATTACK_CRIT,
|
||||||
|
SoundSource.NEUTRAL, 1, .75f);
|
||||||
|
} else {
|
||||||
entity.hurt(pSource, (int) (damage * 16));
|
entity.hurt(pSource, (int) (damage * 16));
|
||||||
if (!(entity instanceof Player p) || !p.isCreative() && !p.isSpectator())
|
world.playSound(null, entity.blockPosition(), SoundEvents.PLAYER_ATTACK_CRIT,
|
||||||
entityMotion = entityMotion.add(entity.position()
|
SoundSource.NEUTRAL, 1, .75f);
|
||||||
|
}
|
||||||
|
|
||||||
|
Vec3 added = entityMotion.add(entity.position()
|
||||||
.subtract(contraptionPosition)
|
.subtract(contraptionPosition)
|
||||||
.multiply(1, 0, 1)
|
.multiply(1, 0, 1)
|
||||||
.normalize()
|
.normalize()
|
||||||
.add(0, .25, 0)
|
.add(0, .25, 0)
|
||||||
.scale(damage * 4))
|
.scale(damage * 4))
|
||||||
.add(diffMotion);
|
.add(diffMotion);
|
||||||
|
entityMotion = VecHelper.clamp(added, 3);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,6 +53,10 @@ public interface MovementBehaviour {
|
||||||
|
|
||||||
default void stopMoving(MovementContext context) {}
|
default void stopMoving(MovementContext context) {}
|
||||||
|
|
||||||
|
default void cancelStall(MovementContext context) {
|
||||||
|
context.stall = false;
|
||||||
|
}
|
||||||
|
|
||||||
default void writeExtraData(MovementContext context) {}
|
default void writeExtraData(MovementContext context) {}
|
||||||
|
|
||||||
default boolean renderAsNormalTileEntity() {
|
default boolean renderAsNormalTileEntity() {
|
||||||
|
|
|
@ -75,11 +75,14 @@ public class OrientedContraptionEntity extends AbstractContraptionEntity {
|
||||||
public float prevPitch;
|
public float prevPitch;
|
||||||
public float pitch;
|
public float pitch;
|
||||||
|
|
||||||
|
public int nonDamageTicks;
|
||||||
|
|
||||||
public OrientedContraptionEntity(EntityType<?> type, Level world) {
|
public OrientedContraptionEntity(EntityType<?> type, Level world) {
|
||||||
super(type, world);
|
super(type, world);
|
||||||
motionBeforeStall = Vec3.ZERO;
|
motionBeforeStall = Vec3.ZERO;
|
||||||
attachedExtraInventories = false;
|
attachedExtraInventories = false;
|
||||||
isSerializingFurnaceCart = false;
|
isSerializingFurnaceCart = false;
|
||||||
|
nonDamageTicks = 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static OrientedContraptionEntity create(Level world, Contraption contraption, Direction initialOrientation) {
|
public static OrientedContraptionEntity create(Level world, Contraption contraption, Direction initialOrientation) {
|
||||||
|
@ -243,6 +246,8 @@ public class OrientedContraptionEntity extends AbstractContraptionEntity {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void tickContraption() {
|
protected void tickContraption() {
|
||||||
|
if (nonDamageTicks > 0)
|
||||||
|
nonDamageTicks--;
|
||||||
Entity e = getVehicle();
|
Entity e = getVehicle();
|
||||||
if (e == null)
|
if (e == null)
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -7,6 +7,8 @@ import com.simibubi.create.foundation.networking.SimplePacketBase;
|
||||||
|
|
||||||
import net.minecraft.network.FriendlyByteBuf;
|
import net.minecraft.network.FriendlyByteBuf;
|
||||||
import net.minecraft.server.level.ServerPlayer;
|
import net.minecraft.server.level.ServerPlayer;
|
||||||
|
import net.minecraft.sounds.SoundEvents;
|
||||||
|
import net.minecraft.sounds.SoundSource;
|
||||||
import net.minecraft.world.damagesource.EntityDamageSource;
|
import net.minecraft.world.damagesource.EntityDamageSource;
|
||||||
import net.minecraft.world.entity.Entity;
|
import net.minecraft.world.entity.Entity;
|
||||||
import net.minecraft.world.level.Level;
|
import net.minecraft.world.level.Level;
|
||||||
|
@ -45,6 +47,8 @@ public class TrainCollisionPacket extends SimplePacketBase {
|
||||||
return;
|
return;
|
||||||
|
|
||||||
player.hurt(new EntityDamageSource("create.run_over", cce), (int) damage);
|
player.hurt(new EntityDamageSource("create.run_over", cce), (int) damage);
|
||||||
|
player.level.playSound(player, entity.blockPosition(), SoundEvents.PLAYER_ATTACK_CRIT, SoundSource.NEUTRAL,
|
||||||
|
1, .75f);
|
||||||
});
|
});
|
||||||
ctx.setPacketHandled(true);
|
ctx.setPacketHandled(true);
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,6 +50,12 @@ public class ContactMovementBehaviour implements MovementBehaviour {
|
||||||
deactivateLastVisitedContact(context);
|
deactivateLastVisitedContact(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void cancelStall(MovementContext context) {
|
||||||
|
MovementBehaviour.super.cancelStall(context);
|
||||||
|
deactivateLastVisitedContact(context);
|
||||||
|
}
|
||||||
|
|
||||||
public void deactivateLastVisitedContact(MovementContext context) {
|
public void deactivateLastVisitedContact(MovementContext context) {
|
||||||
if (context.data.contains("lastContact")) {
|
if (context.data.contains("lastContact")) {
|
||||||
BlockPos last = NbtUtils.readBlockPos(context.data.getCompound("lastContact"));
|
BlockPos last = NbtUtils.readBlockPos(context.data.getCompound("lastContact"));
|
||||||
|
|
|
@ -294,9 +294,9 @@ public class TrackGraph {
|
||||||
frontier.add(connected.getLocation());
|
frontier.add(connected.getLocation());
|
||||||
|
|
||||||
if (target != null) {
|
if (target != null) {
|
||||||
transfer(level, currentNode, target);
|
|
||||||
if (preAssignedIds != null && preAssignedIds.containsKey(currentNode.getNetId()))
|
if (preAssignedIds != null && preAssignedIds.containsKey(currentNode.getNetId()))
|
||||||
target.setId(preAssignedIds.get(currentNode.getNetId()));
|
target.setId(preAssignedIds.get(currentNode.getNetId()));
|
||||||
|
transfer(level, currentNode, target);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -331,6 +331,7 @@ public class TrackGraph {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (level != null)
|
||||||
for (Iterator<UUID> iterator = trains.keySet()
|
for (Iterator<UUID> iterator = trains.keySet()
|
||||||
.iterator(); iterator.hasNext();) {
|
.iterator(); iterator.hasNext();) {
|
||||||
UUID uuid = iterator.next();
|
UUID uuid = iterator.next();
|
||||||
|
@ -340,6 +341,7 @@ public class TrackGraph {
|
||||||
if (!train.isTravellingOn(node))
|
if (!train.isTravellingOn(node))
|
||||||
continue;
|
continue;
|
||||||
train.graph = target;
|
train.graph = target;
|
||||||
|
train.syncTrackGraphChanges();
|
||||||
}
|
}
|
||||||
|
|
||||||
nodes.remove(nodeLoc);
|
nodes.remove(nodeLoc);
|
||||||
|
|
|
@ -123,6 +123,15 @@ public class TrackGraphSync {
|
||||||
for (TrackNode node : graph.nodes.values()) {
|
for (TrackNode node : graph.nodes.values()) {
|
||||||
TrackGraphSyncPacket currentPacket = packet;
|
TrackGraphSyncPacket currentPacket = packet;
|
||||||
currentPacket.addedNodes.put(node.getNetId(), Pair.of(node.getLocation(), node.getNormal()));
|
currentPacket.addedNodes.put(node.getNetId(), Pair.of(node.getLocation(), node.getNormal()));
|
||||||
|
if (sent++ < 1000)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
sent = 0;
|
||||||
|
packet = flushAndCreateNew(graph, player, packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (TrackNode node : graph.nodes.values()) {
|
||||||
|
TrackGraphSyncPacket currentPacket = packet;
|
||||||
if (!graph.connectionsByNode.containsKey(node))
|
if (!graph.connectionsByNode.containsKey(node))
|
||||||
continue;
|
continue;
|
||||||
graph.connectionsByNode.get(node)
|
graph.connectionsByNode.get(node)
|
||||||
|
@ -130,7 +139,7 @@ public class TrackGraphSync {
|
||||||
Couple<Integer> key = Couple.create(node.getNetId(), node2.getNetId());
|
Couple<Integer> key = Couple.create(node.getNetId(), node2.getNetId());
|
||||||
currentPacket.addedEdges.add(Pair.of(key, edge.getTurn()));
|
currentPacket.addedEdges.add(Pair.of(key, edge.getTurn()));
|
||||||
currentPacket.syncEdgeData(node, node2, edge);
|
currentPacket.syncEdgeData(node, node2, edge);
|
||||||
});//FIXME these edges will have missing nodes
|
});
|
||||||
|
|
||||||
if (sent++ < 1000)
|
if (sent++ < 1000)
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -122,7 +122,7 @@ public class Carriage {
|
||||||
Function<TravellingPoint, ITrackSelector> forwardControl,
|
Function<TravellingPoint, ITrackSelector> forwardControl,
|
||||||
Function<TravellingPoint, ITrackSelector> backwardControl, int type) {
|
Function<TravellingPoint, ITrackSelector> backwardControl, int type) {
|
||||||
boolean onTwoBogeys = isOnTwoBogeys();
|
boolean onTwoBogeys = isOnTwoBogeys();
|
||||||
double stress = onTwoBogeys ? bogeySpacing - getAnchorDiff() : 0;
|
double stress = train.derailed ? 0 : onTwoBogeys ? bogeySpacing - getAnchorDiff() : 0;
|
||||||
blocked = false;
|
blocked = false;
|
||||||
|
|
||||||
MutableDouble distanceMoved = new MutableDouble(distance);
|
MutableDouble distanceMoved = new MutableDouble(distance);
|
||||||
|
@ -190,7 +190,7 @@ public class Carriage {
|
||||||
return distanceMoved.getValue();
|
return distanceMoved.getValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
private double getAnchorDiff() {
|
public double getAnchorDiff() {
|
||||||
double diff = 0;
|
double diff = 0;
|
||||||
int entries = 0;
|
int entries = 0;
|
||||||
|
|
||||||
|
@ -825,6 +825,9 @@ public class Carriage {
|
||||||
double diffY = positionVec.y - coupledVec.y;
|
double diffY = positionVec.y - coupledVec.y;
|
||||||
double diffZ = positionVec.z - coupledVec.z;
|
double diffZ = positionVec.z - coupledVec.z;
|
||||||
|
|
||||||
|
if (!entity.level.isClientSide())
|
||||||
|
entity.setServerSidePrevPosition();
|
||||||
|
|
||||||
entity.setPos(positionAnchor);
|
entity.setPos(positionAnchor);
|
||||||
entity.prevYaw = entity.yaw;
|
entity.prevYaw = entity.yaw;
|
||||||
entity.prevPitch = entity.pitch;
|
entity.prevPitch = entity.pitch;
|
||||||
|
|
|
@ -109,6 +109,8 @@ public class CarriageBogey {
|
||||||
public double getStress() {
|
public double getStress() {
|
||||||
if (getDimension() == null)
|
if (getDimension() == null)
|
||||||
return 0;
|
return 0;
|
||||||
|
if (carriage.train.derailed)
|
||||||
|
return 0;
|
||||||
return type.getWheelPointSpacing() - leading().getPosition()
|
return type.getWheelPointSpacing() - leading().getPosition()
|
||||||
.distanceTo(trailing().getPosition());
|
.distanceTo(trailing().getPosition());
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,6 +76,8 @@ public class CarriageContraptionEntity extends OrientedContraptionEntity {
|
||||||
private boolean arrivalSoundReversed;
|
private boolean arrivalSoundReversed;
|
||||||
private int arrivalSoundTicks;
|
private int arrivalSoundTicks;
|
||||||
|
|
||||||
|
private Vec3 serverPrevPos;
|
||||||
|
|
||||||
public CarriageContraptionEntity(EntityType<?> type, Level world) {
|
public CarriageContraptionEntity(EntityType<?> type, Level world) {
|
||||||
super(type, world);
|
super(type, world);
|
||||||
validForRender = false;
|
validForRender = false;
|
||||||
|
@ -133,6 +135,17 @@ public class CarriageContraptionEntity extends OrientedContraptionEntity {
|
||||||
return entityData.get(SCHEDULED);
|
return entityData.get(SCHEDULED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setServerSidePrevPosition() {
|
||||||
|
serverPrevPos = position();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Vec3 getPrevPositionVec() {
|
||||||
|
if (!level.isClientSide() && serverPrevPos != null)
|
||||||
|
return serverPrevPos;
|
||||||
|
return super.getPrevPositionVec();
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isLocalCoordWithin(BlockPos localPos, int min, int max) {
|
public boolean isLocalCoordWithin(BlockPos localPos, int min, int max) {
|
||||||
if (!(getContraption() instanceof CarriageContraption cc))
|
if (!(getContraption() instanceof CarriageContraption cc))
|
||||||
return false;
|
return false;
|
||||||
|
@ -173,6 +186,8 @@ public class CarriageContraptionEntity extends OrientedContraptionEntity {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void tickContraption() {
|
protected void tickContraption() {
|
||||||
|
if (nonDamageTicks > 0)
|
||||||
|
nonDamageTicks--;
|
||||||
if (!(contraption instanceof CarriageContraption cc))
|
if (!(contraption instanceof CarriageContraption cc))
|
||||||
return;
|
return;
|
||||||
if (carriage == null) {
|
if (carriage == null) {
|
||||||
|
@ -511,6 +526,11 @@ public class CarriageContraptionEntity extends OrientedContraptionEntity {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (carriage.train.speedBeforeStall != null && targetSpeed != 0
|
||||||
|
&& Math.signum(carriage.train.speedBeforeStall) != Math.signum(targetSpeed)) {
|
||||||
|
carriage.train.cancelStall();
|
||||||
|
}
|
||||||
|
|
||||||
if (currentStation != null && targetSpeed != 0) {
|
if (currentStation != null && targetSpeed != 0) {
|
||||||
stationMessage = false;
|
stationMessage = false;
|
||||||
player.displayClientMessage(new TextComponent("<i> Departing from ").withStyle(ChatFormatting.YELLOW)
|
player.displayClientMessage(new TextComponent("<i> Departing from ").withStyle(ChatFormatting.YELLOW)
|
||||||
|
|
|
@ -19,7 +19,9 @@ import javax.annotation.Nullable;
|
||||||
import org.apache.commons.lang3.mutable.MutableBoolean;
|
import org.apache.commons.lang3.mutable.MutableBoolean;
|
||||||
import org.apache.commons.lang3.mutable.MutableObject;
|
import org.apache.commons.lang3.mutable.MutableObject;
|
||||||
|
|
||||||
|
import com.simibubi.create.AllMovementBehaviours;
|
||||||
import com.simibubi.create.Create;
|
import com.simibubi.create.Create;
|
||||||
|
import com.simibubi.create.content.contraptions.components.structureMovement.MovementBehaviour;
|
||||||
import com.simibubi.create.content.logistics.trains.DimensionPalette;
|
import com.simibubi.create.content.logistics.trains.DimensionPalette;
|
||||||
import com.simibubi.create.content.logistics.trains.GraphLocation;
|
import com.simibubi.create.content.logistics.trains.GraphLocation;
|
||||||
import com.simibubi.create.content.logistics.trains.TrackEdge;
|
import com.simibubi.create.content.logistics.trains.TrackEdge;
|
||||||
|
@ -186,6 +188,7 @@ public class Train {
|
||||||
Carriage previousCarriage = null;
|
Carriage previousCarriage = null;
|
||||||
int carriageCount = carriages.size();
|
int carriageCount = carriages.size();
|
||||||
boolean stalled = false;
|
boolean stalled = false;
|
||||||
|
double maxStress = 0;
|
||||||
|
|
||||||
for (int i = 0; i < carriageCount; i++) {
|
for (int i = 0; i < carriageCount; i++) {
|
||||||
Carriage carriage = carriages.get(i);
|
Carriage carriage = carriages.get(i);
|
||||||
|
@ -226,6 +229,7 @@ public class Train {
|
||||||
actual = total / entries;
|
actual = total / entries;
|
||||||
|
|
||||||
stress[i - 1] = target - actual;
|
stress[i - 1] = target - actual;
|
||||||
|
maxStress = Math.max(maxStress, Math.abs(target - actual));
|
||||||
}
|
}
|
||||||
|
|
||||||
previousCarriage = carriage;
|
previousCarriage = carriage;
|
||||||
|
@ -275,7 +279,7 @@ public class Train {
|
||||||
Function<TravellingPoint, ITrackSelector> backwardControl =
|
Function<TravellingPoint, ITrackSelector> backwardControl =
|
||||||
toFollowBackward == null ? navigation::control : mp -> mp.follow(toFollowBackward);
|
toFollowBackward == null ? navigation::control : mp -> mp.follow(toFollowBackward);
|
||||||
|
|
||||||
double totalStress = leadingStress + trailingStress;
|
double totalStress = derailed ? 0 : leadingStress + trailingStress;
|
||||||
boolean first = i == 0;
|
boolean first = i == 0;
|
||||||
boolean last = i == carriageCount - 1;
|
boolean last = i == carriageCount - 1;
|
||||||
int carriageType = first ? last ? Carriage.BOTH : Carriage.FIRST : last ? Carriage.LAST : Carriage.MIDDLE;
|
int carriageType = first ? last ? Carriage.BOTH : Carriage.FIRST : last ? Carriage.LAST : Carriage.MIDDLE;
|
||||||
|
@ -283,6 +287,14 @@ public class Train {
|
||||||
carriage.travel(level, graph, distance + totalStress, forwardControl, backwardControl, carriageType);
|
carriage.travel(level, graph, distance + totalStress, forwardControl, backwardControl, carriageType);
|
||||||
blocked |= carriage.blocked;
|
blocked |= carriage.blocked;
|
||||||
|
|
||||||
|
boolean onTwoBogeys = carriage.isOnTwoBogeys();
|
||||||
|
maxStress = Math.max(maxStress, onTwoBogeys ? carriage.bogeySpacing - carriage.getAnchorDiff() : 0);
|
||||||
|
maxStress = Math.max(maxStress, carriage.leadingBogey()
|
||||||
|
.getStress());
|
||||||
|
if (onTwoBogeys)
|
||||||
|
maxStress = Math.max(maxStress, carriage.trailingBogey()
|
||||||
|
.getStress());
|
||||||
|
|
||||||
if (index == 0) {
|
if (index == 0) {
|
||||||
distance = actualDistance;
|
distance = actualDistance;
|
||||||
collideWithOtherTrains(level, carriage);
|
collideWithOtherTrains(level, carriage);
|
||||||
|
@ -296,6 +308,15 @@ public class Train {
|
||||||
navigation.cancelNavigation();
|
navigation.cancelNavigation();
|
||||||
runtime.tick(level);
|
runtime.tick(level);
|
||||||
status.endOfTrack();
|
status.endOfTrack();
|
||||||
|
|
||||||
|
} else if (maxStress > 2) {
|
||||||
|
speed = 0;
|
||||||
|
navigation.cancelNavigation();
|
||||||
|
runtime.tick(level);
|
||||||
|
derailed = true;
|
||||||
|
syncTrackGraphChanges();
|
||||||
|
status.highStress();
|
||||||
|
|
||||||
} else if (speed != 0)
|
} else if (speed != 0)
|
||||||
status.trackOK();
|
status.trackOK();
|
||||||
|
|
||||||
|
@ -338,6 +359,20 @@ public class Train {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void cancelStall() {
|
||||||
|
speedBeforeStall = null;
|
||||||
|
carriages.forEach(c -> {
|
||||||
|
c.stalled = false;
|
||||||
|
c.forEachPresentEntity(cce -> cce.getContraption()
|
||||||
|
.getActors()
|
||||||
|
.forEach(pair -> {
|
||||||
|
MovementBehaviour behaviour = AllMovementBehaviours.of(pair.getKey().state);
|
||||||
|
if (behaviour != null)
|
||||||
|
behaviour.cancelStall(pair.getValue());
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private boolean occupy(UUID groupId, @Nullable UUID boundaryId) {
|
private boolean occupy(UUID groupId, @Nullable UUID boundaryId) {
|
||||||
reservedSignalBlocks.remove(groupId);
|
reservedSignalBlocks.remove(groupId);
|
||||||
if (boundaryId != null && occupiedSignalBlocks.containsKey(groupId))
|
if (boundaryId != null && occupiedSignalBlocks.containsKey(groupId))
|
||||||
|
|
|
@ -96,6 +96,7 @@ public class TrainRelocationPacket extends SimplePacketBase {
|
||||||
sender.displayClientMessage(Lang.translate("train.relocate.success")
|
sender.displayClientMessage(Lang.translate("train.relocate.success")
|
||||||
.withStyle(ChatFormatting.GREEN), true);
|
.withStyle(ChatFormatting.GREEN), true);
|
||||||
train.syncTrackGraphChanges();
|
train.syncTrackGraphChanges();
|
||||||
|
train.carriages.forEach(c -> c.forEachPresentEntity(e -> e.nonDamageTicks = 10));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -147,9 +147,11 @@ public class TrainRelocator {
|
||||||
Vec3 lookAngle = mc.player.getLookAngle();
|
Vec3 lookAngle = mc.player.getLookAngle();
|
||||||
boolean direction = bezierSelection != null && lookAngle.dot(bezierSelection.direction()) < 0;
|
boolean direction = bezierSelection != null && lookAngle.dot(bezierSelection.direction()) < 0;
|
||||||
boolean result = relocate(relocating, mc.level, blockPos, hoveredBezier, direction, lookAngle, true);
|
boolean result = relocate(relocating, mc.level, blockPos, hoveredBezier, direction, lookAngle, true);
|
||||||
if (!simulate && result)
|
if (!simulate && result) {
|
||||||
|
relocating.carriages.forEach(c -> c.forEachPresentEntity(e -> e.nonDamageTicks = 10));
|
||||||
AllPackets.channel.sendToServer(new TrainRelocationPacket(relocatingTrain, blockPos, hoveredBezier,
|
AllPackets.channel.sendToServer(new TrainRelocationPacket(relocatingTrain, blockPos, hoveredBezier,
|
||||||
direction, lookAngle, relocatingEntityId));
|
direction, lookAngle, relocatingEntityId));
|
||||||
|
}
|
||||||
|
|
||||||
return lastHoveredResult = result;
|
return lastHoveredResult = result;
|
||||||
}
|
}
|
||||||
|
@ -238,6 +240,7 @@ public class TrainRelocator {
|
||||||
train.graph = graph;
|
train.graph = graph;
|
||||||
train.speed = 0;
|
train.speed = 0;
|
||||||
train.migratingPoints.clear();
|
train.migratingPoints.clear();
|
||||||
|
train.cancelStall();
|
||||||
|
|
||||||
if (train.navigation.destination != null)
|
if (train.navigation.destination != null)
|
||||||
train.navigation.cancelNavigation();
|
train.navigation.cancelNavigation();
|
||||||
|
|
|
@ -70,6 +70,13 @@ public class TrainStatus {
|
||||||
track = true;
|
track = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void highStress() {
|
||||||
|
if (track)
|
||||||
|
return;
|
||||||
|
displayInformation("Forced stop due to Stress on Couplings", false);
|
||||||
|
track = true;
|
||||||
|
}
|
||||||
|
|
||||||
public void doublePortal() {
|
public void doublePortal() {
|
||||||
if (track)
|
if (track)
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -64,7 +64,7 @@ public class CurvedTrackInteraction {
|
||||||
|
|
||||||
breakTicks++;
|
breakTicks++;
|
||||||
breakTimeout = 2;
|
breakTimeout = 2;
|
||||||
breakProgress += creative ? 0.25f : blockState.getDestroyProgress(player, level, breakPos);
|
breakProgress += creative ? 0.125f : blockState.getDestroyProgress(player, level, breakPos) / 8f;
|
||||||
|
|
||||||
Vec3 vec = VecHelper.offsetRandomly(result.vec(), level.random, 0.25f);
|
Vec3 vec = VecHelper.offsetRandomly(result.vec(), level.random, 0.25f);
|
||||||
level.addParticle(new BlockParticleOption(ParticleTypes.BLOCK, blockState), vec.x, vec.y, vec.z, 0, 0, 0);
|
level.addParticle(new BlockParticleOption(ParticleTypes.BLOCK, blockState), vec.x, vec.y, vec.z, 0, 0, 0);
|
||||||
|
|
Loading…
Reference in a new issue