// Used to automatically re-arm turrets static void Postfix(WorkGiver_ReloadTurret __instance, ref Job __result, Pawn pawn, Thing t, bool forced) { if (__result == null) { if (t is Building_TurretGunCE turret) { if (WorldComp.HasStorages(turret.Map) && CombatExtendedUtil.HasAmmo(turret.CompAmmo.SelectedAmmo)) { var storage = GenClosest.ClosestThingReachable( turret.Position, turret.Map, ThingRequest.ForDef(WorldComp.WeaponStorageDef), Verse.AI.PathEndMode.ClosestTouch, TraverseParms.For(pawn, pawn.NormalMaxDanger(), TraverseMode.ByPawn, false), 100); if (storage != null) { // TODO - Add setting where ammo should be dropped //CombatExtendedUtil.TryDropAmmo(turret.CompAmmo.SelectedAmmo, turret.CompAmmo.Props.magazineSize, storage.Position, storage.Map); __result = new Job( DefDatabase <JobDef> .GetNamed("ReloadTurret", true), t, new StoredAmmo( Patch_WorkGiver_ReloadTurret_HasJobOnThing.WS, turret.CompAmmo.SelectedAmmo, turret.CompAmmo.Props.magazineSize, forced)); } } } } }
static void Postfix(CompAmmoUser __instance, ref bool __result) { if (__result == false && (__instance.Wielder != null || __instance.turret != null)) { if (!__instance.HasMagazine && __instance.UseAmmo) { var def = __instance.GetType().GetField("selectedAmmo", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(__instance) as ThingDef; if (CombatExtendedUtil.TryRemoveAmmo(def, 1)) { //__instance.GetType().GetField("currentAmmoInt", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(__instance, ammo.def as AmmoDef); //__instance.Props.ammoSet __result = true; } } var ammoTypes = __instance.Props?.ammoSet?.ammoTypes; if (ammoTypes != null) { foreach (var t in ammoTypes) { if (CombatExtendedUtil.HasAmmo(t.projectile)) { __result = true; } } } } }
static void Prefix(Building_TurretGunCE __instance) { if (__instance.GetType().GetField("mannableComp", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(__instance) is CompMannable mannable && __instance.CompAmmo.UseAmmo) { CompInventory inv = ThingCompUtility.TryGetComp <CompInventory>(mannable.ManningPawn); if (mannable.ManningPawn.IsColonist && inv != null) { Thing thing = inv.container.FirstOrDefault((Thing x) => x.def == __instance.CompAmmo.SelectedAmmo); if (thing == null) { AmmoDef ammoDef = __instance.CompAmmo.SelectedAmmo; if (ammoDef != null && CombatExtendedUtil.HasAmmo(ammoDef)) { int magazineSize = __instance.CompAmmo.Props.magazineSize; if (CombatExtendedUtil.TryRemoveAmmo(ammoDef, magazineSize, out Thing ammo)) { inv.UpdateInventory(); if (!inv.container.TryAdd(ammo as ThingWithComps)) { Log.Error("Failed to add ammo to pawn inventory"); CombatExtendedUtil.AddAmmo(ammo); } } } } } } }
static void Postfix(Command_Reload __instance, ref FloatMenu __result) { if (__instance.compAmmo.turret == null) { List <FloatMenuOption> options = __result.GetType().GetField("options", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(__result) as List <FloatMenuOption>; List <AmmoDef> list = new List <AmmoDef>(); foreach (AmmoLink curLink in __instance.compAmmo.Props.ammoSet.ammoTypes) { if (CombatExtendedUtil.HasAmmo(curLink.ammo)) { bool containsLabelCap = false; foreach (var o in options) { if (o.Label.Equals(curLink.ammo.ammoClass.LabelCap)) { containsLabelCap = true; break; } } if (!containsLabelCap) { options.Insert(0, new FloatMenuOption( curLink.ammo.ammoClass.LabelCap, delegate { if (__instance.compAmmo.SelectedAmmo != curLink.ammo || __instance.compAmmo.CurMagCount < __instance.compAmmo.Props.magazineSize) { __instance.compAmmo.SelectedAmmo = curLink.ammo; Building_TurretGunCE turret = __instance.compAmmo.turret; if (turret == null || turret.MannableComp == null) { if (CombatExtendedUtil.TryRemoveAmmo(curLink.ammo, __instance.compAmmo.Props.magazineSize, out Thing ammo)) { __instance.compAmmo.TryUnload(); if (!__instance.compAmmo.CompInventory.container.TryAdd(ammo as ThingWithComps)) { Log.Error("Failed to reload ammo"); CombatExtendedUtil.AddAmmo(ammo); } __instance.compAmmo.CompInventory.UpdateInventory(); if (turret != null) { __instance.compAmmo.turret.TryOrderReload(); } else { __instance.compAmmo.TryStartReload(); } } } } }, MenuOptionPriority.Default, null, null, 0f, null, null));
private void RebuildItems() { ammo.Clear(); foreach (ThingDefCount tc in CombatExtendedUtil.GetThingCounts()) { ammo.Add(tc); } /*bool hasCount = false; * general.Clear(); * neolithic.Clear(); * grenades.Clear(); * rockets.Clear(); * shotguns.Clear(); * advanced.Clear(); * foreach (ThingDefCount tc in CombatExtendedUtil.GetThingCounts()) * { * if (tc.Count > 0) * { * hasCount = true; * * string name = tc.ThingDef.GetType().GetField("ammoClass", BindingFlags.Instance | BindingFlags.Public).GetValue(tc.ThingDef).ToString(); * if (name.StartsWith("Rocket")) * this.rockets.Add(tc); * else if (name.StartsWith("Grenade")) * this.grenades.Add(tc); * else if (name.EndsWith("Shot") || * name.EndsWith("Slug") || * name.Equals("Beanbag")) * this.shotguns.Add(tc); * else if (name.Equals("Javelin") || * name.EndsWith("Arrow") || * name.EndsWith("SlingBullet") || * name.EndsWith("CrossbowBolt")) * this.neolithic.Add(tc); * else if (name.StartsWith("Charged") || * name.Equals("Ionized") || * name.Equals("IncendiaryFuel") || * name.Equals("ThermobaricFuel") || * name.Equals("FoamFuel") || * name.Equals("Antigrain") || * name.Equals("RadiationIonising")) * this.advanced.Add(tc); * else * this.general.Add(tc); * } * } * * if (!hasCount) * { * this.selectedTab = Tabs.Empty; * }*/ }
// used to manually re-arm turrets static void Postfix(WorkGiver_ReloadTurret __instance, ref bool __result, Pawn pawn, Thing t, bool forced) { Building_TurretGunCE turret = t as Building_TurretGunCE; if (__result == false && turret != null && !turret.def.hasInteractionCell) { if (WorldComp.HasStorages(turret.Map) && CombatExtendedUtil.HasAmmo(turret.CompAmmo.SelectedAmmo)) { WS = GenClosest.ClosestThingReachable(turret.Position, turret.Map, ThingRequest.ForDef(WorldComp.WeaponStorageDef), Verse.AI.PathEndMode.ClosestTouch, TraverseParms.For(pawn, pawn.NormalMaxDanger(), TraverseMode.ByPawn, false), 100) as Building; __result = WS != null; } } }
static void Prefix(CompAmmoUser __instance) { if (__instance.turret == null && __instance.Wielder != null && __instance.HasMagazine) { AmmoDef ammoDef = __instance.SelectedAmmo;//__instance.GetType().GetProperty("CurrentAmmo", BindingFlags.Instance | BindingFlags.Public).GetValue(__instance, null) as Def; if (ammoDef != null && CombatExtendedUtil.HasAmmo(ammoDef)) { if (!__instance.TryFindAmmoInInventory(out Thing ammo)) { int magazineSize = __instance.Props.magazineSize; if (CombatExtendedUtil.TryRemoveAmmo(ammoDef, magazineSize, out ammo)) { __instance.CompInventory.ammoList.Add(ammo as ThingWithComps); } } } } }
static void Prefix(Pawn_JobTracker __instance, Job newJob, JobCondition lastJobEndCondition, ThinkNode jobGiver, bool resumeCurJobAfterwards, bool cancelBusyStances, ThinkTreeDef thinkTree, JobTag?tag, bool fromQueue) { if (newJob != null && newJob.targetB != null && newJob.targetB.Thing is StoredAmmo sa) { Pawn pawn = __instance.GetType().GetField("pawn", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(__instance) as Pawn; Building_TurretGunCE turret = newJob.targetA.Thing as Building_TurretGunCE; FieldInfo fi = sa.root.GetType().GetField("AllowAdds", BindingFlags.Instance | BindingFlags.Public); try { fi.SetValue(sa.root, false); IntVec3 pos; Building building = sa.root as Building; if (sa.forced || sa.root == null) { pos = pawn.Position; } else { pos = building.InteractionCell; } if (!CombatExtendedUtil.TryDropAmmo(sa.ammoDef, sa.ammoCount, pos, sa.root.Map, out Thing t)) { Log.Error("Could not get ammo"); } else { newJob.targetB = t; newJob.count = t.stackCount; } } finally { fi.SetValue(sa.root, true); } } }
public override void DoWindowContents(Rect inRect) { #if TRACE ++i; #endif GUI.color = Color.white; Text.Font = GameFont.Small; try { float y = 0; Widgets.Label(new Rect(0, y, 100, 30), "WeaponStorage.ManageAmmo".Translate()); y += 32; Widgets.Label(new Rect(0, y + 4, 70, 30), "WeaponStorage.Search".Translate()); string original = searchText; this.searchText = Widgets.TextField(new Rect(75, y, 150, 30), this.searchText); if (!this.searchText.Equals(original)) { this.performSearch = true; } y += 44; List <ThingDefCount> toShow = this.GetThingsToShow(); if (toShow == null || toShow.Count == 0) { string text = "No ammo in storage"; if (this.searchText.Length > 0) { text = "No matches found"; } Widgets.Label(new Rect(40, y, 200, 30), text); } else { /*if (this.searchText.Length == 0) * { * y += 32; * TabDrawer.DrawTabs(new Rect(0, y, inRect.width, inRect.height - y), this.tabs); * y += 20; * }*/ Widgets.BeginScrollView( new Rect(40, y, inRect.width - 80, inRect.height - y - 50), ref this.scrollPosition, new Rect(0, 0, inRect.width - 96, this.PreviousY)); this.PreviousY = 0f; foreach (var tc in toShow) { ThingDef def = tc.ThingDef; Widgets.ThingIcon(new Rect(0f, this.PreviousY, 30, 30), def); if (Widgets.InfoCardButton(40, this.PreviousY, def)) { Find.WindowStack.Add(new Dialog_InfoCard(def)); } Widgets.Label(new Rect(70, this.PreviousY, 250, 30), def.label); Widgets.Label(new Rect(340, this.PreviousY, 40, 30), tc.Count.ToString()); if (Widgets.ButtonImage(new Rect(inRect.width - 100, this.PreviousY, 20, 20), AssignUI.DropTexture)) { CombatExtendedUtil.DropAmmo(def, this.weaponStorage); RebuildItems(); this.performSearch = true; break; } this.PreviousY += 32; } Widgets.EndScrollView(); } } catch (Exception e) { String msg = this.GetType().Name + " closed due to: " + e.GetType().Name + " " + e.Message; Log.Error(msg); Messages.Message(msg, MessageTypeDefOf.NegativeEvent); base.Close(); } finally { Text.Anchor = TextAnchor.UpperLeft; GUI.color = Color.white; } }
//public static Type AmmoDef { get; private set; } static HarmonyPatches_CombatExtended() { CombatExtendedAssembly = null; bool wsFound = false, ceFound = false; CombatExtendedUtil.SetHasCombatExtended(false); var mods = new List <ModMetaData>(ModsConfig.ActiveModsInLoadOrder); for (int i = 0; i < mods.Count; ++i) { if (mods[i].Name.StartsWith("[KV] Weapon Storage")) { wsFound = true; if (ceFound) { break; } } else if (mods[i].Name.Equals("Combat Extended")) { ceFound = true; if (wsFound) { Log.Error("Weapon Storage must be loaded after Combat Extended."); return; } } } if (ceFound) { try { bool found = false; foreach (ModContentPack pack in LoadedModManager.RunningMods) { foreach (Assembly assembly in pack.assemblies.loadedAssemblies) { if (assembly.GetName().Name.Equals("CombatExtended")) { /*AmmoDef = assembly.GetType("CombatExtended.AmmoDef"); * if (AmmoDef == null) * throw new Exception("Unable to find CombatExtended.AmmoDef");*/ /*compAmmoUser = assembly.GetType("CombatExtended.CompAmmoUser"); * if (compAmmoUser == null) * throw new Exception("Unable to find CombatExtended.CompAmmoUser");*/ CombatExtendedAssembly = assembly; found = true; break; } } if (found) { break; } } var harmony = HarmonyInstance.Create("com.combatextendedweaponstoragepatch.rimworld.mod"); harmony.PatchAll(Assembly.GetExecutingAssembly()); CombatExtendedUtil.SetHasCombatExtended(true); } catch (Exception e) { Log.Error("Failed to patch \"Combat Extended\"." + Environment.NewLine + e.Message); } } else { Log.Message("Weapon Storage \"Combat Extended\" Patch did not find \"Combat Extended\". Will not load patch."); } }