What is needed to support the command range mechanic sans officer?

For technical discussions and help
Post Reply
Roknar
Posts: 7
Joined: Mon Jul 31, 2017 7:53 pm

What is needed to support the command range mechanic sans officer?

Post by Roknar »

First off, great work on long war 2. Keep it up for Wotc :D.

So I'm trying to make a class mod for LW 2 that uses officer-esque abilities, but I don't want to restrict that class to being an officer only. I really just want to affect soldiers within command range and ideally have that scale with class rank.
Could somebody point me in the right directions to add the command range mechanic to my class. Do I even need to make my own or is there a way to use the command mechanics without tieing them to the officer status?

Of the top of my head the progression seems like it would be an issue. It's tied to officer ranks isn't it? I'd rather not override anything to improve with class ranks for that particular class instead of officer ranks. When are those ranges determined? In the actual skills? Because in that case I should be able to substitute for my own class values rather than use the LW config values without overrides if I'm not mistaken.
The other thing that might be an issue is the toggle button. I assume I'd have to add that functionality to a skill or so if I want to show the range without actually counting as an officer and gaining the associated base perks.

Anyway, all help is welcome^^ I've bitten off more than I can chew but I'm going to try regardless lol
Roknar
Posts: 7
Joined: Mon Jul 31, 2017 7:53 pm

Re: What is needed to support the command range mechanic sans officer?

Post by Roknar »

Currently I'm thinking about adding class overrides for UITacticalHUD_MouseControls_LWOfficerPack.uc and X2Ability_OfficerAbilitySet.uc.
Not actually changing anything, but having my own classes be extensions of those and overriding the X2Ability_OfficerAbilitySet.GetCommandRangeSq function to use a config for non officer...officers that is based on unit ranks (and defining such leader classes) and then modify the check to differentiate for officer+Leader class, leader class and neither, using whichever is highest for both or the new values for pure leaders. And also change UITacticalHUD_MouseControls_LWOfficerPack.OnClickedCallback to check for either officers of highest rank or a leader class. In the latter case, not checking for rank because simulating the officer formula would result in classes being locked out of their own class skills with no alternative. so also no extra checks pre mission either, it would simply be something to be aware of for modders.

And then publish that as a meta mod. Would this work? As far as I can tell, the officer system would be unfazed and there would be no reason to update the gts scripts and friends since the new abilities would be defined within their own files and don't care about all that other stuff. I would only have to update the config to include others classes. The existing command aura classes should work with non officers since they don't seem to care about actual officer status, only command range. Except for the command range toggle button.

Am I missing anything here?
Roknar
Posts: 7
Joined: Mon Jul 31, 2017 7:53 pm

Re: What is needed to support the command range mechanic sans officer?

Post by Roknar »

