Jump to content

Modding details? Ask away!


Amineri

Recommended Posts

It's me! Of course I made that configurable....

 

.... You should be looking at the XComLW_OfficerPack.ini that's in the Mods folder in the game folder, not any version that may pop up in My Games.

 

 

Yup -- lucky ME, too!

I now feel sooooo silly, lady teacher. I had actually seen (even if with intense sleep depravation of late) each of those special lines, but somehow my weird brain didn't make the connection with time-delays. Problem solved -- many thanks.

 

PS; All three LWS packs are installed in the Workshop root along with any of the others custom mods i've grabbed from Steam... i've figured that much (by simple instinct, i guess) with a few slight corrections for a few of 'hem. Everything works fine. :D

Link to comment
Share on other sites

  • Replies 399
  • Created
  • Last Reply

Top Posters In This Topic

I'm trying to figure out how to nerf Mimic Beacons so they just have the normal priority of a soldier, and are not always targeted first.

 

The AI units have behaviors defined like this in the AI.ini

Behaviors=(BehaviorName=AdvShieldBearer_RedAbilitySelector, NodeType=Selector, Child[0]=MimicBeaconBehavior, Child[1]=ShieldBearerFirstAction, Child[2]=ShieldBearerLastAction) 

If I remove the definition of MimicBeaconBehavior or the child notes, then all the AI units ignore Mimic Beacons instead.

 

 

in AIBehavior.uc this seems to be the result of the priority check:

