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:
NotEvil
2026-04-12 00:51:22 +02:00
parent 2e7a1d403b
commit f6466360b6
1947 changed files with 238025 additions and 1 deletions

View File

@@ -0,0 +1,446 @@
package com.tiedup.remake.client;
import com.mojang.blaze3d.platform.InputConstants;
import com.tiedup.remake.v2.bondage.capability.V2EquipmentHelper;
import com.tiedup.remake.client.gui.screens.AdjustmentScreen;
import com.tiedup.remake.client.gui.screens.UnifiedBondageScreen;
import com.tiedup.remake.items.base.ItemCollar;
import org.jetbrains.annotations.Nullable;
import com.tiedup.remake.core.ModConfig;
import com.tiedup.remake.core.TiedUpMod;
import com.tiedup.remake.items.base.ILockable;
import com.tiedup.remake.network.ModNetwork;
import com.tiedup.remake.network.action.PacketForceSeatModifier;
import com.tiedup.remake.network.action.PacketStruggle;
import com.tiedup.remake.network.action.PacketTighten;
import com.tiedup.remake.network.bounty.PacketRequestBounties;
import com.tiedup.remake.v2.BodyRegionV2;
import com.tiedup.remake.v2.bondage.network.PacketV2StruggleStart;
import com.tiedup.remake.state.PlayerBindState;
import net.minecraft.ChatFormatting;
import net.minecraft.client.KeyMapping;
import net.minecraft.client.Minecraft;
import net.minecraft.network.chat.Component;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.client.event.RegisterKeyMappingsEvent;
import net.minecraftforge.event.TickEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
/**
* Phase 7: Client-side keybindings for TiedUp mod.
*
* Manages key mappings and sends packets to server when keys are pressed.
*
* Based on original KeyBindings from 1.12.2
*/
@Mod.EventBusSubscriber(
modid = TiedUpMod.MOD_ID,
bus = Mod.EventBusSubscriber.Bus.FORGE,
value = Dist.CLIENT
)
public class ModKeybindings {
/**
* Key category for TiedUp keybindings
*/
private static final String CATEGORY = "key.categories.tiedup";
/**
* Struggle keybinding - Press to struggle against binds
* Default: R key
*/
public static final KeyMapping STRUGGLE_KEY = new KeyMapping(
"key.tiedup.struggle", // Translation key
InputConstants.Type.KEYSYM,
InputConstants.KEY_R, // Default key: R
CATEGORY
);
/**
* Adjustment screen keybinding - Open item adjustment screen
* Default: K key
*/
public static final KeyMapping ADJUSTMENT_KEY = new KeyMapping(
"key.tiedup.adjustment_screen",
InputConstants.Type.KEYSYM,
InputConstants.KEY_K, // Default key: K
CATEGORY
);
/**
* Bondage inventory keybinding - Open bondage inventory screen
* Default: J key
*/
public static final KeyMapping INVENTORY_KEY = new KeyMapping(
"key.tiedup.bondage_inventory",
InputConstants.Type.KEYSYM,
InputConstants.KEY_J, // Default key: J
CATEGORY
);
/**
* Slave management keybinding - Open slave management dashboard
* Default: L key
*/
public static final KeyMapping SLAVE_MANAGEMENT_KEY = new KeyMapping(
"key.tiedup.slave_management",
InputConstants.Type.KEYSYM,
InputConstants.KEY_L, // Default key: L
CATEGORY
);
/**
* Bounty list keybinding - Open bounty list screen
* Default: B key
*/
public static final KeyMapping BOUNTY_KEY = new KeyMapping(
"key.tiedup.bounties",
InputConstants.Type.KEYSYM,
InputConstants.KEY_B, // Default key: B
CATEGORY
);
/**
* Force seat keybinding - Hold to force captive on/off vehicles
* Default: Left ALT key
*/
public static final KeyMapping FORCE_SEAT_KEY = new KeyMapping(
"key.tiedup.force_seat",
InputConstants.Type.KEYSYM,
InputConstants.KEY_LALT, // Default key: Left ALT
CATEGORY
);
/**
* Tighten bind keybinding - Tighten binds on looked-at target
* Default: T key
*/
public static final KeyMapping TIGHTEN_KEY = new KeyMapping(
"key.tiedup.tighten",
InputConstants.Type.KEYSYM,
InputConstants.KEY_T, // Default key: T
CATEGORY
);
/** Track last sent state to avoid spamming packets */
private static boolean lastForceSeatState = false;
/**
* Check if Force Seat key is currently pressed.
*/
public static boolean isForceSeatPressed() {
return FORCE_SEAT_KEY.isDown();
}
/**
* Register keybindings.
* Called during mod initialization (MOD bus).
*
* @param event The registration event
*/
public static void register(RegisterKeyMappingsEvent event) {
event.register(STRUGGLE_KEY);
event.register(ADJUSTMENT_KEY);
event.register(INVENTORY_KEY);
event.register(SLAVE_MANAGEMENT_KEY);
event.register(BOUNTY_KEY);
event.register(FORCE_SEAT_KEY);
event.register(TIGHTEN_KEY);
TiedUpMod.LOGGER.info("Registered {} keybindings", 7);
}
// ==================== STRUGGLE MINI-GAME (uses vanilla movement keys) ====================
/**
* Get the vanilla movement keybind for a given direction index.
* Uses Minecraft's movement keys so AZERTY/QWERTY is already configured.
* @param index 0=FORWARD, 1=LEFT, 2=BACK, 3=RIGHT
* @return The keybind or null if invalid index
*/
public static KeyMapping getStruggleDirectionKey(int index) {
Minecraft mc = Minecraft.getInstance();
if (mc.options == null) return null;
return switch (index) {
case 0 -> mc.options.keyUp; // Forward (W/Z)
case 1 -> mc.options.keyLeft; // Strafe Left (A/Q)
case 2 -> mc.options.keyDown; // Back (S)
case 3 -> mc.options.keyRight; // Strafe Right (D)
default -> null;
};
}
/**
* Check if a keycode matches any vanilla movement keybind.
* @param keyCode The GLFW key code
* @return The direction index (0-3) or -1 if not a movement key
*/
public static int getStruggleDirectionFromKeyCode(int keyCode) {
Minecraft mc = Minecraft.getInstance();
if (mc.options == null) return -1;
if (mc.options.keyUp.matches(keyCode, 0)) return 0;
if (mc.options.keyLeft.matches(keyCode, 0)) return 1;
if (mc.options.keyDown.matches(keyCode, 0)) return 2;
if (mc.options.keyRight.matches(keyCode, 0)) return 3;
return -1;
}
/**
* Get the display name of a vanilla movement key.
* Shows the actual bound key (W for QWERTY, Z for AZERTY, etc.)
* @param index 0=FORWARD, 1=LEFT, 2=BACK, 3=RIGHT
* @return The key's display name
*/
public static String getStruggleDirectionKeyName(int index) {
KeyMapping key = getStruggleDirectionKey(index);
if (key == null) return "?";
return key.getTranslatedKeyMessage().getString().toUpperCase();
}
/**
* Handle key presses on client tick.
* Called every client tick (FORGE bus).
*
* @param event The tick event
*/
@SubscribeEvent
public static void onClientTick(TickEvent.ClientTickEvent event) {
// Only run at end of tick
if (event.phase != TickEvent.Phase.END) {
return;
}
Minecraft mc = Minecraft.getInstance();
if (mc.player == null || mc.level == null) {
return;
}
// Sync Force Seat keybind state to server (only send on change)
boolean currentForceSeatState = isForceSeatPressed();
if (currentForceSeatState != lastForceSeatState) {
lastForceSeatState = currentForceSeatState;
ModNetwork.sendToServer(
new PacketForceSeatModifier(currentForceSeatState)
);
}
// Check struggle key - Phase 21: Flow based on bind/accessories
while (STRUGGLE_KEY.consumeClick()) {
handleStruggleKey();
}
// Check adjustment screen key
while (ADJUSTMENT_KEY.consumeClick()) {
// Only open if not already in a screen and player has adjustable items
if (mc.screen == null && AdjustmentScreen.canOpen()) {
mc.setScreen(new AdjustmentScreen());
TiedUpMod.LOGGER.debug(
"[CLIENT] Adjustment key pressed - opening screen"
);
}
}
// Check bondage inventory key - opens UnifiedBondageScreen in SELF or MASTER mode
while (INVENTORY_KEY.consumeClick()) {
if (mc.screen == null) {
LivingEntity masterTarget = findOwnedCollarTarget(mc.player);
if (masterTarget != null) {
mc.setScreen(new UnifiedBondageScreen(masterTarget));
} else {
mc.setScreen(new UnifiedBondageScreen());
}
}
}
// SLAVE_MANAGEMENT_KEY: now handled by [J] with master mode detection (see above)
while (SLAVE_MANAGEMENT_KEY.consumeClick()) {
// consumed but no-op — kept registered to avoid key conflict during transition
}
// Check bounty list key
while (BOUNTY_KEY.consumeClick()) {
// Request bounty list from server (server will open the screen)
if (mc.screen == null) {
ModNetwork.sendToServer(new PacketRequestBounties());
TiedUpMod.LOGGER.debug(
"[CLIENT] Bounty key pressed - requesting bounty list"
);
}
}
// Check tighten key
while (TIGHTEN_KEY.consumeClick()) {
// Send tighten packet to server (server finds target)
if (mc.screen == null) {
ModNetwork.sendToServer(new PacketTighten());
TiedUpMod.LOGGER.debug(
"[CLIENT] Tighten key pressed - sending tighten request"
);
}
}
}
/**
* Phase 21: Handle struggle key press with new flow.
*
* Flow:
* 1. If bind equipped: Send PacketStruggle to server (struggle against bind)
* 2. If no bind: Check for locked accessories
* - If locked accessories exist: Open StruggleChoiceScreen
* - If no locked accessories: Show "Nothing to struggle" message
*/
private static void handleStruggleKey() {
Minecraft mc = Minecraft.getInstance();
Player player = mc.player;
if (player == null || mc.screen != null) {
return;
}
// V2 path: check if player has V2 equipment to struggle against
if (com.tiedup.remake.v2.bondage.capability.V2EquipmentHelper.hasAnyEquipment(player)) {
handleV2Struggle(player);
return;
}
PlayerBindState state = PlayerBindState.getInstance(player);
if (state == null) {
return;
}
// Check if player has bind equipped
if (state.isTiedUp()) {
// Has bind - struggle against it
// Phase 2.5: Check if mini-game is enabled
if (ModConfig.SERVER.struggleMiniGameEnabled.get()) {
// New: Start struggle mini-game
ModNetwork.sendToServer(new PacketV2StruggleStart(BodyRegionV2.ARMS));
TiedUpMod.LOGGER.debug(
"[CLIENT] Struggle key pressed - starting V2 struggle mini-game"
);
} else {
// Legacy: Probability-based struggle
ModNetwork.sendToServer(new PacketStruggle());
TiedUpMod.LOGGER.debug(
"[CLIENT] Struggle key pressed - legacy struggle against bind"
);
}
return;
}
// No bind - check for locked accessories
boolean hasLockedAccessories = hasAnyLockedAccessory(player);
if (hasLockedAccessories) {
// Open UnifiedBondageScreen in self mode
mc.setScreen(new UnifiedBondageScreen());
TiedUpMod.LOGGER.debug(
"[CLIENT] Struggle key pressed - opening unified bondage screen"
);
} else {
// No locked accessories - show message
player.displayClientMessage(
Component.translatable("tiedup.struggle.nothing").withStyle(
ChatFormatting.GRAY
),
true
);
TiedUpMod.LOGGER.debug(
"[CLIENT] Struggle key pressed - nothing to struggle"
);
}
}
/**
* Handle struggle key for V2 equipment.
* Auto-targets the highest posePriority item.
*/
private static void handleV2Struggle(Player player) {
java.util.Map<com.tiedup.remake.v2.BodyRegionV2, ItemStack> equipped =
com.tiedup.remake.v2.bondage.capability.V2EquipmentHelper.getAllEquipped(player);
if (equipped.isEmpty()) return;
// Auto-target: find highest posePriority item
com.tiedup.remake.v2.BodyRegionV2 bestRegion = null;
int bestPriority = Integer.MIN_VALUE;
for (java.util.Map.Entry<com.tiedup.remake.v2.BodyRegionV2, ItemStack> entry : equipped.entrySet()) {
ItemStack stack = entry.getValue();
if (stack.getItem() instanceof com.tiedup.remake.v2.bondage.IV2BondageItem item) {
if (item.getPosePriority(stack) > bestPriority) {
bestPriority = item.getPosePriority(stack);
bestRegion = entry.getKey();
}
}
}
if (bestRegion != null) {
ModNetwork.sendToServer(
new com.tiedup.remake.v2.bondage.network.PacketV2StruggleStart(bestRegion)
);
TiedUpMod.LOGGER.debug(
"[CLIENT] V2 Struggle key pressed - targeting region {}",
bestRegion.name()
);
}
}
/**
* Check the crosshair entity: if it is a LivingEntity wearing a collar owned by the player,
* return it as the MASTER mode target. Returns null if no valid target.
*/
@Nullable
private static LivingEntity findOwnedCollarTarget(Player player) {
if (player == null) return null;
Minecraft mc = Minecraft.getInstance();
net.minecraft.world.entity.Entity crosshair = mc.crosshairPickEntity;
if (crosshair instanceof LivingEntity living) {
return checkCollarOwnership(living, player) ? living : null;
}
return null;
}
/**
* Returns true if the given entity has a collar in the NECK region that lists the player as an owner.
*/
private static boolean checkCollarOwnership(LivingEntity target, Player player) {
ItemStack collarStack = com.tiedup.remake.v2.bondage.capability.V2EquipmentHelper.getInRegion(
target, BodyRegionV2.NECK
);
if (!collarStack.isEmpty() && collarStack.getItem() instanceof ItemCollar collar) {
return collar.isOwner(collarStack, player);
}
return false;
}
/**
* Check if player has any locked accessories.
*/
private static boolean hasAnyLockedAccessory(Player player) {
BodyRegionV2[] accessoryRegions = {
BodyRegionV2.MOUTH,
BodyRegionV2.EYES,
BodyRegionV2.EARS,
BodyRegionV2.NECK,
BodyRegionV2.TORSO,
BodyRegionV2.HANDS,
};
for (BodyRegionV2 region : accessoryRegions) {
ItemStack stack = V2EquipmentHelper.getInRegion(player, region);
if (
!stack.isEmpty() &&
stack.getItem() instanceof ILockable lockable
) {
if (lockable.isLocked(stack)) {
return true;
}
}
}
return false;
}
}