Overriding part of the game

For technical discussions and help
Post Reply
lyravega
Posts: 10
Joined: Thu Feb 11, 2016 8:58 pm

Overriding part of the game

Post by lyravega »

I've tried several ways to tackle this issue, and I am about to give up. To simply put it, my mod simply alters a base template; Proving Grounds facility. Adds an upgrade, another staff slot, and locks that staff slot. Upgrade simply unlocks this locked staff slot.

My attempts:
-OnLoadSaveGame() - This first attempt was obviously flawed, as this function runs only once. However, I made my changes here to not override anything in the base classes, but instead extend them "externally". When a user loads the save game, with this save installed for the first time, the changes can be seen in the game; there is an extra staff slot which is locked, and upgrade button is there. However, if you rebuild the facility, or build it for the first time in the next session, it is not - hence the flawed part.

-Overriding the base class - My second attempt was overriding the base class which has these templates. However, my changes are rejected as the template names already do exist - at least the red screen errors tell me so. Which is both good and a bad thing. Good because it seemed to be on the right track, bad because I cannot suppress the base template creation class. I forgot to do one thing though, which I'll come later.

-Hooking up a screen listener - My third attempt was an ugly one; changing the template via a listener. This is ugly because it only has to be done once, and it can create more problems for me that I cannot foresee. This was also unsuccessful though. Probably I did something wrong here though, but if I can, I'd like to avoid this as it is an ugly solution for my case.

-Overriding the base class (again) - I noticed on these forums that I need to add something to the Engine.ini file in order to properly override a base class. However it is also said there that this won't work on everything, but I gave it a try anyway. Nevertheless, I tried adding the proper line to my Engine.ini file, hoping that it'd suppress the base class, but it resulted in the same thing as my first override attempt.

-Experimental half-attempts - These are half-attempts because I never got to finish them, and they wouldn't work anyway. And it'd also break any other mod that extended DLCInfo class, most probably. What I tried is, to create a new function similar to OnLoadSaveGame(), but it'd be executed on every load, and not just once. I've found the related classes, where OnLoadSaveGame() is executed - it is a simple matter of true / false (if true, only new DLC & Mod OnLoadSaveGame() functions are executed, if false they'll be skipped). There are two ways to go, either ignoring this boolean, and making OnLoadSaveGame() get executed everytime, or creating a 2nd instance for this check, and linking a new function (such as OnEveryLoad()) to this. Needless to say, since my previous override attempts were a failure, I didn't do this, as it'd most probably fail as well anyway.

-Experimental search
- I tried to find where these templates are stored, and maybe replaced them from outside. Of course I didn't find anything, as it is probably handled by the native code we do not get to see. But without a function that'd run from time to time (oh I don't know, maybe on every load for example?) it'd be useless anyway.

What really makes me scratch my head is, on my first and override attempts (save for the last half-attempt), the changes work for ONCE. You install the mod, you load your savegame, and you get 2-manned proving ground. And it is there for good after that, even if you uninstall the mod (aka - replace it with a dummy). However, if you reopen the game, build a new proving ground (or build it for the first time), it is not. While this is expected for my first attempt, I have no idea why it isn't working on my 2nd and 4th attempts.

Let me rephrase what I've written on the last sentence above to confuse you even more. I have no idea why it is working on my 2nd and 4th attempts only once. Because redscreen errors tell that these templates do already exist. Why does it work for only once, and stops working afterwards? I mean these changes are on the override class, not in a function like OnLoadSaveGame() which runs only once. If it works on the first run, it should work for the subsequent runs, no?

As I've said, I am running out of ideas. Solve it and use the mod as if it is yours. I just want people to safely use the mod - while it is safe to use (as far as I can tell), if you install the mod early, or start a new game with it, you won't have the upgrade. Which irritates me by a great deal.

And LongWarStudios! If you can reach out to Firaxis, please tell them to add another function for DLCInfos, like OnEveryLoad() - had that function existed, I wouldn't be banging my head to my screen, I think. The reason I think that this is the case is, everytime I run the game via debugging, OnLoadSaveGame() function is executed, always. Maybe I am wrong, but I tried to make sure mod was running perfectly, and used debug instead of running the game normally, and on every case it was reassembling the mod and the game was treating it like the first time as far as I can tell. Anyway, have a nice day!
Amineri

Re: Overriding part of the game

Post by Amineri »

I had a bunch of troubles trying to do what you are describing, but for the GTS and the Leader training slot -- although in my case it was complicated by the fact that I wanted the second soldier slot to perform a different function than the first, which was not designed for by Firaxis.

Regarding changing the templates, the Facility ones are complicated by the fact of difficulty variants. Although the only variant is on Legend, which increases the time/cost to build.

My general strategy is to load the X2StrategyElementTemplateManager, and then request the template by name. You can then modify the template and save it back to the manager (this last step may not be needed...).

In general template-modifying code can be put into the template-creating class. This is what I did with the SMG mod to update the UpgradeTemplates so they would work with the SMGs. However, if you do this with a difficulty-variant template, it will default to retrieving only the Veteran-difficulty template, and so your changes will only take effect on that difficulty. This was a bug in the leader mod for a month or so...

The issue is that the difficulty code retrieves from a CampaignSettings gamestate, which only exists while a campaign is active -- not on startup, and not when in the shell. And there's currently no direct access method to retrieve a template of a specific difficulty. So my very hacky workaround (in the officer mod) was the following :

1. Set up a UIScreenListener on UIFacility_Academy -- since the change affects this UI, making the template changes here is sufficient
2. Set up code that loops over all difficulties, setting difficulty to each in turn (without changing lowest difficulty)
3. Within the loop, retrieve the template, which implicitly uses the current difficulty
4. Modify the template and save it back to template manager
5. Restore the difficulty to the original

And yes, this is ugly, and yes, Firaxis is aware of it. :)
lyravega
Posts: 10
Joined: Thu Feb 11, 2016 8:58 pm

Re: Overriding part of the game

Post by lyravega »

It seems that Officer slot also suffered from what I've suffered. I never checked that mod out, I'll throughly inspect it now!

But seriously, a function like OnEveryLoad() will save us from ugly hacks. All they (Firaxis) need to do is adding another function to the base DLCInfo class, and allow that function to run on every load, and not just once. I mean I've located where these functions run, as I've said, it is a simple matter of true/false; if it is true, it is run only once but if it is true, it'll be run everytime for every mod that has this function.

Anyway, I'll report back when I have something!
Post Reply