function bool PassesRestriction( vector vPosition )
{

...

// If a visible mimic beacon exists, all destinations must have LoS to it.
			if( BTPriorityTarget > 0 && bScoringPriorityTarget )
			{
				TilePosition = XWorld.GetTileCoordinatesFromPosition(vPosition);
				PriorityTile = XWorld.GetTileCoordinatesFromPosition(ScoringPriorityLocation);
				if (!`XWORLD.CanSeeTileToTile(TilePosition, PriorityTile, VisInfo))
				{
					return false;
				}
			}


Is the BTPriorityTarget always a mimic beacon? iCacheScoringPriorityValues() and BT_SetTargetAsPriority() make it unclear. The AI code generally is super confusing to me.

Edited by Quaro
Link to comment
Share on other sites

I have a voice pack on the steam workshop. Some people are reporting crashes when testing in the armory others are not having problems at all.

 

I've used this tutorial and read the included documentation but I still don't know what the issue is. Since it works fine on my end I can't get any sort of bug reports.

 

I also gone through and read the old Long War voice pack instructions and followed every step but people still report crashes.

 

If you have the time, please take a look through my code and see what could be the problem. It's super frustrating with no official word on what's causing everyone's voice packs to break.

 

Source: https://mega.nz/#!YZ9SwbhL!bylHBE3oOthg2ZMJoyVVZ5nkzr11XOp-YEB1j9x3sVo

 

 

 

You need to download "Boris mod" in Steam and copy script from there, then recompile it from XCOM2ModBuddy. (Recompile is a must! You can't just copy it to your project)

Link to comment
Share on other sites

 

I have a voice pack on the steam workshop. Some people are reporting crashes when testing in the armory others are not having problems at all.

 

I've used this tutorial and read the included documentation but I still don't know what the issue is. Since it works fine on my end I can't get any sort of bug reports.

 

I also gone through and read the old Long War voice pack instructions and followed every step but people still report crashes.

 

If you have the time, please take a look through my code and see what could be the problem. It's super frustrating with no official word on what's causing everyone's voice packs to break.

 

Source: https://mega.nz/#!YZ9SwbhL!bylHBE3oOthg2ZMJoyVVZ5nkzr11XOp-YEB1j9x3sVo

 

 

 

You need to download "Boris mod" in Steam and copy script from there, then recompile it from XCOM2ModBuddy. (Recompile is a must! You can't just copy it to your project)

 

I've tried that script, no luck. Firaxis has said it's possibly a problem on their end.

Link to comment
Share on other sites

I DO get message about which lines have errors -- you may need to check the VS Shell verbosity settings.

 

The problem with your particular code is that the token "Menu" is probably out of scope in your mod class. I'd try changing the last line to something like :

 

`HQPRES.UIRaiseDialogue(kDialogueData);

 

Also, dialogues generally define a callback delegate that specifies which code to execute on each button-press respones.

 

 

Thanks! Going into Tools-Options-Projects and Solutions-Build and run and setting MSBuild project build output verbosity on "Detailed" fixed that.

So, after I changed the lines into:

`HQPRES.UIRaiseDialog(kDialogData);

project was built fine but in-game I don't receive any notification after I load the game with mod enabled for the first time. (I tried doing it in-game and in Avenger mode).So maybe I messed up with script classes?

 

Whole script is

 

 

// This is an Unreal Script

 

class X2DownloadableContentInfoLoadLunette extends X2DownloadableContentInfo;

 

static event OnLoadedSavedGame()

{

 

local CharacterPoolManager pool;

local XComGameState_Unit poolUnit;

local TDialogueBoxData kDialogData;

local String dialogueText;

local String dialogueTitle;

 

dialogueText = "Test message";

dialogueTitle = "Test message from Tomm";

 

 

 

kDialogData.eType = eDialog_Normal;

kDialogData.strTitle = dialogueTitle;

kDialogData.strText = dialogueText;

kDialogData.strAccept = "OK";

`HQPRES.UIRaiseDialog(kDialogData);

}

 

 

Any ideas?

Edited by TommInfinite
Link to comment
Share on other sites

 

Well it works for Boris and for my test pack.

 

That's the weird thing. It works for some, doesn't for others. Really odd. Could you test my mod and tell me if it works for you without it? Mine works with or without that extra script but not for others.

Edited by zuffdaddy
Link to comment
Share on other sites

 

 

Well it works for Boris and for my test pack.

 

That's the weird thing. It works for some, doesn't for others. Really odd. Could you test my mod and tell me if it works for you without it? Mine works with or without that extra script but not for others.

 

You hadn't scripts in your project at all.

 

I think I fixed it but I can't test it separately from my voicepack.

 

mediafire.com/download/71526s7v1i5wnjc/BanditVoicePackFixed.rar

Link to comment
Share on other sites

Hi, Amineri, one more question:

How to show any dialog on InstallNewCampaign?

I try to do that:

 

 

   local XComPresentationLayerBase presentationLayer;
    local Albeoris_RichHeritage_SelectFacilitiesDialog selectFacilitiesDialog;

    presentationLayer = XComPlayerController(class'UIInteraction'.static.GetLocalPlayer(0).Actor).Pres;
    selectFacilitiesDialog = presentationLayer.Spawn(class'Albeoris_RichHeritage_SelectFacilitiesDialog', presentationLayer);
    presentationLayer.ScreenStack.Push(selectFacilitiesDialog);

 

It displayd but instantly disappeared because into movie was played.

How can I avoid this?

P.S. I do not want to override any default functions, so as not to break compatibility with other mods.

Link to comment
Share on other sites

Apparently it's possible to take advantage of subtype polymorphism to get around a limited set of the issues surrounding GameState classes and overriding.

I've seen some people say that classes like XComGameStat_Unit can be successfully overriden, but my experience matches up with what Amineri said early in this thread - That stuff gets baked into the GameState/save and overriding the classes with ModOverrides gets us nowhere. I suspect those who have had luck with overriding XComGameState_X classes have done so in mods that are meant for starting a new campaign.

-- Concept --
Depending on the use-case there are ways around this, though.

Let's say you want to override XComGameStateClassA, for example; but doing so the normal way gets you nowhere. Instead, you can write a class XComGameStateClassA_Child that extends XComGameStateClassA; then modify the game's GameState programmatically once the game has loaded and dynamically replace references to XComGameStateClassA with new XComGameStateClassA_Child objects, copying over data from one to the other as necessary.

References will break, of course; but it's possible to replace by ObjectID in some cases.
Confusing.. But it works. Sometimes.

 

-- Practical Example --
As a practical example, I wanted to modify how the healing rate is calculated for wounded soldiers in HQ. Specifically, I want to be able to do things like allow certain soldier perks affect the healing rate, or perhaps offer different healing rates for different soldier classes or ranks. In this situation, the global healing rate values in the ini files obviously aren't precise enough.

I subclassed XComGameState_HeadquartersProjectHealSoldier - The 'work project' that handles healing of soldiers in HQ, because I wanted to modify its CalculateWorkPerHour() method to add extra modifiers and conditions like the aforementioned.
Simply overriding that class achieves nothing - Or at best it might work for a brand new campaign (Haven't tested - just guessing). Instead, I have a ScreenListener that fires on the UIAfterAction screen and loops through all XComGameState_HeadquartersProjectHealSoldier instances in XCOMHISTORY, and removes each of them from the gamestate; and replaces them with my subclass with its modified methods.; copying over necessary data as we go

Because the subclass counts as an XComGameState_HeadquartersProjectHealSoldier through subtype polymorphism, the new objects can act as drop-in replacements for the stock ones, but when their methods get called, it calls the new ones defined in my subclass.
So when the game processes the healing work projects, it's processing instances of my modified class; instead of the ones normally created from the stock class.

It's a nasty, ugly hack; but it actually works. At least in this case. I suspect it'd work for plenty of other awkward GameState cases too, but it means playing cat and mouse with the game logic as it creates stock XComGameSate_X objects which need to be replaced dynamically in follow-up code by a mod. Registering for events and using screenlisteners are both viable ways to do this.

It's also terrible for mod interoperability for obvious reasons.

One of the interesting potential uses of this technique would be in a larger mod where you want to make extensive changes, but don't want to have to recompile XComGame.u entirely. If you replace a stock object 'early' enough in the callchain, you can have the game creating your own pseudo-overriden classes from there onwards.

Rough code example, hasn't been tested or compiled:

static function SetupModHealing(XComGameState_Unit UnitState)
{
	local XComGameState_HeadquartersXCom XComHQ;
	local XComGameState NewGameState;
	local XComGameStateHistory History;
	local XComGameState_HeadquartersProjectHealSoldier OldProjectState;
	local XComGameState_HeadquartersProjectHealSoldier NewProjectState;

	History = `XCOMHISTORY;
	NewGameState = class'XComGameStateContext_ChangeContainer'.static.CreateChangeState("Post Mission Squad Cleanup");
	XComHQ = XComGameState_HeadquartersXCom(History.GetSingleGameStateObjectForClass(class'XComGameState_HeadquartersXCom'));
	XComHQ = XComGameState_HeadquartersXCom(NewGameState.CreateStateObject(class'XComGameState_HeadquartersXCom', XComHQ.ObjectID));
	NewGameState.AddStateObject(XComHQ);

	NewGameState.AddStateObject(UnitState);
	foreach History.IterateByClassType(class'XComGameState_HeadquartersProjectHealSoldier', OldProjectState)
	{
		// Remove old projectstate from the GameState
		NewGameState.RemoveStateObject(OldProjectState.ObjectID);
		
		// Create an instance of our subclass of XComGameState_HeadquartersProjectHealSoldier, and copy values over from the old one
		
		NewProjectState = XComGameState_HeadquartersProjectHealSoldier(NewGameState.CreateStateObject(class'XComGameState_HeadquartersProjectHealSoldier_Override'));
		NewGameState.AddStateObject(NewProjectState);
		NewProjectState.BlocksRemaining = OldProjectState.BlocksRemaining
		NewProjectState.BlockPointsRemaining = OldProjectState.BlockPointsRemaining
		NewProjectState.ProjectPointsRemaining = OldProjectState.ProjectPointsRemaining
		NewProjectState.UpdateWorkPerHour();
		NewProjectState.StartDateTime = OldProjectState.StartDateTime
		NewProjectState.SetProjectedCompletionDateTime(NewProjectState.StartDateTime);
		NewProjectState.SetProjectFocus(OldProjectState.ProjectFocus, NewGameState);
		XComHQ.Projects.AddItem(NewProjectState.GetReference());
		
		// This new object now has the modified methods of our own override class but the data of the old one, as a drop-in replacement.
	}
	
	`XCOMGAME.GameRuleset.SubmitGameState(NewGameState);
}

-- TL;DR --
Subclass an awkward class, replace objects dynamically in GameState instead of using ModOverrides. And hope that Firaxis does something to improve this situation - Too much of the important game logic that mods want to change is tucked away inside classes that we can't override through any sane means.

It's really great having an SDK and access to so much of the game's source code - It's a far cry from the hexediting we did with EU/EW, but it's also disappointing when you dig into the codebase and see just how much of it is far more awkward to manipulate than it could be. :sad:

Edited by Kvalyr
Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.

×
×
  • Create New...