public static void UnequipPrimaryWeapon(Pawn pawn, AssignedWeaponContainer c) { ThingWithComps weapon = pawn?.equipment?.Primary; if (weapon == null) { return; } pawn.equipment.Remove(weapon); if (c != null && c.Contains(weapon)) { c.Add(weapon); return; } if (WorldComp.Add(weapon)) { return; } if (!BuildingUtil.DropSingleThing(weapon, pawn.Position, pawn.Map, false)) { Log.Warning("Failed to drop " + pawn.Name.ToStringShort + "'s primary weapon [" + pawn.equipment.Primary.Label + "]."); } }
static void Postfix(Pawn_MeleeVerbs __instance, Thing target) { if (Settings.AutoSwitchMelee == false) { return; } Pawn pawn = __instance.Pawn; if (pawn != null && WorldComp.TryGetAssignedWeapons(pawn, out AssignedWeaponContainer c)) { Verb attackVerb = pawn.TryGetAttackVerb(target, !pawn.IsColonist); if (attackVerb != null && attackVerb.verbProps.IsMeleeAttack) { float blunt = target.GetStatValue(StatDefOf.ArmorRating_Blunt); float sharp = target.GetStatValue(StatDefOf.ArmorRating_Sharp); DamageType dt = (blunt > sharp) ? DamageType.Sharp : DamageType.Blunt; if (blunt == sharp) { if (Settings.PreferredDamageType == PreferredDamageTypeEnum.WeaponStorage_None) { return; } dt = (Settings.PreferredDamageType == PreferredDamageTypeEnum.ArmorBlunt) ? DamageType.Blunt : DamageType.Sharp; } if (TryGetBestWeapon(dt, pawn.equipment.Primary, c, out ThingWithComps bestWeapon)) { HarmonyPatchUtil.EquipWeapon(bestWeapon, pawn, c); } } } }
static void Postfix(Lord lord) { foreach (Building_WeaponStorage s in WorldComp.GetWeaponStorages(lord.Map)) { s.ReclaimWeapons(); } }
public static void EquipWeapon(ThingWithComps weapon, Pawn pawn) { if (WorldComp.TryGetAssignedWeapons(pawn, out AssignedWeaponContainer c)) { EquipWeapon(weapon, pawn, c); } }
public void UpdateFoundDefCache() { long now = DateTime.Now.Ticks; if (now - this.lastCacheUpdate > TimeSpan.TicksPerSecond) { this.lastCacheUpdate = now; this.foundDefCache.Clear(); foreach (ThingDef def in this.AllowedDefs) { if (CombatExtendedUtil.GetAmmoCount(def) > 0) { this.foundDefCache.Add(def); continue; } foreach (Building_WeaponStorage s in WorldComp.GetWeaponStorages(null)) { if (s.HasWeapon(this, def)) { this.foundDefCache.Add(def); break; } } } } }
static void Postfix(ref bool __result, ref Pawn __state, ThingWithComps eq) { if (__state != null) { if (WorldComp.TryGetAssignedWeapons(__state, out AssignedWeaponContainer c) && c.Contains(eq)) { if (!Settings.AllowPawnsToDropWeapon) { if (!WorldComp.Add(eq)) { Log.Warning($"unable to find weapon storage that can hold {eq.ThingID} so it will be dropped."); WorldComp.Drop(eq); } } else { if (c.Remove(eq)) { if (eq.def.IsRangedWeapon) { if (!HarmonyPatchUtil.EquipRanged(c)) { HarmonyPatchUtil.EquipMelee(c); } } else { if (!HarmonyPatchUtil.EquipMelee(c)) { HarmonyPatchUtil.EquipRanged(c); } } } if (Settings.PlaceDroppedWeaponsInStorage) { if (!WorldComp.Add(eq)) { Log.Warning($"unable to find weapon storage that can hold {eq.ThingID} so it will be dropped."); WorldComp.Drop(eq); } } } } else { foreach (SharedWeaponFilter swf in WorldComp.SharedWeaponFilter) { if (swf.Allows(eq) && !WorldComp.Add(eq)) { Log.Warning($"unable to find weapon storage that can hold {eq.ThingID} so it will be dropped."); WorldComp.Drop(eq); break; } } } } }
static void Prefix(Verb_ShootOneUse __instance) { if (__instance.caster is Pawn pawn && WorldComp.TryGetAssignedWeapons(pawn, out AssignedWeaponContainer c)) { c.Remove(__instance.EquipmentSource); } }
static void Postfix(Pawn_EquipmentTracker __instance, ThingWithComps newEq) { if (__instance.pawn.Faction == Faction.OfPlayerSilentFail && WorldComp.HasStorages() && WorldComp.CreateOrGetAssignedWeapons(__instance.pawn, out AssignedWeaponContainer aw)) { aw.Add(newEq); } }
public static void ReclaimWeapons() { foreach (Building_WeaponStorage ws in WorldComp.GetWeaponStorages(null)) { if (ws.Map != null && ws.Spawned) { ws.ReclaimWeapons(); } } }
static void Postfix(WealthWatcher __instance) { Map map = (Map)__instance.GetType().GetField("map", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(__instance); FieldInfo wealthItemsFI = __instance.GetType().GetField("wealthItems", BindingFlags.NonPublic | BindingFlags.Instance); float wealthItems = (float)wealthItemsFI.GetValue(__instance); wealthItems = TallyWealth(WorldComp.GetWeaponStorages(map), wealthItems); wealthItemsFI.SetValue(__instance, wealthItems); }
static void Postfix(Pawn_DraftController __instance) { Pawn pawn = __instance.pawn; if (WorldComp.TryGetAssignedWeapons(pawn, out AssignedWeaponContainer weapons) && weapons.TryGetLastThingUsed(pawn, out ThingWithComps w)) { HarmonyPatchUtil.EquipWeapon(w, pawn, weapons); } }
static void Prefix(Pawn_EquipmentTracker __instance, ThingWithComps eq) { if (eq.def.equipmentType == EquipmentType.Primary && __instance.Primary != null) { if (WorldComp.TryGetAssignedWeapons(__instance.pawn, out AssignedWeaponContainer c) && c.Contains(eq)) { __instance.Remove(eq); } } }
static void Prefix(IEnumerable <Pawn> pawns, Faction faction, int exitFromTile, int directionTile, int destinationTile, bool sendMessage) { if (faction == Faction.OfPlayer) { List <Pawn> p = new List <Pawn>(pawns); if (p.Count > 0) { foreach (Building_WeaponStorage s in WorldComp.GetWeaponStorages(null)) { s.ReclaimWeapons(); } } } }
static void Prefix(Window __instance) { Type type = __instance.GetType(); if (type == typeof(Dialog_FormCaravan)) { Map map = __instance.GetType().GetField("map", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(__instance) as Map; foreach (Building_WeaponStorage s in WorldComp.GetWeaponStorages(map)) { s.Empty(); } } }
static void Prefix(Pawn_HealthTracker __instance, ref ThingWithComps __state) { if (Settings.EnableAssignWeapons && pawnFI.GetValue(__instance) is Pawn pawn && !__instance.Downed && pawn.IsColonist && pawn.equipment?.Primary != null) { if (WorldComp.TryGetAssignedWeapons(pawn, out AssignedWeaponContainer c)) { HarmonyPatchUtil.UnequipPrimaryWeapon(pawn, c); } } }
public static IEnumerable <Thing> EmptyWeaponStorages(Map map) { List <Thing> l = new List <Thing>(); foreach (Building_WeaponStorage ws in WorldComp.GetWeaponStorages(map)) { if (ws.Map == map && ws.Spawned && ws.IncludeInTradeDeals) { foreach (ThingWithComps t in ws.GetWeapons(true)) { l.Add(t); } ws.Empty(); } } return(l); }
static void Postfix(Pawn pawn, List <FloatMenuOption> opts) { if (!Settings.AllowPawnsToDropWeapon && pawn.Faction.IsPlayer && pawn.RaceProps.Humanlike && WorldComp.CanAdd(pawn.equipment?.Primary)) { var lookingFor = "Drop".Translate(pawn.equipment.Primary.Label, pawn.equipment.Primary); for (int i = 0; i < opts.Count; ++i) { if (opts[i].Label == lookingFor) { opts.RemoveAt(i); return; } } } }
private void Dispose() { try { if (this.StoredWeapons != null) { foreach (LinkedList <ThingWithComps> l in this.StoredWeapons.Values) { foreach (ThingWithComps t in l) { this.DropThing(t); } } this.StoredWeapons.Clear(); } if (this.StoredBioEncodedWeapons != null) { foreach (LinkedList <ThingWithComps> l in this.StoredBioEncodedWeapons.Values) { foreach (ThingWithComps t in l) { this.DropThing(t); } } this.StoredBioEncodedWeapons.Clear(); } } catch (Exception e) { Log.Error( this.GetType().Name + ".Dispose\n" + e.GetType().Name + " " + e.Message + "\n" + e.StackTrace); } WorldComp.Remove(this); foreach (Building_RepairWeaponStorage r in BuildingUtil.FindThingsOfTypeNextTo <Building_RepairWeaponStorage>(base.Map, base.Position, Settings.RepairAttachmentDistance)) { #if DEBUG_REPAIR Log.Warning("Removing Dresser " + this.Label + " to " + r.Label); #endif r.Remove(this); } }
public override void Notify_ReceivedThing(Thing newItem) { if (!this.AllowAdds) { if (!newItem.Spawned) { DropThing(newItem); } return; } if (!((newItem is ThingWithComps) && ((ThingWithComps)newItem).def.IsWeapon) && !CombatExtendedUtil.IsAmmo(newItem)) { if (!newItem.Spawned) { DropThing(newItem); } return; } base.Notify_ReceivedThing(newItem); if (!CombatExtendedUtil.AddAmmo(newItem)) { if (newItem is ThingWithComps && !this.Contains((ThingWithComps)newItem)) { // Must go after 'contains' check. In the case of 'drop on floor' Notify_ReceiveThing gets called before the weapon is removed from the list if (newItem.Spawned) { newItem.DeSpawn(); } if (!this.AddWeapon(newItem as ThingWithComps) && !WorldComp.Add(newItem as ThingWithComps)) { BuildingUtil.DropThing(newItem, this, this.CurrentMap, true); } } } }
static void Postfix(ref int __result, RecipeWorkerCounter __instance, Bill_Production bill) { List <ThingDefCountClass> products = __instance.recipe.products; var storages = WorldComp.GetWeaponStorages(bill?.Map); if (storages.Count() > 0 && products != null) { foreach (ThingDefCountClass product in products) { ThingDef def = product.thingDef; if (def.IsWeapon) { foreach (Building_WeaponStorage ws in WorldComp.GetWeaponStorages(bill.Map)) { __result += ws.GetWeaponCount(def, bill.qualityRange, bill.hpRange, (bill.limitToAllowedStuff) ? bill.ingredientFilter : null); } } } } }
public void UpdateDefCache(ThingDef def) { if (this.AllowedDefs.Contains(def)) { if (CombatExtendedUtil.GetAmmoCount(def) > 0) { this.foundDefCache.Add(def); return; } foreach (Building_WeaponStorage s in WorldComp.GetWeaponStorages(null)) { if (s.HasWeapon(this, def)) { this.foundDefCache.Add(def); return; } } } this.foundDefCache.Remove(def); }
static void Prefix() { try { foreach (Building_WeaponStorage s in WorldComp.GetWeaponStorages(null)) { try { s.ReclaimWeapons(true); } catch (Exception e) { Log.Warning("Error while reclaiming weapon for storage\n" + e.Message); } } } catch (Exception e) { Log.Warning("Error while reclaiming weapons\n" + e.Message); } }
private void CullStorage(List <ThingWithComps> removed, LinkedList <ThingWithComps> l) { LinkedListNode <ThingWithComps> n = l.First; while (n != null) { var next = n.Next; if (!this.CanAdd(n.Value)) { removed.Add(n.Value); l.Remove(n); } n = next; } foreach (ThingWithComps t in removed) { if (!WorldComp.Add(t)) { this.DropThing(t); } } }
static void Postfix(Pawn __instance, ref State __state) { if (__instance.Dead && __instance.IsColonist && __instance.apparel?.LockedApparel?.Count == 0 && __state.Weapon != null) { if (WorldComp.Add(__state.Weapon)) { __instance.equipment?.Remove(__state.Weapon); } if (WorldComp.TryGetAssignedWeapons(__instance, out AssignedWeaponContainer c)) { WorldComp.RemoveAssignedWeapons(__instance); foreach (ThingWithComps w in c.Weapons) { if (!WorldComp.Add(w)) { BuildingUtil.DropSingleThing(w, __instance.Position, __state.Map); } } } } }
public override void SpawnSetup(Map map, bool respawningAfterLoad) { base.SpawnSetup(map, respawningAfterLoad); this.CurrentMap = map; if (settings == null) { base.settings = new StorageSettings(this); base.settings.CopyFrom(this.def.building.defaultStorageSettings); base.settings.filter.SetDisallowAll(); } this.UpdatePreviousStorageFilter(); WorldComp.Add(this); foreach (Building_RepairWeaponStorage r in BuildingUtil.FindThingsOfTypeNextTo <Building_RepairWeaponStorage>(base.Map, base.Position, Settings.RepairAttachmentDistance)) { #if DEBUG_REPAIR Log.Warning("Adding Dresser " + this.Label + " to " + r.Label); #endif r.Add(this); } WorldComp.InitializeAssignedWeapons(); }
static void Prefix(Pawn_HealthTracker __instance) { if (!Settings.EnableAssignWeapons) { return; } Pawn pawn = (Pawn)__instance.GetType().GetField( "pawn", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(__instance); if (pawn != null && pawn.Faction == Faction.OfPlayer && pawn.def.race.Humanlike) { if (WorldComp.TryGetAssignedWeapons(pawn, out AssignedWeaponContainer c) && pawn.equipment?.Primary == null) { if (c.TryGetLastThingUsed(pawn, out ThingWithComps w)) { HarmonyPatchUtil.EquipWeapon(w, pawn, c); } } } }
static void Postfix(Pawn_DraftController __instance, ref IEnumerable <Gizmo> __result) { try { Pawn pawn = __instance.pawn; if (pawn.Faction == Faction.OfPlayer) { List <Gizmo> l = null; if (Settings.ShowWeaponStorageButtonForPawns && WorldComp.HasStorages()) { l = new List <Gizmo>() { new Command_Action { icon = AssignUI.weaponStorageTexture, defaultLabel = "WeaponStorage.UseWeaponStorage".Translate(), activateSound = SoundDef.Named("Click"), action = delegate { Find.WindowStack.Add(new AssignUI(null, pawn)); } } }; l.AddRange(__result); } if (WorldComp.TryGetAssignedWeapons(__instance.pawn, out AssignedWeaponContainer weapons)) { if (l == null) { l = new List <Gizmo>(); l.AddRange(__result); } //if (pawn.equipment.Primary != null) // l.Add(CreateUnequipGizmo(pawn, weapons)); foreach (ThingWithComps weapon in weapons.Weapons) { bool isTool = Settings.IsTool(weapon); bool show = false; if (pawn.Drafted) { show = true; } else // Not drafted { if (isTool || Settings.ShowWeaponsWhenNotDrafted) { show = true; } } if (show) { show = pawn.equipment.Primary != weapon; } if (show) { l.Add(CreateEquipWeaponGizmo(weapon.def, pawn, delegate { HarmonyPatchUtil.EquipWeapon(weapon, pawn, weapons); weapons.SetLastThingUsed(pawn, weapon, false); })); } } } foreach (SharedWeaponFilter f in WorldComp.SharedWeaponFilter) { if (l == null) { l = new List <Gizmo>(); l.AddRange(__result); } f.UpdateFoundDefCache(); if (f.AssignedPawns.Contains(pawn)) { if (l == null) { l = new List <Gizmo>(); if (__result != null) { l.AddRange(__result); } } foreach (ThingDef d in f.AllowedDefs) { if (d != pawn.equipment.Primary?.def && f.FoundDefCacheContains(d)) { l.Add(CreateEquipWeaponGizmo(d, pawn, delegate { if (WorldComp.TryRemoveWeapon(d, f, false, out ThingWithComps weapon)) { HarmonyPatchUtil.EquipWeapon(weapon, pawn); f.UpdateDefCache(d); } }, "WeaponStorage.EquipShared")); }
static void Prefix(MapParent settlement) { WorldComp.Remove(settlement.Map); }
static void Postfix(ref bool __result, Bill bill, Pawn pawn, Thing billGiver, List <ThingCount> chosen) { if (bill.Map == null) { Log.Error("Bill's map is null"); return; } if (__result == true || !WorldComp.HasStorages(bill.Map) || bill.Map != pawn.Map) { return; } #if DEBUG || DROP_DEBUG || BILL_DEBUG Log.Warning("TryFindBestBillIngredients.Postfix __result: " + __result); #endif Dictionary <ThingDef, int> chosenAmounts = new Dictionary <ThingDef, int>(); foreach (ThingCount c in chosen) { int count; if (chosenAmounts.TryGetValue(c.Thing.def, out count)) { count += c.Count; } else { count = c.Count; } chosenAmounts[c.Thing.def] = count; } #if DEBUG || DROP_DEBUG || BILL_DEBUG Log.Warning(" ChosenAmounts:"); //foreach (KeyValuePair<ThingLookup, int> kv in chosenAmounts) { // Log.Warning(" " + kv.Key.Def.label + " - " + kv.Value); } #endif LinkedList <NeededIngrediants> neededIngs = new LinkedList <NeededIngrediants>(); foreach (IngredientCount ing in bill.recipe.ingredients) { bool found = false; foreach (KeyValuePair <ThingDef, int> kv in chosenAmounts) { if ((int)ing.GetBaseCount() == kv.Value) { #if DEBUG || DROP_DEBUG || BILL_DEBUG Log.Warning(" Needed Ing population count is the same"); #endif if (ing.filter.Allows(kv.Key)) { #if DEBUG || DROP_DEBUG || BILL_DEBUG Log.Warning(" Needed Ing population found: " + kv.Key.label + " count: " + kv.Value); #endif found = true; break; } } } if (!found) { #if DEBUG || DROP_DEBUG || BILL_DEBUG Log.Warning(" Needed Ing population not found"); #endif neededIngs.AddLast(new NeededIngrediants(ing.filter, (int)ing.GetBaseCount())); } } #if DEBUG || DROP_DEBUG || BILL_DEBUG Log.Warning(" Needed Ings:"); foreach (NeededIngrediants ings in neededIngs) { Log.Warning(" " + ings.Count); } #endif List <WeaponsToUse> weaponsToUse = new List <WeaponsToUse>(); foreach (Building_WeaponStorage storage in WorldComp.GetWeaponStorages(bill.Map)) { if ((float)(storage.Position - billGiver.Position).LengthHorizontalSquared < Math.Pow(bill.ingredientSearchRadius, 2)) { LinkedListNode <NeededIngrediants> n = neededIngs.First; while (n != null) { var next = n.Next; NeededIngrediants neededIng = n.Value; List <ThingWithComps> gotten; if (storage.TryGetFilteredWeapons(bill, neededIng.Filter, out gotten)) { foreach (ThingWithComps got in gotten) { neededIng.Add(new StoredWeapons(storage, got)); } if (neededIng.CountReached()) { weaponsToUse.Add(new WeaponsToUse(neededIng.GetFoundThings(), neededIng.Count)); neededIng.Clear(); neededIngs.Remove(n); } } n = next; } } } #if DEBUG || DROP_DEBUG || BILL_DEBUG Log.Warning(" neededIngs.count: " + neededIngs.Count); #endif if (neededIngs.Count == 0) { __result = true; foreach (WeaponsToUse ttu in weaponsToUse) { int count = ttu.Count; foreach (StoredWeapons sa in ttu.Weapons) { if (count <= 0) { break; } if (sa.Storage.Remove(sa.Weapon)) { count -= sa.Weapon.stackCount; chosen.Add(new ThingCount(sa.Weapon, sa.Weapon.stackCount)); } } } } weaponsToUse.Clear(); foreach (NeededIngrediants n in neededIngs) { n.Clear(); } neededIngs.Clear(); chosenAmounts.Clear(); }
static void Prefix() { WorldComp.ClearAll(); }