Jump to content

R&D to Increase Squad Size


Beknatok

Recommended Posts

For those not familiar with the upk-side UI coding conventions that Firaxis used (and maybe are standard for Unreal Engine games??), each UI functionality is typically broken into two parts. The first part is named UI<name> and the second is named XG<name>UI. The XG<name>UI class is referenced in the code as the "manager". Typically each UI<name> class has a functin called GetMgr() that returns the appropriate manager class associated with the UI. The UI<name> class is always the one that contains the actionscript calls, and is also where any callbacks from the UI are first handled. Typically there is no or very little data handling in the UI class. Most data manipulation is handled within the XG<name>UI manager class.

 

For the squad select UI, there are two UI "driver" classes :UISquadSelect and UISquadSelect_Squadlist, while the "driver" class is XGChooseSquadUI. They appear to have slightly bent their naming convention here by not using the same core name. The UISquadSelect_SquadList appears to the the driver that handles individual soldier display info, call the actionscript functions SetAddUnitText, SetSelected, SetUnitHelp, and SetUnitInfo (all of which are defined in the actionscript package Squadlist).

 

Note that the barracks situation is a bit mixed up as there is one common "manager" XGSoldierUI that handles data for all of the various barracks-related UI "driver" classes

 

Now that sort of information should be preserved on the Wiki. With your permission, I'd like to put that into the first of a series of 'Understanding' articles with the aim of presenting what people have discovered about how the game engine functions. I know there are more such nuggets buried in the other R&D threads.

 

-Dubious-

Link to comment
Share on other sites

  • Replies 429
  • Created
  • Last Reply

Top Posters In This Topic

I just tested to modify Init-function in UISquadSelect_SquadList to this:

simulated function Init(XComPlayerController _controller, UIFxsMovie _manager, UI_FxsScreen _screen, XGMission kMission, bool bNav)
{
  local XGShip_Dropship kSkyranger;

  PanelInit(_controller, _manager, _screen);
  bCanNavigate = bNav;
  kSkyranger = kMission.GetAssignedSkyranger();
  m_iMaxSlots = kSkyranger.GetCapacity();
  m_arrFillOrderIndex.AddItem(4);
  m_arrFillOrderIndex.AddItem(3);
  m_arrFillOrderIndex.AddItem(5);
  m_arrFillOrderIndex.AddItem(2);
  m_arrFillOrderIndex.AddItem(6);
  m_arrFillOrderIndex.AddItem(1);
  m_arrFillOrderIndex.AddItem(7);
  m_arrFillOrderIndex.AddItem(0);
  m_arrUIOptions.Add(8);
  //return;  
}

HexEdit: XComStrategyGame.upk (decimal offset 2375915)

D4 16 00 00 AB 1F 00 00 00 00 00 00 CE 16 00 00 00 00 00 00 00 00 00 00 D4 16 00 00 00 00 00 00 39 00 00 00 24 07 00 00 15 01 00 00 C5 00 00 00 1B 57 21 00 00 00 00 00 00 00 D4 16 00 00 00 D3 16 00 00 00 D2 16 00 00 4A 16 14 2D 01 C6 16 00 00 2D 00 D0 16 00 00 0F 00 CF 16 00 00 19 00 D1 16 00 00 0A 00 53 37 00 00 00 1B 8B 0E 00 00 00 00 00 00 16 0F 01 C4 16 00 00 19 00 CF 16 00 00 0A 00 E7 3D 00 00 00 1B AF 0E 00 00 00 00 00 00 16 55 01 C7 16 00 00 03 00 2C 04 16 55 01 C7 16 00 00 03 00 2C 03 16 55 01 C7 16 00 00 03 00 2C 05 16 55 01 C7 16 00 00 02 00 2C 02 16 55 01 C7 16 00 00 03 00 2C 06 16 55 01 C7 16 00 00 02 00 2C 01 16 55 01 C7 16 00 00 03 00 2C 07 16 55 01 C7 16 00 00 03 00 2C 00 16 54 01 C8 16 00 00 2C 08 16 04 0B 53 00 00 00 02 01 02 00 FC 12 00 00 00 00 00 00 

When combined with the LoadSquad mod and the changes to Command1.upk by XMarksTheSpot the result is:

8 Fully working slots! :wub:

Sure, slot 0 and 7 is partially outside screen, but they are usuable as they are. :dance:

 

Edit: Cleaned up the entire message.

Edit: I have also verified that OTS SquadSize I & II works. The extra slots are hidden until available if SkyRanger capacity is set to 6 from start.

Edited by Bertilsson
Link to comment
Share on other sites

All 8 slots are automatically populated if told to do so, and you can manually clear and add soldiers in each individual slot! :wub:

I'm just going to clean up the fill order and will post the hex in a few minutes.

Neat, looks like a pretty straightforward change was all that's needed after all :cool:

I suppose the proper inside-out fill order would be 4-3-5-2-6-1-7-0 for 8 slots, the basic pattern looks to be

capacity/2 = 4
        -1 = 3
        +2 = 5
        -3 = 2
        +4 = 6
        -5 = 1
        +6 = 7
        -7 = 0

Maybe the bunch of "m_arrFillOrderIndex.AddItem(x);" calls could be replaced with a loop construct allowing for different slot counts defined via simple DGC edits, something along the lines of

index = m_iMaxSlots / 2;
for(i = 0; i < m_iMaxSlots; i++)
{
	m_arrFillOrderIndex.AddItem(index);
	index += ((i%2)*2-1)*(i+1);
}

Not sure if this is feasible with UPK hexing though, can you introduce new local helper variables to a function or are you stuck with using what's defined originally?

 

Edit: just noticed this

