Jump to content

No Permanent Death mod


VorticalBeans

Recommended Posts

I know that this is a main part of any XCOM game, but I've started a new campaign for EW, and I already beat Normal in EU and found it way too easy. So I've been playing Classic and dying a lot. The thing is some of my favorite missions are when half my team dies and I just barely scrape through to victory. The only problem is that afterwards I have to start over with all Rookies which is not very fun. So if somebody out there could make a mod where instead of my troops being permanently dead, they just get injured for a long time. I figured this would already be a mod, but I haven't been able to find it. Please if anybody could point me in the right direction or make this mod for me I would be soooooo thankful! Otherwise I'll probably just have to play more on Normal where I never lose missions and barely have to try... :-\

Thank you in advance for any help!

Link to comment
Share on other sites

Not necessarily speaking to the mod request itself, I can tell you that I also had a hard time transitioning from Normal difficulty to Classic difficulty at first. Then I realized that Normal had become so easy that my play had become really sloppy. I was charging straight up the middle of the map, fighting from low cover or sometimes even no cover at all, not worrying too much about destroying enemy cover, etc., none of which translated at all to Classic difficulty. I found the Impossible difficulty guide very useful for Classic. Classic now feels just as easy as Normal felt. Impossible is a different story...

Link to comment
Share on other sites

I've been poking around the UPKs, mapping out how death is handled, and I've rewritten the XGBattle_SP.BuildReturningDropshipSoldier function to resurrect any dead soldiers (set to 1 HP and gravely wounded) before they return to base. Currently this only happens if the mission was successful, but not if you leave them behind or outright lose the fight. I'm curious if people would rather have soldiers resurrected no matter what the outcome of the fight or only on success. Maybe I'll just post both versions. That's probably a good idea.

Link to comment
Share on other sites

I accidentally did this when adding a 'fatigue' mechanic to Long War.

 

Another place that this can be applied is in XGFacility_Barracks.PostMission in the XComStrategyGame.upk. This is where the DetermineTimeout function is called that sets the amount of injury time for returning soldiers.

 

It should be relatively straightforward to turn dead soldiers into gravely wounded ones by setting their HP to 1.

Link to comment
Share on other sites

It's just slightly more difficult than that. It's much harder to do it on the XComStrategyGame.upk side as you would have to expand the functions to include the logic to set dead soldiers' HPs to 1. I know that's possible now with wghost's discovery, but I'm only 10 days into my XCOM modding experience and this is the first function I've rewritten, so this is the best I can do for now. On the XComGame.upk side, I found I could delete enough from XGBattle_SP.BuildReturningDropshipSoldier to make room for any changes and they are actually pretty simple comparatively.

 

The original XGBattle_SP.BuildReturningDropshipSoldier:

 

 

protected function TTransferSoldier BuildReturningDropshipSoldier(XGUnit kSoldier, bool bFirstSoldier)
{
    local TTransferSoldier kTransferSoldier;
    local XGCharacter_Soldier kSoldierChar;
    local int iHP;

    kSoldierChar = XGCharacter_Soldier(kSoldier.GetCharacter());
    // End:0x73
    if(kSoldierChar == none)
    {
        kSoldierChar = XGCharacter_Tank(kSoldier.GetCharacter());
    }
    kTransferSoldier.kChar = kSoldierChar.m_kChar;
    kTransferSoldier.kSoldier = kSoldierChar.m_kSoldier;
    iHP = Min(kSoldier.m_iLowestHP, kSoldierChar.GetCharMaxStat(0));
    // End:0x177
    if(!kSoldier.IsDeadOrDying())
    {
        iHP = Clamp(iHP, 1, iHP);
    }
    kTransferSoldier.CauseOfDeathString = kSoldier.m_strCauseOfDeath;
    // End:0x274
    if((m_iResult != 1) && kSoldier.IsCriticallyWounded())
    {
        iHP = 0;
        kTransferSoldier.CauseOfDeathString = XComGameReplicationInfo(class'Engine'.static.GetCurrentWorldInfo().GRI).m_kGameCore.UnknownCauseOfDeathString;
    }
    // End:0x344
    if(kSoldier.m_bLeftBehind)
    {
        iHP = 0;
        kTransferSoldier.bLeftBehind = true;

        kTransferSoldier.CauseOfDeathString = XComGameReplicationInfo(class'Engine'.static.GetCurrentWorldInfo().GRI).m_kGameCore.UnknownCauseOfDeathString;
    }
    // End:0x55F
    if(Desc().m_bScripted && Desc().m_bDisableSoldierChatter)
    {
        // End:0x554
        if(bFirstSoldier)
        {
            iHP = kSoldierChar.GetCharMaxStat(0);
            // End:0x551

            if(kSoldierChar.m_kSoldier.iXP < XComGameReplicationInfo(class'Engine'.static.GetCurrentWorldInfo().GRI).m_kGameCore.GetXPRequired(kSoldierChar.m_kSoldier.iRank + 1))
            {
                kSoldierChar.SetXP(XComGameReplicationInfo(class'Engine'.static.GetCurrentWorldInfo().GRI).m_kGameCore.GetXPRequired(kSoldierChar.m_kSoldier.iRank + 1));
            }
        }
        // End:0x55F
        else
        {
            iHP = 0;
        }
    }
    kTransferSoldier.iHPAfterCombat = iHP;
    kTransferSoldier.iCriticalWoundsTaken = kSoldier.m_aCurrentStats[15];
    return kTransferSoldier;
    //return ReturnValue;    
}  

 

 

 

