mirror of
https://github.com/Creators-of-Create/Create.git
synced 2024-11-18 07:53:07 +01:00
Bogey power
- Trains now consume fuel from non-vault inventories to boost movement speed
This commit is contained in:
parent
f291dbc03a
commit
41facb7543
8 changed files with 137 additions and 51 deletions
|
@ -1242,6 +1242,10 @@ public abstract class Contraption {
|
|||
return storage.getItems();
|
||||
}
|
||||
|
||||
public IItemHandlerModifiable getSharedFuelInventory() {
|
||||
return storage.getFuelItems();
|
||||
}
|
||||
|
||||
public IFluidHandler getSharedFluidTanks() {
|
||||
return storage.getFluids();
|
||||
}
|
||||
|
|
|
@ -26,16 +26,16 @@ public class MountedStorage {
|
|||
private static final ItemStackHandler dummyHandler = new ItemStackHandler();
|
||||
|
||||
ItemStackHandler handler;
|
||||
boolean noFuel;
|
||||
boolean valid;
|
||||
|
||||
private BlockEntity te;
|
||||
|
||||
public static boolean canUseAsStorage(BlockEntity te) {
|
||||
if (te == null)
|
||||
return false;
|
||||
|
||||
if (te instanceof MechanicalCrafterTileEntity)
|
||||
return false;
|
||||
|
||||
if (AllTileEntities.CREATIVE_CRATE.is(te))
|
||||
return true;
|
||||
if (te instanceof ShulkerBoxBlockEntity)
|
||||
|
@ -55,6 +55,7 @@ public class MountedStorage {
|
|||
public MountedStorage(BlockEntity te) {
|
||||
this.te = te;
|
||||
handler = dummyHandler;
|
||||
noFuel = te instanceof ItemVaultTileEntity;
|
||||
}
|
||||
|
||||
public void removeStorageFromWorld() {
|
||||
|
@ -147,14 +148,16 @@ public class MountedStorage {
|
|||
public CompoundTag serialize() {
|
||||
if (!valid)
|
||||
return null;
|
||||
CompoundTag tag = handler.serializeNBT();
|
||||
|
||||
if (handler instanceof BottomlessItemHandler) {
|
||||
CompoundTag tag = handler.serializeNBT();
|
||||
if (noFuel)
|
||||
NBTHelper.putMarker(tag, "NoFuel");
|
||||
if (!(handler instanceof BottomlessItemHandler))
|
||||
return tag;
|
||||
|
||||
NBTHelper.putMarker(tag, "Bottomless");
|
||||
tag.put("ProvidedStack", handler.getStackInSlot(0)
|
||||
.serializeNBT());
|
||||
}
|
||||
|
||||
return tag;
|
||||
}
|
||||
|
||||
|
@ -164,6 +167,7 @@ public class MountedStorage {
|
|||
if (nbt == null)
|
||||
return storage;
|
||||
storage.valid = true;
|
||||
storage.noFuel = nbt.contains("NoFuel");
|
||||
|
||||
if (nbt.contains("Bottomless")) {
|
||||
ItemStack providedStack = ItemStack.of(nbt.getCompound("ProvidedStack"));
|
||||
|
@ -179,4 +183,8 @@ public class MountedStorage {
|
|||
return valid;
|
||||
}
|
||||
|
||||
public boolean canUseForFuel() {
|
||||
return !noFuel;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
package com.simibubi.create.content.contraptions.components.structureMovement;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
@ -29,6 +31,7 @@ import net.minecraftforge.items.IItemHandlerModifiable;
|
|||
public class MountedStorageManager {
|
||||
|
||||
private ContraptionInvWrapper inventory;
|
||||
private ContraptionInvWrapper fuelInventory;
|
||||
private CombinedTankWrapper fluidInventory;
|
||||
private Map<BlockPos, MountedStorage> storage;
|
||||
private Map<BlockPos, MountedFluidStorage> fluidStorage;
|
||||
|
@ -43,12 +46,16 @@ public class MountedStorageManager {
|
|||
}
|
||||
|
||||
public void createHandlers() {
|
||||
List<IItemHandlerModifiable> list = storage.values()
|
||||
.stream()
|
||||
Collection<MountedStorage> itemHandlers = storage.values();
|
||||
|
||||
inventory = wrap(itemHandlers.stream()
|
||||
.map(MountedStorage::getItemHandler)
|
||||
.collect(Collectors.toList());
|
||||
inventory =
|
||||
new ContraptionInvWrapper(Arrays.copyOf(list.toArray(), list.size(), IItemHandlerModifiable[].class));
|
||||
.toList());
|
||||
|
||||
fuelInventory = wrap(itemHandlers.stream()
|
||||
.filter(MountedStorage::canUseForFuel)
|
||||
.map(MountedStorage::getItemHandler)
|
||||
.toList());
|
||||
|
||||
List<IFluidHandler> fluidHandlers = fluidStorage.values()
|
||||
.stream()
|
||||
|
@ -58,6 +65,10 @@ public class MountedStorageManager {
|
|||
Arrays.copyOf(fluidHandlers.toArray(), fluidHandlers.size(), IFluidHandler[].class));
|
||||
}
|
||||
|
||||
private ContraptionInvWrapper wrap(List<IItemHandlerModifiable> list) {
|
||||
return new ContraptionInvWrapper(Arrays.copyOf(list.toArray(), list.size(), IItemHandlerModifiable[].class));
|
||||
}
|
||||
|
||||
public void addBlock(BlockPos localPos, BlockEntity te) {
|
||||
if (te != null && MountedStorage.canUseAsStorage(te))
|
||||
storage.put(localPos, new MountedStorage(te));
|
||||
|
@ -88,17 +99,22 @@ public class MountedStorageManager {
|
|||
mfs.assignTileEntity(tank);
|
||||
});
|
||||
|
||||
IItemHandlerModifiable[] handlers = new IItemHandlerModifiable[storage.size()];
|
||||
int index = 0;
|
||||
for (MountedStorage mountedStorage : storage.values())
|
||||
handlers[index++] = mountedStorage.getItemHandler();
|
||||
List<IItemHandlerModifiable> handlers = new ArrayList<>();
|
||||
List<IItemHandlerModifiable> fuelHandlers = new ArrayList<>();
|
||||
for (MountedStorage mountedStorage : storage.values()) {
|
||||
IItemHandlerModifiable itemHandler = mountedStorage.getItemHandler();
|
||||
handlers.add(itemHandler);
|
||||
if (mountedStorage.canUseForFuel())
|
||||
fuelHandlers.add(itemHandler);
|
||||
}
|
||||
|
||||
int index = 0;
|
||||
IFluidHandler[] fluidHandlers = new IFluidHandler[fluidStorage.size()];
|
||||
index = 0;
|
||||
for (MountedFluidStorage mountedStorage : fluidStorage.values())
|
||||
fluidHandlers[index++] = mountedStorage.getFluidHandler();
|
||||
|
||||
inventory = new ContraptionInvWrapper(handlers);
|
||||
inventory = wrap(handlers);
|
||||
fuelInventory = wrap(fuelHandlers);
|
||||
fluidInventory = new CombinedTankWrapper(fluidHandlers);
|
||||
}
|
||||
|
||||
|
@ -167,12 +183,17 @@ public class MountedStorageManager {
|
|||
|
||||
public void attachExternal(IItemHandlerModifiable externalStorage) {
|
||||
inventory = new ContraptionInvWrapper(externalStorage, inventory);
|
||||
fuelInventory = new ContraptionInvWrapper(externalStorage, fuelInventory);
|
||||
}
|
||||
|
||||
public IItemHandlerModifiable getItems() {
|
||||
return inventory;
|
||||
}
|
||||
|
||||
public IItemHandlerModifiable getFuelItems() {
|
||||
return fuelInventory;
|
||||
}
|
||||
|
||||
public IFluidHandler getFluids() {
|
||||
return fluidInventory;
|
||||
}
|
||||
|
|
|
@ -496,6 +496,9 @@ public class CarriageContraptionEntity extends OrientedContraptionEntity {
|
|||
targetSteer *= -1;
|
||||
}
|
||||
|
||||
if (targetSpeed != 0)
|
||||
carriage.train.burnFuel();
|
||||
|
||||
boolean slow = inverted ^ targetSpeed < 0;
|
||||
boolean spaceDown = heldControls.contains(4);
|
||||
GlobalStation currentStation = carriage.train.getCurrentStation();
|
||||
|
@ -551,7 +554,7 @@ public class CarriageContraptionEntity extends OrientedContraptionEntity {
|
|||
|
||||
carriage.train.manualSteer =
|
||||
targetSteer < 0 ? SteerDirection.RIGHT : targetSteer > 0 ? SteerDirection.LEFT : SteerDirection.NONE;
|
||||
double topSpeed = AllConfigs.SERVER.trains.getTopSpeedMPT();
|
||||
double topSpeed = carriage.train.maxSpeed();
|
||||
carriage.train.targetSpeed = topSpeed * targetSpeed;
|
||||
if (slow)
|
||||
carriage.train.targetSpeed /= 8;
|
||||
|
|
|
@ -95,8 +95,7 @@ public class Navigation {
|
|||
|
||||
destination.reserveFor(train);
|
||||
|
||||
double acceleration = AllConfigs.SERVER.trains.getAccelerationMPTT();
|
||||
double turnTopSpeed = AllConfigs.SERVER.trains.getTurningTopSpeedMPT();
|
||||
double acceleration = train.acceleration();
|
||||
double brakingDistance = (train.speed * train.speed) / (2 * acceleration);
|
||||
double speedMod = destinationBehindTrain ? -1 : 1;
|
||||
double preDepartureLookAhead = train.getCurrentStation() != null ? 4.5 : 0;
|
||||
|
@ -240,7 +239,11 @@ public class Navigation {
|
|||
return;
|
||||
}
|
||||
|
||||
double topSpeed = AllConfigs.SERVER.trains.getTopSpeedMPT();
|
||||
train.burnFuel();
|
||||
|
||||
double topSpeed = train.maxSpeed();
|
||||
double turnTopSpeed = train.maxTurnSpeed();
|
||||
|
||||
if (targetDistance < 10) {
|
||||
double target = topSpeed * ((targetDistance) / 10);
|
||||
if (target < Math.abs(train.speed)) {
|
||||
|
@ -505,7 +508,7 @@ public class Navigation {
|
|||
return null;
|
||||
|
||||
MutableObject<GlobalStation> result = new MutableObject<>(null);
|
||||
double acceleration = AllConfigs.SERVER.trains.getAccelerationMPTT();
|
||||
double acceleration = train.acceleration();
|
||||
double minDistance = .75f * (train.speed * train.speed) / (2 * acceleration);
|
||||
double maxDistance = Math.max(32, 1.5f * (train.speed * train.speed) / (2 * acceleration));
|
||||
|
||||
|
|
|
@ -56,9 +56,13 @@ import net.minecraft.resources.ResourceKey;
|
|||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.Explosion.BlockInteraction;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import net.minecraftforge.common.ForgeHooks;
|
||||
import net.minecraftforge.items.IItemHandlerModifiable;
|
||||
import net.minecraftforge.items.ItemHandlerHelper;
|
||||
import net.minecraftforge.network.PacketDistributor;
|
||||
|
||||
public class Train {
|
||||
|
@ -96,6 +100,8 @@ public class Train {
|
|||
public int migrationCooldown;
|
||||
public boolean derailed;
|
||||
|
||||
public int fuelTicks;
|
||||
|
||||
int tickOffset;
|
||||
double[] stress;
|
||||
|
||||
|
@ -387,7 +393,7 @@ public class Train {
|
|||
|
||||
private void tickPassiveSlowdown() {
|
||||
if (!manualTick && navigation.destination == null && speed != 0) {
|
||||
double acceleration = AllConfigs.SERVER.trains.getAccelerationMPTT();
|
||||
double acceleration = acceleration();
|
||||
if (speed > 0) {
|
||||
speed = Math.max(speed - acceleration, 0);
|
||||
} else
|
||||
|
@ -747,7 +753,7 @@ public class Train {
|
|||
return;
|
||||
if (manualTick)
|
||||
leaveStation();
|
||||
double acceleration = AllConfigs.SERVER.trains.getAccelerationMPTT();
|
||||
double acceleration = acceleration();
|
||||
if (speed < targetSpeed)
|
||||
speed = Math.min(speed + acceleration * accelerationMod, targetSpeed);
|
||||
else if (speed > targetSpeed)
|
||||
|
@ -854,6 +860,50 @@ public class Train {
|
|||
return Penalties.ANY_TRAIN;
|
||||
}
|
||||
|
||||
public void burnFuel() {
|
||||
if (fuelTicks > 0) {
|
||||
fuelTicks--;
|
||||
return;
|
||||
}
|
||||
|
||||
boolean iterateFromBack = speed < 0;
|
||||
int carriageCount = carriages.size();
|
||||
|
||||
for (int index = 0; index < carriageCount; index++) {
|
||||
int i = iterateFromBack ? carriageCount - 1 - index : index;
|
||||
Carriage carriage = carriages.get(i);
|
||||
IItemHandlerModifiable fuelItems = carriage.storage.getFuelItems();
|
||||
|
||||
for (int slot = 0; slot < fuelItems.getSlots(); slot++) {
|
||||
ItemStack stack = fuelItems.extractItem(slot, 1, true);
|
||||
int burnTime = ForgeHooks.getBurnTime(stack, null);
|
||||
if (burnTime <= 0)
|
||||
continue;
|
||||
|
||||
stack = fuelItems.extractItem(slot, 1, false);
|
||||
fuelTicks += burnTime * stack.getCount();
|
||||
ItemStack containerItem = stack.getContainerItem();
|
||||
if (!containerItem.isEmpty())
|
||||
ItemHandlerHelper.insertItemStacked(fuelItems, containerItem, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public float maxSpeed() {
|
||||
return (fuelTicks > 0 ? AllConfigs.SERVER.trains.poweredTrainTopSpeed.getF()
|
||||
: AllConfigs.SERVER.trains.trainTopSpeed.getF()) / 20;
|
||||
}
|
||||
|
||||
public float maxTurnSpeed() {
|
||||
return (fuelTicks > 0 ? AllConfigs.SERVER.trains.poweredTrainTurningTopSpeed.getF()
|
||||
: AllConfigs.SERVER.trains.trainTurningTopSpeed.getF()) / 20;
|
||||
}
|
||||
|
||||
public float acceleration() {
|
||||
return (fuelTicks > 0 ? AllConfigs.SERVER.trains.poweredTrainAcceleration.getF()
|
||||
: AllConfigs.SERVER.trains.trainAcceleration.getF()) / 400;
|
||||
}
|
||||
|
||||
public CompoundTag write(DimensionPalette dimensions) {
|
||||
CompoundTag tag = new CompoundTag();
|
||||
tag.putUUID("Id", id);
|
||||
|
@ -864,6 +914,7 @@ public class Train {
|
|||
tag.putIntArray("CarriageSpacing", carriageSpacing);
|
||||
tag.putBoolean("DoubleEnded", doubleEnded);
|
||||
tag.putDouble("Speed", speed);
|
||||
tag.putInt("Fuel", fuelTicks);
|
||||
tag.putDouble("TargetSpeed", targetSpeed);
|
||||
tag.putString("IconType", icon.id.toString());
|
||||
tag.putString("Name", Component.Serializer.toJson(name));
|
||||
|
@ -917,6 +968,7 @@ public class Train {
|
|||
train.heldForAssembly = tag.getBoolean("StillAssembling");
|
||||
train.derailed = tag.getBoolean("Derailed");
|
||||
train.updateSignalBlocks = tag.getBoolean("UpdateSignals");
|
||||
train.fuelTicks = tag.getInt("Fuel");
|
||||
|
||||
NBTHelper.iterateCompoundList(tag.getList("SignalBlocks", Tag.TAG_COMPOUND), c -> train.occupiedSignalBlocks
|
||||
.put(c.getUUID("Id"), c.contains("Boundary") ? c.getUUID("Boundary") : null));
|
||||
|
|
|
@ -15,8 +15,6 @@ import com.simibubi.create.content.logistics.trains.management.schedule.conditio
|
|||
import com.simibubi.create.content.logistics.trains.management.schedule.destination.ChangeTitleInstruction;
|
||||
import com.simibubi.create.content.logistics.trains.management.schedule.destination.DestinationInstruction;
|
||||
import com.simibubi.create.content.logistics.trains.management.schedule.destination.ScheduleInstruction;
|
||||
import com.simibubi.create.foundation.config.AllConfigs;
|
||||
import com.simibubi.create.foundation.config.CTrains;
|
||||
import com.simibubi.create.foundation.utility.NBTHelper;
|
||||
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
|
@ -239,8 +237,7 @@ public class ScheduleRuntime {
|
|||
} else {
|
||||
GlobalStation destination = train.navigation.destination;
|
||||
if (destination != null) {
|
||||
CTrains conf = AllConfigs.SERVER.trains;
|
||||
double speed = (conf.getTopSpeedMPT() + conf.getTurningTopSpeedMPT()) / 2;
|
||||
double speed = (train.maxSpeed() + train.maxTurnSpeed()) / 2;
|
||||
int timeRemaining = (int) (train.navigation.distanceToDestination / speed) * 2;
|
||||
|
||||
if (predictionTicks.size() > current && train.navigation.distanceStartedAt != 0) {
|
||||
|
|
|
@ -3,36 +3,34 @@ package com.simibubi.create.foundation.config;
|
|||
public class CTrains extends ConfigBase {
|
||||
|
||||
public final ConfigBool trainsCauseDamage = b(true, "trainsCauseDamage", Comments.trainsCauseDamage);
|
||||
public final ConfigFloat trainTopSpeed = f(36, 0, "trainTopSpeed", Comments.mps, Comments.trainTopSpeed);
|
||||
public final ConfigFloat trainTurningTopSpeed =
|
||||
f(18, 0, "trainTurningTopSpeed", Comments.mps, Comments.trainTurningTopSpeed);
|
||||
public final ConfigFloat trainAcceleration = f(4, 0, "trainAcceleration", Comments.acc, Comments.trainAcceleration);
|
||||
public final ConfigInt maxAssemblyLength = i(128, 5, "maxAssemblyLength", Comments.maxAssemblyLength);
|
||||
public final ConfigInt maxBogeyCount = i(20, 1, "maxBogeyCount", Comments.maxBogeyCount);
|
||||
|
||||
public final ConfigGroup trainStats = group(1, "trainStats", "Standard Trains");
|
||||
public final ConfigFloat trainTopSpeed = f(28, 0, "trainTopSpeed", Comments.mps, Comments.trainTopSpeed);
|
||||
public final ConfigFloat trainTurningTopSpeed = f(14, 0, "trainTurningTopSpeed", Comments.mps, Comments.trainTurningTopSpeed);
|
||||
public final ConfigFloat trainAcceleration = f(3, 0, "trainAcceleration", Comments.acc, Comments.trainAcceleration);
|
||||
|
||||
public final ConfigGroup poweredTrainStats = group(1, "poweredTrainStats", "Powered Trains");
|
||||
public final ConfigFloat poweredTrainTopSpeed = f(40, 0, "poweredTrainTopSpeed", Comments.mps, Comments.poweredTrainTopSpeed);
|
||||
public final ConfigFloat poweredTrainTurningTopSpeed = f(20, 0, "poweredTrainTurningTopSpeed", Comments.mps, Comments.poweredTrainTurningTopSpeed);
|
||||
public final ConfigFloat poweredTrainAcceleration = f(3, 0, "poweredTrainAcceleration", Comments.acc, Comments.poweredTrainAcceleration);
|
||||
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "trains";
|
||||
}
|
||||
|
||||
public double getTopSpeedMPT() {
|
||||
return trainTopSpeed.getF() / 20;
|
||||
}
|
||||
|
||||
public double getTurningTopSpeedMPT() {
|
||||
return trainTurningTopSpeed.getF() / 20;
|
||||
}
|
||||
|
||||
public double getAccelerationMPTT() {
|
||||
return trainAcceleration.getF() / 400;
|
||||
}
|
||||
|
||||
private static class Comments {
|
||||
static String mps = "[in Blocks/Second]";
|
||||
static String acc = "[in Blocks/Second²]";
|
||||
static String trainTopSpeed = "The top speed of any assembled Train.";
|
||||
static String trainTurningTopSpeed = "The top speed of Trains during a turn.";
|
||||
static String trainAcceleration = "The acceleration of any assembled Train.";
|
||||
static String poweredTrainTopSpeed = "The top speed of powered Trains.";
|
||||
static String poweredTrainTurningTopSpeed = "The top speed of powered Trains during a turn.";
|
||||
static String poweredTrainAcceleration = "The acceleration of powered Trains.";
|
||||
static String trainsCauseDamage = "Whether moving Trains can hurt colliding mobs and players.";
|
||||
static String maxAssemblyLength = "Maximum length of a Train Stations' assembly track.";
|
||||
static String maxBogeyCount = "Maximum amount of bogeys assembled as a single Train.";
|
||||
|
|
Loading…
Reference in a new issue