the m_arrFillOrder has to be taken into account in order to properly access the new sprites at positions 6 and 7.

Actually I didn't just append slots 6 and 7 to the end of the sprite list but instead inserted them separately at either end while also modifying the identifiers. So slots 0-5 became 1-6 in the process with a new 0 and 7 entering the list. I just thought that keeping the order along the x axis intact would be a good idea :smile:

Edited by XMarksTheSpot
Link to comment
Share on other sites

According to Amineri it is possible to borrow local variables from other functions when needed, but I haven't tried it out myself yet.

 

However as long as no more than 8 slots are available and nobody miss the following line:

m_iCurrentSelection = ((m_iMaxSlots == 6) ? 5 : 4); (My wild guess is that it marked a slot as selected by default)

 

Then there really is no need for a loop as the two rows added did fit inside that code area.

 

I edited the fillorder while you were typing :tongue:

Edited by Bertilsson
Link to comment
Share on other sites

 

Not sure if this is feasible with UPK hexing though, can you introduce new local helper variables to a function or are you stuck with using what's defined originally?

 

You can. You can use local variables from other functions in the same class. Just want to make sure that variable isn't called in functions that call or are called by the one you are working with, of course.

Link to comment
Share on other sites

 

 

Not sure if this is feasible with UPK hexing though, can you introduce new local helper variables to a function or are you stuck with using what's defined originally?

 

You can. You can use local variables from other functions in the same class. Just want to make sure that variable isn't called in functions that call or are called by the one you are working with, of course.

 

 

It turns out you can also borrow local variables from other classes as well. I did this when I split the class namestrings to make the 8 new class names for Long War fit into the original 4 classname config strings. The local variables I needed were in the UISoliderPromotion class but I was able to re-use them in the XGStrategySoldier class. They do of course have to be in the same upk ;)

 

One other thing to watch out for is certain variables that get put on a "watch list". This appears to make changing the variable automatically trigger some other behavior. I've had a few cases where re-using a particular local variable would cause the game to crash or display other aberrant behavior.

Link to comment
Share on other sites

And this is fantastic, the break modders have been looking for for months now.

 

To sum up where things stand:

- Bertillsson's XGPlayer.LoadSquad() mod fixes deployment issue for up to 12 soldiers - they now all appear at spawn point and do not overlap

- XMarkstheSpot Command1.upk changes allows select-equip boxes for up to 8 soldiers

--- could be adjusted so soldier boxes don't go off screen

- Bertillsson's UISquadSelect_Squadlist.Init() allows actual selection and equipping for up to 8 soldiers

 

Qs:

Do the pawns for the 7th and 8th soldiers actually appear on the equip screen? (I'll find out soon enough)

Do the 7th and 8th soldiers appear in the debrief box after the mission?

Any other changes needed to get fairly seamless functionality?

Link to comment
Share on other sites

Qs:

Do the pawns for the 7th and 8th soldiers actually appear on the equip screen? (I'll find out soon enough)

Do the 7th and 8th soldiers appear in the debrief box after the mission?

Any other changes needed to get fairly seamless functionality?

The answer to all three questions is: Nope :smile:

Edit: Or wait, actually there are probably also a few 4 and 5 that should be changed to 6 and 7 to make the naggers about needing to buy OTS SquadSize I & II working again. But that is really minor and probably very non-complicated :)

Edited by Bertilsson
Link to comment
Share on other sites

The upk-functionality for the Soldier Debrief is in the pair of functions XGDebriefUI and UIDebrief (appropriately named enough).

 

The actionscript for the debrief appears to be in package "10" of the packages that JL originally extracted from command1.upk. The package that is called from the upk is SoldierDebrief. There are several actionscript functions that are called, but the primary one of interest looks to be SetSoldier:

   function SetSoldier(slotId, portraitPath, flagImagePath, rankIconLabel, classIconLabel, name, nickName, killsOverall, killsThisMission, missions, promoteRank, promoteText, classPromoteText, status, isDead, isPsiPromoted)

The slotID in particular would have to support numbers over 6 to handle the debrief side.

 

Looking at some of the actionscript it looks like this is using a custom sprite instead of the listbox (like inventory / lockers in the loadout UI). For one, the class doesn't extend / implement listbox but instead extends MovieClip. Also, the function FillEmptySlots in this package is:

   function fillEmptySlots()
   {
      register2=this.slotsUsed;
      while(register2<6)
      {
            this.SetSoldier(register2,"","","","","","",0,0,0,0,"","","",false,false);
            this.slots[register2].gotoAndPlay("_none");
            register2=register2+1;
      }
   }

That the 6 is hard-coded makes it look like this is using a custom sprite that would have to be re-defined to allow for more soldiers in the debrief UI window.

 

Fortunately this isn't critical as all of the functionality in the Debrief can be handled just as easily in the Barracks.

Link to comment
Share on other sites

Qs:

Do the pawns for the 7th and 8th soldiers actually appear on the equip screen? (I'll find out soon enough)

Do the 7th and 8th soldiers appear in the debrief box after the mission?

Any other changes needed to get fairly seamless functionality?

There are no additional pawns appearing, that's why I asked about that earlier.

Also the soldiers don't appear in the debriefing screen by default (only six slots defined in the corresponding flash file), but the game code appears flexible enough to support additional slots provided there are sprites to go along with them, here's a quick test I did:

http://i.imgur.com/C6Nij6F.jpg

The slots are directly placed into the panel and not wrapped in a potentially scrollable container as was the case in the inventory list of the loadout screen. If it's possible to define new classes in flash files via hex editing I might be able to do something about this, a scrollable list looks like a perfect fit for this kind of screen (as does the psi labs screen, but first things first).

Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.

×
×
  • Create New...