Jump to content

Loadout questions


Krazyguy75

Recommended Posts

So, I've been looking at the loadout arrays in defaultloadouts.ini, and I'm still not sure what is what.

 

From what I can gather, pistols and armor are obvious, large items are primary weapons, small items are miscellaneous, and custom items are alien ability items (psi amp, plague, etc). Is this a correct assumption?

 

If so, why are aliens allowed so many primary weapons? Is it just a placeholder? Can they even use all of them?

Link to comment
Share on other sites

XCOM soldier get custom items too. The Grapple item is added as a custom item to any soldier wearing Skeleton or Ghost Armor, and the Psi Amp is given to any psionic soldier. Both of these happen dynamically in the code.

 

The general data structure for what I call "primitive inventory" is the TInventory structure. It contains space for:

  • 1 Armor item
  • 1 Pistol item
  • 16 Large Items
  • 16 Small Items
  • 16 Custom Items

These are static arrays, not dynamic. I think these were sized back when the game was a more direct translation of the original, when there was more inventory in general. All units share this inventory structure, both XCOM soldiers and tanks, as well as all varieties of aliens and even civilians.

 

Until EW, the most large items I saw on any unit was 2. Heavies carry 2 large items (LMG + Rocket Launcher) and Sectopods carry 2 large items (SectopodChestCannon + SectopodCannon). SectopodClusterBomb is classified as a small item.

 

However, for MECs all of the new weapon systems are large items. This means that a fully-equipped Paladin MEC suit (and a rifle) ends up equipped with 4 large items. This is handled behind the scenes and not in the Locker loadout screen.

 

In the XGStrategy.BuildTransferSoldier function are the lines :

    if(IsAugmented())
    {
        class'XGGameData'.static.GetMecArmorAndWeapons(byte(m_kChar.kInventory.iArmor), eBaseArmor, ePrimaryWeapon, eSecondaryWeapon, eTertiaryWeapon);
        kTransfer.kChar.kInventory.iArmor = eBaseArmor;
        if(ePrimaryWeapon != 0)
        {
            class'XGTacticalGameCoreNativeBase'.static.TInventoryLargeItemsAddItem(kTransfer.kChar.kInventory, ePrimaryWeapon);
        }
        if(eSecondaryWeapon != 0)
        {
            class'XGTacticalGameCoreNativeBase'.static.TInventoryLargeItemsAddItem(kTransfer.kChar.kInventory, eSecondaryWeapon);
        }
        if(eTertiaryWeapon != 0)
        {
            class'XGTacticalGameCoreNativeBase'.static.TInventoryLargeItemsAddItem(kTransfer.kChar.kInventory, eTertiaryWeapon);
        }
    }

This translates from the 17 "weapon-specific MEC armor variants" into the specific 6 weapon systems that go into the particular large item slots.

 

-------

As for the aliens, generally their mesh models are pretty limited in terms of sockets, so they can't have different weapons plugged in very easily. (In contrast with XCOM soldier unit pawns, which are quite flexible in this regard). The only aliens I know of that allow for 2 different weapons to be plugged into their weapon socket is the basic Muton. Even the XCOM SHIV has only 1 weapon socket, and that only accepts the 3 basic SHIV weapon models. I've experimented with giving SHIVs other weapons (like LMGs), and they almost work. They fit and the firing animations work, but the movement animation breaks and the game hangs if a SHIV + LMG tries to move.

 

I haven't experimented as much yet with trying to swap alien weapons, and what experimenting I've done hasn't been successful.

 

If you look at the loose Weapon_*_SF.upk files in the CookedPCConsole folder, you'll see that there are actually variant models of various weapons tuned to particular aliens. So :

  • Weapon_PlasmaRifleLight_SF.upk
  • Weapon_PlasmaRifle_ThinMan_SF.upk
  • Weapon_PlasmaRfLtOutsider_SF.upk
  • Weapon_PlasmaRifleLt_Muton_SF.upk

I think the Firaxis 3D modelers/animators "tuned" each of the weapon models to look/work with each particular alien type.

Link to comment
Share on other sites

If I'm understand you correctly, the attachment points for objects is defined within the mesh object (or something like that, I'm not a 3D modelling expert) itself.

 

When I've used Gildor's umodel tool to view various 3D models there is an option for displaying attachment points, so I'm pretty sure its set there and not within unrealscript.

 

