XCOM Explosive Damage Destroys Corpses Development Notes

From Nexus Mods Wiki
Revision as of 04:06, 17 November 2018 by Dubiousintent (talk | contribs) (Added 'Category:Mod_Creation')
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

Overview

This article describes the information discovered while developing the Explosive Damage Mods.

Purpose of this modlet is to allow the options for aliens that are killed by explosions to have their corpses destroyed.

Details

Weapon Fragments are computed:

  • XGTacticalGameCore.GenerateWeaponFragments computes the amount.
  • Alien Grenade : 4 (0 for Long War)
  • Plasma Pistol : 8 (1 for Long War)
  • L. Plasma Rifle : 8 (1 for Long War)
  • Plasma Rifle : 12 (1 for Long War)
  • Cyberdisc Weapon : 16 (2 for Long War)
  • Drone Beam : 4 (0 for Long War)
  • Heavy Plasma : 20 (2 for Long War)
  • Sectopod Chest Cannon : 24 (3 for Long War)

This is then float multiplied by the FragmentBalance DGC.ini variable (=0.13 for Long War)

  • GenerateWeaponFragments is called in XGUnit.CheckForDamagedItems.

It is only called if the unit is !IsMine() && !m_bKilledByExplosion

  • The Weapon Fragments are then stored in the BattleDesc.m_arrArtifacts
    • This is controlled in XGSummaryUI.CollectArtifactsFromDeadAliens

There is also the call:

  • class'XComCollectible'.static.CollectCollectibles(m_kDesc.m_arrArtifacts);

made in XGBattle during state 'Done' -- unfortunately this is a native function

Code Breakdown

