- Extract 11 movement fields from PlayerBindState into PlayerMovement component - Replace volatile isStruggling/struggleStartTick pair with atomic StruggleSnapshot record - Remove 5+2 misleading synchronized keywords (different monitors, all server-thread-only) - Update all 36 MovementStyleManager field accesses to use getMovement() getters/setters
126 lines
4.2 KiB
Java
126 lines
4.2 KiB
Java
package com.tiedup.remake.state.components;
|
|
|
|
import com.tiedup.remake.state.PlayerBindState;
|
|
import com.tiedup.remake.state.hosts.IPlayerBindStateHost;
|
|
import com.tiedup.remake.state.struggle.StruggleBinds;
|
|
import com.tiedup.remake.state.struggle.StruggleCollar;
|
|
import net.minecraft.world.entity.player.Player;
|
|
|
|
/**
|
|
* Component responsible for struggle mechanics and resistance management.
|
|
*
|
|
* Single Responsibility: Struggle state and resistance tracking
|
|
* Complexity: MEDIUM (volatile fields, animation coordination)
|
|
* Risk: MEDIUM (thread-safety requirements)
|
|
*
|
|
* Threading: Uses host's volatile fields for animation state (isStruggling, struggleStartTick)
|
|
*
|
|
* Note: StruggleBinds and StruggleCollar require PlayerBindState parameter.
|
|
* Since PlayerBindState implements IPlayerBindStateHost, we can safely cast.
|
|
*/
|
|
public class PlayerStruggle {
|
|
|
|
private final IPlayerBindStateHost host;
|
|
private final PlayerBindState state; // Cast reference for struggle system
|
|
|
|
private final StruggleBinds struggleBindState;
|
|
private final StruggleCollar struggleCollarState;
|
|
|
|
public PlayerStruggle(IPlayerBindStateHost host) {
|
|
this.host = host;
|
|
// Safe cast: PlayerBindState implements IPlayerBindStateHost
|
|
this.state = (PlayerBindState) host;
|
|
|
|
// Initialize sub-states for struggling
|
|
this.struggleBindState = new StruggleBinds();
|
|
this.struggleCollarState = new StruggleCollar();
|
|
}
|
|
|
|
// ========== Struggle Methods ==========
|
|
|
|
/**
|
|
* Entry point for the Struggle logic (Key R).
|
|
* Distributes effort between Binds and Collar.
|
|
*
|
|
* Thread Safety: Must be called from the server thread (packet handlers use enqueueWork).
|
|
*/
|
|
public void struggle() {
|
|
if (struggleBindState != null) struggleBindState.struggle(state);
|
|
if (struggleCollarState != null) struggleCollarState.struggle(state);
|
|
}
|
|
|
|
/**
|
|
* Restores resistance to base values when a master tightens the ties.
|
|
*
|
|
* Thread Safety: Must be called from the server thread.
|
|
*/
|
|
public void tighten(Player tightener) {
|
|
if (struggleBindState != null) struggleBindState.tighten(
|
|
tightener,
|
|
state
|
|
);
|
|
if (struggleCollarState != null) struggleCollarState.tighten(
|
|
tightener,
|
|
state
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Get the StruggleBinds instance for external access (mini-game system).
|
|
*/
|
|
public StruggleBinds getStruggleBinds() {
|
|
return struggleBindState;
|
|
}
|
|
|
|
/**
|
|
* Set a cooldown on struggle attempts (used after mini-game exhaustion).
|
|
* @param seconds Cooldown duration in seconds
|
|
*/
|
|
public void setStruggleCooldown(int seconds) {
|
|
if (
|
|
struggleBindState != null &&
|
|
host.getPlayer() != null &&
|
|
host.getLevel() != null
|
|
) {
|
|
struggleBindState.setExternalCooldown(seconds, host.getLevel());
|
|
}
|
|
}
|
|
|
|
/**
|
|
* v2.5: Check if struggle cooldown is active.
|
|
* @return true if cooldown is active (cannot struggle yet)
|
|
*/
|
|
public boolean isStruggleCooldownActive() {
|
|
return (
|
|
struggleBindState != null && struggleBindState.isCooldownActive()
|
|
);
|
|
}
|
|
|
|
/**
|
|
* v2.5: Get remaining struggle cooldown in seconds.
|
|
* @return Remaining seconds, or 0 if no cooldown
|
|
*/
|
|
public int getStruggleCooldownRemaining() {
|
|
return struggleBindState != null
|
|
? struggleBindState.getRemainingCooldownSeconds()
|
|
: 0;
|
|
}
|
|
|
|
// ========== Animation Control ==========
|
|
// Note: Animation state (isStruggling, struggleStartTick) is managed by host
|
|
// via IPlayerBindStateHost interface (volatile fields for thread-safety)
|
|
|
|
/**
|
|
* Check if struggle animation should stop (duration expired).
|
|
* @param currentTick Current game time tick
|
|
* @return True if animation has been playing for >= 80 ticks
|
|
*/
|
|
public boolean shouldStopStruggling(long currentTick) {
|
|
if (!host.isStruggling()) return false;
|
|
return (
|
|
(currentTick - host.getStruggleStartTick()) >=
|
|
com.tiedup.remake.util.GameConstants.STRUGGLE_ANIMATION_DURATION_TICKS
|
|
);
|
|
}
|
|
}
|