For aliens the mapping from TInventory to XGInventoryItem (XGInventory manages the items as attached to the unit pawns) happens in XGLoadoutMgr.ConvertTInventoryToAlienLoadout.

 

It appears that :

Loadout.Items[11] = class<XGWeapon>(class'XGItemLibrary'.static.GetItem(kInventory.iPistol));

Loadout.Items[3] = class<XGWeapon>(class'XGItemLibrary'.static.GetItem(kInventory.arrLargeItems[0]));

Loadout.Items[4] = class<XGWeapon>(class'XGItemLibrary'.static.GetItem(kInventory.arrLargeItems[1]));

Loadout.Items[7] = class<XGWeapon>(class'XGItemLibrary'.static.GetItem(kInventory.arrSmallItems[0]));

 

No small items above the 1st small item can be mapped.

 

Similarly for soldiers only the first 3 non-Backpack small items get mapped into a Loadout index. This can be an issue if using a mod that grants a large number of small items slots and equipping the soldier with many grenades or other non-backpack small items.

 

Oh, I almost forgot ... there is an enum that defines the various Loadout Locations used (defined in XGInventoryItemNativeBase) :

 

 

enum ELocation
{
    eSlot_None,
    eSlot_RightBack,
    eSlot_LeftBack,
    eSlot_RightHand,
    eSlot_LeftHand,
    eSlot_Grapple,
    eSlot_RightThigh,
    eSlot_LeftThigh,
    eSlot_LeftBelt,
    eSlot_RightChest,
    eSlot_LeftChest,
    eSlot_RightForearm,
    eSlot_RightSling,
    eSlot_RearBackPack,
    eSlot_PsiSource,
    eSlot_Head,
    eSlot_CenterChest,
    eSlot_Claw_R,
    eSlot_Claw_L,
    eSlot_ChestCannon,
    eSlot_KineticStrike,
    eSlot_Flamethrower,
    eSlot_ElectroPulse,
    eSlot_GrenadeLauncher,
    eSlot_PMineLauncher,
    eSlot_RestorativeMist,
    eSlot_MAX
}; 

 

 

 

