Skip to content

Commit

Permalink
Update to 1.21.2 (#178)
Browse files Browse the repository at this point in the history
Co-authored-by: IchHabeHunger54 <[email protected]>
Co-authored-by: Dennis C <[email protected]>
  • Loading branch information
3 people authored Nov 15, 2024
1 parent 94bccc3 commit 6130eef
Show file tree
Hide file tree
Showing 158 changed files with 19,514 additions and 2,563 deletions.
4 changes: 2 additions & 2 deletions docs/advanced/_category_.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"label": "Advanced Topics",
"position": 12
"label": "Advanced Topics",
"position": 12
}
18 changes: 9 additions & 9 deletions docs/advanced/accesstransformers.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ Access Transformers need to be declared in `build.gradle`. AT files can be speci
// In build.gradle:
// This block is where your mappings version is also specified
minecraft {
accessTransformers {
file('src/main/resources/META-INF/accesstransformer.cfg')
}
accessTransformers {
file('src/main/resources/META-INF/accesstransformer.cfg')
}
}
```

Expand All @@ -35,10 +35,10 @@ Additionally, multiple AT files can be specified and will be applied in order. T
```groovy
// In build.gradle:
minecraft {
accessTransformers {
file('src/main/resources/accesstransformer_main.cfg')
file('src/additions/resources/accesstransformer_additions.cfg')
}
accessTransformers {
file('src/main/resources/accesstransformer_main.cfg')
file('src/additions/resources/accesstransformer_additions.cfg')
}
}
```

Expand Down Expand Up @@ -135,8 +135,8 @@ public net.minecraft.util.Crypt$ByteArrayToKeyFunction
protected-f net.minecraft.server.MinecraftServer random
# Makes public the 'makeExecutor' method in Util,
# accepting a String and returns an ExecutorService
public net.minecraft.Util makeExecutor(Ljava/lang/String;)Ljava/util/concurrent/ExecutorService;
# accepting a String and returns a TracingExecutor
public net.minecraft.Util makeExecutor(Ljava/lang/String;)Lnet/minecraft/TracingExecutor;
# Makes public the 'leastMostToIntArray' method in UUIDUtil,
# accepting two longs and returning an int[]
Expand Down
5 changes: 2 additions & 3 deletions docs/advanced/extensibleenums.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,9 +88,9 @@ The parameters can be specified in three ways with limitations depending on the

- Inline in the JSON file as an array of constants (only allowed for primitive values, Strings and for passing null to any reference type)
- As a reference to a field of type `EnumProxy<TheEnum>` in a class from the mod (see `EnumProxy` example above)
- The first parameter specifies the target enum and the subsequent parameters are the ones to be passed to the enum constructor
- The first parameter specifies the target enum and the subsequent parameters are the ones to be passed to the enum constructor
- As a reference to a method returning `Object`, where the return value is the parameter value to use. The method must have exactly two parameters of type `int` (index of the parameter) and `Class<?>` (expected type of the parameter)
- The `Class<?>` object should be used to cast (`Class#cast()`) the return value in order to keep `ClassCastException`s in mod code.
- The `Class<?>` object should be used to cast (`Class#cast()`) the return value in order to keep `ClassCastException`s in mod code.

:::warning
The fields and/or methods used as sources for parameter values should be in a separate class to avoid unintentionally loading mod classes too early.
Expand All @@ -117,7 +117,6 @@ Further action is required depending on specific details about the enum:
- If the enum has an int ID parameter which should match the entry's ordinal, then the enum should be annotated with `@NumberedEnum` with the ID's parameter index as the annotation's value if it's not the first parameter
- If the enum has a String name parameter which is used for serialization and should therefore be namespaced, then the enum should be annotated with `@NamedEnum` with the name's parameter index as the annotation's value if it's not the first parameter
- If the enum is sent over the network, then it should be annotated with `@NetworkedEnum` with the annotation's parameter specifying in which direction the values may be sent (clientbound, serverbound or bidirectional)
- Warning: networked enums will require additional steps once network checks for enums are implemented in NeoForge
- If the enum has constructors which are not usable by mods (i.e. because they require registry objects on an enum that may be initialized before modded registration runs), then they should be annotated with `@ReservedConstructor`

