Jump to content

Replace a GameState function


cowfish13

Recommended Posts

Hello all,

I have a specific function in XCom_GameState_Unit I'm looking to overwrite with my own code.

Amineri on the topic of "How Do I Change X in the game?", states for overwriting: "This leaves out a few things, such as archetypes and game states, so it won't work for everything." Also, it's not great for mod compatibility. I'm currently dealing in XComGameState_Unit. I'm not sure if XComGameState_Unit considered a game state, because its more like a game object.


Currently, I am overwriting the class:

class XComGameState_Unit_NoRandCP extends XComGameState_Unit;

function GiveRandomPersonality()
{
 /*****CODE********/
}

GiveRandomPersonality is an existing class for XComGameState_Unit.

I'm looking for the best way to make all instances of "XComGameState_Unit.GiveRandomPersonality" utilize the GiveRandomPersonality function that I offer. My knowledge on inheritance is failing me at the moment.

Edited by cowfish13
Link to comment
Share on other sites

 

I'm not sure if XComGameState_Unit considered a game state

 

It's a game state because it inherits from XComGameState_BaseObject, and is managed by the XComGameStateHistory class.

 

Gamestates are what is serialized into the savefile when saving, and deserialized from the savefile when loading, which make trying to override them a tricky business. For example, what happens if a user applies your mod and then loads an existing campaign savefile? Since it's rife with potential errors, Firaxis decided to not allow the game state creation process to allow overrides.

 

Plus, even if it worked, overriding the whole class in order to change this one small aspect isn't really that great of a plan. Only one mod can override a particular class, so overrided XComGameState_Unit for this would make the mod incompatible with any other mod that wanted to do the same.

 

Unfortunately, there's not currently a clear, simple way to implement what you want. The ideal case would be if a TriggerEvent call were in place within the GiveRandomPersonality() method, so that it looked like :

function GiveRandomPersonality()
{
    local array<X2StrategyElementTemplate> PersonalityTemplates;
    local XGUnit UnitVisualizer;
    local XComHumanPawn HumanPawn;
    local int iChoice;

    PersonalityTemplates = class'X2StrategyElementTemplateManager'.static.GetStrategyElementTemplateManager().GetAllTemplatesOfClass(class'X2SoldierPersonalityTemplate');
    iChoice = `SYNC_RAND(PersonalityTemplates.Length);

    PersonalityTemplate = X2SoldierPersonalityTemplate(PersonalityTemplates[iChoice]);
    PersonalityTemplateName = PersonalityTemplate.DataName;
    kAppearance.iAttitude = iChoice; // Attitude needs to be in sync
    
    //Update the appearance stored in our visualizer if we have one
    UnitVisualizer = XGUnit(GetVisualizer());
    if (UnitVisualizer != none && UnitVisualizer.GetPawn() != none)
    {
        HumanPawn = XComHumanPawn(UnitVisualizer.GetPawn());
        if (HumanPawn != none)
        {
            HumanPawn.SetAppearance(kAppearance, false);
        }
    }

    `X2EVENTMGR.TriggerEvent('OnGiveRandomPersonality', self, self);
}

This would allow any number of mods to listen for the 'OnGiveRandomPersonality' EventID and then make adjustments. So different mods could handle different cases and (potentially) not conflict. Better still this wouldn't prevent other mods from interacting with XComGameState_Unit.

 

However, we aren't yet living in an ideal world, so we have to use somewhat uglier, hackier workarounds if you want to get things working. How I'd probably approach this would be to set up some sort of ScreenListener that is listening for various events, or triggers on certain UI transitions, then go in and look through the various places that units are stored and "patch up" the personality data the way that you want.

Link to comment
Share on other sites

Awesome, thank you! I'm very familiar with event listening as the last game I worked on used them. However, I do have a question on how am I supposed to put my Trigger Event inside GiveRandomPersonality, without doing a function overwrite with the class? Putting a trigger inside a function and overwriting a class seem mutually exclusive.

Link to comment
Share on other sites

Awesome, thank you! I'm very familiar with event listening as the last game I worked on used them. However, I do have a question on how am I supposed to put my Trigger Event inside GiveRandomPersonality, without doing a function overwrite with the class? Putting a trigger inside a function and overwriting a class seem mutually exclusive.

What Amineri is saying is that it would be in the base code already(we wouldn't need to inject our own), so we could easily hook into things like this. Unfortunately, this is not the case as of yet ... we may see more in the future, but no guarantees there.

 

I assume you are doing this for when new units are created, I would look and see if there is an event you can listen for to where when a unit is created and placed into the gamestate you can then call your function and modify the object on demand. This would bypass needing to override the base class, and would still be seamless from the user perspective.

Link to comment
Share on other sites

Sectoid's template is in X2Characters_DefaultCharacters.uc

CharTemplate.strPawnArchetypes.AddItem("GameUnit_Sectoid.ARC_GameUnit_Sectoid");

You can patch it up at any time, basically. Just don't forget to take difficulty variants into account.

 

 

I'm assuming (and fearing) that this same line of conversation applies to enemy template declarations?

 

I want to change which Archetype a Sectoid uses when it spawns, but I seem to be hitting a brick wall...

Link to comment
Share on other sites

  • Recently Browsing   0 members

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