diff --git a/Odyssey/Patches/Odyssey/PawnkindDefs/PawnKinds_Odyssey.xml b/Odyssey/Patches/Odyssey/PawnkindDefs/PawnKinds_Odyssey.xml
index 9e4eb44d41..3c0649fc4d 100644
--- a/Odyssey/Patches/Odyssey/PawnkindDefs/PawnKinds_Odyssey.xml
+++ b/Odyssey/Patches/Odyssey/PawnkindDefs/PawnKinds_Odyssey.xml
@@ -76,6 +76,16 @@
+
+ Defs/PawnKindDef[defName="AncientSoldier_Leader"]
+
+
+ CE_Apparel_TacVest
+ CE_Apparel_Backpack
+
+
+
+
@@ -135,7 +145,7 @@
1
3
-
+
@@ -225,10 +235,10 @@
1
3
-
+
-
+
\ No newline at end of file
diff --git a/Source/CombatExtended/Harmony/Harmony_CompUniqueWeapon.cs b/Source/CombatExtended/Harmony/Harmony_CompUniqueWeapon.cs
index 2feca1d366..977d56aac8 100644
--- a/Source/CombatExtended/Harmony/Harmony_CompUniqueWeapon.cs
+++ b/Source/CombatExtended/Harmony/Harmony_CompUniqueWeapon.cs
@@ -12,6 +12,14 @@ internal static class CompUniqueWeapon_Setup
{
internal static void Postfix(CompUniqueWeapon __instance, bool fromSave)
{
+ // Unique Weapon Spawns before pawn is spawned,
+ // Not doing it on save load, we are not in the business of topping off the player's mags.
+ CompAmmoUser compAmmo = __instance.parent.TryGetComp();
+ if (!fromSave && compAmmo != null && compAmmo.UseAmmo)
+ {
+ compAmmo.ResetAmmoCount();
+ }
+
CompUnderBarrel compUnderBarrel = __instance.parent.TryGetComp();
bool underBarrelApplied = false;
bool verbOverrideApplied = false;
diff --git a/Source/CombatExtended/Harmony/Harmony_QuestNode_Root_AncientMercenaries.cs b/Source/CombatExtended/Harmony/Harmony_QuestNode_Root_AncientMercenaries.cs
new file mode 100644
index 0000000000..d674cf9741
--- /dev/null
+++ b/Source/CombatExtended/Harmony/Harmony_QuestNode_Root_AncientMercenaries.cs
@@ -0,0 +1,93 @@
+using System;
+using System.Linq;
+using HarmonyLib;
+using RimWorld;
+using RimWorld.QuestGen;
+using UnityEngine;
+using Verse;
+
+namespace CombatExtended.HarmonyCE;
+
+// Boss gets his unique gun after loadout gen already ran, so hand him spare mags here. Read the
+// weapon off the slate, not equipment.Primary - the quest nukes his gear and he grabs a sidearm.
+[HarmonyPatch(typeof(QuestNode_Root_AncientMercenaries), "RunInt")]
+internal static class QuestNode_Root_AncientMercenaries_RunInt
+{
+ private static readonly IntRange MagazineCount = new IntRange(3, 5);
+
+ internal static void Postfix()
+ {
+ try
+ {
+ Pawn pawn = QuestGen.slate.Get("LEADER");
+ ThingWithComps weapon = QuestGen.slate.Get("WEAPON") ?? (pawn.equipment?.Primary as ThingWithComps);
+ CompAmmoUser compAmmo = weapon?.TryGetComp();
+ CompInventory inventory = pawn?.TryGetComp();
+ if (pawn == null || weapon == null || compAmmo == null || !compAmmo.UseAmmo || inventory == null || pawn.inventory == null)
+ {
+ return;
+ }
+
+ AmmoDef ammo = PickAmmo(compAmmo);
+ if (ammo == null)
+ {
+ return;
+ }
+
+ compAmmo.ResetAmmoCount(ammo);
+
+ int unit = Mathf.Max(1, compAmmo.MagSizeOverride > 0 ? compAmmo.MagSizeOverride : compAmmo.MagSize);
+
+ // drop the old weapon's mags (dead weight, eats his carry cap) before handing out new ones
+ foreach (Thing dead in inventory.container.Where(t => t.def is AmmoDef && t.def != ammo).ToList())
+ {
+ inventory.container.Remove(dead);
+ if (!dead.Destroyed)
+ {
+ dead.Destroy(DestroyMode.Vanish);
+ }
+ }
+ inventory.UpdateInventory();
+
+ Thing mags = ThingMaker.MakeThing(ammo);
+ mags.stackCount = MagazineCount.RandomInRange * unit;
+ if (inventory.CanFitInInventory(mags, out int maxCount))
+ {
+ if (maxCount < mags.stackCount)
+ {
+ mags.stackCount = maxCount - (maxCount % unit);
+ }
+ if (mags.stackCount > 0)
+ {
+ inventory.container.TryAdd(mags);
+ }
+ }
+ else
+ {
+ Log.Warning($"[CE] Ancient mercenaries leader: no room for {ammo.defName} mags.");
+ }
+ inventory.UpdateInventory();
+ }
+ catch (Exception ex)
+ {
+ Log.Error($"[CE] Ancient mercenaries leader ammo gen failed: {ex}");
+ }
+ }
+
+ private static AmmoDef PickAmmo(CompAmmoUser compAmmo)
+ {
+ if (compAmmo.Props?.ammoSet == null)
+ {
+ return null;
+ }
+ var links = compAmmo.Props.ammoSet.ammoTypes;
+ var avail = links.Where(a => a.ammo != null && a.ammo.alwaysHaulable && !a.ammo.menuHidden && a.ammo.generateAllowChance > 0f)
+ .Select(a => a.ammo)
+ .ToList();
+ if (avail.Count == 0)
+ {
+ avail = links.Where(a => a.ammo != null).Select(a => a.ammo).ToList();
+ }
+ return avail.Count > 0 ? avail.RandomElement() : null;
+ }
+}