feat(D-01/A): V2-aware struggle system (A9)
StruggleBinds: - canStruggle(): instanceof ItemBind → BindModeHelper.isBindItem() - isItemLocked(): instanceof ItemBind → instanceof ILockable (fixes R4) - onAttempt(): instanceof ItemShockCollar → CollarHelper.canShock() (fixes R5) - tighten(): reads ResistanceComponent directly for V2, avoids MAX scan bug StruggleCollar: - getResistanceState/setResistanceState: instanceof ItemCollar → IHasResistance - canStruggle(): instanceof ItemCollar → CollarHelper.isCollar() + ILockable - onAttempt(): shock check via CollarHelper.canShock() - successAction(): unlock via ILockable - tighten(): resistance via IHasResistance All V1 items continue working through the same interfaces they already implement.
This commit is contained in:
@@ -4,12 +4,18 @@ import com.tiedup.remake.core.SettingsAccessor;
|
|||||||
import com.tiedup.remake.core.SystemMessageManager;
|
import com.tiedup.remake.core.SystemMessageManager;
|
||||||
import com.tiedup.remake.core.SystemMessageManager.MessageCategory;
|
import com.tiedup.remake.core.SystemMessageManager.MessageCategory;
|
||||||
import com.tiedup.remake.core.TiedUpMod;
|
import com.tiedup.remake.core.TiedUpMod;
|
||||||
|
import com.tiedup.remake.items.base.IHasResistance;
|
||||||
import com.tiedup.remake.items.base.ILockable;
|
import com.tiedup.remake.items.base.ILockable;
|
||||||
import com.tiedup.remake.items.base.ItemBind;
|
import com.tiedup.remake.items.base.ItemBind;
|
||||||
import com.tiedup.remake.state.IPlayerLeashAccess;
|
import com.tiedup.remake.state.IPlayerLeashAccess;
|
||||||
import com.tiedup.remake.state.PlayerBindState;
|
import com.tiedup.remake.state.PlayerBindState;
|
||||||
import com.tiedup.remake.v2.BodyRegionV2;
|
import com.tiedup.remake.v2.BodyRegionV2;
|
||||||
|
import com.tiedup.remake.v2.bondage.BindModeHelper;
|
||||||
|
import com.tiedup.remake.v2.bondage.CollarHelper;
|
||||||
import com.tiedup.remake.v2.bondage.capability.V2EquipmentHelper;
|
import com.tiedup.remake.v2.bondage.capability.V2EquipmentHelper;
|
||||||
|
import com.tiedup.remake.v2.bondage.component.ComponentType;
|
||||||
|
import com.tiedup.remake.v2.bondage.component.ResistanceComponent;
|
||||||
|
import com.tiedup.remake.v2.bondage.datadriven.DataDrivenBondageItem;
|
||||||
import net.minecraft.world.entity.item.ItemEntity;
|
import net.minecraft.world.entity.item.ItemEntity;
|
||||||
import net.minecraft.world.entity.player.Player;
|
import net.minecraft.world.entity.player.Player;
|
||||||
import net.minecraft.world.item.ItemStack;
|
import net.minecraft.world.item.ItemStack;
|
||||||
@@ -75,16 +81,17 @@ public class StruggleBinds extends StruggleState {
|
|||||||
player,
|
player,
|
||||||
BodyRegionV2.ARMS
|
BodyRegionV2.ARMS
|
||||||
);
|
);
|
||||||
if (
|
if (bindStack.isEmpty() || !BindModeHelper.isBindItem(bindStack)) {
|
||||||
bindStack.isEmpty() ||
|
|
||||||
!(bindStack.getItem() instanceof ItemBind bind)
|
|
||||||
) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The locked check has been moved to struggle() where decrease is reduced
|
// The locked check has been moved to struggle() where decrease is reduced
|
||||||
|
|
||||||
return bind.canBeStruggledOut(bindStack);
|
// Check canBeStruggledOut — works for both V1 and V2 via IHasResistance
|
||||||
|
if (bindStack.getItem() instanceof IHasResistance resistance) {
|
||||||
|
return resistance.canBeStruggledOut(bindStack);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -103,14 +110,13 @@ public class StruggleBinds extends StruggleState {
|
|||||||
player,
|
player,
|
||||||
BodyRegionV2.ARMS
|
BodyRegionV2.ARMS
|
||||||
);
|
);
|
||||||
if (
|
if (bindStack.isEmpty()) return false;
|
||||||
bindStack.isEmpty() ||
|
|
||||||
!(bindStack.getItem() instanceof ItemBind bind)
|
|
||||||
) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return bind.isLocked(bindStack);
|
// Works for both V1 (ItemBind) and V2 (DataDrivenBondageItem) via ILockable
|
||||||
|
if (bindStack.getItem() instanceof ILockable lockable) {
|
||||||
|
return lockable.isLocked(bindStack);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -148,14 +154,18 @@ public class StruggleBinds extends StruggleState {
|
|||||||
BodyRegionV2.NECK
|
BodyRegionV2.NECK
|
||||||
);
|
);
|
||||||
|
|
||||||
if (
|
if (!collar.isEmpty() && CollarHelper.canShock(collar)) {
|
||||||
!collar.isEmpty() &&
|
// V1 shock collar
|
||||||
collar.getItem() instanceof
|
if (collar.getItem() instanceof com.tiedup.remake.items.ItemShockCollar shockCollar) {
|
||||||
com.tiedup.remake.items.ItemShockCollar shockCollar
|
|
||||||
) {
|
|
||||||
return shockCollar.notifyStruggle(player, collar);
|
return shockCollar.notifyStruggle(player, collar);
|
||||||
}
|
}
|
||||||
return true; // No collar, proceed normally
|
// V2 shock collar — notify via IHasResistance if available
|
||||||
|
if (collar.getItem() instanceof IHasResistance resistance) {
|
||||||
|
resistance.notifyStruggle(player);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return true; // No shock collar, proceed normally
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -317,18 +327,23 @@ public class StruggleBinds extends StruggleState {
|
|||||||
target,
|
target,
|
||||||
BodyRegionV2.ARMS
|
BodyRegionV2.ARMS
|
||||||
);
|
);
|
||||||
if (
|
if (bindStack.isEmpty() || !BindModeHelper.isBindItem(bindStack)) {
|
||||||
bindStack.isEmpty() ||
|
|
||||||
!(bindStack.getItem() instanceof ItemBind bind)
|
|
||||||
) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get base resistance from config (BUG-003 fix: was using ModGameRules which
|
// Get base resistance: V2 reads from ResistanceComponent directly,
|
||||||
// only knew 4 types and returned hardcoded 100 for the other 10)
|
// V1 reads from SettingsAccessor via item name (BUG-003 fix)
|
||||||
int baseResistance = SettingsAccessor.getBindResistance(
|
int baseResistance;
|
||||||
bind.getItemName()
|
ResistanceComponent comp = DataDrivenBondageItem.getComponent(
|
||||||
|
bindStack, ComponentType.RESISTANCE, ResistanceComponent.class
|
||||||
);
|
);
|
||||||
|
if (comp != null) {
|
||||||
|
baseResistance = comp.getBaseResistance();
|
||||||
|
} else if (bindStack.getItem() instanceof ItemBind bind) {
|
||||||
|
baseResistance = SettingsAccessor.getBindResistance(bind.getItemName());
|
||||||
|
} else {
|
||||||
|
baseResistance = 100;
|
||||||
|
}
|
||||||
|
|
||||||
// Set current resistance to base (full restore)
|
// Set current resistance to base (full restore)
|
||||||
setResistanceState(state, baseResistance);
|
setResistanceState(state, baseResistance);
|
||||||
|
|||||||
@@ -2,9 +2,12 @@ package com.tiedup.remake.state.struggle;
|
|||||||
|
|
||||||
import com.tiedup.remake.core.SystemMessageManager.MessageCategory;
|
import com.tiedup.remake.core.SystemMessageManager.MessageCategory;
|
||||||
import com.tiedup.remake.core.TiedUpMod;
|
import com.tiedup.remake.core.TiedUpMod;
|
||||||
|
import com.tiedup.remake.items.base.IHasResistance;
|
||||||
|
import com.tiedup.remake.items.base.ILockable;
|
||||||
import com.tiedup.remake.items.base.ItemCollar;
|
import com.tiedup.remake.items.base.ItemCollar;
|
||||||
import com.tiedup.remake.state.PlayerBindState;
|
import com.tiedup.remake.state.PlayerBindState;
|
||||||
import com.tiedup.remake.v2.BodyRegionV2;
|
import com.tiedup.remake.v2.BodyRegionV2;
|
||||||
|
import com.tiedup.remake.v2.bondage.CollarHelper;
|
||||||
import com.tiedup.remake.v2.bondage.capability.V2EquipmentHelper;
|
import com.tiedup.remake.v2.bondage.capability.V2EquipmentHelper;
|
||||||
import net.minecraft.world.entity.player.Player;
|
import net.minecraft.world.entity.player.Player;
|
||||||
import net.minecraft.world.item.ItemStack;
|
import net.minecraft.world.item.ItemStack;
|
||||||
@@ -44,19 +47,14 @@ public class StruggleCollar extends StruggleState {
|
|||||||
@Override
|
@Override
|
||||||
protected int getResistanceState(PlayerBindState state) {
|
protected int getResistanceState(PlayerBindState state) {
|
||||||
Player player = state.getPlayer();
|
Player player = state.getPlayer();
|
||||||
ItemStack collar = V2EquipmentHelper.getInRegion(
|
ItemStack collar = V2EquipmentHelper.getInRegion(player, BodyRegionV2.NECK);
|
||||||
player,
|
|
||||||
BodyRegionV2.NECK
|
|
||||||
);
|
|
||||||
|
|
||||||
if (
|
if (collar.isEmpty() || !CollarHelper.isCollar(collar)) return 0;
|
||||||
collar.isEmpty() ||
|
|
||||||
!(collar.getItem() instanceof ItemCollar collarItem)
|
if (collar.getItem() instanceof IHasResistance resistance) {
|
||||||
) {
|
return resistance.getCurrentResistance(collar, player);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
return 0;
|
||||||
return collarItem.getCurrentResistance(collar, player);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -68,19 +66,13 @@ public class StruggleCollar extends StruggleState {
|
|||||||
@Override
|
@Override
|
||||||
protected void setResistanceState(PlayerBindState state, int resistance) {
|
protected void setResistanceState(PlayerBindState state, int resistance) {
|
||||||
Player player = state.getPlayer();
|
Player player = state.getPlayer();
|
||||||
ItemStack collar = V2EquipmentHelper.getInRegion(
|
ItemStack collar = V2EquipmentHelper.getInRegion(player, BodyRegionV2.NECK);
|
||||||
player,
|
|
||||||
BodyRegionV2.NECK
|
|
||||||
);
|
|
||||||
|
|
||||||
if (
|
if (collar.isEmpty() || !CollarHelper.isCollar(collar)) return;
|
||||||
collar.isEmpty() ||
|
|
||||||
!(collar.getItem() instanceof ItemCollar collarItem)
|
if (collar.getItem() instanceof IHasResistance resistanceItem) {
|
||||||
) {
|
resistanceItem.setCurrentResistance(collar, resistance);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
collarItem.setCurrentResistance(collar, resistance);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -104,33 +96,31 @@ public class StruggleCollar extends StruggleState {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ItemStack collar = V2EquipmentHelper.getInRegion(
|
ItemStack collar = V2EquipmentHelper.getInRegion(player, BodyRegionV2.NECK);
|
||||||
player,
|
|
||||||
BodyRegionV2.NECK
|
|
||||||
);
|
|
||||||
|
|
||||||
if (
|
if (collar.isEmpty() || !CollarHelper.isCollar(collar)) {
|
||||||
collar.isEmpty() ||
|
|
||||||
!(collar.getItem() instanceof ItemCollar collarItem)
|
|
||||||
) {
|
|
||||||
TiedUpMod.LOGGER.debug("[StruggleCollar] No collar equipped");
|
TiedUpMod.LOGGER.debug("[StruggleCollar] No collar equipped");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if locked
|
// Check if locked (works for V1 and V2 via ILockable)
|
||||||
if (!collarItem.isLocked(collar)) {
|
if (collar.getItem() instanceof ILockable lockable) {
|
||||||
|
if (!lockable.isLocked(collar)) {
|
||||||
TiedUpMod.LOGGER.debug("[StruggleCollar] Collar is not locked");
|
TiedUpMod.LOGGER.debug("[StruggleCollar] Collar is not locked");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
// Check if struggle is enabled
|
|
||||||
if (!collarItem.canBeStruggledOut(collar)) {
|
|
||||||
TiedUpMod.LOGGER.debug(
|
|
||||||
"[StruggleCollar] Collar struggle is disabled"
|
|
||||||
);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if struggle is enabled (works for V1 and V2 via IHasResistance)
|
||||||
|
if (collar.getItem() instanceof IHasResistance resistance) {
|
||||||
|
if (!resistance.canBeStruggledOut(collar)) {
|
||||||
|
TiedUpMod.LOGGER.debug("[StruggleCollar] Collar struggle is disabled");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -141,18 +131,18 @@ public class StruggleCollar extends StruggleState {
|
|||||||
@Override
|
@Override
|
||||||
protected boolean onAttempt(PlayerBindState state) {
|
protected boolean onAttempt(PlayerBindState state) {
|
||||||
Player player = state.getPlayer();
|
Player player = state.getPlayer();
|
||||||
ItemStack collar = V2EquipmentHelper.getInRegion(
|
ItemStack collar = V2EquipmentHelper.getInRegion(player, BodyRegionV2.NECK);
|
||||||
player,
|
|
||||||
BodyRegionV2.NECK
|
|
||||||
);
|
|
||||||
|
|
||||||
if (
|
if (!collar.isEmpty() && CollarHelper.canShock(collar)) {
|
||||||
!collar.isEmpty() &&
|
// V1 shock collar
|
||||||
collar.getItem() instanceof
|
if (collar.getItem() instanceof com.tiedup.remake.items.ItemShockCollar shockCollar) {
|
||||||
com.tiedup.remake.items.ItemShockCollar shockCollar
|
|
||||||
) {
|
|
||||||
return shockCollar.notifyStruggle(player, collar);
|
return shockCollar.notifyStruggle(player, collar);
|
||||||
}
|
}
|
||||||
|
// V2 shock collar — notify via IHasResistance
|
||||||
|
if (collar.getItem() instanceof IHasResistance resistance) {
|
||||||
|
resistance.notifyStruggle(player);
|
||||||
|
}
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -167,31 +157,19 @@ public class StruggleCollar extends StruggleState {
|
|||||||
@Override
|
@Override
|
||||||
protected void successAction(PlayerBindState state) {
|
protected void successAction(PlayerBindState state) {
|
||||||
Player player = state.getPlayer();
|
Player player = state.getPlayer();
|
||||||
ItemStack collar = V2EquipmentHelper.getInRegion(
|
ItemStack collar = V2EquipmentHelper.getInRegion(player, BodyRegionV2.NECK);
|
||||||
player,
|
|
||||||
BodyRegionV2.NECK
|
|
||||||
);
|
|
||||||
|
|
||||||
if (
|
if (collar.isEmpty() || !CollarHelper.isCollar(collar)) {
|
||||||
collar.isEmpty() ||
|
TiedUpMod.LOGGER.warn("[StruggleCollar] successAction called but no collar equipped");
|
||||||
!(collar.getItem() instanceof ItemCollar collarItem)
|
|
||||||
) {
|
|
||||||
TiedUpMod.LOGGER.warn(
|
|
||||||
"[StruggleCollar] successAction called but no collar equipped"
|
|
||||||
);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unlock the collar
|
// Unlock the collar (works for V1 and V2 via ILockable)
|
||||||
collarItem.setLocked(collar, false);
|
if (collar.getItem() instanceof ILockable lockable) {
|
||||||
|
lockable.setLocked(collar, false);
|
||||||
|
}
|
||||||
|
|
||||||
TiedUpMod.LOGGER.info(
|
TiedUpMod.LOGGER.info("[StruggleCollar] {} unlocked their collar!", player.getName().getString());
|
||||||
"[StruggleCollar] {} unlocked their collar!",
|
|
||||||
player.getName().getString()
|
|
||||||
);
|
|
||||||
|
|
||||||
// Note: Collar is NOT removed, just unlocked
|
|
||||||
// Player can now manually remove it
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -230,30 +208,27 @@ public class StruggleCollar extends StruggleState {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ItemStack collar = V2EquipmentHelper.getInRegion(
|
ItemStack collar = V2EquipmentHelper.getInRegion(target, BodyRegionV2.NECK);
|
||||||
target,
|
|
||||||
BodyRegionV2.NECK
|
|
||||||
);
|
|
||||||
|
|
||||||
if (
|
if (collar.isEmpty() || !CollarHelper.isCollar(collar)) {
|
||||||
collar.isEmpty() ||
|
|
||||||
!(collar.getItem() instanceof ItemCollar collarItem)
|
|
||||||
) {
|
|
||||||
TiedUpMod.LOGGER.debug("[StruggleCollar] No collar to tighten");
|
TiedUpMod.LOGGER.debug("[StruggleCollar] No collar to tighten");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if collar is locked
|
// Check if collar is locked (V1 and V2 via ILockable)
|
||||||
if (!collarItem.isLocked(collar)) {
|
if (collar.getItem() instanceof ILockable lockable) {
|
||||||
TiedUpMod.LOGGER.debug(
|
if (!lockable.isLocked(collar)) {
|
||||||
"[StruggleCollar] Collar must be locked to tighten"
|
TiedUpMod.LOGGER.debug("[StruggleCollar] Collar must be locked to tighten");
|
||||||
);
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get base resistance from GameRules
|
// Get resistance (V1 and V2 via IHasResistance)
|
||||||
int baseResistance = collarItem.getBaseResistance(target);
|
if (!(collar.getItem() instanceof IHasResistance resistanceItem)) return;
|
||||||
int currentResistance = collarItem.getCurrentResistance(collar, target);
|
int baseResistance = resistanceItem.getBaseResistance(target);
|
||||||
|
int currentResistance = resistanceItem.getCurrentResistance(collar, target);
|
||||||
|
|
||||||
// Only tighten if current resistance is lower than base
|
// Only tighten if current resistance is lower than base
|
||||||
if (currentResistance >= baseResistance) {
|
if (currentResistance >= baseResistance) {
|
||||||
@@ -264,7 +239,7 @@ public class StruggleCollar extends StruggleState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Restore to base resistance
|
// Restore to base resistance
|
||||||
collarItem.setCurrentResistance(collar, baseResistance);
|
resistanceItem.setCurrentResistance(collar, baseResistance);
|
||||||
|
|
||||||
TiedUpMod.LOGGER.info(
|
TiedUpMod.LOGGER.info(
|
||||||
"[StruggleCollar] {} tightened {}'s collar (resistance {} -> {})",
|
"[StruggleCollar] {} tightened {}'s collar (resistance {} -> {})",
|
||||||
|
|||||||
Reference in New Issue
Block a user