I noticed that the command range actor references the commandrange by package, so the range would be wrong since the override I made there doesn't get picked up. However, I would have expected the icon to show regardless.
On the one hand there is the updateControls function which bypasses the officer system by checking if the squad as a "leader" and adds the officerIcon if one is present. And on the other hand, there's the callback that usually checks for the highest officer but now also shows the ring from any "leader" types. Which might cause overlaps, but I still don't know if that would be a problem other than looking too busy.
I do this by checking if the SUPPORTED_CLASSES array contains a supported class name (that's the one set in ClassData right?). If it doesn't, the find function should return -1, otherwise it should meet the templateName from gamestate_Unit.GetSoldierClassTemplateName if I understand correctly.

I'm testing on a savegame that starts on strategic and then I search for a mission, with a newly promoted "leader" soldier via console. Is this too late for a UI layer change to affect the game or is there somethign I'm missing still, because I'm not getting any Toggle button at all?

Added *** in front of the lines that I changed.
Spoiler: show

Code: Select all

***class UITacticalHUD_MouseControls_LeaderMod extends UITacticalHUD_MouseControls_LWOfficerPack config (LeaderMod);

***var config array<name> SUPPORTED_CLASSES;

simulated function UpdateControls()
{
	local string key, label;
	local PlayerInput kInput;
	local XComKeybindingData kKeyData;
	local int i;
	local TacticalBindableCommands command;
	local XComGameState_Ability AbilityState;
	local XComGameStateHistory History;
	local XComGameState_BattleData BattleData;

	***local StateObjectReference UnitRef;
	***local XComGameState_Unit Unit;
	***local XComGameState_HeadquartersXCom XComHQ;
	***local bool SourceIsLeader;

	***SourceIsLeader = false;
	
	if (XComHQ == none)
		XComHQ = `XCOMHQ;
	
	History = `XCOMHISTORY;
	BattleData = XComGameState_BattleData(History.GetSingleGameStateObjectForClass(class'XComGameState_BattleData'));

	kInput = PC.PlayerInput;
	kKeyData = Movie.Pres.m_kKeybindingData;

	AS_SetHoverHelp("");

	if(UITacticalHUD(screen).m_isMenuRaised)
	{
		SetNumActiveControls(1);

		key = kKeyData.GetPrimaryOrSecondaryKeyStringForAction(kInput, eGBC_Cancel, eKC_General);
		SetButtonItem( m_optCancelShot,     m_strCancelShot,       key != "" ? key : m_strNoKeyBoundString,    ButtonItems[0].UIState );

		if (OfficerIcon != none)
			OfficerIcon.Hide();
	}
	else
	{
		SetNumActiveControls(5 + CommandAbilities.Length);  // add "phantom" control to leave space for Command Range icon

		key = kKeyData.GetPrimaryOrSecondaryKeyStringForAction(kInput, eTBC_EndTurn);
		SetButtonItem( m_optEndTurn,        m_strEndTurn,       key != "" ? key : m_strNoKeyBoundString,    ButtonItems[m_optEndTurn].UIState );

		key = kKeyData.GetPrimaryOrSecondaryKeyStringForAction(kInput, eTBC_PrevUnit);
		SetButtonItem( m_optPrevSoldier,    m_strPrevSoldier,   key != "" ? key : m_strNoKeyBoundString,    ButtonItems[m_optPrevSoldier].UIState );

		key = kKeyData.GetPrimaryOrSecondaryKeyStringForAction(kInput, eTBC_NextUnit);
		SetButtonItem( m_optNextSoldier,    m_strNextSoldier,   key != "" ? key : m_strNoKeyBoundString,    ButtonItems[m_optNextSoldier].UIState );

		key = kKeyData.GetPrimaryOrSecondaryKeyStringForAction(kInput, eTBC_CamRotateLeft);
		label = kKeyData.GetTacticalBindableActionLabel(eTBC_CamRotateLeft);
		SetButtonItem( m_optRotateCameraLeft,    label,   key != "" ? key : m_strNoKeyBoundString,    ButtonItems[m_optRotateCameraLeft].UIState );

		key = kKeyData.GetPrimaryOrSecondaryKeyStringForAction(kInput, eTBC_CamRotateRight);
		label = kKeyData.GetTacticalBindableActionLabel(eTBC_CamRotateRight);
		SetButtonItem( m_optRotateCameraRight,    label,   key != "" ? key : m_strNoKeyBoundString,    ButtonItems[m_optRotateCameraRight].UIState );

		for(i = 0; i < CommandAbilities.Length; i++)
		{
			command = TacticalBindableCommands(eTBC_CommandAbility1 + i);
			AbilityState = XComGameState_Ability(`XCOMHISTORY.GetGameStateForObjectID(CommandAbilities[i].AbilityObjectRef.ObjectID));
			key = kKeyData.GetPrimaryOrSecondaryKeyStringForAction(kInput, command);
			label = Caps(AbilityState.GetMyFriendlyName());
			SetButtonItem( m_optCallSkyranger + i,    label,   key != "" ? key : m_strNoKeyBoundString,    ButtonItems[m_optCallSkyranger + i].UIState, BattleData.IsAbilityObjectiveHighlighted(AbilityState.GetMyTemplateName()));
		}

		***foreach XComHQ.Squad(UnitRef)
		***{
			***Unit = XComGameState_Unit(History.GetGameStateForObjectID(UnitRef.ObjectID));
			***if (Unit != none)
			***{
				***if (default.SUPPORTED_CLASSES.find(Unit.GetSoldierClassTemplateName()) != -1) { SourceIsLeader = true;}
			***}
		***}

		***if (class'LWOfficerUtilities'.static.HasOfficerInSquad() || SourceIsLeader)
		{
			if (OfficerIcon != none)
				OfficerIcon.Show();
			else
				AddCommandRangeIcon(-300, 4);
				//AddCommandRangeIcon(-300, 200);  // For tooltip testing. Puts icon more in the middle of the screen.
		}
	}
}

simulated function OnClickedCallback()
{
	local int idx;
	local XComGameState_Unit UnitState;

	if (CRActor == none)
	{
		CRActor = Spawn(class'LWCommandRange_Actor', self, 'CommandRange');
		CRActor.Init();

		// now spawn the CommandRange Actor, passing in the Archetype reference as the template
		//CRActor = Spawn(class'LWCommandRange_Actor', self, 'CommandRange',,,CRTemplate);  // NOT WORKING BECAUSE ARCHETYPE ISN"T WORKING PROPERLY IN UNREALED
	}
	if (CRToggleOn)
	{
		CRToggleOn = false;
		CRActor.RemoveEffects();
		PlaySound( SoundCue'SoundUI.GhostArmorOffCue', true , true );
		//`RedScreen("Toggling CR Off");
	} else {
		CRToggleOn = true;
		for(idx = 0; idx < `XCOMHQ.Squad.Length; idx++)
		{
			UnitState = XComGameState_Unit(`XCOMHISTORY.GetGameStateForObjectID(`XCOMHQ.Squad[idx].ObjectID));
			***if ((class'LWOfficerUtilities'.static.IsOfficer(UnitState) && class'LWOfficerUtilities'.static.IsHighestRankOfficerInSquad(UnitState)) || default.SUPPORTED_CLASSES.find(UnitState.GetSoldierClassTemplateName()) != -1)
			{
				CRActor.AddBoundariesFromOfficer(UnitState);
			}
		}
		CRActor.DrawBoundaries();
		PlaySound( SoundCue'SoundUI.GhostArmorOnCue', true , true );
		//PlaySound( SoundCue'SoundUI.EventNotificationCue', true, true);
		//`RedScreen("Toggling CR On");
	}
}
Roknar
Posts: 7
Joined: Mon Jul 31, 2017 7:53 pm

Re: What is needed to support the command range mechanic sans officer?

Post by Roknar »

Still digging, but now more confused than ever.
UIScreenListener_TacticalHUD_LWOfficerPack which spawns the mouse controller (which should then be overridden) doesn't seem to be registered anywhere and is the only place UITacticalHUD_MouseControls_LWOfficerPack is used. Which makes no sense to me. I've been looking solely in the 844674609 folder but then I'm not familiar with either the unreal engine or script, so maybe I'm looking in the wrong places. That or I'm blind, which is equally possible lol. Anybody care to clear that up?
Roknar
Posts: 7
Joined: Mon Jul 31, 2017 7:53 pm

Re: What is needed to support the command range mechanic sans officer?

Post by Roknar »

Just updating to let people know I'm still looking for help here. Merely shifted my focus to other parts of the class for the time being.
Post Reply