-
Notifications
You must be signed in to change notification settings - Fork 13
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Entity Display Block - Move Item Display's Spawn Egg Entity Display Feature To Its Own Block #58
base: 1.21
Are you sure you want to change the base?
Changes from all commits
997d8dc
4ce8414
b6f6cc9
8e446f8
54bb6b1
7e5f042
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
package dev.hephaestus.glowcase.block; | ||
|
||
import dev.hephaestus.glowcase.Glowcase; | ||
import dev.hephaestus.glowcase.block.entity.EntityDisplayBlockEntity; | ||
import net.minecraft.block.Block; | ||
import net.minecraft.block.BlockEntityProvider; | ||
import net.minecraft.block.BlockState; | ||
import net.minecraft.block.ShapeContext; | ||
import net.minecraft.block.entity.BlockEntity; | ||
import net.minecraft.block.entity.BlockEntityTicker; | ||
import net.minecraft.block.entity.BlockEntityType; | ||
import net.minecraft.entity.player.PlayerEntity; | ||
import net.minecraft.item.Item; | ||
import net.minecraft.item.ItemPlacementContext; | ||
import net.minecraft.item.ItemStack; | ||
import net.minecraft.item.SpawnEggItem; | ||
import net.minecraft.item.tooltip.TooltipType; | ||
import net.minecraft.state.StateManager; | ||
import net.minecraft.state.property.Properties; | ||
import net.minecraft.text.Text; | ||
import net.minecraft.util.ActionResult; | ||
import net.minecraft.util.Formatting; | ||
import net.minecraft.util.Hand; | ||
import net.minecraft.util.ItemActionResult; | ||
import net.minecraft.util.hit.BlockHitResult; | ||
import net.minecraft.util.math.BlockPos; | ||
import net.minecraft.util.math.MathHelper; | ||
import net.minecraft.util.shape.VoxelShape; | ||
import net.minecraft.util.shape.VoxelShapes; | ||
import net.minecraft.world.BlockView; | ||
import net.minecraft.world.World; | ||
import org.jetbrains.annotations.Nullable; | ||
|
||
import java.util.List; | ||
|
||
public class EntityDisplayBlock extends GlowcaseBlock implements BlockEntityProvider { | ||
private static final VoxelShape OUTLINE = VoxelShapes.cuboid(0.25, 0.25, 0.25, 0.75, 0.75, 0.75); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should be a full block shape There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Even though the item display is that size? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. All other glowcase blocks currently are full block shape, it would be best for consistency |
||
|
||
public EntityDisplayBlock() { | ||
super(); | ||
this.setDefaultState(this.getDefaultState().with(Properties.ROTATION, 0)); | ||
} | ||
|
||
@Override | ||
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) { | ||
super.appendProperties(builder); | ||
builder.add(Properties.ROTATION); | ||
} | ||
|
||
@Override | ||
public BlockState getPlacementState(ItemPlacementContext ctx) { | ||
return this.getDefaultState().with(Properties.ROTATION, MathHelper.floor((double) ((ctx.getPlayerYaw()) * 16.0F / 360.0F) + 0.5D) & 15); | ||
} | ||
|
||
@Override | ||
public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) { | ||
return OUTLINE; | ||
} | ||
|
||
@Override | ||
protected ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, BlockHitResult hit) { | ||
if (!(world.getBlockEntity(pos) instanceof EntityDisplayBlockEntity be)) return ActionResult.CONSUME; | ||
|
||
if (be.canGiveTo(player)) { | ||
if (!world.isClient) be.giveTo(player); | ||
return ActionResult.SUCCESS; | ||
} | ||
|
||
return ActionResult.CONSUME; | ||
} | ||
|
||
@Override | ||
protected ItemActionResult onUseWithItem(ItemStack stack, BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) { | ||
if (!(world.getBlockEntity(pos) instanceof EntityDisplayBlockEntity be)) return ItemActionResult.CONSUME; | ||
|
||
if (canEditGlowcase(player, pos)) { | ||
boolean holdingGlowcaseItem = stack.isIn(Glowcase.ITEM_TAG); | ||
boolean holdingSameAsDisplay = ItemStack.areItemsEqual(be.getDisplayedStack(), stack); | ||
boolean isSpawnEgg = stack.getItem() instanceof SpawnEggItem; | ||
|
||
if (!be.hasItem() && isSpawnEgg) { | ||
if (!world.isClient) be.setStack(stack); | ||
return ItemActionResult.SUCCESS; | ||
} else if (holdingSameAsDisplay) { | ||
if (world.isClient) Glowcase.proxy.openEntityDisplayBlockEditScreen(pos); | ||
return ItemActionResult.SUCCESS; | ||
} else if (holdingGlowcaseItem) { | ||
if (!world.isClient) be.setStack(ItemStack.EMPTY); | ||
return ItemActionResult.SUCCESS; | ||
} | ||
} | ||
|
||
return ItemActionResult.PASS_TO_DEFAULT_BLOCK_INTERACTION; | ||
} | ||
|
||
@Nullable | ||
@Override | ||
public BlockEntity createBlockEntity(BlockPos pos, BlockState state) { | ||
return new EntityDisplayBlockEntity(pos, state); | ||
} | ||
|
||
@Nullable | ||
@Override | ||
public <T extends BlockEntity> BlockEntityTicker<T> getTicker(World world, BlockState state, BlockEntityType<T> type) { | ||
return checkType(type, Glowcase.ENTITY_DISPLAY_BLOCK_ENTITY.get(), EntityDisplayBlockEntity::tick); | ||
} | ||
|
||
@Override | ||
public void appendTooltip(ItemStack itemStack, Item.TooltipContext context, List<Text> tooltip, TooltipType options) { | ||
tooltip.add(Text.translatable("block.glowcase.entity_display_block.tooltip.0").formatted(Formatting.GRAY)); | ||
tooltip.add(Text.translatable("block.glowcase.entity_display_block.tooltip.1").formatted(Formatting.DARK_GRAY)); | ||
tooltip.add(Text.translatable("block.glowcase.entity_display_block.tooltip.2").formatted(Formatting.DARK_GRAY)); | ||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
package dev.hephaestus.glowcase.block.entity; | ||
|
||
import dev.hephaestus.glowcase.Glowcase; | ||
import net.minecraft.block.BlockState; | ||
import net.minecraft.entity.Entity; | ||
import net.minecraft.item.ItemStack; | ||
import net.minecraft.item.SpawnEggItem; | ||
import net.minecraft.nbt.NbtCompound; | ||
import net.minecraft.registry.RegistryWrapper; | ||
import net.minecraft.util.math.BlockPos; | ||
import net.minecraft.util.math.MathHelper; | ||
import net.minecraft.util.math.Vec2f; | ||
import net.minecraft.world.World; | ||
|
||
public class EntityDisplayBlockEntity extends ItemDisplayBlockEntity { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why is this extending the item display block? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I was wanting to reduce the amount of copy-pasting from the Item Display as both blocks(item and entity displays) acted mostly the same. I can change to not extend it and copy-paste everything needed from the item display for the entity display if wanted. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These should derive common code from the same abstract class, like an AbstractDisplayBlockEntity |
||
|
||
private Entity displayEntity = null; | ||
|
||
public boolean tickEntity = false; | ||
public float displayScale = 0.5f; | ||
public boolean shouldEditScale = true; | ||
|
||
public EntityDisplayBlockEntity(BlockPos pos, BlockState state) { | ||
super(Glowcase.ENTITY_DISPLAY_BLOCK_ENTITY.get(), pos, state); | ||
} | ||
|
||
@Override | ||
public void writeNbt(NbtCompound tag, RegistryWrapper.WrapperLookup registryLookup) { | ||
super.writeNbt(tag, registryLookup); | ||
|
||
tag.putBoolean("tick_entity", this.tickEntity); | ||
tag.putFloat("display_scale", this.displayScale); | ||
tag.putBoolean("scale_edited", this.shouldEditScale); | ||
} | ||
|
||
@Override | ||
public void readNbt(NbtCompound tag, RegistryWrapper.WrapperLookup registryLookup) { | ||
this.clearDisplayEntity(); | ||
super.readNbt(tag, registryLookup); | ||
|
||
this.tickEntity = tag.getBoolean("tick_entity"); | ||
this.displayScale = tag.getFloat("display_scale"); | ||
this.shouldEditScale = tag.getBoolean("scale_edited"); | ||
} | ||
|
||
@Override | ||
public void setStack(ItemStack stack) { | ||
super.setStack(stack); | ||
this.setShouldEditScale(true); | ||
this.clearDisplayEntity(); | ||
this.markDirty(); | ||
} | ||
|
||
public void setShouldEditScale(boolean shouldEditScale) { | ||
this.shouldEditScale = shouldEditScale; | ||
this.markDirty(); | ||
} | ||
|
||
private void clearDisplayEntity() { | ||
this.displayEntity = null; | ||
} | ||
|
||
public Entity getDisplayEntity() { | ||
if (this.displayEntity == null && this.world != null && this.stack.getItem() instanceof SpawnEggItem eggItem) { | ||
this.displayEntity = eggItem.getEntityType(this.stack).create(this.world); | ||
if(shouldEditScale && this.displayEntity != null) { | ||
//make the default scale of the entity the roughly same size as the block | ||
//shouldEditScale gets set to true after changing the entity | ||
float calcScale = displayEntity.getHeight() >= displayEntity.getWidth() ? 1F / displayEntity.getHeight() : 0.5F; | ||
float roundedScale = (float) Math.round(calcScale / 0.125f) * 0.125f; | ||
if(Math.abs(roundedScale) > 3) { | ||
roundedScale = 0.5f; //just in case | ||
} | ||
this.displayScale = roundedScale; | ||
} | ||
} | ||
|
||
return this.displayEntity; | ||
} | ||
|
||
public static Vec2f getPitchAndYaw(Entity camera, EntityDisplayBlockEntity entityDisplay, float delta) { | ||
BlockPos pos = entityDisplay.getPos(); | ||
float displayScale = entityDisplay.displayScale; | ||
float displayedEntityHeight = entityDisplay.displayEntity == null ? 0 : entityDisplay.displayEntity.getHeight(); | ||
double d = pos.getX() - camera.getLerpedPos(delta).x + 0.5; | ||
double e = pos.getY() + (displayScale * displayedEntityHeight - 0.5) - camera.getEyeY() + 0.5; | ||
double f = pos.getZ() - camera.getLerpedPos(delta).z + 0.5; | ||
double g = MathHelper.sqrt((float) (d * d + f * f)); | ||
|
||
float pitch = (float) ((-MathHelper.atan2(e, g))); | ||
float yaw = (float) (-MathHelper.atan2(f, d) + Math.PI / 2); | ||
|
||
return new Vec2f(pitch, yaw); | ||
} | ||
|
||
public static void tick(World world, BlockPos blockPos, BlockState state, EntityDisplayBlockEntity blockEntity) { | ||
if(blockEntity.getDisplayEntity() != null) { | ||
++blockEntity.displayEntity.age; | ||
// if(blockEntity.tickEntity) { | ||
// blockEntity.displayEntity.tick(); | ||
// } | ||
} | ||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,11 +3,11 @@ | |
import dev.hephaestus.glowcase.Glowcase; | ||
import net.minecraft.block.BlockState; | ||
import net.minecraft.block.entity.BlockEntity; | ||
import net.minecraft.block.entity.BlockEntityType; | ||
import net.minecraft.entity.Entity; | ||
import net.minecraft.entity.player.PlayerEntity; | ||
import net.minecraft.inventory.Inventory; | ||
import net.minecraft.item.ItemStack; | ||
import net.minecraft.item.SpawnEggItem; | ||
import net.minecraft.nbt.NbtCompound; | ||
import net.minecraft.nbt.NbtElement; | ||
import net.minecraft.nbt.NbtList; | ||
|
@@ -23,14 +23,12 @@ | |
import net.minecraft.util.math.Vec2f; | ||
import net.minecraft.world.World; | ||
import org.jetbrains.annotations.Nullable; | ||
|
||
import java.util.HashSet; | ||
import java.util.Set; | ||
import java.util.UUID; | ||
|
||
public class ItemDisplayBlockEntity extends BlockEntity implements Inventory { | ||
private ItemStack stack = ItemStack.EMPTY; | ||
private Entity displayEntity = null; | ||
protected ItemStack stack = ItemStack.EMPTY; | ||
|
||
public RotationType rotationType = RotationType.TRACKING; | ||
public GivesItem givesItem = GivesItem.YES; | ||
|
@@ -40,8 +38,12 @@ public class ItemDisplayBlockEntity extends BlockEntity implements Inventory { | |
public float yaw; | ||
public Set<UUID> givenTo = new HashSet<>(); | ||
|
||
public ItemDisplayBlockEntity(BlockEntityType<?> type, BlockPos pos, BlockState state) { | ||
super(type, pos, state); | ||
} | ||
|
||
public ItemDisplayBlockEntity(BlockPos pos, BlockState state) { | ||
super(Glowcase.ITEM_DISPLAY_BLOCK_ENTITY.get(), pos, state); | ||
this(Glowcase.ITEM_DISPLAY_BLOCK_ENTITY.get(), pos, state); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What is the reason behind this change? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Edit: turns out I actually did use it. The EntityDisplayBlockEntity changes the |
||
} | ||
|
||
@Override | ||
|
@@ -72,7 +74,6 @@ public void readNbt(NbtCompound tag, RegistryWrapper.WrapperLookup registryLooku | |
this.stack = tag.contains("item", NbtElement.COMPOUND_TYPE) | ||
? ItemStack.fromNbt(registryLookup, tag.getCompound("item")).orElse(ItemStack.EMPTY) | ||
: ItemStack.EMPTY; | ||
this.clearDisplayEntity(); | ||
|
||
if (tag.contains("tracking")) { | ||
this.rotationType = tag.getBoolean("tracking") ? RotationType.TRACKING : RotationType.LOCKED; | ||
|
@@ -121,23 +122,10 @@ public void setStack(ItemStack stack) { | |
this.stack = stack.copy(); | ||
|
||
this.givenTo.clear(); | ||
this.clearDisplayEntity(); | ||
this.markDirty(); | ||
this.dispatch(); | ||
} | ||
|
||
private void clearDisplayEntity() { | ||
this.displayEntity = null; | ||
} | ||
|
||
public Entity getDisplayEntity() { | ||
if (this.displayEntity == null && this.world != null && this.stack.getItem() instanceof SpawnEggItem eggItem) { | ||
this.displayEntity = eggItem.getEntityType(this.stack).create(this.world); | ||
} | ||
|
||
return this.displayEntity; | ||
} | ||
|
||
public ItemStack getDisplayedStack() { | ||
return this.stack; | ||
} | ||
|
@@ -221,10 +209,7 @@ public static Vec2f getPitchAndYaw(Entity camera, BlockPos pos, float delta) { | |
} | ||
|
||
public static void tick(World world, BlockPos blockPos, BlockState state, ItemDisplayBlockEntity blockEntity) { | ||
if (blockEntity.getDisplayEntity() != null) { | ||
blockEntity.displayEntity.tick(); | ||
++blockEntity.displayEntity.age; | ||
} | ||
//does nothing right now | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This method should be removed |
||
} | ||
|
||
public enum RotationType { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please configure your IDE to not do automatic star imports