:::note
Expand Down
4 changes: 2 additions & 2 deletions docs/blockentities/_category_.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"label": "Block Entities",
"position": 6
"label": "Block Entities",
"position": 6
}
10 changes: 10 additions & 0 deletions docs/blockentities/ber.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,16 @@ public static void registerClientExtensions(RegisterClientExtensionsEvent event)
`IClientItemExtensions` are generally expected to be treated as singletons. Do not construct them outside `RegisterClientExtensionsEvent`!
:::
Finally, the item has to know that it should use the BEWLR for its rendering. This is done by having the final [`BakedModel`][bakedmodel] return true for `#isCustomRenderer`. The easiest way to do this is to have the [item model JSON][model] with a `parent` of `minecraft:builtin/entity`:
```json5
// In some item model file assets/<mod_id>/models/item/<registry_name>.json
{
"parent": "minecraft: builtin/entity",
// ...
}
```
[block]: ../blocks/index.md
[blockentity]: index.md
[event]: ../concepts/events.md#registering-an-event-handler
Expand Down
4 changes: 2 additions & 2 deletions docs/blockentities/container.md
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ public class MyBackpackContainer extends SimpleContainer {
And voilà, you have created an item-backed container! Call `new MyBackpackContainer(stack)` to create a container for a menu or other use case.

:::warning
Be aware that `Menu`s that directly interface with `Container`s must `#copy()` their `ItemStack`s when modifying them, as otherwise the immutability contract on data components is broken. To do this, NeoForge provides the `StackCopySlot` class for you.
Be aware that menus that directly interface with `Container`s must `#copy()` their `ItemStack`s when modifying them, as otherwise the immutability contract on data components is broken. To do this, NeoForge provides the `StackCopySlot` class for you.
:::

## `Container`s on `Entity`s
Expand Down Expand Up @@ -306,7 +306,7 @@ When iterating over the inventory contents, it is recommended to iterate over `i
[block]: ../blocks/index.md
[blockentity]: index.md
[component]: ../resources/client/i18n.md#components
[datacomponent]: ../items/datacomponents.mdx
[datacomponent]: ../items/datacomponents.md
[item]: ../items/index.md
[itemstack]: ../items/index.md#itemstacks
[menu]: ../gui/menus.md
18 changes: 11 additions & 7 deletions docs/blockentities/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,27 +22,29 @@ public class MyBlockEntity extends BlockEntity {

As you may have noticed, we pass an undefined variable `type` to the super constructor. Let's leave that undefined variable there for a moment and instead move to registration.

Registration happens in a similar fashion to entities. We create an instance of the associated singleton class `BlockEntityType<?>` and register it to the block entity type registry, like so:
[Registration][registration] happens in a similar fashion to entities. We create an instance of the associated singleton class `BlockEntityType<?>` and register it to the block entity type registry, like so:

```java
public static final DeferredRegister<BlockEntityType<?>> BLOCK_ENTITY_TYPES =
DeferredRegister.create(Registries.BLOCK_ENTITY_TYPE, ExampleMod.MOD_ID);

public static final Supplier<BlockEntityType<MyBlockEntity>> MY_BLOCK_ENTITY = BLOCK_ENTITY_TYPES.register(
"my_block_entity",
// The block entity type, created using a builder.
() -> BlockEntityType.Builder.of(
// The block entity type.
() -> new BlockEntityType<>(
// The supplier to use for constructing the block entity instances.
MyBlockEntity::new,
// A vararg of blocks that can have this block entity.
// This assumes the existence of the referenced blocks as DeferredBlock<Block>s.
MyBlocks.MY_BLOCK_1.get(), MyBlocks.MY_BLOCK_2.get()
)
// Build using null; vanilla does some datafixer shenanigans with the parameter that we don't need.
.build(null)
);
```

:::note
Remember that the `DeferredRegister` must be registered to the [mod event bus][modbus]!
:::

Now that we have our block entity type, we can use it in place of the `type` variable we left earlier:

```java
Expand All @@ -54,7 +56,7 @@ public class MyBlockEntity extends BlockEntity {
```

:::info
The reason for this rather confusing setup process is that `BlockEntityType.Builder#of` expects a `BlockEntityType.BlockEntitySupplier<T extends BlockEntity>`, which is basically a `BiFunction<BlockPos, BlockState, T extends BlockEntity>`. As such, having a constructor we can directly reference using `::new` is highly beneficial. However, we also need to provide the constructed block entity type to the default and only constructor of `BlockEntity`, so we need to pass references around a bit.
The reason for this rather confusing setup process is that `BlockEntityType` expects a `BlockEntityType.BlockEntitySupplier<T extends BlockEntity>`, which is basically a `BiFunction<BlockPos, BlockState, T extends BlockEntity>`. As such, having a constructor we can directly reference using `::new` is highly beneficial. However, we also need to provide the constructed block entity type to the default and only constructor of `BlockEntity`, so we need to pass references around a bit.
:::

Finally, we need to modify the block class associated with the block entity. This means that we will not be able to attach block entities to simple instances of `Block`, instead, we need a subclass:
Expand All @@ -75,7 +77,7 @@ public class MyEntityBlock extends Block implements EntityBlock {
}
```

And then, you of course need to use this class as the type in your block registration:
And then, you of course need to use this class as the type in your [block registration][blockreg]:

```java
public static final DeferredBlock<MyEntityBlock> MY_BLOCK_1 =
Expand Down Expand Up @@ -232,8 +234,10 @@ It is important that you do safety checks, as the `BlockEntity` might already be
:::

[block]: ../blocks/index.md
[blockreg]: ../blocks/index.md#basic-blocks
[blockstate]: ../blocks/states.md
[dataattachments]: ../datastorage/attachments.md
[modbus]: ../concepts/events.md#event-buses
[nbt]: ../datastorage/nbt.md
[networking]: ../networking/index.md
[registration]: ../concepts/registries.md#methods-for-registering
Expand Down
4 changes: 2 additions & 2 deletions docs/blocks/_category_.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"label": "Blocks",
"position": 3
"label": "Blocks",
"position": 3
}
29 changes: 20 additions & 9 deletions docs/blocks/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ So now, let's register our blocks:

```java
//BLOCKS is a DeferredRegister.Blocks
public static final DeferredBlock<Block> MY_BLOCK = BLOCKS.register("my_block", () -> new Block(...));
public static final DeferredBlock<Block> MY_BLOCK = BLOCKS.register("my_block", registryName -> new Block(...));
```

After registering the block, all references to the new `my_block` should use this constant. For example, if you want to check if the block at a given position is `my_block`, the code for that would look something like this:
Expand Down Expand Up @@ -51,6 +51,8 @@ public static final DeferredRegister.Blocks BLOCKS = DeferredRegister.createBloc

For simple blocks which need no special functionality (think cobblestone, wooden planks, etc.), the `Block` class can be used directly. To do so, during registration, instantiate `Block` with a `BlockBehaviour.Properties` parameter. This `BlockBehaviour.Properties` parameter can be created using `BlockBehaviour.Properties#of`, and it can be customized by calling its methods. The most important methods for this are:

- `setId` - Sets the resource key of the block.
- This **must** be set on every block; otherwise, an exception will be thrown.
- `destroyTime` - Determines the time the block needs to be destroyed.
- Stone has a destroy time of 1.5, dirt has 0.5, obsidian has 50, and bedrock has -1 (unbreakable).
- `explosionResistance` - Determines the explosion resistance of the block.
Expand All @@ -68,8 +70,9 @@ So for example, a simple implementation would look something like this:
//BLOCKS is a DeferredRegister.Blocks
public static final DeferredBlock<Block> MY_BETTER_BLOCK = BLOCKS.register(
"my_better_block",
() -> new Block(BlockBehaviour.Properties.of()
registryName -> new Block(BlockBehaviour.Properties.of()
//highlight-start
.setId(ResourceKey.create(Registries.BLOCK, registryName))
.destroyTime(2.0f)
.explosionResistance(10.0f)
.sound(SoundType.GRAVEL)
Expand Down Expand Up @@ -108,14 +111,14 @@ public class SimpleBlock extends Block {

@Override
public MapCodec<SimpleBlock> codec() {
return SIMPLE_CODEC.value();
return SIMPLE_CODEC.get();
}
}

// In some registration class
public static final DeferredRegister<MapCodec<? extends Block>> REGISTRAR = DeferredRegister.create(BuiltInRegistries.BLOCK_TYPE, "yourmodid");

public static final DeferredHolder<MapCodec<? extends Block>, MapCodec<SimpleBlock>> SIMPLE_CODEC = REGISTRAR.register(
public static final Supplier<MapCodec<SimpleBlock>> SIMPLE_CODEC = REGISTRAR.register(
"simple",
() -> simpleCodec(SimpleBlock::new)
);
Expand All @@ -133,7 +136,7 @@ public class ComplexBlock extends Block {

@Override
public MapCodec<ComplexBlock> codec() {
return COMPLEX_CODEC.value();
return COMPLEX_CODEC.get();
}

public int getValue() {
Expand All @@ -144,14 +147,14 @@ public class ComplexBlock extends Block {
// In some registration class
public static final DeferredRegister<MapCodec<? extends Block>> REGISTRAR = DeferredRegister.create(BuiltInRegistries.BLOCK_TYPE, "yourmodid");

public static final DeferredHolder<MapCodec<? extends Block>, MapCodec<ComplexBlock>> COMPLEX_CODEC = REGISTRAR.register(
public static final Supplier<MapCodec<ComplexBlock>> COMPLEX_CODEC = REGISTRAR.register(
"simple",
() -> RecordCodecBuilder.mapCodec(instance ->
instance.group(
Codec.INT.fieldOf("value").forGetter(ComplexBlock::getValue),
BlockBehaviour.propertiesCodec() // represents the BlockBehavior.Properties parameter
).apply(instance, ComplexBlock::new)
);
)
);
```

Expand All @@ -166,15 +169,23 @@ We already discussed how to create a `DeferredRegister.Blocks` [above], as well
```java
public static final DeferredRegister.Blocks BLOCKS = DeferredRegister.createBlocks("yourmodid");

public static final DeferredBlock<Block> EXAMPLE_BLOCK = BLOCKS.register(
"example_block", registryName -> new Block(
BlockBehaviour.Properties.of()
// The ID must be set on the block
.setId(ResourceKey.create(Registries.BLOCK, registryName))
)
);

// Same as above, except that the block properties are constructed eagerly.
// setId is also called internally on the properties object.
public static final DeferredBlock<Block> EXAMPLE_BLOCK = BLOCKS.registerBlock(
"example_block",
Block::new, // The factory that the properties will be passed into.
BlockBehaviour.Properties.of() // The properties to use.
);
```

Internally, this will simply call `BLOCKS.register("example_block", () -> new Block(BlockBehaviour.Properties.of()))` by applying the properties parameter to the provided block factory (which is commonly the constructor).

If you want to use `Block::new`, you can leave out the factory entirely:

```java
Expand Down
11 changes: 4 additions & 7 deletions docs/blocks/states.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,6 @@ To implement a blockstate property, in your block class, create or reference a `
- Implements `Property<E>`. Defines a property that can take on the values of an Enum class.
- Created by calling `EnumProperty#create(String propertyName, Class<E> enumClass)`.
- It is also possible to use only a subset of the Enum values (e.g. 4 out of 16 `DyeColor`s), see the overloads of `EnumProperty#create`.
- `DirectionProperty`
- Extends `EnumProperty<Direction>`. Defines a property that can take on a `Direction`.
- Created by calling `DirectionProperty#create(String propertyName)`.
- Several convenience predicates are provided. For example, to get a property that represents the cardinal directions, call `DirectionProperty.create("<name>", Direction.Plane.HORIZONTAL)`; to get the X directions, `DirectionProperty.create("<name>", Direction.Axis.X)`.

The class `BlockStateProperties` contains shared vanilla properties which should be used or referenced whenever possible, in place of creating your own properties.

Expand All @@ -72,7 +68,7 @@ To further illustrate this, this is what the relevant bits of the `EndPortalFram
public class EndPortalFrameBlock extends Block {
// Note: It is possible to directly use the values in BlockStateProperties instead of referencing them here again.
// However, for the sake of simplicity and readability, it is recommended to add constants like this.
public static final DirectionProperty FACING = BlockStateProperties.FACING;
public static final EnumProperty<Direction> FACING = BlockStateProperties.FACING;
public static final BooleanProperty EYE = BlockStateProperties.EYE;

public EndPortalFrameBlock(BlockBehaviour.Properties pProperties) {
Expand Down Expand Up @@ -107,7 +103,7 @@ To go from `Block` to `BlockState`, call `Block#defaultBlockState()`. The defaul
You can get the value of a property by calling `BlockState#getValue(Property<?>)`, passing it the property you want to get the value of. Reusing our end portal frame example, this would look something like this:

```java
// EndPortalFrameBlock.FACING is a DirectionProperty and thus can be used to obtain a Direction from the BlockState
// EndPortalFrameBlock.FACING is an EnumPropery<Direction> and thus can be used to obtain a Direction from the BlockState
Direction direction = endPortalFrameBlockState.getValue(EndPortalFrameBlock.FACING);
```

Expand Down Expand Up @@ -138,9 +134,10 @@ To help setting the update flags correctly, there are a number of `int` constant
- `Block.UPDATE_KNOWN_SHAPE` stops neighbor update recursion.
- `Block.UPDATE_SUPPRESS_DROPS` disables block drops for the old block at that position.
- `Block.UPDATE_MOVE_BY_PISTON` is only used by piston code to signal that the block was moved by a piston. This is mainly responsible for delaying light engine updates.
- `Block.UPDATE_SKIP_SHAPE_UPDATE_ON_WIRE` is used by the `ExperimentalRedstoneWireEvaluator` to signal if the shape should be skipped. This is set only when the power strength is changed from not a placement or that the original source on the signal is not the current wire.
- `Block.UPDATE_ALL` is an alias for `Block.UPDATE_NEIGHBORS | Block.UPDATE_CLIENTS`.
- `Block.UPDATE_ALL_IMMEDIATE` is an alias for `Block.UPDATE_NEIGHBORS | Block.UPDATE_CLIENTS | Block.UPDATE_IMMEDIATE`.
- `Block.NONE` is an alias for `Block.UPDATE_INVISIBLE`.
- `Block.UPDATE_NONE` is an alias for `Block.UPDATE_INVISIBLE`.

There is also a convenience method `Level#setBlockAndUpdate(BlockPos pos, BlockState state)` that calls `setBlock(pos, state, Block.UPDATE_ALL)` internally.

Expand Down
4 changes: 2 additions & 2 deletions docs/concepts/_category_.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"label": "Concepts",
"position": 2
"label": "Concepts",
"position": 2
}
Loading

0 comments on commit 6130eef

Please sign in to comment.