Strip all Phase references, TODO/FUTURE roadmap notes, and internal planning comments from the codebase. Run Prettier for consistent formatting across all Java files.
320 lines
8.4 KiB
Java
320 lines
8.4 KiB
Java
package com.tiedup.remake.blocks.entity;
|
|
|
|
import com.tiedup.remake.items.base.ItemBind;
|
|
import com.tiedup.remake.items.base.ItemBlindfold;
|
|
import com.tiedup.remake.items.base.ItemCollar;
|
|
import com.tiedup.remake.items.base.ItemEarplugs;
|
|
import com.tiedup.remake.items.base.ItemGag;
|
|
import com.tiedup.remake.items.clothes.GenericClothes;
|
|
import javax.annotation.Nullable;
|
|
import net.minecraft.core.BlockPos;
|
|
import net.minecraft.nbt.CompoundTag;
|
|
import net.minecraft.network.protocol.Packet;
|
|
import net.minecraft.network.protocol.game.ClientGamePacketListener;
|
|
import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket;
|
|
import net.minecraft.world.item.ItemStack;
|
|
import net.minecraft.world.level.block.entity.BlockEntity;
|
|
import net.minecraft.world.level.block.entity.BlockEntityType;
|
|
import net.minecraft.world.level.block.state.BlockState;
|
|
|
|
/**
|
|
* Base BlockEntity for blocks that store bondage items.
|
|
*
|
|
*
|
|
* Stores up to 6 bondage items:
|
|
* - Bind (ropes, chains, straitjacket, etc.)
|
|
* - Gag
|
|
* - Blindfold
|
|
* - Earplugs
|
|
* - Collar
|
|
* - Clothes
|
|
*
|
|
* Features:
|
|
* - Full NBT serialization
|
|
* - Network synchronization for client rendering
|
|
* - Item type validation on load
|
|
*
|
|
* Based on original TileEntityBondageItemHandler from 1.12.2
|
|
*/
|
|
public abstract class BondageItemBlockEntity
|
|
extends BlockEntity
|
|
implements IBondageItemHolder
|
|
{
|
|
|
|
// STORED ITEMS
|
|
|
|
private ItemStack bind = ItemStack.EMPTY;
|
|
private ItemStack gag = ItemStack.EMPTY;
|
|
private ItemStack blindfold = ItemStack.EMPTY;
|
|
private ItemStack earplugs = ItemStack.EMPTY;
|
|
private ItemStack collar = ItemStack.EMPTY;
|
|
private ItemStack clothes = ItemStack.EMPTY;
|
|
|
|
/**
|
|
* Off-mode prevents network updates.
|
|
* Used when reading NBT for tooltips without affecting the world.
|
|
*/
|
|
private final boolean offMode;
|
|
|
|
// CONSTRUCTORS
|
|
|
|
public BondageItemBlockEntity(
|
|
BlockEntityType<?> type,
|
|
BlockPos pos,
|
|
BlockState state
|
|
) {
|
|
this(type, pos, state, false);
|
|
}
|
|
|
|
public BondageItemBlockEntity(
|
|
BlockEntityType<?> type,
|
|
BlockPos pos,
|
|
BlockState state,
|
|
boolean offMode
|
|
) {
|
|
super(type, pos, state);
|
|
this.offMode = offMode;
|
|
}
|
|
|
|
// BIND
|
|
|
|
@Override
|
|
public ItemStack getBind() {
|
|
return this.bind;
|
|
}
|
|
|
|
@Override
|
|
public void setBind(ItemStack bind) {
|
|
this.bind = bind != null ? bind : ItemStack.EMPTY;
|
|
this.setChangedAndSync();
|
|
}
|
|
|
|
// GAG
|
|
|
|
@Override
|
|
public ItemStack getGag() {
|
|
return this.gag;
|
|
}
|
|
|
|
@Override
|
|
public void setGag(ItemStack gag) {
|
|
this.gag = gag != null ? gag : ItemStack.EMPTY;
|
|
this.setChangedAndSync();
|
|
}
|
|
|
|
// BLINDFOLD
|
|
|
|
@Override
|
|
public ItemStack getBlindfold() {
|
|
return this.blindfold;
|
|
}
|
|
|
|
@Override
|
|
public void setBlindfold(ItemStack blindfold) {
|
|
this.blindfold = blindfold != null ? blindfold : ItemStack.EMPTY;
|
|
this.setChangedAndSync();
|
|
}
|
|
|
|
// EARPLUGS
|
|
|
|
@Override
|
|
public ItemStack getEarplugs() {
|
|
return this.earplugs;
|
|
}
|
|
|
|
@Override
|
|
public void setEarplugs(ItemStack earplugs) {
|
|
this.earplugs = earplugs != null ? earplugs : ItemStack.EMPTY;
|
|
this.setChangedAndSync();
|
|
}
|
|
|
|
// COLLAR
|
|
|
|
@Override
|
|
public ItemStack getCollar() {
|
|
return this.collar;
|
|
}
|
|
|
|
@Override
|
|
public void setCollar(ItemStack collar) {
|
|
this.collar = collar != null ? collar : ItemStack.EMPTY;
|
|
this.setChangedAndSync();
|
|
}
|
|
|
|
// CLOTHES
|
|
|
|
@Override
|
|
public ItemStack getClothes() {
|
|
return this.clothes;
|
|
}
|
|
|
|
@Override
|
|
public void setClothes(ItemStack clothes) {
|
|
this.clothes = clothes != null ? clothes : ItemStack.EMPTY;
|
|
this.setChangedAndSync();
|
|
}
|
|
|
|
// STATE
|
|
|
|
@Override
|
|
public boolean isArmed() {
|
|
return !this.bind.isEmpty();
|
|
}
|
|
|
|
/**
|
|
* Clear all stored bondage items.
|
|
* Called after applying items to a target.
|
|
*/
|
|
public void clearAllItems() {
|
|
this.bind = ItemStack.EMPTY;
|
|
this.gag = ItemStack.EMPTY;
|
|
this.blindfold = ItemStack.EMPTY;
|
|
this.earplugs = ItemStack.EMPTY;
|
|
this.collar = ItemStack.EMPTY;
|
|
this.clothes = ItemStack.EMPTY;
|
|
this.setChangedAndSync();
|
|
}
|
|
|
|
// NBT SERIALIZATION
|
|
|
|
@Override
|
|
public void load(CompoundTag tag) {
|
|
super.load(tag);
|
|
this.readBondageData(tag);
|
|
}
|
|
|
|
@Override
|
|
protected void saveAdditional(CompoundTag tag) {
|
|
super.saveAdditional(tag);
|
|
this.writeBondageData(tag);
|
|
}
|
|
|
|
@Override
|
|
public void readBondageData(CompoundTag tag) {
|
|
// Read bind with type validation
|
|
if (tag.contains("bind")) {
|
|
ItemStack bindStack = ItemStack.of(tag.getCompound("bind"));
|
|
if (
|
|
!bindStack.isEmpty() && bindStack.getItem() instanceof ItemBind
|
|
) {
|
|
this.bind = bindStack;
|
|
}
|
|
}
|
|
|
|
// Read gag with type validation
|
|
if (tag.contains("gag")) {
|
|
ItemStack gagStack = ItemStack.of(tag.getCompound("gag"));
|
|
if (!gagStack.isEmpty() && gagStack.getItem() instanceof ItemGag) {
|
|
this.gag = gagStack;
|
|
}
|
|
}
|
|
|
|
// Read blindfold with type validation
|
|
if (tag.contains("blindfold")) {
|
|
ItemStack blindfoldStack = ItemStack.of(
|
|
tag.getCompound("blindfold")
|
|
);
|
|
if (
|
|
!blindfoldStack.isEmpty() &&
|
|
blindfoldStack.getItem() instanceof ItemBlindfold
|
|
) {
|
|
this.blindfold = blindfoldStack;
|
|
}
|
|
}
|
|
|
|
// Read earplugs with type validation
|
|
if (tag.contains("earplugs")) {
|
|
ItemStack earplugsStack = ItemStack.of(tag.getCompound("earplugs"));
|
|
if (
|
|
!earplugsStack.isEmpty() &&
|
|
earplugsStack.getItem() instanceof ItemEarplugs
|
|
) {
|
|
this.earplugs = earplugsStack;
|
|
}
|
|
}
|
|
|
|
// Read collar with type validation
|
|
if (tag.contains("collar")) {
|
|
ItemStack collarStack = ItemStack.of(tag.getCompound("collar"));
|
|
if (
|
|
!collarStack.isEmpty() &&
|
|
collarStack.getItem() instanceof ItemCollar
|
|
) {
|
|
this.collar = collarStack;
|
|
}
|
|
}
|
|
|
|
// Read clothes with type validation
|
|
if (tag.contains("clothes")) {
|
|
ItemStack clothesStack = ItemStack.of(tag.getCompound("clothes"));
|
|
if (
|
|
!clothesStack.isEmpty() &&
|
|
clothesStack.getItem() instanceof GenericClothes
|
|
) {
|
|
this.clothes = clothesStack;
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public CompoundTag writeBondageData(CompoundTag tag) {
|
|
if (!this.bind.isEmpty()) {
|
|
tag.put("bind", this.bind.save(new CompoundTag()));
|
|
}
|
|
if (!this.gag.isEmpty()) {
|
|
tag.put("gag", this.gag.save(new CompoundTag()));
|
|
}
|
|
if (!this.blindfold.isEmpty()) {
|
|
tag.put("blindfold", this.blindfold.save(new CompoundTag()));
|
|
}
|
|
if (!this.earplugs.isEmpty()) {
|
|
tag.put("earplugs", this.earplugs.save(new CompoundTag()));
|
|
}
|
|
if (!this.collar.isEmpty()) {
|
|
tag.put("collar", this.collar.save(new CompoundTag()));
|
|
}
|
|
if (!this.clothes.isEmpty()) {
|
|
tag.put("clothes", this.clothes.save(new CompoundTag()));
|
|
}
|
|
return tag;
|
|
}
|
|
|
|
// NETWORK SYNC
|
|
|
|
/**
|
|
* Mark dirty and sync to clients.
|
|
*/
|
|
protected void setChangedAndSync() {
|
|
if (!this.offMode && this.level != null) {
|
|
this.setChanged();
|
|
// Notify clients of block update
|
|
this.level.sendBlockUpdated(
|
|
this.worldPosition,
|
|
this.getBlockState(),
|
|
this.getBlockState(),
|
|
3
|
|
);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public CompoundTag getUpdateTag() {
|
|
CompoundTag tag = super.getUpdateTag();
|
|
this.writeBondageData(tag);
|
|
return tag;
|
|
}
|
|
|
|
@Nullable
|
|
@Override
|
|
public Packet<ClientGamePacketListener> getUpdatePacket() {
|
|
return ClientboundBlockEntityDataPacket.create(this);
|
|
}
|
|
|
|
@Override
|
|
public void handleUpdateTag(CompoundTag tag) {
|
|
if (!this.offMode) {
|
|
this.readBondageData(tag);
|
|
}
|
|
}
|
|
}
|