From 73f4ed09ca2b13b18e1f62ba2ad5b15b380d6ca2 Mon Sep 17 00:00:00 2001 From: blevouschurverantunt <35274597+blevouschurverantunt@users.noreply.github.com> Date: Mon, 21 Sep 2026 15:37:25 -0500 Subject: [PATCH] Include trait demand in away assignment events Adds officer_traits, critical_trait_scores, success_chance, critical_success_chance, max_critical_success_chance, key_stat, max_assignable_officers and the attack/defense/health weights, all from the AwayAssignmentInstance the event already parses. On a fresh offer critical_trait_scores is [] and the chances are 0 until officers are assigned. The chance fields are in the de-dup hash, so an assignment re-emits when they change. Co-Authored-By: Claude Fable 5.1 --- mods/src/patches/parts/sync.cc | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/mods/src/patches/parts/sync.cc b/mods/src/patches/parts/sync.cc index 6a0221bfb..e09ca6d45 100644 --- a/mods/src/patches/parts/sync.cc +++ b/mods/src/patches/parts/sync.cc @@ -1119,6 +1119,21 @@ static void away_assignment_event(const Digit::PrimeServer::Models::AwayAssignme } } + auto officer_traits = json::array(); + for (const auto& trait : instance.officertraits()) { + officer_traits.push_back({{"tid", trait.traitid()}, {"max_level", trait.maxlevel()}}); + } + + // Same ordering concern as officer_ids: sort by trait id so the array and the de-dup hash are stable. + std::vector> critical_trait_pairs(instance.parameters().criticaltraitscores().begin(), + instance.parameters().criticaltraitscores().end()); + std::ranges::sort(critical_trait_pairs, {}, &std::pair::first); + + auto critical_trait_scores = json::array(); + for (const auto& [tid, score] : critical_trait_pairs) { + critical_trait_scores.push_back({{"tid", tid}, {"score", score}}); + } + json event = {{"type", SyncConfig::Type::AwayAssignments}, {"aid", instance.id()}, {"template_id", instance.awayassignmenttemplateid()}, @@ -1126,7 +1141,17 @@ static void away_assignment_event(const Digit::PrimeServer::Models::AwayAssignme {"officer_ids", officer_ids}, {"job_uuid", instance.jobuuid()}, {"duration", instance.parameters().duration()}, - {"rarity", instance.rarity()}}; + {"rarity", instance.rarity()}, + {"officer_traits", officer_traits}, + {"critical_trait_scores", critical_trait_scores}, + {"success_chance", instance.parameters().successchance()}, + {"critical_success_chance", instance.parameters().criticalsuccesschance()}, + {"max_critical_success_chance", instance.maxcriticalsuccesschance()}, + {"key_stat", instance.keystat()}, + {"max_assignable_officers", instance.maxassignableofficerscount()}, + {"attack_weight", instance.attackweight()}, + {"defense_weight", instance.defenseweight()}, + {"health_weight", instance.healthweight()}}; const auto state_value = std::hash{}(event);