mirror of
https://github.com/Sollace/Unicopia.git
synced 2024-11-24 05:47:59 +01:00
Crystal doors can now be locked by providing them a signed bangle of comradery.
When locked they will only let the owner or players wearing a signed bangle through. Also you can't cheat them
This commit is contained in:
parent
b99c6b6c29
commit
408c9d11c0
7 changed files with 182 additions and 28 deletions
|
@ -1,36 +1,72 @@
|
||||||
package com.minelittlepony.unicopia.block;
|
package com.minelittlepony.unicopia.block;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import com.minelittlepony.unicopia.EquineContext;
|
import com.minelittlepony.unicopia.EquineContext;
|
||||||
import com.minelittlepony.unicopia.Race;
|
import com.minelittlepony.unicopia.Race;
|
||||||
import com.minelittlepony.unicopia.USounds;
|
import com.minelittlepony.unicopia.USounds;
|
||||||
|
import com.minelittlepony.unicopia.item.FriendshipBraceletItem;
|
||||||
import com.minelittlepony.unicopia.item.UItems;
|
import com.minelittlepony.unicopia.item.UItems;
|
||||||
|
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
|
import net.minecraft.block.BlockEntityProvider;
|
||||||
import net.minecraft.block.BlockSetType;
|
import net.minecraft.block.BlockSetType;
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
|
import net.minecraft.block.Blocks;
|
||||||
import net.minecraft.block.DoorBlock;
|
import net.minecraft.block.DoorBlock;
|
||||||
|
import net.minecraft.block.entity.BlockEntity;
|
||||||
import net.minecraft.block.enums.DoubleBlockHalf;
|
import net.minecraft.block.enums.DoubleBlockHalf;
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.nbt.NbtCompound;
|
||||||
|
import net.minecraft.server.world.ServerWorld;
|
||||||
import net.minecraft.sound.SoundCategory;
|
import net.minecraft.sound.SoundCategory;
|
||||||
|
import net.minecraft.state.StateManager;
|
||||||
|
import net.minecraft.state.property.BooleanProperty;
|
||||||
|
import net.minecraft.state.property.Properties;
|
||||||
import net.minecraft.util.ActionResult;
|
import net.minecraft.util.ActionResult;
|
||||||
import net.minecraft.util.Hand;
|
import net.minecraft.util.Hand;
|
||||||
import net.minecraft.util.hit.BlockHitResult;
|
import net.minecraft.util.hit.BlockHitResult;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.Direction;
|
import net.minecraft.util.math.Direction;
|
||||||
|
import net.minecraft.util.math.random.Random;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
import net.minecraft.world.event.GameEvent;
|
import net.minecraft.world.event.GameEvent;
|
||||||
|
|
||||||
public class CrystalDoorBlock extends DoorBlock {
|
public class CrystalDoorBlock extends DoorBlock implements BlockEntityProvider {
|
||||||
|
public static final BooleanProperty LOCKED = Properties.LOCKED;
|
||||||
|
|
||||||
public CrystalDoorBlock(Settings settings, BlockSetType blockSet) {
|
public CrystalDoorBlock(Settings settings, BlockSetType blockSet) {
|
||||||
super(settings, blockSet);
|
super(settings, blockSet);
|
||||||
|
setDefaultState(getDefaultState().with(LOCKED, false));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
|
||||||
|
super.appendProperties(builder);
|
||||||
|
builder.add(LOCKED);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasRandomTicks(BlockState state) {
|
||||||
|
return state.get(LOCKED);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
@Override
|
||||||
|
public void randomTick(BlockState state, ServerWorld world, BlockPos pos, Random random) {
|
||||||
|
super.randomTick(state, world, pos, random);
|
||||||
|
if (!isLocked(world, pos)) {
|
||||||
|
setOnGuard(state, world, pos, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void neighborUpdate(BlockState state, World world, BlockPos pos, Block sourceBlock, BlockPos sourcePos, boolean notify) {
|
public void neighborUpdate(BlockState state, World world, BlockPos pos, Block sourceBlock, BlockPos sourcePos, boolean notify) {
|
||||||
|
if (!state.get(LOCKED)) {
|
||||||
boolean powered = world.isReceivingRedstonePower(pos) || world.isReceivingRedstonePower(pos.offset(state.get(HALF) == DoubleBlockHalf.LOWER ? Direction.UP : Direction.DOWN));
|
boolean powered = world.isReceivingRedstonePower(pos) || world.isReceivingRedstonePower(pos.offset(state.get(HALF) == DoubleBlockHalf.LOWER ? Direction.UP : Direction.DOWN));
|
||||||
if (!getDefaultState().isOf(sourceBlock) && powered != state.get(POWERED)) {
|
if (!getDefaultState().isOf(sourceBlock) && powered != state.get(POWERED)) {
|
||||||
if (powered) {
|
if (powered) {
|
||||||
|
@ -43,22 +79,104 @@ public class CrystalDoorBlock extends DoorBlock {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (state.get(HALF) == DoubleBlockHalf.LOWER && sourcePos.getY() == pos.getY() - 1) {
|
||||||
|
if (!canPlaceAt(state, world, pos) && world.isAir(sourcePos)) {
|
||||||
|
world.setBlockState(sourcePos, Blocks.DIRT.getDefaultState());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) {
|
public ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) {
|
||||||
if (!EquineContext.of(player).getCompositeRace().any(Race::canCast)) {
|
if (!shouldProvideAccess(world, pos, player)) {
|
||||||
|
if (isLocked(world, pos) || !player.getStackInHand(hand).isOf(UItems.MEADOWBROOKS_STAFF)) {
|
||||||
if (!player.getStackInHand(hand).isOf(UItems.MEADOWBROOKS_STAFF)) {
|
|
||||||
playOpenCloseSound(player, world, pos, false);
|
playOpenCloseSound(player, world, pos, false);
|
||||||
return ActionResult.FAIL;
|
setOnGuard(state, world, pos, true);
|
||||||
|
return ActionResult.CONSUME;
|
||||||
} else {
|
} else {
|
||||||
world.playSound(player, pos, USounds.ENTITY_CRYSTAL_SHARDS_AMBIENT, SoundCategory.BLOCKS, 1, world.getRandom().nextFloat() * 0.1F + 0.9F);
|
world.playSound(player, pos, USounds.ENTITY_CRYSTAL_SHARDS_AMBIENT, SoundCategory.BLOCKS, 1, world.getRandom().nextFloat() * 0.1F + 0.9F);
|
||||||
}
|
}
|
||||||
|
} else if (!isLocked(world, pos)) {
|
||||||
|
ItemStack heldStack = player.getStackInHand(hand);
|
||||||
|
if (heldStack.isOf(UItems.FRIENDSHIP_BRACELET)) {
|
||||||
|
@Nullable
|
||||||
|
UUID signator = FriendshipBraceletItem.getSignatorId(heldStack);
|
||||||
|
if (signator != null) {
|
||||||
|
BlockEntityUtil.getOrCreateBlockEntity(world, state.get(HALF) == DoubleBlockHalf.LOWER ? pos.up() : pos, UBlockEntities.CRYSTAL_DOOR).ifPresent(data -> {
|
||||||
|
data.setSignator(signator);
|
||||||
|
setOnGuard(state, world, pos, true);
|
||||||
|
world.playSound(player, pos, USounds.ENTITY_CRYSTAL_SHARDS_AMBIENT, SoundCategory.BLOCKS, 1, world.getRandom().nextFloat() * 0.1F + 0.9F);
|
||||||
|
});
|
||||||
|
return ActionResult.SUCCESS;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
setOnGuard(state, world, pos, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return super.onUse(state, world, pos, player, hand, hit);
|
return super.onUse(state, world, pos, player, hand, hit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void setOnGuard(BlockState state, World world, BlockPos pos, boolean locked) {
|
||||||
|
world.setBlockState(pos, state.with(LOCKED, locked));
|
||||||
|
pos = pos.offset(state.get(HALF) == DoubleBlockHalf.LOWER ? Direction.UP : Direction.DOWN);
|
||||||
|
state = world.getBlockState(pos);
|
||||||
|
if (state.isOf(this)) {
|
||||||
|
world.setBlockState(pos, state.with(LOCKED, locked));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean shouldProvideAccess(World world, BlockPos pos, PlayerEntity player) {
|
||||||
|
UUID signator = getSignator(world, pos);
|
||||||
|
if (signator != null) {
|
||||||
|
return signator.equals(player.getUuid()) || FriendshipBraceletItem.isComrade(signator, player);
|
||||||
|
}
|
||||||
|
return EquineContext.of(player).getCompositeRace().any(Race::canCast);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isLocked(World world, BlockPos pos) {
|
||||||
|
return getSignator(world, pos) != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private UUID getSignator(World world, BlockPos pos) {
|
||||||
|
pos = world.getBlockState(pos).get(HALF) == DoubleBlockHalf.LOWER ? pos.up() : pos;
|
||||||
|
var d = world.getBlockEntity(pos, UBlockEntities.CRYSTAL_DOOR);
|
||||||
|
return d.map(data -> data.signator).orElse(null);
|
||||||
|
}
|
||||||
|
|
||||||
private void playOpenCloseSound(@Nullable Entity entity, World world, BlockPos pos, boolean open) {
|
private void playOpenCloseSound(@Nullable Entity entity, World world, BlockPos pos, boolean open) {
|
||||||
world.playSound(entity, pos, open ? getBlockSetType().doorOpen() : getBlockSetType().doorClose(), SoundCategory.BLOCKS, 1, world.getRandom().nextFloat() * 0.1f + 0.9f);
|
world.playSound(entity, pos, open ? getBlockSetType().doorOpen() : getBlockSetType().doorClose(), SoundCategory.BLOCKS, 1, world.getRandom().nextFloat() * 0.1f + 0.9f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BlockEntity createBlockEntity(BlockPos pos, BlockState state) {
|
||||||
|
return new TileData(pos, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class TileData extends BlockEntity {
|
||||||
|
@Nullable
|
||||||
|
private UUID signator;
|
||||||
|
|
||||||
|
public TileData(BlockPos pos, BlockState state) {
|
||||||
|
super(UBlockEntities.CRYSTAL_DOOR, pos, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSignator(UUID signator) {
|
||||||
|
this.signator = signator;
|
||||||
|
markDirty();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void readNbt(NbtCompound nbt) {
|
||||||
|
signator = nbt.containsUuid("signator") ? nbt.getUuid("signator") : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void writeNbt(NbtCompound nbt) {
|
||||||
|
if (signator != null) {
|
||||||
|
nbt.putUuid("signator", signator);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@ public interface UBlockEntities {
|
||||||
BlockEntityType<ChestBlockEntity> CLOUD_CHEST = create("cloud_chest", BlockEntityType.Builder.create(CloudChestBlock.TileData::new, UBlocks.CLOUD_CHEST));
|
BlockEntityType<ChestBlockEntity> CLOUD_CHEST = create("cloud_chest", BlockEntityType.Builder.create(CloudChestBlock.TileData::new, UBlocks.CLOUD_CHEST));
|
||||||
BlockEntityType<HiveBlock.TileData> HIVE_STORAGE = create("hive_storage", BlockEntityType.Builder.create(HiveBlock.TileData::new, UBlocks.HIVE));
|
BlockEntityType<HiveBlock.TileData> HIVE_STORAGE = create("hive_storage", BlockEntityType.Builder.create(HiveBlock.TileData::new, UBlocks.HIVE));
|
||||||
BlockEntityType<ItemJarBlock.TileData> ITEM_JAR = create("item_jar", BlockEntityType.Builder.create(ItemJarBlock.TileData::new, UBlocks.JAR));
|
BlockEntityType<ItemJarBlock.TileData> ITEM_JAR = create("item_jar", BlockEntityType.Builder.create(ItemJarBlock.TileData::new, UBlocks.JAR));
|
||||||
|
BlockEntityType<CrystalDoorBlock.TileData> CRYSTAL_DOOR = create("crystal_door", BlockEntityType.Builder.create(CrystalDoorBlock.TileData::new, UBlocks.CRYSTAL_DOOR));
|
||||||
|
|
||||||
static <T extends BlockEntity> BlockEntityType<T> create(String id, Builder<T> builder) {
|
static <T extends BlockEntity> BlockEntityType<T> create(String id, Builder<T> builder) {
|
||||||
return Registry.register(Registries.BLOCK_ENTITY_TYPE, id, builder.build(null));
|
return Registry.register(Registries.BLOCK_ENTITY_TYPE, id, builder.build(null));
|
||||||
|
|
|
@ -34,6 +34,7 @@ import net.minecraft.data.client.Model;
|
||||||
import net.minecraft.data.client.ModelIds;
|
import net.minecraft.data.client.ModelIds;
|
||||||
import net.minecraft.data.client.Models;
|
import net.minecraft.data.client.Models;
|
||||||
import net.minecraft.data.client.MultipartBlockStateSupplier;
|
import net.minecraft.data.client.MultipartBlockStateSupplier;
|
||||||
|
import net.minecraft.data.client.TextureKey;
|
||||||
import net.minecraft.data.client.TextureMap;
|
import net.minecraft.data.client.TextureMap;
|
||||||
import net.minecraft.data.client.TexturedModel;
|
import net.minecraft.data.client.TexturedModel;
|
||||||
import net.minecraft.data.client.VariantSettings;
|
import net.minecraft.data.client.VariantSettings;
|
||||||
|
@ -89,7 +90,8 @@ public class UBlockStateModelGenerator extends BlockStateModelGenerator {
|
||||||
registerAll((g, block) -> g.registerParentedItemModel(block, ModelIds.getBlockModelId(block)), UBlocks.SHAPING_BENCH, UBlocks.SURFACE_CHITIN);
|
registerAll((g, block) -> g.registerParentedItemModel(block, ModelIds.getBlockModelId(block)), UBlocks.SHAPING_BENCH, UBlocks.SURFACE_CHITIN);
|
||||||
registerAll(UBlockStateModelGenerator::registerSimpleState, UBlocks.SHAPING_BENCH, UBlocks.BANANAS);
|
registerAll(UBlockStateModelGenerator::registerSimpleState, UBlocks.SHAPING_BENCH, UBlocks.BANANAS);
|
||||||
// doors
|
// doors
|
||||||
registerAll(UBlockStateModelGenerator::registerStableDoor, UBlocks.STABLE_DOOR, UBlocks.DARK_OAK_DOOR, UBlocks.CRYSTAL_DOOR, UBlocks.CLOUD_DOOR);
|
registerAll(UBlockStateModelGenerator::registerStableDoor, UBlocks.STABLE_DOOR, UBlocks.DARK_OAK_DOOR, UBlocks.CLOUD_DOOR);
|
||||||
|
registerLockingDoor(UBlocks.CRYSTAL_DOOR);
|
||||||
|
|
||||||
// cloud blocks
|
// cloud blocks
|
||||||
createCustomTexturePool(UBlocks.CLOUD, TexturedModel.CUBE_ALL).same(UBlocks.UNSTABLE_CLOUD).slab(UBlocks.CLOUD_SLAB).stairs(UBlocks.CLOUD_STAIRS);
|
createCustomTexturePool(UBlocks.CLOUD, TexturedModel.CUBE_ALL).same(UBlocks.UNSTABLE_CLOUD).slab(UBlocks.CLOUD_SLAB).stairs(UBlocks.CLOUD_STAIRS);
|
||||||
|
@ -347,23 +349,37 @@ public class UBlockStateModelGenerator extends BlockStateModelGenerator {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void registerStableDoor(Block door) {
|
public void registerStableDoor(Block door) {
|
||||||
TextureMap topTextures = TextureMap.topBottom(door);
|
|
||||||
TextureMap bottomTextures = topTextures.copyAndAdd(TOP, topTextures.getTexture(BOTTOM));
|
|
||||||
registerItemModel(door.asItem());
|
|
||||||
var variants = BlockStateVariantMap.create(Properties.HORIZONTAL_FACING, Properties.DOUBLE_BLOCK_HALF, Properties.DOOR_HINGE, Properties.OPEN);
|
var variants = BlockStateVariantMap.create(Properties.HORIZONTAL_FACING, Properties.DOUBLE_BLOCK_HALF, Properties.DOOR_HINGE, Properties.OPEN);
|
||||||
fillStableDoorVariantMap(variants, DoubleBlockHalf.LOWER,
|
registerItemModel(door.asItem());
|
||||||
BlockModels.DOOR_LEFT.upload(door, "_bottom_left", bottomTextures, modelCollector),
|
buildDoorStateModels(door, "", variants::register);
|
||||||
BlockModels.DOOR_RIGHT.upload(door, "_bottom_right", bottomTextures, modelCollector)
|
|
||||||
);
|
|
||||||
fillStableDoorVariantMap(variants, DoubleBlockHalf.UPPER,
|
|
||||||
BlockModels.DOOR_LEFT.upload(door, "_top_left", topTextures, modelCollector),
|
|
||||||
BlockModels.DOOR_RIGHT.upload(door, "_top_right", topTextures, modelCollector)
|
|
||||||
);
|
|
||||||
blockStateCollector.accept(VariantsBlockStateSupplier.create(door).coordinate(variants));
|
blockStateCollector.accept(VariantsBlockStateSupplier.create(door).coordinate(variants));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void fillStableDoorVariantMap(
|
public void registerLockingDoor(Block door) {
|
||||||
BlockStateVariantMap.QuadrupleProperty<Direction, DoubleBlockHalf, DoorHinge, Boolean> variantMap,
|
var variants = BlockStateVariantMap.create(Properties.HORIZONTAL_FACING, Properties.DOUBLE_BLOCK_HALF, Properties.DOOR_HINGE, Properties.OPEN, Properties.LOCKED);
|
||||||
|
registerItemModel(door.asItem());
|
||||||
|
buildDoorStateModels(door, "", (facing, half, hinge, open, map) -> variants.register(facing, half, hinge, open, false, map));
|
||||||
|
buildDoorStateModels(door, "_locked", (facing, half, hinge, open, map) -> variants.register(facing, half, hinge, open, true, map));
|
||||||
|
blockStateCollector.accept(VariantsBlockStateSupplier.create(door).coordinate(variants));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void buildDoorStateModels(Block door, String suffex, DoorStateConsumer variants) {
|
||||||
|
TextureMap topTextures = new TextureMap()
|
||||||
|
.put(TextureKey.TOP, TextureMap.getSubId(door, "_top" + suffex))
|
||||||
|
.put(TextureKey.BOTTOM, TextureMap.getSubId(door, "_bottom" + suffex));
|
||||||
|
TextureMap bottomTextures = topTextures.copyAndAdd(TOP, topTextures.getTexture(BOTTOM));
|
||||||
|
fillStableDoorVariantMap(variants, DoubleBlockHalf.LOWER,
|
||||||
|
BlockModels.DOOR_LEFT.upload(door, "_bottom_left" + suffex, bottomTextures, modelCollector),
|
||||||
|
BlockModels.DOOR_RIGHT.upload(door, "_bottom_right" + suffex, bottomTextures, modelCollector)
|
||||||
|
);
|
||||||
|
fillStableDoorVariantMap(variants, DoubleBlockHalf.UPPER,
|
||||||
|
BlockModels.DOOR_LEFT.upload(door, "_top_left" + suffex, topTextures, modelCollector),
|
||||||
|
BlockModels.DOOR_RIGHT.upload(door, "_top_right" + suffex, topTextures, modelCollector)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void fillStableDoorVariantMap(
|
||||||
|
DoorStateConsumer variantMap,
|
||||||
DoubleBlockHalf targetHalf, Identifier leftModelId, Identifier rightModelId) {
|
DoubleBlockHalf targetHalf, Identifier leftModelId, Identifier rightModelId) {
|
||||||
fillStableDoorVariantMap(variantMap, targetHalf, DoorHinge.LEFT, false, R0, leftModelId);
|
fillStableDoorVariantMap(variantMap, targetHalf, DoorHinge.LEFT, false, R0, leftModelId);
|
||||||
fillStableDoorVariantMap(variantMap, targetHalf, DoorHinge.RIGHT, false, R0, rightModelId);
|
fillStableDoorVariantMap(variantMap, targetHalf, DoorHinge.RIGHT, false, R0, rightModelId);
|
||||||
|
@ -373,7 +389,7 @@ public class UBlockStateModelGenerator extends BlockStateModelGenerator {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void fillStableDoorVariantMap(
|
public static void fillStableDoorVariantMap(
|
||||||
BlockStateVariantMap.QuadrupleProperty<Direction, DoubleBlockHalf, DoorHinge, Boolean> variantMap,
|
DoorStateConsumer variantMap,
|
||||||
DoubleBlockHalf targetHalf,
|
DoubleBlockHalf targetHalf,
|
||||||
DoorHinge hinge, boolean open, Rotation rotation,
|
DoorHinge hinge, boolean open, Rotation rotation,
|
||||||
Identifier modelId) {
|
Identifier modelId) {
|
||||||
|
@ -386,6 +402,10 @@ public class UBlockStateModelGenerator extends BlockStateModelGenerator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface DoorStateConsumer {
|
||||||
|
void register(Direction direction, DoubleBlockHalf half, DoorHinge hinge, boolean open, BlockStateVariant variant);
|
||||||
|
}
|
||||||
|
|
||||||
public void registerPillar(Block pillar) {
|
public void registerPillar(Block pillar) {
|
||||||
TextureMap textures = new TextureMap()
|
TextureMap textures = new TextureMap()
|
||||||
.put(SIDE, ModelIds.getBlockSubModelId(pillar, "_side"))
|
.put(SIDE, ModelIds.getBlockSubModelId(pillar, "_side"))
|
||||||
|
|
|
@ -124,6 +124,10 @@ public class FriendshipBraceletItem extends WearableItem implements DyeableItem,
|
||||||
.isPresent();
|
.isPresent();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean isComrade(UUID signator, Entity entity) {
|
||||||
|
return entity instanceof LivingEntity l && getWornBangles(l).anyMatch(stack -> isSignedBy(stack, signator));
|
||||||
|
}
|
||||||
|
|
||||||
public static Stream<Pony> getPartyMembers(Caster<?> caster, double radius) {
|
public static Stream<Pony> getPartyMembers(Caster<?> caster, double radius) {
|
||||||
return Pony.stream(caster.findAllEntitiesInRange(radius, entity -> isComrade(caster, entity)));
|
return Pony.stream(caster.findAllEntitiesInRange(radius, entity -> isComrade(caster, entity)));
|
||||||
}
|
}
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 6.8 KiB |
Binary file not shown.
After Width: | Height: | Size: 11 KiB |
|
@ -0,0 +1,11 @@
|
||||||
|
{
|
||||||
|
"animation": {
|
||||||
|
"frametime": 200,
|
||||||
|
"frames": [
|
||||||
|
0, 1, 2, 3,
|
||||||
|
1, 2, 3, 0,
|
||||||
|
2, 3, 0, 1,
|
||||||
|
3, 0, 1, 2
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue