View Issue Details
ID | Project | Category | Date Submitted | Last Update | |
---|---|---|---|---|---|
0025669 | AI War 2 | Crash/Exception | Oct 17, 2021 5:21 pm | Oct 27, 2021 6:42 am | |
Reporter | tom.prince | Assigned To | tom.prince | ||
Status | resolved | Resolution | fixed | ||
Product Version | Beta 3.712 Loading Hotfix | ||||
Fixed in Version | Beta 3.740 Code Panopticon | ||||
Summary | 0025669: Multiple Spire Cities don't appear to properly bolster a fleet. | ||||
Description | It looks like ''RecalculateSpireCityMobileFleetContents_MainThreadSimOnly'' uses ''GetOrAddMembershipGroupBasedOnSquadType_WithUniqueIDForDuplicates'' to add ship cap to the fleet from each city. However, (based on looking at the disassembly) that function only works for ''FleetCategory.PlayerMobile'' and otherwise delegates to ''GetOrAddMembershipGroupBasedOnSquadType_AssumeNoDuplicates''. If that function needs the category check, either ''PlayerCustomCityFedMobile'' should be added, or the bolstering logic needs to be changed to use ''GetOrAddMembershipGroupBasedOnSquadType_AssumeNoDuplicates''. The other overload of ''GetOrAddMembershipGroupBasedOnSquadType_WithUniqueIDForDuplicates'' can't obviously be used, since it takes a ''byte'' instead of an ''int'' for the differentiatior and I assume that is too narrow to pass the ''FleetID'' into, without possibly having a collision. | ||||
Tags | No tags attached. | ||||
|
I was also surprised that the frigate-per-city was hard-coded in the code, rather than provided by the spire hub structure, though I guess that may be because they are not part of part of the ''SpireCity'' build category, so aren't iterated over. |
|
> I was also surprised that the frigate-per-city was hard-coded in the code, rather than provided by the spire hub structure, though I guess that may be because they are not part of part of the ''SpireCity'' build category, so aren't iterated over. It also appears that this logic is incorrect, as isn't combined with the value from ''ship_type_name_to_grant_more_of_in_custom_fleet''. |
|
I've attached a few patches that address some of the issues here: 1. A patch that fixes up the logic around frigates, by moving it to be provided by the spire hub (and adding a new tag to the spire buildings that provide ships) 2. A workaround for ''GetOrAddMembershipGroupBasedOnSquadType_WithUniqueIDForDuplicates'' that uses the alternate overload, but this should really be fixed in core instead, as this patch narrows the `FleetID` to a byte, so will cause problems if two spire cities have the same fleet id modulo 256. 3. A patch that will cleanup spire fleet members that aren't bolstered by a specific city due to this bug. This isn't a great implementation, as it runs every tick, and just destroys the ships. However, as I'm guessing the save format may be broken again, this is likely unnecessary. spire-frigate-tracking.patch (5,653 bytes)
# HG changeset patch # User Tom Prince <[email protected]> # Date 1634510205 21600 # Sun Oct 17 16:36:45 2021 -0600 # Node ID 6e080cd656aa4cbfaf6e3f4064e280c4088339d5 # Parent f28b7cdbcd3024b2a3dc3244babbf8599a770a4a Make Spire Frigates be properly tracked. diff --git CodeExternal/AIWarExternalDeepProcessingCode/src/DeepInfo/DLC1/FallenSpireFactionDeepInfo.cs CodeExternal/AIWarExternalDeepProcessingCode/src/DeepInfo/DLC1/FallenSpireFactionDeepInfo.cs --- CodeExternal/AIWarExternalDeepProcessingCode/src/DeepInfo/DLC1/FallenSpireFactionDeepInfo.cs +++ CodeExternal/AIWarExternalDeepProcessingCode/src/DeepInfo/DLC1/FallenSpireFactionDeepInfo.cs @@ -1941,7 +1941,7 @@ namespace Arcen.AIW2.External public void RecalculateSpireCityMobileFleetContents_MainThreadSimOnly( Faction faction, ArcenHostOnlySimContext Context ) { spireShipsToAdd.Clear(); - List<GameEntityTypeData> spireCityBuildings = GameEntityTypeDataTable.Instance.GetAllRowsWithTagOrNull( "SpireCityBuildMenu" ); + List<GameEntityTypeData> spireCityBuildings = GameEntityTypeDataTable.Instance.GetAllRowsWithTagOrNull( "SpireFeedsFleet" ); int maxMarkLevelOfAnyCity = 0; @@ -2115,7 +2115,6 @@ namespace Arcen.AIW2.External int cruisersToHave = 0; int battleshipsToHave = 0; - int frigatesToHave = 1; if ( fleetForCity.MaxMarkLevelOfAnyInFleet >= 6 ) //city mark 6 or higher { @@ -2139,13 +2138,6 @@ namespace Arcen.AIW2.External if ( battleshipMem.ExplicitBaseSquadCap < battleshipsToHave ) battleshipMem.ExplicitBaseSquadCap = battleshipsToHave; } - - if ( frigatesToHave > 0 && !isCityItselfDisabled ) //increase the cap only if the city is not disabled - { - FleetMembership battleshipMem = fleetForMobile.GetOrAddMembershipGroupBasedOnSquadType_WithUniqueIDForDuplicates( GameEntityTypeDataTable.Instance.GetRowByName( "SpireFrigate" ), fleetForCity.FleetID ); - if ( battleshipMem.ExplicitBaseSquadCap < frigatesToHave ) - battleshipMem.ExplicitBaseSquadCap = frigatesToHave; - } return DelReturn.Continue; } ); diff --git Expansions/1_The_Spire_Rises/GameData/Configuration/GameEntity/TSR_Ships_Spire.xml Expansions/1_The_Spire_Rises/GameData/Configuration/GameEntity/TSR_Ships_Spire.xml --- Expansions/1_The_Spire_Rises/GameData/Configuration/GameEntity/TSR_Ships_Spire.xml +++ Expansions/1_The_Spire_Rises/GameData/Configuration/GameEntity/TSR_Ships_Spire.xml @@ -543,7 +543,7 @@ ************************************************************************************************ ************************************************************************************************--> - <entity name="SpireCityHub" tags="SpireCity" + <entity name="SpireCityHub" tags="SpireCity,SpireFeedsFleet" special_entity_type="CityCenter" draw_in_galaxy_view="true" name_for_city_center="Spire City" name_for_city_sockets="Spire Casing" visuals="Assets/_DLC1/FallenSpire/SpireCityHub/SpireCityHub.prefab" visuals_bundle="exp1_the_spire_rises" @@ -574,11 +574,12 @@ description_appender_dll="AIWarExternalCode" description_appender_type="Arcen.AIW2.External.SpireHubDescriptionAppender" shows_on_galaxy_map_for_explored_planets="true" always_visible_to_players="true" + ship_type_name_to_grant_more_of_in_custom_fleet="SpireFrigate" ship_type_count_to_grant_more_of_in_custom_fleet="1" > <metal_flow purpose="SelfConstruction" throughput="2500"/> </entity> - <entity name="SpireGalacticCapitol" tags="SpireCity" + <entity name="SpireGalacticCapitol" tags="SpireCity,SpireFeedsFleet" special_entity_type="CityCenter" draw_in_galaxy_view="true" name_for_city_center="Spire City" name_for_city_sockets="Spire Casing" visuals="Assets/_DLC1/FallenSpire/SpireGalacticCapitol/SpireGalacticCapitol.prefab" visuals_bundle="exp1_the_spire_rises" @@ -608,6 +609,7 @@ description_appender_dll="AIWarExternalCode" description_appender_type="Arcen.AIW2.External.SpireHubDescriptionAppender" shows_on_galaxy_map_for_explored_planets="true" always_visible_to_players="true" + ship_type_name_to_grant_more_of_in_custom_fleet="SpireFrigate" ship_type_count_to_grant_more_of_in_custom_fleet="1" > <metal_flow purpose="SelfConstruction" throughput="2500"/> <system name="HeavyBeamCannon" display_name="Spire Coil Beam" @@ -770,7 +772,7 @@ </entity> <entity name="SpireFrigateNeuralNet" - tags="SpireCityBuildMenu" + tags="SpireCityBuildMenu,SpireFeedsFleet" visuals="Assets/_DLC1/FallenSpire/SpireFrigateNeuralNet/SpireFrigateNeuralNet.prefab" visuals_bundle="exp1_the_spire_rises" icon_name="Ships1/NeuralNet" icon_overlay="Overlays2/NeuralNet_SpireFrigate" gimbal_icon_size_multiplier="1.5" voice_group="Spire" @@ -817,7 +819,7 @@ <entity name="SpireDestroyerNeuralNet" - tags="SpireCityBuildMenu" + tags="SpireCityBuildMenu,SpireFeedsFleet" visuals="Assets/_DLC1/FallenSpire/SpireDestroyerNeuralNet/SpireDestroyerNeuralNet.prefab" visuals_bundle="exp1_the_spire_rises" icon_name="Ships1/NeuralNet" icon_overlay="Overlays2/NeuralNet_SpireDestroyer" gimbal_icon_size_multiplier="1.5" voice_group="Spire" workaround-for-withuniqueidforduplicates-filtering.patch (4,520 bytes)
# HG changeset patch # User Tom Prince <[email protected]> # Date 1634510400 21600 # Sun Oct 17 16:40:00 2021 -0600 # Node ID 78137f5317ded8b7573bc5f417738b0203595836 # Parent 6e080cd656aa4cbfaf6e3f4064e280c4088339d5 Work around ``GetOrAddMembershipGroupBasedOnSquadType_WithUniqueIDForDuplicates`` category filtering. This uses the alternate overload of ``GetOrAddMembershipGroupBasedOnSquadType_WithUniqueIDForDuplicates``, by passing in a default cap. However, this has a bug that we can only use a byte for the differentiator. Hopefully every spire city will have differnet fleet IDs module 256. diff --git CodeExternal/AIWarExternalDeepProcessingCode/src/DeepInfo/DLC1/FallenSpireFactionDeepInfo.cs CodeExternal/AIWarExternalDeepProcessingCode/src/DeepInfo/DLC1/FallenSpireFactionDeepInfo.cs --- CodeExternal/AIWarExternalDeepProcessingCode/src/DeepInfo/DLC1/FallenSpireFactionDeepInfo.cs +++ CodeExternal/AIWarExternalDeepProcessingCode/src/DeepInfo/DLC1/FallenSpireFactionDeepInfo.cs @@ -2011,8 +2011,12 @@ namespace Arcen.AIW2.External otherMobileFleet.DoForMemberGroupsUnsorted_Sim( delegate ( FleetMembership mem ) { + if ( mem.FedHereFromCityFleetID == 0 ) { + mem.DespawnAllContentsFromNoLongerBolstering( Context ); + return DelReturn.RemoveAndContinue; //remove the entire line! + } //whoops, this is fed here from us! Time to clear it, since we're not bolstering that. - if ( mem.FedHereFromCityFleetID == fleetForCity.FleetID ) + if ( mem.FedHereFromCityFleetID == (byte)fleetForCity.FleetID ) { mem.DespawnAllContentsFromNoLongerBolstering( Context ); return DelReturn.RemoveAndContinue; //remove the entire line! @@ -2102,7 +2106,8 @@ namespace Arcen.AIW2.External continue; } int numberToHave = kv.Value; - FleetMembership mem = fleetForMobile.GetOrAddMembershipGroupBasedOnSquadType_WithUniqueIDForDuplicates( typeData, fleetForCity.FleetID ); + // Pass in numberToHave to get version of GetOrAddMembershipGroupBasedOnSquadType_WithUniqueIDForDuplicates that doesn't care about FleetCategory + FleetMembership mem = fleetForMobile.GetOrAddMembershipGroupBasedOnSquadType_WithUniqueIDForDuplicates( typeData, (byte)fleetForCity.FleetID, 0); //increase the cap only if the city is not disabled if ( mem.ExplicitBaseSquadCap < numberToHave && !isCityItselfDisabled ) mem.ExplicitBaseSquadCap = numberToHave; @@ -2127,14 +2132,14 @@ namespace Arcen.AIW2.External if ( cruisersToHave > 0 && !isCityItselfDisabled ) //increase the cap only if the city is not disabled { - FleetMembership cruiserMem = fleetForMobile.GetOrAddMembershipGroupBasedOnSquadType_WithUniqueIDForDuplicates( GameEntityTypeDataTable.Instance.GetRowByName( "SpireCruiser" ), fleetForCity.FleetID ); + FleetMembership cruiserMem = fleetForMobile.GetOrAddMembershipGroupBasedOnSquadType_WithUniqueIDForDuplicates( GameEntityTypeDataTable.Instance.GetRowByName( "SpireCruiser" ), (byte) fleetForCity.FleetID, 0 ); if ( cruiserMem.ExplicitBaseSquadCap < cruisersToHave ) cruiserMem.ExplicitBaseSquadCap = cruisersToHave; } if ( battleshipsToHave > 0 && !isCityItselfDisabled ) //increase the cap only if the city is not disabled { - FleetMembership battleshipMem = fleetForMobile.GetOrAddMembershipGroupBasedOnSquadType_WithUniqueIDForDuplicates( GameEntityTypeDataTable.Instance.GetRowByName( "SpireBattleship" ), fleetForCity.FleetID ); + FleetMembership battleshipMem = fleetForMobile.GetOrAddMembershipGroupBasedOnSquadType_WithUniqueIDForDuplicates( GameEntityTypeDataTable.Instance.GetRowByName( "SpireBattleship" ), (byte) fleetForCity.FleetID, 0 ); if ( battleshipMem.ExplicitBaseSquadCap < battleshipsToHave ) battleshipMem.ExplicitBaseSquadCap = battleshipsToHave; } cleanup-for-missing-bolster-data.patch (4,520 bytes)
# HG changeset patch # User Tom Prince <[email protected]> # Date 1634510400 21600 # Sun Oct 17 16:40:00 2021 -0600 # Node ID 78137f5317ded8b7573bc5f417738b0203595836 # Parent 6e080cd656aa4cbfaf6e3f4064e280c4088339d5 Work around ``GetOrAddMembershipGroupBasedOnSquadType_WithUniqueIDForDuplicates`` category filtering. This uses the alternate overload of ``GetOrAddMembershipGroupBasedOnSquadType_WithUniqueIDForDuplicates``, by passing in a default cap. However, this has a bug that we can only use a byte for the differentiator. Hopefully every spire city will have differnet fleet IDs module 256. diff --git CodeExternal/AIWarExternalDeepProcessingCode/src/DeepInfo/DLC1/FallenSpireFactionDeepInfo.cs CodeExternal/AIWarExternalDeepProcessingCode/src/DeepInfo/DLC1/FallenSpireFactionDeepInfo.cs --- CodeExternal/AIWarExternalDeepProcessingCode/src/DeepInfo/DLC1/FallenSpireFactionDeepInfo.cs +++ CodeExternal/AIWarExternalDeepProcessingCode/src/DeepInfo/DLC1/FallenSpireFactionDeepInfo.cs @@ -2011,8 +2011,12 @@ namespace Arcen.AIW2.External otherMobileFleet.DoForMemberGroupsUnsorted_Sim( delegate ( FleetMembership mem ) { + if ( mem.FedHereFromCityFleetID == 0 ) { + mem.DespawnAllContentsFromNoLongerBolstering( Context ); + return DelReturn.RemoveAndContinue; //remove the entire line! + } //whoops, this is fed here from us! Time to clear it, since we're not bolstering that. - if ( mem.FedHereFromCityFleetID == fleetForCity.FleetID ) + if ( mem.FedHereFromCityFleetID == (byte)fleetForCity.FleetID ) { mem.DespawnAllContentsFromNoLongerBolstering( Context ); return DelReturn.RemoveAndContinue; //remove the entire line! @@ -2102,7 +2106,8 @@ namespace Arcen.AIW2.External continue; } int numberToHave = kv.Value; - FleetMembership mem = fleetForMobile.GetOrAddMembershipGroupBasedOnSquadType_WithUniqueIDForDuplicates( typeData, fleetForCity.FleetID ); + // Pass in numberToHave to get version of GetOrAddMembershipGroupBasedOnSquadType_WithUniqueIDForDuplicates that doesn't care about FleetCategory + FleetMembership mem = fleetForMobile.GetOrAddMembershipGroupBasedOnSquadType_WithUniqueIDForDuplicates( typeData, (byte)fleetForCity.FleetID, 0); //increase the cap only if the city is not disabled if ( mem.ExplicitBaseSquadCap < numberToHave && !isCityItselfDisabled ) mem.ExplicitBaseSquadCap = numberToHave; @@ -2127,14 +2132,14 @@ namespace Arcen.AIW2.External if ( cruisersToHave > 0 && !isCityItselfDisabled ) //increase the cap only if the city is not disabled { - FleetMembership cruiserMem = fleetForMobile.GetOrAddMembershipGroupBasedOnSquadType_WithUniqueIDForDuplicates( GameEntityTypeDataTable.Instance.GetRowByName( "SpireCruiser" ), fleetForCity.FleetID ); + FleetMembership cruiserMem = fleetForMobile.GetOrAddMembershipGroupBasedOnSquadType_WithUniqueIDForDuplicates( GameEntityTypeDataTable.Instance.GetRowByName( "SpireCruiser" ), (byte) fleetForCity.FleetID, 0 ); if ( cruiserMem.ExplicitBaseSquadCap < cruisersToHave ) cruiserMem.ExplicitBaseSquadCap = cruisersToHave; } if ( battleshipsToHave > 0 && !isCityItselfDisabled ) //increase the cap only if the city is not disabled { - FleetMembership battleshipMem = fleetForMobile.GetOrAddMembershipGroupBasedOnSquadType_WithUniqueIDForDuplicates( GameEntityTypeDataTable.Instance.GetRowByName( "SpireBattleship" ), fleetForCity.FleetID ); + FleetMembership battleshipMem = fleetForMobile.GetOrAddMembershipGroupBasedOnSquadType_WithUniqueIDForDuplicates( GameEntityTypeDataTable.Instance.GetRowByName( "SpireBattleship" ), (byte) fleetForCity.FleetID, 0 ); if ( battleshipMem.ExplicitBaseSquadCap < battleshipsToHave ) battleshipMem.ExplicitBaseSquadCap = battleshipsToHave; } |
Date Modified | Username | Field | Change |
---|---|---|---|
Oct 17, 2021 5:21 pm | tom.prince | New Issue | |
Oct 17, 2021 5:29 pm | tom.prince | Note Added: 0062977 | |
Oct 17, 2021 5:41 pm | tom.prince | Note Added: 0062978 | |
Oct 17, 2021 6:58 pm | tom.prince | Note Added: 0062979 | |
Oct 17, 2021 6:58 pm | tom.prince | File Added: spire-frigate-tracking.patch | |
Oct 17, 2021 6:58 pm | tom.prince | File Added: workaround-for-withuniqueidforduplicates-filtering.patch | |
Oct 17, 2021 6:58 pm | tom.prince | File Added: cleanup-for-missing-bolster-data.patch | |
Oct 17, 2021 6:59 pm | tom.prince | Description Updated | |
Oct 27, 2021 6:42 am | tom.prince | Assigned To | => tom.prince |
Oct 27, 2021 6:42 am | tom.prince | Status | new => resolved |
Oct 27, 2021 6:42 am | tom.prince | Resolution | open => fixed |
Oct 27, 2021 6:42 am | tom.prince | Fixed in Version | => Beta 3.740 Code Panopticon |