
箱子就是箱子
为原版箱子、木桶及类似容器,以及一些模组对应物提供新功能,让它们更具沉浸感且更有趣。
你是否想过,为什么箱子打开时,物品不会掉进去? ……好吧,我承认,在产生这个想法之前我也没想过。但仔细想想…… 这很合理,对吧?
所以现在,你可以自豪地说箱子就是箱子!享受物品掉进你的存储容器中, 而不是傻乎乎地手动放进去的乐趣吧!
但既然物品可以掉进一个打开的箱子……如果箱子在正确的方向打开, 它们不也应该能从中掉下来吗? 因此,你可以让木桶在朝下打开时,将所有内容物倾倒到地面上!
回到箱子的话题,如果你能打开盖子让物品掉进去,那么盖子打开时难道不应该把物品甩出去吗? 没错!有了这个模组,你可以让箱子在打开时将站在其上的所有物品甩飞! (仅限物品,以保全性命)
最后但同样重要的一点,既然到目前为止打开容器一直只是手动操作, 为了让你能够自动化这些新功能,现在可以通过激活一个指向该容器的空发射器来打开容器!
现在游戏会感觉更自然了,哪怕只是一点点,你同意吗?
功能
- 将物品放入打开的容器中
- 默认:启用
- 游戏规则:
chests.insertOpen
- 让物品从底部打开的容器中掉落
- 默认:禁用
- 游戏规则:
chests.barrelFall - 特殊物品掉落(例如雪球作为实际投掷的雪球掉落)
- 默认:启用
- 游戏规则:
chests.barrelFall.throwableSpecial - 物品标签:
#chests_are_chests:special_fall
- 让箱子盖甩飞物品
- 默认:禁用
- 游戏规则:
chests.lidFling - 实体类型标签:
#chests_are_chests:flingable - 水平甩飞速度
- 默认:0.25
- 游戏规则:
chests.lidFling.horizontalPower
- 垂直甩飞速度
- 默认:0.6
- 游戏规则:
chests.lidFling.verticalPower
- 通过给空发射器供能来打开容器
- 默认:启用
- 游戏规则:
chests.dispenserOpen - 自动打开持续时间(以世界刻为单位)
- 默认:10
- 游戏规则:
chests.dispenserOpen.duration
依赖
模组兼容性
内部兼容性
虽然兼容性已在计划中,但始终更倾向于由模组自身直接实现。 因此,如果你的模组已被计划、正在开发中,甚至已经实现, 请毫不犹豫地自行实现,如有需要,请联系我们寻求帮助,或告知我们 无需保留我们自己的兼容性实现。
已实现
自然兼容
已知(应该)与本模组具有自然兼容性、无需额外实现的模组
正在开发中
已计划
内部拒绝
- Iron Chests: Restocked 由于模组作者名称注册不当,该模组无法被轻易处理。 因此,决定不尝试实现内置兼容性。
自行实现
容器实现
本模组调整了方块实体和物品实体的行为。
为了实现与本模组的兼容性,你需要让你的自定义方块实体实现
mc.recraftors.chestsarechests.util.FallInContainer 接口。
你也可以利用其他接口,例如 mc.recraftors.chestsarechests.util.BlockOpenableContainer
或 mc.recraftors.chestsarechests.util.BooleanHolder,你可以随意使用它们,或者
在你已经继承了原版箱子或木桶类的情况下加以利用。
请随时查看 箱子 和木桶 的实现,以了解如何在所提供的方法中处理方块打开和朝向。
另外,不必担心更新时出现更多方法而你的模组未实现它们,从而导致问题。 没有任何方法计划被删除,也不会包含主版本变更。所有新方法 将_始终_附带默认实现,以避免无意义的问题。
物品实现
本模组允许某些物品(注册在相应物品标签中)在从容器中“掉落”时具有自定义行为。
为此,物品本身必须实现
mc.recraftors.chestsarechests.util.ContainerItemHelper 接口。
该接口有两个需要实现的方法。第一个是可选的,指示物品掉落方向。 这允许指定物品可以从容器的哪一面开口出来。(例如,向上重力的物品可以 指定向上的掉落方向)
默认情况下,第一个方法将返回 DOWN。
第二个方法是特殊掉落行为的实际实现。它应该使用第一个方法来判断 是否运行,并执行预期的操作。该方法的返回值指示物品堆叠是否 已掉落(理论上已被消耗),还是未掉落,因此不应再尝试让它向 同一方向掉落,以避免造成更多的运行时计算压力。
请随时查看 箭或 雪球的实现 ,以了解如何处理特殊物品掉落。
同样,不必担心更新时出现更多方法,因为所有新方法同样将附带默认 实现(如果可能的话,基于已有的方法)。
示例
与版本 0.5 保持同步
容器实现
public class MyCustomBlockEntity extends BlockEntity implements FallInContainer {
private boolean isOpen;
private final int size;
private final DefaultedList<ItemStack> content;
private final Map<Integer, Integer> fallUpdateMap = new HashMap<>();
@Override
public boolean chests$tryInsertion(ItemEntity entity) {
return FallInContainer.chests$inventoryInsertion(this.content, entity, this::setStack);
}
@Override
public boolean chests$isOpen() {
return isOpen;
}
@Override
public VoxelShape chests$InputAreaShape() {
return FallInContainer.ABOVE;
}
@Override
public void chests$forceOpen(ServerWorld world, BlockPos at, BlockState from) {
this.isOpen = true;
this.onOpen();
}
@Override
public boolean chests$tryForceOpen(BlockState from) {
ServerWorld serverWorld = (ServerWorld) this.getWorld();
BlockPos blockPos = this.getPos();
this.chests$forceOpen(serverWorld, blockPos, from);
ChestsAreChests.scheduleTick(serverWorld, blockPos, duration);
}
@Override
public boolean chests$forceClose() {
this.isOpen = false;
this.onClose();
}
@Override
public Map<Integer, Integer> getFallUpdateMap() {
return this.fallUpdateMap;
}
void onOpen() {
// ...
// potential rendering stuff
ChestsAreChests.ejectAbove(Direction.UP, this);
}
}
物品实现
public class MyCustomItem extends Item implements ContainerItemHelper {
public Direction[] chests$getFallDirection(ItemStack stack) {
return new Direction[]{Directions.UP};
}
public boolean defaultOnOpenTick(ItemStack stack, FallInContainer container, Direction direction, World world, Vec3d pos, Vec3d velocity) {
if (!ChestsAreChests.isInArray(direction, chests$getFallDirection(stack))) return false;
MyGravitatedEntity entity = new MyGravitatedEntity(world, pos.x, pos.y, pos.z, stack.copy());
entity.setVelocity(velocity);
world.spawnEntity(entity);
return true;
}
}
展示
正在加载版本记录…

正在加载评论…
评论在新手盒子客户端中发表,这里同步展示。