eXecator Posted February 18, 2016 Share Posted February 18, 2016 Does it work by explicitly changing the difficulty of the game and then fetching the template? Cause that could interfere with achievements if it calls code that sets the "lowest difficulty used" flag. It'd be nice to get an official way to get and set the templates for particular difficulties regardless of what the current level is. I cant check right now, but XDataSet.uc contains the following: /// <summary> /// Helper function to construct Difficulty variants for each difficulty. /// </summary> static function CreateDifficultyVariantsForTemplate(X2DataTemplate BaseTemplate, out array<X2DataTemplate> NewTemplates) { local int DifficultyIndex; local X2DataTemplate NewTemplate; local string NewTemplateName; for( DifficultyIndex = `MIN_DIFFICULTY_INDEX; DifficultyIndex <= `MAX_DIFFICULTY_INDEX; ++DifficultyIndex ) { NewTemplateName = BaseTemplate.DataName $ "_Diff_" $ DifficultyIndex; NewTemplate = new(None, NewTemplateName) BaseTemplate.Class (BaseTemplate); NewTemplate.SetDifficulty(DifficultyIndex); NewTemplates.AddItem(NewTemplate); } }To me this looks like the templates for particular difficulties have modifed names. Maybe they can be accessed from whatever difficulty by using that name? Like knowing a demons true name will give you power over him... I will try this later =) Link to comment Share on other sites More sharing options...
Amineri Posted February 18, 2016 Share Posted February 18, 2016 To me this looks like the templates for particular difficulties have modifed names. Maybe they can be accessed from whatever difficulty by using that name? Like knowing a demons true name will give you power over him... I tried this, but to no avail. As far as I can tell, the only way to access a particular difficulty variant of a template is to actually set the difficulty and then retrieve the template by it's "official" name. And difficulty can only be set when in a campaign, since it is retrieved from the CampaignSettings gamestate, which doesn't exist in the shell. I would very much like to see a direct accessor to retrieve a specified difficulty variant, but that would need to be done in native code. Link to comment Share on other sites More sharing options...
eXecator Posted February 18, 2016 Share Posted February 18, 2016 So sad I am... :sad: Link to comment Share on other sites More sharing options...
tracktwo Posted February 18, 2016 Share Posted February 18, 2016 Yeah that's how it works. UnrealScript code in mods has full access to achievements and nothing is protected from scripts - You could in theory write a mod that instantly gives you all of the achievements as far as I can see. That's presumably why Firaxis made it so that mods don't disable achievements, because then they'd need to set up some kind of code-tainting system similar to what games like WoW have; and that would be an immense effort for them (and a pain in the ass for modders). You just store the current difficulty and the lowest-difficulty-used; modify the dificulty temporarily, then set the difficulty and lowest-difficulty back to the values they were at before you modified templates. That way, achievements are unaffected. Technically a mod could be used to 'cheat' that stuff and set 'lowest difficulty used' to 'Legend' for a game that was played entirely on rookie difficulty. XCOM2 achievements are not secure. :tongue: For sure. I wasn't worried so much about cheat mods but rather mods that were using this technique to adjust difficulty templates without saving and restoring the lowest difficulty setting. People would be understandably upset to discover their achievement didn't unlock because of a mod that doesn't really drastically impact gameplay. Link to comment Share on other sites More sharing options...
Kvalyr Posted February 18, 2016 Share Posted February 18, 2016 (edited) Yeah that's how it works. UnrealScript code in mods has full access to achievements and nothing is protected from scripts - You could in theory write a mod that instantly gives you all of the achievements as far as I can see. That's presumably why Firaxis made it so that mods don't disable achievements, because then they'd need to set up some kind of code-tainting system similar to what games like WoW have; and that would be an immense effort for them (and a pain in the ass for modders). You just store the current difficulty and the lowest-difficulty-used; modify the dificulty temporarily, then set the difficulty and lowest-difficulty back to the values they were at before you modified templates. That way, achievements are unaffected. Technically a mod could be used to 'cheat' that stuff and set 'lowest difficulty used' to 'Legend' for a game that was played entirely on rookie difficulty. XCOM2 achievements are not secure. :tongue: For sure. I wasn't worried so much about cheat mods but rather mods that were using this technique to adjust difficulty templates without saving and restoring the lowest difficulty setting. People would be understandably upset to discover their achievement didn't unlock because of a mod that doesn't really drastically impact gameplay. Definitely - And that's a distinct possibility. Worse still is the potential for someone to do it out of malice! Edited February 18, 2016 by Kvalyr Link to comment Share on other sites More sharing options...
eXecator Posted February 19, 2016 Share Posted February 19, 2016 [...]As far as I can tell, the only way to access a particular difficulty variant of a template is to actually set the difficulty and then retrieve the template by it's "official" name. And difficulty can only be set when in a campaign, since it is retrieved from the CampaignSettings gamestate, which doesn't exist in the shell. I would very much like to see a direct accessor to retrieve a specified difficulty variant, but that would need to be done in native code. Has anyone tried to create a fresh XComGameState_CampaignSettings with the desired difficulty set before querying TemplateManagers while in the shell or anywhere else during startup? local XComGameState StartState; local XComGameState_CampaignSettings Settings; local X2CharacterTemplateManager CharTemplateMgr; local X2CharacterTemplate LegendarySoldier; local int LegendaryDifficulty; LegendaryDifficulty = 3; StartState = History.GetStartState(); Settings = XComGameState_CampaignSettings(StartState.CreateStateObject(class'XComGameState_CampaignSettings')); StartState.AddStateObject(Settings); Settings.SetDifficulty(LegendaryDifficulty); CharTemplateMgr = class'X2CharacterTemplateManager'.static.GetCharacterTemplateManager(); LegendarySoldier = CharTemplateMgr.FindCharacterTemplate(DataTemplateName); I imagine this could work if TemplateManger implementations use 'XComGameState_CampaignSettings'.static.GetDifficultyFromSettings(). Link to comment Share on other sites More sharing options...
Amineri Posted February 19, 2016 Share Posted February 19, 2016 [...]As far as I can tell, the only way to access a particular difficulty variant of a template is to actually set the difficulty and then retrieve the template by it's "official" name. And difficulty can only be set when in a campaign, since it is retrieved from the CampaignSettings gamestate, which doesn't exist in the shell. I would very much like to see a direct accessor to retrieve a specified difficulty variant, but that would need to be done in native code. Has anyone tried to create a fresh XComGameState_CampaignSettings with the desired difficulty set before querying TemplateManagers while in the shell or anywhere else during startup? I did not try that. It's a really interesting idea... :) In theory it could work, but you'd have to do some dangerous/risky things, I think. A lot of "root" class, like CampaignSettings use the GetSingleGameStateObjectForClass method. These gamestate are implicitly assumed to be singletons, so you really have to sure sure to not introduce a second one, or terrible things can happen. Example being having two instances of UITacticalHUD because a listener kept a reference to it, disallowing it from being GCed. So, if you were to create a CampaignSettings during startup, in order for GetDifficultyFromSettings to work, you'd have to add it the history. And then when you load a savefile, there could potentially be two of them. So you'd have to actually completely delete the temporary CampaignSettings from the history. Typically gamestates don't get properly deleted, just flagged as inactive. And if the code misbehaves, and deletes CampaignSettings in an actual campaign savefile, I think it would be toast. Link to comment Share on other sites More sharing options...
eXecator Posted February 19, 2016 Share Posted February 19, 2016 Agreed on the dangerous/risky part. But I realy want those Templates! ;) /// <summary> /// Removes all information related to the last Count states from the history. /// </summary> /// <param name="Count">Number of states to pop from the history.</param> native final function ObliterateGameStatesFromHistory(optional int Count = 1);What about that badboy? It claims to obliterate game states from history of all things. That has to deal some serious damage. Is it just me, or is that a ridiculously funny name for a method? :D As an afterthought: I realy like that they made this one final. Nice touch. Link to comment Share on other sites More sharing options...
davidlallen Posted February 19, 2016 Share Posted February 19, 2016 LOL. It travels back in time, rips your name out from the phone book, then hunts you down and kills you. Link to comment Share on other sites More sharing options...
Amineri Posted February 19, 2016 Share Posted February 19, 2016 I think the word obliterate was used to make people realize how potentially catastrophic it could be. It's similar naming to what is used in Perforce VCS -- deleting/removing files just removes them from the most recent version, but doesn't delete all older versions from the depot. You have to use obliterate for that. The more typical method of removing gamestates is XComGameState.RemoveStateObject, which is intended to be the typical path for 'removing' a state object from the history. A new state is created, and the 'bRemoved' flag is set on the state object indicating that it should no longer appear in lists of 'current' state objects. The state object will still show up if history frames are examined prior to its removal. Link to comment Share on other sites More sharing options...
Recommended Posts