diff --git a/Defs/TempTestDef.xml b/Defs/TempTestDef.xml
new file mode 100644
index 0000000000..9e7ac47f58
--- /dev/null
+++ b/Defs/TempTestDef.xml
@@ -0,0 +1,177 @@
+
+
+
+ Turret_GenericAmmoUserTest
+
+ 6
+
+ Things/Building/Turrets/MachineGunBase
+
+ (0.27,0.25,0.27)
+ (0,0,0)
+
+
+ UI/Icons/Turrets/MediumAutoTurret_uiIcon
+
+ 20000
+ 200
+ 0.6
+ 30
+ 40
+ 0.5
+ 0.75
+
+ Automatic turret equiped with a full powered cartridge machine gun. Fairly resistant to damage.
+
+ 150
+ 8
+
+
+ true
+ Gun_GenericAmmoUserTest
+
+
+ PlaceWorker_TurretTop
+ PlaceWorker_ShowTurretRadius
+
+
+
+ CompPowerTrader
+ 150
+
+
+ MinifiedThing
+
+ GunTurrets
+ PrecisionRifling
+
+
+
+
+ Gun_GenericAmmoUserTest
+
+
+ Things/Building/Turrets/MediumTurret_Top
+ Graphic_Single
+
+ Full powered cartridge gun on a turret mount.
+
+ 1
+ 0.05
+ 0.84
+ 0.36
+ 10
+
+
+
+ 0.95
+ CombatExtended.Verb_ShootCE
+ true
+ Bullet_762x51mmNATO_FMJ
+ 1.3
+ 55
+ 6
+ 10
+ MediumMG
+ GunTail_Medium
+ 11
+ Mounted
+
+
+
+
+ CombatExtended.CompAmmoUserGeneric
+ 80
+ 7.8
+ AmmoSet_762x51mmNATO
+
+
+
+
+
+ Turret_GenericAmmoUserTestII
+
+ 6
+
+ Things/Building/Turrets/MachineGunBase
+
+ (0.27,0.25,0.27)
+ (0,0,0)
+
+
+ UI/Icons/Turrets/MediumAutoTurret_uiIcon
+
+ 20000
+ 200
+ 0.6
+ 30
+ 40
+ 0.5
+ 0.75
+
+ Automatic turret equiped with a full powered cartridge machine gun. Fairly resistant to damage.
+
+ 150
+ 8
+
+
+ true
+ Gun_GenericAmmoUserTestII
+
+
+ PlaceWorker_TurretTop
+ PlaceWorker_ShowTurretRadius
+
+
+
+ CompPowerTrader
+ 150
+
+
+ MinifiedThing
+
+ GunTurrets
+ PrecisionRifling
+
+
+
+
+ Gun_GenericAmmoUserTestII
+
+
+ Things/Building/Turrets/MediumTurret_Top
+ Graphic_Single
+
+ Full powered cartridge gun on a turret mount.
+
+ 1
+ 0.05
+ 0.84
+ 0.36
+ 10
+
+
+
+ 0.95
+ CombatExtended.Verb_ShootCE
+ true
+ Bullet_762x51mmNATO_FMJ
+ 1.3
+ 55
+ 6
+ 10
+ MediumMG
+ GunTail_Medium
+ 11
+ Mounted
+
+
+
+
+ 80
+ 7.8
+ AmmoSet_303British
+
+
+
+
\ No newline at end of file
diff --git a/Defs/ThingDefs_Buildings/AutoLoaderExample.xml b/Defs/ThingDefs_Buildings/AutoLoaderExample.xml
index a8bcec7417..3484c6b900 100644
--- a/Defs/ThingDefs_Buildings/AutoLoaderExample.xml
+++ b/Defs/ThingDefs_Buildings/AutoLoaderExample.xml
@@ -1,144 +1,119 @@
-
+ 0.5
+ false
+ 42
+ (2,1)
+
+ 200
+
+
+ BuildingDestroyed_Metal_Small
+
+
+ 100
+ 1800
+ 20
+ 0.5
+
+ 0.5
+
+ Misc
+ MinifiedThing
+
+ BuildingsMisc
+
+
\ No newline at end of file
diff --git a/Source/CombatExtended/CombatExtended/Building_AmmoContainerCE/Building_AutoloaderCE.cs b/Source/CombatExtended/CombatExtended/Building_AmmoContainerCE/Building_AutoloaderCE.cs
index d4c594649d..da4468f889 100644
--- a/Source/CombatExtended/CombatExtended/Building_AmmoContainerCE/Building_AutoloaderCE.cs
+++ b/Source/CombatExtended/CombatExtended/Building_AmmoContainerCE/Building_AutoloaderCE.cs
@@ -88,14 +88,14 @@ public override Graphic Graphic
public bool CanReplaceAmmo(CompAmmoUser ammoUser)
{
- return shouldReplaceAmmo && ammoUser.Props.ammoSet == CompAmmoUser.Props.ammoSet && ammoUser.CurrentAmmo != CompAmmoUser.CurrentAmmo;
+ return shouldReplaceAmmo && ammoUser.CurAmmoSet == CompAmmoUser.CurAmmoSet && ammoUser.CurrentAmmo != CompAmmoUser.CurrentAmmo;
}
public override void SpawnSetup(Map map, bool respawningAfterLoad)
{
base.SpawnSetup(map, respawningAfterLoad);
Map.GetComponent().Register(this);
- CompAmmoUser = GetComp();
+ CompAmmoUser = this.TryGetComp();
dormantComp = GetComp();
initiatableComp = GetComp();
@@ -228,7 +228,7 @@ public override IEnumerable GetGizmos()
}
if (!success)
{
- Messages.Message(string.Format("CE_AutoLoader_NoTurretToReload".Translate(), Label, CompAmmoUser.Props.ammoSet.label), this, MessageTypeDefOf.RejectInput, historical: false);
+ Messages.Message(string.Format("CE_AutoLoader_NoTurretToReload".Translate(), Label, CompAmmoUser.CurAmmoSet.label), this, MessageTypeDefOf.RejectInput, historical: false);
}
};
yield return reload;
@@ -349,18 +349,24 @@ public bool StartReload(CompAmmoUser TurretMagazine, bool continued = false)
//if this is the right turret to reload
if (graphicsExt != null)
{
- //if def exists and match
- bool tagMatch = graphicsExt.allowedTurrets.Any() && graphicsExt.allowedTurrets.Contains(turret.def.defName);
+ //if turret type restriction is in place, if both are null, tag chech automatically pass
+ bool tagMatch = graphicsExt.allowedTurrets.NullOrEmpty() && graphicsExt.allowedTurretTags.NullOrEmpty();
- //if tag exists and match
- if (!tagMatch && graphicsExt.allowedTurretTags.Any())
+ if (!tagMatch)
{
- foreach (string loadertag in graphicsExt.allowedTurretTags)
+ //if def dont exist or match
+ tagMatch = graphicsExt.allowedTurrets.NullOrEmpty() || graphicsExt.allowedTurrets.Contains(turret.def.defName);
+
+ //if tag exists and match
+ if (!tagMatch && graphicsExt.allowedTurretTags.Any())
{
- if (turret.def.building.buildingTags.NotNullAndContains(loadertag))
+ foreach (string loadertag in graphicsExt.allowedTurretTags)
{
- tagMatch = true;
- break;
+ if (turret.def.building.buildingTags.NotNullAndContains(loadertag))
+ {
+ tagMatch = true;
+ break;
+ }
}
}
}
diff --git a/Source/CombatExtended/CombatExtended/Comps/CompAmmoUser.cs b/Source/CombatExtended/CombatExtended/Comps/CompAmmoUser.cs
index e1aa4617b6..91c3ae0e4f 100644
--- a/Source/CombatExtended/CombatExtended/Comps/CompAmmoUser.cs
+++ b/Source/CombatExtended/CombatExtended/Comps/CompAmmoUser.cs
@@ -17,9 +17,9 @@ public class CompAmmoUser : CompRangedGizmoGiver
{
#region Fields
- private int curMagCountInt = 0;
- private AmmoDef currentAmmoInt = null;
- private AmmoDef selectedAmmo;
+ protected int curMagCountInt = 0;
+ protected AmmoDef currentAmmoInt = null;
+ protected AmmoDef selectedAmmo;
private Thing ammoToBeDeleted;
@@ -46,7 +46,7 @@ public int MagsLeft
{
CompInventory.UpdateInventory();
int count = 0;
- foreach (AmmoLink link in Props.ammoSet.ammoTypes)
+ foreach (AmmoLink link in CurAmmoSet.ammoTypes)
{
count += CompInventory.AmmoCountOfDef(link.ammo);
}
@@ -137,7 +137,7 @@ public bool UseAmmo
{
get
{
- return Props.ammoSet != null && AmmoUtility.IsAmmoSystemActive(Props.ammoSet);
+ return CurAmmoSet != null && AmmoUtility.IsAmmoSystemActive(CurAmmoSet);
}
}
public bool IsAOEWeapon
@@ -172,7 +172,7 @@ public bool HasAmmo
{
get
{
- return CompInventory != null && CompInventory.ammoList.Any(x => Props.ammoSet.ammoTypes.Any(a => a.ammo == x.def));
+ return CompInventory != null && CompInventory.ammoList.Any(x => CurAmmoSet.ammoTypes.Any(a => a.ammo == x.def));
}
}
public bool HasMagazine => MagSize > 0;
@@ -217,7 +217,9 @@ public bool FullMagazine
}
}
- public ThingDef CurAmmoProjectile => Props.ammoSet?.ammoTypes?.FirstOrDefault(x => x.ammo == CurrentAmmo)?.projectile ?? parent.def.Verbs.FirstOrDefault().defaultProjectile;
+ public virtual AmmoSetDef CurAmmoSet => Props.ammoSet;
+
+ public virtual ThingDef CurAmmoProjectile => CurAmmoSet?.ammoTypes?.FirstOrDefault(x => x.ammo == CurrentAmmo)?.projectile ?? parent.def.Verbs.FirstOrDefault().defaultProjectile;
public CompInventory CompInventory
{
get
@@ -267,7 +269,7 @@ private Map Map
}
public bool ShouldThrowMote => Props.throwMote && MagSize > 1;
- public AmmoDef SelectedAmmo
+ public virtual AmmoDef SelectedAmmo
{
get
{
@@ -297,7 +299,7 @@ public override void Initialize(CompProperties vprops)
// Initialize ammo with default if none is set
if (UseAmmo)
{
- if (Props.ammoSet.ammoTypes.NullOrEmpty())
+ if (CurAmmoSet.ammoTypes.NullOrEmpty())
{
Log.Error(parent.Label + " has no available ammo types");
}
@@ -305,7 +307,7 @@ public override void Initialize(CompProperties vprops)
{
if (currentAmmoInt == null)
{
- currentAmmoInt = (AmmoDef)Props.ammoSet.ammoTypes[0].ammo;
+ currentAmmoInt = (AmmoDef)CurAmmoSet.ammoTypes[0].ammo;
}
if (selectedAmmo == null)
{
@@ -671,7 +673,7 @@ public bool TryPickupAmmo()
{
return false;
}
- IEnumerable supportedAmmo = Props.ammoSet.ammoTypes.Select(a => a.ammo);
+ IEnumerable supportedAmmo = CurAmmoSet.ammoTypes.Select(a => a.ammo);
foreach (Thing thing in Holder.Position.AmmoInRange(Holder.Map, 6).Where(t => t is AmmoThing ammo
&& supportedAmmo.Contains(ammo.AmmoDef)
&& (!Holder.IsColonist || (!ammo.IsForbidden(Holder) && ammo.Position.AdjacentTo8WayOrInside(Holder)))))
@@ -831,7 +833,7 @@ public bool TryFindAmmoInInventory(out Thing ammoThing)
}
// Try finding ammo from different type
- foreach (AmmoLink link in Props.ammoSet.ammoTypes)
+ foreach (AmmoLink link in CurAmmoSet.ammoTypes)
{
ammoThing = CompInventory.ammoList.Find(thing => thing.def == link.ammo);
if (ammoThing != null)
@@ -927,7 +929,7 @@ public override IEnumerable CompGetGizmosExtra()
public override string TransformLabel(string label)
{
- string ammoSet = UseAmmo && Controller.settings.ShowCaliberOnGuns ? " (" + (string)Props.ammoSet.LabelCap + ") " : "";
+ string ammoSet = UseAmmo && Controller.settings.ShowCaliberOnGuns ? " (" + (string)CurAmmoSet.LabelCap + ") " : "";
return label + ammoSet;
}
diff --git a/Source/CombatExtended/CombatExtended/Comps/CompAmmoUserGeneric.cs b/Source/CombatExtended/CombatExtended/Comps/CompAmmoUserGeneric.cs
new file mode 100644
index 0000000000..e792a46783
--- /dev/null
+++ b/Source/CombatExtended/CombatExtended/Comps/CompAmmoUserGeneric.cs
@@ -0,0 +1,187 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Security.Cryptography;
+using System.Text;
+using System.Threading.Tasks;
+using UnityEngine;
+using Verse;
+
+namespace CombatExtended
+{
+ public class CompAmmoUserGeneric : CompAmmoUser
+ {
+ protected List usableAmmoSets = new List();
+
+ public AmmoSetDef SelectedAmmoSet;
+
+ public AmmoSetDef UsedGenericAmmoSet => Props.ammoSet.similarTo ?? Props.ammoSet;
+
+ const float margin = 4f;
+
+ public virtual List UsableAmmoSets
+ {
+ get
+ {
+ if (usableAmmoSets.NullOrEmpty())
+ {
+ foreach (var def in DefDatabase.AllDefs)
+ {
+ if (def.similarTo == null)
+ {
+ continue;
+ }
+ if (def.similarTo == UsedGenericAmmoSet && !def.ammoTypes.First().ammo.menuHidden && !IsIdenticalToAny(def))
+ {
+ usableAmmoSets.Add(def);
+ }
+ }
+ }
+ return usableAmmoSets;
+ }
+ }
+
+ //Merge ammosets with identical ammo usage. I'm worried about its performance and I might want to caculate this during game start up.
+ protected bool IsIdenticalToAny(AmmoSetDef def)
+ {
+ if (usableAmmoSets.NullOrEmpty())
+ {
+ return false;
+ }
+ foreach (var v in usableAmmoSets)
+ {
+ if (IsIdenticalTo(v, def))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ protected bool IsIdenticalTo(AmmoSetDef a, AmmoSetDef b)
+ {
+ if (a.ammoTypes.Count != b.ammoTypes.Count)
+ {
+ return false;
+ }
+ HashSet list = new HashSet();
+ foreach (var v in a.ammoTypes)
+ {
+ list.Add(v.ammo);
+ }
+ foreach (var n in b.ammoTypes)
+ {
+ if (!list.Contains(n.ammo))
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+
+ public override AmmoSetDef CurAmmoSet => SelectedAmmoSet;
+
+ public override void PostExposeData()
+ {
+ base.PostExposeData();
+ Scribe_Defs.Look(ref SelectedAmmoSet, "SelectedAmmoSet");
+ }
+
+ public override void Initialize(CompProperties vprops)
+ {
+ base.Initialize(vprops);
+ SelectedAmmoSet = Props.ammoSet;
+ RegenSelectedAmmo();
+ }
+ public void RegenSelectedAmmo()
+ {
+ if (currentAmmoInt == null)
+ {
+ currentAmmoInt = (AmmoDef)CurAmmoSet.ammoTypes[0].ammo;
+ }
+ if (selectedAmmo == null)
+ {
+ selectedAmmo = currentAmmoInt;
+ }
+ else
+ {
+ //turned out it was bold to assume similar ammosets always have same ammo types
+ var tempAmmoLink = CurAmmoSet.ammoTypes.Where(l => l.ammo.ammoClass == currentAmmoInt.ammoClass);
+ if (tempAmmoLink.Any())
+ {
+ selectedAmmo = tempAmmoLink.First().ammo;
+ }
+ else
+ {
+ selectedAmmo = CurAmmoSet.ammoTypes.First().ammo;
+ }
+ }
+ }
+
+ [Compatibility.Multiplayer.SyncMethod]
+ private void SyncedSelectAmmoSet(AmmoSetDef caliber)
+ {
+ SelectedAmmoSet = caliber;
+ RegenSelectedAmmo();
+ }
+
+ public override IEnumerable CompGetGizmosExtra()
+ {
+ foreach (var gizmo in base.CompGetGizmosExtra())
+ {
+ yield return gizmo;
+ }
+ if (!Controller.settings.GenericAmmo)
+ {
+ Command_Action command_Action = new Command_Action();
+ command_Action.defaultLabel = "CE_SelectAmmoSet".Translate();
+ command_Action.defaultDesc = "CommandSelectMineralToScanForDesc".Translate();
+ command_Action.icon = ContentFinder.Get("UI/Buttons/Reload", reportFailure: false);
+ command_Action.action = delegate
+ {
+ List list = new List();
+ foreach (AmmoSetDef caliber in UsableAmmoSets)
+ {
+ FloatMenuOption item = new FloatMenuOption(caliber.LabelCap, delegate
+ {
+ SyncedSelectAmmoSet(caliber);
+ }, MenuOptionPriority.Default,
+ delegate (Rect rect)
+ {
+ ContainedAmmoPopOut(rect, caliber);
+ }
+ , null);
+ list.Add(item);
+ }
+ Find.WindowStack.Add(new FloatMenu(list));
+ };
+ yield return command_Action;
+ }
+ }
+
+ AmmoSetDef currentlyHoveredOverAmmoSet = null;
+
+ string ammoSetContentDescCache;
+
+ public void ContainedAmmoPopOut(Rect rect, AmmoSetDef ammoSet)
+ {
+ if (ammoSet != currentlyHoveredOverAmmoSet)
+ {
+ BuildAmmosetString(ammoSet);
+ }
+ TooltipHandler.TipRegion(rect, ammoSetContentDescCache);
+
+ }
+
+ public void BuildAmmosetString(AmmoSetDef ammoSetDef)
+ {
+ StringBuilder stringBuilder = new StringBuilder();
+ foreach (var v in ammoSetDef.ammoTypes)
+ {
+ stringBuilder.AppendLine(v.ammo.label);
+ }
+ ammoSetContentDescCache = stringBuilder.ToString();
+ }
+ }
+}
diff --git a/Source/CombatExtended/CombatExtended/Gizmos/Command_Reload.cs b/Source/CombatExtended/CombatExtended/Gizmos/Command_Reload.cs
index d8a83d5f0f..d93368b433 100644
--- a/Source/CombatExtended/CombatExtended/Gizmos/Command_Reload.cs
+++ b/Source/CombatExtended/CombatExtended/Gizmos/Command_Reload.cs
@@ -119,7 +119,7 @@ private List BuildAmmoOptions()
{
var user = other.compAmmo;
- foreach (AmmoLink link in user.Props.ammoSet.ammoTypes)
+ foreach (AmmoLink link in user.CurAmmoSet.ammoTypes)
{
var ammoDef = link.ammo;
var ammoClass = ammoDef.ammoClass;
diff --git a/Source/CombatExtended/CombatExtended/Jobs/JobGiver_CheckReload.cs b/Source/CombatExtended/CombatExtended/Jobs/JobGiver_CheckReload.cs
index 57c4446115..0a5af7ae86 100644
--- a/Source/CombatExtended/CombatExtended/Jobs/JobGiver_CheckReload.cs
+++ b/Source/CombatExtended/CombatExtended/Jobs/JobGiver_CheckReload.cs
@@ -132,7 +132,7 @@ private bool DoReloadCheck(Pawn pawn, out ThingWithComps reloadWeapon, out AmmoD
{
// Get key stats of the weapon.
tmpComp = gun.TryGetComp();
- AmmoDef ammoType = tmpComp.CurrentAmmo;
+ AmmoDef ammoType = tmpComp.SelectedAmmo;
int ammoAmount = tmpComp.CurMagCount;
int magazineSize = tmpComp.MagSize;
@@ -140,7 +140,7 @@ private bool DoReloadCheck(Pawn pawn, out ThingWithComps reloadWeapon, out AmmoD
if (tmpComp.UseAmmo && pawnHasLoadout && !TrackingSatisfied(pawn, ammoType, magazineSize))
{
// Do we have ammo in the inventory that the gun uses which satisfies requirements? (expensive)
- AmmoDef matchAmmo = tmpComp.Props.ammoSet.ammoTypes
+ AmmoDef matchAmmo = tmpComp.CurAmmoSet.ammoTypes
.Where(al => al.ammo != ammoType)
.Select(al => al.ammo)
.FirstOrDefault(ad => TrackingSatisfied(pawn, ad, magazineSize)
diff --git a/Source/CombatExtended/CombatExtended/Jobs/JobGiver_ManTurretsNearPointCE.cs b/Source/CombatExtended/CombatExtended/Jobs/JobGiver_ManTurretsNearPointCE.cs
index c9448e901a..228f64d9f0 100644
--- a/Source/CombatExtended/CombatExtended/Jobs/JobGiver_ManTurretsNearPointCE.cs
+++ b/Source/CombatExtended/CombatExtended/Jobs/JobGiver_ManTurretsNearPointCE.cs
@@ -54,7 +54,7 @@ private static Thing FindAmmoForTurret(Pawn pawn, Thing turret)
40f,
t => !t.IsForbidden(pawn) &&
pawn.CanReserve(t, 10, 1) &&
- compAmmo.Props.ammoSet.ammoTypes.Any(l => l.ammo == t.def));
+ compAmmo.CurAmmoSet.ammoTypes.Any(l => l.ammo == t.def));
}
}
}
diff --git a/Source/CombatExtended/CombatExtended/Jobs/JobGiver_ManTurretsNearSelfCE.cs b/Source/CombatExtended/CombatExtended/Jobs/JobGiver_ManTurretsNearSelfCE.cs
index b02bca7243..1129cfa3d5 100644
--- a/Source/CombatExtended/CombatExtended/Jobs/JobGiver_ManTurretsNearSelfCE.cs
+++ b/Source/CombatExtended/CombatExtended/Jobs/JobGiver_ManTurretsNearSelfCE.cs
@@ -54,7 +54,7 @@ private static Thing FindAmmoForTurret(Pawn pawn, Thing turret)
40f,
t => !t.IsForbidden(pawn) &&
pawn.CanReserve(t, 10, 1) &&
- compAmmo.Props.ammoSet.ammoTypes.Any(l => l.ammo == t.def));
+ compAmmo.CurAmmoSet.ammoTypes.Any(l => l.ammo == t.def));
}
}
}