function CollectArtifactsFromDeadAliens()
{
    local XGInventorySlot kSlot;
    local XGSquad kSquad;
    local XGUnit kAlien;
    local int I, iSlot, iItem;
    local XGGameData.EItemType eItem, eCaptive;

    Desc().m_kDropShipCargoInfo.m_arrArtifacts.Remove(0, Desc().m_kDropShipCargoInfo.m_arrArtifacts.Length); // clears dropshipcargo artifacts
    Desc().m_kDropShipCargoInfo.m_arrArtifacts.Add(195); // reallocates space for dropshipcargo artifacts
    // End:0x13d Loop:False
    if(Desc().m_bScripted) // sets collected artifacts for tutorial mission
    {
        Desc().m_kDropShipCargoInfo.m_arrArtifacts[144] = 2;
        Desc().m_kDropShipCargoInfo.m_arrArtifacts[173] = 4;
        return;
    }
    I = 170 + 1;
    J0x14c:

    // End:0x1d2 Loop:True
    if(I < 190) // copies non-corpse/captive/weapon collectibles from BattleDesc (e.g. fragments, alloys, elerium, alien food)
    {
        Desc().m_kDropShipCargoInfo.m_arrArtifacts[I] = Desc().m_arrArtifacts[I];
        ++ I;
        // This is an implied JumpToken; Continue!
        goto J0x14c;
    }
    kSquad = XComTacticalGRI(class'Engine'.static.GetCurrentWorldInfo().GRI).m_kBattle.GetAIPlayer().GetSquad();
    I = 0;
    J0x265:

    // End:0xba1 Loop:True
    if(I < kSquad.GetNumPermanentMembers()) 
    {
        kAlien = kSquad.GetPermanentMemberAt(I);
        // End:0x37b Loop:False
        if(kAlien.m_bWasKilledByExplosion) // don't allow Sectoid Commanders to be "killed by explosion" in base attack missions
        {
            // End:0x37b Loop:False
            if(kAlien.GetCharacter().m_kChar.iType == 9)
            {
                // End:0x37b Loop:False
                if(Desc().m_iMissionType == 6)
                {
                    kAlien.m_bWasKilledByExplosion = false;
                }
            }
        }
        // End:0x38d Loop:False
        if(kAlien == none)
        {
        }
        // End:0xb93
        else
        {
            // End:0x4b5 Loop:False
            if(kAlien.m_bStunned) // store alien captive if stunned, except for outsiders
            {
                eCaptive = class'XGGameData'.static.CharToCaptive(byte(kAlien.GetCharacter().m_kChar.iType));
                // End:0x4b2 Loop:False
                if(kAlien.GetCharacter().m_kChar.iType != 18)
                {
                    Desc().m_kDropShipCargoInfo.m_arrArtifacts[eCaptive] += 1;
                }
            }
            // End:0x59f
            else
            {
                // End:0x4df Loop:False
                if(!kAlien.IsDead())
                {
                    // This is an implied JumpToken;
                    goto J0xb93;
                }
                // End:0x59f
                else // store alien corpses -- need to add conditional here to disallow this if kAlien.m_bWasKilledByExplosion
                {
                    iItem = class'XGGameData'.static.CharToCorpse(kAlien.GetCharacter().m_kChar.iType);
                    // End:0x59f Loop:False
                    if(iItem != 0)
                    {
                        Desc().m_kDropShipCargoInfo.m_arrArtifacts[iItem] += 1;
                    }
                }
            }
            // End:0x5c4 Loop:False
            if(kAlien.m_bWasKilledByExplosion)
            {
            }
            // End:0xb93
            else // get any 'non-special', 'non-damaged' primary items carried by aliens that were not killed by explosions -- this is nothing
            {
                iSlot = 0;
                J0x5cf:

                // End:0x78a Loop:True
                if(iSlot < 22)
                {
                    kSlot = kAlien.GetInventory().GetSlot(byte(iSlot));
                    // End:0x77c Loop:False
                    if(kSlot != none && (kSlot.m_bEnabled) && (kSlot.GetPrimaryItem() != none))
                    {
                        // End:0x6be Loop:False
                        if(kSlot.GetPrimaryItem().m_bDamaged)
                        {
                        }
                        // End:0x77c
                        else
                        {
                            iItem = kSlot.GetPrimaryItem().GameplayType();
                            // End:0x724 Loop:False
                            if(iItem > 29 && (iItem < 54))
                            {
                            }
                            // End:0x77c
                            else
                            {
                                eItem = byte(iItem);
                                Desc().m_kDropShipCargoInfo.m_arrArtifacts[eItem] += 1;
                            }
                        }
                    }
                    ++ iSlot;
                    // This is an implied JumpToken; Continue!
                    goto J0x5cf;
                }
                // End:0x88d Loop:False
                if(kAlien.GetCharacter().m_kChar.iType == 8) // get cyberdisc special artifacts
                {
                    Desc().m_kDropShipCargoInfo.m_arrArtifacts[171] += int(class'XGTacticalGameCore'.default.CYBERDISC_ELERIUM);
                    Desc().m_kDropShipCargoInfo.m_arrArtifacts[172] += int(class'XGTacticalGameCore'.default.CYBERDISC_ALLOYS);
                }
                // End:0xb93
                else
                {
                    // End:0x990 Loop:False
                    if(kAlien.GetCharacter().m_kChar.iType == 17) // get drone special artifacts
                    {
                        Desc().m_kDropShipCargoInfo.m_arrArtifacts[171] += int(class'XGTacticalGameCore'.default.DRONE_ELERIUM);
                        Desc().m_kDropShipCargoInfo.m_arrArtifacts[172] += int(class'XGTacticalGameCore'.default.DRONE_ALLOYS);
                    }
                    // End:0xb93
                    else
                    {
                        // End:0xa93 Loop:False
                        if(kAlien.GetCharacter().m_kChar.iType == 10) // get heavy floater special artifacts
                        {
                            Desc().m_kDropShipCargoInfo.m_arrArtifacts[171] += int(class'XGTacticalGameCore'.default.HFLOATER_ELERIUM);
                            Desc().m_kDropShipCargoInfo.m_arrArtifacts[172] += int(class'XGTacticalGameCore'.default.HFLOATER_ALLOYS);
                        }
                        // End:0xb93
                        else
                        {
                            // End:0xb93 Loop:False
                            if(kAlien.GetCharacter().m_kChar.iType == 16) // get sectopod special artifacts
                            {
                                Desc().m_kDropShipCargoInfo.m_arrArtifacts[171] += int(class'XGTacticalGameCore'.default.SECTOPOD_ELERIUM);
                                Desc().m_kDropShipCargoInfo.m_arrArtifacts[172] += int(class'XGTacticalGameCore'.default.SECTOPOD_ALLOYS);
                            }
                        }
                    }
                }
            }
        }
        ++ I;
        // This is an implied JumpToken; Continue!
        goto J0x265;
    }
    Desc().m_kDropShipCargoInfo.m_arrArtifacts[173] = Desc().m_arrArtifacts[173]; // copy weapon fragments
    Desc().m_kDropShipCargoInfo.m_arrArtifacts[191] = Desc().m_arrArtifacts[191]; // copy base shards
    // End:0xc92 Loop:False
    if(Desc().m_kDropShipCargoInfo.m_arrArtifacts[180] >= 1)
    {
    }
}


