Skip to content

Commit 848c058

Browse files
authored
Merge pull request #6 from DanjelPiDev/feature/dw-link
Feature/dw link
2 parents f52a23c + 422dbd9 commit 848c058

7 files changed

Lines changed: 490 additions & 44 deletions

File tree

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ message("Using toolchain file ${CMAKE_TOOLCHAIN_FILE}.")
66
########################################################################################################################
77
project(
88
DynamicSpeedController
9-
VERSION 1.5.0
9+
VERSION 1.5.2
1010
DESCRIPTION "Skyrim Special Edition DSC."
1111
LANGUAGES CXX)
1212

include/Settings.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
struct Settings {
1010
enum class SmoothingMode { Exponential = 0, RateLimit = 1, ExpoThenRate = 2 };
11+
enum class ScaleCompMode { Additive = 0, Inverse = 1 };
1112

1213
// Slopes
1314
static inline std::atomic<bool> slopeEnabled{false};
@@ -47,6 +48,7 @@ struct Settings {
4748
static inline std::atomic<bool> scaleCompEnabled{false};
4849
static inline std::atomic<bool> scaleCompOnlyBelowOne{true}; // Only apply if player scale < 1.0
4950
static inline std::atomic<float> scaleCompPerUnitSM{120.0f};
51+
static inline ScaleCompMode scaleCompMode{ScaleCompMode::Additive};
5052

5153
static inline std::atomic<float> reduceOutOfCombat{45.0f};
5254
static inline std::atomic<float> reduceJoggingOutOfCombat{15.0f};
@@ -112,6 +114,16 @@ struct Settings {
112114
static inline std::atomic<float> magickaReducePct{15.0f};
113115
static inline std::atomic<float> magickaSmoothWidthPct{10.0f};
114116

117+
// DW (Dynamic Wetness) integration settings
118+
static inline std::atomic<bool> dwEnabled{true};
119+
120+
static inline std::atomic<bool> dwSlopeFeatureEnabled{false};
121+
static inline std::atomic<float> dwStartDeg{4.0f};
122+
static inline std::atomic<float> dwFullDeg{16.0f};
123+
124+
static inline std::atomic<float> dwBuildUpPerSec{0.35f};
125+
static inline std::atomic<float> dwDryPerSec{0.15f};
126+
115127
// Location stuff
116128
static bool ParseFormSpec(const std::string& spec, std::string& plugin, std::uint32_t& id);
117129

include/SpeedController.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,13 +60,21 @@ class SpeedController : public RE::BSTEventSink<RE::TESCombatEvent>,
6060
void ClearPathFor(RE::Actor* a);
6161
void PushPathSample(RE::Actor* a, const RE::NiPoint3& pos, uint64_t nowMs);
6262
bool ComputePathSlopeDeg(RE::Actor* a, float lookbackUnits, float maxAgeSec, float& outDeg);
63+
void ClearScaleDeltaFor(RE::Actor* a);
64+
bool UpdateScaleCompDelta(RE::Actor* a, float predictedNoScaleFinal);
65+
float& ScaleDeltaSlot(RE::Actor* a);
6366

6467
float diagResidualPlayer_ = 0.0f;
6568
std::unordered_map<std::uint32_t, float> diagResidualNPC_;
6669

6770
float slopeResidualPlayer_ = 0.0f;
6871
std::unordered_map<std::uint32_t, float> slopeResidualNPC_;
6972

73+
float scaleResidualPlayer_ = 0.0f;
74+
std::unordered_map<std::uint32_t, float> scaleResidualNPC_;
75+
float scaleDeltaPlayer_ = 0.0f;
76+
std::unordered_map<std::uint32_t, float> scaleDeltaNPC_;
77+
7078
inline float& DiagResidualSlot(RE::Actor* a) {
7179
auto* pc = RE::PlayerCharacter::GetSingleton();
7280
if (a == pc) return diagResidualPlayer_;
@@ -77,6 +85,11 @@ class SpeedController : public RE::BSTEventSink<RE::TESCombatEvent>,
7785
if (a == pc) return slopeResidualPlayer_;
7886
return slopeResidualNPC_[a->GetFormID()];
7987
}
88+
inline float& ScaleResidualSlot(RE::Actor* a) {
89+
auto* pc = RE::PlayerCharacter::GetSingleton();
90+
if (a == pc) return scaleResidualPlayer_;
91+
return scaleResidualNPC_[a->GetFormID()];
92+
}
8093

8194
private:
8295
enum class MoveCase : std::uint8_t { Combat, Drawn, Sneak, Default };
@@ -196,6 +209,7 @@ class SpeedController : public RE::BSTEventSink<RE::TESCombatEvent>,
196209
void LoadToggleBindingFromJson();
197210

198211
void StartHeartbeat();
212+
void StopHeartbeat();
199213
void TryInitDrawnFromGraph();
200214

201215
MoveCase ComputeCase(const RE::Actor* pc) const;

include/UI.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ namespace UI {
1313
void __stdcall RenderVitals();
1414
void __stdcall RenderLocations();
1515
void __stdcall RenderWeather();
16+
void __stdcall RenderAddons();
1617

1718
inline std::string saveIcon = FontAwesome::UnicodeToUtf8(0xf0c7) + " Save Settings";
1819

src/Settings.cpp

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,23 @@ bool Settings::SaveToJson(const std::filesystem::path& file) {
149149
j["kScaleCompEnabled"] = scaleCompEnabled.load();
150150
j["kScaleCompOnlyBelowOne"] = scaleCompOnlyBelowOne.load();
151151
j["kScaleCompPerUnitSM"] = scaleCompPerUnitSM.load();
152+
switch (scaleCompMode) {
153+
case ScaleCompMode::Inverse:
154+
j["kScaleCompMode"] = "Inverse";
155+
break;
156+
case ScaleCompMode::Additive:
157+
default:
158+
j["kScaleCompMode"] = "Additive";
159+
break;
160+
}
152161

162+
j["kDwEnabled"] = dwEnabled.load();
163+
j["kDwSlopeFeatureEnabled"] = dwSlopeFeatureEnabled.load();
164+
j["kDwStartDeg"] = dwStartDeg.load();
165+
j["kDwFullDeg"] = dwFullDeg.load();
166+
167+
j["kDwBuildUpPerSec"] = dwBuildUpPerSec.load();
168+
j["kDwDryPerSec"] = dwDryPerSec.load();
153169

154170
std::ofstream out(file);
155171
if (!out.is_open()) return false;
@@ -481,5 +497,39 @@ bool Settings::LoadFromJson(const std::filesystem::path& file) {
481497
scaleCompPerUnitSM = std::clamp(v, -300.0f, 300.0f);
482498
}
483499

500+
// DW (Dynamic Wetness) integration settings
501+
if (j.contains("kDwEnabled")) {
502+
dwEnabled = j["kDwEnabled"].get<bool>();
503+
}
504+
if (j.contains("kDwSlopeFeatureEnabled")) {
505+
dwSlopeFeatureEnabled = j["kDwSlopeFeatureEnabled"].get<bool>();
506+
}
507+
if (j.contains("kDwStartDeg")) {
508+
float v = j["kDwStartDeg"].get<float>();
509+
dwStartDeg = std::clamp(v, 0.0f, dwFullDeg.load());
510+
}
511+
if (j.contains("kDwFullDeg")) {
512+
float v = j["kDwFullDeg"].get<float>();
513+
dwFullDeg = std::clamp(v, dwStartDeg.load(), 90.0f);
514+
}
515+
if (j.contains("kDwBuildUpPerSec")) {
516+
float v = j["kDwBuildUpPerSec"].get<float>();
517+
dwBuildUpPerSec = std::clamp(v, 0.0f, 20.0f);
518+
}
519+
if (j.contains("kDwDryPerSec")) {
520+
float v = j["kDwDryPerSec"].get<float>();
521+
dwDryPerSec = std::clamp(v, 0.0f, 20.0f);
522+
}
523+
if (j.contains("kScaleCompMode")) {
524+
auto& m = j["kScaleCompMode"];
525+
if (m.is_string()) {
526+
std::string s = m.get<std::string>();
527+
std::transform(s.begin(), s.end(), s.begin(), ::tolower);
528+
scaleCompMode = (s == "inverse") ? ScaleCompMode::Inverse : ScaleCompMode::Additive;
529+
} else if (m.is_number_integer()) {
530+
int v = m.get<int>();
531+
scaleCompMode = (v == 1) ? ScaleCompMode::Inverse : ScaleCompMode::Additive;
532+
}
533+
}
484534
return true;
485535
}

0 commit comments

Comments
 (0)