Clean repo for open source release
Remove build artifacts, dev tool configs, unused dependencies, and third-party source dumps. Add proper README, update .gitignore, clean up Makefile.
This commit is contained in:
398
src/main/java/com/tiedup/remake/items/ItemShockerController.java
Normal file
398
src/main/java/com/tiedup/remake/items/ItemShockerController.java
Normal file
@@ -0,0 +1,398 @@
|
||||
package com.tiedup.remake.items;
|
||||
|
||||
import com.tiedup.remake.core.ModSounds;
|
||||
import com.tiedup.remake.v2.BodyRegionV2;
|
||||
import com.tiedup.remake.core.SystemMessageManager;
|
||||
import com.tiedup.remake.core.TiedUpMod;
|
||||
import com.tiedup.remake.items.base.ItemCollar;
|
||||
import com.tiedup.remake.items.base.ItemOwnerTarget;
|
||||
import com.tiedup.remake.state.IRestrainable;
|
||||
import com.tiedup.remake.util.KidnappedHelper;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import net.minecraft.ChatFormatting;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.chat.MutableComponent;
|
||||
import net.minecraft.world.InteractionHand;
|
||||
import net.minecraft.world.InteractionResult;
|
||||
import net.minecraft.world.InteractionResultHolder;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.TooltipFlag;
|
||||
import net.minecraft.world.level.Level;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class ItemShockerController extends ItemOwnerTarget {
|
||||
|
||||
private static final String NBT_BROADCAST = "broadcast";
|
||||
private static final String NBT_RADIUS = "radius";
|
||||
|
||||
public ItemShockerController() {
|
||||
super(new net.minecraft.world.item.Item.Properties().stacksTo(1));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendHoverText(
|
||||
ItemStack stack,
|
||||
@Nullable Level level,
|
||||
List<Component> tooltip,
|
||||
TooltipFlag flag
|
||||
) {
|
||||
super.appendHoverText(stack, level, tooltip, flag);
|
||||
|
||||
appendOwnerTooltip(stack, tooltip, "Right-click a player");
|
||||
|
||||
if (isBroadcastEnabled(stack)) {
|
||||
tooltip.add(
|
||||
Component.literal("MODE: BROADCAST").withStyle(
|
||||
ChatFormatting.DARK_RED
|
||||
)
|
||||
);
|
||||
tooltip.add(
|
||||
Component.literal("(Affects ALL your slaves in radius)")
|
||||
.withStyle(ChatFormatting.GRAY)
|
||||
.withStyle(ChatFormatting.ITALIC)
|
||||
);
|
||||
} else {
|
||||
tooltip.add(
|
||||
Component.literal("MODE: TARGETED").withStyle(
|
||||
ChatFormatting.BLUE
|
||||
)
|
||||
);
|
||||
if (hasTarget(stack)) {
|
||||
String displayName = getTargetName(stack);
|
||||
boolean isDisconnected = true;
|
||||
|
||||
if (level != null) {
|
||||
Player target = level.getPlayerByUUID(getTargetId(stack));
|
||||
if (target != null) {
|
||||
IRestrainable targetState =
|
||||
KidnappedHelper.getKidnappedState(target);
|
||||
if (targetState != null && targetState.hasCollar()) {
|
||||
isDisconnected = false;
|
||||
ItemStack collar = targetState.getEquipment(BodyRegionV2.NECK);
|
||||
if (
|
||||
collar.getItem() instanceof
|
||||
ItemCollar collarItem &&
|
||||
collarItem.hasNickname(collar)
|
||||
) {
|
||||
displayName =
|
||||
collarItem.getNickname(collar) +
|
||||
" (" +
|
||||
displayName +
|
||||
")";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MutableComponent targetComp = Component.literal(" > ")
|
||||
.withStyle(ChatFormatting.BLUE)
|
||||
.append(
|
||||
Component.literal(displayName).withStyle(
|
||||
isDisconnected
|
||||
? ChatFormatting.STRIKETHROUGH
|
||||
: ChatFormatting.WHITE
|
||||
)
|
||||
);
|
||||
|
||||
if (isDisconnected) {
|
||||
targetComp.append(
|
||||
Component.literal(" [FREED]")
|
||||
.withStyle(ChatFormatting.RED)
|
||||
.withStyle(ChatFormatting.BOLD)
|
||||
);
|
||||
}
|
||||
tooltip.add(targetComp);
|
||||
} else {
|
||||
tooltip.add(
|
||||
Component.literal(" > No target connected").withStyle(
|
||||
ChatFormatting.GRAY
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
tooltip.add(
|
||||
Component.literal("Radius: " + getRadius(stack) + "m").withStyle(
|
||||
ChatFormatting.GREEN
|
||||
)
|
||||
);
|
||||
tooltip.add(
|
||||
Component.literal("Shift + Right-click to toggle Broadcast mode")
|
||||
.withStyle(ChatFormatting.DARK_GRAY)
|
||||
.withStyle(ChatFormatting.ITALIC)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InteractionResultHolder<ItemStack> use(
|
||||
Level level,
|
||||
Player player,
|
||||
InteractionHand hand
|
||||
) {
|
||||
ItemStack stack = player.getItemInHand(hand);
|
||||
|
||||
if (player.isShiftKeyDown()) {
|
||||
if (!level.isClientSide) {
|
||||
if (hasOwner(stack) && !isOwner(stack, player)) {
|
||||
SystemMessageManager.sendToPlayer(
|
||||
player,
|
||||
SystemMessageManager.MessageCategory.SHOCKER_NOT_OWNER
|
||||
);
|
||||
return InteractionResultHolder.fail(stack);
|
||||
}
|
||||
|
||||
boolean newState = !isBroadcastEnabled(stack);
|
||||
setBroadcastEnabled(stack, newState);
|
||||
player.setItemInHand(hand, stack);
|
||||
SystemMessageManager.sendToPlayer(
|
||||
player,
|
||||
SystemMessageManager.MessageCategory.SHOCKER_MODE_SET,
|
||||
(newState ? "BROADCAST" : "TARGETED")
|
||||
);
|
||||
}
|
||||
return InteractionResultHolder.sidedSuccess(
|
||||
stack,
|
||||
level.isClientSide()
|
||||
);
|
||||
}
|
||||
|
||||
if (level.isClientSide) return InteractionResultHolder.success(stack);
|
||||
|
||||
IRestrainable playerState = KidnappedHelper.getKidnappedState(player);
|
||||
if (
|
||||
playerState != null && playerState.isTiedUp()
|
||||
) return InteractionResultHolder.fail(stack);
|
||||
|
||||
if (!hasOwner(stack)) {
|
||||
SystemMessageManager.sendToPlayer(
|
||||
player,
|
||||
SystemMessageManager.MessageCategory.ERROR,
|
||||
"You must claim this shocker first! (Right-click a player)"
|
||||
);
|
||||
return InteractionResultHolder.fail(stack);
|
||||
}
|
||||
|
||||
if (!isOwner(stack, player)) {
|
||||
SystemMessageManager.sendToPlayer(
|
||||
player,
|
||||
SystemMessageManager.MessageCategory.SHOCKER_NOT_OWNER
|
||||
);
|
||||
return InteractionResultHolder.fail(stack);
|
||||
}
|
||||
|
||||
List<LivingEntity> nearbyTargets = getNearbyKidnappedTargets(
|
||||
level,
|
||||
player,
|
||||
stack
|
||||
);
|
||||
|
||||
if (isBroadcastEnabled(stack)) {
|
||||
for (LivingEntity target : nearbyTargets) {
|
||||
IRestrainable targetState = KidnappedHelper.getKidnappedState(
|
||||
target
|
||||
);
|
||||
if (targetState != null) targetState.shockKidnapped();
|
||||
}
|
||||
|
||||
if (nearbyTargets.isEmpty()) {
|
||||
SystemMessageManager.sendToPlayer(
|
||||
player,
|
||||
SystemMessageManager.MessageCategory.ERROR,
|
||||
"No valid targets in range!"
|
||||
);
|
||||
} else {
|
||||
SystemMessageManager.sendToPlayer(
|
||||
player,
|
||||
SystemMessageManager.MessageCategory.INFO,
|
||||
"Broadcast shock triggered! (" +
|
||||
nearbyTargets.size() +
|
||||
" targets)"
|
||||
);
|
||||
playTriggerSound(player);
|
||||
}
|
||||
} else if (hasTarget(stack)) {
|
||||
Player target = level.getPlayerByUUID(getTargetId(stack));
|
||||
IRestrainable targetState =
|
||||
target != null
|
||||
? KidnappedHelper.getKidnappedState(target)
|
||||
: null;
|
||||
|
||||
if (
|
||||
target != null &&
|
||||
targetState != null &&
|
||||
targetState.hasCollar() &&
|
||||
nearbyTargets.contains(target)
|
||||
) {
|
||||
targetState.shockKidnapped();
|
||||
String name = target.getName().getString();
|
||||
SystemMessageManager.sendToPlayer(
|
||||
player,
|
||||
SystemMessageManager.MessageCategory.SHOCKER_TRIGGERED,
|
||||
name
|
||||
);
|
||||
playTriggerSound(player);
|
||||
} else {
|
||||
String error = (target == null)
|
||||
? "Target is out of range or in another dimension!"
|
||||
: (!targetState.hasCollar()
|
||||
? "Target is no longer wearing a collar!"
|
||||
: "Target is out of range!");
|
||||
SystemMessageManager.sendToPlayer(
|
||||
player,
|
||||
SystemMessageManager.MessageCategory.ERROR,
|
||||
error
|
||||
);
|
||||
}
|
||||
} else {
|
||||
SystemMessageManager.sendToPlayer(
|
||||
player,
|
||||
SystemMessageManager.MessageCategory.ERROR,
|
||||
"No target set and broadcast is disabled!"
|
||||
);
|
||||
}
|
||||
|
||||
return InteractionResultHolder.success(stack);
|
||||
}
|
||||
|
||||
/**
|
||||
* Phase 14.1.5: Refactored to support IRestrainable (LivingEntity + NPCs)
|
||||
*/
|
||||
@Override
|
||||
public InteractionResult interactLivingEntity(
|
||||
ItemStack stack,
|
||||
Player player,
|
||||
LivingEntity target,
|
||||
InteractionHand hand
|
||||
) {
|
||||
if (player.level().isClientSide) return InteractionResult.SUCCESS;
|
||||
|
||||
IRestrainable playerState = KidnappedHelper.getKidnappedState(player);
|
||||
if (
|
||||
playerState != null && playerState.isTiedUp()
|
||||
) return InteractionResult.FAIL;
|
||||
|
||||
// Claim shocker if unclaimed
|
||||
if (!hasOwner(stack)) {
|
||||
setOwner(stack, player);
|
||||
SystemMessageManager.sendToPlayer(
|
||||
player,
|
||||
SystemMessageManager.MessageCategory.SHOCKER_CLAIMED
|
||||
);
|
||||
} else if (!isOwner(stack, player)) {
|
||||
SystemMessageManager.sendToPlayer(
|
||||
player,
|
||||
SystemMessageManager.MessageCategory.SHOCKER_NOT_OWNER
|
||||
);
|
||||
return InteractionResult.FAIL;
|
||||
}
|
||||
|
||||
// Connect to target (works with any LivingEntity that can be kidnapped)
|
||||
IRestrainable targetState = KidnappedHelper.getKidnappedState(target);
|
||||
if (targetState != null) {
|
||||
setTarget(stack, target);
|
||||
player.setItemInHand(hand, stack);
|
||||
SystemMessageManager.sendChatToPlayer(
|
||||
player,
|
||||
"Connected to " + target.getName().getString(),
|
||||
ChatFormatting.GREEN
|
||||
);
|
||||
return InteractionResult.SUCCESS;
|
||||
}
|
||||
|
||||
return InteractionResult.PASS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Phase 14.1.5: New method to support LivingEntity (Players + NPCs)
|
||||
* Returns all kidnappable entities in range wearing shock collars owned by the shocker owner or in public mode.
|
||||
*/
|
||||
private List<LivingEntity> getNearbyKidnappedTargets(
|
||||
Level level,
|
||||
Player source,
|
||||
ItemStack stack
|
||||
) {
|
||||
double radius = getRadius(stack);
|
||||
UUID ownerId = getOwnerId(stack);
|
||||
List<LivingEntity> targets = new ArrayList<>();
|
||||
|
||||
// Check all living entities in range
|
||||
for (LivingEntity entity : level.getEntitiesOfClass(
|
||||
LivingEntity.class,
|
||||
source.getBoundingBox().inflate(radius)
|
||||
)) {
|
||||
if (entity == source) continue;
|
||||
|
||||
IRestrainable state = KidnappedHelper.getKidnappedState(entity);
|
||||
if (state != null && state.hasCollar()) {
|
||||
ItemStack collarStack = state.getEquipment(BodyRegionV2.NECK);
|
||||
if (
|
||||
collarStack.getItem() instanceof ItemShockCollar collarItem
|
||||
) {
|
||||
if (
|
||||
collarItem.getOwners(collarStack).contains(ownerId) ||
|
||||
collarItem.isPublic(collarStack)
|
||||
) {
|
||||
targets.add(entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return targets;
|
||||
}
|
||||
|
||||
private void playTriggerSound(Player player) {
|
||||
player
|
||||
.level()
|
||||
.playSound(
|
||||
null,
|
||||
player.blockPosition(),
|
||||
ModSounds.SHOCKER_ACTIVATED.get(),
|
||||
net.minecraft.sounds.SoundSource.PLAYERS,
|
||||
0.5f,
|
||||
1.0f
|
||||
);
|
||||
}
|
||||
|
||||
public boolean isBroadcastEnabled(ItemStack stack) {
|
||||
CompoundTag tag = stack.getTag();
|
||||
return tag != null && tag.getBoolean(NBT_BROADCAST);
|
||||
}
|
||||
|
||||
public void setBroadcastEnabled(ItemStack stack, boolean enabled) {
|
||||
stack.getOrCreateTag().putBoolean(NBT_BROADCAST, enabled);
|
||||
}
|
||||
|
||||
public int getRadius(ItemStack stack) {
|
||||
CompoundTag tag = stack.getTag();
|
||||
return (tag != null && tag.contains(NBT_RADIUS))
|
||||
? tag.getInt(NBT_RADIUS)
|
||||
: com.tiedup.remake.core.SettingsAccessor.getShockerControllerRadius(null);
|
||||
}
|
||||
|
||||
public void setRadius(ItemStack stack, int radius) {
|
||||
stack.getOrCreateTag().putInt(NBT_RADIUS, radius);
|
||||
}
|
||||
|
||||
public static ItemStack mergeShockers(List<ItemStack> stacks) {
|
||||
if (stacks == null || stacks.size() <= 1) return ItemStack.EMPTY;
|
||||
|
||||
int totalRadius = 0;
|
||||
for (ItemStack s : stacks) {
|
||||
if (s.getItem() instanceof ItemShockerController sc) {
|
||||
totalRadius += sc.getRadius(s);
|
||||
}
|
||||
}
|
||||
|
||||
ItemStack result = new ItemStack(stacks.get(0).getItem());
|
||||
((ItemShockerController) result.getItem()).setRadius(
|
||||
result,
|
||||
totalRadius
|
||||
);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user