-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathFieldwrightConfig.cs
More file actions
113 lines (98 loc) · 4.44 KB
/
Copy pathFieldwrightConfig.cs
File metadata and controls
113 lines (98 loc) · 4.44 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
using System;
using Vintagestory.API.Common;
namespace Fieldwright;
/// <summary>
/// How strictly the match tracker treats a placed block as "the right block" for a
/// given ghost cell. Defaults to Loose to preserve v0.1.0 behavior and respect
/// external user feedback (KiriRae, ModDB): builders often can't source the exact
/// rock/wood type that was used in creative, and want substitutability by family.
/// </summary>
public enum MatchingMode
{
/// <summary>block.FirstCodePart() only, "any cobble for any cobble".</summary>
Loose,
/// <summary>VS Variant API, stripping rotation/facing/orientation variants only.
/// Preserves rock type, wood type, condition. Andesite cobble distinct from granite cobble,
/// but all rotation variants of slanted thatch share a key.</summary>
Medium,
/// <summary>Full block code including every variant. Likely unusable in practice
/// because VS auto-orients blocks at placement, but exposed for completeness.</summary>
Strict,
}
/// <summary>
/// User-editable mod config. Lives at %APPDATA%/VintagestoryData/ModConfig/Fieldwright.json.
/// Loaded on StartClientSide; created with defaults if missing. New knobs added here
/// should pick conservative defaults that match v0.1.0 behavior so existing users
/// don't see surprise changes after an update.
/// </summary>
public class FieldwrightConfig
{
/// <summary>Default matching mode for newly pasted ghosts. Overridable per-paste via .fw paste <name> <mode>.</summary>
public MatchingMode DefaultMatchingMode { get; set; } = MatchingMode.Loose;
/// <summary>Vertex alpha for the floating ghost mesh. Range 0.0 (invisible) to 1.0 (opaque). Default 0.3.</summary>
public float GhostAlpha { get; set; } = 0.3f;
/// <summary>Maximum render distance for the ghost in blocks. Default 256.</summary>
public int RenderDistanceBlocks { get; set; } = 256;
/// <summary>Milliseconds the checklist HUD lingers after structure completion before auto-dismissing. Default 5500.</summary>
public int AutoDismissMs { get; set; } = 5500;
/// <summary>Top-left pixel offset of the checklist HUD. Defaults (8, 60).</summary>
public int HudOffsetX { get; set; } = 8;
/// <summary>Top-left pixel offset of the checklist HUD. Defaults (8, 60).</summary>
public int HudOffsetY { get; set; } = 60;
/// <summary>
/// Load the config from disk, falling back to defaults (and writing them out) if the
/// file doesn't exist or fails to parse. Never throws.
/// </summary>
public static FieldwrightConfig Load(ICoreAPI api)
{
const string filename = "Fieldwright.json";
FieldwrightConfig? config = null;
try
{
config = api.LoadModConfig<FieldwrightConfig>(filename);
}
catch (Exception ex)
{
FieldwrightLogger.Warn(api, "config",
$"failed to load {filename}: {ex.Message}. Using defaults; existing file (if any) is not touched.");
return new FieldwrightConfig();
}
if (config == null)
{
config = new FieldwrightConfig();
try
{
api.StoreModConfig(config, filename);
FieldwrightLogger.Info(api, "config",
$"created default config at ModConfig/{filename}, edit to customize.");
}
catch (Exception ex)
{
FieldwrightLogger.Warn(api, "config",
$"failed to write default {filename}: {ex.Message}. Defaults still apply in memory.");
}
}
else
{
FieldwrightLogger.Info(api, "config",
$"loaded config: matching={config.DefaultMatchingMode}, alpha={config.GhostAlpha}, " +
$"renderDist={config.RenderDistanceBlocks}, autoDismiss={config.AutoDismissMs}ms");
}
return config;
}
/// <summary>
/// Parse a string into a MatchingMode for the `.fw paste <name> <mode>` arg path.
/// Returns null if the input doesn't match a known mode (caller surfaces the error).
/// </summary>
public static MatchingMode? ParseMatchingMode(string? raw)
{
if (string.IsNullOrWhiteSpace(raw)) return null;
return raw.ToLowerInvariant() switch
{
"loose" => MatchingMode.Loose,
"medium" => MatchingMode.Medium,
"strict" => MatchingMode.Strict,
_ => null,
};
}
}