if (kAlien.m_bWasKilledByExplosion) (22 bytes)
07 7B 03 19 00 CC AD 00 00 0A 00 90 AF 00 00 00 2D 01 90 AF 00 00
change to:
07 8D 03 19 00 CC AD 00 00 0A 00 90 AF 00 00 00 2D 01 90 AF 00 00


if(kAlien == none) (14 bytes) -- if this is removed, and the jump offset for the previous is moved
{
}
// End:0xb93
else
07 8D 03 72 00 CC AD 00 00 2A 16 06 93 0B
change to:
0B 0B 0B 0B 00 CC AD 00 00 0B 0B 06 9F 05


function CollectArtifactsFromDeadAliens()
{
    local XGInventorySlot kSlot;
    local XGSquad kSquad;
    local XGUnit kAlien;
    local int I, iSlot, iItem;
    local XGGameData.EItemType eItem, eCaptive;

    Desc().m_kDropShipCargoInfo.m_arrArtifacts.Remove(0, Desc().m_kDropShipCargoInfo.m_arrArtifacts.Length);
    Desc().m_kDropShipCargoInfo.m_arrArtifacts.Add(195);
    // End:0x13D
    if(Desc().m_bScripted)
    {
        Desc().m_kDropShipCargoInfo.m_arrArtifacts[144] = 2;
        Desc().m_kDropShipCargoInfo.m_arrArtifacts[173] = 4;
        return;
    }
    I = 170 + 1;
    J0x14C:
    // End:0x1D2 [Loop If]
    if(I < 190)
    {
        Desc().m_kDropShipCargoInfo.m_arrArtifacts[I] = Desc().m_arrArtifacts[I];
        ++ I;
        // [Loop Continue]
        goto J0x14C;
    }
    kSquad = XComTacticalGRI(class'Engine'.static.GetCurrentWorldInfo().GRI).m_kBattle.GetAIPlayer().GetSquad();
    I = 0;
    J0x265:
    // End:0xBA1 [Loop If]
    if(I < kSquad.GetNumPermanentMembers())
    {
        kAlien = kSquad.GetPermanentMemberAt(I);
        // End:0x37B
        if(kAlien.m_bWasKilledByExplosion)
        {
            // End:0x37B
            if(kAlien.GetCharacter().m_kChar.iType == 9)
            {
                // End:0x37B
                if(Desc().m_iMissionType == 6)
                {
                    kAlien.m_bWasKilledByExplosion = false;
                }
            }
        }
        else
        {
             // End:0x4B5
            if(kAlien.m_bStunned)
            {
                eCaptive = class'XGGameData'.static.CharToCaptive(byte(kAlien.GetCharacter().m_kChar.iType));
                // End:0x4B2
                if(kAlien.GetCharacter().m_kChar.iType != 18)
                {
                    Desc().m_kDropShipCargoInfo.m_arrArtifacts[eCaptive] += 1;
                }
            }
            // End:0x59F
            else
            {
                // End:0x4DF
                if(!kAlien.IsDead())
                {
                    goto J0xB93;
                }
                // End:0x59F
                else
                {
                    iItem = class'XGGameData'.static.CharToCorpse(kAlien.GetCharacter().m_kChar.iType);
                    // End:0x59F
                    if(iItem != 0)
                    {
                        Desc().m_kDropShipCargoInfo.m_arrArtifacts[iItem] += 1;
                    }
                }
            }
        }
        // End:0x5C4
        if(kAlien.m_bWasKilledByExplosion)
        {
        }
        // End:0xB93
        else
        {
            iSlot = 0;
            J0x5CF:
            // End:0x78A [Loop If]
            if(iSlot < 22)
            {
                kSlot = kAlien.GetInventory().GetSlot(byte(iSlot));
                // End:0x77C
                if(((kSlot != none) && kSlot.m_bEnabled) && kSlot.GetPrimaryItem() != none)
                {
                    // End:0x6BE
                    if(kSlot.GetPrimaryItem().m_bDamaged)
                    {
                    }
                    // End:0x77C
                    else
                    {
                        iItem = kSlot.GetPrimaryItem().GameplayType();
                        // End:0x724
                        if((iItem > 29) && iItem < 54)
                        {
                        }
                        // End:0x77C
                        else
                        {
                            eItem = byte(iItem);
                            Desc().m_kDropShipCargoInfo.m_arrArtifacts[eItem] += 1;
                        }
                    }
                }
                ++ iSlot;
                // [Loop Continue]
                goto J0x5CF;
            }
            // End:0x88D
            if(kAlien.GetCharacter().m_kChar.iType == 8)
            {
                Desc().m_kDropShipCargoInfo.m_arrArtifacts[171] += int(class'XGTacticalGameCore'.default.CYBERDISC_ELERIUM);
                Desc().m_kDropShipCargoInfo.m_arrArtifacts[172] += int(class'XGTacticalGameCore'.default.CYBERDISC_ALLOYS);
            }
            // End:0xB93
            else
            {
                // End:0x990
                if(kAlien.GetCharacter().m_kChar.iType == 17)
                {
                    Desc().m_kDropShipCargoInfo.m_arrArtifacts[171] += int(class'XGTacticalGameCore'.default.DRONE_ELERIUM);
                    Desc().m_kDropShipCargoInfo.m_arrArtifacts[172] += int(class'XGTacticalGameCore'.default.DRONE_ALLOYS);
                }
                // End:0xB93
                else
                {
                    // End:0xA93
                    if(kAlien.GetCharacter().m_kChar.iType == 10)
                    {
                        Desc().m_kDropShipCargoInfo.m_arrArtifacts[171] += int(class'XGTacticalGameCore'.default.HFLOATER_ELERIUM);
                        Desc().m_kDropShipCargoInfo.m_arrArtifacts[172] += int(class'XGTacticalGameCore'.default.HFLOATER_ALLOYS);
                    }
                    // End:0xB93
                    else
                    {
                        // End:0xB93
                        if(kAlien.GetCharacter().m_kChar.iType == 16)
                        {
                            Desc().m_kDropShipCargoInfo.m_arrArtifacts[171] += int(class'XGTacticalGameCore'.default.SECTOPOD_ELERIUM);
                            Desc().m_kDropShipCargoInfo.m_arrArtifacts[172] += int(class'XGTacticalGameCore'.default.SECTOPOD_ALLOYS);
                        }
                    }
                }
            }
        }
        ++ I;
        // [Loop Continue]
        goto J0x265;
    }
    Desc().m_kDropShipCargoInfo.m_arrArtifacts[173] = Desc().m_arrArtifacts[173];
    Desc().m_kDropShipCargoInfo.m_arrArtifacts[191] = Desc().m_arrArtifacts[191];
    // End:0xC92
    if(Desc().m_kDropShipCargoInfo.m_arrArtifacts[180] >= 1)
    {
    }
    //return;    
}

