This can happen if HeliAttack tells the heli to return to base when the player doesn't have any of the RearmBuildings available, because the activity queues itself after the HRTB, and the latter will, after a forced land, then queue back HeliAttack, which then immediately queues back HRTB and so on.
Instead, we now assume that if there is no base to return to, going to NextActivity is pointless and don't queue NextActivity.
RTB was likely ordered by HeliAttack due to lack of ammo, so resuming the attack would be pointless.
This avoids a crash that stops the maps from being updated
when the base mod ruleset is not valid (e.g. a trait is missing a
FieldLoader.Required property). This also significantly improves the
upgrade performance.
- Rename Bits<T> to BitSet<T>.
- Implement set based helpers for BitSet<T>.
- When representing TargetTypes of ITargetable in various traits, use a BitSet<TargetableType> instead of HashSet<string> for better performance & reduced memory usage.
- Fix FieldLoader to trim input values when generating a BitSet<T>.
- Require T in BitSet<T> and BitSetAllocator<T> to be a class since it's just a marker value. This allows the JIT to instantiate generic code for these classes once, as they don't benefit from specialized code for T. (Typically JITs will generate shared code for all reference types, and unique code for every value type encountered).
- Cache active target query.
- Prefer .Count == 0 over Any when working with Lists.
- Use helper for GetEnabledTargetTypes.
- Don't declare target variable until actually needed.
Actors involved in the trigger are determined as actors move around near the trigger - and can be expensive in some maps. This allows us to avoid allocating new sets and the CPU hit required to set it up each time.
This provides a more efficient way of determining the bounds by avoiding LINQ. A helper that works directly on arrays prevents allocation of an enumerator when the collection is know to be an array.
Shroud footprints are recalculated as actors move around the map, and thus this gets called quite often. This allows us to avoid allocating a new set and the CPU hit required to set it up each time.