Jump to content

Mod- Explosions destroy corpses


Amineri

Recommended Posts

I happened across this section of code, and it turned out to be a pretty straightforward hex change to make explosion-related deaths destroy corpses as well as preventing any weapon fragments from being collected.

 

This may be handy for those mods with many more tactical battles, to help prevent excessive piling-up of unsightly and smelly alien corpses.

 

The change is in XGSummaryUI.CollectArtifactsFromDeadAliens

 

((this is not where the weapon fragment generation code is located, interestingly)).

 

Hex Change to XcomGame.upk

 

 

 

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

The code change is kind of subtle. I changed the jump offset of one (kalien.m_bWasKilledByExplosion), deleted another conditional, and subverted the second conditional's else statement to act as the first ones (also changed the jump offset of the else statement). Kinda ninja, if I do say so myself ^_^
Decompiled code before:

if(kAlien.m_bWasKilledByExplosion)
{
// 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)
{
}

code segment after:

if(kAlien.m_bWasKilledByExplosion)
{
// End:0x37B
if(kAlien.GetCharacter().m_kChar.iType == 9)
{
// End:0x37B
if(Desc().m_iMissionType == 6)
{
kAlien.m_bWasKilledByExplosion = false;
}
}
kAlien
}
// End:0x59F
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)
{
}

The game had a cheat in it that even if you killed the Sectoid Commander at the alien base with explosion, it would be marked as having been NOT killed by explosion. This has been fixed. In fact, if you kill the Sectoid Commander at the alien base with an explosion, you won't even get a corpse ^_^.
Good times!

 

Link to comment
Share on other sites

  • 2 weeks later...

Hey, I just implemented this mod and I've noticed that now I'm collecting smoke grenades from sectoids, but I'm not sure exactly what's happening here 'cause those are added to storage (in engineering each of those items I collect it increases the count of the same smoke grenade item I can manufacture, and I can equip them, but in the tactical game it doesn't report ability charges, although I've checked twice the UpdateItemCharges function and it's ok, item 86, so maybe it's a duplicate item)...

btw I haven't tried to capture an alive alien yet, but shouldn't the inventory slots loop be in the kAlien.m_bStunned block? Definitively I'm not collecting plasma pistols from dead sectoids, so I'm clearly quite lost as how this all works... any hint is appreciated.

Link to comment
Share on other sites

I did manage to get this mod's notes and such posted up on the wiki, here: http://wiki.tesnexus.com/index.php/Explosive_Damage_-_XCOM:EU_2012

 

The only change is in XcomGame.upk >> XGSummaryUI.CollectArtifactsFromDeadAliens

 

Here's how I intended the mod to work:

The original function begins with a conditional block:

kAlien = kSquad.GetPermanentMemberAt(I);
// End:0x37B
if(kAlien.m_bWasKilledByExplosion)
{
if(kAlien.GetCharacter().m_kChar.iType == 9)
{
if(Desc().m_iMissionType == 6)
{
kAlien.m_bWasKilledByExplosion = false;
}
}
}

The purpose of this block is to prevent Sectoid Commander corpses from being destroyed in the base attack mission.
It is then followed by a block that creates captives and corpses.

 

if(kAlien == none)
{
}
// End:0xB93
else
{
if(kAlien.m_bStunned)
{
eCaptive = class'XGGameData'.static.CharToCaptive(byte(kAlien.GetCharacter().m_kChar.iType));
if(kAlien.GetCharacter().m_kChar.iType != 18)
{
Desc().m_kDropShipCargoInfo.m_arrArtifacts[eCaptive] += 1;
}
}
else
{
if(!kAlien.IsDead())
{
}
else
{
iItem = class'XGGameData'.static.CharToCorpse(kAlien.GetCharacter().m_kChar.iType);
if(iItem != 0)
{
Desc().m_kDropShipCargoInfo.m_arrArtifacts[iItem] += 1;
}
}
}

...((continuing to end of function))

 

I modified the small area around the if(kAlien == none), turning that section into an "else" block for the earlier conditional.

 

This results in:

 

if(kAlien.m_bWasKilledByExplosion)
{
// End:0x37B
if(kAlien.GetCharacter().m_kChar.iType == 9)
{
// End:0x37B
if(Desc().m_iMissionType == 6)
{
kAlien.m_bWasKilledByExplosion = false;
}
}
kAlien
}
// End:0x59F
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;
}
}
}
}

 

This makes the second part (where the alien corpses and captives are generated) only execute when the if(kAlien.m_bWasKilledByExplosion) evaluates false.

 

I think that the inventory slots loop:

 

if(I < 190)
{
Desc().m_kDropShipCargoInfo.m_arrArtifacts[I] = Desc().m_arrArtifacts[I];
++ I;
// [Loop Continue]
goto J0x14C;
}

 

is outside the "destroyed by explosion" / "is stunned" area because the game must create those artifacts when the alien is killed. This also originally would have allowed soldiers to pick up artifacts or collect artifacts in other ways during a mission (in the OG, it was possible to pick up an alien weapon that it had dropped, then retreat to the skyranger and abort).

 

I'm not sure why you would be collecting smoke grenades from sectoids, tbh ...

Link to comment
Share on other sites

all this pieces of code looks the same in my function, except for the sectoid commander that I set to true (it would only check if already was killed by explosives, so just confirming that :) ), the only difference there might be I don't include smoke grenades in the infinite items array. I thought I could've messed something up but the strange thing is that I still get the corpses and weapon fragments from aliens not killed by explosives, so the mod is working, but I get the same number of smoke grenades than sectoid corpses... so I guess they have a smoke grenade item in their inventory, or I'm adding it to them... the only possible case is if they run the UpdateItemCharges and they have the "smoke and mirrors" perk, in that case I'd be giving them a smoke grenade item... is that possible? By the way when implementing the mod I followed the instructions and made that ninja edit, jumps and offsets match yours.

Link to comment
Share on other sites

The infinite items array should even be visible from the tactical game, where this code is being run.

 

It looks as though somehow your m_arrArtifacts is getting things added to it. Digging through the code I found that XGBattle.<state 'Done'> is where the artifacts (such as weapons and grenades) appear to be added to the artifact array.

 

This is done via a call to : class'XComCollectible'.static.CollectCollectibles(m_kDesc.m_arrArtifacts);

 

Unfortunately, CollectCollectibles is a native function, so it's entirely unclear how it's determining what items get added to the artifacts array. All I can speculate is that some other change you've made has caused this function to add the smoke grenade item to the m_arrArtifacts array.

 

As a quick double check you could suppress the line : Desc().m_kDropShipCargoInfo.m_arrArtifacts[I] = Desc().m_arrArtifacts[I];

in XGSummaryUI.CollectArtifactsFromDeadAliens and see if that prevents sectoids from giving you smoke grenades (it will also prevent you from getting and weapons from captured aliens, I think). This isn't a permanant solution ... just a double check to make sure that the alien weapons aren't being added from some other source.

Link to comment
Share on other sites

  • Recently Browsing   0 members

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