17 | */
18 | @SuppressWarnings("CanBeFinal")
19 | public final class Crafters {
20 | static ICokeOvenCrafter cokeOven = new ICokeOvenCrafter() {};
21 | private static IBlastFurnaceCrafter blastFurnace = new IBlastFurnaceCrafter() {};
22 | static IRockCrusherCrafter rockCrusher = new IRockCrusherCrafter() {};
23 | static IRollingMachineCrafter rollingMachine = new IRollingMachineCrafter() {};
24 |
25 | private static void validateStage() {
26 | RailcraftCore.validateStage(RailcraftCore.InitStage.PRE_INIT, RailcraftCore.InitStage.INIT, RailcraftCore.InitStage.POST_INIT, RailcraftCore.InitStage.FINISHED);
27 | }
28 |
29 | /**
30 | * Returns the coke oven crafting manager.
31 | *
32 | * If railcraft is not available, a dummy one is returned.
33 | *
34 | * @return The coke oven crafting manager
35 | */
36 | public static ICokeOvenCrafter cokeOven() {
37 | validateStage();
38 | return cokeOven;
39 | }
40 |
41 | /**
42 | * Returns the blast furnace crafting manager.
43 | *
44 | * If railcraft is not available, a dummy one is returned.
45 | *
46 | * @return The blast furnace crafting manager
47 | */
48 | public static IBlastFurnaceCrafter blastFurnace() {
49 | validateStage();
50 | return blastFurnace;
51 | }
52 |
53 | /**
54 | * Returns the rock crusher crafting manager.
55 | *
56 | * If railcraft is not available, a dummy one is returned.
57 | *
58 | * @return The rock crusher crafting manager
59 | */
60 | public static IRockCrusherCrafter rockCrusher() {
61 | validateStage();
62 | return rockCrusher;
63 | }
64 |
65 | /**
66 | * Returns the rolling machine crafting manager.
67 | *
68 | * If railcraft is not available, a dummy one is returned.
69 | *
70 | * @return The rolling machine crafting manager
71 | */
72 | public static IRollingMachineCrafter rollingMachine() {
73 | validateStage();
74 | return rollingMachine;
75 | }
76 |
77 | private Crafters() {
78 | }
79 |
80 | }
81 |
--------------------------------------------------------------------------------
/src/api/java/mods/railcraft/api/carts/IItemCart.java:
--------------------------------------------------------------------------------
1 | /*------------------------------------------------------------------------------
2 | Copyright (c) CovertJaguar, 2011-2020
3 |
4 | This work (the API) is licensed under the "MIT" License,
5 | see LICENSE.md for details.
6 | -----------------------------------------------------------------------------*/
7 | package mods.railcraft.api.carts;
8 |
9 | import net.minecraft.entity.item.EntityMinecart;
10 | import net.minecraft.item.ItemStack;
11 |
12 | /**
13 | * This class replaces IItemTransfer for controlling how items move through a train.
14 | * It is entirely optional to implement this class, default values will be determined based on several factors.
15 | *
16 | * It is not required that every cart implementing this also has an inventory, but if you wish to accept or provide
17 | * items you should implement IInventory or provide an IItemHandler capability.
18 | *
19 | *
20 | * Created by CovertJaguar on 5/9/2015.
21 | *
22 | * @see mods.railcraft.api.carts.ITrainTransferHelper
23 | */
24 | public interface IItemCart {
25 | /**
26 | * This function controls whether a cart can pass push or pull requests.
27 | * This function is only called if the cart cannot fulfill the request itself.
28 | *
29 | * If this interface is not implemented, a default value will be inferred based on the size of the inventory of the Minecart.
30 | * Anything with eight or more slots will be assumed to allow passage.
31 | *
32 | * @return true if can pass push and pull requests
33 | */
34 | boolean canPassItemRequests(ItemStack stack);
35 |
36 | /**
37 | * This function controls whether a cart will accept a pushed Item.
38 | * Even if this function returns true, there still must be a slot that accepts the item in question before it can be added to the cart.
39 | *
40 | * If this interface is not implemented, it is assumed to be true.
41 | *
42 | * @param requester the EntityMinecart that initiated the action
43 | * @param stack the ItemStack
44 | * @return true if the cart can accept the item
45 | */
46 | boolean canAcceptPushedItem(EntityMinecart requester, ItemStack stack);
47 |
48 | /**
49 | * This function controls whether a cart will fulfill a pull request for a specific item.
50 | * Even if this function returns true, there still must be a slot that can extract the item in question before it can be removed from the cart.
51 | *
52 | * If this interface is not implemented, it is assumed to be true.
53 | *
54 | * @param requester the EntityMinecart that initiated the action
55 | * @param stack the ItemStack
56 | * @return true if the cart can provide the item
57 | */
58 | boolean canProvidePulledItem(EntityMinecart requester, ItemStack stack);
59 | }
60 |
--------------------------------------------------------------------------------
/src/api/java/mods/railcraft/api/carts/IFluidCart.java:
--------------------------------------------------------------------------------
1 | /*------------------------------------------------------------------------------
2 | Copyright (c) CovertJaguar, 2011-2020
3 |
4 | This work (the API) is licensed under the "MIT" License,
5 | see LICENSE.md for details.
6 | -----------------------------------------------------------------------------*/
7 | package mods.railcraft.api.carts;
8 |
9 | import net.minecraft.entity.item.EntityMinecart;
10 | import net.minecraftforge.fluids.FluidStack;
11 |
12 | /**
13 | * Replaces ILiquidTransfer with a simpler interface for moving Fluids between Minecarts.
14 | *
15 | * Created by CovertJaguar on 5/9/2015.
16 | *
17 | * @see mods.railcraft.api.carts.ITrainTransferHelper
18 | */
19 | public interface IFluidCart {
20 | /**
21 | * This function controls whether a cart can pass push or pull requests.
22 | * This function is only called if the cart cannot fulfill the request itself.
23 | *
24 | * If this interface is not implemented, a default value will be inferred based on the size of the tanks of the Minecart.
25 | * Anything with eight or more buckets will be assumed to allow passage, but only if the contained fluid matches the request.
26 | *
27 | * @return true if can pass push and pull requests
28 | */
29 | boolean canPassFluidRequests(FluidStack fluid);
30 |
31 | /**
32 | * This function controls whether a cart will accept a pushed Fluid.
33 | * Even if this function returns true, there still must be a tank that accepts the Fluid in question before it can be added to the cart.
34 | *
35 | * If this interface is not implemented, it is assumed to be true.
36 | *
37 | * @param requester the EntityMinecart that initiated the action
38 | * @param fluid the Fluid
39 | * @return true if cart will accept the fluid
40 | */
41 | boolean canAcceptPushedFluid(EntityMinecart requester, FluidStack fluid);
42 |
43 | /**
44 | * This function controls whether a cart will fulfill a pull request for a specific Fluid.
45 | * Even if this function returns true, there still must be a tank that can extract the Fluid in question before it can be removed from the cart.
46 | *
47 | * If this interface is not implemented, it is assumed to be true.
48 | *
49 | * @param requester the EntityMinecart that initiated the action
50 | * @param fluid the Fluid
51 | * @return true if the cart can provide the fluid
52 | */
53 | boolean canProvidePulledFluid(EntityMinecart requester, FluidStack fluid);
54 |
55 | /**
56 | * Set by the Liquid Loader while filling, primarily used for rendering a
57 | * visible change while being filled.
58 | *
59 | * @param filling true if the cart is being filled from above
60 | */
61 | default void setFilling(boolean filling) {
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/src/api/java/mods/railcraft/api/signals/SimpleSignalController.java:
--------------------------------------------------------------------------------
1 | /*------------------------------------------------------------------------------
2 | Copyright (c) CovertJaguar, 2011-2020
3 |
4 | This work (the API) is licensed under the "MIT" License,
5 | see LICENSE.md for details.
6 | -----------------------------------------------------------------------------*/
7 | package mods.railcraft.api.signals;
8 |
9 | import net.minecraft.nbt.NBTTagCompound;
10 | import net.minecraft.tileentity.TileEntity;
11 | import net.minecraft.util.math.BlockPos;
12 |
13 | import java.io.DataInputStream;
14 | import java.io.DataOutputStream;
15 | import java.io.IOException;
16 |
17 | /**
18 | * @author CovertJaguar
19 | */
20 | public class SimpleSignalController extends SignalController {
21 |
22 | private SignalAspect aspect = SignalAspect.BLINK_RED;
23 | private boolean needsInit = true;
24 |
25 | public SimpleSignalController(String locTag, TileEntity tile) {
26 | super(locTag, tile, 1);
27 | }
28 |
29 | public SignalAspect getAspect() {
30 | return aspect;
31 | }
32 |
33 | public void setAspect(SignalAspect aspect) {
34 | if (this.aspect != aspect) {
35 | this.aspect = aspect;
36 | updateReceiver();
37 | }
38 | }
39 |
40 | @Override
41 | public SignalAspect getAspectFor(BlockPos receiver) {
42 | return aspect;
43 | }
44 |
45 | @Override
46 | public void tickServer() {
47 | super.tickServer();
48 | if (needsInit) {
49 | needsInit = false;
50 | updateReceiver();
51 | }
52 | }
53 |
54 | private void updateReceiver() {
55 | for (BlockPos recv : getPairs()) {
56 | SignalReceiver receiver = getReceiverAt(recv);
57 | if (receiver != null) {
58 | receiver.onControllerAspectChange(this, aspect);
59 | }
60 | }
61 | }
62 |
63 | @Override
64 | protected void saveNBT(NBTTagCompound data) {
65 | super.saveNBT(data);
66 | data.setByte("aspect", (byte) aspect.ordinal());
67 | }
68 |
69 | @Override
70 | protected void loadNBT(NBTTagCompound data) {
71 | super.loadNBT(data);
72 | aspect = SignalAspect.fromOrdinal(data.getByte("aspect"));
73 | }
74 |
75 | @Override
76 | public void writePacketData(DataOutputStream data) throws IOException {
77 | super.writePacketData(data);
78 | data.writeByte(aspect.ordinal());
79 | }
80 |
81 | @Override
82 | public void readPacketData(DataInputStream data) throws IOException {
83 | super.readPacketData(data);
84 | aspect = SignalAspect.fromOrdinal(data.readByte());
85 | }
86 |
87 | @Override
88 | public String toString() {
89 | return String.format("Controller:%s (%s)", aspect, super.toString());
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/src/api/java/mods/railcraft/api/items/IToolCrowbar.java:
--------------------------------------------------------------------------------
1 | /*------------------------------------------------------------------------------
2 | Copyright (c) CovertJaguar, 2011-2020
3 |
4 | This work (the API) is licensed under the "MIT" License,
5 | see LICENSE.md for details.
6 | -----------------------------------------------------------------------------*/
7 | package mods.railcraft.api.items;
8 |
9 | import net.minecraft.entity.item.EntityMinecart;
10 | import net.minecraft.entity.player.EntityPlayer;
11 | import net.minecraft.item.ItemStack;
12 | import net.minecraft.util.EnumHand;
13 | import net.minecraft.util.math.BlockPos;
14 |
15 | /**
16 | * @author CovertJaguar
17 | */
18 | @ActivationBlockingItem
19 | public interface IToolCrowbar {
20 | String ORE_TAG = "toolCrowbar";
21 |
22 | /**
23 | * Controls non-rotational interactions with blocks. Crowbar specific stuff.
24 | *
25 | * Rotational interaction is handled by the Block.rotateBlock() function,
26 | * which should be called from the Item.onUseFirst() function of your tool.
27 | *
28 | * @param player the player
29 | * @param crowbar the crowbar
30 | * @param pos the block @return true if can whack a block
31 | */
32 | boolean canWhack(EntityPlayer player, EnumHand hand, ItemStack crowbar, BlockPos pos);
33 |
34 | /**
35 | * Callback to do damage to the item.
36 | *
37 | * @param player the player
38 | * @param crowbar the crowbar
39 | * @param pos the block
40 | */
41 | void onWhack(EntityPlayer player, EnumHand hand, ItemStack crowbar, BlockPos pos);
42 |
43 | /**
44 | * Controls whether you can link a cart.
45 | *
46 | * @param player the player
47 | * @param crowbar the crowbar
48 | * @param cart the cart @return true if can link a cart
49 | */
50 | boolean canLink(EntityPlayer player, EnumHand hand, ItemStack crowbar, EntityMinecart cart);
51 |
52 | /**
53 | * Callback to do damage.
54 | *
55 | * @param player the player
56 | * @param crowbar the crowbar
57 | * @param cart the cart
58 | */
59 | void onLink(EntityPlayer player, EnumHand hand, ItemStack crowbar, EntityMinecart cart);
60 |
61 | /**
62 | * Controls whether you can boost a cart.
63 | *
64 | * @param player the player
65 | * @param crowbar the crowbar
66 | * @param cart the cart @return true if can boost a cart
67 | */
68 | boolean canBoost(EntityPlayer player, EnumHand hand, ItemStack crowbar, EntityMinecart cart);
69 |
70 | /**
71 | * Callback to do damage, boosting a cart usually does more damage than
72 | * normal usage.
73 | *
74 | * @param player the player
75 | * @param crowbar the crowbar
76 | * @param cart the cart
77 | */
78 | void onBoost(EntityPlayer player, EnumHand hand, ItemStack crowbar, EntityMinecart cart);
79 | }
80 |
--------------------------------------------------------------------------------
/src/api/java/mods/railcraft/api/signals/SignalReceiver.java:
--------------------------------------------------------------------------------
1 | /*------------------------------------------------------------------------------
2 | Copyright (c) CovertJaguar, 2011-2020
3 |
4 | This work (the API) is licensed under the "MIT" License,
5 | see LICENSE.md for details.
6 | -----------------------------------------------------------------------------*/
7 | package mods.railcraft.api.signals;
8 |
9 | import net.minecraft.tileentity.TileEntity;
10 | import net.minecraft.util.math.BlockPos;
11 | import org.jetbrains.annotations.Nullable;
12 |
13 | /**
14 | * @author CovertJaguar
15 | */
16 | public abstract class SignalReceiver extends AbstractPair {
17 | private boolean needsInit = true;
18 |
19 | protected SignalReceiver(String locTag, TileEntity tile, int maxPairings) {
20 | super(locTag, tile, maxPairings);
21 | }
22 |
23 | public @Nullable SignalController getControllerAt(BlockPos coord) {
24 | TileEntity con = getPairAt(coord);
25 | if (con != null) {
26 | return ((IControllerTile) con).getController();
27 | }
28 | return null;
29 | }
30 |
31 | @Override
32 | public void informPairsOfNameChange() {
33 | for (BlockPos coord : getPairs()) {
34 | SignalController ctrl = getControllerAt(coord);
35 | if (ctrl != null) {
36 | ctrl.onPairNameChange(getCoords(), getName());
37 | }
38 | }
39 | }
40 |
41 | @Override
42 | protected String getTagName() {
43 | return "receiver";
44 | }
45 |
46 | @Override
47 | public boolean isValidPair(BlockPos otherCoord, TileEntity otherTile) {
48 | if (otherTile instanceof IControllerTile) {
49 | SignalController controller = ((IControllerTile) otherTile).getController();
50 | return controller.isPairedWith(getCoords());
51 | }
52 | return false;
53 | }
54 |
55 | public void onControllerAspectChange(SignalController con, SignalAspect aspect) {
56 | ((IReceiverTile) tile).onControllerAspectChange(con, aspect);
57 | }
58 |
59 | @Override
60 | public boolean createPair(TileEntity other) {
61 | if (tile instanceof IControllerTile) {
62 | registerController(((IControllerTile) other).getController());
63 | return true;
64 | }
65 | return false;
66 | }
67 |
68 | protected void registerController(SignalController controller) {
69 | addPairing(controller.getCoords());
70 | }
71 |
72 | @Override
73 | public void tickServer() {
74 | super.tickServer();
75 | if (needsInit) {
76 | needsInit = false;
77 | for (BlockPos pair : getPairs()) {
78 | SignalController controller = getControllerAt(pair);
79 | if (controller != null) {
80 | onControllerAspectChange(controller, controller.getAspectFor(getCoords()));
81 | }
82 | }
83 | }
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/src/api/java/mods/railcraft/api/signals/SignalController.java:
--------------------------------------------------------------------------------
1 | /*------------------------------------------------------------------------------
2 | Copyright (c) CovertJaguar, 2011-2020
3 |
4 | This work (the API) is licensed under the "MIT" License,
5 | see LICENSE.md for details.
6 | -----------------------------------------------------------------------------*/
7 | package mods.railcraft.api.signals;
8 |
9 | import net.minecraft.tileentity.TileEntity;
10 | import net.minecraft.util.math.BlockPos;
11 | import org.jetbrains.annotations.Nullable;
12 |
13 | /**
14 | * @author CovertJaguar
15 | */
16 | public abstract class SignalController extends AbstractPair {
17 | protected SignalController(String locTag, TileEntity tile, int maxPairings) {
18 | super(locTag, tile, maxPairings);
19 | }
20 |
21 | public @Nullable SignalReceiver getReceiverAt(BlockPos coord) {
22 | TileEntity recv = getPairAt(coord);
23 | if (recv != null) {
24 | return ((IReceiverTile) recv).getReceiver();
25 | }
26 | return null;
27 | }
28 |
29 | public abstract SignalAspect getAspectFor(BlockPos receiver);
30 |
31 | @Override
32 | public void informPairsOfNameChange() {
33 | for (BlockPos coord : getPairs()) {
34 | SignalReceiver recv = getReceiverAt(coord);
35 | if (recv != null) {
36 | recv.onPairNameChange(getCoords(), getName());
37 | }
38 | }
39 | }
40 |
41 | @Override
42 | protected String getTagName() {
43 | return "controller";
44 | }
45 |
46 | @Override
47 | public boolean isValidPair(BlockPos otherCoord, TileEntity otherTile) {
48 | if (otherTile instanceof IReceiverTile) {
49 | SignalReceiver receiver = ((IReceiverTile) otherTile).getReceiver();
50 | return receiver.isPairedWith(getCoords());
51 | }
52 | return false;
53 | }
54 |
55 | @Override
56 | public boolean createPair(TileEntity other) {
57 | if (other instanceof IReceiverTile) {
58 | registerReceiver(((IReceiverTile) other).getReceiver());
59 | return true;
60 | }
61 | return false;
62 | }
63 |
64 | protected void registerReceiver(SignalReceiver receiver) {
65 | BlockPos coords = receiver.getCoords();
66 | addPairing(coords);
67 | receiver.registerController(this);
68 | receiver.onControllerAspectChange(this, getAspectFor(coords));
69 | }
70 |
71 | @Override
72 | public void tickClient() {
73 | super.tickClient();
74 | if (SignalTools.effectManager != null && SignalTools.effectManager.isTuningAuraActive()) {
75 | for (BlockPos coord : getPairs()) {
76 | SignalReceiver receiver = getReceiverAt(coord);
77 | if (receiver != null) {
78 | SignalTools.effectManager.tuningEffect(getTile(), receiver.getTile());
79 | }
80 | }
81 | }
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/src/api/java/mods/railcraft/api/crafting/ICokeOvenCrafter.java:
--------------------------------------------------------------------------------
1 | /*------------------------------------------------------------------------------
2 | Copyright (c) CovertJaguar, 2011-2020
3 |
4 | This work (the API) is licensed under the "MIT" License,
5 | see LICENSE.md for details.
6 | -----------------------------------------------------------------------------*/
7 |
8 | package mods.railcraft.api.crafting;
9 |
10 | import net.minecraft.item.ItemStack;
11 | import net.minecraftforge.fluids.FluidStack;
12 | import org.jetbrains.annotations.Nullable;
13 |
14 | import java.util.Collections;
15 | import java.util.List;
16 | import java.util.Optional;
17 |
18 | /**
19 | * A manager for coke oven recipes.
20 | *
21 | * @author CovertJaguar
22 | */
23 | public interface ICokeOvenCrafter {
24 | int DEFAULT_COOK_TIME = 1800;
25 |
26 | /**
27 | * @param input An object that can be converted into an Ingredient. This includes,
28 | * but is not limited to Ingredients, ItemStacks, Items, Blocks, and OreTag Strings.
29 | */
30 | default ICokeOvenRecipeBuilder newRecipe(Object input) {
31 | return new ICokeOvenRecipeBuilder() {};
32 | }
33 |
34 | /**
35 | * Gets the coke oven recipe that matches this input item stack.
36 | *
37 | * @param stack The input item stack
38 | * @return The matching recipe, may be {@code null}
39 | */
40 | default Optional getRecipe(ItemStack stack) {
41 | return Optional.empty();
42 | }
43 |
44 | /**
45 | * Gets all the coke oven recipes registered in this manager.
46 | *
47 | * You can remove recipes from this list, but do not add them, it will throw an UnsupportedOperationException.
48 | *
49 | * @return The recipes registered
50 | */
51 | default List getRecipes() {
52 | return Collections.emptyList();
53 | }
54 |
55 | /**
56 | * A coke oven recipe.
57 | */
58 | interface IRecipe extends ISimpleRecipe {
59 |
60 | /**
61 | * Gets the fluid output for this recipe.
62 | *
63 | * Returns {@code null} if this recipe has no fluid products.
64 | *
65 | * @return The fluid output
66 | */
67 | @Nullable
68 | FluidStack getFluidOutput();
69 |
70 | /**
71 | * Gets the item stack output for this recipe.
72 | *
73 | * @return The output item stack
74 | */
75 | ItemStack getOutput();
76 | }
77 |
78 | interface ICokeOvenRecipeBuilder extends
79 | IRecipeBuilder,
80 | IRecipeBuilder.ISingleInputFeature,
81 | IRecipeBuilder.ISingleItemStackOutputFeature,
82 | IRecipeBuilder.ITimeFeature {
83 |
84 | default ICokeOvenRecipeBuilder fluid(@Nullable FluidStack outputFluid) {
85 | return this;
86 | }
87 |
88 | /**
89 | * Finalize and commit the recipe.
90 | */
91 | default void register() {}
92 | }
93 | }
94 |
--------------------------------------------------------------------------------
/src/api/java/mods/railcraft/api/items/ISpikeMaulTarget.java:
--------------------------------------------------------------------------------
1 | /*------------------------------------------------------------------------------
2 | Copyright (c) CovertJaguar, 2011-2020
3 |
4 | This work (the API) is licensed under the "MIT" License,
5 | see LICENSE.md for details.
6 | -----------------------------------------------------------------------------*/
7 |
8 | package mods.railcraft.api.items;
9 |
10 | import mods.railcraft.api.tracks.TrackKit;
11 | import mods.railcraft.api.tracks.TrackToolsAPI;
12 | import mods.railcraft.api.tracks.TrackType;
13 | import net.minecraft.block.BlockRailBase;
14 | import net.minecraft.block.state.IBlockState;
15 | import net.minecraft.entity.player.EntityPlayer;
16 | import net.minecraft.util.math.BlockPos;
17 | import net.minecraft.world.World;
18 |
19 | import java.util.ArrayList;
20 | import java.util.List;
21 | import java.util.function.Supplier;
22 |
23 | /**
24 | * Created by CovertJaguar on 3/6/2017 for Railcraft.
25 | *
26 | * @author CovertJaguar
27 | */
28 | public interface ISpikeMaulTarget {
29 | /**
30 | * A list for registering or changing spike maul targets.
31 | */
32 | List spikeMaulTargets = new ArrayList<>();
33 |
34 | /**
35 | * Returns true when the given state is your resulting state.
36 | *
37 | * @param world The world
38 | * @param pos The position
39 | * @param state The block state
40 | * @return True if the given state is the target's result
41 | */
42 | boolean matches(World world, BlockPos pos, IBlockState state);
43 |
44 | /**
45 | * Returns true when you successfully set another state to your
46 | * resulting state. Return false to revert changes.
47 | *
48 | * @param world The world
49 | * @param pos The position
50 | * @param state The block state
51 | * @param player The player
52 | * @param shape The rail direction
53 | * @param trackType The track type
54 | * @return If operation is successful
55 | */
56 | boolean setToTarget(World world, BlockPos pos, IBlockState state, EntityPlayer player, BlockRailBase.EnumRailDirection shape, TrackType trackType);
57 |
58 | class TrackKitTarget implements ISpikeMaulTarget {
59 | private final Supplier trackKit;
60 |
61 | public TrackKitTarget(Supplier trackKit) {
62 | this.trackKit = trackKit;
63 | }
64 |
65 | @Override
66 | public boolean matches(World world, BlockPos pos, IBlockState state) {
67 | return TrackToolsAPI.getTrackKit(world, pos) == trackKit.get();
68 | }
69 |
70 | @Override
71 | public boolean setToTarget(World world,
72 | BlockPos pos,
73 | IBlockState state,
74 | EntityPlayer player,
75 | BlockRailBase.EnumRailDirection shape,
76 | TrackType trackType) {
77 | return TrackToolsAPI.blockTrackOutfitted.place(world, pos, player, shape, trackType, trackKit.get());
78 | }
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/src/api/java/mods/railcraft/api/signals/DualSignalReceiver.java:
--------------------------------------------------------------------------------
1 | /*------------------------------------------------------------------------------
2 | Copyright (c) CovertJaguar, 2011-2020
3 |
4 | This work (the API) is licensed under the "MIT" License,
5 | see LICENSE.md for details.
6 | -----------------------------------------------------------------------------*/
7 | package mods.railcraft.api.signals;
8 |
9 | import net.minecraft.nbt.NBTTagCompound;
10 | import net.minecraft.tileentity.TileEntity;
11 | import net.minecraft.util.math.BlockPos;
12 |
13 | import java.io.DataInputStream;
14 | import java.io.DataOutputStream;
15 | import java.io.IOException;
16 | import java.util.EnumMap;
17 |
18 | /**
19 | * @author CovertJaguar
20 | */
21 | public class DualSignalReceiver extends SignalReceiver {
22 |
23 | private EnumMap aspects = new EnumMap<>(DualLamp.class);
24 |
25 | public DualSignalReceiver(String locTag, TileEntity tile) {
26 | super(locTag, tile, 2);
27 | }
28 |
29 | {
30 | for (DualLamp lamp : DualLamp.values()) {
31 | aspects.put(lamp, SignalAspect.BLINK_RED);
32 | }
33 | }
34 |
35 | @Override
36 | public void onControllerAspectChange(SignalController con, SignalAspect aspect) {
37 | BlockPos coord = pairings.peekFirst();
38 | if (coord == null) {
39 | return;
40 | }
41 | if (coord.equals(con.getCoords())) {
42 | if (setAspect(DualLamp.TOP, aspect)) {
43 | super.onControllerAspectChange(con, aspect);
44 | }
45 | } else {
46 | if (setAspect(DualLamp.BOTTOM, aspect)) {
47 | super.onControllerAspectChange(con, aspect);
48 | }
49 | }
50 | }
51 |
52 | @Override
53 | protected void saveNBT(NBTTagCompound data) {
54 | super.saveNBT(data);
55 | data.setByte("topAspect", (byte) aspects.get(DualLamp.TOP).ordinal());
56 | data.setByte("bottomAspect", (byte) aspects.get(DualLamp.BOTTOM).ordinal());
57 | }
58 |
59 | @Override
60 | protected void loadNBT(NBTTagCompound data) {
61 | super.loadNBT(data);
62 | setAspect(DualLamp.TOP, SignalAspect.values()[data.getByte("topAspect")]);
63 | setAspect(DualLamp.BOTTOM, SignalAspect.values()[data.getByte("bottomAspect")]);
64 | }
65 |
66 | @Override
67 | public void writePacketData(DataOutputStream data) throws IOException {
68 | super.writePacketData(data);
69 | data.writeByte(aspects.get(DualLamp.TOP).ordinal());
70 | data.writeByte(aspects.get(DualLamp.BOTTOM).ordinal());
71 | }
72 |
73 | @Override
74 | public void readPacketData(DataInputStream data) throws IOException {
75 | super.readPacketData(data);
76 | setAspect(DualLamp.TOP, SignalAspect.values()[data.readByte()]);
77 | setAspect(DualLamp.BOTTOM, SignalAspect.values()[data.readByte()]);
78 | }
79 |
80 | public SignalAspect getAspect(DualLamp lamp) {
81 | return aspects.get(lamp);
82 | }
83 |
84 | public boolean setAspect(DualLamp lamp, SignalAspect aspect) {
85 | return aspects.put(lamp, aspect) != aspect;
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/src/api/java/mods/railcraft/api/crafting/IRockCrusherCrafter.java:
--------------------------------------------------------------------------------
1 | /*------------------------------------------------------------------------------
2 | Copyright (c) CovertJaguar, 2011-2020
3 |
4 | This work (the API) is licensed under the "MIT" License,
5 | see LICENSE.md for details.
6 | -----------------------------------------------------------------------------*/
7 |
8 | package mods.railcraft.api.crafting;
9 |
10 | import net.minecraft.item.ItemStack;
11 |
12 | import java.util.Collections;
13 | import java.util.List;
14 | import java.util.Optional;
15 | import java.util.Random;
16 | import java.util.stream.Collectors;
17 |
18 | /**
19 | * @author CovertJaguar
20 | */
21 | public interface IRockCrusherCrafter {
22 | int PROCESS_TIME = 100;
23 |
24 | /**
25 | * Begins the definition of a Rock Crusher recipe.
26 | *
27 | * @param input An object that can be converted into an Ingredient. This includes,
28 | * but is not limited to Ingredients, ItemStacks, Items, Blocks, and OreTag Strings.
29 | */
30 | default IRockCrusherRecipeBuilder makeRecipe(Object input) {
31 | return new IRockCrusherRecipeBuilder() {};
32 | }
33 |
34 | /**
35 | * This function will locate the highest priority recipe that successfully matches against the given ItemStack.
36 | */
37 | default Optional getRecipe(ItemStack input) {
38 | return Optional.empty();
39 | }
40 |
41 | /**
42 | * You can remove recipes from this list, but do not add them, it will throw an UnsupportedOperationException.
43 | */
44 | default List getRecipes() {
45 | return Collections.emptyList();
46 | }
47 |
48 | interface IRockCrusherRecipeBuilder extends
49 | IRecipeBuilder,
50 | IRecipeBuilder.ISingleInputFeature,
51 | IRecipeBuilder.ITimeFeature {
52 |
53 | default IRockCrusherRecipeBuilder addOutput(IOutputEntry entry) {
54 | return this;
55 | }
56 |
57 | default IRockCrusherRecipeBuilder addOutput(ItemStack output, IGenRule rule) {
58 | return this;
59 | }
60 |
61 | default IRockCrusherRecipeBuilder addOutput(ItemStack output, float chance) {
62 | return this;
63 | }
64 |
65 | default IRockCrusherRecipeBuilder addOutput(ItemStack output) {
66 | return addOutput(output, 1);
67 | }
68 |
69 | /**
70 | * Finalize and commit the recipe.
71 | */
72 | default void register() {}
73 | }
74 |
75 | /**
76 | * A Rock Crusher Recipe
77 | */
78 | interface IRecipe extends ISimpleRecipe {
79 |
80 | /**
81 | * Returns a list containing each output entry.
82 | */
83 | List getOutputs();
84 |
85 | /**
86 | * Returns a list of outputs after it has passed through the predicate processor.
87 | */
88 | default List pollOutputs(Random random) {
89 | return getOutputs().stream()
90 | .filter(entry -> entry.getGenRule().test(random))
91 | .map(IOutputEntry::getOutput)
92 | .collect(Collectors.toList());
93 | }
94 |
95 | }
96 | }
97 |
--------------------------------------------------------------------------------
/src/api/java/mods/railcraft/api/signals/SignalBlockRelay.java:
--------------------------------------------------------------------------------
1 | /*------------------------------------------------------------------------------
2 | Copyright (c) CovertJaguar, 2011-2020
3 |
4 | This work (the API) is licensed under the "MIT" License,
5 | see LICENSE.md for details.
6 | -----------------------------------------------------------------------------*/
7 |
8 | package mods.railcraft.api.signals;
9 |
10 | import mods.railcraft.api.core.CollectionToolsAPI;
11 | import net.minecraft.nbt.NBTTagCompound;
12 | import net.minecraft.nbt.NBTTagList;
13 | import net.minecraft.tileentity.TileEntity;
14 | import net.minecraft.util.math.BlockPos;
15 |
16 | import java.util.HashMap;
17 | import java.util.Map;
18 |
19 | /**
20 | * @author CovertJaguar
21 | */
22 | public class SignalBlockRelay extends SignalBlock {
23 |
24 | private final Map aspects = CollectionToolsAPI.blockPosMap(new HashMap<>());
25 |
26 | public SignalBlockRelay(String locTag, TileEntity tile) {
27 | super(locTag, tile, 2);
28 | }
29 |
30 | @Override
31 | protected void updateSignalAspect() {
32 | aspects.keySet().retainAll(getPairs());
33 | for (BlockPos otherCoord : getPairs()) {
34 | aspects.put(otherCoord, determineAspect(otherCoord));
35 | }
36 | }
37 |
38 | @Override
39 | public SignalAspect getSignalAspect() {
40 | if (isWaitingForRetest() || isBeingPaired()) {
41 | return SignalAspect.BLINK_YELLOW;
42 | }
43 | if (!isPaired()) {
44 | return SignalAspect.BLINK_RED;
45 | }
46 | SignalAspect aspect = SignalAspect.GREEN;
47 | for (BlockPos otherCoord : getPairs()) {
48 | aspect = SignalAspect.mostRestrictive(aspect, aspects.get(otherCoord));
49 | }
50 | return aspect;
51 | }
52 |
53 | @Override
54 | protected SignalAspect getSignalAspectForPair(BlockPos otherCoord) {
55 | SignalAspect aspect = SignalAspect.GREEN;
56 | for (Map.Entry entry : aspects.entrySet()) {
57 | if (entry.getKey().equals(otherCoord)) {
58 | continue;
59 | }
60 | aspect = SignalAspect.mostRestrictive(aspect, entry.getValue());
61 | }
62 | return aspect;
63 | }
64 |
65 | @Override
66 | protected void saveNBT(NBTTagCompound data) {
67 | super.saveNBT(data);
68 | NBTTagList tagList = data.getTagList("aspects", 10);
69 | for (int i = 0; i < tagList.tagCount(); i++) {
70 | NBTTagCompound nbt = tagList.getCompoundTagAt(i);
71 | BlockPos coord = SignalTools.readFromNBT(nbt, "coord");
72 | SignalAspect aspect = SignalAspect.readFromNBT(nbt, "aspect");
73 | aspects.put(coord, aspect);
74 | }
75 | }
76 |
77 | @Override
78 | protected void loadNBT(NBTTagCompound data) {
79 | super.loadNBT(data);
80 | NBTTagList tagList = new NBTTagList();
81 | for (Map.Entry entry : aspects.entrySet()) {
82 | NBTTagCompound nbt = new NBTTagCompound();
83 | if (entry.getKey() != null && entry.getValue() != null) {
84 | SignalTools.writeToNBT(nbt, "coord", entry.getKey());
85 | entry.getValue().writeToNBT(nbt, "aspect");
86 | tagList.appendTag(nbt);
87 | }
88 | }
89 | data.setTag("aspects", tagList);
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/src/api/java/mods/railcraft/api/signals/TrackLocator.java:
--------------------------------------------------------------------------------
1 | /*------------------------------------------------------------------------------
2 | Copyright (c) CovertJaguar, 2011-2020
3 |
4 | This work (the API) is licensed under the "MIT" License,
5 | see LICENSE.md for details.
6 | -----------------------------------------------------------------------------*/
7 |
8 | package mods.railcraft.api.signals;
9 |
10 | import mods.railcraft.api.tracks.TrackToolsAPI;
11 | import net.minecraft.tileentity.TileEntity;
12 | import net.minecraft.util.math.BlockPos;
13 | import net.minecraft.world.World;
14 | import org.jetbrains.annotations.Nullable;
15 |
16 | /**
17 | * Created by CovertJaguar on 7/9/2017 for Railcraft.
18 | *
19 | * @author CovertJaguar
20 | */
21 | public class TrackLocator {
22 | private final TileEntity signalTile;
23 | private @Nullable BlockPos trackLocation;
24 |
25 | public TrackLocator(TileEntity signalTile) {
26 | this.signalTile = signalTile;
27 | }
28 |
29 | public @Nullable BlockPos getTrackLocation() {
30 | if (trackLocation == null)
31 | locateTrack();
32 | return trackLocation;
33 | }
34 |
35 | public Status getTrackStatus() {
36 | if (trackLocation == null)
37 | return locateTrack();
38 | if (!signalTile.getWorld().isBlockLoaded(trackLocation))
39 | return Status.UNKNOWN;
40 | if (!TrackToolsAPI.isRailBlockAt(signalTile.getWorld(), trackLocation)) {
41 | trackLocation = null;
42 | return locateTrack();
43 | }
44 | return Status.VALID;
45 | }
46 |
47 | private Status locateTrack() {
48 | int x = signalTile.getPos().getX();
49 | int y = signalTile.getPos().getY();
50 | int z = signalTile.getPos().getZ();
51 | Status status = testForTrack(x, y, z);
52 | if (status != Status.INVALID)
53 | return status;
54 | status = testForTrack(x - 1, y, z);
55 | if (status != Status.INVALID)
56 | return status;
57 | status = testForTrack(x + 1, y, z);
58 | if (status != Status.INVALID)
59 | return status;
60 | status = testForTrack(x, y, z - 1);
61 | if (status != Status.INVALID)
62 | return status;
63 | status = testForTrack(x, y, z + 1);
64 | if (status != Status.INVALID)
65 | return status;
66 | status = testForTrack(x - 2, y, z);
67 | if (status != Status.INVALID)
68 | return status;
69 | status = testForTrack(x + 2, y, z);
70 | if (status != Status.INVALID)
71 | return status;
72 | status = testForTrack(x, y, z - 2);
73 | if (status != Status.INVALID)
74 | return status;
75 | status = testForTrack(x, y, z + 2);
76 | if (status != Status.INVALID)
77 | return status;
78 | return Status.INVALID;
79 | }
80 |
81 | private Status testForTrack(int x, int y, int z) {
82 | World world = signalTile.getWorld();
83 | for (int jj = -2; jj < 4; jj++) {
84 | BlockPos pos = new BlockPos(x, y - jj, z);
85 | if (!world.isBlockLoaded(pos))
86 | return Status.UNKNOWN;
87 | if (TrackToolsAPI.isRailBlockAt(world, pos)) {
88 | trackLocation = pos;
89 | return Status.VALID;
90 | }
91 | }
92 | return Status.INVALID;
93 | }
94 |
95 | public enum Status {
96 |
97 | VALID, INVALID, UNKNOWN
98 | }
99 | }
100 |
--------------------------------------------------------------------------------
/src/api/java/mods/railcraft/api/charge/IBattery.java:
--------------------------------------------------------------------------------
1 | /*------------------------------------------------------------------------------
2 | Copyright (c) CovertJaguar, 2011-2020
3 |
4 | This work (the API) is licensed under the "MIT" License,
5 | see LICENSE.md for details.
6 | -----------------------------------------------------------------------------*/
7 |
8 | package mods.railcraft.api.charge;
9 |
10 | import net.minecraft.nbt.NBTTagCompound;
11 |
12 | /**
13 | * Base interface for charge batteries.
14 | *
15 | * Created by CovertJaguar on 5/13/2017 for Railcraft.
16 | *
17 | * @author CovertJaguar
18 | */
19 | public interface IBattery {
20 |
21 | /**
22 | * Gets the charge in the battery.
23 | *
24 | * This value can potentially exceed the capacity on occasion.
25 | * Batteries can have more charge than the max capacity for performance reasons.
26 | *
27 | * @return The charge
28 | */
29 | double getCharge();
30 |
31 | /**
32 | * The amount of charge that can be drawn from this battery right now.
33 | *
34 | * Some implementations limit this by how much can be drawn from a battery per tick.
35 | *
36 | * @return The charge amount
37 | */
38 | default double getAvailableCharge() {
39 | return getCharge();
40 | }
41 |
42 | /**
43 | * Gets the maximum charge the battery can have.
44 | *
45 | * @return The maximum charge
46 | */
47 | double getCapacity();
48 |
49 | /**
50 | * True if and only if {@code getCharge()< getCapacity()}.
51 | *
52 | * @return {@code getCharge()< getCapacity()}
53 | */
54 | default boolean needsCharging() {
55 | return getCharge() < getCapacity();
56 | }
57 |
58 | default double room() {
59 | return Math.max(0.0, getCapacity() - getCharge());
60 | }
61 |
62 | /**
63 | * Sets the charge in the battery.
64 | *
65 | * @param charge The target amount
66 | */
67 | void setCharge(double charge);
68 |
69 | /**
70 | * Adds some charge to the battery.
71 | *
72 | * You are responsible for ensuring that you don't add charge to a full battery.
73 | *
74 | * Batteries can have more charge than the max capacity for performance reasons.
75 | *
76 | * @param charge The charge intended to add
77 | * @see #needsCharging()
78 | */
79 | void addCharge(double charge);
80 |
81 | /**
82 | * Removes some charge from the battery.
83 | *
84 | * @param charge The maximum amount of charge requested
85 | * @return The amount of charge removed
86 | */
87 | double removeCharge(double charge);
88 |
89 | /**
90 | * The efficiency refers to how much of the power put into a battery can be drawn back out of it.
91 | */
92 | default double getEfficiency() {
93 | return 1.0;
94 | }
95 |
96 | /**
97 | * Reads the charge information from the minecart.
98 | *
99 | * @param data The tag that stores the information
100 | * @return The tag provided
101 | */
102 | default NBTTagCompound readFromNBT(NBTTagCompound data) {
103 | setCharge(data.getDouble("charge"));
104 | return data;
105 | }
106 |
107 | /**
108 | * Saves the charge information to the minecart.
109 | *
110 | * @param data The tag that saves the information
111 | * @return The tag provided
112 | */
113 | default NBTTagCompound writeToNBT(NBTTagCompound data) {
114 | data.setDouble("charge", getCharge());
115 | return data;
116 | }
117 |
118 | }
119 |
--------------------------------------------------------------------------------
/src/api/java/mods/railcraft/api/carts/IEnergyTransfer.java:
--------------------------------------------------------------------------------
1 | /*------------------------------------------------------------------------------
2 | Copyright (c) CovertJaguar, 2011-2020
3 |
4 | This work (the API) is licensed under the "MIT" License,
5 | see LICENSE.md for details.
6 | -----------------------------------------------------------------------------*/
7 |
8 | package mods.railcraft.api.carts;
9 |
10 | /**
11 | * This interface is implemented by the Energy Cart
12 | * and is used by the Energy Loaders to charge/discharge carts.
13 | * It is roughly equivalent to the IItemTransfer interface
14 | * and based on ElectricItem and IElectricItem.
15 | *
16 | * This interface has been superseded by the CapabilityCartCharge
17 | * interface for general use. It remains in use solely for the
18 | * IC2 based Energy Loaders.
19 | *
20 | * @author CovertJaguar
21 | */
22 | public interface IEnergyTransfer {
23 |
24 | /**
25 | * Injects the specified amount of EU into the device.
26 | *
27 | * The function returns the remainder of the EU after
28 | * any EU used is subtracted.
29 | *
30 | * @param source Object initiating the transfer, should be an Entity or Tile Entity
31 | * @param amount amount of energy to transfer in EU
32 | * @param tier tier of the source device, has to be at least as high as the target device
33 | * @param ignoreTransferLimit ignore the transfer limit specified by getTransferLimit()
34 | * @param simulate don't actually change the item, just determine the return value
35 | * @return The amount of EU not used
36 | */
37 | double injectEnergy(Object source, double amount, int tier, boolean ignoreTransferLimit, boolean simulate, boolean passAlong);
38 |
39 | /**
40 | * Requests a certain amount of EU from the device.
41 | *
42 | * The is function will subtract EU from the device's store of power
43 | * and return a portion up to, but not exceeding, the amount of EU requested.
44 | *
45 | * @param source Object initiating the transfer, should be an Entity or Tile Entity
46 | * @param amount amount of energy to transfer in EU
47 | * @param tier tier of the source device, has to be at least as high as the target device
48 | * @param ignoreTransferLimit ignore the transfer limit specified by getTransferLimit()
49 | * @param simulate don't actually change the item, just determine the return value
50 | * @param passAlong whether neighboring carts should be asked to provide any missing power.
51 | * @return The amount of EU transferred
52 | */
53 | double extractEnergy(Object source, double amount, int tier, boolean ignoreTransferLimit, boolean simulate, boolean passAlong);
54 |
55 | /**
56 | * Return true if energy can be injected into this device.
57 | *
58 | * @return true if can inject energy
59 | */
60 | boolean canInjectEnergy();
61 |
62 | /**
63 | * Return true if energy can be extracted from this device.
64 | *
65 | * @return true if can extract energy
66 | */
67 | boolean canExtractEnergy();
68 |
69 | /**
70 | * The max capacity of the device.
71 | *
72 | * @return max capacity
73 | */
74 | int getCapacity();
75 |
76 | /**
77 | * Returns the current energy contained in the device.
78 | *
79 | * @return current energy
80 | */
81 | double getEnergy();
82 |
83 | int getTier();
84 |
85 | /**
86 | * The device's transfer rate in EU/t.
87 | *
88 | * @return the transfer rate
89 | */
90 | int getTransferLimit();
91 |
92 | }
93 |
--------------------------------------------------------------------------------
/src/api/java/mods/railcraft/api/carts/ILinkableCart.java:
--------------------------------------------------------------------------------
1 | /*------------------------------------------------------------------------------
2 | Copyright (c) CovertJaguar, 2011-2020
3 |
4 | This work (the API) is licensed under the "MIT" License,
5 | see LICENSE.md for details.
6 | -----------------------------------------------------------------------------*/
7 |
8 | package mods.railcraft.api.carts;
9 |
10 | import net.minecraft.entity.item.EntityMinecart;
11 |
12 | /**
13 | * This interface should be implemented by any minecart that wishes
14 | * to change the default linkage behavior.
15 | * It is NOT required to be able to link a cart,
16 | * it merely gives you more control over the process.
17 | *
18 | * @author CovertJaguar
19 | */
20 | public interface ILinkableCart {
21 |
22 | /**
23 | * To disable linking altogether, return false here.
24 | *
25 | * @return True if this cart is linkable.
26 | */
27 | default boolean isLinkable() {
28 | return true;
29 | }
30 |
31 | /**
32 | * Check called when attempting to link carts.
33 | *
34 | * @param cart The cart that we are attempting to link with.
35 | * @return True if we can link with this cart.
36 | */
37 | @SuppressWarnings("BooleanMethodIsAlwaysInverted")
38 | default boolean canLink(EntityMinecart cart) {
39 | return isLinkable();
40 | }
41 |
42 | /**
43 | * Returns true if this cart has two links
44 | * or false if it can only link with one cart.
45 | *
46 | * If {@link #isLinkable()} returns false, this method
47 | * must return false, too.
48 | *
49 | * @return True if two links
50 | */
51 | default boolean hasTwoLinks() {
52 | return isLinkable();
53 | }
54 |
55 | /**
56 | * Gets the distance at which this cart can be linked.
57 | * This is called on both carts and added together to determine
58 | * how close two carts need to be for a successful link.
59 | * Default = LinkageManager.LINKAGE_DISTANCE
60 | *
61 | * @param cart The cart that you are attempting to link with.
62 | * @return The linkage distance
63 | */
64 | default float getLinkageDistance(EntityMinecart cart) {
65 | return ILinkageManager.LINKAGE_DISTANCE;
66 | }
67 |
68 | /**
69 | * Gets the optimal distance between linked carts.
70 | * This is called on both carts and added together to determine
71 | * the optimal rest distance between linked carts.
72 | * The LinkageManager will attempt to maintain this distance
73 | * between linked carts at all times.
74 | * Default = LinkageManager.OPTIMAL_DISTANCE
75 | *
76 | * @param cart The cart that you are linked with.
77 | * @return The optimal rest distance
78 | */
79 | default float getOptimalDistance(EntityMinecart cart) {
80 | return ILinkageManager.OPTIMAL_DISTANCE;
81 | }
82 |
83 | /**
84 | * Return false if linked carts have no effect on the velocity of this cart.
85 | * Use carefully, if you link two carts that can't be adjusted,
86 | * it will behave as if they are not linked.
87 | *
88 | * @param cart The cart doing the adjusting.
89 | * @return Whether the cart can have its velocity adjusted.
90 | */
91 | default boolean canBeAdjusted(EntityMinecart cart) {
92 | return isLinkable();
93 | }
94 |
95 | /**
96 | * Called upon successful link creation.
97 | *
98 | * @param cart The cart we linked with.
99 | */
100 | default void onLinkCreated(EntityMinecart cart) {
101 | }
102 |
103 | /**
104 | * Called when a link is broken (usually).
105 | *
106 | * @param cart The cart we were linked with.
107 | */
108 | @SuppressWarnings("EmptyMethod")
109 | default void onLinkBroken(EntityMinecart cart) {
110 | }
111 | }
112 |
--------------------------------------------------------------------------------
/src/api/java/mods/railcraft/api/crafting/IBlastFurnaceCrafter.java:
--------------------------------------------------------------------------------
1 | /*------------------------------------------------------------------------------
2 | Copyright (c) CovertJaguar, 2011-2020
3 |
4 | This work (the API) is licensed under the "MIT" License,
5 | see LICENSE.md for details.
6 | -----------------------------------------------------------------------------*/
7 |
8 | package mods.railcraft.api.crafting;
9 |
10 | import net.minecraft.item.ItemStack;
11 | import org.jetbrains.annotations.NotNull;
12 |
13 | import java.util.Collections;
14 | import java.util.List;
15 | import java.util.Optional;
16 |
17 | public interface IBlastFurnaceCrafter {
18 | /**
19 | * The default number of ticks it takes to turn an ingot of iron into an ingot of steel.
20 | */
21 | int SMELT_TIME = 1280;
22 |
23 | /**
24 | * Add a fuel source. It uses the standard Furnace cookTime for the heat value.
25 | *
26 | * By default, it will look up the heat value the vanilla Furnace uses.
27 | *
28 | * @param input An object that can be converted into an Ingredient. This includes,
29 | * but is not limited to Ingredients, ItemStacks, Items, Blocks, and OreTag Strings.
30 | */
31 | default IFuelBuilder newFuel(Object input) {
32 | return new IFuelBuilder() {};
33 | }
34 |
35 | /**
36 | * Begins the definition of a Blast Furnace recipe.
37 | *
38 | * @param input An object that can be converted into an Ingredient. This includes,
39 | * but is not limited to Ingredients, ItemStacks, Items, Blocks, and OreTag Strings.
40 | */
41 | default IBlastFurnaceRecipeBuilder newRecipe(Object input) {
42 | return new IBlastFurnaceRecipeBuilder() {};
43 | }
44 |
45 | /**
46 | * You can remove fuels from this list, but do not add them, it will throw an UnsupportedOperationException.
47 | */
48 | default List<@NotNull ISimpleRecipe> getFuels() {
49 | return Collections.emptyList();
50 | }
51 |
52 | /**
53 | * You can remove recipes from this list, but do not add them, it will throw an UnsupportedOperationException.
54 | */
55 | default List<@NotNull IRecipe> getRecipes() {
56 | return Collections.emptyList();
57 | }
58 |
59 | default Optional getFuel(ItemStack stack) {
60 | return Optional.empty();
61 | }
62 |
63 | default Optional getRecipe(ItemStack stack) {
64 | return Optional.empty();
65 | }
66 |
67 | /**
68 | * Represents a blast furnace recipe.
69 | */
70 | interface IRecipe extends ISimpleRecipe {
71 |
72 | /**
73 | * Gets the output for this recipe.
74 | *
75 | * @return The output, safe to modify
76 | */
77 | ItemStack getOutput();
78 |
79 | /**
80 | * Gets the slag output for this recipe.
81 | */
82 | int getSlagOutput();
83 | }
84 |
85 | interface IBlastFurnaceRecipeBuilder extends
86 | IRecipeBuilder,
87 | IRecipeBuilder.ISingleInputFeature,
88 | IRecipeBuilder.ISingleItemStackOutputFeature,
89 | IRecipeBuilder.ITimeFeature {
90 |
91 | /**
92 | * Sets the slag output of a furnace recipe.
93 | */
94 | default IBlastFurnaceRecipeBuilder slagOutput(int num) {
95 | return this;
96 | }
97 |
98 | /**
99 | * Finalize and commit the recipe.
100 | */
101 | default void register() {}
102 | }
103 |
104 | interface IFuelBuilder extends
105 | IRecipeBuilder,
106 | IRecipeBuilder.ISingleInputFeature,
107 | IRecipeBuilder.ITimeFeature {
108 |
109 | /**
110 | * Finalize and commit the recipe.
111 | */
112 | default void register() {}
113 | }
114 | }
115 |
--------------------------------------------------------------------------------
/src/api/java/mods/railcraft/api/carts/ILinkageManager.java:
--------------------------------------------------------------------------------
1 | /*------------------------------------------------------------------------------
2 | Copyright (c) CovertJaguar, 2011-2020
3 |
4 | This work (the API) is licensed under the "MIT" License,
5 | see LICENSE.md for details.
6 | -----------------------------------------------------------------------------*/
7 |
8 | package mods.railcraft.api.carts;
9 |
10 | import net.minecraft.entity.item.EntityMinecart;
11 | import org.jetbrains.annotations.Nullable;
12 |
13 | import java.util.stream.Stream;
14 |
15 | /**
16 | * The LinkageManager contains all the functions needed to link and interact
17 | * with linked carts.
18 | *
19 | * To obtain an instance of this interface, call {@link CartToolsAPI#linkageManager()}.
20 | *
21 | * Each cart can up to two links. They are called Link A and Link B. Some carts
22 | * will have only Link A, for example the Tunnel Bore.
23 | *
24 | * @author CovertJaguar
25 | * @see CartToolsAPI , ILinkableCart
26 | */
27 | public interface ILinkageManager {
28 |
29 | /**
30 | * The default max distance at which carts can be linked, divided by 2.
31 | */
32 | float LINKAGE_DISTANCE = 1.25f;
33 | /**
34 | * The default distance at which linked carts are maintained, divided by 2.
35 | */
36 | float OPTIMAL_DISTANCE = 0.78f;
37 |
38 | /**
39 | * Allows or disallows the cart to automatically link to the next cart it collides with.
40 | *
41 | * @param cart The minecart
42 | * @param autoLink Whether the auto link feature is enabled
43 | * @return True if tries to disable link or enable link while there is any free link
44 | */
45 | default boolean setAutoLink(EntityMinecart cart, boolean autoLink) {
46 | return false;
47 | }
48 |
49 | default boolean hasAutoLink(EntityMinecart cart) {
50 | return false;
51 | }
52 |
53 | default boolean tryAutoLink(EntityMinecart cart1, EntityMinecart cart2) {
54 | return false;
55 | }
56 |
57 | /**
58 | * Creates a link between two carts, but only if there is nothing preventing
59 | * such a link.
60 | *
61 | * @return True if the link succeeded.
62 | */
63 | default boolean createLink(EntityMinecart cart1, EntityMinecart cart2) {
64 | return false;
65 | }
66 |
67 | default boolean hasFreeLink(EntityMinecart cart) {
68 | return false;
69 | }
70 |
71 | /**
72 | * Returns the cart linked to Link A or null if nothing is currently
73 | * occupying Link A.
74 | *
75 | * @param cart The cart for which to get the link
76 | * @return The linked cart or null
77 | */
78 | default @Nullable EntityMinecart getLinkedCartA(EntityMinecart cart) {
79 | return null;
80 | }
81 |
82 | /**
83 | * Returns the cart linked to Link B or null if nothing is currently
84 | * occupying Link B.
85 | *
86 | * @param cart The cart for which to get the link
87 | * @return The linked cart or null
88 | */
89 | default @Nullable EntityMinecart getLinkedCartB(EntityMinecart cart) {
90 | return null;
91 | }
92 |
93 | /**
94 | * Returns true if the two carts are linked to each other.
95 | *
96 | * @return True if linked
97 | */
98 | default boolean areLinked(EntityMinecart cart1, EntityMinecart cart2) {
99 | return false;
100 | }
101 |
102 | /**
103 | * Breaks a link between two carts, if any link exists.
104 | */
105 | default void breakLink(EntityMinecart cart1, EntityMinecart cart2) {
106 | }
107 |
108 | /**
109 | * Breaks all links the cart has.
110 | */
111 | default void breakLinks(EntityMinecart cart) {
112 | }
113 |
114 | /**
115 | * Counts how many carts are in the train.
116 | *
117 | * @param cart Any cart in the train
118 | * @return The number of carts in the train
119 | */
120 | @SuppressWarnings("unused")
121 | default int countCartsInTrain(EntityMinecart cart) {
122 | return 0;
123 | }
124 |
125 | /**
126 | * Returns a Stream which will iterate over every cart in the provided cart's train.
127 | *
128 | * There is no guarantee of order.
129 | *
130 | * If called on the client, it will only contain the passed cart object.
131 | * There is no linkage information on the client.
132 | */
133 | default Stream streamTrain(EntityMinecart cart) {
134 | return Stream.empty();
135 | }
136 |
137 | }
138 |
--------------------------------------------------------------------------------
/src/api/java/mods/railcraft/api/core/CollectionToolsAPI.java:
--------------------------------------------------------------------------------
1 | /*------------------------------------------------------------------------------
2 | Copyright (c) CovertJaguar, 2011-2020
3 |
4 | This work (the API) is licensed under the "MIT" License,
5 | see LICENSE.md for details.
6 | -----------------------------------------------------------------------------*/
7 |
8 | package mods.railcraft.api.core;
9 |
10 | import com.google.common.collect.ForwardingDeque;
11 | import com.google.common.collect.ForwardingList;
12 | import com.google.common.collect.ForwardingMap;
13 | import com.google.common.collect.ForwardingSet;
14 | import net.minecraft.util.math.BlockPos;
15 |
16 | import java.util.*;
17 | import java.util.function.Supplier;
18 |
19 | /**
20 | * Created by CovertJaguar on 12/4/2018 for Railcraft.
21 | *
22 | * @author CovertJaguar
23 | */
24 | public class CollectionToolsAPI {
25 |
26 | public static List blockPosList(Supplier> delegate) {
27 | return blockPosList(delegate.get());
28 | }
29 |
30 | public static List blockPosList(List delegate) {
31 | return new BlockPosList(delegate);
32 | }
33 |
34 | private static class BlockPosList extends ForwardingList {
35 | private final List delegate;
36 |
37 | private BlockPosList(List delegate) {
38 | this.delegate = delegate;
39 | }
40 |
41 | @Override
42 | protected List delegate() {
43 | return delegate;
44 | }
45 |
46 | @Override
47 | public boolean add(BlockPos element) {
48 | return super.add(element.toImmutable());
49 | }
50 |
51 | @Override
52 | public boolean addAll(Collection extends BlockPos> collection) {
53 | return standardAddAll(collection);
54 | }
55 |
56 | }
57 |
58 | public static Deque blockPosDeque(Supplier> delegate) {
59 | return blockPosDeque(delegate.get());
60 | }
61 |
62 | public static Deque blockPosDeque(Deque delegate) {
63 | return new BlockPosDeque(delegate);
64 | }
65 |
66 | private static class BlockPosDeque extends ForwardingDeque {
67 | private final Deque delegate;
68 |
69 | private BlockPosDeque(Deque delegate) {
70 | this.delegate = delegate;
71 | }
72 |
73 | @Override
74 | protected Deque delegate() {
75 | return delegate;
76 | }
77 |
78 | @Override
79 | public boolean add(BlockPos element) {
80 | return super.add(element.toImmutable());
81 | }
82 |
83 | @Override
84 | public boolean addAll(Collection extends BlockPos> collection) {
85 | return standardAddAll(collection);
86 | }
87 |
88 | }
89 |
90 | public static Set blockPosSet(Supplier> delegate) {
91 | return blockPosSet(delegate.get());
92 | }
93 |
94 | public static Set blockPosSet(Set delegate) {
95 | return new BlockPosSet(delegate);
96 | }
97 |
98 | private static class BlockPosSet extends ForwardingSet {
99 | private final Set delegate;
100 |
101 | private BlockPosSet(Set delegate) {
102 | this.delegate = delegate;
103 | }
104 |
105 | @Override
106 | protected Set delegate() {
107 | return delegate;
108 | }
109 |
110 | @Override
111 | public boolean add(BlockPos element) {
112 | return super.add(element.toImmutable());
113 | }
114 |
115 | @Override
116 | public boolean addAll(Collection extends BlockPos> collection) {
117 | return standardAddAll(collection);
118 | }
119 |
120 | }
121 |
122 | public static Map blockPosMap(Map delegate) {
123 | return new BlockPosMap<>(delegate);
124 | }
125 |
126 | private static class BlockPosMap extends ForwardingMap {
127 | private final Map delegate;
128 |
129 | private BlockPosMap(Map delegate) {
130 | this.delegate = delegate;
131 | }
132 |
133 | @Override
134 | protected Map delegate() {
135 | return delegate;
136 | }
137 |
138 | @Override
139 | public V put(BlockPos key, V value) {
140 | return super.put(key.toImmutable(), value);
141 | }
142 | }
143 |
144 | }
145 |
--------------------------------------------------------------------------------
/src/api/java/mods/railcraft/api/crafting/IRecipeBuilder.java:
--------------------------------------------------------------------------------
1 | /*------------------------------------------------------------------------------
2 | Copyright (c) CovertJaguar, 2011-2020
3 |
4 | This work (the API) is licensed under the "MIT" License,
5 | see LICENSE.md for details.
6 | -----------------------------------------------------------------------------*/
7 |
8 | package mods.railcraft.api.crafting;
9 |
10 | import net.minecraft.block.Block;
11 | import net.minecraft.item.Item;
12 | import net.minecraft.item.ItemStack;
13 | import net.minecraft.item.crafting.Ingredient;
14 | import net.minecraft.util.ResourceLocation;
15 | import org.jetbrains.annotations.Nullable;
16 |
17 | import java.util.Optional;
18 | import java.util.function.ToIntFunction;
19 |
20 | /**
21 | * Created by CovertJaguar on 12/25/2018 for Railcraft.
22 | *
23 | * @author CovertJaguar
24 | */
25 | @SuppressWarnings("unchecked")
26 | public interface IRecipeBuilder {
27 |
28 | /**
29 | * Adds a resource location that describes the recipe.
30 | * It is only used for logging, so it doesn't need to be exact.
31 | *
32 | * This is required.
33 | */
34 | default B name(@Nullable ResourceLocation name) {
35 | return (B) this;
36 | }
37 |
38 | /**
39 | * Adds a resource location that describes the recipe.
40 | * It is only used for logging, so it doesn't need to be exact.
41 | *
42 | * This is required.
43 | */
44 | default B name(String name) {
45 | name(new ResourceLocation(name));
46 | return (B) this;
47 | }
48 |
49 | /**
50 | * Adds a resource location that describes the recipe.
51 | * It is only used for logging, so it doesn't need to be exact.
52 | *
53 | * This is required.
54 | */
55 | default B name(String namespace, String descriptor) {
56 | name(new ResourceLocation(namespace, descriptor));
57 | return (B) this;
58 | }
59 |
60 | /**
61 | * This function will attempt to generate a ResourceLocation from the given object.
62 | *
63 | * This is required.
64 | */
65 | default B name(@Nullable Object name) {
66 | return (B) this;
67 | }
68 |
69 | default ResourceLocation getName() {
70 | return new ResourceLocation("invalid", "dummy");
71 | }
72 |
73 | default boolean notRegistered() {return true;}
74 |
75 | interface IFeature {
76 | default Optional getFeature(Class feature) {
77 | return Optional.empty();
78 | }
79 | }
80 |
81 | interface ITimeFeature extends IFeature {
82 |
83 | /**
84 | * Sets the cooking time/heat value/process time for this recipe, in ticks.
85 | */
86 | default B time(int ticks) {
87 | return time(stack -> ticks);
88 | }
89 |
90 | /**
91 | * Sets the cooking time/heat value/process time for this recipe, in ticks.
92 | */
93 | default B time(ToIntFunction tickFunction) {
94 | getFeature(ITimeFeature.class).ifPresent(impl -> impl.time(tickFunction));
95 | return (B) this;
96 | }
97 |
98 | default ToIntFunction getTimeFunction() {
99 | return getFeature(ITimeFeature.class).map(ITimeFeature::getTimeFunction).get();
100 | }
101 | }
102 |
103 | interface ISingleInputFeature extends IFeature {
104 | default Ingredient getInput() {
105 | return getFeature(ISingleInputFeature.class).map(ISingleInputFeature::getInput).get();
106 | }
107 | }
108 |
109 | interface ISingleItemStackOutputFeature extends IFeature {
110 | default B output(@Nullable ItemStack output) {
111 | getFeature(ISingleItemStackOutputFeature.class).ifPresent(impl -> impl.output(output));
112 | return (B) this;
113 | }
114 |
115 | default B output(@Nullable Item output) {
116 | return output(output, 1);
117 | }
118 |
119 | default B output(@Nullable Item output, int amount) {
120 | return output(new ItemStack(output, amount));
121 | }
122 |
123 | default B output(@Nullable Block output) {
124 | return output(output, 1);
125 | }
126 |
127 | default B output(@Nullable Block output, int amount) {
128 | return output(new ItemStack(output, amount));
129 | }
130 |
131 | default ItemStack getOutput() {
132 | return getFeature(ISingleItemStackOutputFeature.class).map(ISingleItemStackOutputFeature::getOutput).orElse(ItemStack.EMPTY);
133 | }
134 | }
135 | }
136 |
--------------------------------------------------------------------------------
/src/api/java/mods/railcraft/api/carts/ITrainTransferHelper.java:
--------------------------------------------------------------------------------
1 | /*------------------------------------------------------------------------------
2 | Copyright (c) CovertJaguar, 2011-2020
3 |
4 | This work (the API) is licensed under the "MIT" License,
5 | see LICENSE.md for details.
6 | -----------------------------------------------------------------------------*/
7 | package mods.railcraft.api.carts;
8 |
9 | import net.minecraft.entity.item.EntityMinecart;
10 | import net.minecraft.item.ItemStack;
11 | import net.minecraftforge.fluids.FluidStack;
12 | import net.minecraftforge.fluids.capability.IFluidHandler;
13 | import net.minecraftforge.items.IItemHandlerModifiable;
14 | import org.jetbrains.annotations.Contract;
15 | import org.jetbrains.annotations.Nullable;
16 |
17 | import java.util.Optional;
18 | import java.util.function.Predicate;
19 |
20 | /**
21 | * This interface is the API facing wrapper for an internal helper class that makes it
22 | * simple to pass items and fluids around within a Train.
23 | *
24 | * The helper object can be accessed from CartTools and is aware of the IItemCart and IFluidCart interfaces.
25 | *
26 | * Created by CovertJaguar on 5/11/2015.
27 | *
28 | * @see CartToolsAPI
29 | * @see mods.railcraft.api.carts.IItemCart
30 | * @see mods.railcraft.api.carts.IFluidCart
31 | */
32 | @SuppressWarnings("unused")
33 | public interface ITrainTransferHelper {
34 | // ***************************************************************************************************************************
35 | // Items
36 | // ***************************************************************************************************************************
37 |
38 | /**
39 | * Will attempt to push an ItemStack to the Train.
40 | *
41 | * @param requester the source EntityMinecart
42 | * @param stack the ItemStack to be pushed
43 | * @return the ItemStack that remains after any pushed items were removed, or null if it was fully pushed
44 | * @see mods.railcraft.api.carts.IFluidCart
45 | */
46 | default ItemStack pushStack(EntityMinecart requester, ItemStack stack) {
47 | return stack;
48 | }
49 |
50 | /**
51 | * Will request an item from the Train.
52 | *
53 | * @param requester the source EntityMinecart
54 | * @param filter a Predicate that defines the requested item
55 | * @return the ItemStack pulled from the Train, or null if the request cannot be met
56 | * @see mods.railcraft.api.carts.IItemCart
57 | */
58 | default ItemStack pullStack(EntityMinecart requester, Predicate filter) {
59 | return ItemStack.EMPTY;
60 | }
61 |
62 | /**
63 | * Offers an item stack to the Train or drops it if no one wants it.
64 | *
65 | * @param requester the source EntityMinecart
66 | * @param stack the ItemStack to be offered
67 | */
68 | default void offerOrDropItem(EntityMinecart requester, ItemStack stack) {
69 | }
70 |
71 | /**
72 | * Returns an IItemHandlerModifiable with represents the entire train.
73 | *
74 | * @param cart a cart in the train
75 | */
76 | default Optional getTrainItemHandler(EntityMinecart cart) {
77 | return Optional.empty();
78 | }
79 |
80 |
81 | // ***************************************************************************************************************************
82 | // Fluids
83 | // ***************************************************************************************************************************
84 |
85 | /**
86 | * Will attempt to push fluid to the Train.
87 | *
88 | * @param requester the source EntityMinecart
89 | * @param fluidStack the amount and type of Fluid to be pushed
90 | * @return the FluidStack that remains after any pushed Fluid was removed, or null if it was fully pushed
91 | * @see mods.railcraft.api.carts.IFluidCart
92 | */
93 | default @Nullable FluidStack pushFluid(EntityMinecart requester, FluidStack fluidStack) {
94 | return fluidStack;
95 | }
96 |
97 | /**
98 | * Will request fluid from the Train.
99 | *
100 | * @param requester the source EntityMinecart
101 | * @param fluidStack the amount and type of Fluid requested
102 | * @return the FluidStack pulled from the Train, or null if the request cannot be met
103 | * @see mods.railcraft.api.carts.IFluidCart
104 | */
105 | @Contract("_, null -> null")
106 | default @Nullable FluidStack pullFluid(EntityMinecart requester, @Nullable FluidStack fluidStack) {
107 | return null;
108 | }
109 |
110 | /**
111 | * Returns an IFluidHandler with represents the entire train.
112 | *
113 | * @param cart a cart in the train
114 | */
115 | default Optional getTrainFluidHandler(EntityMinecart cart) {
116 | return Optional.empty();
117 | }
118 | }
119 |
--------------------------------------------------------------------------------
/src/api/java/mods/railcraft/api/tracks/ITrackKitInstance.java:
--------------------------------------------------------------------------------
1 | /*------------------------------------------------------------------------------
2 | Copyright (c) CovertJaguar, 2011-2020
3 |
4 | This work (the API) is licensed under the "MIT" License,
5 | see LICENSE.md for details.
6 | -----------------------------------------------------------------------------*/
7 |
8 | package mods.railcraft.api.tracks;
9 |
10 | import mcp.MethodsReturnNonnullByDefault;
11 | import mods.railcraft.api.core.INetworkedObject;
12 | import net.minecraft.block.Block;
13 | import net.minecraft.block.BlockRailBase;
14 | import net.minecraft.block.state.IBlockState;
15 | import net.minecraft.entity.EntityLivingBase;
16 | import net.minecraft.entity.item.EntityMinecart;
17 | import net.minecraft.entity.player.EntityPlayer;
18 | import net.minecraft.item.ItemStack;
19 | import net.minecraft.nbt.NBTTagCompound;
20 | import net.minecraft.tileentity.TileEntity;
21 | import net.minecraft.util.EnumHand;
22 | import net.minecraft.util.math.BlockPos;
23 | import net.minecraft.world.World;
24 | import org.jetbrains.annotations.Nullable;
25 |
26 | import javax.annotation.ParametersAreNonnullByDefault;
27 | import java.io.DataInputStream;
28 | import java.io.DataOutputStream;
29 | import java.util.ArrayList;
30 | import java.util.List;
31 |
32 | /**
33 | * This interface defines a track.
34 | *
35 | * Basically all block and tile entity functions for Tracks are delegated to an
36 | * ITrackInstance.
37 | *
38 | * Instead of implementing this interface directly, you should probably extend
39 | * TrackInstanceBase. It will simplify your life.
40 | *
41 | * You must have a constructor that accepts a single TileEntity object.
42 | *
43 | * All packet manipulation is handled by Railcraft's code, you just need to
44 | * implement the functions in INetworkedObject to pass data from the server to
45 | * the client.
46 | *
47 | * @author CovertJaguar
48 | * @see TrackKitInstance
49 | */
50 | @MethodsReturnNonnullByDefault
51 | @ParametersAreNonnullByDefault
52 | public interface ITrackKitInstance extends INetworkedObject {
53 |
54 | T getTile();
55 |
56 | void setTile(T tileEntity);
57 |
58 | TrackKit getTrackKit();
59 |
60 | /**
61 | * Return the render state. Ranges from 0 to 15.
62 | * Used by the TrackKit blockstate JSON to determine which model/texture to display.
63 | */
64 | default int getRenderState() {
65 | return 0;
66 | }
67 |
68 | default List getDrops(int fortune) {
69 | List drops = new ArrayList<>();
70 | drops.add(getTrackKit().getTrackKitItem());
71 | return drops;
72 | }
73 |
74 | /**
75 | * Return the rail's shape.
76 | * Can be used to make the cart think the rail something other than it is,
77 | * for example when making diamond junctions or switches.
78 | *
79 | * @param cart The cart asking for the metadata, null if it is not called by
80 | * EntityMinecart.
81 | * @return The metadata.
82 | */
83 | BlockRailBase.EnumRailDirection getRailDirection(IBlockState state, @Nullable EntityMinecart cart);
84 |
85 | /**
86 | * This function is called by any minecart that passes over this rail. It is
87 | * called once per update tick that the minecart is on the rail.
88 | *
89 | * @param cart The cart on the rail.
90 | */
91 | default void onMinecartPass(EntityMinecart cart) {
92 | }
93 |
94 | default void writeToNBT(NBTTagCompound data) {
95 | }
96 |
97 | default void readFromNBT(NBTTagCompound data) {
98 | }
99 |
100 | default void update() {
101 | }
102 |
103 | boolean blockActivated(EntityPlayer player, EnumHand hand);
104 |
105 | default void onBlockRemoved() {
106 | }
107 |
108 | void onBlockPlacedBy(IBlockState state, @Nullable EntityLivingBase placer, ItemStack stack);
109 |
110 | void onNeighborBlockChange(IBlockState state, @Nullable Block neighborBlock);
111 |
112 | default BlockPos getPos() {
113 | return getTile().getPos();
114 | }
115 |
116 | @Override
117 | default @Nullable World theWorld() {
118 | return getTile().getWorld();
119 | }
120 |
121 | /**
122 | * Returns the max speed of the rail.
123 | *
124 | * @param cart The cart on the rail, may be null.
125 | * @return The max speed of the current rail.
126 | */
127 | default float getRailMaxSpeed(World world, @Nullable EntityMinecart cart, BlockPos pos) {
128 | return getTrackType().getEventHandler().getMaxSpeed(world, cart, pos);
129 | }
130 |
131 | /**
132 | * Returning true here will make the track unbreakable.
133 | */
134 | default boolean isProtected() {
135 | return false;
136 | }
137 |
138 | /**
139 | * Returns the track type of this track.
140 | */
141 | default TrackType getTrackType() {
142 | return getTile().getTrackType();
143 | }
144 |
145 | /**
146 | * Requests for saving the data of the track kit.
147 | */
148 | default void markDirty() {
149 | getTile().markDirty();
150 | }
151 | }
152 |
--------------------------------------------------------------------------------
/src/api/java/mods/railcraft/api/core/WorldCoordinate.java:
--------------------------------------------------------------------------------
1 | /*------------------------------------------------------------------------------
2 | Copyright (c) CovertJaguar, 2011-2020
3 |
4 | This work (the API) is licensed under the "MIT" License,
5 | see LICENSE.md for details.
6 | -----------------------------------------------------------------------------*/
7 | package mods.railcraft.api.core;
8 |
9 | import net.minecraft.nbt.NBTTagCompound;
10 | import net.minecraft.tileentity.TileEntity;
11 | import net.minecraft.util.math.BlockPos;
12 | import net.minecraft.util.math.Vec3d;
13 | import org.jetbrains.annotations.Nullable;
14 |
15 | /**
16 | * This immutable class represents a point in the Minecraft world, while taking
17 | * into account the possibility of coordinates in different dimensions.
18 | *
19 | * @author CovertJaguar
20 | */
21 | public final class WorldCoordinate {
22 | /**
23 | * The dimension
24 | */
25 | private final int dimension;
26 |
27 | private final BlockPos pos;
28 |
29 | /**
30 | * Creates a new WorldCoordinate
31 | *
32 | * @param dimension Dimension ID
33 | * @param x World Coordinate
34 | * @param y World Coordinate
35 | * @param z World Coordinate
36 | */
37 | public WorldCoordinate(int dimension, int x, int y, int z) {
38 | this.dimension = dimension;
39 | this.pos = new BlockPos(x, y, z);
40 | }
41 |
42 | /**
43 | * Creates a new WorldCoordinate
44 | *
45 | * @param dimension Dimension ID
46 | * @param pos World Coordinates
47 | */
48 | public WorldCoordinate(int dimension, BlockPos pos) {
49 | this.dimension = dimension;
50 | this.pos = pos;
51 | }
52 |
53 | public static WorldCoordinate from(TileEntity tile) {
54 | return new WorldCoordinate(tile.getWorld().provider != null ? tile.getWorld().provider.getDimension() : 0, tile.getPos());
55 | }
56 |
57 | public static @Nullable WorldCoordinate readFromNBT(NBTTagCompound data, String key) {
58 | if (data.hasKey(key, 10)) {
59 | NBTTagCompound nbt = data.getCompoundTag(key);
60 | int dim = nbt.getInteger("dim");
61 | int x = nbt.getInteger("x");
62 | int y = nbt.getInteger("y");
63 | int z = nbt.getInteger("z");
64 | return new WorldCoordinate(dim, x, y, z);
65 | } else if (data.hasKey(key, 11)) {
66 | int[] c = data.getIntArray(key);
67 | return new WorldCoordinate(c[0], c[1], c[2], c[3]);
68 | }
69 | return null;
70 | }
71 |
72 | public void writeToNBT(NBTTagCompound data, String tag) {
73 | data.setIntArray(tag, new int[]{dimension, getX(), getY(), getZ()});
74 | }
75 |
76 | public boolean isInSameChunk(WorldCoordinate otherCoord) {
77 | return dimension == otherCoord.dimension && getX() >> 4 == otherCoord.getX() >> 4 && getZ() >> 4 == otherCoord.getZ() >> 4;
78 | }
79 |
80 | public boolean isEqual(int dim, int x, int y, int z) {
81 | return getX() == x && getY() == y && getZ() == z && dimension == dim;
82 | }
83 |
84 | public boolean isEqual(int dim, BlockPos p) {
85 | return getX() == p.getX() && getY() == p.getY() && getZ() == p.getZ() && dimension == dim;
86 | }
87 |
88 | public boolean isEqual(WorldCoordinate p) {
89 | return getX() == p.getX() && getY() == p.getY() && getZ() == p.getZ() && getDim() == p.getDim();
90 | }
91 |
92 | // public int compareTo(@Nonnull WorldCoordinate o) {
93 | // if (dimension != o.dimension)
94 | // return dimension - o.dimension;
95 | // if (getX() != o.getX())
96 | // return getX() - o.getX();
97 | // if (getY() != o.getY())
98 | // return getY() - o.getY();
99 | // if (getZ() != o.getZ())
100 | // return getZ() - o.getZ();
101 | // return 0;
102 | // }
103 |
104 | @Override
105 | public boolean equals(Object o) {
106 | if (this == o) return true;
107 | if (o == null || getClass() != o.getClass()) return false;
108 |
109 | WorldCoordinate that = (WorldCoordinate) o;
110 |
111 | return dimension == that.dimension && pos.equals(that.pos);
112 | }
113 |
114 | @Override
115 | public int hashCode() {
116 | int result = dimension;
117 | result = 31 * result + pos.hashCode();
118 | return result;
119 | }
120 |
121 | @Override
122 | public String toString() {
123 | return "WorldCoordinate{" + "dimension=" + dimension + ", x=" + getX() + ", y=" + getY() + ", z=" + getZ() + '}';
124 | }
125 |
126 | public int getDim() {
127 | return dimension;
128 | }
129 |
130 | public BlockPos getPos() {
131 | return pos;
132 | }
133 |
134 | public int getX() {
135 | return pos.getX();
136 | }
137 |
138 | public int getY() {
139 | return pos.getY();
140 | }
141 |
142 | public int getZ() {
143 | return pos.getZ();
144 | }
145 |
146 | public Vec3d getVec3d() {
147 | return new Vec3d(getPos());
148 | }
149 |
150 | @Deprecated // cubic chunks
151 | public boolean isBelowWorld() {
152 | return getY() < 0;
153 | }
154 | }
155 |
--------------------------------------------------------------------------------
/src/api/java/mods/railcraft/api/tracks/TrackScanner.java:
--------------------------------------------------------------------------------
1 | /*------------------------------------------------------------------------------
2 | Copyright (c) CovertJaguar, 2011-2020
3 |
4 | This work (the API) is licensed under the "MIT" License,
5 | see LICENSE.md for details.
6 | -----------------------------------------------------------------------------*/
7 |
8 | package mods.railcraft.api.tracks;
9 |
10 | import net.minecraft.util.math.BlockPos;
11 | import net.minecraft.world.World;
12 |
13 | /**
14 | * Created by CovertJaguar on 3/19/2016 for Railcraft.
15 | *
16 | * @author CovertJaguar
17 | */
18 | public final class TrackScanner {
19 |
20 | /**
21 | * Verifies that two rails are connected to each other along a straight line
22 | * with no gaps or wanderings.
23 | *
24 | * @param world The World object
25 | * @return true if they are connected
26 | */
27 | public static boolean areTracksConnectedAlongAxis(World world, BlockPos start, BlockPos end) {
28 | return scanStraightTrackSection(world, start, end).verdict == ScanResult.Verdict.VALID;
29 | }
30 |
31 | /**
32 | * Verifies that two rails are connected to each other along a straight line
33 | * with no gaps or wanderings.
34 | *
35 | * Also records the min and max y values along the way.
36 | *
37 | * @param world The World object
38 | * @return ScanResult object with results
39 | */
40 | public static ScanResult scanStraightTrackSection(World world, BlockPos start, BlockPos end) {
41 | int x1 = start.getX();
42 | int y1 = start.getY();
43 | int z1 = start.getZ();
44 |
45 | int x2 = end.getX();
46 | int y2 = end.getY();
47 | int z2 = end.getZ();
48 |
49 | int minY = Math.min(y1, y2);
50 | int maxY = Math.max(y1, y2);
51 | if (x1 != x2 && z1 != z2)
52 | return new ScanResult(ScanResult.Verdict.NOT_ALIGNED, minY, maxY);
53 | if (x1 != x2) {
54 | int min;
55 | int max;
56 | int yy;
57 | if (x1 < x2) {
58 | min = x1;
59 | max = x2;
60 | yy = y1;
61 | } else {
62 | min = x2;
63 | max = x1;
64 | yy = y2;
65 | }
66 | for (int xx = min; xx <= max; xx++) {
67 | // if (world.blockExists(xx, yy, z1))
68 | BlockPos p = new BlockPos(xx, yy, z1);
69 | if (TrackToolsAPI.isRailBlockAt(world, p)) {
70 | // NOOP
71 | } else if (TrackToolsAPI.isRailBlockAt(world, p.down())) {
72 | yy--;
73 | if (yy < minY)
74 | minY = yy;
75 | } else if (TrackToolsAPI.isRailBlockAt(world, p.up())) {
76 | yy++;
77 | if (yy > maxY)
78 | maxY = yy;
79 | } else if (!world.isBlockLoaded(p)) {
80 | return new ScanResult(ScanResult.Verdict.UNKNOWN, minY, maxY);
81 | } else
82 | return new ScanResult(ScanResult.Verdict.PATH_NOT_FOUND, minY, maxY);
83 | }
84 | } else if (z1 != z2) {
85 | int min;
86 | int max;
87 | int yy;
88 | if (z1 < z2) {
89 | min = z1;
90 | max = z2;
91 | yy = y1;
92 | } else {
93 | min = z2;
94 | max = z1;
95 | yy = y2;
96 | }
97 | for (int zz = min; zz <= max; zz++) {
98 | // if (world.blockExists(x1, yy, zz))
99 | BlockPos p = new BlockPos(x1, yy, zz);
100 | if (TrackToolsAPI.isRailBlockAt(world, p)) {
101 | // NOOP
102 | } else if (TrackToolsAPI.isRailBlockAt(world, p.down())) {
103 | yy--;
104 | if (yy < minY)
105 | minY = yy;
106 | } else if (TrackToolsAPI.isRailBlockAt(world, p.up())) {
107 | yy++;
108 | if (yy > maxY)
109 | maxY = yy;
110 | } else if (!world.isBlockLoaded(p)) {
111 | return new ScanResult(ScanResult.Verdict.UNKNOWN, minY, maxY);
112 | } else
113 | return new ScanResult(ScanResult.Verdict.PATH_NOT_FOUND, minY, maxY);
114 | }
115 | }
116 | return new ScanResult(ScanResult.Verdict.VALID, minY, maxY);
117 | }
118 |
119 | private TrackScanner() {
120 | }
121 |
122 | public static final class ScanResult {
123 | public final Verdict verdict;
124 | public final boolean areConnected;
125 | public final int minY, maxY;
126 |
127 | public ScanResult(Verdict verdict, int minY, int maxY) {
128 | this.verdict = verdict;
129 | this.areConnected = verdict == Verdict.VALID;
130 | this.minY = minY;
131 | this.maxY = maxY;
132 | }
133 |
134 | public enum Verdict {
135 | VALID,
136 | UNKNOWN,
137 | NOT_ALIGNED,
138 | PATH_NOT_FOUND
139 | }
140 | }
141 | }
142 |
--------------------------------------------------------------------------------
/src/api/java/mods/railcraft/api/charge/IBatteryBlock.java:
--------------------------------------------------------------------------------
1 | /*------------------------------------------------------------------------------
2 | Copyright (c) CovertJaguar, 2011-2020
3 |
4 | This work (the API) is licensed under the "MIT" License,
5 | see LICENSE.md for details.
6 | -----------------------------------------------------------------------------*/
7 |
8 | package mods.railcraft.api.charge;
9 |
10 | import com.google.common.base.Objects;
11 | import mods.railcraft.api.core.ILocalizedObject;
12 |
13 | /**
14 | * Batteries the heart of the Charge Network.
15 | *
16 | * Consumers and 'wires' don't need batteries, but generators and battery blocks do.
17 | *
18 | * You don't to have a Tile Entity to provide a battery for the network,
19 | * serialization and ticking is handled by the network itself.
20 | *
21 | * Generators should add their power output directly to its battery object.
22 | *
23 | * You shouldn't hold onto battery objects for longer than you need them.
24 | * The API makes no guarantee that the battery object assigned to a specific coordinate
25 | * will always be the same object.
26 | *
27 | * Such that sometimes:
28 | * {@code
29 | * IBatteryBlock bat1 = Charge.distribution.network(world).access(pos).getBattery();
30 | * IBatteryBlock bat2 = Charge.distribution.network(world).access(pos).getBattery();
31 | * bat1 != bat2
32 | * }
33 | *
34 | * Created by CovertJaguar on 10/27/2018 for Railcraft.
35 | *
36 | * @author CovertJaguar
37 | */
38 | public
39 | interface IBatteryBlock extends IBattery {
40 | enum State implements ILocalizedObject {
41 | /**
42 | * Infinite Batteries will supply an infinite amount of power to the network.
43 | */
44 | INFINITE("tile.railcraft.battery.state.infinite"),
45 | /**
46 | * Source batteries are used in generators and transformers. The charge they hold will be used to charge
47 | * the rechargeable batteries in the network, but they themselves will not be load balanced.
48 | */
49 | SOURCE("tile.railcraft.battery.state.source"),
50 | /**
51 | * Rechargeable batteries can be filled and drained indefinitely.
52 | * The charge network will balance the change level between all
53 | * the rechargeable batteries in the network.
54 | *
55 | * Generators should posses a small rechargeable battery just large enough to hold
56 | * the generator's max per tick output with a similar draw level and 100% efficiency.
57 | */
58 | RECHARGEABLE("tile.railcraft.battery.state.rechargeable"),
59 | /**
60 | * Disposable batteries are excluded from the charge network's level balancing.
61 | * They will be drained after rechargeable batteries.
62 | */
63 | DISPOSABLE("tile.railcraft.battery.state.disposable"),
64 | /**
65 | * Disabled batteries are ignored by the network. Use for redstone switching or multiblock logic, etc.
66 | */
67 | DISABLED("tile.railcraft.battery.state.disabled");
68 |
69 | private final String locTag;
70 |
71 | State(String locTag) {
72 | this.locTag = locTag;
73 | }
74 |
75 | @Override
76 | public String getLocalizationTag() {
77 | return locTag;
78 | }
79 | }
80 |
81 | /**
82 | * Gets the current state of the battery.
83 | *
84 | * @return The battery's state.
85 | */
86 | default State getState() {
87 | return State.RECHARGEABLE;
88 | }
89 |
90 | /**
91 | * Sets the current state of the battery.
92 | *
93 | * The state of a battery is always under the control of the client,
94 | * the network will never change it for you.
95 | *
96 | * @param stateImpl The battery's new state.
97 | */
98 | default void setState(State stateImpl) {
99 | }
100 |
101 | class Spec {
102 | private final IBatteryBlock.State initialState;
103 | private final double capacity;
104 | private final double maxDraw;
105 | private final double efficiency;
106 |
107 | /**
108 | * @param initialState The initial state of the battery.
109 | * @param capacity The capacity of the battery.
110 | * @param maxDraw How much charge can be drawn from this battery per tick.
111 | * @param efficiency How efficient it is to draw from this battery.
112 | *
113 | * Generators/Converters should generally have this set to 1.0.
114 | * Other types of blocks will vary.
115 | */
116 | public Spec(IBatteryBlock.State initialState, double capacity, double maxDraw, double efficiency) {
117 | this.initialState = initialState;
118 | this.capacity = capacity;
119 | this.maxDraw = maxDraw;
120 | this.efficiency = efficiency;
121 | }
122 |
123 | public IBatteryBlock.State getInitialState() {
124 | return initialState;
125 | }
126 |
127 | public double getCapacity() {
128 | return capacity;
129 | }
130 |
131 | public double getMaxDraw() {
132 | return maxDraw;
133 | }
134 |
135 | public double getEfficiency() {
136 | return efficiency;
137 | }
138 |
139 | @Override
140 | public String toString() {
141 | return String.format("Battery{Cap: %.2f, Draw: %.2f, Eff: %.2f}", capacity, maxDraw, efficiency);
142 | }
143 |
144 | @Override
145 | public boolean equals(Object o) {
146 | if (this == o) return true;
147 | if (o == null || getClass() != o.getClass()) return false;
148 | Spec spec = (Spec) o;
149 | return Double.compare(spec.capacity, capacity) == 0 &&
150 | Double.compare(spec.maxDraw, maxDraw) == 0 &&
151 | Double.compare(spec.efficiency, efficiency) == 0 &&
152 | initialState == spec.initialState;
153 | }
154 |
155 | @Override
156 | public int hashCode() {
157 | return Objects.hashCode(initialState, capacity, maxDraw, efficiency);
158 | }
159 | }
160 | }
161 |
--------------------------------------------------------------------------------
/src/api/java/mods/railcraft/api/signals/SignalAspect.java:
--------------------------------------------------------------------------------
1 | /*------------------------------------------------------------------------------
2 | Copyright (c) CovertJaguar, 2011-2020
3 |
4 | This work (the API) is licensed under the "MIT" License,
5 | see LICENSE.md for details.
6 | -----------------------------------------------------------------------------*/
7 |
8 | package mods.railcraft.api.signals;
9 |
10 | import net.minecraft.nbt.NBTTagCompound;
11 | import org.jetbrains.annotations.Nullable;
12 |
13 | import java.util.Locale;
14 |
15 | /**
16 | * Represents a Signal state.
17 | *
18 | * @author CovertJaguar
19 | */
20 | public enum SignalAspect {
21 |
22 | /**
23 | * The All Clear.
24 | */
25 | GREEN(0, 5, "gui.railcraft.aspect.green.name"),
26 | /**
27 | * Typically means pairing in progress.
28 | */
29 | BLINK_YELLOW(1, 3, "gui.railcraft.aspect.blink.yellow.name"),
30 | /**
31 | * Caution, cart heading away.
32 | */
33 | YELLOW(1, 5, "gui.railcraft.aspect.yellow.name"),
34 | /**
35 | * Maintenance warning, the signal is malfunctioning.
36 | */
37 | BLINK_RED(2, 3, "gui.railcraft.aspect.blink.red.name"),
38 | /**
39 | * Stop!
40 | */
41 | RED(2, 5, "gui.railcraft.aspect.red.name"),
42 | /**
43 | * Can't happen, really it can't (or shouldn't). Only used when rendering
44 | * blink states (for the texture offset).
45 | */
46 | OFF(3, 0, "gui.railcraft.aspect.off.name");
47 | private final int textureIndex;
48 | private final int lightValue;
49 | private final String localizationTag;
50 | private static boolean blinkState;
51 | private static final int SIGNAL_BRIGHTNESS = 210;
52 | public static final SignalAspect[] VALUES = values();
53 |
54 | SignalAspect(int textureIndex, int lightValue, String localizationTag) {
55 | this.textureIndex = textureIndex;
56 | this.lightValue = lightValue;
57 | this.localizationTag = localizationTag;
58 | }
59 |
60 | /**
61 | * Returns the texture offset for this specific aspect.
62 | *
63 | * @return offset
64 | */
65 | public int getTextureIndex() {
66 | return textureIndex;
67 | }
68 |
69 | /**
70 | * Returns the texture brightness for this specific aspect.
71 | *
72 | * @return brightness
73 | */
74 | public float getTextureBrightness() {
75 | if (this == OFF) return 0F;
76 | return SIGNAL_BRIGHTNESS / 16F;
77 | }
78 |
79 | /**
80 | * Returns true if the aspect is one of the blink states.
81 | *
82 | * @return true if blinks
83 | */
84 | public boolean isBlinkAspect() {
85 | return this == BLINK_YELLOW || this == BLINK_RED;
86 | }
87 |
88 | /**
89 | * Returns true if the aspect should appear off. The return value varies for
90 | * Blink states.
91 | *
92 | * @return true if appears off.
93 | */
94 | public boolean isOffState() {
95 | return this == OFF || (isBlinkAspect() && !isBlinkOn());
96 | }
97 |
98 | /**
99 | * Returns the SignalAspect that should be used during rendering.
100 | * This will vary for blinking SignalAspects based on the global blink state.
101 | *
102 | * @return the SignalAspect that should be rendered
103 | */
104 | public SignalAspect getDisplayAspect() {
105 | if (isOffState())
106 | return OFF;
107 | if (this == BLINK_YELLOW)
108 | return YELLOW;
109 | if (this == BLINK_RED)
110 | return RED;
111 | return this;
112 | }
113 |
114 | /**
115 | * Returns the level at which the Aspect emits light.
116 | */
117 | public int getLightValue() {
118 | return lightValue;
119 | }
120 |
121 | /**
122 | * Return true if the light is currently off.
123 | *
124 | * @return true if the light is currently off.
125 | */
126 | public static boolean isBlinkOn() {
127 | return blinkState;
128 | }
129 |
130 | /**
131 | * Don't call this, its used to change blink states by Railcraft.
132 | */
133 | public static void invertBlinkState() {
134 | blinkState = !blinkState;
135 | }
136 |
137 | /**
138 | * Takes an Ordinal and returns the corresponding SignalAspect.
139 | *
140 | * @param ordinal the ordinal
141 | * @return the Signal Aspect with the specified Ordinal
142 | */
143 | public static SignalAspect fromOrdinal(int ordinal) {
144 | if (ordinal < 0 || ordinal >= VALUES.length)
145 | return SignalAspect.RED;
146 | return VALUES[ordinal];
147 | }
148 |
149 | /**
150 | * Read an aspect from NBT.
151 | */
152 | public static SignalAspect readFromNBT(NBTTagCompound nbt, String tag) {
153 | if (nbt.hasKey(tag, 1))
154 | return fromOrdinal(nbt.getByte(tag));
155 | return RED;
156 | }
157 |
158 | /**
159 | * Write an aspect to NBT.
160 | */
161 | public void writeToNBT(NBTTagCompound nbt, String tag) {
162 | nbt.setByte(tag, (byte) ordinal());
163 | }
164 |
165 | /**
166 | * Tests two Aspects and determines which is more restrictive. The concept
167 | * of "most restrictive" refers to which aspect enforces the most
168 | * limitations of movement to a train.
169 | *
170 | * In Railcraft the primary use is in Signal Box logic.
171 | *
172 | * @param first aspect one
173 | * @param second aspect two
174 | * @return The most restrictive Aspect
175 | */
176 | public static SignalAspect mostRestrictive(@Nullable SignalAspect first, @Nullable SignalAspect second) {
177 | if (first == null && second == null)
178 | return RED;
179 | if (first == null)
180 | return second;
181 | if (second == null)
182 | return first;
183 | if (first.ordinal() > second.ordinal())
184 | return first;
185 | return second;
186 | }
187 |
188 | public String getLocalizationTag() {
189 | return localizationTag;
190 | }
191 |
192 | @Override
193 | public String toString() {
194 | String[] sa = name().split("_");
195 | StringBuilder out = new StringBuilder();
196 | for (String s : sa) {
197 | out.append(s, 0, 1).append(s.substring(1).toLowerCase(Locale.ENGLISH)).append(" ");
198 | }
199 | return out.toString().trim();
200 | }
201 |
202 | }
203 |
--------------------------------------------------------------------------------
/src/api/java/mods/railcraft/api/tracks/TrackType.java:
--------------------------------------------------------------------------------
1 | /*------------------------------------------------------------------------------
2 | Copyright (c) CovertJaguar, 2011-2020
3 |
4 | This work (the API) is licensed under the "MIT" License,
5 | see LICENSE.md for details.
6 | -----------------------------------------------------------------------------*/
7 |
8 | package mods.railcraft.api.tracks;
9 |
10 | import mods.railcraft.api.core.IIngredientSource;
11 | import mods.railcraft.api.core.ILocalizedObject;
12 | import net.minecraft.block.Block;
13 | import net.minecraft.block.BlockRailBase;
14 | import net.minecraft.block.state.IBlockState;
15 | import net.minecraft.entity.Entity;
16 | import net.minecraft.entity.item.EntityMinecart;
17 | import net.minecraft.init.Blocks;
18 | import net.minecraft.item.ItemStack;
19 | import net.minecraft.util.IStringSerializable;
20 | import net.minecraft.util.ResourceLocation;
21 | import net.minecraft.util.math.BlockPos;
22 | import net.minecraft.world.IBlockAccess;
23 | import net.minecraft.world.World;
24 | import net.minecraftforge.registries.IForgeRegistryEntry;
25 | import org.jetbrains.annotations.Nullable;
26 |
27 | /**
28 | * Created by CovertJaguar on 8/10/2016 for Railcraft.
29 | *
30 | * @author CovertJaguar
31 | */
32 | public class TrackType extends IForgeRegistryEntry.Impl implements IStringSerializable, ILocalizedObject {
33 | public static final String NBT_TAG = "rail";
34 |
35 | private final ResourceLocation baseBlock;
36 | private final IIngredientSource rail;
37 | private final IIngredientSource railbed;
38 | private final float resistance;
39 | private final boolean highSpeed;
40 | private final boolean electric;
41 | private final int maxSupportDistance;
42 | private final EventHandler eventHandler;
43 |
44 | public TrackType(ResourceLocation registryName, ResourceLocation baseBlock,
45 | IIngredientSource rail, IIngredientSource railbed,
46 | float resistance, boolean highSpeed, boolean electric, int maxSupportDistance,
47 | EventHandler eventHandler) {
48 | setRegistryName(registryName);
49 | this.baseBlock = baseBlock;
50 | this.rail = rail;
51 | this.railbed = railbed;
52 | this.resistance = resistance;
53 | this.highSpeed = highSpeed;
54 | this.electric = electric;
55 | this.maxSupportDistance = maxSupportDistance;
56 | this.eventHandler = eventHandler;
57 | }
58 |
59 | public IIngredientSource getRail() {
60 | return rail;
61 | }
62 |
63 | public IIngredientSource getRailbed() {
64 | return railbed;
65 | }
66 |
67 | public boolean isHighSpeed() {
68 | return highSpeed;
69 | }
70 |
71 | public boolean isElectric() {
72 | return electric;
73 | }
74 |
75 | @Override
76 | public final String getName() {
77 | return getRegistryName().toString().replaceAll("[.:]", "_");
78 | }
79 |
80 | @Override
81 | public String getLocalizationTag() {
82 | return "track_type.railcraft." + getName() + ".name";
83 | }
84 |
85 | public BlockRailBase getBaseBlock() {
86 | BlockRailBase block = (BlockRailBase) Block.getBlockFromName(baseBlock.toString());
87 | if (block == null)
88 | return (BlockRailBase) Blocks.RAIL;
89 | return block;
90 | }
91 |
92 | public ItemStack getFlexStack() {
93 | return getFlexStack(1);
94 | }
95 |
96 | public ItemStack getFlexStack(int qty) {
97 | return new ItemStack(getBaseBlock(), qty);
98 | }
99 |
100 | public final float getResistance() {
101 | return resistance;
102 | }
103 |
104 | public int getMaxSupportDistance() {
105 | return maxSupportDistance;
106 | }
107 |
108 | public EventHandler getEventHandler() {
109 | return eventHandler;
110 | }
111 |
112 | @Override
113 | public String toString() {
114 | return "TrackType{" + getName() + "}";
115 | }
116 |
117 | public static final class Builder {
118 | private final ResourceLocation registryName;
119 | private final ResourceLocation baseBlock;
120 | private final IIngredientSource rail;
121 | private final IIngredientSource railbed;
122 | private float resistance = 3.5F;
123 | private boolean highSpeed;
124 | private boolean electric;
125 | private int maxSupportDistance;
126 | private EventHandler eventHandler;
127 |
128 | public Builder(ResourceLocation registryName, ResourceLocation baseBlock, IIngredientSource rail, IIngredientSource railbed) {
129 | this.registryName = registryName;
130 | this.baseBlock = baseBlock;
131 | this.rail = rail;
132 | this.railbed = railbed;
133 | }
134 |
135 | public TrackType build() {
136 | if (eventHandler == null)
137 | eventHandler = new EventHandler();
138 | return new TrackType(registryName, baseBlock, rail, railbed,
139 | resistance, highSpeed, electric, maxSupportDistance, eventHandler);
140 | }
141 |
142 | public Builder setResistance(float resistance) {
143 | this.resistance = resistance;
144 | return this;
145 | }
146 |
147 | public Builder setHighSpeed(boolean highSpeed) {
148 | this.highSpeed = highSpeed;
149 | return this;
150 | }
151 |
152 | public Builder setElectric(boolean electric) {
153 | this.electric = electric;
154 | return this;
155 | }
156 |
157 | public Builder setMaxSupportDistance(int maxSupportDistance) {
158 | this.maxSupportDistance = maxSupportDistance;
159 | return this;
160 | }
161 |
162 | public Builder setEventHandler(EventHandler eventHandler) {
163 | this.eventHandler = eventHandler;
164 | return this;
165 | }
166 | }
167 |
168 | public static class EventHandler {
169 | public void onMinecartPass(World worldIn, EntityMinecart cart, BlockPos pos, @Nullable TrackKit trackKit) {
170 | }
171 |
172 | public @Nullable BlockRailBase.EnumRailDirection getRailDirectionOverride(IBlockAccess world, BlockPos pos, IBlockState state, @Nullable EntityMinecart cart) {
173 | return null;
174 | }
175 |
176 | public void onEntityCollision(World world, BlockPos pos, IBlockState state, Entity entity) {
177 | }
178 |
179 | public float getMaxSpeed(World world, @Nullable EntityMinecart cart, BlockPos pos) {
180 | return 0.4f;
181 | }
182 | }
183 | }
184 |
--------------------------------------------------------------------------------
/src/api/java/mods/railcraft/api/charge/IChargeBlock.java:
--------------------------------------------------------------------------------
1 | /*------------------------------------------------------------------------------
2 | Copyright (c) CovertJaguar, 2011-2020
3 |
4 | This work (the API) is licensed under the "MIT" License,
5 | see LICENSE.md for details.
6 | -----------------------------------------------------------------------------*/
7 |
8 | package mods.railcraft.api.charge;
9 |
10 | import com.google.common.base.Objects;
11 | import net.minecraft.block.state.IBlockState;
12 | import net.minecraft.util.math.BlockPos;
13 | import net.minecraft.world.IBlockAccess;
14 | import net.minecraft.world.World;
15 | import org.jetbrains.annotations.Nullable;
16 |
17 | import java.util.Collections;
18 | import java.util.EnumSet;
19 | import java.util.Map;
20 | import java.util.Random;
21 |
22 | /**
23 | * This interface must be implement by any {@link net.minecraft.block.Block}
24 | * that wants to interface with any of the charge networks.
25 | *
26 | * Created by CovertJaguar on 7/25/2016 for Railcraft.
27 | *
28 | * @author CovertJaguar
29 | */
30 | public interface IChargeBlock {
31 |
32 | /**
33 | * Asks the Block to provide a map of ChargeSpecs for each network.
34 | *
35 | * It is generally to be considered an error to return the same charge definition to multiple networks.
36 | * Most blocks will probably be members of the {@link Charge#distribution} network only.
37 | *
38 | * Only "transformer" blocks that pass charge from one network to another should respond to multiple networks.
39 | *
40 | * @return A mapping of networks to ChargeSpecs. Most blocks should only respond to one
41 | * type of network or an empty map. If an empty map is returned, the charge networks will ignore the block.
42 | */
43 | default Map getChargeSpecs(IBlockState state, IBlockAccess world, BlockPos pos) {
44 | return Collections.emptyMap();
45 | }
46 |
47 | /**
48 | * The Charge Meter calls this to get access for meter readings.
49 | *
50 | * Most blocks don't need to touch this, but Multi-blocks may want to redirect to the master block.
51 | */
52 | default @Nullable Charge.IAccess getMeterAccess(Charge network, IBlockState state, World world, BlockPos pos) {
53 | return network.network(world).access(pos);
54 | }
55 |
56 | /**
57 | * Helper method for registering a block to the networks.
58 | *
59 | * This function must be called from the following functions:
60 | * {@link net.minecraft.block.Block#onBlockAdded(World, BlockPos, IBlockState)}
61 | * {@link net.minecraft.block.Block#updateTick(World, BlockPos, IBlockState, Random)}
62 | *
63 | * The block must set {@link net.minecraft.block.Block#setTickRandomly(boolean)} to true in the constructor.
64 | */
65 | default void registerNode(IBlockState state, World world, BlockPos pos) {
66 | EnumSet.allOf(Charge.class).forEach(n -> n.network(world).addNode(pos, state));
67 | }
68 |
69 | /**
70 | * Helper method for removing a block from the networks.
71 | *
72 | * This function must be called from the following function:
73 | * {@link net.minecraft.block.Block#breakBlock(World, BlockPos, IBlockState)}
74 | */
75 | //FLATTENING make sure this not called during state changes
76 | default void deregisterNode(World world, BlockPos pos) {
77 | EnumSet.allOf(Charge.class).forEach(n -> n.network(world).removeNode(pos));
78 | }
79 |
80 | enum ConnectType {
81 | BLOCK, SLAB, TRACK, WIRE
82 | }
83 |
84 | /**
85 | * A ChargeSpec defines the electrical properties of the block.
86 | */
87 | final class ChargeSpec {
88 | private final ConnectType connectType;
89 | private final double losses;
90 | private final @Nullable IBatteryBlock.Spec batterySpec;
91 |
92 | /**
93 | * Helper method for ChargeSpec map construction.
94 | */
95 | public static Map make(Charge network, ConnectType connectType, double losses) {
96 | return Collections.singletonMap(network, new ChargeSpec(connectType, losses));
97 | }
98 |
99 | /**
100 | * Helper method for ChargeSpec map construction.
101 | */
102 | public static Map make(Charge network, ConnectType connectType, double losses, @Nullable IBatteryBlock.Spec batterySpec) {
103 | return Collections.singletonMap(network, new ChargeSpec(connectType, losses, batterySpec));
104 | }
105 |
106 | public ChargeSpec(ConnectType connectType, double losses) {
107 | this(connectType, losses, null);
108 | }
109 |
110 | /**
111 | * @param connectType This controls how our block will connect to other blocks.
112 | * Many blocks can only connect in specific ways due to block shape.
113 | * @param losses The cost of connecting this block to the charge network due to resistance losses, etc.
114 | * Transformers are typically 0.5. Batteries 0.2-0.3. Wires 0.025. Tracks 0.01.
115 | * Generators 0. Consumers 0.1.
116 | * @param batterySpec The battery specification for our block. Batteries are optional.
117 | */
118 | public ChargeSpec(ConnectType connectType, double losses, @Nullable IBatteryBlock.Spec batterySpec) {
119 | this.connectType = connectType;
120 | this.losses = losses;
121 | this.batterySpec = batterySpec;
122 | }
123 |
124 | public double getLosses() {
125 | return losses;
126 | }
127 |
128 | public @Nullable IBatteryBlock.Spec getBatterySpec() {
129 | return batterySpec;
130 | }
131 |
132 | public ConnectType getConnectType() {
133 | return connectType;
134 | }
135 |
136 | @Override
137 | public String toString() {
138 | String string = String.format("ChargeSpec{%s, losses=%.2f}", connectType, losses);
139 | if (batterySpec != null)
140 | string += "|" + batterySpec;
141 | return string;
142 | }
143 |
144 | @Override
145 | public boolean equals(Object o) {
146 | if (this == o) return true;
147 | if (o == null || getClass() != o.getClass()) return false;
148 | ChargeSpec that = (ChargeSpec) o;
149 | return Double.compare(that.losses, losses) == 0 &&
150 | connectType == that.connectType &&
151 | Objects.equal(batterySpec, that.batterySpec);
152 | }
153 |
154 | @Override
155 | public int hashCode() {
156 | return Objects.hashCode(connectType, losses, batterySpec);
157 | }
158 | }
159 |
160 | }
161 |
--------------------------------------------------------------------------------