WOTCStrategyOverhaul / CovertInfiltration

A mod that overhauls the Covert Actions system to bring back the Infiltration mechanic from Long War 2
MIT License
21 stars 8 forks source link

Gather Survivors Mission - Personnel Rewards is not as expected #665

Closed TeslaRage closed 3 years ago

TeslaRage commented 3 years ago

In Gather Survivors mission where player needs to rescue the VIP (in CI, the VIP is a soldier) and the optional soldier, the rewards are not granted as expected.

Discussion on Discord starts from here: https://discord.com/channels/578606792448409610/639765305345835009/865403674204307507

Summarized test result in a table: https://discord.com/channels/578606792448409610/639765305345835009/865902572274319402

Mission result (whether the mission is successful or not) is as expected i.e. as long as the VIP is rescued, the mission is a success regardless of the status of the optional soldier.

Xymanek commented 3 years ago

So apparently it was found that with CI, that mission is missing the 2nd optional soldier, which is the actual bug here.

Digging, I found the following:

XGStrategy::LaunchTacticalBattle converts MissionState.Rewards into BattleData.RewardUnits. https://github.com/X2CommunityCore/X2WOTCCommunityHighlander/blob/fb6622d26fdae062153f9bad20b692a69705b1b1/X2WOTCCommunityHighlander/Src/XComGame/Classes/XGStrategy.uc#L500-L534

BattleData.RewardUnits is then used by XComTacticalMissionManager::CreatePawnCommon to set the actual unit in the battle + its objective metadata. If the unit is passed from strategy, it will use that one directly, otherwise create one from the default template specified in mission config. To check whether strategy has provided a unit, it does RewardUnitIndex >= BattleData.RewardUnits.Length. https://github.com/X2CommunityCore/X2WOTCCommunityHighlander/blob/fb6622d26fdae062153f9bad20b692a69705b1b1/X2WOTCCommunityHighlander/Src/XComGame/Classes/XComTacticalMissionManager.uc#L1017-L1044

RewardUnitIndex is by XComTacticalMissionManager::SpawnMissionObjectivesForInfo using the following logic:

1) RewardUnitIndex = SpawnInfo.SpawnVIPWithXComSquad ? 1 : 0; 2) Increment after each created unit

https://github.com/X2CommunityCore/X2WOTCCommunityHighlander/blob/fb6622d26fdae062153f9bad20b692a69705b1b1/X2WOTCCommunityHighlander/Src/XComGame/Classes/XComTacticalMissionManager.uc#L1486-L1499

So in our case it will be 0 since it spawns separate from the squad. What's in that slot? It's populated starting from

https://github.com/WOTCStrategyOverhaul/CovertInfiltration/blob/451083b88f9bdca5e3e87512df1e05d2100183b7/CovertInfiltration/Src/CovertInfiltration/Classes/X2StrategyElement_DefaultActivities.uc#L154-L206

Which means that slot 0 will be the unit tagged with SoldierRewardA - the same unit as the one which is used as the first optional, since the optional spawning uses the tags directly, without caring about the index.

In vanilla WOTC, the unit preparation is handled by X2StrategyElement_XpackMissionSources::BuildResOpMission which also spawns another unit - tagged with VIPReward - before spawning SoldierRewardA and (potentially) SoldierRewardB - which avoids the unit "reuse".


The solution here is probably to spawn some civilian in InformantAssaultSetup to be used as the objective unit. but we need to check carefully which other mission types and activities are involved/suffering from the same issue