Ever since I modded the gaian terraformer, I've had bug reports of gaians spawning with literally hundreds of high-level weapons on board. I have been puzzling over this for about a year, and I've finally cracked it as much as I can.
The weapons that get spammed are always the secondary guns, which I change from the stock thermo cannon to a non-ammo weapon. Changing the weapon changes what the game spams over to the new one. Oddly the weapon involved seems as though it may impact how many get spawned as well.
This only happens on 'naturally' spawned terraformers: ships spawned with the debug console or with testing god-mods don't show this behaviour. They only ever have up to four guns in their loot. But the encounters have between 26 (gaian nanite gun-equipped fresh spawns) and well over 100 (older ships with the P51) weapons stuffed into the cargo hold. This doesn't happen in vanilla though: repeated tests show only normal behaviour with vanilla terraformers. Most recently I was finally able to replicate this with Elemental Shift running by hand-spawning the encounter stations themselves.
The only difference between the ship spawned by itself, and a ship spawned in the encounter? The gaian encounter has a (probably very old) custom controller.
QED: there's something funky in that controller, possibly something designed around ammunition levels that wasn't built to be future-proof, that is causing abnormal behaviour and the duplication of the terraformer's secondary weapons as cargo-hold items when a mod alters the ship to use different (possibly only non-ammo) secondary weapons.
Here’s the screenshot of something I did in the console for testing (and ignore the typo that ran the wrong item list in the middle of all that):
https://cdn.discordapp.com/attachments/395488409206128650/823299814455377930/Screenshot_at_2021-03-21_16-56-53.png
Neither Processor spawned with an excessive stack of a specific weapon, so it’s not specifically the 'gaianProcessor
controller that’s causing the bug…?
Further SCIENCE! while running Elemental Shift:
https://cdn.discordapp.com/attachments/395488409206128650/823607093910962186/unknown.png
Apparently they don’t spawn with massive stacks of a single weapon, so Song and I figured that it has to happen after the fact. Spawning one in the intro screen with the 'gaianProcessor
controller and letting it vacuum up a wreck or two yielded the following:
https://cdn.discordapp.com/attachments/395488409206128650/823611434747428945/unknown.png
So basically something weird is probably happening in either the controller or in the vacuuming process.
I spent some time looking at the Gaian controller code:
https://github.com/kronosaur/TranscendenceDev/blob/master/Mammoth/TSE/CGaianProcessor.cpp
And then the weapon code that the controller calls:
https://github.com/kronosaur/TranscendenceDev/blob/02d94b8cc68551500e796c88442709a5b6875a36/Mammoth/TSE/CWeaponClass.cpp
On line 220 of the gaian controller, it calls `GetSelectedVariantInfo(m_pShip, NULL, NULL, &pAmmoType);`
If we look at the type signature of GetSelectedVariantInfo, it is:
void CWeaponClass::GetSelectedVariantInfo (const CSpaceObject *pSource,
const CInstalledDevice *pDevice,
CString *retsLabel,
int *retiAmmoLeft,
CItemType **retpType,
bool bUseCustomAmmoCountHandler)
Notice that the `pAmmoType` that we pass to the function is the fourth parameter, which the function says is retiAmmoLeft, i.e. the amount of ammo left on the device. But the Gaian controller code thinks this is a *type*, not a *quantity*.
I can't swear this is the correct fix, but I strongly suspect that what needs to happen here is inserting a third NULL into the call to GetSelectedVariantInfo, i.e. `Weapon.GetSelectedVariantInfo(m_pShip, NULL, NULL, NULL, &pAmmoType);`. That would actually match the type signature of the function (i.e. we'd be passing a CItemType** value to a CItemType** parameter, instead of passing a CItemType** to an int* parameter).