Merge pull request 'centralize all ModConfig.SERVER reads through SettingsAccessor' (#16) from chore/audit-c02-config-unification into develop

Reviewed-on: #16
This commit was merged in pull request #16.
This commit is contained in:
2026-04-16 11:49:22 +00:00
23 changed files with 461 additions and 88 deletions

View File

@@ -3,7 +3,7 @@ package com.tiedup.remake.client;
import com.mojang.blaze3d.platform.InputConstants; import com.mojang.blaze3d.platform.InputConstants;
import com.tiedup.remake.client.gui.screens.AdjustmentScreen; import com.tiedup.remake.client.gui.screens.AdjustmentScreen;
import com.tiedup.remake.client.gui.screens.UnifiedBondageScreen; import com.tiedup.remake.client.gui.screens.UnifiedBondageScreen;
import com.tiedup.remake.core.ModConfig; import com.tiedup.remake.core.SettingsAccessor;
import com.tiedup.remake.core.TiedUpMod; import com.tiedup.remake.core.TiedUpMod;
import com.tiedup.remake.items.base.ILockable; import com.tiedup.remake.items.base.ILockable;
import com.tiedup.remake.v2.bondage.CollarHelper; import com.tiedup.remake.v2.bondage.CollarHelper;
@@ -315,7 +315,7 @@ public class ModKeybindings {
// Check if player has bind equipped // Check if player has bind equipped
if (state.isTiedUp()) { if (state.isTiedUp()) {
// Has bind - struggle against it // Has bind - struggle against it
if (ModConfig.SERVER.struggleMiniGameEnabled.get()) { if (SettingsAccessor.isStruggleMiniGameEnabled()) {
// New: Start struggle mini-game // New: Start struggle mini-game
ModNetwork.sendToServer( ModNetwork.sendToServer(
new PacketV2StruggleStart(BodyRegionV2.ARMS) new PacketV2StruggleStart(BodyRegionV2.ARMS)

View File

@@ -9,16 +9,32 @@ import net.minecraftforge.common.ForgeConfigSpec;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
/** /**
* Centralized accessor for mod settings that resolves the GameRules vs ModConfig priority. * Centralized accessor for all TiedUp! mod settings.
* *
* Priority order: * <h2>Three-Tier Resolution</h2>
* 1. GameRules (if a world is loaded and rules are available) - these are per-world overrides * <ul>
* 2. ModConfig (if config is loaded) - these are the user's intended defaults * <li><b>Tier 1 — GameRules</b> (per-world, overridable via {@code /gamerule}): ~24 settings.
* 3. Hardcoded fallback - safe defaults if neither system is available yet * These take priority when a world is loaded and {@code GameRules} is available.</li>
* <li><b>Tier 2 — ModConfig</b> (server {@code .toml} defaults): ~78+ settings.
* Read via {@link #safeGet} to tolerate early access before the config spec is loaded.</li>
* <li><b>Tier 3 — Hardcoded fallbacks</b>: safe defaults returned when neither Tier 1
* nor Tier 2 is available (e.g., during mod construction).</li>
* </ul>
* *
* This class exists because GameRules defaults (set at registration time before config loads) * <h2>Rule</h2>
* can diverge from ModConfig defaults. Without this accessor, ModConfig spawn rate values * <p><b>All game code should read settings through this class, never directly from
* were completely ignored (BUG-001). * {@link ModConfig} or {@link ModGameRules}.</b> This ensures a single choke-point
* for defaults, null-safety, and future GameRule promotion of any setting.</p>
*
* <p>Settings that only exist in ModConfig (no GameRule equivalent) use parameterless
* getters. Settings that have a GameRule override accept a {@code @Nullable GameRules}
* parameter.</p>
*
* <p>Client-side config ({@code ModConfig.CLIENT.*}) is excluded — it is read-only
* and single-source, so no accessor is needed.</p>
*
* @see ModConfig.ServerConfig
* @see ModGameRules
*/ */
public class SettingsAccessor { public class SettingsAccessor {
@@ -531,6 +547,377 @@ public class SettingsAccessor {
); );
} }
// ==================== Minigame Toggles ====================
/**
* Check if the struggle mini-game is enabled.
* When disabled, struggle actions are rejected or use instant logic.
*
* @return true if the struggle mini-game is enabled (default true)
*/
public static boolean isStruggleMiniGameEnabled() {
return safeGet(() -> ModConfig.SERVER.struggleMiniGameEnabled.get(), true);
}
/**
* Check if the lockpick mini-game is enabled.
* When disabled, lockpick actions are rejected or use instant logic.
*
* @return true if the lockpick mini-game is enabled (default true)
*/
public static boolean isLockpickMiniGameEnabled() {
return safeGet(() -> ModConfig.SERVER.lockpickMiniGameEnabled.get(), true);
}
// ==================== Combat & Weapons ====================
/**
* Get the whip damage amount.
*
* @return Damage as float (default 2.0)
*/
public static float getWhipDamage() {
return safeGet(() -> ModConfig.SERVER.whipDamage.get(), 2.0).floatValue();
}
/**
* Get the resistance decrease per whip hit.
*
* @return Resistance decrease amount (default 15)
*/
public static int getWhipResistanceDecrease() {
return safeGet(() -> ModConfig.SERVER.whipResistanceDecrease.get(), 15);
}
/**
* Get the taser stun effect duration in ticks.
*
* @return Duration in ticks (default 100 = 5 seconds)
*/
public static int getTaserStunDuration() {
return safeGet(() -> ModConfig.SERVER.taserStunDuration.get(), 100);
}
/**
* Get the swim speed multiplier applied to tied players.
*
* @return Multiplier (0.0-1.0, default 0.5)
*/
public static double getTiedSwimSpeedMultiplier() {
return safeGet(() -> ModConfig.SERVER.tiedSwimSpeedMultiplier.get(), 0.5);
}
// ==================== Lockpick ====================
/**
* Get the lockpick success chance (0-100).
*
* @return Success chance percentage (default 25)
*/
public static int getLockpickSuccessChance() {
return safeGet(() -> ModConfig.SERVER.lockpickSuccessChance.get(), 25);
}
/**
* Get the lockpick jam chance (0.0-100.0).
*
* @return Jam chance percentage as double (default 2.5)
*/
public static double getLockpickJamChance() {
return safeGet(() -> ModConfig.SERVER.lockpickJamChance.get(), 2.5);
}
/**
* Get the lockpick break chance (0-100).
*
* @return Break chance percentage (default 15)
*/
public static int getLockpickBreakChance() {
return safeGet(() -> ModConfig.SERVER.lockpickBreakChance.get(), 15);
}
// ==================== Rag ====================
/**
* Get the default rag wet time in ticks.
*
* @return Wet time in ticks (default 6000 = 5 minutes)
*/
public static int getRagWetTime() {
return safeGet(() -> ModConfig.SERVER.ragWetTime.get(), 6000);
}
// ==================== Arrows ====================
/**
* Get the rope arrow bind chance for non-archer shooters (0-100).
*
* @return Bind chance percentage (default 50)
*/
public static int getRopeArrowBindChance() {
return safeGet(() -> ModConfig.SERVER.ropeArrowBindChance.get(), 50);
}
/**
* Get the archer's base bind chance per arrow hit (0-100).
*
* @return Base bind chance percentage (default 10)
*/
public static int getArcherArrowBindChanceBase() {
return safeGet(() -> ModConfig.SERVER.archerArrowBindChanceBase.get(), 10);
}
/**
* Get the additional bind chance per previous hit for archers (0-100).
*
* @return Per-hit chance increase percentage (default 10)
*/
public static int getArcherArrowBindChancePerHit() {
return safeGet(() -> ModConfig.SERVER.archerArrowBindChancePerHit.get(), 10);
}
// ==================== Kidnap Bomb ====================
/**
* Get the kidnap bomb fuse duration in ticks.
*
* @return Fuse in ticks (default 80 = 4 seconds)
*/
public static int getKidnapBombFuse() {
return safeGet(() -> ModConfig.SERVER.kidnapBombFuse.get(), 80);
}
// ==================== Merchant ====================
/**
* Get the merchant hostile cooldown duration in ticks.
*
* @return Duration in ticks (default 6000 = 5 minutes)
*/
public static int getMerchantHostileDuration() {
return safeGet(() -> ModConfig.SERVER.merchantHostileDuration.get(), 6000);
}
/**
* Get the minimum number of random trades a merchant generates.
*
* @return Minimum trade count (default 8)
*/
public static int getMerchantMinTrades() {
return safeGet(() -> ModConfig.SERVER.merchantMinTrades.get(), 8);
}
/**
* Get the maximum number of random trades a merchant generates.
*
* @return Maximum trade count (default 12)
*/
public static int getMerchantMaxTrades() {
return safeGet(() -> ModConfig.SERVER.merchantMaxTrades.get(), 12);
}
/**
* Get the tier 1 minimum price in nuggets.
* @return Min price (default 9)
*/
public static int getTier1PriceMin() {
return safeGet(() -> ModConfig.SERVER.tier1PriceMin.get(), 9);
}
/**
* Get the tier 1 maximum price in nuggets.
* @return Max price (default 18)
*/
public static int getTier1PriceMax() {
return safeGet(() -> ModConfig.SERVER.tier1PriceMax.get(), 18);
}
/**
* Get the tier 2 minimum price in nuggets.
* @return Min price (default 27)
*/
public static int getTier2PriceMin() {
return safeGet(() -> ModConfig.SERVER.tier2PriceMin.get(), 27);
}
/**
* Get the tier 2 maximum price in nuggets.
* @return Max price (default 45)
*/
public static int getTier2PriceMax() {
return safeGet(() -> ModConfig.SERVER.tier2PriceMax.get(), 45);
}
/**
* Get the tier 3 minimum price in nuggets.
* @return Min price (default 54)
*/
public static int getTier3PriceMin() {
return safeGet(() -> ModConfig.SERVER.tier3PriceMin.get(), 54);
}
/**
* Get the tier 3 maximum price in nuggets.
* @return Max price (default 90)
*/
public static int getTier3PriceMax() {
return safeGet(() -> ModConfig.SERVER.tier3PriceMax.get(), 90);
}
/**
* Get the tier 4 minimum price in nuggets.
* @return Min price (default 90)
*/
public static int getTier4PriceMin() {
return safeGet(() -> ModConfig.SERVER.tier4PriceMin.get(), 90);
}
/**
* Get the tier 4 maximum price in nuggets.
* @return Max price (default 180)
*/
public static int getTier4PriceMax() {
return safeGet(() -> ModConfig.SERVER.tier4PriceMax.get(), 180);
}
// ==================== Dialogue ====================
/**
* Get the dialogue broadcast radius in blocks.
*
* @return Radius in blocks (default 20)
*/
public static int getDialogueRadius() {
return safeGet(() -> ModConfig.SERVER.dialogueRadius.get(), 20);
}
/**
* Get the dialogue cooldown in ticks.
*
* @return Cooldown in ticks (default 100 = 5 seconds)
*/
public static int getDialogueCooldown() {
return safeGet(() -> ModConfig.SERVER.dialogueCooldown.get(), 100);
}
// ==================== Labor ====================
/**
* Get the labor rest duration in seconds.
*
* @return Rest duration in seconds (default 120)
*/
public static int getLaborRestSeconds() {
return safeGet(() -> ModConfig.SERVER.laborRestSeconds.get(), 120);
}
// ==================== Solo Mode / Master Spawn ====================
/**
* Check if Master NPC spawning is enabled.
*
* @return true if Master can spawn (default true)
*/
public static boolean isEnableMasterSpawn() {
return safeGet(() -> ModConfig.SERVER.enableMasterSpawn.get(), true);
}
/**
* Check if solo mode fallback behavior is enabled.
* When enabled, kidnappers in solo worlds use alternative captive handling.
*
* @return true if solo fallback is enabled (default true)
*/
public static boolean isEnableSoloFallback() {
return safeGet(() -> ModConfig.SERVER.enableSoloFallback.get(), true);
}
/**
* Get the solo mode timeout in seconds before the kidnapper gives up waiting.
*
* @return Timeout in seconds (default 120)
*/
public static int getSoloTimeoutSeconds() {
return safeGet(() -> ModConfig.SERVER.soloTimeoutSeconds.get(), 120);
}
/**
* Get the probability (0.0-1.0) that a kidnapper keeps the captive in solo mode.
*
* @return Keep chance (default 0.6)
*/
public static double getSoloKeepChance() {
return safeGet(() -> ModConfig.SERVER.soloKeepChance.get(), 0.6);
}
// ==================== Abandon Behavior ====================
/**
* Check if kidnapper abandonment keeps the blindfold on the captive.
*
* @return true if blindfold is kept (default true)
*/
public static boolean isAbandonKeepsBlindfold() {
return safeGet(() -> ModConfig.SERVER.abandonKeepsBlindfold.get(), true);
}
/**
* Check if kidnapper abandonment keeps binds on the captive.
*
* @return true if binds are kept (default true)
*/
public static boolean isAbandonKeepsBinds() {
return safeGet(() -> ModConfig.SERVER.abandonKeepsBinds.get(), true);
}
// ==================== Gag Settings ====================
/**
* Get the configured comprehension factor for a gag material.
* Falls back to the material's hardcoded default if the config key is missing.
*
* @param materialKey Lowercase gag material name (e.g., "cloth", "ball")
* @param defaultValue The material's built-in default comprehension
* @return Comprehension factor as float
*/
public static float getGagComprehension(String materialKey, float defaultValue) {
return safeGet(
() -> {
if (ModConfig.SERVER == null) return defaultValue;
Map<String, ForgeConfigSpec.DoubleValue> map =
ModConfig.SERVER.gagComprehension;
if (map != null && map.containsKey(materialKey)) {
return map.get(materialKey).get().floatValue();
}
return defaultValue;
},
defaultValue
);
}
/**
* Get the configured talk range for a gag material.
* Falls back to the material's hardcoded default if the config key is missing.
*
* @param materialKey Lowercase gag material name (e.g., "cloth", "ball")
* @param defaultValue The material's built-in default talk range
* @return Talk range as double
*/
public static double getGagTalkRange(String materialKey, double defaultValue) {
return safeGet(
() -> {
if (ModConfig.SERVER == null) return defaultValue;
Map<String, ForgeConfigSpec.DoubleValue> map =
ModConfig.SERVER.gagRange;
if (map != null && map.containsKey(materialKey)) {
return map.get(materialKey).get();
}
return defaultValue;
},
defaultValue
);
}
// ==================== Helpers ==================== // ==================== Helpers ====================
/** /**

View File

@@ -1,6 +1,6 @@
package com.tiedup.remake.entities; package com.tiedup.remake.entities;
import com.tiedup.remake.core.ModConfig; import com.tiedup.remake.core.SettingsAccessor;
import com.tiedup.remake.core.TiedUpMod; import com.tiedup.remake.core.TiedUpMod;
import com.tiedup.remake.dialogue.EntityDialogueManager; import com.tiedup.remake.dialogue.EntityDialogueManager;
import java.util.UUID; import java.util.UUID;
@@ -179,7 +179,7 @@ public class DamselRewardTracker {
// Thank the savior via dialogue // Thank the savior via dialogue
damsel.talkToPlayersInRadius( damsel.talkToPlayersInRadius(
EntityDialogueManager.DialogueCategory.DAMSEL_FREED, EntityDialogueManager.DialogueCategory.DAMSEL_FREED,
ModConfig.SERVER.dialogueRadius.get() SettingsAccessor.getDialogueRadius()
); );
TiedUpMod.LOGGER.info( TiedUpMod.LOGGER.info(

View File

@@ -1,7 +1,6 @@
package com.tiedup.remake.entities; package com.tiedup.remake.entities;
import com.tiedup.remake.blocks.entity.KidnapBombBlockEntity; import com.tiedup.remake.blocks.entity.KidnapBombBlockEntity;
import com.tiedup.remake.core.ModConfig;
import com.tiedup.remake.core.SettingsAccessor; import com.tiedup.remake.core.SettingsAccessor;
import com.tiedup.remake.util.KidnapExplosion; import com.tiedup.remake.util.KidnapExplosion;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@@ -56,7 +55,7 @@ public class EntityKidnapBomb extends PrimedTnt {
this.setPos(x, y, z); this.setPos(x, y, z);
double d0 = level.random.nextDouble() * (Math.PI * 2); double d0 = level.random.nextDouble() * (Math.PI * 2);
this.setDeltaMovement(-Math.sin(d0) * 0.02, 0.2, -Math.cos(d0) * 0.02); this.setDeltaMovement(-Math.sin(d0) * 0.02, 0.2, -Math.cos(d0) * 0.02);
this.setFuse(ModConfig.SERVER.kidnapBombFuse.get()); this.setFuse(SettingsAccessor.getKidnapBombFuse());
this.xo = x; this.xo = x;
this.yo = y; this.yo = y;

View File

@@ -335,9 +335,9 @@ public class EntityKidnapperArcher
public int getBindChanceForTarget(UUID targetUUID) { public int getBindChanceForTarget(UUID targetUUID) {
int hitCount = targetHitCounts.getOrDefault(targetUUID, 0); int hitCount = targetHitCounts.getOrDefault(targetUUID, 0);
int baseChance = int baseChance =
com.tiedup.remake.core.ModConfig.SERVER.archerArrowBindChanceBase.get(); SettingsAccessor.getArcherArrowBindChanceBase();
int perHitChance = int perHitChance =
com.tiedup.remake.core.ModConfig.SERVER.archerArrowBindChancePerHit.get(); SettingsAccessor.getArcherArrowBindChancePerHit();
int chance = baseChance + (hitCount * perHitChance); int chance = baseChance + (hitCount * perHitChance);
return Math.min(chance, ARCHER_MAX_BIND_CHANCE); return Math.min(chance, ARCHER_MAX_BIND_CHANCE);

View File

@@ -2,7 +2,6 @@ package com.tiedup.remake.entities;
import static com.tiedup.remake.util.GameConstants.*; import static com.tiedup.remake.util.GameConstants.*;
import com.tiedup.remake.core.ModConfig;
import com.tiedup.remake.core.SettingsAccessor; import com.tiedup.remake.core.SettingsAccessor;
import com.tiedup.remake.core.TiedUpMod; import com.tiedup.remake.core.TiedUpMod;
import com.tiedup.remake.dialogue.SpeakerType; import com.tiedup.remake.dialogue.SpeakerType;
@@ -356,7 +355,7 @@ public class EntityKidnapperMerchant extends EntityKidnapperElite {
private void transitionToHostile(LivingEntity attacker) { private void transitionToHostile(LivingEntity attacker) {
currentState = MerchantState.HOSTILE; currentState = MerchantState.HOSTILE;
attackerUUID = attacker.getUUID(); attackerUUID = attacker.getUUID();
hostileCooldownTicks = ModConfig.SERVER.merchantHostileDuration.get(); hostileCooldownTicks = SettingsAccessor.getMerchantHostileDuration();
entityData.set(DATA_MERCHANT_STATE, MerchantState.HOSTILE.getId()); entityData.set(DATA_MERCHANT_STATE, MerchantState.HOSTILE.getId());
// Equip kidnapper items // Equip kidnapper items
@@ -536,8 +535,8 @@ public class EntityKidnapperMerchant extends EntityKidnapperElite {
addGuaranteedUtilities(); addGuaranteedUtilities();
// RANDOM TRADES // RANDOM TRADES
int min = ModConfig.SERVER.merchantMinTrades.get(); int min = SettingsAccessor.getMerchantMinTrades();
int max = ModConfig.SERVER.merchantMaxTrades.get(); int max = SettingsAccessor.getMerchantMaxTrades();
int count = min + this.random.nextInt(Math.max(1, max - min + 1)); int count = min + this.random.nextInt(Math.max(1, max - min + 1));
// Collect all mod items // Collect all mod items
@@ -644,21 +643,21 @@ public class EntityKidnapperMerchant extends EntityKidnapperElite {
int minPrice, maxPrice; int minPrice, maxPrice;
switch (tier) { switch (tier) {
case 4: case 4:
minPrice = ModConfig.SERVER.tier4PriceMin.get(); minPrice = SettingsAccessor.getTier4PriceMin();
maxPrice = ModConfig.SERVER.tier4PriceMax.get(); maxPrice = SettingsAccessor.getTier4PriceMax();
break; break;
case 3: case 3:
minPrice = ModConfig.SERVER.tier3PriceMin.get(); minPrice = SettingsAccessor.getTier3PriceMin();
maxPrice = ModConfig.SERVER.tier3PriceMax.get(); maxPrice = SettingsAccessor.getTier3PriceMax();
break; break;
case 2: case 2:
minPrice = ModConfig.SERVER.tier2PriceMin.get(); minPrice = SettingsAccessor.getTier2PriceMin();
maxPrice = ModConfig.SERVER.tier2PriceMax.get(); maxPrice = SettingsAccessor.getTier2PriceMax();
break; break;
case 1: case 1:
default: default:
minPrice = ModConfig.SERVER.tier1PriceMin.get(); minPrice = SettingsAccessor.getTier1PriceMin();
maxPrice = ModConfig.SERVER.tier1PriceMax.get(); maxPrice = SettingsAccessor.getTier1PriceMax();
break; break;
} }

View File

@@ -1,6 +1,6 @@
package com.tiedup.remake.entities; package com.tiedup.remake.entities;
import com.tiedup.remake.core.ModConfig; import com.tiedup.remake.core.SettingsAccessor;
import com.tiedup.remake.core.TiedUpMod; import com.tiedup.remake.core.TiedUpMod;
import com.tiedup.remake.items.ModItems; import com.tiedup.remake.items.ModItems;
import com.tiedup.remake.state.IBondageState; import com.tiedup.remake.state.IBondageState;
@@ -87,7 +87,7 @@ public class EntityRopeArrow extends AbstractArrow {
bindChance = archer.getBindChanceForTarget(target.getUUID()); bindChance = archer.getBindChanceForTarget(target.getUUID());
} else { } else {
// Other shooters: default 50% chance // Other shooters: default 50% chance
bindChance = ModConfig.SERVER.ropeArrowBindChance.get(); bindChance = SettingsAccessor.getRopeArrowBindChance();
} }
// Roll for bind chance // Roll for bind chance

View File

@@ -1,6 +1,6 @@
package com.tiedup.remake.entities.ai.kidnapper; package com.tiedup.remake.entities.ai.kidnapper;
import com.tiedup.remake.core.ModConfig; import com.tiedup.remake.core.SettingsAccessor;
import com.tiedup.remake.core.TiedUpMod; import com.tiedup.remake.core.TiedUpMod;
import com.tiedup.remake.dialogue.EntityDialogueManager; import com.tiedup.remake.dialogue.EntityDialogueManager;
import com.tiedup.remake.dialogue.EntityDialogueManager.DialogueCategory; import com.tiedup.remake.dialogue.EntityDialogueManager.DialogueCategory;
@@ -155,7 +155,7 @@ public class KidnapperWaitForBuyerGoal extends Goal {
// Check if Master should spawn immediately for solo player // Check if Master should spawn immediately for solo player
IRestrainable captive = this.kidnapper.getCaptive(); IRestrainable captive = this.kidnapper.getCaptive();
boolean isMasterEnabled = ModConfig.SERVER.enableMasterSpawn.get(); boolean isMasterEnabled = SettingsAccessor.isEnableMasterSpawn();
boolean isPlayer = boolean isPlayer =
captive != null && captive.asLivingEntity() instanceof Player; captive != null && captive.asLivingEntity() instanceof Player;
@@ -171,12 +171,12 @@ public class KidnapperWaitForBuyerGoal extends Goal {
// Don't return - let the goal continue so kidnapper waits for Master // Don't return - let the goal continue so kidnapper waits for Master
// The wait duration is set to allow Master to arrive // The wait duration is set to allow Master to arrive
this.waitDuration = 6000; // 5 minutes max wait for Master to arrive this.waitDuration = 6000; // 5 minutes max wait for Master to arrive
} else if (this.soloMode && ModConfig.SERVER.enableSoloFallback.get()) { } else if (this.soloMode && SettingsAccessor.isEnableSoloFallback()) {
// Solo mode (non-player captive): use config timeout // Solo mode (non-player captive): use config timeout
this.waitDuration = ModConfig.SERVER.soloTimeoutSeconds.get() * 20; this.waitDuration = SettingsAccessor.getSoloTimeoutSeconds() * 20;
TiedUpMod.LOGGER.debug( TiedUpMod.LOGGER.debug(
"[KidnapperWaitForBuyerGoal] Solo mode detected, using {}s timeout", "[KidnapperWaitForBuyerGoal] Solo mode detected, using {}s timeout",
ModConfig.SERVER.soloTimeoutSeconds.get() SettingsAccessor.getSoloTimeoutSeconds()
); );
} else { } else {
// Normal mode: random 5-8 minutes // Normal mode: random 5-8 minutes
@@ -426,7 +426,7 @@ public class KidnapperWaitForBuyerGoal extends Goal {
} }
// Handle solo mode fallback // Handle solo mode fallback
if (this.soloMode && ModConfig.SERVER.enableSoloFallback.get()) { if (this.soloMode && SettingsAccessor.isEnableSoloFallback()) {
handleSoloModeFallback(captive); handleSoloModeFallback(captive);
} else { } else {
// Normal multiplayer mode: just flee // Normal multiplayer mode: just flee
@@ -450,7 +450,7 @@ public class KidnapperWaitForBuyerGoal extends Goal {
} }
// Check if Master spawn is enabled and captive is a player // Check if Master spawn is enabled and captive is a player
boolean isMasterEnabled = ModConfig.SERVER.enableMasterSpawn.get(); boolean isMasterEnabled = SettingsAccessor.isEnableMasterSpawn();
boolean isPlayer = captive.asLivingEntity() instanceof Player; boolean isPlayer = captive.asLivingEntity() instanceof Player;
if (isMasterEnabled && isPlayer) { if (isMasterEnabled && isPlayer) {
@@ -460,7 +460,7 @@ public class KidnapperWaitForBuyerGoal extends Goal {
} }
// Fallback to original behavior // Fallback to original behavior
double keepChance = ModConfig.SERVER.soloKeepChance.get(); double keepChance = SettingsAccessor.getSoloKeepChance();
double roll = this.kidnapper.getRandom().nextDouble(); double roll = this.kidnapper.getRandom().nextDouble();
TiedUpMod.LOGGER.debug( TiedUpMod.LOGGER.debug(

View File

@@ -2,7 +2,7 @@ package com.tiedup.remake.entities.ai.maid.goals;
import com.tiedup.remake.cells.CellDataV2; import com.tiedup.remake.cells.CellDataV2;
import com.tiedup.remake.cells.CellRegistryV2; import com.tiedup.remake.cells.CellRegistryV2;
import com.tiedup.remake.core.ModConfig; import com.tiedup.remake.core.SettingsAccessor;
import com.tiedup.remake.core.TiedUpMod; import com.tiedup.remake.core.TiedUpMod;
import com.tiedup.remake.entities.EntityMaid; import com.tiedup.remake.entities.EntityMaid;
import com.tiedup.remake.labor.LaborTask; import com.tiedup.remake.labor.LaborTask;
@@ -87,7 +87,7 @@ public class MaidAssignTaskGoal extends Goal {
if (phase == LaborRecord.WorkPhase.RESTING) { if (phase == LaborRecord.WorkPhase.RESTING) {
// Check if rest is complete (config: laborRestSeconds, default 120s) // Check if rest is complete (config: laborRestSeconds, default 120s)
long restTicks = ModConfig.SERVER.laborRestSeconds.get() * 20L; long restTicks = SettingsAccessor.getLaborRestSeconds() * 20L;
long elapsed = labor.getTimeInPhase(currentTime); long elapsed = labor.getTimeInPhase(currentTime);
if (elapsed >= restTicks) { if (elapsed >= restTicks) {
labor.finishRest(currentTime); labor.finishRest(currentTime);

View File

@@ -1,6 +1,6 @@
package com.tiedup.remake.entities.damsel.components; package com.tiedup.remake.entities.damsel.components;
import com.tiedup.remake.core.ModConfig; import com.tiedup.remake.core.SettingsAccessor;
import com.tiedup.remake.core.TiedUpMod; import com.tiedup.remake.core.TiedUpMod;
import com.tiedup.remake.entities.EntityDamsel; import com.tiedup.remake.entities.EntityDamsel;
import com.tiedup.remake.entities.ai.damsel.*; import com.tiedup.remake.entities.ai.damsel.*;
@@ -223,7 +223,7 @@ public class DamselAIController {
Player.class, Player.class,
host host
.getBoundingBox() .getBoundingBox()
.inflate(ModConfig.SERVER.dialogueRadius.get()) .inflate(SettingsAccessor.getDialogueRadius())
); );
// Get captor entity for comparison // Get captor entity for comparison
@@ -258,7 +258,7 @@ public class DamselAIController {
} }
// Reset cooldown // Reset cooldown
int baseCooldown = ModConfig.SERVER.dialogueCooldown.get(); int baseCooldown = SettingsAccessor.getDialogueCooldown();
if (foundTarget) { if (foundTarget) {
// Full cooldown if we talked // Full cooldown if we talked
this.callForHelpCooldown = this.callForHelpCooldown =

View File

@@ -1,6 +1,6 @@
package com.tiedup.remake.entities.damsel.components; package com.tiedup.remake.entities.damsel.components;
import com.tiedup.remake.core.ModConfig; import com.tiedup.remake.core.SettingsAccessor;
import com.tiedup.remake.dialogue.EntityDialogueManager; import com.tiedup.remake.dialogue.EntityDialogueManager;
import com.tiedup.remake.dialogue.EntityDialogueManager.DialogueCategory; import com.tiedup.remake.dialogue.EntityDialogueManager.DialogueCategory;
import java.util.HashMap; import java.util.HashMap;
@@ -101,7 +101,7 @@ public class DamselDialogueHandler {
if ( if (
lastUsed != null && lastUsed != null &&
(currentTick - lastUsed) < ModConfig.SERVER.dialogueCooldown.get() (currentTick - lastUsed) < SettingsAccessor.getDialogueCooldown()
) { ) {
return false; // Still on cooldown return false; // Still on cooldown
} }

View File

@@ -1,6 +1,6 @@
package com.tiedup.remake.entities.damsel.components; package com.tiedup.remake.entities.damsel.components;
import com.tiedup.remake.core.ModConfig; import com.tiedup.remake.core.SettingsAccessor;
import com.tiedup.remake.core.TiedUpMod; import com.tiedup.remake.core.TiedUpMod;
import com.tiedup.remake.entities.AbstractTiedUpNpc; import com.tiedup.remake.entities.AbstractTiedUpNpc;
import com.tiedup.remake.state.ICaptor; import com.tiedup.remake.state.ICaptor;
@@ -137,7 +137,7 @@ public class NpcCaptivityManager {
if (!entity.level().isClientSide()) { if (!entity.level().isClientSide()) {
host.talkToPlayersInRadius( host.talkToPlayersInRadius(
com.tiedup.remake.dialogue.EntityDialogueManager.DialogueCategory.DAMSEL_FREED, com.tiedup.remake.dialogue.EntityDialogueManager.DialogueCategory.DAMSEL_FREED,
ModConfig.SERVER.dialogueRadius.get() SettingsAccessor.getDialogueRadius()
); );
} }
} else { } else {

View File

@@ -1,6 +1,6 @@
package com.tiedup.remake.entities.damsel.components; package com.tiedup.remake.entities.damsel.components;
import com.tiedup.remake.core.ModConfig; import com.tiedup.remake.core.SettingsAccessor;
import com.tiedup.remake.core.TiedUpMod; import com.tiedup.remake.core.TiedUpMod;
import com.tiedup.remake.entities.AbstractTiedUpNpc; import com.tiedup.remake.entities.AbstractTiedUpNpc;
import com.tiedup.remake.items.base.ILockable; import com.tiedup.remake.items.base.ILockable;
@@ -206,7 +206,7 @@ public class NpcEquipmentManager {
if (!wasAlreadyTied && !entity.level().isClientSide()) { if (!wasAlreadyTied && !entity.level().isClientSide()) {
host.talkToPlayersInRadius( host.talkToPlayersInRadius(
com.tiedup.remake.dialogue.EntityDialogueManager.DialogueCategory.DAMSEL_CAPTURED, com.tiedup.remake.dialogue.EntityDialogueManager.DialogueCategory.DAMSEL_CAPTURED,
ModConfig.SERVER.dialogueRadius.get() SettingsAccessor.getDialogueRadius()
); );
} }

View File

@@ -1,7 +1,7 @@
package com.tiedup.remake.entities.kidnapper.components; package com.tiedup.remake.entities.kidnapper.components;
import com.tiedup.remake.cells.CellDataV2; import com.tiedup.remake.cells.CellDataV2;
import com.tiedup.remake.core.ModConfig; import com.tiedup.remake.core.SettingsAccessor;
import com.tiedup.remake.core.TiedUpMod; import com.tiedup.remake.core.TiedUpMod;
import com.tiedup.remake.dialogue.EntityDialogueManager; import com.tiedup.remake.dialogue.EntityDialogueManager;
import com.tiedup.remake.entities.EntityKidnapper; import com.tiedup.remake.entities.EntityKidnapper;
@@ -628,7 +628,7 @@ public class KidnapperCaptiveManager {
// Apply blindfold if enabled in config // Apply blindfold if enabled in config
if ( if (
com.tiedup.remake.core.ModConfig.SERVER.abandonKeepsBlindfold.get() SettingsAccessor.isAbandonKeepsBlindfold()
) { ) {
net.minecraft.world.item.ItemStack blindfold = getBlindfoldItem(); net.minecraft.world.item.ItemStack blindfold = getBlindfoldItem();
if ( if (
@@ -652,7 +652,7 @@ public class KidnapperCaptiveManager {
// Remove restraints if NOT configured to keep them // Remove restraints if NOT configured to keep them
boolean keepBinds = boolean keepBinds =
com.tiedup.remake.core.ModConfig.SERVER.abandonKeepsBinds.get(); SettingsAccessor.isAbandonKeepsBinds();
if (!keepBinds) { if (!keepBinds) {
// Full release including binds // Full release including binds
this.currentCaptive.untie(true); this.currentCaptive.untie(true);

View File

@@ -1,5 +1,6 @@
package com.tiedup.remake.events.restriction; package com.tiedup.remake.events.restriction;
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;
@@ -134,7 +135,7 @@ public class BondageItemRestrictionHandler {
Vec3 motion = player.getDeltaMovement(); Vec3 motion = player.getDeltaMovement();
player.setDeltaMovement( player.setDeltaMovement(
motion.scale( motion.scale(
com.tiedup.remake.core.ModConfig.SERVER.tiedSwimSpeedMultiplier.get() SettingsAccessor.getTiedSwimSpeedMultiplier()
) )
); );
} }

View File

@@ -1,6 +1,5 @@
package com.tiedup.remake.items; package com.tiedup.remake.items;
import com.tiedup.remake.core.ModConfig;
import com.tiedup.remake.core.SystemMessageManager; import com.tiedup.remake.core.SystemMessageManager;
import com.tiedup.remake.core.TiedUpMod; import com.tiedup.remake.core.TiedUpMod;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;

View File

@@ -1,6 +1,6 @@
package com.tiedup.remake.items; package com.tiedup.remake.items;
import com.tiedup.remake.core.ModConfig; import com.tiedup.remake.core.SettingsAccessor;
import com.tiedup.remake.core.SystemMessageManager; import com.tiedup.remake.core.SystemMessageManager;
import com.tiedup.remake.core.TiedUpMod; import com.tiedup.remake.core.TiedUpMod;
import com.tiedup.remake.items.base.ILockable; import com.tiedup.remake.items.base.ILockable;
@@ -208,7 +208,7 @@ public class ItemLockpick extends Item {
// Roll for success // Roll for success
boolean success = boolean success =
random.nextInt(100) < ModConfig.SERVER.lockpickSuccessChance.get(); random.nextInt(100) < SettingsAccessor.getLockpickSuccessChance();
if (success) { if (success) {
// SUCCESS: Unlock the item, PRESERVE the padlock // SUCCESS: Unlock the item, PRESERVE the padlock
@@ -241,7 +241,7 @@ public class ItemLockpick extends Item {
// 2. Check for jam // 2. Check for jam
boolean jammed = boolean jammed =
random.nextDouble() * 100 < random.nextDouble() * 100 <
ModConfig.SERVER.lockpickJamChance.get(); SettingsAccessor.getLockpickJamChance();
if (jammed) { if (jammed) {
lockable.setJammed(targetStack, true); lockable.setJammed(targetStack, true);
SystemMessageManager.sendToPlayer( SystemMessageManager.sendToPlayer(
@@ -265,7 +265,7 @@ public class ItemLockpick extends Item {
// 3. Check for break // 3. Check for break
boolean broke = boolean broke =
random.nextInt(100) < random.nextInt(100) <
ModConfig.SERVER.lockpickBreakChance.get(); SettingsAccessor.getLockpickBreakChance();
if (broke) { if (broke) {
lockpickStack.shrink(1); lockpickStack.shrink(1);
SystemMessageManager.sendToPlayer( SystemMessageManager.sendToPlayer(

View File

@@ -1,6 +1,5 @@
package com.tiedup.remake.items; package com.tiedup.remake.items;
import com.tiedup.remake.core.ModConfig;
import com.tiedup.remake.core.SettingsAccessor; import com.tiedup.remake.core.SettingsAccessor;
import com.tiedup.remake.core.SystemMessageManager; import com.tiedup.remake.core.SystemMessageManager;
import com.tiedup.remake.core.TiedUpMod; import com.tiedup.remake.core.TiedUpMod;
@@ -280,6 +279,6 @@ public class ItemRag extends Item {
* @return Default wet time in ticks * @return Default wet time in ticks
*/ */
public static int getDefaultWetTime() { public static int getDefaultWetTime() {
return ModConfig.SERVER.ragWetTime.get(); return SettingsAccessor.getRagWetTime();
} }
} }

View File

@@ -2,7 +2,7 @@ package com.tiedup.remake.items;
import com.google.common.collect.ImmutableMultimap; import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.Multimap; import com.google.common.collect.Multimap;
import com.tiedup.remake.core.ModConfig; import com.tiedup.remake.core.SettingsAccessor;
import com.tiedup.remake.core.ModSounds; import com.tiedup.remake.core.ModSounds;
import java.util.UUID; import java.util.UUID;
import net.minecraft.sounds.SoundSource; import net.minecraft.sounds.SoundSource;
@@ -74,7 +74,7 @@ public class ItemTaser extends Item {
1.0f 1.0f
); );
int duration = ModConfig.SERVER.taserStunDuration.get(); int duration = SettingsAccessor.getTaserStunDuration();
// Apply Slowness I // Apply Slowness I
target.addEffect( target.addEffect(

View File

@@ -1,6 +1,6 @@
package com.tiedup.remake.items; package com.tiedup.remake.items;
import com.tiedup.remake.core.ModConfig; import com.tiedup.remake.core.SettingsAccessor;
import com.tiedup.remake.core.TiedUpMod; import com.tiedup.remake.core.TiedUpMod;
import com.tiedup.remake.entities.EntityDamsel; import com.tiedup.remake.entities.EntityDamsel;
import com.tiedup.remake.entities.EntityKidnapper; import com.tiedup.remake.entities.EntityKidnapper;
@@ -92,8 +92,8 @@ public class ItemWhip extends Item {
return InteractionResult.PASS; return InteractionResult.PASS;
} }
float damage = ModConfig.SERVER.whipDamage.get().floatValue(); float damage = SettingsAccessor.getWhipDamage();
int resistanceDecrease = ModConfig.SERVER.whipResistanceDecrease.get(); int resistanceDecrease = SettingsAccessor.getWhipResistanceDecrease();
// 1. Play whip sound // 1. Play whip sound
TiedUpSounds.playWhipSound(target); TiedUpSounds.playWhipSound(target);

View File

@@ -1,6 +1,6 @@
package com.tiedup.remake.util; package com.tiedup.remake.util;
import com.tiedup.remake.core.ModConfig; import com.tiedup.remake.core.SettingsAccessor;
/** /**
* GagMaterial DNA - Defines the "sound" and behavior of different gag materials. * GagMaterial DNA - Defines the "sound" and behavior of different gag materials.
@@ -180,28 +180,15 @@ public enum GagMaterial {
} }
public float getComprehension() { public float getComprehension() {
String key = this.name().toLowerCase(); return SettingsAccessor.getGagComprehension(
if ( this.name().toLowerCase(), defaultComprehension
ModConfig.SERVER != null && );
ModConfig.SERVER.gagComprehension.containsKey(key)
) {
return ModConfig.SERVER.gagComprehension
.get(key)
.get()
.floatValue();
}
return defaultComprehension;
} }
public double getTalkRange() { public double getTalkRange() {
String key = this.name().toLowerCase(); return SettingsAccessor.getGagTalkRange(
if ( this.name().toLowerCase(), defaultTalkRange
ModConfig.SERVER != null && );
ModConfig.SERVER.gagRange.containsKey(key)
) {
return ModConfig.SERVER.gagRange.get(key).get();
}
return defaultTalkRange;
} }
/** /**

View File

@@ -1,5 +1,6 @@
package com.tiedup.remake.v2.bondage.network; package com.tiedup.remake.v2.bondage.network;
import com.tiedup.remake.core.SettingsAccessor;
import com.tiedup.remake.items.base.IHasResistance; 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.minigame.ContinuousStruggleMiniGameState; import com.tiedup.remake.minigame.ContinuousStruggleMiniGameState;
@@ -76,7 +77,7 @@ public class PacketV2StruggleStart {
// RISK-002 fix: respect server config // RISK-002 fix: respect server config
if ( if (
!com.tiedup.remake.core.ModConfig.SERVER.struggleMiniGameEnabled.get() !SettingsAccessor.isStruggleMiniGameEnabled()
) return; ) return;
int resistance = resistanceItem.getCurrentResistance(stack, player); int resistance = resistanceItem.getCurrentResistance(stack, player);

View File

@@ -1,5 +1,6 @@
package com.tiedup.remake.v2.furniture.network; package com.tiedup.remake.v2.furniture.network;
import com.tiedup.remake.core.SettingsAccessor;
import com.tiedup.remake.core.TiedUpMod; import com.tiedup.remake.core.TiedUpMod;
import com.tiedup.remake.items.ItemLockpick; import com.tiedup.remake.items.ItemLockpick;
import com.tiedup.remake.minigame.ContinuousStruggleMiniGameState; import com.tiedup.remake.minigame.ContinuousStruggleMiniGameState;
@@ -203,7 +204,7 @@ public class PacketFurnitureEscape {
// Respect server config: if struggle minigame is disabled, skip // Respect server config: if struggle minigame is disabled, skip
if ( if (
!com.tiedup.remake.core.ModConfig.SERVER.struggleMiniGameEnabled.get() !SettingsAccessor.isStruggleMiniGameEnabled()
) { ) {
TiedUpMod.LOGGER.debug( TiedUpMod.LOGGER.debug(
"[PacketFurnitureEscape] Struggle minigame disabled by server config" "[PacketFurnitureEscape] Struggle minigame disabled by server config"
@@ -333,7 +334,7 @@ public class PacketFurnitureEscape {
// Respect server config: if lockpick minigame is disabled, skip // Respect server config: if lockpick minigame is disabled, skip
if ( if (
!com.tiedup.remake.core.ModConfig.SERVER.lockpickMiniGameEnabled.get() !SettingsAccessor.isLockpickMiniGameEnabled()
) { ) {
TiedUpMod.LOGGER.debug( TiedUpMod.LOGGER.debug(
"[PacketFurnitureEscape] Lockpick minigame disabled by server config" "[PacketFurnitureEscape] Lockpick minigame disabled by server config"