Code Changes


hex chunk before:
07 7B 03 19 00 CC AD 00 00 0A 00 90 AF 00 00 00 2D 01 90 AF 00 00 07 7B 03 9A 35 D3 0D 00 00 D5 0D 00 00 00 00 19 19 00 CC AD 00 00 0A 00 63 B4 00 00 00 1B 7B 31 00 00 00 00 00 00 16 09 00 C3 A2 00 00 00 01 C3 A2 00 00 2C 09 16 07 7B 03 9A 19 1B BD 19 00 00 00 00 00 00 16 09 00 B0 9F 00 00 00 01 B0 9F 00 00 2C 06 16 14 19 00 CC AD 00 00 0A 00 90 AF 00 00 00 2D 01 90 AF 00 00 28 07 8D 03 72 00 CC AD 00 00 2A 16 06 93 0B 

hex chunk before:
07 8D 03 19 00 CC AD 00 00 0A 00 90 AF 00 00 00 2D 01 90 AF 00 00 07 7B 03 9A 35 D3 0D 00 00 D5 0D 00 00 00 00 19 19 00 CC AD 00 00 0A 00 63 B4 00 00 00 1B 7B 31 00 00 00 00 00 00 16 09 00 C3 A2 00 00 00 01 C3 A2 00 00 2C 09 16 07 7B 03 9A 19 1B BD 19 00 00 00 00 00 00 16 09 00 B0 9F 00 00 00 01 B0 9F 00 00 2C 06 16 14 19 00 CC AD 00 00 0A 00 90 AF 00 00 00 2D 01 90 AF 00 00 28 0B 0B 0B 0B 00 CC AD 00 00 0B 0B 06 9F 05 

if (kAlien.m_bWasKilledByExplosion) (22 bytes)
07 7B 03 19 00 CC AD 00 00 0A 00 90 AF 00 00 00 2D 01 90 AF 00 00
change to:
07 8D 03 19 00 CC AD 00 00 0A 00 90 AF 00 00 00 2D 01 90 AF 00 00


if(kAlien == none) (14 bytes) -- if this is removed, and the jump offset for the previous is moved
{
}
// End:0xb93
else
07 8D 03 72 00 CC AD 00 00 2A 16 06 93 0B
change to:
0B 0B 0B 0B 00 CC AD 00 00 0B 0B 06 9F 05


Reference

Referred to by this article:

That refer to this article: