fully renamed original to ReFramed and removed some api stuffs and cleanups

This commit is contained in:
Adrien1106 2024-02-14 19:51:08 +01:00
parent f0195a80f9
commit d0e22d21d4
164 changed files with 1069 additions and 1629 deletions

136
README.md
View File

@ -1,136 +0,0 @@
<img src="icon.png" align="right" width="180px"/>
# Templates 2
[>> Downloads <<](https://modrinth.com/mod/templates-2)
*Slopes?*
**This mod is open source and under a permissive license.** As such, it can be included in any modpack on any platform without prior permission. I appreciate hearing about people using my mods, but you do not need to ask to use them. See the [LICENSE file](LICENSE) for more details.[^1]
If a Template block is placed in the world and right-clicked with a full-size block, it will take on the appearance of that block, including whether it emits light and redstone. Adding a *redstone torch* will make them emit redstone power, *glowstone dust* will make them emit light, and *popped chorus fruit* will make them intangible.
While Templates itself adds a handful of common shapes, it's not too hard for other mods to interface with Templates and add their own templatable blocks.
# For addon developers
## Creating a block entity
All templates need a block entity to store what block they look like. Templates registers one under `templates:slope`[^2], but as an addon developer you can't add additional blocks to my block entity. (Don't try, please.)
To that end, nothing in Templates relies on the *specific* block entity ID, so just re-register the `TemplateEntity` class under your own name. You are free to extend `TemplateEntity` as well.
The only hard requirement on the block entity is that it `implements ThemeableBlockEntity`. (This implies it returns a `BlockEntity` from `getRenderAttachmentData`.)
## Creating your block
There are various block interactions in Templates, like adding redstone to make the block emit power. To make your block fit with the other Templates, you'll want those behaviors to apply to your block as well. There's a couple options, depending on the complexity of the block you'd like to "template-ify".
If you simply registered a `Block` or a simple vanilla class like `WallBlock`, use the corresponding class in `io.github.cottonmc.templates.block`.
If you registered something different (like a `MyFancyBlock`), the simplest approach is to leverage `TemplateInteractionUtil`, which is where all of the interaction code lives in a mildly "pluggable" form. Here are the suggested steps:
* Create a `TemplateMyFancyBlock` class that extends your block class.
* Copy-paste the body of `TemplateBlock` into it; adjust the constructor as needed. (It was designed to be copy-pasted in this way; this is how i filled out most of the other classes.)
* Make sure it instantiates your block entity type.
* Check that the methods are implemented the way you'd like.
* Particularly you might want to look at the redstone emission methods; the default ones don't call `super`.
And if all else fails, just reimplement whatever interactions you'd like, or simply don't bother. None of this is important for the actual *retexturing* part of the mod, apart from returning a suitable block entity.
## Creating the custom model
(TL;DR look at `assets/templates/blockstates` and the bottom of `TemplatesClient`)
Of course Templates leverages custom baked models. All of Templates's baked model implementations find and retexture quads from an upstream source that you will need to provide.
Templates needs three pieces of information to perform retexturing:
* the quad to be retextured
* whether you actually want to retexture it or just pass it through unchanged (see the Lever Template, which doesn't change the lever arm);
* what face of the block it corresponds to (which is sometimes different from "the direction it points" - see the Door Template, the textures "stick" when you open the door)
The last piece of information is important because Templates tries hard to retain the orientation of blocks placed inside of them - you can place specifically an *east-facing* log into a Template, for example, and some faces get the cut wood while other faces get the bark. (Some other mods just use the same texture on all faces of the block, like the particle texture.)
Pick a model implementation that suits your needs:
### Auto retexturing
* the quad: Sourced from a JSON model.
* whether you want to retexture it: "Yes". All quads will be retextured.
* what face of the block: Automatically determined by facing direction.
Construct with `TemplatesClientApi.getInstance().auto`. Pass the ID of the model you want to source quads from.
There's no way to configure this, so if you want to skip retexturing a face, try the next model implementation instead.
**TODO**: this does not work well with `multipart` models with differently-rotated parts, like the fence model (consisting of 1 fence post and 1 fence-side model that gets rotated around to fill all 4 sides)
### Special texture-based retexturing
* the quad: Sourced from a JSON model.
* whether you want to retexture it: Determined from the texture applied to the quad.
* what face of the block: Determined via the texture applied to the quad.
Construct with `TemplatesClientApi.getInstance().json`. Pass the ID of the model you want to source quads from. All quads textured with the *special textures* `templates:templates_special/east` will be textured with the east side of the theme, all quads textured with `templates:templates_special/up` will be retextured with the top side of the theme, etc. Quads textured with any other texture will be passed through unaltered.
<details><summary>Regarding texture variables:</summary>
On the off-chance your blockmodel already has texture variables for `north`, `south`, etc, you can simply apply Templates's special textures to it:
```json
{
"parent": "mymod:block/my_model",
"textures": {
"north": "templates:templates_special/north",
"east": "templates:templates_special/east",
"south": "templates:templates_special/south",
"west": "templates:templates_special/west",
"up": "templates:templates_special/up",
"down": "templates:templates_special/down",
}
}
```
Sadly, many models don't specify *completely* separate textures for all six sides. If you have a setup like an "ends" variable which gets applied to "the top and bottom" or something, please don't use the texture-variables approach. Instead, see if the `UnbakedAutoRetexturedModel` suits your needs, or make a second copy of the json model that does separately fill in all faces.
</details>
(This one works better with multipart models.)
### Mesh retexturing
* the quad: Sourced from a `Mesh`.
* whether you want to retexture it: Quads with a nonzero `tag`.
* what face of the block: Determined from the `tag`.
Construct with `TemplatesClientApi.getInstance().mesh`, passing a `Supplier<Mesh>`. To mark a face "retexture this with the EAST side of the block", call `.tag(Direction.EAST.ordinal() + 1)` on it; same for the other directions. (So, the valid tags are 1, 2, 3, 4, 5, and 6, corresponding to down, up, north, south, west, east.) Give these faces UV coordinates ranging from 0 to 1.
A `.tag` of 0 (the default) will be passed through unchanged. This is a little useless since you still need to provide UV coordinates, so instead of passing a `Supplier<Mesh>` you can also pass a `Function<Function<SpriteIdentifier, Sprite>, Mesh>`; you will be provided with a `Function<SpriteIdentifier, Sprite>` that you can query for sprite information, including their UVs.
(To construct this type, you will also need to pass the identifier of a "base model", which can be a regular JSON model. Miscellaneous `BakedModel` properties like rotations, AO, `isSideLit`, etc will be sourced from it. See Template's `models/block/slope_base`. You may need to set `"gui_light": "front"` to avoid a flat look in the ui.)
### A secret, fourth thing
Templates doesn't actually care about the implementation of the UnbakedModel you pass in. It won't *work* unless you reimplement the retexturing, but if you have your needs I won't stop you.
All the models are supposed to be extensible (if i left a stray `private` let me know). All the `UnbakedModels` are backed by the same abstract class called `RetexturingBakedModel` which actually does the retexturing; feel free to extend it.
## Registering your model
After you've decided on and constructed your special model, you should tell Templates about it. Pick an ID that's different from the base model. (If your base model is `mymod:block/awesome_template`, a good name might be `mymod:awesome_template_special`). Register your special model under that ID using `TemplatesClientApi.getInstance().addTemplateModel`.
To assign the block model, using a vanilla blockstate file, simply point your block at that model ID as normal. (See this mod's `blockstates` folder.) You may also use the `x`, `y`, and `uvlock` properties.
To assign the item model, since items don't have the "blockstate file" level of indirection, call `TemplatesClientApi.getInstance().assignItemModel`, passing your special model's ID and the items it should be assigned to. Or if you'd rather use a vanilla json model (that won't be retextured) just make one the vanilla way.
# Most important attribution in the whole wide world
COOL RIVULET is by mev, this is the most important block in the mod & perhaps the most important block in any mod ever since `incorporeal:clearly`
# License
MIT, which is unusual for me (usually i write LGPL). It's the upstream project's license.
[^1]: This is inherited from a [CottonMC project](https://github.com/CottonMC/Templates), which inherited [the ElytraDev template](https://github.com/elytra/Concrete), which might explain if the readme layout looks familiar.
[^2]: Yes, even the blocks other than slopes use `templates:slope`. The slope was the first block added to Templates and I forgot to change the block entity ID, and now I can't change it without breaking worlds. At least it demonstrates how the block entity can be used for more than one template?

View File

@ -10,8 +10,8 @@ loader_version=0.15.6
# Mod Properties
mod_version = 1.0-SNAPSHOT
maven_group = fr.adrien1106
archives_base_name = ReFramedTemplates
mod_id = reframedtemplates
archives_base_name = ReFramed
mod_id = reframed
# Dependencies
# check this on https://modmuss50.me/fabric.html

BIN
icon.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

View File

@ -0,0 +1,92 @@
package fr.adrien1106.reframed;
import fr.adrien1106.reframed.util.ReFramedInteractionUtil;
import fr.adrien1106.reframed.block.*;
import net.fabricmc.api.ModInitializer;
import net.fabricmc.fabric.api.itemgroup.v1.FabricItemGroup;
import net.fabricmc.fabric.api.object.builder.v1.block.entity.FabricBlockEntityTypeBuilder;
import net.minecraft.block.AbstractBlock;
import net.minecraft.block.Block;
import net.minecraft.block.BlockSetType;
import net.minecraft.block.Blocks;
import net.minecraft.block.entity.BlockEntityType;
import net.minecraft.item.BlockItem;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.registry.Registries;
import net.minecraft.registry.Registry;
import net.minecraft.text.Text;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import java.util.ArrayList;
import java.util.function.BiConsumer;
import java.util.stream.Collectors;
/**
* TODO handle grass side, multiple camos
*/
public class ReFramed implements ModInitializer {
public static final String MODID = "reframed";
public static final ArrayList<Block> BLOCKS = new ArrayList<>();
public static Block CUBE, STAIRS, SLAB, POST, FENCE, FENCE_GATE, DOOR, TRAPDOOR, IRON_DOOR, IRON_TRAPDOOR, PRESSURE_PLATE, BUTTON, LEVER, WALL, CARPET, PANE, CANDLE;
public static BlockEntityType<ReFramedEntity> REFRAMED_BLOCK_ENTITY;
public static BiConsumer<World, BlockPos> chunkRerenderProxy = (world, pos) -> {};
@Override
public void onInitialize() {
//registerReFramed mutates FRAMES as a side effect, which is a List, so order is preserved
//the ordering is used in the creative tab, so they're roughly sorted by encounter order of the
//corresponding vanilla block in the "search" creative tab... with the non-vanilla "post" and
//"vertical slab" inserted where they fit ...and i moved the lever way up next to the pressureplate
//and button, because they're redstoney... hopefully this ordering makes sense lol
CUBE = registerReFramed("cube" , new ReFramedBlock(ReFramedInteractionUtil.makeSettings()));
STAIRS = registerReFramed("stairs" , new ReFramedStairsBlock(cp(Blocks.OAK_STAIRS)));
SLAB = registerReFramed("slab" , new ReFramedSlabBlock(cp(Blocks.OAK_SLAB)));
POST = registerReFramed("post" , new ReFramedPostBlock(cp(Blocks.OAK_FENCE)));
FENCE = registerReFramed("fence" , new ReFramedFenceBlock(cp(Blocks.OAK_FENCE)));
FENCE_GATE = registerReFramed("fence_gate" , new ReFramedFenceGateBlock(cp(Blocks.OAK_FENCE_GATE)));
DOOR = registerReFramed("door" , new ReFramedDoorBlock(cp(Blocks.OAK_DOOR), BlockSetType.OAK));
TRAPDOOR = registerReFramed("trapdoor" , new ReFramedTrapdoorBlock(cp(Blocks.OAK_TRAPDOOR), BlockSetType.OAK));
IRON_DOOR = registerReFramed("iron_door" , new ReFramedDoorBlock(cp(Blocks.IRON_DOOR), BlockSetType.IRON));
IRON_TRAPDOOR = registerReFramed("iron_trapdoor" , new ReFramedTrapdoorBlock(cp(Blocks.IRON_TRAPDOOR), BlockSetType.IRON));
PRESSURE_PLATE = registerReFramed("pressure_plate", new ReFramedPressurePlateBlock(cp(Blocks.OAK_PRESSURE_PLATE)));
BUTTON = registerReFramed("button" , new ReFramedButtonBlock(cp(Blocks.OAK_BUTTON)));
LEVER = registerReFramed("lever" , new ReFramedLeverBlock(cp(Blocks.LEVER)));
WALL = registerReFramed("wall" , new ReFramedWallBlock(ReFramedInteractionUtil.makeSettings()));
CARPET = registerReFramed("carpet" , new ReFramedCarpetBlock(cp(Blocks.WHITE_CARPET)));
PANE = registerReFramed("pane" , new ReFramedPaneBlock(cp(Blocks.GLASS_PANE)));
CANDLE = registerReFramed("candle" , new ReFramedCandleBlock(ReFramedCandleBlock.configureSettings(cp(Blocks.CANDLE))));
REFRAMED_BLOCK_ENTITY = Registry.register(Registries.BLOCK_ENTITY_TYPE, id("camo"),
FabricBlockEntityTypeBuilder.create((pos, state) -> new ReFramedEntity(REFRAMED_BLOCK_ENTITY, pos, state), BLOCKS.toArray(new Block[0])).build(null)
);
Registry.register(Registries.ITEM_GROUP, id("tab"), FabricItemGroup.builder()
.displayName(Text.translatable("itemGroup.reframed.tab"))
.icon(() -> new ItemStack(SLAB))
.entries((ctx, e) -> e.addAll(BLOCKS.stream().map(ItemStack::new).collect(Collectors.toList()))).build()
);
}
private static AbstractBlock.Settings cp(Block base) {
return ReFramedInteractionUtil.configureSettings(AbstractBlock.Settings.copy(base));
}
private static <B extends Block> B registerReFramed(String path, B block) {
Identifier id = id(path);
Registry.register(Registries.BLOCK, id, block);
Registry.register(Registries.ITEM, id, new BlockItem(block, new Item.Settings()));
BLOCKS.add(block);
return block;
}
public static Identifier id(String path) {
return new Identifier(MODID, path);
}
}

View File

@ -1,8 +1,8 @@
package fr.adrien1106.reframedtemplates.block;
package fr.adrien1106.reframed.block;
import com.google.common.base.MoreObjects;
import fr.adrien1106.reframedtemplates.Templates;
import fr.adrien1106.reframedtemplates.api.TemplateInteractionUtil;
import fr.adrien1106.reframed.ReFramed;
import fr.adrien1106.reframed.util.ReFramedInteractionUtil;
import net.minecraft.block.Block;
import net.minecraft.block.BlockEntityProvider;
import net.minecraft.block.BlockState;
@ -23,66 +23,66 @@ import net.minecraft.world.BlockView;
import net.minecraft.world.World;
import org.jetbrains.annotations.Nullable;
public class TemplateBlock extends Block implements BlockEntityProvider {
public TemplateBlock(Settings settings) {
public class ReFramedBlock extends Block implements BlockEntityProvider {
public ReFramedBlock(Settings settings) {
super(settings);
setDefaultState(TemplateInteractionUtil.setDefaultStates(getDefaultState()));
setDefaultState(ReFramedInteractionUtil.setDefaultStates(getDefaultState()));
}
//For addon devs: override this so your blocks don't end up trying to place my block entity, my BlockEntityType only handles blocks internal to the mod
//Just make your own BlockEntityType, it's fine, you can even use the same TemplateEntity class
//Just make your own BlockEntityType, it's fine, you can even use the same ReFramedEntity class
@Override
public @Nullable BlockEntity createBlockEntity(BlockPos pos, BlockState state) {
return Templates.TEMPLATE_BLOCK_ENTITY.instantiate(pos, state);
return ReFramed.REFRAMED_BLOCK_ENTITY.instantiate(pos, state);
}
@Override
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
super.appendProperties(TemplateInteractionUtil.appendProperties(builder));
super.appendProperties(ReFramedInteractionUtil.appendProperties(builder));
}
@Nullable
@Override
public BlockState getPlacementState(ItemPlacementContext ctx) {
return TemplateInteractionUtil.modifyPlacementState(super.getPlacementState(ctx), ctx);
return ReFramedInteractionUtil.modifyPlacementState(super.getPlacementState(ctx), ctx);
}
@Override
public ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) {
ActionResult r = TemplateInteractionUtil.onUse(state, world, pos, player, hand, hit);
ActionResult r = ReFramedInteractionUtil.onUse(state, world, pos, player, hand, hit);
if(!r.isAccepted()) r = super.onUse(state, world, pos, player, hand, hit);
return r;
}
@Override
public void onStateReplaced(BlockState state, World world, BlockPos pos, BlockState newState, boolean moved) {
TemplateInteractionUtil.onStateReplaced(state, world, pos, newState, moved);
ReFramedInteractionUtil.onStateReplaced(state, world, pos, newState, moved);
super.onStateReplaced(state, world, pos, newState, moved);
}
@Override
public void onPlaced(World world, BlockPos pos, BlockState state, @Nullable LivingEntity placer, ItemStack stack) {
TemplateInteractionUtil.onPlaced(world, pos, state, placer, stack);
ReFramedInteractionUtil.onPlaced(world, pos, state, placer, stack);
super.onPlaced(world, pos, state, placer, stack);
}
@Override
public VoxelShape getCollisionShape(BlockState state, BlockView view, BlockPos pos, ShapeContext ctx) {
return MoreObjects.firstNonNull(TemplateInteractionUtil.getCollisionShape(state, view, pos, ctx), super.getCollisionShape(state, view, pos, ctx));
return MoreObjects.firstNonNull(ReFramedInteractionUtil.getCollisionShape(state, view, pos, ctx), super.getCollisionShape(state, view, pos, ctx));
}
@Override
public boolean emitsRedstonePower(BlockState state) {
return TemplateInteractionUtil.emitsRedstonePower(state);
return ReFramedInteractionUtil.emitsRedstonePower(state);
}
@Override
public int getWeakRedstonePower(BlockState state, BlockView view, BlockPos pos, Direction dir) {
return TemplateInteractionUtil.getWeakRedstonePower(state, view, pos, dir);
return ReFramedInteractionUtil.getWeakRedstonePower(state, view, pos, dir);
}
@Override
public int getStrongRedstonePower(BlockState state, BlockView view, BlockPos pos, Direction dir) {
return TemplateInteractionUtil.getStrongRedstonePower(state, view, pos, dir);
return ReFramedInteractionUtil.getStrongRedstonePower(state, view, pos, dir);
}
}

View File

@ -1,8 +1,8 @@
package fr.adrien1106.reframedtemplates.block;
package fr.adrien1106.reframed.block;
import com.google.common.base.MoreObjects;
import fr.adrien1106.reframedtemplates.Templates;
import fr.adrien1106.reframedtemplates.api.TemplateInteractionUtil;
import fr.adrien1106.reframed.ReFramed;
import fr.adrien1106.reframed.util.ReFramedInteractionUtil;
import net.minecraft.block.Block;
import net.minecraft.block.BlockEntityProvider;
import net.minecraft.block.BlockSetType;
@ -25,66 +25,65 @@ import net.minecraft.world.BlockView;
import net.minecraft.world.World;
import org.jetbrains.annotations.Nullable;
public class TemplateButtonBlock extends ButtonBlock implements BlockEntityProvider {
public TemplateButtonBlock(Settings settings) {
public class ReFramedButtonBlock extends ButtonBlock implements BlockEntityProvider {
public ReFramedButtonBlock(Settings settings) {
this(settings, BlockSetType.OAK, 30);
}
public TemplateButtonBlock(Settings settings, BlockSetType blockSetType, int i) {
public ReFramedButtonBlock(Settings settings, BlockSetType blockSetType, int i) {
super(blockSetType, i, settings);
setDefaultState(TemplateInteractionUtil.setDefaultStates(getDefaultState()));
setDefaultState(ReFramedInteractionUtil.setDefaultStates(getDefaultState()));
}
@Nullable
@Override
public BlockEntity createBlockEntity(BlockPos pos, BlockState state) {
return Templates.TEMPLATE_BLOCK_ENTITY.instantiate(pos, state);
return ReFramed.REFRAMED_BLOCK_ENTITY.instantiate(pos, state);
}
@Override
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
super.appendProperties(TemplateInteractionUtil.appendProperties(builder));
super.appendProperties(ReFramedInteractionUtil.appendProperties(builder));
}
@Nullable
@Override
public BlockState getPlacementState(ItemPlacementContext ctx) {
return TemplateInteractionUtil.modifyPlacementState(super.getPlacementState(ctx), ctx);
return ReFramedInteractionUtil.modifyPlacementState(super.getPlacementState(ctx), ctx);
}
@Override
public ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) {
ActionResult r = TemplateInteractionUtil.onUse(state, world, pos, player, hand, hit);
ActionResult r = ReFramedInteractionUtil.onUse(state, world, pos, player, hand, hit);
if(!r.isAccepted()) r = super.onUse(state, world, pos, player, hand, hit);
return r;
}
@Override
public void onStateReplaced(BlockState state, World world, BlockPos pos, BlockState newState, boolean moved) {
TemplateInteractionUtil.onStateReplaced(state, world, pos, newState, moved);
ReFramedInteractionUtil.onStateReplaced(state, world, pos, newState, moved);
super.onStateReplaced(state, world, pos, newState, moved);
}
@Override
public void onPlaced(World world, BlockPos pos, BlockState state, @Nullable LivingEntity placer, ItemStack stack) {
TemplateInteractionUtil.onPlaced(world, pos, state, placer, stack);
ReFramedInteractionUtil.onPlaced(world, pos, state, placer, stack);
}
@Override
public VoxelShape getCollisionShape(BlockState state, BlockView view, BlockPos pos, ShapeContext ctx) {
return MoreObjects.firstNonNull(TemplateInteractionUtil.getCollisionShape(state, view, pos, ctx), super.getCollisionShape(state, view, pos, ctx));
return MoreObjects.firstNonNull(ReFramedInteractionUtil.getCollisionShape(state, view, pos, ctx), super.getCollisionShape(state, view, pos, ctx));
}
@Override
public boolean emitsRedstonePower(BlockState state) {
//return TemplateInteractionUtil.emitsRedstonePower(state);
return super.emitsRedstonePower(state);
}
@Override
public int getWeakRedstonePower(BlockState state, BlockView view, BlockPos pos, Direction dir) {
boolean a = 0 != super.getWeakRedstonePower(state, view, pos, dir);
boolean b = 0 != TemplateInteractionUtil.getWeakRedstonePower(state, view, pos, dir);
boolean b = 0 != ReFramedInteractionUtil.getWeakRedstonePower(state, view, pos, dir);
return (a ^ b) ? 15 : 0;
}

View File

@ -1,8 +1,8 @@
package fr.adrien1106.reframedtemplates.block;
package fr.adrien1106.reframed.block;
import com.google.common.base.MoreObjects;
import fr.adrien1106.reframedtemplates.Templates;
import fr.adrien1106.reframedtemplates.api.TemplateInteractionUtil;
import fr.adrien1106.reframed.ReFramed;
import fr.adrien1106.reframed.util.ReFramedInteractionUtil;
import net.minecraft.block.AbstractBlock;
import net.minecraft.block.Block;
import net.minecraft.block.BlockEntityProvider;
@ -25,68 +25,68 @@ import net.minecraft.world.BlockView;
import net.minecraft.world.World;
import org.jetbrains.annotations.Nullable;
public class TemplateCandleBlock extends CandleBlock implements BlockEntityProvider {
public TemplateCandleBlock(Settings settings) {
public class ReFramedCandleBlock extends CandleBlock implements BlockEntityProvider {
public ReFramedCandleBlock(Settings settings) {
super(settings);
setDefaultState(TemplateInteractionUtil.setDefaultStates(getDefaultState()));
setDefaultState(ReFramedInteractionUtil.setDefaultStates(getDefaultState()));
}
public static AbstractBlock.Settings configureSettings(AbstractBlock.Settings in) {
return in.luminance(state -> Math.max(TemplateInteractionUtil.luminance(state), CandleBlock.STATE_TO_LUMINANCE.applyAsInt(state)));
return in.luminance(state -> Math.max(ReFramedInteractionUtil.luminance(state), CandleBlock.STATE_TO_LUMINANCE.applyAsInt(state)));
}
@Override
public @Nullable BlockEntity createBlockEntity(BlockPos pos, BlockState state) {
return Templates.TEMPLATE_BLOCK_ENTITY.instantiate(pos, state);
return ReFramed.REFRAMED_BLOCK_ENTITY.instantiate(pos, state);
}
@Override
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
super.appendProperties(TemplateInteractionUtil.appendProperties(builder));
super.appendProperties(ReFramedInteractionUtil.appendProperties(builder));
}
@Nullable
@Override
public BlockState getPlacementState(ItemPlacementContext ctx) {
return TemplateInteractionUtil.modifyPlacementState(super.getPlacementState(ctx), ctx);
return ReFramedInteractionUtil.modifyPlacementState(super.getPlacementState(ctx), ctx);
}
@Override
public ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) {
ActionResult r = TemplateInteractionUtil.onUse(state, world, pos, player, hand, hit);
ActionResult r = ReFramedInteractionUtil.onUse(state, world, pos, player, hand, hit);
if(!r.isAccepted()) r = super.onUse(state, world, pos, player, hand, hit);
return r;
}
@Override
public void onStateReplaced(BlockState state, World world, BlockPos pos, BlockState newState, boolean moved) {
TemplateInteractionUtil.onStateReplaced(state, world, pos, newState, moved);
ReFramedInteractionUtil.onStateReplaced(state, world, pos, newState, moved);
super.onStateReplaced(state, world, pos, newState, moved);
}
@Override
public void onPlaced(World world, BlockPos pos, BlockState state, @Nullable LivingEntity placer, ItemStack stack) {
TemplateInteractionUtil.onPlaced(world, pos, state, placer, stack);
ReFramedInteractionUtil.onPlaced(world, pos, state, placer, stack);
super.onPlaced(world, pos, state, placer, stack);
}
@Override
public VoxelShape getCollisionShape(BlockState state, BlockView view, BlockPos pos, ShapeContext ctx) {
return MoreObjects.firstNonNull(TemplateInteractionUtil.getCollisionShape(state, view, pos, ctx), super.getCollisionShape(state, view, pos, ctx));
return MoreObjects.firstNonNull(ReFramedInteractionUtil.getCollisionShape(state, view, pos, ctx), super.getCollisionShape(state, view, pos, ctx));
}
@Override
public boolean emitsRedstonePower(BlockState state) {
return TemplateInteractionUtil.emitsRedstonePower(state);
return ReFramedInteractionUtil.emitsRedstonePower(state);
}
@Override
public int getWeakRedstonePower(BlockState state, BlockView view, BlockPos pos, Direction dir) {
return TemplateInteractionUtil.getWeakRedstonePower(state, view, pos, dir);
return ReFramedInteractionUtil.getWeakRedstonePower(state, view, pos, dir);
}
@Override
public int getStrongRedstonePower(BlockState state, BlockView view, BlockPos pos, Direction dir) {
return TemplateInteractionUtil.getStrongRedstonePower(state, view, pos, dir);
return ReFramedInteractionUtil.getStrongRedstonePower(state, view, pos, dir);
}
}

View File

@ -1,8 +1,8 @@
package fr.adrien1106.reframedtemplates.block;
package fr.adrien1106.reframed.block;
import com.google.common.base.MoreObjects;
import fr.adrien1106.reframedtemplates.Templates;
import fr.adrien1106.reframedtemplates.api.TemplateInteractionUtil;
import fr.adrien1106.reframed.ReFramed;
import fr.adrien1106.reframed.util.ReFramedInteractionUtil;
import net.minecraft.block.Block;
import net.minecraft.block.BlockEntityProvider;
import net.minecraft.block.BlockState;
@ -24,64 +24,64 @@ import net.minecraft.world.BlockView;
import net.minecraft.world.World;
import org.jetbrains.annotations.Nullable;
public class TemplateCarpetBlock extends CarpetBlock implements BlockEntityProvider {
public TemplateCarpetBlock(Settings settings) {
public class ReFramedCarpetBlock extends CarpetBlock implements BlockEntityProvider {
public ReFramedCarpetBlock(Settings settings) {
super(settings);
setDefaultState(TemplateInteractionUtil.setDefaultStates(getDefaultState()));
setDefaultState(ReFramedInteractionUtil.setDefaultStates(getDefaultState()));
}
@Nullable
@Override
public BlockEntity createBlockEntity(BlockPos pos, BlockState state) {
return Templates.TEMPLATE_BLOCK_ENTITY.instantiate(pos, state);
return ReFramed.REFRAMED_BLOCK_ENTITY.instantiate(pos, state);
}
@Override
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
super.appendProperties(TemplateInteractionUtil.appendProperties(builder));
super.appendProperties(ReFramedInteractionUtil.appendProperties(builder));
}
@Nullable
@Override
public BlockState getPlacementState(ItemPlacementContext ctx) {
return TemplateInteractionUtil.modifyPlacementState(super.getPlacementState(ctx), ctx);
return ReFramedInteractionUtil.modifyPlacementState(super.getPlacementState(ctx), ctx);
}
@Override
public ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) {
ActionResult r = TemplateInteractionUtil.onUse(state, world, pos, player, hand, hit);
ActionResult r = ReFramedInteractionUtil.onUse(state, world, pos, player, hand, hit);
if(!r.isAccepted()) r = super.onUse(state, world, pos, player, hand, hit);
return r;
}
@Override
public void onStateReplaced(BlockState state, World world, BlockPos pos, BlockState newState, boolean moved) {
TemplateInteractionUtil.onStateReplaced(state, world, pos, newState, moved);
ReFramedInteractionUtil.onStateReplaced(state, world, pos, newState, moved);
super.onStateReplaced(state, world, pos, newState, moved);
}
@Override
public void onPlaced(World world, BlockPos pos, BlockState state, @Nullable LivingEntity placer, ItemStack stack) {
TemplateInteractionUtil.onPlaced(world, pos, state, placer, stack);
ReFramedInteractionUtil.onPlaced(world, pos, state, placer, stack);
}
@Override
public VoxelShape getCollisionShape(BlockState state, BlockView view, BlockPos pos, ShapeContext ctx) {
return MoreObjects.firstNonNull(TemplateInteractionUtil.getCollisionShape(state, view, pos, ctx), super.getCollisionShape(state, view, pos, ctx));
return MoreObjects.firstNonNull(ReFramedInteractionUtil.getCollisionShape(state, view, pos, ctx), super.getCollisionShape(state, view, pos, ctx));
}
@Override
public boolean emitsRedstonePower(BlockState state) {
return TemplateInteractionUtil.emitsRedstonePower(state);
return ReFramedInteractionUtil.emitsRedstonePower(state);
}
@Override
public int getWeakRedstonePower(BlockState state, BlockView view, BlockPos pos, Direction dir) {
return TemplateInteractionUtil.getWeakRedstonePower(state, view, pos, dir);
return ReFramedInteractionUtil.getWeakRedstonePower(state, view, pos, dir);
}
@Override
public int getStrongRedstonePower(BlockState state, BlockView view, BlockPos pos, Direction dir) {
return TemplateInteractionUtil.getStrongRedstonePower(state, view, pos, dir);
return ReFramedInteractionUtil.getStrongRedstonePower(state, view, pos, dir);
}
}

View File

@ -1,8 +1,8 @@
package fr.adrien1106.reframedtemplates.block;
package fr.adrien1106.reframed.block;
import com.google.common.base.MoreObjects;
import fr.adrien1106.reframedtemplates.Templates;
import fr.adrien1106.reframedtemplates.api.TemplateInteractionUtil;
import fr.adrien1106.reframed.ReFramed;
import fr.adrien1106.reframed.util.ReFramedInteractionUtil;
import net.minecraft.block.Block;
import net.minecraft.block.BlockEntityProvider;
import net.minecraft.block.BlockSetType;
@ -25,65 +25,65 @@ import net.minecraft.world.BlockView;
import net.minecraft.world.World;
import org.jetbrains.annotations.Nullable;
public class TemplateDoorBlock extends DoorBlock implements BlockEntityProvider {
public TemplateDoorBlock(Settings settings, BlockSetType blockSetType) {
public class ReFramedDoorBlock extends DoorBlock implements BlockEntityProvider {
public ReFramedDoorBlock(Settings settings, BlockSetType blockSetType) {
super(blockSetType, settings);
setDefaultState(TemplateInteractionUtil.setDefaultStates(getDefaultState()));
setDefaultState(ReFramedInteractionUtil.setDefaultStates(getDefaultState()));
}
@Nullable
@Override
public BlockEntity createBlockEntity(BlockPos pos, BlockState state) {
return Templates.TEMPLATE_BLOCK_ENTITY.instantiate(pos, state);
return ReFramed.REFRAMED_BLOCK_ENTITY.instantiate(pos, state);
}
@Override
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
super.appendProperties(TemplateInteractionUtil.appendProperties(builder));
super.appendProperties(ReFramedInteractionUtil.appendProperties(builder));
}
@Nullable
@Override
public BlockState getPlacementState(ItemPlacementContext ctx) {
return TemplateInteractionUtil.modifyPlacementState(super.getPlacementState(ctx), ctx);
return ReFramedInteractionUtil.modifyPlacementState(super.getPlacementState(ctx), ctx);
}
@Override
public ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) {
ActionResult r = TemplateInteractionUtil.onUse(state, world, pos, player, hand, hit);
ActionResult r = ReFramedInteractionUtil.onUse(state, world, pos, player, hand, hit);
if(!r.isAccepted()) r = super.onUse(state, world, pos, player, hand, hit);
return r;
}
@Override
public void onStateReplaced(BlockState state, World world, BlockPos pos, BlockState newState, boolean moved) {
TemplateInteractionUtil.onStateReplaced(state, world, pos, newState, moved);
ReFramedInteractionUtil.onStateReplaced(state, world, pos, newState, moved);
super.onStateReplaced(state, world, pos, newState, moved);
}
@Override
public void onPlaced(World world, BlockPos pos, BlockState state, @Nullable LivingEntity placer, ItemStack stack) {
TemplateInteractionUtil.onPlaced(world, pos, state, placer, stack);
ReFramedInteractionUtil.onPlaced(world, pos, state, placer, stack);
super.onPlaced(world, pos, state, placer, stack);
}
@Override
public VoxelShape getCollisionShape(BlockState state, BlockView view, BlockPos pos, ShapeContext ctx) {
return MoreObjects.firstNonNull(TemplateInteractionUtil.getCollisionShape(state, view, pos, ctx), super.getCollisionShape(state, view, pos, ctx));
return MoreObjects.firstNonNull(ReFramedInteractionUtil.getCollisionShape(state, view, pos, ctx), super.getCollisionShape(state, view, pos, ctx));
}
@Override
public boolean emitsRedstonePower(BlockState state) {
return TemplateInteractionUtil.emitsRedstonePower(state);
return ReFramedInteractionUtil.emitsRedstonePower(state);
}
@Override
public int getWeakRedstonePower(BlockState state, BlockView view, BlockPos pos, Direction dir) {
return TemplateInteractionUtil.getWeakRedstonePower(state, view, pos, dir);
return ReFramedInteractionUtil.getWeakRedstonePower(state, view, pos, dir);
}
@Override
public int getStrongRedstonePower(BlockState state, BlockView view, BlockPos pos, Direction dir) {
return TemplateInteractionUtil.getStrongRedstonePower(state, view, pos, dir);
return ReFramedInteractionUtil.getStrongRedstonePower(state, view, pos, dir);
}
}

View File

@ -1,8 +1,8 @@
package fr.adrien1106.reframedtemplates.block;
package fr.adrien1106.reframed.block;
import fr.adrien1106.reframedtemplates.Templates;
import fr.adrien1106.reframedtemplates.api.TemplateInteractionUtil;
import fr.adrien1106.reframedtemplates.api.ThemeableBlockEntity;
import fr.adrien1106.reframed.ReFramed;
import fr.adrien1106.reframed.util.ReFramedInteractionUtil;
import fr.adrien1106.reframed.util.ThemeableBlockEntity;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.block.entity.BlockEntity;
@ -26,7 +26,7 @@ import java.util.Objects;
//Keeping the weight of this block entity down, both in terms of memory consumption and NBT sync traffic,
//is pretty important since players might place a lot of them. There were tons and tons of these at Blanketcon.
//To that end, most of the state has been crammed into a bitfield.
public class FramedEntity extends BlockEntity implements ThemeableBlockEntity {
public class ReFramedEntity extends BlockEntity implements ThemeableBlockEntity {
protected BlockState renderedState = Blocks.AIR.getDefaultState();
protected byte bitfield = DEFAULT_BITFIELD;
@ -35,7 +35,7 @@ public class FramedEntity extends BlockEntity implements ThemeableBlockEntity {
protected static final int SPENT_POPPED_CHORUS_MASK = 0b00000100;
protected static final int EMITS_REDSTONE_MASK = 0b00001000;
protected static final int IS_SOLID_MASK = 0b00010000;
protected static final byte DEFAULT_BITFIELD = IS_SOLID_MASK; //brand-new templates shall be solid
protected static final byte DEFAULT_BITFIELD = IS_SOLID_MASK; //brand-new frames shall be solid
//Using one-character names is a little brash, like, what if there's a mod that adds crap to the NBT of every
//block entity, and uses short names for the same reason I am (because there are lots and lots of block entities)?
@ -43,7 +43,7 @@ public class FramedEntity extends BlockEntity implements ThemeableBlockEntity {
protected static final String BLOCKSTATE_KEY = "s";
protected static final String BITFIELD_KEY = "b";
public FramedEntity(BlockEntityType<?> type, BlockPos pos, BlockState state) {
public ReFramedEntity(BlockEntityType<?> type, BlockPos pos, BlockState state) {
super(type, pos, state);
}
@ -68,7 +68,7 @@ public class FramedEntity extends BlockEntity implements ThemeableBlockEntity {
//Force a chunk remesh on the client if the displayed blockstate has changed
if(world != null && world.isClient && !Objects.equals(lastRenderedState, renderedState)) {
Templates.chunkRerenderProxy.accept(world, pos);
ReFramed.chunkRerenderProxy.accept(world, pos);
}
}
@ -105,8 +105,8 @@ public class FramedEntity extends BlockEntity implements ThemeableBlockEntity {
NbtCompound blockEntityTag = BlockItem.getBlockEntityNbt(stack);
if(blockEntityTag == null) return state;
if(state.contains(TemplateInteractionUtil.LIGHT)) {
state = state.with(TemplateInteractionUtil.LIGHT,
if(state.contains(ReFramedInteractionUtil.LIGHT)) {
state = state.with(ReFramedInteractionUtil.LIGHT,
blockEntityTag.getBoolean("spentglow") || //2.0.4
((blockEntityTag.contains(BITFIELD_KEY) ? blockEntityTag.getByte(BITFIELD_KEY) : DEFAULT_BITFIELD) & SPENT_GLOWSTONE_DUST_MASK) != 0 || //2.0.5
readStateFromItem(stack).getLuminance() != 0 //glowstone dust wasn't manually added, the block just emits light

View File

@ -1,8 +1,8 @@
package fr.adrien1106.reframedtemplates.block;
package fr.adrien1106.reframed.block;
import com.google.common.base.MoreObjects;
import fr.adrien1106.reframedtemplates.Templates;
import fr.adrien1106.reframedtemplates.api.TemplateInteractionUtil;
import fr.adrien1106.reframed.ReFramed;
import fr.adrien1106.reframed.util.ReFramedInteractionUtil;
import net.minecraft.block.Block;
import net.minecraft.block.BlockEntityProvider;
import net.minecraft.block.BlockState;
@ -24,64 +24,64 @@ import net.minecraft.world.BlockView;
import net.minecraft.world.World;
import org.jetbrains.annotations.Nullable;
public class TemplateFenceBlock extends FenceBlock implements BlockEntityProvider {
public TemplateFenceBlock(Settings settings) {
public class ReFramedFenceBlock extends FenceBlock implements BlockEntityProvider {
public ReFramedFenceBlock(Settings settings) {
super(settings);
setDefaultState(TemplateInteractionUtil.setDefaultStates(getDefaultState()));
setDefaultState(ReFramedInteractionUtil.setDefaultStates(getDefaultState()));
}
@Nullable
@Override
public BlockEntity createBlockEntity(BlockPos pos, BlockState state) {
return Templates.TEMPLATE_BLOCK_ENTITY.instantiate(pos, state);
return ReFramed.REFRAMED_BLOCK_ENTITY.instantiate(pos, state);
}
@Override
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
super.appendProperties(TemplateInteractionUtil.appendProperties(builder));
super.appendProperties(ReFramedInteractionUtil.appendProperties(builder));
}
@Nullable
@Override
public BlockState getPlacementState(ItemPlacementContext ctx) {
return TemplateInteractionUtil.modifyPlacementState(super.getPlacementState(ctx), ctx);
return ReFramedInteractionUtil.modifyPlacementState(super.getPlacementState(ctx), ctx);
}
@Override
public ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) {
ActionResult r = TemplateInteractionUtil.onUse(state, world, pos, player, hand, hit);
ActionResult r = ReFramedInteractionUtil.onUse(state, world, pos, player, hand, hit);
if(!r.isAccepted()) r = super.onUse(state, world, pos, player, hand, hit);
return r;
}
@Override
public void onStateReplaced(BlockState state, World world, BlockPos pos, BlockState newState, boolean moved) {
TemplateInteractionUtil.onStateReplaced(state, world, pos, newState, moved);
ReFramedInteractionUtil.onStateReplaced(state, world, pos, newState, moved);
super.onStateReplaced(state, world, pos, newState, moved);
}
@Override
public void onPlaced(World world, BlockPos pos, BlockState state, @Nullable LivingEntity placer, ItemStack stack) {
TemplateInteractionUtil.onPlaced(world, pos, state, placer, stack);
ReFramedInteractionUtil.onPlaced(world, pos, state, placer, stack);
}
@Override
public VoxelShape getCollisionShape(BlockState state, BlockView view, BlockPos pos, ShapeContext ctx) {
return MoreObjects.firstNonNull(TemplateInteractionUtil.getCollisionShape(state, view, pos, ctx), super.getCollisionShape(state, view, pos, ctx));
return MoreObjects.firstNonNull(ReFramedInteractionUtil.getCollisionShape(state, view, pos, ctx), super.getCollisionShape(state, view, pos, ctx));
}
@Override
public boolean emitsRedstonePower(BlockState state) {
return TemplateInteractionUtil.emitsRedstonePower(state);
return ReFramedInteractionUtil.emitsRedstonePower(state);
}
@Override
public int getWeakRedstonePower(BlockState state, BlockView view, BlockPos pos, Direction dir) {
return TemplateInteractionUtil.getWeakRedstonePower(state, view, pos, dir);
return ReFramedInteractionUtil.getWeakRedstonePower(state, view, pos, dir);
}
@Override
public int getStrongRedstonePower(BlockState state, BlockView view, BlockPos pos, Direction dir) {
return TemplateInteractionUtil.getStrongRedstonePower(state, view, pos, dir);
return ReFramedInteractionUtil.getStrongRedstonePower(state, view, pos, dir);
}
}

View File

@ -1,9 +1,9 @@
package fr.adrien1106.reframedtemplates.block;
package fr.adrien1106.reframed.block;
import com.google.common.base.MoreObjects;
import fr.adrien1106.reframedtemplates.Templates;
import fr.adrien1106.reframedtemplates.api.TemplateInteractionUtil;
import fr.adrien1106.reframedtemplates.api.TemplateInteractionUtilExt;
import fr.adrien1106.reframed.ReFramed;
import fr.adrien1106.reframed.util.ReFramedInteractionUtil;
import fr.adrien1106.reframed.util.ReframedInteractible;
import net.minecraft.block.Block;
import net.minecraft.block.BlockEntityProvider;
import net.minecraft.block.BlockState;
@ -26,73 +26,73 @@ import net.minecraft.world.BlockView;
import net.minecraft.world.World;
import org.jetbrains.annotations.Nullable;
public class TemplateFenceGateBlock extends FenceGateBlock implements BlockEntityProvider, TemplateInteractionUtilExt {
public TemplateFenceGateBlock(Settings settings, WoodType woodType) {
public class ReFramedFenceGateBlock extends FenceGateBlock implements BlockEntityProvider, ReframedInteractible {
public ReFramedFenceGateBlock(Settings settings, WoodType woodType) {
super(woodType, settings);
setDefaultState(TemplateInteractionUtil.setDefaultStates(getDefaultState()));
setDefaultState(ReFramedInteractionUtil.setDefaultStates(getDefaultState()));
}
public TemplateFenceGateBlock(Settings settings) {
public ReFramedFenceGateBlock(Settings settings) {
this(settings, WoodType.OAK);
}
@Nullable
@Override
public BlockEntity createBlockEntity(BlockPos pos, BlockState state) {
return Templates.TEMPLATE_BLOCK_ENTITY.instantiate(pos, state);
return ReFramed.REFRAMED_BLOCK_ENTITY.instantiate(pos, state);
}
@Nullable
@Override
public BlockState getPlacementState(ItemPlacementContext ctx) {
return TemplateInteractionUtil.modifyPlacementState(super.getPlacementState(ctx), ctx);
return ReFramedInteractionUtil.modifyPlacementState(super.getPlacementState(ctx), ctx);
}
@Override
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
super.appendProperties(TemplateInteractionUtil.appendProperties(builder));
super.appendProperties(ReFramedInteractionUtil.appendProperties(builder));
}
@Override
public ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) {
ActionResult r = TemplateInteractionUtil.onUse(state, world, pos, player, hand, hit);
ActionResult r = ReFramedInteractionUtil.onUse(state, world, pos, player, hand, hit);
if(!r.isAccepted()) r = super.onUse(state, world, pos, player, hand, hit);
return r;
}
@Override
public void onStateReplaced(BlockState state, World world, BlockPos pos, BlockState newState, boolean moved) {
TemplateInteractionUtil.onStateReplaced(state, world, pos, newState, moved);
ReFramedInteractionUtil.onStateReplaced(state, world, pos, newState, moved);
super.onStateReplaced(state, world, pos, newState, moved);
}
@Override
public void onPlaced(World world, BlockPos pos, BlockState state, @Nullable LivingEntity placer, ItemStack stack) {
TemplateInteractionUtil.onPlaced(world, pos, state, placer, stack);
ReFramedInteractionUtil.onPlaced(world, pos, state, placer, stack);
}
@Override
public VoxelShape getCollisionShape(BlockState state, BlockView view, BlockPos pos, ShapeContext ctx) {
return MoreObjects.firstNonNull(TemplateInteractionUtil.getCollisionShape(state, view, pos, ctx), super.getCollisionShape(state, view, pos, ctx));
return MoreObjects.firstNonNull(ReFramedInteractionUtil.getCollisionShape(state, view, pos, ctx), super.getCollisionShape(state, view, pos, ctx));
}
@Override
public boolean emitsRedstonePower(BlockState state) {
return TemplateInteractionUtil.emitsRedstonePower(state);
return ReFramedInteractionUtil.emitsRedstonePower(state);
}
@Override
public int getWeakRedstonePower(BlockState state, BlockView view, BlockPos pos, Direction dir) {
return TemplateInteractionUtil.getWeakRedstonePower(state, view, pos, dir);
return ReFramedInteractionUtil.getWeakRedstonePower(state, view, pos, dir);
}
@Override
public int getStrongRedstonePower(BlockState state, BlockView view, BlockPos pos, Direction dir) {
return TemplateInteractionUtil.getStrongRedstonePower(state, view, pos, dir);
return ReFramedInteractionUtil.getStrongRedstonePower(state, view, pos, dir);
}
@Override
public boolean templatesPlayerCanAddRedstoneEmission(BlockState state, BlockView view, BlockPos pos) {
public boolean canAddRedstoneEmission(BlockState state, BlockView view, BlockPos pos) {
return false;
}
}

View File

@ -1,8 +1,8 @@
package fr.adrien1106.reframedtemplates.block;
package fr.adrien1106.reframed.block;
import com.google.common.base.MoreObjects;
import fr.adrien1106.reframedtemplates.Templates;
import fr.adrien1106.reframedtemplates.api.TemplateInteractionUtil;
import fr.adrien1106.reframed.ReFramed;
import fr.adrien1106.reframed.util.ReFramedInteractionUtil;
import net.minecraft.block.Block;
import net.minecraft.block.BlockEntityProvider;
import net.minecraft.block.BlockState;
@ -24,62 +24,61 @@ import net.minecraft.world.BlockView;
import net.minecraft.world.World;
import org.jetbrains.annotations.Nullable;
public class TemplateLeverBlock extends LeverBlock implements BlockEntityProvider {
public TemplateLeverBlock(Settings settings) {
public class ReFramedLeverBlock extends LeverBlock implements BlockEntityProvider {
public ReFramedLeverBlock(Settings settings) {
super(settings);
setDefaultState(TemplateInteractionUtil.setDefaultStates(getDefaultState()));
setDefaultState(ReFramedInteractionUtil.setDefaultStates(getDefaultState()));
}
@Nullable
@Override
public BlockEntity createBlockEntity(BlockPos pos, BlockState state) {
return Templates.TEMPLATE_BLOCK_ENTITY.instantiate(pos, state);
return ReFramed.REFRAMED_BLOCK_ENTITY.instantiate(pos, state);
}
@Nullable
@Override
public BlockState getPlacementState(ItemPlacementContext ctx) {
return TemplateInteractionUtil.modifyPlacementState(super.getPlacementState(ctx), ctx);
return ReFramedInteractionUtil.modifyPlacementState(super.getPlacementState(ctx), ctx);
}
@Override
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
super.appendProperties(TemplateInteractionUtil.appendProperties(builder));
super.appendProperties(ReFramedInteractionUtil.appendProperties(builder));
}
@Override
public ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) {
ActionResult r = TemplateInteractionUtil.onUse(state, world, pos, player, hand, hit);
ActionResult r = ReFramedInteractionUtil.onUse(state, world, pos, player, hand, hit);
if(!r.isAccepted()) r = super.onUse(state, world, pos, player, hand, hit);
return r;
}
@Override
public void onStateReplaced(BlockState state, World world, BlockPos pos, BlockState newState, boolean moved) {
TemplateInteractionUtil.onStateReplaced(state, world, pos, newState, moved);
ReFramedInteractionUtil.onStateReplaced(state, world, pos, newState, moved);
super.onStateReplaced(state, world, pos, newState, moved);
}
@Override
public void onPlaced(World world, BlockPos pos, BlockState state, @Nullable LivingEntity placer, ItemStack stack) {
TemplateInteractionUtil.onPlaced(world, pos, state, placer, stack);
ReFramedInteractionUtil.onPlaced(world, pos, state, placer, stack);
}
@Override
public VoxelShape getCollisionShape(BlockState state, BlockView view, BlockPos pos, ShapeContext ctx) {
return MoreObjects.firstNonNull(TemplateInteractionUtil.getCollisionShape(state, view, pos, ctx), super.getCollisionShape(state, view, pos, ctx));
return MoreObjects.firstNonNull(ReFramedInteractionUtil.getCollisionShape(state, view, pos, ctx), super.getCollisionShape(state, view, pos, ctx));
}
@Override
public boolean emitsRedstonePower(BlockState state) {
//return TemplateInteractionUtil.emitsRedstonePower(state);
return super.emitsRedstonePower(state);
}
@Override
public int getWeakRedstonePower(BlockState state, BlockView view, BlockPos pos, Direction dir) {
boolean a = 0 != super.getWeakRedstonePower(state, view, pos, dir);
boolean b = 0 != TemplateInteractionUtil.getWeakRedstonePower(state, view, pos, dir);
boolean b = 0 != ReFramedInteractionUtil.getWeakRedstonePower(state, view, pos, dir);
return (a ^ b) ? 15 : 0;
}

View File

@ -1,8 +1,8 @@
package fr.adrien1106.reframedtemplates.block;
package fr.adrien1106.reframed.block;
import com.google.common.base.MoreObjects;
import fr.adrien1106.reframedtemplates.Templates;
import fr.adrien1106.reframedtemplates.api.TemplateInteractionUtil;
import fr.adrien1106.reframed.ReFramed;
import fr.adrien1106.reframed.util.ReFramedInteractionUtil;
import net.minecraft.block.Block;
import net.minecraft.block.BlockEntityProvider;
import net.minecraft.block.BlockState;
@ -24,64 +24,64 @@ import net.minecraft.world.BlockView;
import net.minecraft.world.World;
import org.jetbrains.annotations.Nullable;
public class TemplatePaneBlock extends PaneBlock implements BlockEntityProvider {
public TemplatePaneBlock(Settings settings) {
public class ReFramedPaneBlock extends PaneBlock implements BlockEntityProvider {
public ReFramedPaneBlock(Settings settings) {
super(settings);
setDefaultState(TemplateInteractionUtil.setDefaultStates(getDefaultState()));
setDefaultState(ReFramedInteractionUtil.setDefaultStates(getDefaultState()));
}
@Override
public @Nullable BlockEntity createBlockEntity(BlockPos pos, BlockState state) {
return Templates.TEMPLATE_BLOCK_ENTITY.instantiate(pos, state);
return ReFramed.REFRAMED_BLOCK_ENTITY.instantiate(pos, state);
}
@Nullable
@Override
public BlockState getPlacementState(ItemPlacementContext ctx) {
return TemplateInteractionUtil.modifyPlacementState(super.getPlacementState(ctx), ctx);
return ReFramedInteractionUtil.modifyPlacementState(super.getPlacementState(ctx), ctx);
}
@Override
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
super.appendProperties(TemplateInteractionUtil.appendProperties(builder));
super.appendProperties(ReFramedInteractionUtil.appendProperties(builder));
}
@Override
public ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) {
ActionResult r = TemplateInteractionUtil.onUse(state, world, pos, player, hand, hit);
ActionResult r = ReFramedInteractionUtil.onUse(state, world, pos, player, hand, hit);
if(!r.isAccepted()) r = super.onUse(state, world, pos, player, hand, hit);
return r;
}
@Override
public void onStateReplaced(BlockState state, World world, BlockPos pos, BlockState newState, boolean moved) {
TemplateInteractionUtil.onStateReplaced(state, world, pos, newState, moved);
ReFramedInteractionUtil.onStateReplaced(state, world, pos, newState, moved);
super.onStateReplaced(state, world, pos, newState, moved);
}
@Override
public void onPlaced(World world, BlockPos pos, BlockState state, @Nullable LivingEntity placer, ItemStack stack) {
TemplateInteractionUtil.onPlaced(world, pos, state, placer, stack);
ReFramedInteractionUtil.onPlaced(world, pos, state, placer, stack);
super.onPlaced(world, pos, state, placer, stack);
}
@Override
public VoxelShape getCollisionShape(BlockState state, BlockView view, BlockPos pos, ShapeContext ctx) {
return MoreObjects.firstNonNull(TemplateInteractionUtil.getCollisionShape(state, view, pos, ctx), super.getCollisionShape(state, view, pos, ctx));
return MoreObjects.firstNonNull(ReFramedInteractionUtil.getCollisionShape(state, view, pos, ctx), super.getCollisionShape(state, view, pos, ctx));
}
@Override
public boolean emitsRedstonePower(BlockState state) {
return TemplateInteractionUtil.emitsRedstonePower(state);
return ReFramedInteractionUtil.emitsRedstonePower(state);
}
@Override
public int getWeakRedstonePower(BlockState state, BlockView view, BlockPos pos, Direction dir) {
return TemplateInteractionUtil.getWeakRedstonePower(state, view, pos, dir);
return ReFramedInteractionUtil.getWeakRedstonePower(state, view, pos, dir);
}
@Override
public int getStrongRedstonePower(BlockState state, BlockView view, BlockPos pos, Direction dir) {
return TemplateInteractionUtil.getStrongRedstonePower(state, view, pos, dir);
return ReFramedInteractionUtil.getStrongRedstonePower(state, view, pos, dir);
}
}

View File

@ -1,7 +1,7 @@
package fr.adrien1106.reframedtemplates.block;
package fr.adrien1106.reframed.block;
import com.google.common.base.MoreObjects;
import fr.adrien1106.reframedtemplates.api.TemplateInteractionUtil;
import fr.adrien1106.reframed.util.ReFramedInteractionUtil;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.ShapeContext;
@ -14,8 +14,8 @@ import net.minecraft.util.shape.VoxelShape;
import net.minecraft.world.BlockView;
import org.jetbrains.annotations.Nullable;
public class TemplatePostBlock extends WaterloggableTemplateBlock {
public TemplatePostBlock(Settings settings) {
public class ReFramedPostBlock extends WaterloggableReFramedBlock {
public ReFramedPostBlock(Settings settings) {
super(settings);
setDefaultState(getDefaultState().with(Properties.AXIS, Direction.Axis.Y));
@ -28,7 +28,6 @@ public class TemplatePostBlock extends WaterloggableTemplateBlock {
@Override
public @Nullable BlockState getPlacementState(ItemPlacementContext ctx) {
//not calling TemplateInteractionUtil.modifyPlacementState because we extend WaterloggableTemplateBlock which already does
BlockState sup = super.getPlacementState(ctx);
if(sup != null) sup = sup.with(Properties.AXIS, ctx.getSide().getAxis());
return sup;
@ -48,7 +47,7 @@ public class TemplatePostBlock extends WaterloggableTemplateBlock {
@Override
public VoxelShape getCollisionShape(BlockState state, BlockView view, BlockPos pos, ShapeContext ctx) {
return MoreObjects.firstNonNull(TemplateInteractionUtil.getCollisionShape(state, view, pos, ctx), shap(state));
return MoreObjects.firstNonNull(ReFramedInteractionUtil.getCollisionShape(state, view, pos, ctx), shap(state));
}
@Override

View File

@ -1,8 +1,8 @@
package fr.adrien1106.reframedtemplates.block;
package fr.adrien1106.reframed.block;
import com.google.common.base.MoreObjects;
import fr.adrien1106.reframedtemplates.Templates;
import fr.adrien1106.reframedtemplates.api.TemplateInteractionUtil;
import fr.adrien1106.reframed.ReFramed;
import fr.adrien1106.reframed.util.ReFramedInteractionUtil;
import net.minecraft.block.*;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.entity.LivingEntity;
@ -20,66 +20,65 @@ import net.minecraft.world.BlockView;
import net.minecraft.world.World;
import org.jetbrains.annotations.Nullable;
public class TemplatePressurePlateBlock extends PressurePlateBlock implements BlockEntityProvider {
public TemplatePressurePlateBlock(Settings settings, BlockSetType blockSetType) {
public class ReFramedPressurePlateBlock extends PressurePlateBlock implements BlockEntityProvider {
public ReFramedPressurePlateBlock(Settings settings, BlockSetType blockSetType) {
super(blockSetType, settings);
setDefaultState(TemplateInteractionUtil.setDefaultStates(getDefaultState()));
setDefaultState(ReFramedInteractionUtil.setDefaultStates(getDefaultState()));
}
public TemplatePressurePlateBlock(Settings settings) {
public ReFramedPressurePlateBlock(Settings settings) {
this(settings, BlockSetType.OAK);
}
@Override
public @Nullable BlockEntity createBlockEntity(BlockPos pos, BlockState state) {
return Templates.TEMPLATE_BLOCK_ENTITY.instantiate(pos, state);
return ReFramed.REFRAMED_BLOCK_ENTITY.instantiate(pos, state);
}
@Override
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
super.appendProperties(TemplateInteractionUtil.appendProperties(builder));
super.appendProperties(ReFramedInteractionUtil.appendProperties(builder));
}
@Nullable
@Override
public BlockState getPlacementState(ItemPlacementContext ctx) {
return TemplateInteractionUtil.modifyPlacementState(super.getPlacementState(ctx), ctx);
return ReFramedInteractionUtil.modifyPlacementState(super.getPlacementState(ctx), ctx);
}
@Override
public ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) {
ActionResult r = TemplateInteractionUtil.onUse(state, world, pos, player, hand, hit);
ActionResult r = ReFramedInteractionUtil.onUse(state, world, pos, player, hand, hit);
if(!r.isAccepted()) r = super.onUse(state, world, pos, player, hand, hit);
return r;
}
@Override
public void onStateReplaced(BlockState state, World world, BlockPos pos, BlockState newState, boolean moved) {
TemplateInteractionUtil.onStateReplaced(state, world, pos, newState, moved);
ReFramedInteractionUtil.onStateReplaced(state, world, pos, newState, moved);
super.onStateReplaced(state, world, pos, newState, moved);
}
@Override
public void onPlaced(World world, BlockPos pos, BlockState state, @Nullable LivingEntity placer, ItemStack stack) {
TemplateInteractionUtil.onPlaced(world, pos, state, placer, stack);
ReFramedInteractionUtil.onPlaced(world, pos, state, placer, stack);
super.onPlaced(world, pos, state, placer, stack);
}
@Override
public VoxelShape getCollisionShape(BlockState state, BlockView view, BlockPos pos, ShapeContext ctx) {
return MoreObjects.firstNonNull(TemplateInteractionUtil.getCollisionShape(state, view, pos, ctx), super.getCollisionShape(state, view, pos, ctx));
return MoreObjects.firstNonNull(ReFramedInteractionUtil.getCollisionShape(state, view, pos, ctx), super.getCollisionShape(state, view, pos, ctx));
}
@Override
public boolean emitsRedstonePower(BlockState state) {
//return TemplateInteractionUtil.emitsRedstonePower(state);
return super.emitsRedstonePower(state);
}
@Override
public int getWeakRedstonePower(BlockState state, BlockView view, BlockPos pos, Direction dir) {
boolean a = 0 != super.getWeakRedstonePower(state, view, pos, dir);
boolean b = 0 != TemplateInteractionUtil.getWeakRedstonePower(state, view, pos, dir);
boolean b = 0 != ReFramedInteractionUtil.getWeakRedstonePower(state, view, pos, dir);
return (a ^ b) ? 15 : 0;
}

View File

@ -1,6 +1,6 @@
package fr.adrien1106.reframedtemplates.block;
package fr.adrien1106.reframed.block;
import fr.adrien1106.reframedtemplates.generator.MultipartBlockStateProvider;
import fr.adrien1106.reframed.generator.MultipartBlockStateProvider;
import net.minecraft.block.*;
import net.minecraft.data.client.MultipartBlockStateSupplier;
import net.minecraft.item.ItemPlacementContext;
@ -13,7 +13,7 @@ import net.minecraft.util.shape.VoxelShapes;
import net.minecraft.world.BlockView;
import org.jetbrains.annotations.Nullable;
public class TemplateSlabBlock extends WaterloggableTemplateBlock implements MultipartBlockStateProvider {
public class ReFramedSlabBlock extends WaterloggableReFramedBlock implements MultipartBlockStateProvider {
private static final VoxelShape DOWN = VoxelShapes.cuboid(0f, 0f, 0f, 1f, 0.5f, 1f);
private static final VoxelShape UP = VoxelShapes.cuboid(0f, 0.5f, 0f, 1f, 1f, 1f);
@ -22,7 +22,7 @@ public class TemplateSlabBlock extends WaterloggableTemplateBlock implements Mul
private static final VoxelShape EAST = VoxelShapes.cuboid(0.5f, 0f, 0f, 1f, 1f, 1f);
private static final VoxelShape WEST = VoxelShapes.cuboid(0f, 0f, 0f, 0.5f, 1f, 1f);
public TemplateSlabBlock(Settings settings) {
public ReFramedSlabBlock(Settings settings) {
super(settings);
setDefaultState(getDefaultState().with(Properties.FACING, Direction.DOWN));
}

View File

@ -1,11 +1,11 @@
package fr.adrien1106.reframedtemplates.block;
package fr.adrien1106.reframed.block;
import fr.adrien1106.reframedtemplates.Templates;
import fr.adrien1106.reframedtemplates.generator.GBlockstate;
import fr.adrien1106.reframedtemplates.generator.MultipartBlockStateProvider;
import fr.adrien1106.reframedtemplates.util.VoxelHelper;
import fr.adrien1106.reframedtemplates.util.property.StairDirection;
import fr.adrien1106.reframedtemplates.util.property.StairShape;
import fr.adrien1106.reframed.ReFramed;
import fr.adrien1106.reframed.generator.GBlockstate;
import fr.adrien1106.reframed.generator.MultipartBlockStateProvider;
import fr.adrien1106.reframed.util.VoxelHelper;
import fr.adrien1106.reframed.util.property.StairDirection;
import fr.adrien1106.reframed.util.property.StairShape;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.ShapeContext;
@ -30,17 +30,17 @@ import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;
import static fr.adrien1106.reframedtemplates.util.property.StairShape.*;
import static fr.adrien1106.reframed.util.property.StairShape.*;
import static net.minecraft.data.client.VariantSettings.Rotation.*;
import static fr.adrien1106.reframedtemplates.util.property.StairDirection.*;
import static fr.adrien1106.reframed.util.property.StairDirection.*;
public class TemplateStairsBlock extends WaterloggableTemplateBlock implements MultipartBlockStateProvider {
public class ReFramedStairsBlock extends WaterloggableReFramedBlock implements MultipartBlockStateProvider {
public static final EnumProperty<StairDirection> FACING = EnumProperty.of("facing", StairDirection.class);
public static final EnumProperty<StairShape> SHAPE = EnumProperty.of("shape", StairShape.class);
private static final List<VoxelShape> VOXEL_LIST= new ArrayList<>();
public TemplateStairsBlock(Settings settings) {
public ReFramedStairsBlock(Settings settings) {
super(settings);
setDefaultState(getDefaultState().with(FACING, StairDirection.NORTH_DOWN).with(SHAPE, STRAIGHT));
}
@ -215,7 +215,7 @@ public class TemplateStairsBlock extends WaterloggableTemplateBlock implements M
pos.offset(reverse ? direction.getOpposite() : direction)
);
if (block_state.getBlock() instanceof TemplateStairsBlock && block_state.get(FACING).hasDirection(reference)) {
if (block_state.getBlock() instanceof ReFramedStairsBlock && block_state.get(FACING).hasDirection(reference)) {
if (block_state.get(FACING).hasDirection(face.getLeftDirection())) return "left";
else if (block_state.get(FACING).hasDirection(face.getRightDirection())) return "right";
}
@ -260,10 +260,10 @@ public class TemplateStairsBlock extends WaterloggableTemplateBlock implements M
@Override
public MultipartBlockStateSupplier getMultipart() {
Identifier straight_id = Templates.id("stairs_special");
Identifier double_outer_id = Templates.id("double_outer_stairs_special");
Identifier inner_id = Templates.id("inner_stairs_special");
Identifier outer_id = Templates.id("outer_stairs_special");
Identifier straight_id = ReFramed.id("stairs_special");
Identifier double_outer_id = ReFramed.id("double_outer_stairs_special");
Identifier inner_id = ReFramed.id("inner_stairs_special");
Identifier outer_id = ReFramed.id("outer_stairs_special");
return MultipartBlockStateSupplier.create(this)
/* STRAIGHT X AXIS */
.with(GBlockstate.when(FACING, DOWN_EAST, SHAPE, STRAIGHT),

View File

@ -1,9 +1,9 @@
package fr.adrien1106.reframedtemplates.block;
package fr.adrien1106.reframed.block;
import com.google.common.base.MoreObjects;
import fr.adrien1106.reframedtemplates.Templates;
import fr.adrien1106.reframedtemplates.api.TemplateInteractionUtil;
import fr.adrien1106.reframedtemplates.api.TemplateInteractionUtilExt;
import fr.adrien1106.reframed.ReFramed;
import fr.adrien1106.reframed.util.ReFramedInteractionUtil;
import fr.adrien1106.reframed.util.ReframedInteractible;
import net.minecraft.block.Block;
import net.minecraft.block.BlockEntityProvider;
import net.minecraft.block.BlockSetType;
@ -26,73 +26,69 @@ import net.minecraft.world.BlockView;
import net.minecraft.world.World;
import org.jetbrains.annotations.Nullable;
public class TemplateTrapdoorBlock extends TrapdoorBlock implements BlockEntityProvider, TemplateInteractionUtilExt {
public TemplateTrapdoorBlock(Settings settings, BlockSetType woodType) {
public class ReFramedTrapdoorBlock extends TrapdoorBlock implements BlockEntityProvider, ReframedInteractible {
public ReFramedTrapdoorBlock(Settings settings, BlockSetType woodType) {
super(woodType, settings);
setDefaultState(TemplateInteractionUtil.setDefaultStates(getDefaultState()));
}
public TemplateTrapdoorBlock(Settings settings) {
this(settings, BlockSetType.OAK);
setDefaultState(ReFramedInteractionUtil.setDefaultStates(getDefaultState()));
}
@Override
public @Nullable BlockEntity createBlockEntity(BlockPos pos, BlockState state) {
return Templates.TEMPLATE_BLOCK_ENTITY.instantiate(pos, state);
return ReFramed.REFRAMED_BLOCK_ENTITY.instantiate(pos, state);
}
@Override
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
super.appendProperties(TemplateInteractionUtil.appendProperties(builder));
super.appendProperties(ReFramedInteractionUtil.appendProperties(builder));
}
@Nullable
@Override
public BlockState getPlacementState(ItemPlacementContext ctx) {
return TemplateInteractionUtil.modifyPlacementState(super.getPlacementState(ctx), ctx);
return ReFramedInteractionUtil.modifyPlacementState(super.getPlacementState(ctx), ctx);
}
@Override
public ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) {
ActionResult r = TemplateInteractionUtil.onUse(state, world, pos, player, hand, hit);
ActionResult r = ReFramedInteractionUtil.onUse(state, world, pos, player, hand, hit);
if(!r.isAccepted()) r = super.onUse(state, world, pos, player, hand, hit);
return r;
}
@Override
public void onStateReplaced(BlockState state, World world, BlockPos pos, BlockState newState, boolean moved) {
TemplateInteractionUtil.onStateReplaced(state, world, pos, newState, moved);
ReFramedInteractionUtil.onStateReplaced(state, world, pos, newState, moved);
super.onStateReplaced(state, world, pos, newState, moved);
}
@Override
public void onPlaced(World world, BlockPos pos, BlockState state, @Nullable LivingEntity placer, ItemStack stack) {
TemplateInteractionUtil.onPlaced(world, pos, state, placer, stack);
ReFramedInteractionUtil.onPlaced(world, pos, state, placer, stack);
super.onPlaced(world, pos, state, placer, stack);
}
@Override
public VoxelShape getCollisionShape(BlockState state, BlockView view, BlockPos pos, ShapeContext ctx) {
return MoreObjects.firstNonNull(TemplateInteractionUtil.getCollisionShape(state, view, pos, ctx), super.getCollisionShape(state, view, pos, ctx));
return MoreObjects.firstNonNull(ReFramedInteractionUtil.getCollisionShape(state, view, pos, ctx), super.getCollisionShape(state, view, pos, ctx));
}
@Override
public boolean emitsRedstonePower(BlockState state) {
return TemplateInteractionUtil.emitsRedstonePower(state);
return ReFramedInteractionUtil.emitsRedstonePower(state);
}
@Override
public int getWeakRedstonePower(BlockState state, BlockView view, BlockPos pos, Direction dir) {
return TemplateInteractionUtil.getWeakRedstonePower(state, view, pos, dir);
return ReFramedInteractionUtil.getWeakRedstonePower(state, view, pos, dir);
}
@Override
public int getStrongRedstonePower(BlockState state, BlockView view, BlockPos pos, Direction dir) {
return TemplateInteractionUtil.getStrongRedstonePower(state, view, pos, dir);
return ReFramedInteractionUtil.getStrongRedstonePower(state, view, pos, dir);
}
@Override
public boolean templatesPlayerCanAddRedstoneEmission(BlockState state, BlockView view, BlockPos pos) {
public boolean canAddRedstoneEmission(BlockState state, BlockView view, BlockPos pos) {
return false;
}
}

View File

@ -1,9 +1,9 @@
package fr.adrien1106.reframedtemplates.block;
package fr.adrien1106.reframed.block;
import com.google.common.base.MoreObjects;
import fr.adrien1106.reframedtemplates.Templates;
import fr.adrien1106.reframedtemplates.api.TemplateInteractionUtil;
import fr.adrien1106.reframedtemplates.mixin.WallBlockAccessor;
import fr.adrien1106.reframed.ReFramed;
import fr.adrien1106.reframed.util.ReFramedInteractionUtil;
import fr.adrien1106.reframed.mixin.WallBlockAccessor;
import net.minecraft.block.Block;
import net.minecraft.block.BlockEntityProvider;
import net.minecraft.block.BlockState;
@ -30,10 +30,10 @@ import org.jetbrains.annotations.Nullable;
import java.util.HashMap;
import java.util.Map;
public class TemplateWallBlock extends WallBlock implements BlockEntityProvider {
public TemplateWallBlock(Settings settings) {
public class ReFramedWallBlock extends WallBlock implements BlockEntityProvider {
public ReFramedWallBlock(Settings settings) {
super(settings);
setDefaultState(TemplateInteractionUtil.setDefaultStates(getDefaultState()));
setDefaultState(ReFramedInteractionUtil.setDefaultStates(getDefaultState()));
initNewShapemaps(); //WallBlock specific haxx
}
@ -41,41 +41,41 @@ public class TemplateWallBlock extends WallBlock implements BlockEntityProvider
@Nullable
@Override
public BlockEntity createBlockEntity(BlockPos pos, BlockState state) {
return Templates.TEMPLATE_BLOCK_ENTITY.instantiate(pos, state);
return ReFramed.REFRAMED_BLOCK_ENTITY.instantiate(pos, state);
}
@Override
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
super.appendProperties(TemplateInteractionUtil.appendProperties(builder));
super.appendProperties(ReFramedInteractionUtil.appendProperties(builder));
}
@Nullable
@Override
public BlockState getPlacementState(ItemPlacementContext ctx) {
return TemplateInteractionUtil.modifyPlacementState(super.getPlacementState(ctx), ctx);
return ReFramedInteractionUtil.modifyPlacementState(super.getPlacementState(ctx), ctx);
}
@Override
public ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) {
ActionResult r = TemplateInteractionUtil.onUse(state, world, pos, player, hand, hit);
ActionResult r = ReFramedInteractionUtil.onUse(state, world, pos, player, hand, hit);
if(!r.isAccepted()) r = super.onUse(state, world, pos, player, hand, hit);
return r;
}
@Override
public void onStateReplaced(BlockState state, World world, BlockPos pos, BlockState newState, boolean moved) {
TemplateInteractionUtil.onStateReplaced(state, world, pos, newState, moved);
ReFramedInteractionUtil.onStateReplaced(state, world, pos, newState, moved);
super.onStateReplaced(state, world, pos, newState, moved);
}
@Override
public void onPlaced(World world, BlockPos pos, BlockState state, @Nullable LivingEntity placer, ItemStack stack) {
TemplateInteractionUtil.onPlaced(world, pos, state, placer, stack);
ReFramedInteractionUtil.onPlaced(world, pos, state, placer, stack);
}
@Override
public VoxelShape getCollisionShape(BlockState state, BlockView view, BlockPos pos, ShapeContext ctx) {
return MoreObjects.firstNonNull(TemplateInteractionUtil.getCollisionShape(state, view, pos, ctx), getNewShape(state, newCollisionShapeMap));
return MoreObjects.firstNonNull(ReFramedInteractionUtil.getCollisionShape(state, view, pos, ctx), getNewShape(state, newCollisionShapeMap));
}
@Override
@ -85,17 +85,17 @@ public class TemplateWallBlock extends WallBlock implements BlockEntityProvider
@Override
public boolean emitsRedstonePower(BlockState state) {
return TemplateInteractionUtil.emitsRedstonePower(state);
return ReFramedInteractionUtil.emitsRedstonePower(state);
}
@Override
public int getWeakRedstonePower(BlockState state, BlockView view, BlockPos pos, Direction dir) {
return TemplateInteractionUtil.getWeakRedstonePower(state, view, pos, dir);
return ReFramedInteractionUtil.getWeakRedstonePower(state, view, pos, dir);
}
@Override
public int getStrongRedstonePower(BlockState state, BlockView view, BlockPos pos, Direction dir) {
return TemplateInteractionUtil.getStrongRedstonePower(state, view, pos, dir);
return ReFramedInteractionUtil.getStrongRedstonePower(state, view, pos, dir);
}
//Shapemap heck (WallBlock has a map keyed on BlockState, but since we add more blockstates most of those map lookups fail)
@ -116,8 +116,8 @@ public class TemplateWallBlock extends WallBlock implements BlockEntityProvider
protected final Map<ShapeKey, VoxelShape> newCollisionShapeMap = new HashMap<>();
protected void initNewShapemaps() {
initNewShapemap(((WallBlockAccessor) this).templates$getShapeMap(), newShapeMap);
initNewShapemap(((WallBlockAccessor) this).templates$getCollisionShapeMap(), newCollisionShapeMap);
initNewShapemap(((WallBlockAccessor) this).getShapeMap(), newShapeMap);
initNewShapemap(((WallBlockAccessor) this).getCollisionShapeMap(), newCollisionShapeMap);
}
protected void initNewShapemap(Map<BlockState, VoxelShape> oldShapeMap, Map<ShapeKey, VoxelShape> newShapeMap) {

View File

@ -1,4 +1,4 @@
package fr.adrien1106.reframedtemplates.block;
package fr.adrien1106.reframed.block;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
@ -13,8 +13,8 @@ import net.minecraft.util.math.Direction;
import net.minecraft.world.WorldAccess;
import org.jetbrains.annotations.Nullable;
public class WaterloggableTemplateBlock extends TemplateBlock implements Waterloggable {
public WaterloggableTemplateBlock(Settings settings) {
public class WaterloggableReFramedBlock extends ReFramedBlock implements Waterloggable {
public WaterloggableReFramedBlock(Settings settings) {
super(settings);
setDefaultState(getDefaultState().with(Properties.WATERLOGGED, false));
@ -28,7 +28,6 @@ public class WaterloggableTemplateBlock extends TemplateBlock implements Waterlo
@Nullable
@Override
public BlockState getPlacementState(ItemPlacementContext ctx) {
//not calling TemplateInteractionUtil.modifyPlacementState because we extend TemplateBlock which already does
BlockState sup = super.getPlacementState(ctx);
if(sup != null) sup = sup.with(Properties.WATERLOGGED, ctx.getWorld().getFluidState(ctx.getBlockPos()).isOf(Fluids.WATER));
return sup;

View File

@ -0,0 +1,117 @@
package fr.adrien1106.reframed.client;
import fr.adrien1106.reframed.ReFramed;
import net.fabricmc.api.ClientModInitializer;
import net.fabricmc.fabric.api.blockrenderlayer.v1.BlockRenderLayerMap;
import net.fabricmc.fabric.api.client.model.ModelLoadingRegistry;
import net.fabricmc.fabric.api.resource.ResourceManagerHelper;
import net.fabricmc.fabric.api.resource.SimpleSynchronousResourceReloadListener;
import net.minecraft.block.Block;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.render.RenderLayer;
import net.minecraft.resource.ResourceManager;
import net.minecraft.resource.ResourceType;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.ChunkSectionPos;
public class ReFramedClient implements ClientModInitializer {
public static final ReFramedModelProvider PROVIDER = new ReFramedModelProvider();
public static final ReFramedClientHelper HELPER = new ReFramedClientHelper(PROVIDER);
@Override
public void onInitializeClient() {
privateInit(); //<- Stuff you shouldn't replicate in any addon mods ;)
//all frames mustn't be on the SOLID layer because they are not opaque!
BlockRenderLayerMap.INSTANCE.putBlocks(RenderLayer.getCutout(), ReFramed.BLOCKS.toArray(new Block[0]));
HELPER.addReFramedModel(ReFramed.id("button_special") , HELPER.auto(new Identifier("block/button")));
HELPER.addReFramedModel(ReFramed.id("button_pressed_special") , HELPER.auto(new Identifier("block/button_pressed")));
HELPER.addReFramedModel(ReFramed.id("one_candle_special") , HELPER.auto(new Identifier("block/template_candle")));
HELPER.addReFramedModel(ReFramed.id("two_candles_special") , HELPER.auto(new Identifier("block/template_two_candles")));
HELPER.addReFramedModel(ReFramed.id("three_candles_special") , HELPER.auto(new Identifier("block/template_three_candles")));
HELPER.addReFramedModel(ReFramed.id("four_candles_special") , HELPER.auto(new Identifier("block/template_four_candles")));
HELPER.addReFramedModel(ReFramed.id("carpet_special") , HELPER.auto(new Identifier("block/carpet")));
HELPER.addReFramedModel(ReFramed.id("cube_special") , HELPER.auto(new Identifier("block/cube")));
HELPER.addReFramedModel(ReFramed.id("door_bottom_left_special") , HELPER.auto(new Identifier("block/door_bottom_left")));
HELPER.addReFramedModel(ReFramed.id("door_bottom_right_special") , HELPER.auto(new Identifier("block/door_bottom_right")));
HELPER.addReFramedModel(ReFramed.id("door_top_left_special") , HELPER.auto(new Identifier("block/door_top_left")));
HELPER.addReFramedModel(ReFramed.id("door_top_right_special") , HELPER.auto(new Identifier("block/door_top_right")));
HELPER.addReFramedModel(ReFramed.id("door_bottom_left_open_special"), HELPER.auto(new Identifier("block/door_bottom_left_open")));
HELPER.addReFramedModel(ReFramed.id("door_bottom_right_open_special"), HELPER.auto(new Identifier("block/door_bottom_right_open"))); //This is why we dont format code as tables kids
HELPER.addReFramedModel(ReFramed.id("door_top_left_open_special") , HELPER.auto(new Identifier("block/door_top_left_open")));
HELPER.addReFramedModel(ReFramed.id("door_top_right_open_special") , HELPER.auto(new Identifier("block/door_top_right_open")));
HELPER.addReFramedModel(ReFramed.id("fence_post_special") , HELPER.auto(new Identifier("block/fence_post")));
HELPER.addReFramedModel(ReFramed.id("fence_gate_special") , HELPER.auto(new Identifier("block/template_fence_gate")));
HELPER.addReFramedModel(ReFramed.id("fence_gate_open_special") , HELPER.auto(new Identifier("block/template_fence_gate_open")));
HELPER.addReFramedModel(ReFramed.id("fence_gate_wall_special") , HELPER.auto(new Identifier("block/template_fence_gate_wall")));
HELPER.addReFramedModel(ReFramed.id("fence_gate_wall_open_special") , HELPER.auto(new Identifier("block/template_fence_gate_wall_open")));
HELPER.addReFramedModel(ReFramed.id("glass_pane_post_special") , HELPER.auto(new Identifier("block/glass_pane_post")));
HELPER.addReFramedModel(ReFramed.id("glass_pane_noside_special") , HELPER.auto(new Identifier("block/glass_pane_noside")));
HELPER.addReFramedModel(ReFramed.id("glass_pane_noside_alt_special"), HELPER.auto(new Identifier("block/glass_pane_noside_alt")));
HELPER.addReFramedModel(ReFramed.id("pressure_plate_up_special") , HELPER.auto(new Identifier("block/pressure_plate_up")));
HELPER.addReFramedModel(ReFramed.id("pressure_plate_down_special") , HELPER.auto(new Identifier("block/pressure_plate_down")));
HELPER.addReFramedModel(ReFramed.id("slab_special") , HELPER.auto(new Identifier("block/slab")));
HELPER.addReFramedModel(ReFramed.id("stairs_special") , HELPER.auto(new Identifier("block/stairs")));
HELPER.addReFramedModel(ReFramed.id("double_outer_stairs_special") , HELPER.auto(ReFramed.id("block/double_outer_stairs")));
HELPER.addReFramedModel(ReFramed.id("inner_stairs_special") , HELPER.auto(new Identifier("block/inner_stairs")));
HELPER.addReFramedModel(ReFramed.id("outer_stairs_special") , HELPER.auto(new Identifier("block/outer_stairs")));
HELPER.addReFramedModel(ReFramed.id("trapdoor_bottom_special") , HELPER.auto(new Identifier("block/template_trapdoor_bottom")));
HELPER.addReFramedModel(ReFramed.id("trapdoor_top_special") , HELPER.auto(new Identifier("block/template_trapdoor_top")));
HELPER.addReFramedModel(ReFramed.id("wall_post_special") , HELPER.auto(new Identifier("block/template_wall_post")));
//vanilla style models (using "special-sprite replacement" method)
HELPER.addReFramedModel(ReFramed.id("lever_special") , HELPER.json(ReFramed.id("block/lever")));
HELPER.addReFramedModel(ReFramed.id("trapdoor_open_special") , HELPER.json(ReFramed.id("block/trapdoor_open")));
HELPER.addReFramedModel(ReFramed.id("lever_on_special") , HELPER.json(ReFramed.id("block/lever_on")));
//these next five only exist because AutoRetexturedModels don't seem to rotate their textures the right way when rotated from a multipart blockstate
HELPER.addReFramedModel(ReFramed.id("fence_side_special") , HELPER.json(ReFramed.id("block/fence_side")));
HELPER.addReFramedModel(ReFramed.id("glass_pane_side_special") , HELPER.json(ReFramed.id("block/glass_pane_side")));
HELPER.addReFramedModel(ReFramed.id("glass_pane_side_alt_special") , HELPER.json(ReFramed.id("block/glass_pane_side_alt")));
HELPER.addReFramedModel(ReFramed.id("wall_side_special") , HELPER.json(ReFramed.id("block/wall_side")));
HELPER.addReFramedModel(ReFramed.id("wall_side_tall_special") , HELPER.json(ReFramed.id("block/wall_side_tall")));
//item only models
HELPER.addReFramedModel(ReFramed.id("button_inventory_special") , HELPER.auto(new Identifier("block/button_inventory")));
HELPER.addReFramedModel(ReFramed.id("fence_inventory_special") , HELPER.auto(new Identifier("block/fence_inventory")));
HELPER.addReFramedModel(ReFramed.id("fence_post_inventory_special") , HELPER.auto(ReFramed.id("block/fence_post_inventory")));
HELPER.addReFramedModel(ReFramed.id("wall_inventory_special") , HELPER.auto(new Identifier("block/wall_inventory")));
//item model assignments (in lieu of models/item/___.json)
HELPER.assignItemModel(ReFramed.id("button_inventory_special") , ReFramed.BUTTON);
HELPER.assignItemModel(ReFramed.id("carpet_special") , ReFramed.CARPET);
HELPER.assignItemModel(ReFramed.id("cube_special") , ReFramed.CUBE);
HELPER.assignItemModel(ReFramed.id("fence_inventory_special") , ReFramed.FENCE);
HELPER.assignItemModel(ReFramed.id("fence_gate_special") , ReFramed.FENCE_GATE);
HELPER.assignItemModel(ReFramed.id("trapdoor_bottom_special") , ReFramed.IRON_TRAPDOOR);
HELPER.assignItemModel(ReFramed.id("fence_post_inventory_special") , ReFramed.POST);
HELPER.assignItemModel(ReFramed.id("pressure_plate_up_special") , ReFramed.PRESSURE_PLATE);
HELPER.assignItemModel(ReFramed.id("slab_special") , ReFramed.SLAB);
HELPER.assignItemModel(ReFramed.id("stairs_special") , ReFramed.STAIRS);
HELPER.assignItemModel(ReFramed.id("trapdoor_bottom_special") , ReFramed.TRAPDOOR);
HELPER.assignItemModel(ReFramed.id("wall_inventory_special") , ReFramed.WALL);
}
private void privateInit() {
//set up some magic to force chunk rerenders when you change a template (see TemplateEntity)
ReFramed.chunkRerenderProxy = (world, pos) -> {
if(world == MinecraftClient.getInstance().world) {
MinecraftClient.getInstance().worldRenderer.scheduleBlockRender(
ChunkSectionPos.getSectionCoord(pos.getX()),
ChunkSectionPos.getSectionCoord(pos.getY()),
ChunkSectionPos.getSectionCoord(pos.getZ())
);
}
};
//supporting code for the TemplatesModelProvider
ModelLoadingRegistry.INSTANCE.registerResourceProvider(rm -> PROVIDER); //block models
ModelLoadingRegistry.INSTANCE.registerVariantProvider(rm -> PROVIDER); //item models
ResourceManagerHelper.get(ResourceType.CLIENT_RESOURCES).registerReloadListener(new SimpleSynchronousResourceReloadListener() {
@Override public Identifier getFabricId() { return ReFramed.id("dump-caches"); }
@Override public void reload(ResourceManager blah) { PROVIDER.dumpCache(); }
});
}
}

View File

@ -0,0 +1,60 @@
package fr.adrien1106.reframed.client;
import fr.adrien1106.reframed.client.model.apperance.CamoAppearanceManager;
import fr.adrien1106.reframed.client.model.UnbakedAutoRetexturedModel;
import fr.adrien1106.reframed.client.model.UnbakedJsonRetexturedModel;
import net.fabricmc.fabric.api.renderer.v1.Renderer;
import net.fabricmc.fabric.api.renderer.v1.RendererAccess;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.client.render.model.UnbakedModel;
import net.minecraft.client.texture.Sprite;
import net.minecraft.client.util.SpriteIdentifier;
import net.minecraft.item.ItemConvertible;
import net.minecraft.util.Identifier;
import org.jetbrains.annotations.NotNull;
import java.util.function.Function;
public class ReFramedClientHelper {
public ReFramedClientHelper(ReFramedModelProvider prov) {
this.prov = prov;
}
private final ReFramedModelProvider prov;
public UnbakedModel auto(Identifier parent) {
return new UnbakedAutoRetexturedModel(parent);
}
public UnbakedModel json(Identifier parent) {
return new UnbakedJsonRetexturedModel(parent);
}
public void addReFramedModel(Identifier id, UnbakedModel unbaked) {
prov.addReFramedModel(id, unbaked);
}
public void assignItemModel(Identifier model_id, ItemConvertible... item_convertibles) {
prov.assignItemModel(model_id, item_convertibles);
}
public CamoAppearanceManager getCamoApperanceManager(Function<SpriteIdentifier, Sprite> spriteLookup) {
return prov.getCamoApperanceManager(spriteLookup);
}
public @NotNull Renderer getFabricRenderer() {
Renderer obj = RendererAccess.INSTANCE.getRenderer();
if(obj != null) return obj;
//Welp, not much more we can do, this mod heavily relies on frapi
String msg = "A Fabric Rendering API implementation is required to use ReFramed!";
if(!FabricLoader.getInstance().isModLoaded("fabric-renderer-indigo"))
msg += "\nI noticed you don't have Indigo installed, which is a part of the complete Fabric API package.";
if(FabricLoader.getInstance().isModLoaded("sodium"))
msg += "\nI noticed you have Sodium installed - consider also installing Indium to provide a compatible renderer implementation.";
throw new NullPointerException(msg);
}
}

View File

@ -1,6 +1,6 @@
package fr.adrien1106.reframedtemplates;
package fr.adrien1106.reframed.client;
import fr.adrien1106.reframedtemplates.model.apperance.TemplateAppearanceManager;
import fr.adrien1106.reframed.client.model.apperance.CamoAppearanceManager;
import net.fabricmc.fabric.api.client.model.ModelProviderContext;
import net.fabricmc.fabric.api.client.model.ModelResourceProvider;
import net.fabricmc.fabric.api.client.model.ModelVariantProvider;
@ -18,11 +18,11 @@ import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
public class TemplatesModelProvider implements ModelResourceProvider, ModelVariantProvider {
public class ReFramedModelProvider implements ModelResourceProvider, ModelVariantProvider {
private final Map<Identifier, UnbakedModel> models = new HashMap<>();
private final Map<ModelIdentifier, Identifier> itemAssignments = new HashMap<>();
private volatile TemplateAppearanceManager appearanceManager;
private volatile CamoAppearanceManager appearanceManager;
/// fabric model provider api
@ -34,7 +34,7 @@ public class TemplatesModelProvider implements ModelResourceProvider, ModelVaria
//For blocks, you can point the game directly at the custom model in the blockstate json file.
//Item models don't have that layer of indirection; it always wants to load the hardcoded "item:id#inventory" model.
//You *would* be able to create a model json for it and set the "parent" field to the custom model,
//but json models are never allowed to have non-json models as a parent, and template unbaked models are not json models. Ah well.
//but json models are never allowed to have non-json models as a parent, and frame unbaked models are not json models. Ah well.
//So, instead, we use a ModelVariantProvider to redirect attempts to load the item:id#inventory model.
@Override
public @Nullable UnbakedModel loadModelVariant(ModelIdentifier modelId, ModelProviderContext context) {
@ -42,16 +42,16 @@ public class TemplatesModelProvider implements ModelResourceProvider, ModelVaria
return customModelId == null ? null : loadModelResource(customModelId, context);
}
/// template appearance manager cache
/// camo appearance manager cache
public TemplateAppearanceManager getOrCreateTemplateApperanceManager(Function<SpriteIdentifier, Sprite> spriteLookup) {
public CamoAppearanceManager getCamoApperanceManager(Function<SpriteIdentifier, Sprite> spriteLookup) {
//This is kind of needlessly sketchy using the "volatile double checked locking" pattern.
//I'd like all template models to use the same TemplateApperanceManager, despite the model
//I'd like all frame models to use the same CamoApperanceManager, despite the model
//baking process happening concurrently on several threads, but I also don't want to
//hold up the model baking process too long.
//Volatile field read:
TemplateAppearanceManager read = appearanceManager;
CamoAppearanceManager read = appearanceManager;
if(read == null) {
//Acquire a lock:
@ -61,7 +61,7 @@ public class TemplatesModelProvider implements ModelResourceProvider, ModelVaria
read = appearanceManager;
if(read == null) {
//If no-one has initialized it still, I guess it falls to us
read = appearanceManager = new TemplateAppearanceManager(spriteLookup);
read = appearanceManager = new CamoAppearanceManager(spriteLookup);
}
}
}
@ -73,19 +73,15 @@ public class TemplatesModelProvider implements ModelResourceProvider, ModelVaria
appearanceManager = null; //volatile write
}
public void addTemplateModel(Identifier id, UnbakedModel unbaked) {
public void addReFramedModel(Identifier id, UnbakedModel unbaked) {
models.put(id, unbaked);
}
public void assignItemModel(Identifier templateModelId, ModelIdentifier... modelIds) {
for(ModelIdentifier modelId : modelIds) itemAssignments.put(modelId, templateModelId);
public void assignItemModel(Identifier model_id, Identifier... itemIds) {
for(Identifier itemId : itemIds) itemAssignments.put(new ModelIdentifier(itemId, "inventory"), model_id);
}
public void assignItemModel(Identifier templateModelId, Identifier... itemIds) {
for(Identifier itemId : itemIds) itemAssignments.put(new ModelIdentifier(itemId, "inventory"), templateModelId);
}
public void assignItemModel(Identifier templateModelId, ItemConvertible... itemConvs) {
for(ItemConvertible itemConv : itemConvs) assignItemModel(templateModelId, Registries.ITEM.getId(itemConv.asItem()));
public void assignItemModel(Identifier model_id, ItemConvertible... itemConvs) {
for(ItemConvertible itemConv : itemConvs) assignItemModel(model_id, Registries.ITEM.getId(itemConv.asItem()));
}
}

View File

@ -1,6 +1,6 @@
package fr.adrien1106.reframedtemplates.model;
package fr.adrien1106.reframed.client.model;
import fr.adrien1106.reframedtemplates.api.TemplatesClientApi;
import fr.adrien1106.reframed.client.ReFramedClient;
import net.fabricmc.fabric.api.renderer.v1.mesh.Mesh;
import net.fabricmc.fabric.api.renderer.v1.mesh.MeshBuilder;
import net.fabricmc.fabric.api.renderer.v1.mesh.QuadEmitter;
@ -16,7 +16,7 @@ import java.util.Map;
public class MeshTransformUtil {
public static Mesh pretransformMesh(Mesh mesh, RenderContext.QuadTransform transform) {
MeshBuilder builder = TemplatesClientApi.getInstance().getFabricRenderer().meshBuilder();
MeshBuilder builder = ReFramedClient.HELPER.getFabricRenderer().meshBuilder();
QuadEmitter emitter = builder.getEmitter();
mesh.forEach(quad -> {
@ -27,19 +27,6 @@ public class MeshTransformUtil {
return builder.build();
}
//Hard to explain what this is for...
//Basically, Templates 1.x manually emitted the north/south/east/west faces all individually.
//This means it was easy to get the orientation of the block correct - to popular the north face of the slope, look at
//the north texture of the theme block. In this version, there is only *one* slope model that is dynamically rotated
//to form the other possible orientations. If I populate the north face of the model using the north face of the theme,
//then rotate the model, it's no longer facing the right way. So I need to "un-rotate" the face assignments first.
//
//This seems to work, but I'm kinda surprised I don't need to invert the transformation here, which is a clue that
//I don't really understand all the math, loool
public static Map<Direction, Direction> facePermutation(ModelBakeSettings aff) {
return facePermutation(aff.getRotation().getMatrix());
}
public static Map<Direction, Direction> facePermutation(Matrix4f mat) {
Map<Direction, Direction> facePermutation = new EnumMap<>(Direction.class);
for(Direction input : Direction.values()) {

View File

@ -1,4 +1,4 @@
package fr.adrien1106.reframedtemplates.model;
package fr.adrien1106.reframed.client.model;
import net.fabricmc.fabric.api.renderer.v1.mesh.MutableQuadView;
import net.fabricmc.fabric.api.renderer.v1.mesh.QuadView;
@ -21,7 +21,7 @@ record QuadUvBounds(float minU, float maxU, float minV, float maxV) {
return sprite.getMinU() <= minU && sprite.getMaxU() >= maxU && sprite.getMinV() <= minV && sprite.getMaxV() >= maxV;
}
void normalizeUv(MutableQuadView quad, Sprite sprite) { // TODO find out for sprites rotations and mirroring
void normalizeUv(MutableQuadView quad, Sprite sprite) {
float remappedMinU = norm(minU, sprite.getMinU(), sprite.getMaxU());
float remappedMaxU = norm(maxU, sprite.getMinU(), sprite.getMaxU());
float remappedMinV = norm(minV, sprite.getMinV(), sprite.getMaxV());

View File

@ -1,10 +1,10 @@
package fr.adrien1106.reframedtemplates.model;
package fr.adrien1106.reframed.client.model;
import fr.adrien1106.reframedtemplates.block.FramedEntity;
import fr.adrien1106.reframedtemplates.mixin.MinecraftAccessor;
import fr.adrien1106.reframedtemplates.model.apperance.TemplateAppearance;
import fr.adrien1106.reframedtemplates.model.apperance.TemplateAppearanceManager;
import fr.adrien1106.reframedtemplates.model.apperance.WeightedComputedAppearance;
import fr.adrien1106.reframed.block.ReFramedEntity;
import fr.adrien1106.reframed.mixin.MinecraftAccessor;
import fr.adrien1106.reframed.client.model.apperance.CamoAppearance;
import fr.adrien1106.reframed.client.model.apperance.CamoAppearanceManager;
import fr.adrien1106.reframed.client.model.apperance.WeightedComputedAppearance;
import net.fabricmc.fabric.api.renderer.v1.mesh.Mesh;
import net.fabricmc.fabric.api.renderer.v1.mesh.MutableQuadView;
import net.fabricmc.fabric.api.renderer.v1.mesh.QuadEmitter;
@ -27,25 +27,23 @@ import java.util.concurrent.ConcurrentMap;
import java.util.function.Supplier;
public abstract class RetexturingBakedModel extends ForwardingBakedModel {
public RetexturingBakedModel(BakedModel baseModel, TemplateAppearanceManager tam, ModelBakeSettings settings, BlockState itemModelState, boolean ao) {
public RetexturingBakedModel(BakedModel baseModel, CamoAppearanceManager tam, ModelBakeSettings settings, BlockState itemModelState, boolean ao) {
this.wrapped = baseModel; //field from the superclass; vanilla getQuads etc. will delegate through to this
this.tam = tam;
// this.facePermutation = MeshTransformUtil.facePermutation(settings);
this.uvlock = settings.isUvLocked();
this.itemModelState = itemModelState;
this.ao = ao;
}
protected final TemplateAppearanceManager tam;
// protected final Map<Direction, Direction> facePermutation;
protected final CamoAppearanceManager tam;
protected final boolean uvlock;
protected final BlockState itemModelState;
protected final boolean ao;
protected record MeshCacheKey(BlockState state, TransformCacheKey transform) {}
protected final ConcurrentMap<MeshCacheKey, Mesh> retextured_meshes = new ConcurrentHashMap<>(); //mutable, append-only cache
protected record TransformCacheKey(TemplateAppearance appearance, int model_id) {}
protected record TransformCacheKey(CamoAppearance appearance, int model_id) {}
protected final ConcurrentMap<TransformCacheKey, RetexturingTransformer> retextured_transforms = new ConcurrentHashMap<>();
protected static final Direction[] DIRECTIONS = Direction.values();
@ -74,16 +72,16 @@ public abstract class RetexturingBakedModel extends ForwardingBakedModel {
}
if(theme.getBlock() == Blocks.BARRIER) return;
TemplateAppearance template_appearance = tam.getTemplateAppearance(theme);
CamoAppearance camo = tam.getCamoAppearance(theme);
long seed = theme.getRenderingSeed(pos);
int model_id = 0;
if (template_appearance instanceof WeightedComputedAppearance wca) model_id = wca.getAppearanceIndex(seed);
if (camo instanceof WeightedComputedAppearance wca) model_id = wca.getAppearanceIndex(seed);
int tint = 0xFF000000 | MinecraftClient.getInstance().getBlockColors().getColor(theme, blockView, pos, 0);
Mesh untintedMesh = getUntintedRetexturedMesh(
new MeshCacheKey(
state,
new TransformCacheKey(template_appearance, model_id)
new TransformCacheKey(camo, model_id)
),
seed
);
@ -93,7 +91,7 @@ public abstract class RetexturingBakedModel extends ForwardingBakedModel {
if(tint == 0xFFFFFFFF) {
untintedMesh.outputTo(quad_emitter);
} else {
context.pushTransform(new TintingTransformer(template_appearance, tint, seed));
context.pushTransform(new TintingTransformer(camo, tint, seed));
untintedMesh.outputTo(quad_emitter);
context.popTransform();
}
@ -103,12 +101,12 @@ public abstract class RetexturingBakedModel extends ForwardingBakedModel {
public void emitItemQuads(ItemStack stack, Supplier<Random> randomSupplier, RenderContext context) {
//cheeky: if the item has NBT data, pluck out the blockstate from it & look up the item color provider
//none of this is accessible unless you're in creative mode doing ctrl-pick btw
TemplateAppearance nbtAppearance;
CamoAppearance nbtAppearance;
int tint;
BlockState theme = FramedEntity.readStateFromItem(stack);
BlockState theme = ReFramedEntity.readStateFromItem(stack);
if(!theme.isAir()) {
nbtAppearance = tam.getTemplateAppearance(theme);
tint = 0xFF000000 | ((MinecraftAccessor) MinecraftClient.getInstance()).templates$getItemColors().getColor(new ItemStack(theme.getBlock()), 0);
nbtAppearance = tam.getCamoAppearance(theme);
tint = 0xFF000000 | ((MinecraftAccessor) MinecraftClient.getInstance()).getItemColors().getColor(new ItemStack(theme.getBlock()), 0);
} else {
nbtAppearance = tam.getDefaultAppearance();
tint = 0xFFFFFFFF;
@ -137,12 +135,12 @@ public abstract class RetexturingBakedModel extends ForwardingBakedModel {
protected class RetexturingTransformer implements RenderContext.QuadTransform {
private final long seed;
protected RetexturingTransformer(TemplateAppearance ta, long seed) {
protected RetexturingTransformer(CamoAppearance ta, long seed) {
this.ta = ta;
this.seed = seed;
}
protected final TemplateAppearance ta;
protected final CamoAppearance ta;
@Override
public boolean transform(MutableQuadView quad) {
@ -152,7 +150,7 @@ public abstract class RetexturingBakedModel extends ForwardingBakedModel {
if(tag == 0) return true; //Pass the quad through unmodified.
//The quad tag numbers were selected so this magic trick works:
Direction direction = quad.nominalFace(); // facePermutation.get(quad.nominalFace());
Direction direction = quad.nominalFace();
quad.spriteBake(ta.getSprite(direction, seed), MutableQuadView.BAKE_NORMALIZED | ta.getBakeFlags(direction, seed) | (uvlock ? MutableQuadView.BAKE_LOCK_UV : 0));
return true;
}
@ -160,13 +158,13 @@ public abstract class RetexturingBakedModel extends ForwardingBakedModel {
protected class TintingTransformer implements RenderContext.QuadTransform {
private final long seed;
protected TintingTransformer(TemplateAppearance ta, int tint, long seed) {
protected TintingTransformer(CamoAppearance ta, int tint, long seed) {
this.ta = ta;
this.tint = tint;
this.seed = seed;
}
protected final TemplateAppearance ta;
protected final CamoAppearance ta;
protected final int tint;
@Override
@ -174,7 +172,6 @@ public abstract class RetexturingBakedModel extends ForwardingBakedModel {
int tag = quad.tag();
if(tag == 0) return true;
// Direction dir = facePermutation.get(DIRECTIONS[quad.tag() - 1]);
if(ta.hasColor(quad.nominalFace(), seed)) quad.color(tint, tint, tint, tint);
return true;

View File

@ -1,6 +1,6 @@
package fr.adrien1106.reframedtemplates.model;
package fr.adrien1106.reframed.client.model;
import fr.adrien1106.reframedtemplates.api.TemplatesClientApi;
import fr.adrien1106.reframed.client.ReFramedClient;
import net.fabricmc.fabric.api.renderer.v1.Renderer;
import net.fabricmc.fabric.api.renderer.v1.material.RenderMaterial;
import net.fabricmc.fabric.api.renderer.v1.mesh.Mesh;
@ -26,7 +26,7 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.function.Function;
public class UnbakedAutoRetexturedModel implements UnbakedModel, TemplatesClientApi.TweakableUnbakedModel {
public class UnbakedAutoRetexturedModel implements UnbakedModel {
public UnbakedAutoRetexturedModel(Identifier parent) {
this.parent = parent;
}
@ -35,22 +35,6 @@ public class UnbakedAutoRetexturedModel implements UnbakedModel, TemplatesClient
protected BlockState itemModelState = Blocks.AIR.getDefaultState();
protected boolean ao = true;
/// user configuration
@Override
public UnbakedAutoRetexturedModel disableAo() {
ao = false;
return this;
}
@Override
public TemplatesClientApi.TweakableUnbakedModel itemModelState(BlockState state) {
this.itemModelState = state;
return this;
}
/// actual unbakedmodel stuff
@Override
public Collection<Identifier> getModelDependencies() {
return Collections.singletonList(parent);
@ -66,7 +50,7 @@ public class UnbakedAutoRetexturedModel implements UnbakedModel, TemplatesClient
public BakedModel bake(Baker baker, Function<SpriteIdentifier, Sprite> spriteLookup, ModelBakeSettings modelBakeSettings, Identifier identifier) {
return new RetexturingBakedModel(
baker.bake(parent, modelBakeSettings),
TemplatesClientApi.getInstance().getOrCreateTemplateApperanceManager(spriteLookup),
ReFramedClient.HELPER.getCamoApperanceManager(spriteLookup),
modelBakeSettings,
itemModelState,
ao
@ -80,7 +64,7 @@ public class UnbakedAutoRetexturedModel implements UnbakedModel, TemplatesClient
}
private Mesh convertModel(BlockState state) {
Renderer r = TemplatesClientApi.getInstance().getFabricRenderer();
Renderer r = ReFramedClient.HELPER.getFabricRenderer();
MeshBuilder builder = r.meshBuilder();
QuadEmitter emitter = builder.getEmitter();
RenderMaterial mat = tam.getCachedMaterial(state, false);

View File

@ -1,7 +1,7 @@
package fr.adrien1106.reframedtemplates.model;
package fr.adrien1106.reframed.client.model;
import fr.adrien1106.reframedtemplates.Templates;
import fr.adrien1106.reframedtemplates.api.TemplatesClientApi;
import fr.adrien1106.reframed.ReFramed;
import fr.adrien1106.reframed.client.ReFramedClient;
import net.fabricmc.fabric.api.renderer.v1.Renderer;
import net.fabricmc.fabric.api.renderer.v1.material.RenderMaterial;
import net.fabricmc.fabric.api.renderer.v1.mesh.Mesh;
@ -24,7 +24,7 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.function.Function;
public class UnbakedJsonRetexturedModel implements UnbakedModel, TemplatesClientApi.TweakableUnbakedModel {
public class UnbakedJsonRetexturedModel implements UnbakedModel {
public UnbakedJsonRetexturedModel(Identifier parent) {
this.parent = parent;
}
@ -33,22 +33,6 @@ public class UnbakedJsonRetexturedModel implements UnbakedModel, TemplatesClient
protected BlockState itemModelState;
protected boolean ao = true;
/// user configuration
@Override
public UnbakedJsonRetexturedModel disableAo() {
ao = false;
return this;
}
@Override
public TemplatesClientApi.TweakableUnbakedModel itemModelState(BlockState state) {
this.itemModelState = state;
return this;
}
/// actual unbakedmodel stuff
@Override
public Collection<Identifier> getModelDependencies() {
return Collections.singletonList(parent);
@ -66,7 +50,7 @@ public class UnbakedJsonRetexturedModel implements UnbakedModel, TemplatesClient
Sprite[] specialSprites = new Sprite[DIRECTIONS.length];
for(int i = 0; i < DIRECTIONS.length; i++) {
SpriteIdentifier id = new SpriteIdentifier(PlayerScreenHandler.BLOCK_ATLAS_TEXTURE, Templates.id("templates_special/" + DIRECTIONS[i].getName()));
SpriteIdentifier id = new SpriteIdentifier(PlayerScreenHandler.BLOCK_ATLAS_TEXTURE, ReFramed.id("reframed_special/" + DIRECTIONS[i].getName()));
specialSprites[i] = Objects.requireNonNull(spriteLookup.apply(id), () -> "Couldn't find sprite " + id + " !");
}
@ -74,7 +58,7 @@ public class UnbakedJsonRetexturedModel implements UnbakedModel, TemplatesClient
return new RetexturingBakedModel(
model,
TemplatesClientApi.getInstance().getOrCreateTemplateApperanceManager(spriteLookup),
ReFramedClient.HELPER.getCamoApperanceManager(spriteLookup),
modelBakeSettings,
itemModelState,
ao
@ -88,7 +72,7 @@ public class UnbakedJsonRetexturedModel implements UnbakedModel, TemplatesClient
}
private Mesh convertModel(BlockState state) {
Renderer r = TemplatesClientApi.getInstance().getFabricRenderer();
Renderer r = ReFramedClient.HELPER.getFabricRenderer();
MeshBuilder builder = r.meshBuilder();
QuadEmitter emitter = builder.getEmitter();
RenderMaterial mat = tam.getCachedMaterial(state, false);

View File

@ -1,6 +1,6 @@
package fr.adrien1106.reframedtemplates.model;
package fr.adrien1106.reframed.client.model;
import fr.adrien1106.reframedtemplates.api.TemplatesClientApi;
import fr.adrien1106.reframed.client.ReFramedClient;
import net.fabricmc.fabric.api.renderer.v1.mesh.Mesh;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
@ -16,7 +16,7 @@ import java.util.Collection;
import java.util.Collections;
import java.util.function.Function;
public class UnbakedMeshRetexturedModel implements UnbakedModel, TemplatesClientApi.TweakableUnbakedModel {
public class UnbakedMeshRetexturedModel implements UnbakedModel {
public UnbakedMeshRetexturedModel(Identifier parent, Function<Function<SpriteIdentifier, Sprite>, Mesh> baseMeshFactory) {
this.parent = parent;
this.baseMeshFactory = baseMeshFactory;
@ -26,21 +26,6 @@ public class UnbakedMeshRetexturedModel implements UnbakedModel, TemplatesClient
protected final Function<Function<SpriteIdentifier, Sprite>, Mesh> baseMeshFactory;
protected boolean ao = true;
/// user configuration
@Override
public UnbakedMeshRetexturedModel disableAo() {
ao = false;
return this;
}
@Override
public TemplatesClientApi.TweakableUnbakedModel itemModelState(BlockState state) {
throw new UnsupportedOperationException("UnbakedMeshRetexturedModel does not need an item model state set; it uses meshes");
}
/// actual unbakedmodel stuff
@Override
public Collection<Identifier> getModelDependencies() {
return Collections.singletonList(parent);
@ -57,7 +42,7 @@ public class UnbakedMeshRetexturedModel implements UnbakedModel, TemplatesClient
return new RetexturingBakedModel(
baker.bake(parent, modelBakeSettings),
TemplatesClientApi.getInstance().getOrCreateTemplateApperanceManager(spriteLookup),
ReFramedClient.HELPER.getCamoApperanceManager(spriteLookup),
modelBakeSettings,
Blocks.AIR.getDefaultState(),
ao

View File

@ -1,4 +1,4 @@
package fr.adrien1106.reframedtemplates.model.apperance;
package fr.adrien1106.reframed.client.model.apperance;
import net.minecraft.client.texture.Sprite;

View File

@ -1,11 +1,11 @@
package fr.adrien1106.reframedtemplates.model.apperance;
package fr.adrien1106.reframed.client.model.apperance;
import net.fabricmc.fabric.api.renderer.v1.material.RenderMaterial;
import net.minecraft.client.texture.Sprite;
import net.minecraft.util.math.Direction;
import org.jetbrains.annotations.NotNull;
public interface TemplateAppearance {
public interface CamoAppearance {
@NotNull RenderMaterial getRenderMaterial(boolean ao);
@NotNull Sprite getSprite(Direction dir, long seed);
int getBakeFlags(Direction dir, long seed);

View File

@ -1,7 +1,8 @@
package fr.adrien1106.reframedtemplates.model.apperance;
package fr.adrien1106.reframed.client.model.apperance;
import fr.adrien1106.reframedtemplates.api.TemplatesClientApi;
import fr.adrien1106.reframedtemplates.mixin.model.WeightedBakedModelAccessor;
import fr.adrien1106.reframed.ReFramed;
import fr.adrien1106.reframed.client.ReFramedClient;
import fr.adrien1106.reframed.mixin.model.WeightedBakedModelAccessor;
import net.fabricmc.fabric.api.renderer.v1.Renderer;
import net.fabricmc.fabric.api.renderer.v1.material.BlendMode;
import net.fabricmc.fabric.api.renderer.v1.material.MaterialFinder;
@ -31,10 +32,10 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Function;
public class TemplateAppearanceManager {
public class CamoAppearanceManager {
public TemplateAppearanceManager(Function<SpriteIdentifier, Sprite> spriteLookup) {
MaterialFinder finder = TemplatesClientApi.getInstance().getFabricRenderer().materialFinder();
public CamoAppearanceManager(Function<SpriteIdentifier, Sprite> spriteLookup) {
MaterialFinder finder = ReFramedClient.HELPER.getFabricRenderer().materialFinder();
for(BlendMode blend : BlendMode.values()) {
finder.clear().disableDiffuse(false).blendMode(blend);
@ -51,23 +52,23 @@ public class TemplateAppearanceManager {
this.barrierItemAppearance = new SingleSpriteAppearance(barrier, materialsWithoutAo.get(BlendMode.CUTOUT), serialNumber.getAndIncrement());
}
protected static final SpriteIdentifier DEFAULT_SPRITE_ID = new SpriteIdentifier(PlayerScreenHandler.BLOCK_ATLAS_TEXTURE, new Identifier("reframedtemplates:block/framed_block"));
protected static final SpriteIdentifier DEFAULT_SPRITE_ID = new SpriteIdentifier(PlayerScreenHandler.BLOCK_ATLAS_TEXTURE, new Identifier(ReFramed.MODID, "block/framed_block"));
private static final SpriteIdentifier BARRIER_SPRITE_ID = new SpriteIdentifier(PlayerScreenHandler.BLOCK_ATLAS_TEXTURE, new Identifier("minecraft:item/barrier"));
private final TemplateAppearance defaultAppearance;
private final TemplateAppearance barrierItemAppearance;
private final CamoAppearance defaultAppearance;
private final CamoAppearance barrierItemAppearance;
private final ConcurrentHashMap<BlockState, TemplateAppearance> appearanceCache = new ConcurrentHashMap<>(); //Mutable, append-only cache
private final ConcurrentHashMap<BlockState, CamoAppearance> appearanceCache = new ConcurrentHashMap<>(); //Mutable, append-only cache
private final AtomicInteger serialNumber = new AtomicInteger(0); //Mutable
private final EnumMap<BlendMode, RenderMaterial> materialsWithAo = new EnumMap<>(BlendMode.class);
private final EnumMap<BlendMode, RenderMaterial> materialsWithoutAo = new EnumMap<>(BlendMode.class); //Immutable contents
public TemplateAppearance getDefaultAppearance() {
public CamoAppearance getDefaultAppearance() {
return defaultAppearance;
}
public TemplateAppearance getTemplateAppearance(BlockState state) {
public CamoAppearance getCamoAppearance(BlockState state) {
return appearanceCache.computeIfAbsent(state, this::computeAppearance);
}
@ -76,22 +77,11 @@ public class TemplateAppearanceManager {
return m.get(BlendMode.fromRenderLayer(RenderLayers.getBlockLayer(state)));
}
private static final int[] MAGIC_BAKEFLAGS_SBOX = new int[16];
static {
//left to right -> u0 v0 u1 v1
//the bit is set if the coordinate is "high"
MAGIC_BAKEFLAGS_SBOX[0b1110] = 0;
MAGIC_BAKEFLAGS_SBOX[0b1000] = MutableQuadView.BAKE_ROTATE_90;
MAGIC_BAKEFLAGS_SBOX[0b0001] = MutableQuadView.BAKE_ROTATE_180;
MAGIC_BAKEFLAGS_SBOX[0b0111] = MutableQuadView.BAKE_ROTATE_270;
//TODO: handle more cases. Also, it might be possible to drop v1 and still have the table be unambiguous
}
// I'm pretty sure ConcurrentHashMap semantics allow for this function to be called multiple times on the same key, on different threads.
// The computeIfAbsent map update will work without corrupting the map, but there will be some "wasted effort" computing the value twice.
// The results are going to be the same, apart from their serialNumbers differing (= their equals & hashCode differing).
//Tiny amount of wasted space in some caches if TemplateAppearances are used as a map key, then. IMO it's not a critical issue.
private TemplateAppearance computeAppearance(BlockState state) {
// Tiny amount of wasted space in some caches if CamoAppearances are used as a map key, then. IMO it's not a critical issue.
private CamoAppearance computeAppearance(BlockState state) {
if(state.getBlock() == Blocks.BARRIER) return barrierItemAppearance;
BakedModel model = MinecraftClient.getInstance().getBlockRenderManager().getModel(state);
@ -117,7 +107,7 @@ public class TemplateAppearanceManager {
private Appearance getAppearance(BakedModel model) {
// Only for parsing vanilla quads:
Renderer r = TemplatesClientApi.getInstance().getFabricRenderer();
Renderer r = ReFramedClient.HELPER.getFabricRenderer();
QuadEmitter quad_emitter = r.meshBuilder().getEmitter();
RenderMaterial material = r.materialFinder().clear().find();
Random random = Random.create();
@ -126,7 +116,6 @@ public class TemplateAppearanceManager {
int[] flags = new int[6];
byte[] color_mask = {0b000000};
System.out.println("new mesh"); // TODO remove
//Read quads off the model by their `cullface`
Arrays.stream(Direction.values()).forEach(direction -> {
List<BakedQuad> quads = model.getQuads(null, direction, random);
@ -161,7 +150,7 @@ public class TemplateAppearanceManager {
return new Appearance(sprites, flags, color_mask[0]);
}
private static int getBakeFlags(QuadEmitter emitter, Sprite sprite) { // TODO can probably receive tons of improvements
private static int getBakeFlags(QuadEmitter emitter, Sprite sprite) {
boolean[][] order_matrix = getOrderMatrix(emitter, sprite);
int flag = 0;
if (!isClockwise(order_matrix)) { // check if quad has been mirrored on model

View File

@ -1,4 +1,4 @@
package fr.adrien1106.reframedtemplates.model.apperance;
package fr.adrien1106.reframed.client.model.apperance;
import net.fabricmc.fabric.api.renderer.v1.material.RenderMaterial;
import net.minecraft.client.texture.Sprite;
@ -7,7 +7,7 @@ import org.jetbrains.annotations.NotNull;
import java.util.Arrays;
public class ComputedAppearance implements TemplateAppearance {
public class ComputedAppearance implements CamoAppearance {
private final Appearance appearance;
private final int id;
private final RenderMaterial matWithAo;

View File

@ -1,11 +1,11 @@
package fr.adrien1106.reframedtemplates.model.apperance;
package fr.adrien1106.reframed.client.model.apperance;
import net.fabricmc.fabric.api.renderer.v1.material.RenderMaterial;
import net.minecraft.client.texture.Sprite;
import net.minecraft.util.math.Direction;
import org.jetbrains.annotations.NotNull;
public class SingleSpriteAppearance implements TemplateAppearance {
public class SingleSpriteAppearance implements CamoAppearance {
private final @NotNull Sprite defaultSprite;
private final RenderMaterial mat;
private final int id;

View File

@ -1,4 +1,4 @@
package fr.adrien1106.reframedtemplates.model.apperance;
package fr.adrien1106.reframed.client.model.apperance;
import net.fabricmc.fabric.api.renderer.v1.material.RenderMaterial;
import net.minecraft.client.texture.Sprite;
@ -11,7 +11,7 @@ import org.jetbrains.annotations.NotNull;
import java.util.Arrays;
import java.util.List;
public class WeightedComputedAppearance implements TemplateAppearance {
public class WeightedComputedAppearance implements CamoAppearance {
private final List<Weighted.Present<Appearance>> appearances;
private final int total_weight;
private final int id;

View File

@ -1,4 +1,4 @@
package fr.adrien1106.reframedtemplates.generator;
package fr.adrien1106.reframed.generator;
import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput;
import net.fabricmc.fabric.api.datagen.v1.provider.FabricBlockLootTableProvider;

View File

@ -1,4 +1,4 @@
package fr.adrien1106.reframedtemplates.generator;
package fr.adrien1106.reframed.generator;
import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput;
import net.fabricmc.fabric.api.datagen.v1.provider.FabricModelProvider;
@ -15,7 +15,7 @@ public class GBlockstate extends FabricModelProvider {
}
@Override
public void generateBlockStateModels(BlockStateModelGenerator model_generator) { // TODO Find out smth for items
public void generateBlockStateModels(BlockStateModelGenerator model_generator) {
Generator.BLOCKS
.forEach(model_generator::excludeFromSimpleItemModelGeneration);
Generator.BLOCKS.stream()

View File

@ -1,4 +1,4 @@
package fr.adrien1106.reframedtemplates.generator;
package fr.adrien1106.reframed.generator;
import net.fabricmc.fabric.api.datagen.v1.DataGeneratorEntrypoint;
import net.fabricmc.fabric.api.datagen.v1.FabricDataGenerator;
@ -6,7 +6,7 @@ import net.minecraft.block.Block;
import java.util.List;
import static fr.adrien1106.reframedtemplates.Templates.*;
import static fr.adrien1106.reframed.ReFramed.*;
public class Generator implements DataGeneratorEntrypoint {

View File

@ -1,4 +1,4 @@
package fr.adrien1106.reframedtemplates.generator;
package fr.adrien1106.reframed.generator;
import net.minecraft.data.client.MultipartBlockStateSupplier;

View File

@ -1,4 +1,4 @@
package fr.adrien1106.reframedtemplates.mixin;
package fr.adrien1106.reframed.mixin;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.color.item.ItemColors;
@ -8,5 +8,5 @@ import org.spongepowered.asm.mixin.gen.Accessor;
@Mixin(MinecraftClient.class)
public interface MinecraftAccessor {
//Yeah there's a fabric API for this, but do we really need it, no.
@Accessor("itemColors") ItemColors templates$getItemColors();
@Accessor("itemColors") ItemColors getItemColors();
}

View File

@ -1,4 +1,4 @@
package fr.adrien1106.reframedtemplates.mixin;
package fr.adrien1106.reframed.mixin;
import net.minecraft.block.BlockState;
import net.minecraft.block.WallBlock;
@ -8,9 +8,9 @@ import org.spongepowered.asm.mixin.gen.Accessor;
import java.util.Map;
//Used in TemplateWallBlock, since the vanilla wall block code explodes if you add more blockstates.
//Used in ReFramedWallBlock, since the vanilla wall block code explodes if you add more blockstates.
@Mixin(WallBlock.class)
public interface WallBlockAccessor {
@Accessor("shapeMap") Map<BlockState, VoxelShape> templates$getShapeMap();
@Accessor("collisionShapeMap") Map<BlockState, VoxelShape> templates$getCollisionShapeMap();
@Accessor("shapeMap") Map<BlockState, VoxelShape> getShapeMap();
@Accessor("collisionShapeMap") Map<BlockState, VoxelShape> getCollisionShapeMap();
}

View File

@ -1,4 +1,4 @@
package fr.adrien1106.reframedtemplates.mixin.model;
package fr.adrien1106.reframed.mixin.model;
import net.minecraft.client.render.model.BakedModel;
import net.minecraft.client.render.model.WeightedBakedModel;

View File

@ -0,0 +1,15 @@
package fr.adrien1106.reframed.mixin.particles;
import net.minecraft.client.particle.Particle;
import net.minecraft.util.math.random.Random;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
@Mixin(Particle.class)
public interface AccessorParticle {
@Accessor("random") Random getRandom();
@Accessor("red") void setRed(float red);
@Accessor("green") void setGreen(float green);
@Accessor("blue") void setBlue(float blue);
}

View File

@ -1,4 +1,4 @@
package fr.adrien1106.reframedtemplates.mixin.particles;
package fr.adrien1106.reframed.mixin.particles;
import net.minecraft.client.particle.SpriteBillboardParticle;
import net.minecraft.client.texture.Sprite;
@ -7,5 +7,5 @@ import org.spongepowered.asm.mixin.gen.Invoker;
@Mixin(SpriteBillboardParticle.class)
public interface AccessorSpriteBillboardParticle {
@Invoker("setSprite") void templates$setSprite(Sprite sprite);
@Invoker("setSprite") void setNewSprite(Sprite sprite);
}

View File

@ -1,6 +1,6 @@
package fr.adrien1106.reframedtemplates.mixin.particles;
package fr.adrien1106.reframed.mixin.particles;
import fr.adrien1106.reframedtemplates.api.ThemeableBlockEntity;
import fr.adrien1106.reframed.util.ThemeableBlockEntity;
import net.minecraft.block.BlockState;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.particle.BlockDustParticle;
@ -18,23 +18,23 @@ public class MixinBlockDustParticle {
method = "<init>(Lnet/minecraft/client/world/ClientWorld;DDDDDDLnet/minecraft/block/BlockState;Lnet/minecraft/util/math/BlockPos;)V",
at = @At("TAIL")
)
void templates$init$modifyParticleSprite(ClientWorld clientWorld, double d, double e, double f, double g, double h, double i, BlockState state, BlockPos pos, CallbackInfo ci) {
void modifyParticleSprite(ClientWorld clientWorld, double d, double e, double f, double g, double h, double i, BlockState state, BlockPos pos, CallbackInfo ci) {
AccessorParticle a = (AccessorParticle) this;
if(a.templates$getRandom().nextBoolean() && clientWorld.getBlockEntity(pos) instanceof ThemeableBlockEntity themeable) {
if(a.getRandom().nextBoolean() && clientWorld.getBlockEntity(pos) instanceof ThemeableBlockEntity themeable) {
BlockState theme = themeable.getThemeState();
if(theme == null || theme.isAir()) return;
Sprite replacement = MinecraftClient.getInstance().getBlockRenderManager().getModels().getModelParticleSprite(theme);
((AccessorSpriteBillboardParticle) this).templates$setSprite(replacement);
((AccessorSpriteBillboardParticle) this).setNewSprite(replacement);
//basically just re-implement what the constructor does - since we mixin at tail, this already ran
//some modifyvariable magic on the BlockState wouldn't hurt, i suppose, but, eh
//it'd need to capture method arguments but in this version of mixin it requires using threadlocals,
//and 99.9999% of block dust particles are not for template blocks, so it seems like a waste of cpu cycles
//and 99.9999% of block dust particles are not for frame blocks, so it seems like a waste of cpu cycles
int color = MinecraftClient.getInstance().getBlockColors().getColor(theme, clientWorld, pos, 0);
a.templates$setRed(0.6f * ((color & 0xFF0000) >> 16) / 255f);
a.templates$setGreen(0.6f * ((color & 0x00FF00) >> 8) / 255f);
a.templates$setBlue(0.6f * (color & 0x0000FF) / 255f);
a.setRed(0.6f * ((color & 0xFF0000) >> 16) / 255f);
a.setGreen(0.6f * ((color & 0x00FF00) >> 8) / 255f);
a.setBlue(0.6f * (color & 0x0000FF) / 255f);
}
}
}

View File

@ -1,6 +1,6 @@
package fr.adrien1106.reframedtemplates.mixin.particles;
package fr.adrien1106.reframed.mixin.particles;
import fr.adrien1106.reframedtemplates.api.ThemeableBlockEntity;
import fr.adrien1106.reframed.util.ThemeableBlockEntity;
import net.minecraft.block.BlockState;
import net.minecraft.entity.Entity;
import net.minecraft.util.math.BlockPos;
@ -18,7 +18,7 @@ public abstract class MixinEntity {
method = "spawnSprintingParticles",
at = @At(value = "INVOKE", target = "Lnet/minecraft/particle/BlockStateParticleEffect;<init>(Lnet/minecraft/particle/ParticleType;Lnet/minecraft/block/BlockState;)V")
)
private BlockState templates$spawnSprintingParticles$modifyParticleState(BlockState origState) {
private BlockState modifyParticleState(BlockState origState) {
World world = ((Entity) (Object) this).getWorld();
if(world.getBlockEntity(getLandingPos()) instanceof ThemeableBlockEntity themeable) {

View File

@ -1,6 +1,6 @@
package fr.adrien1106.reframedtemplates.mixin.particles;
package fr.adrien1106.reframed.mixin.particles;
import fr.adrien1106.reframedtemplates.api.ThemeableBlockEntity;
import fr.adrien1106.reframed.util.ThemeableBlockEntity;
import net.minecraft.block.BlockState;
import net.minecraft.entity.Entity;
import net.minecraft.entity.LivingEntity;
@ -18,7 +18,7 @@ public class MixinLivingEntity {
@Unique private BlockPos lastFallCheckPos;
@Inject(method = "fall", at = @At("HEAD"))
private void templates$onFall(double d, boolean bl, BlockState blockState, BlockPos blockPos, CallbackInfo ci) {
private void onFall(double d, boolean bl, BlockState blockState, BlockPos blockPos, CallbackInfo ci) {
lastFallCheckPos = blockPos;
}
@ -26,7 +26,7 @@ public class MixinLivingEntity {
method = "fall",
at = @At(value = "INVOKE", target = "Lnet/minecraft/particle/BlockStateParticleEffect;<init>(Lnet/minecraft/particle/ParticleType;Lnet/minecraft/block/BlockState;)V")
)
private BlockState templates$fall$modifyParticleState(BlockState origState) {
private BlockState modifyParticleState(BlockState origState) {
World world = ((Entity) (Object) this).getWorld();
if(lastFallCheckPos != null && world.getBlockEntity(lastFallCheckPos) instanceof ThemeableBlockEntity themeable) {

View File

@ -1,6 +1,6 @@
package fr.adrien1106.reframedtemplates.api;
package fr.adrien1106.reframed.util;
import fr.adrien1106.reframedtemplates.block.FramedEntity;
import fr.adrien1106.reframed.block.ReFramedEntity;
import net.minecraft.block.AbstractBlock;
import net.minecraft.block.Block;
import net.minecraft.block.BlockEntityProvider;
@ -36,8 +36,8 @@ import org.jetbrains.annotations.Nullable;
//For an example of how to use this class, have a look at TemplateBlock.
//Basically there are several methods that would like to modify the return value of something.
public class TemplateInteractionUtil {
public static final BooleanProperty LIGHT = BooleanProperty.of("templates_light");
public class ReFramedInteractionUtil {
public static final BooleanProperty LIGHT = BooleanProperty.of("frame_light");
public static StateManager.Builder<Block, BlockState> appendProperties(StateManager.Builder<Block, BlockState> builder) {
return builder.add(LIGHT);
@ -47,7 +47,7 @@ public class TemplateInteractionUtil {
//(To complete the look, don't forget to tag your blocks with mineable/axe.)
private static final AbstractBlock.ContextPredicate NOPE = (blah, blahdey, blahh) -> false;
public static AbstractBlock.Settings configureSettings(AbstractBlock.Settings s) {
return s.luminance(TemplateInteractionUtil::luminance).nonOpaque().sounds(BlockSoundGroup.WOOD).hardness(0.2f).suffocates(NOPE).blockVision(NOPE);
return s.luminance(ReFramedInteractionUtil::luminance).nonOpaque().sounds(BlockSoundGroup.WOOD).hardness(0.2f).suffocates(NOPE).blockVision(NOPE);
}
//And if you don't have a Block.Settings to copy off of.
@ -61,15 +61,15 @@ public class TemplateInteractionUtil {
}
public static @Nullable BlockState modifyPlacementState(@Nullable BlockState in, ItemPlacementContext ctx) {
return FramedEntity.weirdNbtLightLevelStuff(in, ctx.getStack());
return ReFramedEntity.weirdNbtLightLevelStuff(in, ctx.getStack());
}
public static ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) {
if(!(world.getBlockEntity(pos) instanceof FramedEntity be)) return ActionResult.PASS;
if(!(world.getBlockEntity(pos) instanceof ReFramedEntity be)) return ActionResult.PASS;
if(!player.canModifyBlocks() || !world.canPlayerModifyAt(player, pos)) return ActionResult.PASS;
ItemStack held = player.getStackInHand(hand);
TemplateInteractionUtilExt ext = state.getBlock() instanceof TemplateInteractionUtilExt e ? e : TemplateInteractionUtilExt.Default.INSTANCE;
ReframedInteractible ext = state.getBlock() instanceof ReframedInteractible e ? e : ReframedInteractible.Default.INSTANCE;
//Glowstone
if(state.contains(LIGHT) && held.getItem() == Items.GLOWSTONE_DUST && !state.get(LIGHT) && !be.hasSpentGlowstoneDust()) {
@ -85,7 +85,7 @@ public class TemplateInteractionUtil {
if(held.getItem() == Blocks.REDSTONE_TORCH.asItem() &&
!be.emitsRedstone() &&
!be.hasSpentRedstoneTorch() &&
ext.templatesPlayerCanAddRedstoneEmission(state, world, pos)
ext.canAddRedstoneEmission(state, world, pos)
) {
be.setEmitsRedstone(true);
be.spentRedstoneTorch();
@ -99,7 +99,7 @@ public class TemplateInteractionUtil {
if(held.getItem() == Items.POPPED_CHORUS_FRUIT &&
be.isSolid() &&
!be.hasSpentPoppedChorus() &&
ext.templatesPlayerCanRemoveCollision(state, world, pos)
ext.canRemoveCollision(state, world, pos)
) {
be.setSolidity(false);
be.spentPoppedChorus();
@ -132,18 +132,18 @@ public class TemplateInteractionUtil {
//Maybe an odd spot to put this logic but it's consistent w/ vanilla chests, barrels, etc
public static void onStateReplaced(BlockState state, World world, BlockPos pos, BlockState newState, boolean moved) {
if(!state.isOf(newState.getBlock()) &&
world.getBlockEntity(pos) instanceof FramedEntity template &&
world.getBlockEntity(pos) instanceof ReFramedEntity frame &&
world.getGameRules().getBoolean(GameRules.DO_TILE_DROPS)
) {
DefaultedList<ItemStack> drops = DefaultedList.of();
//TODO: remember the specific ItemStack
Block theme = template.getThemeState().getBlock();
Block theme = frame.getThemeState().getBlock();
if(theme != Blocks.AIR) drops.add(new ItemStack(theme));
if(template.hasSpentRedstoneTorch()) drops.add(new ItemStack(Items.REDSTONE_TORCH));
if(template.hasSpentGlowstoneDust()) drops.add(new ItemStack(Items.GLOWSTONE_DUST));
if(template.hasSpentPoppedChorus()) drops.add(new ItemStack(Items.POPPED_CHORUS_FRUIT));
if(frame.hasSpentRedstoneTorch()) drops.add(new ItemStack(Items.REDSTONE_TORCH));
if(frame.hasSpentGlowstoneDust()) drops.add(new ItemStack(Items.GLOWSTONE_DUST));
if(frame.hasSpentPoppedChorus()) drops.add(new ItemStack(Items.POPPED_CHORUS_FRUIT));
ItemScatterer.spawn(world, pos, drops);
}
@ -152,7 +152,7 @@ public class TemplateInteractionUtil {
public static void onPlaced(World world, BlockPos pos, BlockState state, @Nullable LivingEntity placer, ItemStack stack) {
//Load the BlockEntityTag clientside, which fixes the template briefly showing its default state when placing it.
//I'm surprised this doesn't happen by default; the BlockEntityTag stuff is only done serverside.
if(world.isClient && world.getBlockEntity(pos) instanceof FramedEntity be) {
if(world.isClient && world.getBlockEntity(pos) instanceof ReFramedEntity be) {
NbtCompound tag = BlockItem.getBlockEntityNbt(stack);
if(tag != null) be.readNbt(tag);
}
@ -160,7 +160,7 @@ public class TemplateInteractionUtil {
//Returns "null" to signal "no opinion". Imagine it like an InteractionResult.PASS.
public static @Nullable VoxelShape getCollisionShape(BlockState state, BlockView view, BlockPos pos, ShapeContext ctx) {
return view.getBlockEntity(pos) instanceof FramedEntity be && !be.isSolid() ? VoxelShapes.empty() : null;
return view.getBlockEntity(pos) instanceof ReFramedEntity be && !be.isSolid() ? VoxelShapes.empty() : null;
}
public static boolean emitsRedstonePower(BlockState state) {
@ -169,11 +169,11 @@ public class TemplateInteractionUtil {
}
public static int getWeakRedstonePower(BlockState state, BlockView view, BlockPos pos, Direction dir) {
return view.getBlockEntity(pos) instanceof FramedEntity be && be.emitsRedstone() ? 15 : 0;
return view.getBlockEntity(pos) instanceof ReFramedEntity be && be.emitsRedstone() ? 15 : 0;
}
public static int getStrongRedstonePower(BlockState state, BlockView view, BlockPos pos, Direction dir) {
return view.getBlockEntity(pos) instanceof FramedEntity be && be.emitsRedstone() ? 15 : 0;
return view.getBlockEntity(pos) instanceof ReFramedEntity be && be.emitsRedstone() ? 15 : 0;
}
public static int luminance(BlockState state) {

View File

@ -1,20 +1,20 @@
package fr.adrien1106.reframedtemplates.api;
package fr.adrien1106.reframed.util;
import net.minecraft.block.BlockState;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.world.BlockView;
public interface TemplateInteractionUtilExt {
default boolean templatesPlayerCanAddRedstoneEmission(BlockState state, BlockView view, BlockPos pos) {
public interface ReframedInteractible {
default boolean canAddRedstoneEmission(BlockState state, BlockView view, BlockPos pos) {
return state.getWeakRedstonePower(view, pos, Direction.UP) == 0;
}
default boolean templatesPlayerCanRemoveCollision(BlockState state, BlockView view, BlockPos pos) {
default boolean canRemoveCollision(BlockState state, BlockView view, BlockPos pos) {
return !state.getCollisionShape(view, pos).isEmpty();
}
class Default implements TemplateInteractionUtilExt {
class Default implements ReframedInteractible {
public static final Default INSTANCE = new Default();
}
}

View File

@ -1,4 +1,4 @@
package fr.adrien1106.reframedtemplates.api;
package fr.adrien1106.reframed.util;
import net.fabricmc.fabric.api.rendering.data.v1.RenderAttachmentBlockEntity;
import net.minecraft.block.BlockState;

View File

@ -1,4 +1,4 @@
package fr.adrien1106.reframedtemplates.util;
package fr.adrien1106.reframed.util;
import net.minecraft.util.function.BooleanBiFunction;
import net.minecraft.util.math.Direction;

View File

@ -1,4 +1,4 @@
package fr.adrien1106.reframedtemplates.util.property;
package fr.adrien1106.reframed.util.property;
import net.minecraft.util.StringIdentifiable;
import net.minecraft.util.math.Direction;

View File

@ -1,4 +1,4 @@
package fr.adrien1106.reframedtemplates.util.property;
package fr.adrien1106.reframed.util.property;
import net.minecraft.util.StringIdentifiable;

View File

@ -1,95 +0,0 @@
package fr.adrien1106.reframedtemplates;
import fr.adrien1106.reframedtemplates.api.TemplateInteractionUtil;
import fr.adrien1106.reframedtemplates.block.*;
import net.fabricmc.api.ModInitializer;
import net.fabricmc.fabric.api.itemgroup.v1.FabricItemGroup;
import net.fabricmc.fabric.api.object.builder.v1.block.entity.FabricBlockEntityTypeBuilder;
import net.minecraft.block.AbstractBlock;
import net.minecraft.block.Block;
import net.minecraft.block.BlockSetType;
import net.minecraft.block.Blocks;
import net.minecraft.block.entity.BlockEntityType;
import net.minecraft.item.BlockItem;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.registry.Registries;
import net.minecraft.registry.Registry;
import net.minecraft.text.Text;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import org.jetbrains.annotations.ApiStatus;
import java.util.ArrayList;
import java.util.function.BiConsumer;
import java.util.stream.Collectors;
/**
* TODO handle random textures rotation and mirroring wip, handle grass side, multiple camos
*/
public class Templates implements ModInitializer {
public static final String MODID = "reframedtemplates";
protected static final ArrayList<Block> INTERNAL_TEMPLATES = new ArrayList<>();
public static Block CUBE, STAIRS, SLAB, POST, FENCE, FENCE_GATE, DOOR, TRAPDOOR, IRON_DOOR, IRON_TRAPDOOR, PRESSURE_PLATE, BUTTON, LEVER, WALL, CARPET, PANE, CANDLE;
public static BlockEntityType<FramedEntity> TEMPLATE_BLOCK_ENTITY;
public static BiConsumer<World, BlockPos> chunkRerenderProxy = (world, pos) -> {};
@Override
public void onInitialize() {
//registerTemplate mutates MY_TEMPLATES as a side effect, which is a List, so order is preserved
//the ordering is used in the creative tab, so they're roughly sorted by encounter order of the
//corresponding vanilla block in the "search" creative tab... with the non-vanilla "post" and
//"vertical slab" inserted where they fit ...and i moved the lever way up next to the pressureplate
//and button, because they're redstoney... hopefully this ordering makes sense lol
CUBE = registerTemplate("cube" , new TemplateBlock(TemplateInteractionUtil.makeSettings()));
STAIRS = registerTemplate("stairs" , new TemplateStairsBlock(cp(Blocks.OAK_STAIRS)));
SLAB = registerTemplate("slab" , new TemplateSlabBlock(cp(Blocks.OAK_SLAB)));
POST = registerTemplate("post" , new TemplatePostBlock(cp(Blocks.OAK_FENCE)));
FENCE = registerTemplate("fence" , new TemplateFenceBlock(cp(Blocks.OAK_FENCE)));
FENCE_GATE = registerTemplate("fence_gate" , new TemplateFenceGateBlock(cp(Blocks.OAK_FENCE_GATE)));
DOOR = registerTemplate("door" , new TemplateDoorBlock(cp(Blocks.OAK_DOOR), BlockSetType.OAK));
TRAPDOOR = registerTemplate("trapdoor" , new TemplateTrapdoorBlock(cp(Blocks.OAK_TRAPDOOR), BlockSetType.OAK));
IRON_DOOR = registerTemplate("iron_door" , new TemplateDoorBlock(cp(Blocks.IRON_DOOR), BlockSetType.IRON));
IRON_TRAPDOOR = registerTemplate("iron_trapdoor" , new TemplateTrapdoorBlock(cp(Blocks.IRON_TRAPDOOR), BlockSetType.IRON));
PRESSURE_PLATE = registerTemplate("pressure_plate", new TemplatePressurePlateBlock(cp(Blocks.OAK_PRESSURE_PLATE)));
BUTTON = registerTemplate("button" , new TemplateButtonBlock(cp(Blocks.OAK_BUTTON)));
LEVER = registerTemplate("lever" , new TemplateLeverBlock(cp(Blocks.LEVER)));
WALL = registerTemplate("wall" , new TemplateWallBlock(TemplateInteractionUtil.makeSettings()));
CARPET = registerTemplate("carpet" , new TemplateCarpetBlock(cp(Blocks.WHITE_CARPET)));
PANE = registerTemplate("pane" , new TemplatePaneBlock(cp(Blocks.GLASS_PANE)));
CANDLE = registerTemplate("candle" , new TemplateCandleBlock(TemplateCandleBlock.configureSettings(cp(Blocks.CANDLE))));
//The block entity is still called templates:slope; this is a bit of a legacy mistake.
TEMPLATE_BLOCK_ENTITY = Registry.register(Registries.BLOCK_ENTITY_TYPE, id("slope"),
FabricBlockEntityTypeBuilder.create((pos, state) -> new FramedEntity(TEMPLATE_BLOCK_ENTITY, pos, state), INTERNAL_TEMPLATES.toArray(new Block[0])).build(null)
);
Registry.register(Registries.ITEM_GROUP, id("tab"), FabricItemGroup.builder()
.displayName(Text.translatable("itemGroup.reframedtemplates.tab"))
.icon(() -> new ItemStack(SLAB))
.entries((ctx, e) -> e.addAll(INTERNAL_TEMPLATES.stream().map(ItemStack::new).collect(Collectors.toList()))).build()
);
}
private static AbstractBlock.Settings cp(Block base) {
return TemplateInteractionUtil.configureSettings(AbstractBlock.Settings.copy(base));
}
private static <B extends Block> B registerTemplate(String path, B block) {
Identifier id = id(path);
Registry.register(Registries.BLOCK, id, block);
Registry.register(Registries.ITEM, id, new BlockItem(block, new Item.Settings()));
INTERNAL_TEMPLATES.add(block);
return block;
}
@ApiStatus.Internal
public static Identifier id(String path) {
return new Identifier(MODID, path);
}
}

View File

@ -1,123 +0,0 @@
package fr.adrien1106.reframedtemplates;
import fr.adrien1106.reframedtemplates.api.TemplatesClientApi;
import net.fabricmc.api.ClientModInitializer;
import net.fabricmc.fabric.api.blockrenderlayer.v1.BlockRenderLayerMap;
import net.fabricmc.fabric.api.client.model.ModelLoadingRegistry;
import net.fabricmc.fabric.api.resource.ResourceManagerHelper;
import net.fabricmc.fabric.api.resource.SimpleSynchronousResourceReloadListener;
import net.minecraft.block.Block;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.render.RenderLayer;
import net.minecraft.resource.ResourceManager;
import net.minecraft.resource.ResourceType;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.ChunkSectionPos;
import org.jetbrains.annotations.ApiStatus;
public class TemplatesClient implements ClientModInitializer {
@ApiStatus.Internal //2.2 - Please use the new TemplatesClientApi.getInstance() method.
public static final TemplatesModelProvider provider = new TemplatesModelProvider();
@ApiStatus.Internal //Please use TemplatesClientApi.getInstance() instead.
public static final TemplatesClientApiImpl API_IMPL = new TemplatesClientApiImpl(provider);
@Override
public void onInitializeClient() {
privateInit(); //<- Stuff you shouldn't replicate in any addon mods ;)
//all templates mustn't be on the SOLID layer because they are not opaque!
BlockRenderLayerMap.INSTANCE.putBlocks(RenderLayer.getCutout(), Templates.INTERNAL_TEMPLATES.toArray(new Block[0]));
//now, assign special item models
TemplatesClientApi api = TemplatesClientApi.getInstance();
api.addTemplateModel(Templates.id("button_special") , api.auto(new Identifier("block/button")));
api.addTemplateModel(Templates.id("button_pressed_special") , api.auto(new Identifier("block/button_pressed")));
api.addTemplateModel(Templates.id("one_candle_special") , api.auto(new Identifier("block/template_candle")));
api.addTemplateModel(Templates.id("two_candles_special") , api.auto(new Identifier("block/template_two_candles")));
api.addTemplateModel(Templates.id("three_candles_special") , api.auto(new Identifier("block/template_three_candles")));
api.addTemplateModel(Templates.id("four_candles_special") , api.auto(new Identifier("block/template_four_candles")));
api.addTemplateModel(Templates.id("carpet_special") , api.auto(new Identifier("block/carpet")));
api.addTemplateModel(Templates.id("cube_special") , api.auto(new Identifier("block/cube")));
api.addTemplateModel(Templates.id("door_bottom_left_special") , api.auto(new Identifier("block/door_bottom_left")));
api.addTemplateModel(Templates.id("door_bottom_right_special") , api.auto(new Identifier("block/door_bottom_right")));
api.addTemplateModel(Templates.id("door_top_left_special") , api.auto(new Identifier("block/door_top_left")));
api.addTemplateModel(Templates.id("door_top_right_special") , api.auto(new Identifier("block/door_top_right")));
api.addTemplateModel(Templates.id("door_bottom_left_open_special"), api.auto(new Identifier("block/door_bottom_left_open")));
api.addTemplateModel(Templates.id("door_bottom_right_open_special"), api.auto(new Identifier("block/door_bottom_right_open"))); //This is why we dont format code as tables kids
api.addTemplateModel(Templates.id("door_top_left_open_special") , api.auto(new Identifier("block/door_top_left_open")));
api.addTemplateModel(Templates.id("door_top_right_open_special") , api.auto(new Identifier("block/door_top_right_open")));
api.addTemplateModel(Templates.id("fence_post_special") , api.auto(new Identifier("block/fence_post")));
api.addTemplateModel(Templates.id("fence_gate_special") , api.auto(new Identifier("block/template_fence_gate")));
api.addTemplateModel(Templates.id("fence_gate_open_special") , api.auto(new Identifier("block/template_fence_gate_open")));
api.addTemplateModel(Templates.id("fence_gate_wall_special") , api.auto(new Identifier("block/template_fence_gate_wall")));
api.addTemplateModel(Templates.id("fence_gate_wall_open_special") , api.auto(new Identifier("block/template_fence_gate_wall_open")));
api.addTemplateModel(Templates.id("glass_pane_post_special") , api.auto(new Identifier("block/glass_pane_post")));
api.addTemplateModel(Templates.id("glass_pane_noside_special") , api.auto(new Identifier("block/glass_pane_noside")));
api.addTemplateModel(Templates.id("glass_pane_noside_alt_special"), api.auto(new Identifier("block/glass_pane_noside_alt")));
api.addTemplateModel(Templates.id("pressure_plate_up_special") , api.auto(new Identifier("block/pressure_plate_up")));
api.addTemplateModel(Templates.id("pressure_plate_down_special") , api.auto(new Identifier("block/pressure_plate_down")));
api.addTemplateModel(Templates.id("slab_special") , api.auto(new Identifier("block/slab")));
api.addTemplateModel(Templates.id("stairs_special") , api.auto(new Identifier("block/stairs")));
api.addTemplateModel(Templates.id("double_outer_stairs_special") , api.auto(Templates.id("block/double_outer_stairs")));
api.addTemplateModel(Templates.id("inner_stairs_special") , api.auto(new Identifier("block/inner_stairs")));
api.addTemplateModel(Templates.id("outer_stairs_special") , api.auto(new Identifier("block/outer_stairs")));
api.addTemplateModel(Templates.id("trapdoor_bottom_special") , api.auto(new Identifier("block/template_trapdoor_bottom")));
api.addTemplateModel(Templates.id("trapdoor_top_special") , api.auto(new Identifier("block/template_trapdoor_top")));
api.addTemplateModel(Templates.id("wall_post_special") , api.auto(new Identifier("block/template_wall_post")));
//vanilla style models (using "special-sprite replacement" method)
api.addTemplateModel(Templates.id("lever_special") , api.json(Templates.id("block/lever")));
api.addTemplateModel(Templates.id("trapdoor_open_special") , api.json(Templates.id("block/trapdoor_open")));
api.addTemplateModel(Templates.id("lever_on_special") , api.json(Templates.id("block/lever_on")));
//these next five only exist because AutoRetexturedModels don't seem to rotate their textures the right way when rotated from a multipart blockstate
api.addTemplateModel(Templates.id("fence_side_special") , api.json(Templates.id("block/fence_side")));
api.addTemplateModel(Templates.id("glass_pane_side_special") , api.json(Templates.id("block/glass_pane_side")));
api.addTemplateModel(Templates.id("glass_pane_side_alt_special") , api.json(Templates.id("block/glass_pane_side_alt")));
api.addTemplateModel(Templates.id("wall_side_special") , api.json(Templates.id("block/wall_side")));
api.addTemplateModel(Templates.id("wall_side_tall_special") , api.json(Templates.id("block/wall_side_tall")));
//item only models
api.addTemplateModel(Templates.id("button_inventory_special") , api.auto(new Identifier("block/button_inventory")));
api.addTemplateModel(Templates.id("fence_inventory_special") , api.auto(new Identifier("block/fence_inventory")));
api.addTemplateModel(Templates.id("fence_post_inventory_special") , api.auto(Templates.id("block/fence_post_inventory")));
api.addTemplateModel(Templates.id("wall_inventory_special") , api.auto(new Identifier("block/wall_inventory")));
//item model assignments (in lieu of models/item/___.json)
api.assignItemModel(Templates.id("button_inventory_special") , Templates.BUTTON);
api.assignItemModel(Templates.id("carpet_special") , Templates.CARPET);
api.assignItemModel(Templates.id("cube_special") , Templates.CUBE);
api.assignItemModel(Templates.id("fence_inventory_special") , Templates.FENCE);
api.assignItemModel(Templates.id("fence_gate_special") , Templates.FENCE_GATE);
api.assignItemModel(Templates.id("trapdoor_bottom_special") , Templates.IRON_TRAPDOOR);
api.assignItemModel(Templates.id("fence_post_inventory_special") , Templates.POST);
api.assignItemModel(Templates.id("pressure_plate_up_special") , Templates.PRESSURE_PLATE);
api.assignItemModel(Templates.id("slab_special") , Templates.SLAB);
api.assignItemModel(Templates.id("stairs_special") , Templates.STAIRS);
api.assignItemModel(Templates.id("trapdoor_bottom_special") , Templates.TRAPDOOR);
api.assignItemModel(Templates.id("wall_inventory_special") , Templates.WALL);
}
private void privateInit() {
//set up some magic to force chunk rerenders when you change a template (see TemplateEntity)
Templates.chunkRerenderProxy = (world, pos) -> {
if(world == MinecraftClient.getInstance().world) {
MinecraftClient.getInstance().worldRenderer.scheduleBlockRender(
ChunkSectionPos.getSectionCoord(pos.getX()),
ChunkSectionPos.getSectionCoord(pos.getY()),
ChunkSectionPos.getSectionCoord(pos.getZ())
);
}
};
//supporting code for the TemplatesModelProvider
ModelLoadingRegistry.INSTANCE.registerResourceProvider(rm -> provider); //block models
ModelLoadingRegistry.INSTANCE.registerVariantProvider(rm -> provider); //item models
ResourceManagerHelper.get(ResourceType.CLIENT_RESOURCES).registerReloadListener(new SimpleSynchronousResourceReloadListener() {
@Override public Identifier getFabricId() { return Templates.id("dump-caches"); }
@Override public void reload(ResourceManager blah) { provider.dumpCache(); }
});
}
}

View File

@ -1,84 +0,0 @@
package fr.adrien1106.reframedtemplates;
import fr.adrien1106.reframedtemplates.api.TemplatesClientApi;
import fr.adrien1106.reframedtemplates.model.apperance.TemplateAppearanceManager;
import fr.adrien1106.reframedtemplates.model.UnbakedAutoRetexturedModel;
import fr.adrien1106.reframedtemplates.model.UnbakedJsonRetexturedModel;
import fr.adrien1106.reframedtemplates.model.UnbakedMeshRetexturedModel;
import net.fabricmc.fabric.api.renderer.v1.Renderer;
import net.fabricmc.fabric.api.renderer.v1.RendererAccess;
import net.fabricmc.fabric.api.renderer.v1.mesh.Mesh;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.client.render.model.UnbakedModel;
import net.minecraft.client.texture.Sprite;
import net.minecraft.client.util.ModelIdentifier;
import net.minecraft.client.util.SpriteIdentifier;
import net.minecraft.item.ItemConvertible;
import net.minecraft.util.Identifier;
import org.jetbrains.annotations.NotNull;
import java.util.function.Function;
public class TemplatesClientApiImpl implements TemplatesClientApi {
public TemplatesClientApiImpl(TemplatesModelProvider prov) {
this.prov = prov;
}
private final TemplatesModelProvider prov;
@Override
public TweakableUnbakedModel auto(Identifier parent) {
return new UnbakedAutoRetexturedModel(parent);
}
@Override
public TweakableUnbakedModel json(Identifier parent) {
return new UnbakedJsonRetexturedModel(parent);
}
@Override
public TweakableUnbakedModel mesh(Identifier parent, Function<Function<SpriteIdentifier, Sprite>, Mesh> baseMeshFactory) {
return new UnbakedMeshRetexturedModel(parent, baseMeshFactory);
}
@Override
public void addTemplateModel(Identifier id, UnbakedModel unbaked) {
prov.addTemplateModel(id, unbaked);
}
@Override
public void assignItemModel(Identifier templateModelId, ModelIdentifier... modelIds) {
prov.assignItemModel(templateModelId, modelIds);
}
@Override
public void assignItemModel(Identifier templateModelId, Identifier... itemIds) {
prov.assignItemModel(templateModelId, itemIds);
}
@Override
public void assignItemModel(Identifier templateModelId, ItemConvertible... itemConvs) {
prov.assignItemModel(templateModelId, itemConvs);
}
@Override
public TemplateAppearanceManager getOrCreateTemplateApperanceManager(Function<SpriteIdentifier, Sprite> spriteLookup) {
return prov.getOrCreateTemplateApperanceManager(spriteLookup);
}
@Override
public @NotNull Renderer getFabricRenderer() {
Renderer obj = RendererAccess.INSTANCE.getRenderer();
if(obj != null) return obj;
//Welp, not much more we can do, this mod heavily relies on frapi
String msg = "A Fabric Rendering API implementation is required to use Templates 2!";
if(!FabricLoader.getInstance().isModLoaded("fabric-renderer-indigo"))
msg += "\nI noticed you don't have Indigo installed, which is a part of the complete Fabric API package.";
if(FabricLoader.getInstance().isModLoaded("sodium"))
msg += "\nI noticed you have Sodium installed - consider also installing Indium to provide a compatible renderer implementation.";
throw new NullPointerException(msg);
}
}

View File

@ -1,116 +0,0 @@
package fr.adrien1106.reframedtemplates.api;
import fr.adrien1106.reframedtemplates.model.apperance.TemplateAppearanceManager;
import fr.adrien1106.reframedtemplates.TemplatesClient;
import net.fabricmc.fabric.api.renderer.v1.Renderer;
import net.fabricmc.fabric.api.renderer.v1.mesh.Mesh;
import net.minecraft.block.BlockState;
import net.minecraft.client.render.model.UnbakedModel;
import net.minecraft.client.texture.Sprite;
import net.minecraft.client.util.ModelIdentifier;
import net.minecraft.client.util.SpriteIdentifier;
import net.minecraft.item.ItemConvertible;
import net.minecraft.util.Identifier;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import java.util.function.Function;
import java.util.function.Supplier;
@ApiStatus.AvailableSince("2.2")
@SuppressWarnings({"unused", "UnusedReturnValue"}) //this is all public api
public interface TemplatesClientApi {
/**
* Obtain the current API instance.
*/
static TemplatesClientApi getInstance() {
return TemplatesClient.API_IMPL;
}
/// CONSTRUCTING UNBAKED MODELS ///
/**
* - the quad: Sourced from the ID you pass in. It can be a json model.
* - whether you want to retexture it: "Yes". All quads will be retextured.
* - what face of the block: Automatically determined by facing direction.
*/
TweakableUnbakedModel auto(Identifier parent);
/**
* - the quad: Sourced from the ID you pass in. It can be a json model.
* - whether you want to retexture it: Determined from the texture applied to the quad.
* - what face of the block: Determined via the texture applied to the quad.
*/
TweakableUnbakedModel json(Identifier parent);
/**
* - the quad: Sourced from a `Mesh`.
* - whether you want to retexture it: Quads with a nonzero `tag`.
* - what face of the block: Determined from the `tag`.
* <p>
* This form doesn't give the ability to look up sprites, so it's hard to make a sensible quad that won't be retextured.
*/
default TweakableUnbakedModel mesh(Identifier parent, Supplier<Mesh> baseMeshFactory) {
return mesh(parent, __ -> baseMeshFactory.get());
}
/**
* - the quad: Sourced from a `Mesh`.
* - whether you want to retexture it: Quads with a nonzero `tag`.
* - what face of the block: Determined from the `tag`.
* <p>
* You can use the provided Function<SpriteIdentifier, Sprite> to look up sprite UVs and put them on faces with a 0 tag.
* These faces will not get retextured.
*/
TweakableUnbakedModel mesh(Identifier parent, Function<Function<SpriteIdentifier, Sprite>, Mesh> baseMeshFactory);
/**
* Get the TemplateAppearanceManager instance. To retexture a template, there has to be some way of determining what texture should
* go on the top, what texture should go on the north side, and the TemplateAppearanceManager is in charge of gleaning this information
* from the target blockmodels. It also caches this information.
* <p>
* There is one TemplateApperanceManager per resource-load. Please obtain a new one every model bake.
*
* @param spriteLookup Something you'll find as part of UnbakedModel#bake.
*/
TemplateAppearanceManager getOrCreateTemplateApperanceManager(Function<SpriteIdentifier, Sprite> spriteLookup);
/// REGISTERING UNBAKED MODELS ///
/**
* Register an UnbakedModel to be loaded behind a particular ID.
* Astute viewers will note that this is, *currently*, a thin wrapper around the fabric ModelResourceProvider system.
*/
void addTemplateModel(Identifier id, UnbakedModel unbaked);
/**
* When the game loads this ModelIdentifier, it will instead load the UnbakedModel corresponding to the id passed to addTemplateModel.
* Astute viewers will note that this is, *currently*, a thin wrapper around the fabric ModelVariantProvider system.
*/
void assignItemModel(Identifier templateModelId, ModelIdentifier... modelIds);
/**
* Calls assignItemModel(Identifier, ModelIdentifier) with "#inventory" appended.
* In practice: you can pass an item's ID.
*/
void assignItemModel(Identifier templateModelId, Identifier... itemIds);
/**
* Calls assignItemModel(Identifier, Identifier) by first converting the argument to an item, then taking its ID.
* In practice: you can pass a Block (or Item), and the model will be assigned to the block's item form.
*/
void assignItemModel(Identifier templateModelId, ItemConvertible... itemConvs);
/// OTHER STUFF LOL ///
/**
* Simple wrapper around fabric's RenderAccess.INSTANCE.getRenderer() that throws a slightly more informative error if one is not
* present. Note that NullPointerException is not a checked exception.
*/
@NotNull Renderer getFabricRenderer() throws NullPointerException;
interface TweakableUnbakedModel extends UnbakedModel {
TweakableUnbakedModel disableAo();
TweakableUnbakedModel itemModelState(BlockState state);
}
}

View File

@ -1,15 +0,0 @@
package fr.adrien1106.reframedtemplates.mixin.particles;
import net.minecraft.client.particle.Particle;
import net.minecraft.util.math.random.Random;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
@Mixin(Particle.class)
public interface AccessorParticle {
@Accessor("random") Random templates$getRandom();
@Accessor("red") void templates$setRed(float red);
@Accessor("green") void templates$setGreen(float green);
@Accessor("blue") void templates$setBlue(float blue);
}

View File

@ -1,89 +0,0 @@
package fr.adrien1106.reframedtemplates.util;
import net.minecraft.item.ItemPlacementContext;
import net.minecraft.util.StringIdentifiable;
import net.minecraft.util.math.Direction;
import org.joml.Vector3d;
import java.util.Locale;
public enum Edge implements StringIdentifiable {
DOWN_NORTH,
DOWN_SOUTH,
UP_SOUTH,
UP_NORTH,
NORTH_WEST,
SOUTH_WEST,
SOUTH_EAST,
NORTH_EAST,
DOWN_WEST,
UP_WEST,
UP_EAST,
DOWN_EAST;
public static Edge stairslikePlacement(ItemPlacementContext ctx) {
Direction playerHorizontalFacing = ctx.getHorizontalPlayerFacing();
Direction clickedFace = ctx.getSide();
boolean sneaky = ctx.getPlayer() != null && ctx.getPlayer().isSneaky();
double dx = ctx.getHitPos().x - ctx.getBlockPos().getX();
double dy = ctx.getHitPos().y - ctx.getBlockPos().getY();
double dz = ctx.getHitPos().z - ctx.getBlockPos().getZ();
if(clickedFace == Direction.UP || (!sneaky && dy <= 0.5)) return switch(playerHorizontalFacing) {
case NORTH -> DOWN_NORTH;
case EAST -> DOWN_EAST;
case SOUTH -> DOWN_SOUTH;
case WEST -> DOWN_WEST;
default -> throw new IllegalArgumentException();
};
else if(clickedFace == Direction.DOWN || (!sneaky && dy >= 0.5)) return switch(playerHorizontalFacing) {
case NORTH -> UP_NORTH;
case EAST -> UP_EAST;
case SOUTH -> UP_SOUTH;
case WEST -> UP_WEST;
default -> throw new IllegalArgumentException();
};
else return switch(playerHorizontalFacing) {
case NORTH -> dx < 0.5 ? Edge.NORTH_WEST : Edge.NORTH_EAST;
case EAST -> dz < 0.5 ? Edge.NORTH_EAST : Edge.SOUTH_EAST;
case SOUTH -> dx > 0.5 ? Edge.SOUTH_EAST : Edge.SOUTH_WEST;
case WEST -> dz > 0.5 ? Edge.SOUTH_WEST : Edge.NORTH_WEST;
default -> throw new IllegalArgumentException();
};
}
//I may have skill issue
//Beep boop i am very maintainable yes
public record CoordinateFrame(Vector3d origin, Vector3d along, Vector3d a, Vector3d b) {}
private static final Vector3d ZR = new Vector3d();
private static final Vector3d PX = new Vector3d(1, 0, 0);
private static final Vector3d NX = new Vector3d(-1, 0, 0);
private static final Vector3d PY = new Vector3d(0, 1, 0);
private static final Vector3d NY = new Vector3d(0, -1, 0);
private static final Vector3d PZ = new Vector3d(0, 0, 1);
private static final Vector3d NZ = new Vector3d(0, 0, -1);
public CoordinateFrame makeCoordinateFrame() {
return switch(this) {
case DOWN_NORTH -> new CoordinateFrame(ZR, PX, PZ, PY);
case DOWN_EAST -> new CoordinateFrame(PX, PZ, NX, PY);
case DOWN_SOUTH -> new CoordinateFrame(new Vector3d(1, 0, 1), NX, NZ, PY);
case DOWN_WEST -> new CoordinateFrame(PZ, NZ, PX, PY);
case UP_NORTH -> new CoordinateFrame(PY, PX, PZ, NY);
case UP_EAST -> new CoordinateFrame(new Vector3d(1, 1, 0), PZ, NX, NY);
case UP_SOUTH -> new CoordinateFrame(new Vector3d(1, 1, 1), NX, NZ, NY);
case UP_WEST -> new CoordinateFrame(new Vector3d(0, 1, 1), NZ, PX, NY);
case NORTH_WEST -> new CoordinateFrame(ZR, PY, PZ, PX);
case NORTH_EAST -> new CoordinateFrame(PX, PY, NX, PZ);
case SOUTH_EAST -> new CoordinateFrame(new Vector3d(1, 0, 1), PY, NZ, NX);
case SOUTH_WEST -> new CoordinateFrame(PZ, PY, PX, NZ);
};
}
@Override
public String asString() {
return name().toLowerCase(Locale.ROOT);
}
}

View File

@ -1,32 +0,0 @@
package fr.adrien1106.reframedtemplates.util;
import net.minecraft.util.shape.VoxelShape;
import net.minecraft.util.shape.VoxelShapes;
import org.joml.Vector3d;
public class StairShapeMaker {
//TODO: clean this the fuck up, maybe keep in mind that VoxelShapes can be rotated multiples of 90 degrees by just rotating their corners
public static VoxelShape makeStair(Edge innerEdge, double stepIn, double initialStepRise, double stepRise, double stepRun, int stepCount) {
Edge.CoordinateFrame frame = innerEdge.makeCoordinateFrame();
Vector3d origin = frame.origin();
Vector3d in = new Vector3d(frame.a()).mul(stepIn);
Vector3d fstRise = new Vector3d(frame.b()).mul(initialStepRise);
Vector3d cursor = new Vector3d(origin).add(frame.along()).add(in).add(fstRise);
Vector3d step = new Vector3d(frame.b()).mul(stepRise).add(new Vector3d(frame.a()).mul(-stepRun));
VoxelShape shape = VoxelShapes.empty();
for(int i = 0; i < stepCount; i++) {
shape = VoxelShapes.union(shape, box(origin.x, origin.y, origin.z, cursor.x, cursor.y, cursor.z));
cursor.add(step);
}
return shape.simplify();
}
//VoxelShape's constructor is picky about specifying your mins before your maxs
private static VoxelShape box(double x1, double y1, double z1, double x2, double y2, double z2) {
return VoxelShapes.cuboid(Math.min(x1, x2), Math.min(y1, y2), Math.min(z1, z2), Math.max(x1, x2), Math.max(y1, y2), Math.max(z1, z2));
}
}

View File

@ -2,8 +2,8 @@
"sources": [
{
"type": "directory",
"source": "templates_special",
"prefix": "templates_special/"
"source": "reframed_special",
"prefix": "reframed_special/"
}
]
}

View File

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

@ -1,115 +1,115 @@
{
"variants": {
"face=ceiling,facing=east,powered=false": {
"model": "reframedtemplates:button_special",
"model": "reframed:button_special",
"x": 180,
"y": 270
},
"face=ceiling,facing=east,powered=true": {
"model": "reframedtemplates:button_pressed_special",
"model": "reframed:button_pressed_special",
"x": 180,
"y": 270
},
"face=ceiling,facing=north,powered=false": {
"model": "reframedtemplates:button_special",
"model": "reframed:button_special",
"x": 180,
"y": 180
},
"face=ceiling,facing=north,powered=true": {
"model": "reframedtemplates:button_pressed_special",
"model": "reframed:button_pressed_special",
"x": 180,
"y": 180
},
"face=ceiling,facing=south,powered=false": {
"model": "reframedtemplates:button_special",
"model": "reframed:button_special",
"x": 180
},
"face=ceiling,facing=south,powered=true": {
"model": "reframedtemplates:button_pressed_special",
"model": "reframed:button_pressed_special",
"x": 180
},
"face=ceiling,facing=west,powered=false": {
"model": "reframedtemplates:button_special",
"model": "reframed:button_special",
"x": 180,
"y": 90
},
"face=ceiling,facing=west,powered=true": {
"model": "reframedtemplates:button_pressed_special",
"model": "reframed:button_pressed_special",
"x": 180,
"y": 90
},
"face=floor,facing=east,powered=false": {
"model": "reframedtemplates:button_special",
"model": "reframed:button_special",
"y": 90
},
"face=floor,facing=east,powered=true": {
"model": "reframedtemplates:button_pressed_special",
"model": "reframed:button_pressed_special",
"y": 90
},
"face=floor,facing=north,powered=false": {
"model": "reframedtemplates:button_special"
"model": "reframed:button_special"
},
"face=floor,facing=north,powered=true": {
"model": "reframedtemplates:button_pressed_special"
"model": "reframed:button_pressed_special"
},
"face=floor,facing=south,powered=false": {
"model": "reframedtemplates:button_special",
"model": "reframed:button_special",
"y": 180
},
"face=floor,facing=south,powered=true": {
"model": "reframedtemplates:button_pressed_special",
"model": "reframed:button_pressed_special",
"y": 180
},
"face=floor,facing=west,powered=false": {
"model": "reframedtemplates:button_special",
"model": "reframed:button_special",
"y": 270
},
"face=floor,facing=west,powered=true": {
"model": "reframedtemplates:button_pressed_special",
"model": "reframed:button_pressed_special",
"y": 270
},
"face=wall,facing=east,powered=false": {
"model": "reframedtemplates:button_special",
"model": "reframed:button_special",
"uvlock": true,
"x": 90,
"y": 90
},
"face=wall,facing=east,powered=true": {
"model": "reframedtemplates:button_pressed_special",
"model": "reframed:button_pressed_special",
"uvlock": true,
"x": 90,
"y": 90
},
"face=wall,facing=north,powered=false": {
"model": "reframedtemplates:button_special",
"model": "reframed:button_special",
"uvlock": true,
"x": 90
},
"face=wall,facing=north,powered=true": {
"model": "reframedtemplates:button_pressed_special",
"model": "reframed:button_pressed_special",
"uvlock": true,
"x": 90
},
"face=wall,facing=south,powered=false": {
"model": "reframedtemplates:button_special",
"model": "reframed:button_special",
"uvlock": true,
"x": 90,
"y": 180
},
"face=wall,facing=south,powered=true": {
"model": "reframedtemplates:button_pressed_special",
"model": "reframed:button_pressed_special",
"uvlock": true,
"x": 90,
"y": 180
},
"face=wall,facing=west,powered=false": {
"model": "reframedtemplates:button_special",
"model": "reframed:button_special",
"uvlock": true,
"x": 90,
"y": 270
},
"face=wall,facing=west,powered=true": {
"model": "reframedtemplates:button_pressed_special",
"model": "reframed:button_pressed_special",
"uvlock": true,
"x": 90,
"y": 270

View File

@ -0,0 +1,16 @@
{
"variants": {
"candles=1": {
"model": "reframed:one_candle_special"
},
"candles=2": {
"model": "reframed:two_candles_special"
},
"candles=3": {
"model": "reframed:three_candles_special"
},
"candles=4": {
"model": "reframed:four_candles_special"
}
}
}

View File

@ -0,0 +1,7 @@
{
"variants": {
"": {
"model": "reframed:carpet_special"
}
}
}

View File

@ -0,0 +1,7 @@
{
"variants": {
"": {
"model": "reframed:cube_special"
}
}
}

View File

@ -1,123 +1,123 @@
{
"variants": {
"facing=east,half=lower,hinge=left,open=false": {
"model": "reframedtemplates:door_bottom_left_special"
"model": "reframed:door_bottom_left_special"
},
"facing=east,half=lower,hinge=left,open=true": {
"model": "reframedtemplates:door_bottom_left_open_special",
"model": "reframed:door_bottom_left_open_special",
"y": 90
},
"facing=east,half=lower,hinge=right,open=false": {
"model": "reframedtemplates:door_bottom_right_special"
"model": "reframed:door_bottom_right_special"
},
"facing=east,half=lower,hinge=right,open=true": {
"model": "reframedtemplates:door_bottom_right_open_special",
"model": "reframed:door_bottom_right_open_special",
"y": 270
},
"facing=east,half=upper,hinge=left,open=false": {
"model": "reframedtemplates:door_top_left_special"
"model": "reframed:door_top_left_special"
},
"facing=east,half=upper,hinge=left,open=true": {
"model": "reframedtemplates:door_top_left_open_special",
"model": "reframed:door_top_left_open_special",
"y": 90
},
"facing=east,half=upper,hinge=right,open=false": {
"model": "reframedtemplates:door_top_right_special"
"model": "reframed:door_top_right_special"
},
"facing=east,half=upper,hinge=right,open=true": {
"model": "reframedtemplates:door_top_right_open_special",
"model": "reframed:door_top_right_open_special",
"y": 270
},
"facing=north,half=lower,hinge=left,open=false": {
"model": "reframedtemplates:door_bottom_left_special",
"model": "reframed:door_bottom_left_special",
"y": 270
},
"facing=north,half=lower,hinge=left,open=true": {
"model": "reframedtemplates:door_bottom_left_open_special"
"model": "reframed:door_bottom_left_open_special"
},
"facing=north,half=lower,hinge=right,open=false": {
"model": "reframedtemplates:door_bottom_right_special",
"model": "reframed:door_bottom_right_special",
"y": 270
},
"facing=north,half=lower,hinge=right,open=true": {
"model": "reframedtemplates:door_bottom_right_open_special",
"model": "reframed:door_bottom_right_open_special",
"y": 180
},
"facing=north,half=upper,hinge=left,open=false": {
"model": "reframedtemplates:door_top_left_special",
"model": "reframed:door_top_left_special",
"y": 270
},
"facing=north,half=upper,hinge=left,open=true": {
"model": "reframedtemplates:door_top_left_open_special"
"model": "reframed:door_top_left_open_special"
},
"facing=north,half=upper,hinge=right,open=false": {
"model": "reframedtemplates:door_top_right_special",
"model": "reframed:door_top_right_special",
"y": 270
},
"facing=north,half=upper,hinge=right,open=true": {
"model": "reframedtemplates:door_top_right_open_special",
"model": "reframed:door_top_right_open_special",
"y": 180
},
"facing=south,half=lower,hinge=left,open=false": {
"model": "reframedtemplates:door_bottom_left_special",
"model": "reframed:door_bottom_left_special",
"y": 90
},
"facing=south,half=lower,hinge=left,open=true": {
"model": "reframedtemplates:door_bottom_left_open_special",
"model": "reframed:door_bottom_left_open_special",
"y": 180
},
"facing=south,half=lower,hinge=right,open=false": {
"model": "reframedtemplates:door_bottom_right_special",
"model": "reframed:door_bottom_right_special",
"y": 90
},
"facing=south,half=lower,hinge=right,open=true": {
"model": "reframedtemplates:door_bottom_right_open_special"
"model": "reframed:door_bottom_right_open_special"
},
"facing=south,half=upper,hinge=left,open=false": {
"model": "reframedtemplates:door_top_left_special",
"model": "reframed:door_top_left_special",
"y": 90
},
"facing=south,half=upper,hinge=left,open=true": {
"model": "reframedtemplates:door_top_left_open_special",
"model": "reframed:door_top_left_open_special",
"y": 180
},
"facing=south,half=upper,hinge=right,open=false": {
"model": "reframedtemplates:door_top_right_special",
"model": "reframed:door_top_right_special",
"y": 90
},
"facing=south,half=upper,hinge=right,open=true": {
"model": "reframedtemplates:door_top_right_open_special"
"model": "reframed:door_top_right_open_special"
},
"facing=west,half=lower,hinge=left,open=false": {
"model": "reframedtemplates:door_bottom_left_special",
"model": "reframed:door_bottom_left_special",
"y": 180
},
"facing=west,half=lower,hinge=left,open=true": {
"model": "reframedtemplates:door_bottom_left_open_special",
"model": "reframed:door_bottom_left_open_special",
"y": 270
},
"facing=west,half=lower,hinge=right,open=false": {
"model": "reframedtemplates:door_bottom_right_special",
"model": "reframed:door_bottom_right_special",
"y": 180
},
"facing=west,half=lower,hinge=right,open=true": {
"model": "reframedtemplates:door_bottom_right_open_special",
"model": "reframed:door_bottom_right_open_special",
"y": 90
},
"facing=west,half=upper,hinge=left,open=false": {
"model": "reframedtemplates:door_top_left_special",
"model": "reframed:door_top_left_special",
"y": 180
},
"facing=west,half=upper,hinge=left,open=true": {
"model": "reframedtemplates:door_top_left_open_special",
"model": "reframed:door_top_left_open_special",
"y": 270
},
"facing=west,half=upper,hinge=right,open=false": {
"model": "reframedtemplates:door_top_right_special",
"model": "reframed:door_top_right_special",
"y": 180
},
"facing=west,half=upper,hinge=right,open=true": {
"model": "reframedtemplates:door_top_right_open_special",
"model": "reframed:door_top_right_open_special",
"y": 90
}
}

View File

@ -2,12 +2,12 @@
"multipart": [
{
"apply": {
"model": "reframedtemplates:fence_post_special"
"model": "reframed:fence_post_special"
}
},
{
"apply": {
"model": "reframedtemplates:fence_side_special",
"model": "reframed:fence_side_special",
"uvlock": true
},
"when": {
@ -16,7 +16,7 @@
},
{
"apply": {
"model": "reframedtemplates:fence_side_special",
"model": "reframed:fence_side_special",
"uvlock": true,
"y": 90
},
@ -26,7 +26,7 @@
},
{
"apply": {
"model": "reframedtemplates:fence_side_special",
"model": "reframed:fence_side_special",
"uvlock": true,
"y": 180
},
@ -36,7 +36,7 @@
},
{
"apply": {
"model": "reframedtemplates:fence_side_special",
"model": "reframed:fence_side_special",
"uvlock": true,
"y": 270
},

View File

@ -1,78 +1,78 @@
{
"variants": {
"facing=east,in_wall=false,open=false": {
"model": "reframedtemplates:fence_gate_special",
"model": "reframed:fence_gate_special",
"uvlock": true,
"y": 270
},
"facing=east,in_wall=false,open=true": {
"model": "reframedtemplates:fence_gate_open_special",
"model": "reframed:fence_gate_open_special",
"uvlock": true,
"y": 270
},
"facing=east,in_wall=true,open=false": {
"model": "reframedtemplates:fence_gate_wall_special",
"model": "reframed:fence_gate_wall_special",
"uvlock": true,
"y": 270
},
"facing=east,in_wall=true,open=true": {
"model": "reframedtemplates:fence_gate_wall_open_special",
"model": "reframed:fence_gate_wall_open_special",
"uvlock": true,
"y": 270
},
"facing=north,in_wall=false,open=false": {
"model": "reframedtemplates:fence_gate_special",
"model": "reframed:fence_gate_special",
"uvlock": true,
"y": 180
},
"facing=north,in_wall=false,open=true": {
"model": "reframedtemplates:fence_gate_open_special",
"model": "reframed:fence_gate_open_special",
"uvlock": true,
"y": 180
},
"facing=north,in_wall=true,open=false": {
"model": "reframedtemplates:fence_gate_wall_special",
"model": "reframed:fence_gate_wall_special",
"uvlock": true,
"y": 180
},
"facing=north,in_wall=true,open=true": {
"model": "reframedtemplates:fence_gate_wall_open_special",
"model": "reframed:fence_gate_wall_open_special",
"uvlock": true,
"y": 180
},
"facing=south,in_wall=false,open=false": {
"model": "reframedtemplates:fence_gate_special",
"model": "reframed:fence_gate_special",
"uvlock": true
},
"facing=south,in_wall=false,open=true": {
"model": "reframedtemplates:fence_gate_open_special",
"model": "reframed:fence_gate_open_special",
"uvlock": true
},
"facing=south,in_wall=true,open=false": {
"model": "reframedtemplates:fence_gate_wall_special",
"model": "reframed:fence_gate_wall_special",
"uvlock": true
},
"facing=south,in_wall=true,open=true": {
"model": "reframedtemplates:fence_gate_wall_open_special",
"model": "reframed:fence_gate_wall_open_special",
"uvlock": true
},
"facing=west,in_wall=false,open=false": {
"model": "reframedtemplates:fence_gate_special",
"model": "reframed:fence_gate_special",
"uvlock": true,
"y": 90
},
"facing=west,in_wall=false,open=true": {
"model": "reframedtemplates:fence_gate_open_special",
"model": "reframed:fence_gate_open_special",
"uvlock": true,
"y": 90
},
"facing=west,in_wall=true,open=false": {
"model": "reframedtemplates:fence_gate_wall_special",
"model": "reframed:fence_gate_wall_special",
"uvlock": true,
"y": 90
},
"facing=west,in_wall=true,open=true": {
"model": "reframedtemplates:fence_gate_wall_open_special",
"model": "reframed:fence_gate_wall_open_special",
"uvlock": true,
"y": 90
}

View File

@ -1,123 +1,123 @@
{
"variants": {
"facing=east,half=lower,hinge=left,open=false": {
"model": "reframedtemplates:door_bottom_left_special"
"model": "reframed:door_bottom_left_special"
},
"facing=east,half=lower,hinge=left,open=true": {
"model": "reframedtemplates:door_bottom_left_open_special",
"model": "reframed:door_bottom_left_open_special",
"y": 90
},
"facing=east,half=lower,hinge=right,open=false": {
"model": "reframedtemplates:door_bottom_right_special"
"model": "reframed:door_bottom_right_special"
},
"facing=east,half=lower,hinge=right,open=true": {
"model": "reframedtemplates:door_bottom_right_open_special",
"model": "reframed:door_bottom_right_open_special",
"y": 270
},
"facing=east,half=upper,hinge=left,open=false": {
"model": "reframedtemplates:door_top_left_special"
"model": "reframed:door_top_left_special"
},
"facing=east,half=upper,hinge=left,open=true": {
"model": "reframedtemplates:door_top_left_open_special",
"model": "reframed:door_top_left_open_special",
"y": 90
},
"facing=east,half=upper,hinge=right,open=false": {
"model": "reframedtemplates:door_top_right_special"
"model": "reframed:door_top_right_special"
},
"facing=east,half=upper,hinge=right,open=true": {
"model": "reframedtemplates:door_top_right_open_special",
"model": "reframed:door_top_right_open_special",
"y": 270
},
"facing=north,half=lower,hinge=left,open=false": {
"model": "reframedtemplates:door_bottom_left_special",
"model": "reframed:door_bottom_left_special",
"y": 270
},
"facing=north,half=lower,hinge=left,open=true": {
"model": "reframedtemplates:door_bottom_left_open_special"
"model": "reframed:door_bottom_left_open_special"
},
"facing=north,half=lower,hinge=right,open=false": {
"model": "reframedtemplates:door_bottom_right_special",
"model": "reframed:door_bottom_right_special",
"y": 270
},
"facing=north,half=lower,hinge=right,open=true": {
"model": "reframedtemplates:door_bottom_right_open_special",
"model": "reframed:door_bottom_right_open_special",
"y": 180
},
"facing=north,half=upper,hinge=left,open=false": {
"model": "reframedtemplates:door_top_left_special",
"model": "reframed:door_top_left_special",
"y": 270
},
"facing=north,half=upper,hinge=left,open=true": {
"model": "reframedtemplates:door_top_left_open_special"
"model": "reframed:door_top_left_open_special"
},
"facing=north,half=upper,hinge=right,open=false": {
"model": "reframedtemplates:door_top_right_special",
"model": "reframed:door_top_right_special",
"y": 270
},
"facing=north,half=upper,hinge=right,open=true": {
"model": "reframedtemplates:door_top_right_open_special",
"model": "reframed:door_top_right_open_special",
"y": 180
},
"facing=south,half=lower,hinge=left,open=false": {
"model": "reframedtemplates:door_bottom_left_special",
"model": "reframed:door_bottom_left_special",
"y": 90
},
"facing=south,half=lower,hinge=left,open=true": {
"model": "reframedtemplates:door_bottom_left_open_special",
"model": "reframed:door_bottom_left_open_special",
"y": 180
},
"facing=south,half=lower,hinge=right,open=false": {
"model": "reframedtemplates:door_bottom_right_special",
"model": "reframed:door_bottom_right_special",
"y": 90
},
"facing=south,half=lower,hinge=right,open=true": {
"model": "reframedtemplates:door_bottom_right_open_special"
"model": "reframed:door_bottom_right_open_special"
},
"facing=south,half=upper,hinge=left,open=false": {
"model": "reframedtemplates:door_top_left_special",
"model": "reframed:door_top_left_special",
"y": 90
},
"facing=south,half=upper,hinge=left,open=true": {
"model": "reframedtemplates:door_top_left_open_special",
"model": "reframed:door_top_left_open_special",
"y": 180
},
"facing=south,half=upper,hinge=right,open=false": {
"model": "reframedtemplates:door_top_right_special",
"model": "reframed:door_top_right_special",
"y": 90
},
"facing=south,half=upper,hinge=right,open=true": {
"model": "reframedtemplates:door_top_right_open_special"
"model": "reframed:door_top_right_open_special"
},
"facing=west,half=lower,hinge=left,open=false": {
"model": "reframedtemplates:door_bottom_left_special",
"model": "reframed:door_bottom_left_special",
"y": 180
},
"facing=west,half=lower,hinge=left,open=true": {
"model": "reframedtemplates:door_bottom_left_open_special",
"model": "reframed:door_bottom_left_open_special",
"y": 270
},
"facing=west,half=lower,hinge=right,open=false": {
"model": "reframedtemplates:door_bottom_right_special",
"model": "reframed:door_bottom_right_special",
"y": 180
},
"facing=west,half=lower,hinge=right,open=true": {
"model": "reframedtemplates:door_bottom_right_open_special",
"model": "reframed:door_bottom_right_open_special",
"y": 90
},
"facing=west,half=upper,hinge=left,open=false": {
"model": "reframedtemplates:door_top_left_special",
"model": "reframed:door_top_left_special",
"y": 180
},
"facing=west,half=upper,hinge=left,open=true": {
"model": "reframedtemplates:door_top_left_open_special",
"model": "reframed:door_top_left_open_special",
"y": 270
},
"facing=west,half=upper,hinge=right,open=false": {
"model": "reframedtemplates:door_top_right_special",
"model": "reframed:door_top_right_special",
"y": 180
},
"facing=west,half=upper,hinge=right,open=true": {
"model": "reframedtemplates:door_top_right_open_special",
"model": "reframed:door_top_right_open_special",
"y": 90
}
}

View File

@ -1,67 +1,67 @@
{
"variants": {
"facing=east,half=bottom,open=false": {
"model": "reframedtemplates:trapdoor_bottom_special",
"model": "reframed:trapdoor_bottom_special",
"y": 90
},
"facing=east,half=bottom,open=true": {
"model": "reframedtemplates:trapdoor_open_special",
"model": "reframed:trapdoor_open_special",
"y": 90
},
"facing=east,half=top,open=false": {
"model": "reframedtemplates:trapdoor_top_special",
"model": "reframed:trapdoor_top_special",
"y": 90
},
"facing=east,half=top,open=true": {
"model": "reframedtemplates:trapdoor_open_special",
"model": "reframed:trapdoor_open_special",
"x": 180,
"y": 270
},
"facing=north,half=bottom,open=false": {
"model": "reframedtemplates:trapdoor_bottom_special"
"model": "reframed:trapdoor_bottom_special"
},
"facing=north,half=bottom,open=true": {
"model": "reframedtemplates:trapdoor_open_special"
"model": "reframed:trapdoor_open_special"
},
"facing=north,half=top,open=false": {
"model": "reframedtemplates:trapdoor_top_special"
"model": "reframed:trapdoor_top_special"
},
"facing=north,half=top,open=true": {
"model": "reframedtemplates:trapdoor_open_special",
"model": "reframed:trapdoor_open_special",
"x": 180,
"y": 180
},
"facing=south,half=bottom,open=false": {
"model": "reframedtemplates:trapdoor_bottom_special",
"model": "reframed:trapdoor_bottom_special",
"y": 180
},
"facing=south,half=bottom,open=true": {
"model": "reframedtemplates:trapdoor_open_special",
"model": "reframed:trapdoor_open_special",
"y": 180
},
"facing=south,half=top,open=false": {
"model": "reframedtemplates:trapdoor_top_special",
"model": "reframed:trapdoor_top_special",
"y": 180
},
"facing=south,half=top,open=true": {
"model": "reframedtemplates:trapdoor_open_special",
"model": "reframed:trapdoor_open_special",
"x": 180,
"y": 0
},
"facing=west,half=bottom,open=false": {
"model": "reframedtemplates:trapdoor_bottom_special",
"model": "reframed:trapdoor_bottom_special",
"y": 270
},
"facing=west,half=bottom,open=true": {
"model": "reframedtemplates:trapdoor_open_special",
"model": "reframed:trapdoor_open_special",
"y": 270
},
"facing=west,half=top,open=false": {
"model": "reframedtemplates:trapdoor_top_special",
"model": "reframed:trapdoor_top_special",
"y": 270
},
"facing=west,half=top,open=true": {
"model": "reframedtemplates:trapdoor_open_special",
"model": "reframed:trapdoor_open_special",
"x": 180,
"y": 90
}

View File

@ -1,108 +1,108 @@
{
"variants": {
"face=ceiling,facing=east,powered=false": {
"model": "reframedtemplates:lever_on_special",
"model": "reframed:lever_on_special",
"x": 180,
"y": 270
},
"face=ceiling,facing=east,powered=true": {
"model": "reframedtemplates:lever_special",
"model": "reframed:lever_special",
"x": 180,
"y": 270
},
"face=ceiling,facing=north,powered=false": {
"model": "reframedtemplates:lever_on_special",
"model": "reframed:lever_on_special",
"x": 180,
"y": 180
},
"face=ceiling,facing=north,powered=true": {
"model": "reframedtemplates:lever_special",
"model": "reframed:lever_special",
"x": 180,
"y": 180
},
"face=ceiling,facing=south,powered=false": {
"model": "reframedtemplates:lever_on_special",
"model": "reframed:lever_on_special",
"x": 180
},
"face=ceiling,facing=south,powered=true": {
"model": "reframedtemplates:lever_special",
"model": "reframed:lever_special",
"x": 180
},
"face=ceiling,facing=west,powered=false": {
"model": "reframedtemplates:lever_on_special",
"model": "reframed:lever_on_special",
"x": 180,
"y": 90
},
"face=ceiling,facing=west,powered=true": {
"model": "reframedtemplates:lever_special",
"model": "reframed:lever_special",
"x": 180,
"y": 90
},
"face=floor,facing=east,powered=false": {
"model": "reframedtemplates:lever_on_special",
"model": "reframed:lever_on_special",
"y": 90
},
"face=floor,facing=east,powered=true": {
"model": "reframedtemplates:lever_special",
"model": "reframed:lever_special",
"y": 90
},
"face=floor,facing=north,powered=false": {
"model": "reframedtemplates:lever_on_special"
"model": "reframed:lever_on_special"
},
"face=floor,facing=north,powered=true": {
"model": "reframedtemplates:lever_special"
"model": "reframed:lever_special"
},
"face=floor,facing=south,powered=false": {
"model": "reframedtemplates:lever_on_special",
"model": "reframed:lever_on_special",
"y": 180
},
"face=floor,facing=south,powered=true": {
"model": "reframedtemplates:lever_special",
"model": "reframed:lever_special",
"y": 180
},
"face=floor,facing=west,powered=false": {
"model": "reframedtemplates:lever_on_special",
"model": "reframed:lever_on_special",
"y": 270
},
"face=floor,facing=west,powered=true": {
"model": "reframedtemplates:lever_special",
"model": "reframed:lever_special",
"y": 270
},
"face=wall,facing=east,powered=false": {
"model": "reframedtemplates:lever_on_special",
"model": "reframed:lever_on_special",
"x": 90,
"y": 90
},
"face=wall,facing=east,powered=true": {
"model": "reframedtemplates:lever_special",
"model": "reframed:lever_special",
"x": 90,
"y": 90
},
"face=wall,facing=north,powered=false": {
"model": "reframedtemplates:lever_on_special",
"model": "reframed:lever_on_special",
"x": 90
},
"face=wall,facing=north,powered=true": {
"model": "reframedtemplates:lever_special",
"model": "reframed:lever_special",
"x": 90
},
"face=wall,facing=south,powered=false": {
"model": "reframedtemplates:lever_on_special",
"model": "reframed:lever_on_special",
"x": 90,
"y": 180
},
"face=wall,facing=south,powered=true": {
"model": "reframedtemplates:lever_special",
"model": "reframed:lever_special",
"x": 90,
"y": 180
},
"face=wall,facing=west,powered=false": {
"model": "reframedtemplates:lever_on_special",
"model": "reframed:lever_on_special",
"x": 90,
"y": 270
},
"face=wall,facing=west,powered=true": {
"model": "reframedtemplates:lever_special",
"model": "reframed:lever_special",
"x": 90,
"y": 270
}

View File

@ -2,12 +2,12 @@
"multipart": [
{
"apply": {
"model": "reframedtemplates:glass_pane_post_special"
"model": "reframed:glass_pane_post_special"
}
},
{
"apply": {
"model": "reframedtemplates:glass_pane_side_special"
"model": "reframed:glass_pane_side_special"
},
"when": {
"north": "true"
@ -15,7 +15,7 @@
},
{
"apply": {
"model": "reframedtemplates:glass_pane_side_special",
"model": "reframed:glass_pane_side_special",
"y": 90
},
"when": {
@ -24,7 +24,7 @@
},
{
"apply": {
"model": "reframedtemplates:glass_pane_side_alt_special"
"model": "reframed:glass_pane_side_alt_special"
},
"when": {
"south": "true"
@ -32,7 +32,7 @@
},
{
"apply": {
"model": "reframedtemplates:glass_pane_side_alt_special",
"model": "reframed:glass_pane_side_alt_special",
"y": 90
},
"when": {
@ -41,7 +41,7 @@
},
{
"apply": {
"model": "reframedtemplates:glass_pane_noside_special"
"model": "reframed:glass_pane_noside_special"
},
"when": {
"north": "false"
@ -49,7 +49,7 @@
},
{
"apply": {
"model": "reframedtemplates:glass_pane_noside_alt_special"
"model": "reframed:glass_pane_noside_alt_special"
},
"when": {
"east": "false"
@ -57,7 +57,7 @@
},
{
"apply": {
"model": "reframedtemplates:glass_pane_noside_alt_special",
"model": "reframed:glass_pane_noside_alt_special",
"y": 90
},
"when": {
@ -66,7 +66,7 @@
},
{
"apply": {
"model": "reframedtemplates:glass_pane_noside_special",
"model": "reframed:glass_pane_noside_special",
"y": 270
},
"when": {

View File

@ -1,17 +1,17 @@
{
"variants": {
"axis=x": {
"model": "reframedtemplates:fence_post_special",
"model": "reframed:fence_post_special",
"x": 90,
"y": 90,
"uvlock": true
},
"axis=y": {
"model": "reframedtemplates:fence_post_special",
"model": "reframed:fence_post_special",
"uvlock": true
},
"axis=z": {
"model": "reframedtemplates:fence_post_special",
"model": "reframed:fence_post_special",
"uvlock": true,
"x": 90
}

View File

@ -0,0 +1,10 @@
{
"variants": {
"powered=false": {
"model": "reframed:pressure_plate_up_special"
},
"powered=true": {
"model": "reframed:pressure_plate_down_special"
}
}
}

View File

@ -2,7 +2,7 @@
"multipart": [
{
"apply": {
"model": "reframedtemplates:slab_special",
"model": "reframed:slab_special",
"uvlock": true
},
"when": {
@ -11,7 +11,7 @@
},
{
"apply": {
"model": "reframedtemplates:slab_special",
"model": "reframed:slab_special",
"uvlock": true,
"x": 180
},
@ -21,7 +21,7 @@
},
{
"apply": {
"model": "reframedtemplates:slab_special",
"model": "reframed:slab_special",
"uvlock": true,
"x": 270
},
@ -31,7 +31,7 @@
},
{
"apply": {
"model": "reframedtemplates:slab_special",
"model": "reframed:slab_special",
"uvlock": true,
"x": 90
},
@ -41,7 +41,7 @@
},
{
"apply": {
"model": "reframedtemplates:slab_special",
"model": "reframed:slab_special",
"uvlock": true,
"x": 90,
"y": 90
@ -52,7 +52,7 @@
},
{
"apply": {
"model": "reframedtemplates:slab_special",
"model": "reframed:slab_special",
"uvlock": true,
"x": 90,
"y": 270

View File

@ -1,67 +1,67 @@
{
"variants": {
"facing=east,half=bottom,open=false": {
"model": "reframedtemplates:trapdoor_bottom_special",
"model": "reframed:trapdoor_bottom_special",
"y": 90
},
"facing=east,half=bottom,open=true": {
"model": "reframedtemplates:trapdoor_open_special",
"model": "reframed:trapdoor_open_special",
"y": 90
},
"facing=east,half=top,open=false": {
"model": "reframedtemplates:trapdoor_top_special",
"model": "reframed:trapdoor_top_special",
"y": 90
},
"facing=east,half=top,open=true": {
"model": "reframedtemplates:trapdoor_open_special",
"model": "reframed:trapdoor_open_special",
"x": 180,
"y": 270
},
"facing=north,half=bottom,open=false": {
"model": "reframedtemplates:trapdoor_bottom_special"
"model": "reframed:trapdoor_bottom_special"
},
"facing=north,half=bottom,open=true": {
"model": "reframedtemplates:trapdoor_open_special"
"model": "reframed:trapdoor_open_special"
},
"facing=north,half=top,open=false": {
"model": "reframedtemplates:trapdoor_top_special"
"model": "reframed:trapdoor_top_special"
},
"facing=north,half=top,open=true": {
"model": "reframedtemplates:trapdoor_open_special",
"model": "reframed:trapdoor_open_special",
"x": 180,
"y": 180
},
"facing=south,half=bottom,open=false": {
"model": "reframedtemplates:trapdoor_bottom_special",
"model": "reframed:trapdoor_bottom_special",
"y": 180
},
"facing=south,half=bottom,open=true": {
"model": "reframedtemplates:trapdoor_open_special",
"model": "reframed:trapdoor_open_special",
"y": 180
},
"facing=south,half=top,open=false": {
"model": "reframedtemplates:trapdoor_top_special",
"model": "reframed:trapdoor_top_special",
"y": 180
},
"facing=south,half=top,open=true": {
"model": "reframedtemplates:trapdoor_open_special",
"model": "reframed:trapdoor_open_special",
"x": 180,
"y": 0
},
"facing=west,half=bottom,open=false": {
"model": "reframedtemplates:trapdoor_bottom_special",
"model": "reframed:trapdoor_bottom_special",
"y": 270
},
"facing=west,half=bottom,open=true": {
"model": "reframedtemplates:trapdoor_open_special",
"model": "reframed:trapdoor_open_special",
"y": 270
},
"facing=west,half=top,open=false": {
"model": "reframedtemplates:trapdoor_top_special",
"model": "reframed:trapdoor_top_special",
"y": 270
},
"facing=west,half=top,open=true": {
"model": "reframedtemplates:trapdoor_open_special",
"model": "reframed:trapdoor_open_special",
"x": 180,
"y": 90
}

View File

@ -2,7 +2,7 @@
"multipart": [
{
"apply": {
"model": "reframedtemplates:wall_post_special"
"model": "reframed:wall_post_special"
},
"when": {
"up": "true"
@ -10,7 +10,7 @@
},
{
"apply": {
"model": "reframedtemplates:wall_side_special",
"model": "reframed:wall_side_special",
"uvlock": true
},
"when": {
@ -19,7 +19,7 @@
},
{
"apply": {
"model": "reframedtemplates:wall_side_special",
"model": "reframed:wall_side_special",
"uvlock": true,
"y": 90
},
@ -29,7 +29,7 @@
},
{
"apply": {
"model": "reframedtemplates:wall_side_special",
"model": "reframed:wall_side_special",
"uvlock": true,
"y": 180
},
@ -39,7 +39,7 @@
},
{
"apply": {
"model": "reframedtemplates:wall_side_special",
"model": "reframed:wall_side_special",
"uvlock": true,
"y": 270
},
@ -49,7 +49,7 @@
},
{
"apply": {
"model": "reframedtemplates:wall_side_tall_special",
"model": "reframed:wall_side_tall_special",
"uvlock": true
},
"when": {
@ -58,7 +58,7 @@
},
{
"apply": {
"model": "reframedtemplates:wall_side_tall_special",
"model": "reframed:wall_side_tall_special",
"uvlock": true,
"y": 90
},
@ -68,7 +68,7 @@
},
{
"apply": {
"model": "reframedtemplates:wall_side_tall_special",
"model": "reframed:wall_side_tall_special",
"uvlock": true,
"y": 180
},
@ -78,7 +78,7 @@
},
{
"apply": {
"model": "reframedtemplates:wall_side_tall_special",
"model": "reframed:wall_side_tall_special",
"uvlock": true,
"y": 270
},

View File

@ -0,0 +1,22 @@
{
"itemGroup.reframed.tab": "Frames",
"block.reframed.button": "Button Frame",
"block.reframed.candle": "Candle Frame",
"block.reframed.carpet": "Carpet Frame",
"block.reframed.cube": "Cube Frame",
"block.reframed.door": "Door Frame",
"block.reframed.fence": "Fence Frame",
"block.reframed.fence_gate": "Fence Gate Frame",
"block.reframed.iron_door": "Iron Door Frame",
"block.reframed.iron_trapdoor": "Iron Trapdoor Frame",
"block.reframed.lever": "Lever Frame",
"block.reframed.pane": "Pane Frame",
"block.reframed.post": "Post Frame",
"block.reframed.pressure_plate": "Pressure Plate Frame",
"block.reframed.slab": "Slab Frame",
"block.reframed.stairs": "Stairs Frame",
"block.reframed.trapdoor": "Trapdoor Frame",
"block.reframed.wall": "Wall Frame"
}

View File

@ -1,12 +1,4 @@
{
"textures": {
"down": "reframedtemplates:templates_special/down",
"up": "reframedtemplates:templates_special/up",
"north": "reframedtemplates:templates_special/north",
"south": "reframedtemplates:templates_special/south",
"west": "reframedtemplates:templates_special/west",
"east": "reframedtemplates:templates_special/east"
},
"elements": [
{
"from": [7, 12, 0],

View File

@ -1,13 +1,5 @@
{
"ambientocclusion": false,
"textures": {
"down": "reframedtemplates:templates_special/down",
"up": "reframedtemplates:templates_special/up",
"north": "reframedtemplates:templates_special/north",
"south": "reframedtemplates:templates_special/south",
"west": "reframedtemplates:templates_special/west",
"east": "reframedtemplates:templates_special/east"
},
"elements": [
{
"from": [7, 0, 0],

View File

@ -1,13 +1,5 @@
{
"ambientocclusion": false,
"textures": {
"down": "reframedtemplates:templates_special/down",
"up": "reframedtemplates:templates_special/up",
"north": "reframedtemplates:templates_special/north",
"south": "reframedtemplates:templates_special/south",
"west": "reframedtemplates:templates_special/west",
"east": "reframedtemplates:templates_special/east"
},
"elements": [
{
"from": [7, 0, 9],

View File

@ -2,12 +2,6 @@
"parent": "block/block",
"ambientocclusion": false,
"textures": {
"down": "reframedtemplates:templates_special/down",
"up": "reframedtemplates:templates_special/up",
"north": "reframedtemplates:templates_special/north",
"south": "reframedtemplates:templates_special/south",
"west": "reframedtemplates:templates_special/west",
"east": "reframedtemplates:templates_special/east",
"lever": "block/lever"
},
"elements": [

View File

@ -2,12 +2,6 @@
"parent": "block/block",
"ambientocclusion": false,
"textures": {
"down": "reframedtemplates:templates_special/down",
"up": "reframedtemplates:templates_special/up",
"north": "reframedtemplates:templates_special/north",
"south": "reframedtemplates:templates_special/south",
"west": "reframedtemplates:templates_special/west",
"east": "reframedtemplates:templates_special/east",
"lever": "block/lever"
},
"elements": [

View File

@ -1,13 +1,5 @@
{
"parent": "block/block",
"textures": {
"down": "reframedtemplates:templates_special/down",
"up": "reframedtemplates:templates_special/up",
"north": "reframedtemplates:templates_special/north",
"south": "reframedtemplates:templates_special/south",
"west": "reframedtemplates:templates_special/west",
"east": "reframedtemplates:templates_special/east"
},
"elements": [
{
"from": [0, 0, 13],

View File

@ -1,12 +1,4 @@
{
"textures": {
"down": "reframedtemplates:templates_special/down",
"up": "reframedtemplates:templates_special/up",
"north": "reframedtemplates:templates_special/north",
"south": "reframedtemplates:templates_special/south",
"west": "reframedtemplates:templates_special/west",
"east": "reframedtemplates:templates_special/east"
},
"elements": [
{
"from": [5, 0, 0],

View File

@ -1,12 +1,4 @@
{
"textures": {
"down": "reframedtemplates:templates_special/down",
"up": "reframedtemplates:templates_special/up",
"north": "reframedtemplates:templates_special/north",
"south": "reframedtemplates:templates_special/south",
"west": "reframedtemplates:templates_special/west",
"east": "reframedtemplates:templates_special/east"
},
"elements": [
{
"from": [5, 0, 0],

View File

@ -1,6 +1,6 @@
{
"parent": "minecraft:item/generated",
"textures": {
"layer0": "reframedtemplates:item/candle"
"layer0": "reframed:item/candle"
}
}

View File

@ -1,6 +1,6 @@
{
"parent": "minecraft:item/generated",
"textures": {
"layer0": "reframedtemplates:item/door"
"layer0": "reframed:item/door"
}
}

View File

@ -1,6 +1,6 @@
{
"parent": "minecraft:item/generated",
"textures": {
"layer0": "reframedtemplates:item/door"
"layer0": "reframed:item/door"
}
}

View File

@ -1,6 +1,6 @@
{
"parent": "minecraft:item/generated",
"textures": {
"layer0": "reframedtemplates:item/lever"
"layer0": "reframed:item/lever"
}
}

View File

@ -0,0 +1,6 @@
{
"parent": "minecraft:item/generated",
"textures": {
"layer0": "reframed:block/framed_block"
}
}

View File

Before

Width:  |  Height:  |  Size: 566 B

After

Width:  |  Height:  |  Size: 566 B

View File

Before

Width:  |  Height:  |  Size: 857 B

After

Width:  |  Height:  |  Size: 857 B

View File

Before

Width:  |  Height:  |  Size: 535 B

After

Width:  |  Height:  |  Size: 535 B

Some files were not shown because too many files have changed in this diff Show More