2023-03-15 21:52:13 +00:00
|
|
|
// Copyright Daniel Ratcliffe, 2011-2022. This API may be redistributed unmodified and in full only.
|
|
|
|
//
|
|
|
|
// SPDX-License-Identifier: LicenseRef-CCPL
|
|
|
|
|
2017-05-01 13:32:39 +00:00
|
|
|
package dan200.computercraft.api.turtle;
|
|
|
|
|
|
|
|
import dan200.computercraft.api.peripheral.IPeripheral;
|
2022-12-03 15:02:00 +00:00
|
|
|
import dan200.computercraft.api.upgrades.UpgradeBase;
|
2024-01-31 20:55:14 +00:00
|
|
|
import dan200.computercraft.api.upgrades.UpgradeSerialiser;
|
|
|
|
import dan200.computercraft.impl.ComputerCraftAPIService;
|
2021-08-03 20:46:53 +00:00
|
|
|
import net.minecraft.core.Direction;
|
2024-01-31 20:55:14 +00:00
|
|
|
import net.minecraft.core.Registry;
|
2024-04-25 20:32:48 +00:00
|
|
|
import net.minecraft.core.component.DataComponentPatch;
|
2024-01-31 20:55:14 +00:00
|
|
|
import net.minecraft.resources.ResourceKey;
|
2017-05-01 13:32:39 +00:00
|
|
|
|
2017-05-06 23:07:42 +00:00
|
|
|
import javax.annotation.Nullable;
|
2017-05-01 13:32:39 +00:00
|
|
|
|
|
|
|
/**
|
Rewrite turtle upgrade registration to be more data driven (#967)
The feature nobody asked for, but we're getting anyway.
Old way to register a turtle/pocket computer upgrade:
ComputerCraftAPI.registerTurtleUpgrade(new MyUpgrade(new ResourceLocation("my_mod", "my_upgrade")));
New way to register a turtle/pocket computer upgrade:
First, define a serialiser for your turtle upgrade type:
static final DeferredRegister<TurtleUpgradeSerialiser<?>> SERIALISERS = DeferredRegister.create( TurtleUpgradeSerialiser.TYPE, "my_mod" );
public static final RegistryObject<TurtleUpgradeSerialiser<MyUpgrade>> MY_UPGRADE =
SERIALISERS.register( "my_upgrade", () -> TurtleUpgradeSerialiser.simple( MyUpgrade::new ) );
SERIALISERS.register(bus); // Call in your mod constructor.
Now either create a JSON string or use a data generator to register your upgrades:
class TurtleDataGenerator extends TurtleUpgradeDataProvider {
@Override
protected void addUpgrades( @Nonnull Consumer<Upgrade<TurtleUpgradeSerialiser<?>>> addUpgrade )
simple(new ResourceLocation("my_mod", my_upgrade"), MY_UPGRADE.get()).add(addUpgrade);
}
}
See much better! In all seriousness, this does offer some benefits,
namely that it's now possible to overwrite or create upgrades via
datapacks.
Actual changes:
- Remove ComputerCraftAPI.register{Turtle,Pocket}Upgrade functions.
- Instead add {Turtle,Pocket}UpgradeSerialiser classes, which are used
to load upgrades from JSON files in datapacks, and then read/write
them to network packets (much like recipe serialisers).
- The upgrade registries now subscribe to datapack reload events. They
find all JSON files in the
data/$mod_id/computercraft/{turtle,pocket}_upgrades directories,
parse them, and then register them as upgrades.
Once datapacks have fully reloaded, these upgrades are then sent over
the network to the client.
- Add data generators for turtle and pocket computer upgrades, to make
the creation of JSON files a bit easier.
- Port all of CC:T's upgrades over to use the new system.
2021-11-26 23:36:02 +00:00
|
|
|
* The primary interface for defining an update for Turtles. A turtle update can either be a new tool, or a new
|
|
|
|
* peripheral.
|
2022-10-25 21:36:21 +00:00
|
|
|
* <p>
|
Rewrite turtle upgrade registration to be more data driven (#967)
The feature nobody asked for, but we're getting anyway.
Old way to register a turtle/pocket computer upgrade:
ComputerCraftAPI.registerTurtleUpgrade(new MyUpgrade(new ResourceLocation("my_mod", "my_upgrade")));
New way to register a turtle/pocket computer upgrade:
First, define a serialiser for your turtle upgrade type:
static final DeferredRegister<TurtleUpgradeSerialiser<?>> SERIALISERS = DeferredRegister.create( TurtleUpgradeSerialiser.TYPE, "my_mod" );
public static final RegistryObject<TurtleUpgradeSerialiser<MyUpgrade>> MY_UPGRADE =
SERIALISERS.register( "my_upgrade", () -> TurtleUpgradeSerialiser.simple( MyUpgrade::new ) );
SERIALISERS.register(bus); // Call in your mod constructor.
Now either create a JSON string or use a data generator to register your upgrades:
class TurtleDataGenerator extends TurtleUpgradeDataProvider {
@Override
protected void addUpgrades( @Nonnull Consumer<Upgrade<TurtleUpgradeSerialiser<?>>> addUpgrade )
simple(new ResourceLocation("my_mod", my_upgrade"), MY_UPGRADE.get()).add(addUpgrade);
}
}
See much better! In all seriousness, this does offer some benefits,
namely that it's now possible to overwrite or create upgrades via
datapacks.
Actual changes:
- Remove ComputerCraftAPI.register{Turtle,Pocket}Upgrade functions.
- Instead add {Turtle,Pocket}UpgradeSerialiser classes, which are used
to load upgrades from JSON files in datapacks, and then read/write
them to network packets (much like recipe serialisers).
- The upgrade registries now subscribe to datapack reload events. They
find all JSON files in the
data/$mod_id/computercraft/{turtle,pocket}_upgrades directories,
parse them, and then register them as upgrades.
Once datapacks have fully reloaded, these upgrades are then sent over
the network to the client.
- Add data generators for turtle and pocket computer upgrades, to make
the creation of JSON files a bit easier.
- Port all of CC:T's upgrades over to use the new system.
2021-11-26 23:36:02 +00:00
|
|
|
* Turtle upgrades are defined in two stages. First, one creates a {@link ITurtleUpgrade} subclass and corresponding
|
2024-01-31 20:55:14 +00:00
|
|
|
* {@link UpgradeSerialiser} instance, which are then registered in a registry.
|
2022-10-25 21:36:21 +00:00
|
|
|
* <p>
|
Rewrite turtle upgrade registration to be more data driven (#967)
The feature nobody asked for, but we're getting anyway.
Old way to register a turtle/pocket computer upgrade:
ComputerCraftAPI.registerTurtleUpgrade(new MyUpgrade(new ResourceLocation("my_mod", "my_upgrade")));
New way to register a turtle/pocket computer upgrade:
First, define a serialiser for your turtle upgrade type:
static final DeferredRegister<TurtleUpgradeSerialiser<?>> SERIALISERS = DeferredRegister.create( TurtleUpgradeSerialiser.TYPE, "my_mod" );
public static final RegistryObject<TurtleUpgradeSerialiser<MyUpgrade>> MY_UPGRADE =
SERIALISERS.register( "my_upgrade", () -> TurtleUpgradeSerialiser.simple( MyUpgrade::new ) );
SERIALISERS.register(bus); // Call in your mod constructor.
Now either create a JSON string or use a data generator to register your upgrades:
class TurtleDataGenerator extends TurtleUpgradeDataProvider {
@Override
protected void addUpgrades( @Nonnull Consumer<Upgrade<TurtleUpgradeSerialiser<?>>> addUpgrade )
simple(new ResourceLocation("my_mod", my_upgrade"), MY_UPGRADE.get()).add(addUpgrade);
}
}
See much better! In all seriousness, this does offer some benefits,
namely that it's now possible to overwrite or create upgrades via
datapacks.
Actual changes:
- Remove ComputerCraftAPI.register{Turtle,Pocket}Upgrade functions.
- Instead add {Turtle,Pocket}UpgradeSerialiser classes, which are used
to load upgrades from JSON files in datapacks, and then read/write
them to network packets (much like recipe serialisers).
- The upgrade registries now subscribe to datapack reload events. They
find all JSON files in the
data/$mod_id/computercraft/{turtle,pocket}_upgrades directories,
parse them, and then register them as upgrades.
Once datapacks have fully reloaded, these upgrades are then sent over
the network to the client.
- Add data generators for turtle and pocket computer upgrades, to make
the creation of JSON files a bit easier.
- Port all of CC:T's upgrades over to use the new system.
2021-11-26 23:36:02 +00:00
|
|
|
* You then write a JSON file in your mod's {@literal data/} folder. This is then parsed when the world is loaded, and
|
2024-01-31 20:55:14 +00:00
|
|
|
* the upgrade automatically registered. It is recommended this is done via {@linkplain TurtleUpgradeDataProvider data
|
|
|
|
* generators}.
|
Rewrite turtle upgrade registration to be more data driven (#967)
The feature nobody asked for, but we're getting anyway.
Old way to register a turtle/pocket computer upgrade:
ComputerCraftAPI.registerTurtleUpgrade(new MyUpgrade(new ResourceLocation("my_mod", "my_upgrade")));
New way to register a turtle/pocket computer upgrade:
First, define a serialiser for your turtle upgrade type:
static final DeferredRegister<TurtleUpgradeSerialiser<?>> SERIALISERS = DeferredRegister.create( TurtleUpgradeSerialiser.TYPE, "my_mod" );
public static final RegistryObject<TurtleUpgradeSerialiser<MyUpgrade>> MY_UPGRADE =
SERIALISERS.register( "my_upgrade", () -> TurtleUpgradeSerialiser.simple( MyUpgrade::new ) );
SERIALISERS.register(bus); // Call in your mod constructor.
Now either create a JSON string or use a data generator to register your upgrades:
class TurtleDataGenerator extends TurtleUpgradeDataProvider {
@Override
protected void addUpgrades( @Nonnull Consumer<Upgrade<TurtleUpgradeSerialiser<?>>> addUpgrade )
simple(new ResourceLocation("my_mod", my_upgrade"), MY_UPGRADE.get()).add(addUpgrade);
}
}
See much better! In all seriousness, this does offer some benefits,
namely that it's now possible to overwrite or create upgrades via
datapacks.
Actual changes:
- Remove ComputerCraftAPI.register{Turtle,Pocket}Upgrade functions.
- Instead add {Turtle,Pocket}UpgradeSerialiser classes, which are used
to load upgrades from JSON files in datapacks, and then read/write
them to network packets (much like recipe serialisers).
- The upgrade registries now subscribe to datapack reload events. They
find all JSON files in the
data/$mod_id/computercraft/{turtle,pocket}_upgrades directories,
parse them, and then register them as upgrades.
Once datapacks have fully reloaded, these upgrades are then sent over
the network to the client.
- Add data generators for turtle and pocket computer upgrades, to make
the creation of JSON files a bit easier.
- Port all of CC:T's upgrades over to use the new system.
2021-11-26 23:36:02 +00:00
|
|
|
*
|
2024-01-31 20:55:14 +00:00
|
|
|
* <h2>Example</h2>
|
|
|
|
* <pre>{@code
|
|
|
|
* // We use Forge's DeferredRegister to register our serialiser. Fabric mods may register their serialiser directly.
|
|
|
|
* static final DeferredRegister<UpgradeSerialiser<? extends ITurtleUpgrade>> SERIALISERS = DeferredRegister.create(ITurtleUpgrade.serialiserRegistryKey(), "my_mod");
|
|
|
|
*
|
|
|
|
* // Register a new upgrade serialiser called "my_upgrade".
|
|
|
|
* public static final RegistryObject<UpgradeSerialiser<MyUpgrade>> MY_UPGRADE =
|
|
|
|
* SERIALISERS.register( "my_upgrade", () -> TurtleUpgradeSerialiser.simple( MyUpgrade::new ) );
|
|
|
|
*
|
|
|
|
* // Then in your constructor
|
|
|
|
* SERIALISERS.register( bus );
|
|
|
|
* }</pre>
|
|
|
|
* <p>
|
|
|
|
* We can then define a new upgrade using JSON by placing the following in
|
|
|
|
* {@literal data/<my_mod>/computercraft/turtle_upgrades/<my_upgrade_id>.json}}.
|
|
|
|
*
|
|
|
|
* <pre>{@code
|
|
|
|
* {
|
|
|
|
* "type": my_mod:my_upgrade",
|
|
|
|
* }
|
|
|
|
* }</pre>
|
|
|
|
* <p>
|
|
|
|
* {@link TurtleUpgradeDataProvider} provides a data provider to aid with generating these JSON files.
|
|
|
|
* <p>
|
|
|
|
* Finally, we need to register a model for our upgrade, see
|
|
|
|
* {@link dan200.computercraft.api.client.turtle.TurtleUpgradeModeller} for more information.
|
|
|
|
*
|
|
|
|
* <pre>{@code
|
|
|
|
* // Register our model inside FMLClientSetupEvent
|
|
|
|
* ComputerCraftAPIClient.registerTurtleUpgradeModeller(MY_UPGRADE.get(), TurtleUpgradeModeller.flatItem())
|
|
|
|
* }</pre>
|
2017-05-01 13:32:39 +00:00
|
|
|
*/
|
2022-12-03 15:02:00 +00:00
|
|
|
public interface ITurtleUpgrade extends UpgradeBase {
|
2024-01-31 20:55:14 +00:00
|
|
|
/**
|
|
|
|
* The registry key for upgrade serialisers.
|
|
|
|
*
|
|
|
|
* @return The registry key.
|
|
|
|
*/
|
|
|
|
static ResourceKey<Registry<UpgradeSerialiser<? extends ITurtleUpgrade>>> serialiserRegistryKey() {
|
|
|
|
return ComputerCraftAPIService.get().turtleUpgradeRegistryId();
|
|
|
|
}
|
|
|
|
|
2017-05-01 14:48:44 +00:00
|
|
|
/**
|
|
|
|
* Return whether this turtle adds a tool or a peripheral to the turtle.
|
2017-05-05 13:56:15 +00:00
|
|
|
*
|
2017-05-05 15:07:18 +00:00
|
|
|
* @return The type of upgrade this is.
|
|
|
|
* @see TurtleUpgradeType for the differences between them.
|
2017-05-05 13:56:15 +00:00
|
|
|
*/
|
2017-05-06 23:07:42 +00:00
|
|
|
TurtleUpgradeType getType();
|
2017-05-05 13:56:15 +00:00
|
|
|
|
2017-05-01 13:32:39 +00:00
|
|
|
/**
|
2017-05-05 13:56:15 +00:00
|
|
|
* Will only be called for peripheral upgrades. Creates a peripheral for a turtle being placed using this upgrade.
|
2022-10-25 18:17:55 +00:00
|
|
|
* <p>
|
2017-05-05 13:56:15 +00:00
|
|
|
* The peripheral created will be stored for the lifetime of the upgrade and will be passed as an argument to
|
|
|
|
* {@link #update(ITurtleAccess, TurtleSide)}. It will be attached, detached and have methods called in the same
|
|
|
|
* manner as a Computer peripheral.
|
2017-05-01 14:48:44 +00:00
|
|
|
*
|
2017-05-01 13:32:39 +00:00
|
|
|
* @param turtle Access to the turtle that the peripheral is being created for.
|
2017-05-05 13:56:15 +00:00
|
|
|
* @param side Which side of the turtle (left or right) that the upgrade resides on.
|
|
|
|
* @return The newly created peripheral. You may return {@code null} if this upgrade is a Tool
|
2017-05-01 14:48:44 +00:00
|
|
|
* and this method is not expected to be called.
|
2017-05-05 13:56:15 +00:00
|
|
|
*/
|
2017-05-06 23:07:42 +00:00
|
|
|
@Nullable
|
2022-11-06 15:50:24 +00:00
|
|
|
default IPeripheral createPeripheral(ITurtleAccess turtle, TurtleSide side) {
|
2018-12-17 21:33:49 +00:00
|
|
|
return null;
|
|
|
|
}
|
2017-05-01 13:32:39 +00:00
|
|
|
|
2017-05-01 14:48:44 +00:00
|
|
|
/**
|
|
|
|
* Will only be called for Tool turtle. Called when turtle.dig() or turtle.attack() is called
|
|
|
|
* by the turtle, and the tool is required to do some work.
|
2022-10-25 18:17:55 +00:00
|
|
|
* <p>
|
2022-11-06 15:07:13 +00:00
|
|
|
* Conforming implementations should fire loader-specific events when using the tool, for instance Forge's
|
|
|
|
* {@code AttackEntityEvent}.
|
2018-02-16 10:33:32 +00:00
|
|
|
*
|
2017-05-05 13:56:15 +00:00
|
|
|
* @param turtle Access to the turtle that the tool resides on.
|
|
|
|
* @param side Which side of the turtle (left or right) the tool resides on.
|
|
|
|
* @param verb Which action (dig or attack) the turtle is being called on to perform.
|
2017-05-01 14:48:44 +00:00
|
|
|
* @param direction Which world direction the action should be performed in, relative to the turtles
|
2017-05-05 13:56:15 +00:00
|
|
|
* position. This will either be up, down, or the direction the turtle is facing, depending on
|
|
|
|
* whether dig, digUp or digDown was called.
|
|
|
|
* @return Whether the turtle was able to perform the action, and hence whether the {@code turtle.dig()}
|
|
|
|
* or {@code turtle.attack()} lua method should return true. If true is returned, the tool will perform
|
|
|
|
* a swinging animation. You may return {@code null} if this turtle is a Peripheral and this method is not expected
|
|
|
|
* to be called.
|
2017-05-01 14:48:44 +00:00
|
|
|
*/
|
2022-11-06 15:50:24 +00:00
|
|
|
default TurtleCommandResult useTool(ITurtleAccess turtle, TurtleSide side, TurtleVerb verb, Direction direction) {
|
2018-12-17 21:33:49 +00:00
|
|
|
return TurtleCommandResult.failure();
|
|
|
|
}
|
2017-05-01 13:32:39 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Called once per tick for each turtle which has the upgrade equipped.
|
2017-05-05 13:56:15 +00:00
|
|
|
*
|
2017-05-01 13:32:39 +00:00
|
|
|
* @param turtle Access to the turtle that the upgrade resides on.
|
2017-05-05 13:56:15 +00:00
|
|
|
* @param side Which side of the turtle (left or right) the upgrade resides on.
|
2017-05-01 13:32:39 +00:00
|
|
|
*/
|
2022-11-06 15:50:24 +00:00
|
|
|
default void update(ITurtleAccess turtle, TurtleSide side) {
|
2017-06-12 20:08:35 +00:00
|
|
|
}
|
2023-07-02 09:55:55 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Get upgrade data that should be persisted when the turtle was broken.
|
|
|
|
* <p>
|
|
|
|
* This method should be overridden when you don't need to store all upgrade data by default. For instance, if you
|
|
|
|
* store peripheral state in the upgrade data, which should be lost when the turtle is broken.
|
|
|
|
*
|
|
|
|
* @param upgradeData Data that currently stored for this upgrade
|
|
|
|
* @return Filtered version of this data.
|
|
|
|
*/
|
2024-04-25 20:32:48 +00:00
|
|
|
default DataComponentPatch getPersistedData(DataComponentPatch upgradeData) {
|
2023-07-02 09:55:55 +00:00
|
|
|
return upgradeData;
|
|
|
|
}
|
2017-05-01 13:32:39 +00:00
|
|
|
}
|