XGBattle_SP.BuildReturningDropshipSoldier no permanent death:

 

 

protected function TTransferSoldier BuildReturningDropshipSoldier(XGUnit kSoldier, bool bFirstSoldier)
{
    local TTransferSoldier kTransferSoldier;
    local XGCharacter_Soldier kSoldierChar;
    local int iHP;

    kSoldierChar = XGCharacter_Soldier(kSoldier.GetCharacter());
    // End:0x73
    if(kSoldierChar == none)
    {
        kSoldierChar = XGCharacter_Tank(kSoldier.GetCharacter());
    }
    kTransferSoldier.kChar = kSoldierChar.m_kChar;
    kTransferSoldier.kSoldier = kSoldierChar.m_kSoldier;
    iHP = Min(kSoldier.m_iLowestHP, kSoldierChar.GetCharMaxStat(0));
    iHP = Clamp(iHP, 1, iHP);
    kTransferSoldier.CauseOfDeathString = kSoldier.m_strCauseOfDeath;
    // End:0x250
    if((m_iResult != 1) && kSoldier.IsDeadOrDying())
    {
        iHP = 1;
        kTransferSoldier.CauseOfDeathString = XComGameReplicationInfo(class'Engine'.static.GetCurrentWorldInfo().GRI).m_kGameCore.UnknownCauseOfDeathString;
    }
    // End:0x320
    if(kSoldier.m_bLeftBehind)
    {
        iHP = 1;
        kTransferSoldier.bLeftBehind = true;        
        kTransferSoldier.CauseOfDeathString = XComGameReplicationInfo(class'Engine'.static.GetCurrentWorldInfo().GRI).m_kGameCore.UnknownCauseOfDeathString;
    }
    // End:0x53B
    if(Desc().m_bScripted && Desc().m_bDisableSoldierChatter)
    {
        // End:0x530
        if(bFirstSoldier)
        {
            iHP = kSoldierChar.GetCharMaxStat(0);
            // End:0x52D            
            if(kSoldierChar.m_kSoldier.iXP < XComGameReplicationInfo(class'Engine'.static.GetCurrentWorldInfo().GRI).m_kGameCore.GetXPRequired(kSoldierChar.m_kSoldier.iRank + 1))
            {                
                kSoldierChar.SetXP(XComGameReplicationInfo(class'Engine'.static.GetCurrentWorldInfo().GRI).m_kGameCore.GetXPRequired(kSoldierChar.m_kSoldier.iRank + 1));
            }
        }
        // End:0x53B
        else
        {
            iHP = 1;
        }
    }
    kTransferSoldier.iHPAfterCombat = iHP;
    kTransferSoldier.iCriticalWoundsTaken = kSoldier.m_aCurrentStats[15];
    return kTransferSoldier;
    return ReturnValue;
}

 

 

 

And finally you just change all the iHP = 1 entries to iHP = 0 if you want to have it only apply if a mission is successful. I have these all prepared as mod files for use with PatcherUPK and I'll be uploading them soon. I also could have deleted the cause of death strings, but they don't really affect anything, and I wanted to make as few overall changes to the code as possible.

Link to comment
Share on other sites

  • Recently Browsing   0 members

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