The default loadout positions for XCOM soldier large weapons is actually in the RightBack and LeftBack slots. Only the equip action makes a soldier move the weapon from the back to their RightHand. However aliens by default load their large weapons into the RightHand slot (so you never don't see aliens swap their weapons to their backs when performing another action like soldiers do when using a Medikit, for example).

Link to comment
Share on other sites

When going through some of my notes (in particular fixing the glitch where the SHIV sentry gun would not display in the Barracks view), I came across some of my notes concerning how weapons are loaded out.

 

Thought someone might find it useful (it's just my personal notes, so may be a little "stream of consciousness")

 

 

 

Just as with the aliens, the mesh / animation information has to be loaded.

This occurs in XGBattleDesc

For aliens the function is InitAlienLoadoutInfos

For XCOM it appears to be either InitHumanLoadoutInfosFromDropshipCargoInfo or InitHumanLoadoutInfosFromProfileSettingsSaveData

InitHumanLoadoutInfosFromDropshipCargoInfo loops over soldiers in the m_kDropshipCargoInfo and sets up mesh/animations to load using :
                UnitContent = BuildSoldierContent(m_kDropShipCargoInfo.m_arrSoldiers[UnitIndex]);
                m_arrTeamLoadoutInfos[PlayerIndex].m_arrUnits.AddItem(UnitContent);
				
InitHumanLoadoutInfosFromProfileSettingsSaveData is similar, but uses the kProfileSettings structure and :
                TransferSoldier = kProfileSettings.m_aSoldiers[UnitIndex];
                UnitContent = BuildUnitContentFromEnums(byte(TransferSoldier.kChar.kInventory.arrLargeItems[0]), byte(TransferSoldier.kChar.kInventory.iPistol), byte(TransferSoldier.kChar.kInventory.iArmor), byte(TransferSoldier.kChar.kInventory.arrSmallItems[0]), byte(TransferSoldier.kSoldier.kAppearance.iGender));
                m_arrTeamLoadoutInfos[PlayerIndex].m_arrUnits.AddItem(UnitContent);
				
This appears to most likely be related to Multiplayer. BuildUnitContentFromEnums uses a fixed Head type, so can't be getting used during a campaign.


The InitHumanLoadoutInfosFromDropshipCargoInfo is called from XComTacticalGRI.InitBattle

The InitHumanLoadoutInfosFromProfileSettingsSaveData is called from XGBattle_MP.InitDescription and from XGBattle_SP.InitDescription if m_kTransferSave != none is false.


In BuildSoldierContent are the lines :
    kContent.iPawn = MapSoldierToPawn(kTransfer.kChar.kInventory.iArmor, kTransfer.kSoldier.kAppearance.iGender); // sets base armor pawn type based on armor/gender
    kContent.iKit = DetermineSoldierKit(kTransfer, kContent.iPawn);  // determines kit based on primary weapon / armor (weapon + armor overlay)
    kContent.kAppearance = kTransfer.kSoldier.kAppearance;   // sets head based on customization options
    kContent.kInventory = kTransfer.kChar.kInventory;           // sets rest of inventory
	
The kContent.kInventory must be the source of the problem. For a First Aid Kit the ID will be 83 instead of 76. Similarly the Sentry gun could have problems here.

All of this information is stored in the XGBattleDesc class array m_arrTeamLoadoutInfos. In XGBattleDesc this is only filled out. It is a protected variable, and has the accessor function GetTeamLoadoutInfo. If this function is called, it is called by native code / Unreal Engine code, as it is never accessed from the upk file.


The key function appears to be DeterminePawnContent, which calls DetermineAlienPawnContent and DetermineSoldierPawnContent
        if((m_kBattle.m_kDesc != none) && WorldInfo.NetMode == NM_Standalone)
        {
            Content = m_kBattle.m_kDesc.DeterminePawnContent();
            XComContentManager(class'Engine'.static.GetEngine().GetContentManager()).RequestContent(Content, true);
            XComContentManager(class'Engine'.static.GetEngine().GetContentManager()).RequestContentForCheckpoint(OnlineEventMgr.CurrentTacticalCheckpoint);
            PostLoad_LoadRequiredContent(XComContentManager(class'Engine'.static.GetEngine().GetContentManager()));
is called in XComTacticalGRI.InitBattle. This is what is loading the mesh/animation information.

Ultimately it is the function XGBattleDesc.BuildSoldierContent that is building the content structure for each soldier.

static function TSoldierPawnContent BuildSoldierContent(TTransferSoldier kTransfer)
{
    local TSoldierPawnContent kContent;

    // End:0x1D2
    if(((kTransfer.kChar.kInventory.iArmor == 59) || kTransfer.kChar.kInventory.iArmor == 62) && XComGameReplicationInfo(class'Engine'.static.GetCurrentWorldInfo().GRI).m_kGameCore.TInventoryCustomItemsFind(kTransfer.kChar.kInventory, 36) == -1)
    {
        XComGameReplicationInfo(class'Engine'.static.GetCurrentWorldInfo().GRI).m_kGameCore.TInventoryCustomItemsAddItem(kTransfer.kChar.kInventory, 36);
    }
    // End:0x397
    if(XComGameReplicationInfo(class'Engine'.static.GetCurrentWorldInfo().GRI).m_kGameCore.CharacterIsPsionic(kTransfer.kChar) && XComGameReplicationInfo(class'Engine'.static.GetCurrentWorldInfo().GRI).m_kGameCore.TInventoryCustomItemsFind(kTransfer.kChar.kInventory, 35) == -1)
    {
        XComGameReplicationInfo(class'Engine'.static.GetCurrentWorldInfo().GRI).m_kGameCore.TInventoryCustomItemsAddItem(kTransfer.kChar.kInventory, 35);
    }
    kContent.iPawn = MapSoldierToPawn(kTransfer.kChar.kInventory.iArmor, kTransfer.kSoldier.kAppearance.iGender);
    kContent.iKit = DetermineSoldierKit(kTransfer, kContent.iPawn);
    kContent.kAppearance = kTransfer.kSoldier.kAppearance;
    kContent.kInventory = kTransfer.kChar.kInventory;
    return kContent;
    //return ReturnValue;    
}

The first conditional is adding the grapple item to the Skeleton / Ghost armors if the unit doesn't already have the grapple.

The second conditional is adding the PsiAmp item if the character is psionic and doesn't already have the item.

Then the base pawn is set based on armor / sex.

Then the kit is determined based on pawn type (e.g. armor) and weapon

Then the head is set based on appearance.

Then the entire soldier inventory is copied over

 

 

Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...