Bertilsson Posted July 13, 2013 Share Posted July 13, 2013 A new idea how to select which extra soldiers to bring on a mission. We know that the extra soldiers are the "topmost" available soldiers in the barracks... So I looked around in XComStrategyGame.upk to see how soldiers are arranged and found XGFacility_Barracks.OrderedHigher function bool OrderedHigher(XGStrategySoldier kSoldier1, XGStrategySoldier kSoldier2) { // End:0x3A if(kSoldier1.m_kSoldier.iPsiRank == 4) { return true; } // End:0x74 if(kSoldier2.m_kSoldier.iPsiRank == 4) { return false; } // End:0xC1 if(kSoldier1.IsInjured() && !kSoldier2.IsInjured()) { return false; } // End:0x10B else { // End:0x10B if(kSoldier2.IsInjured() && !kSoldier1.IsInjured()) { return true; } } // End:0x158 if(kSoldier1.IsInPsiTraining() && !kSoldier2.IsInPsiTraining()) { return false; } // End:0x1A2 else { // End:0x1A2 if(kSoldier2.IsInPsiTraining() && !kSoldier1.IsInPsiTraining()) { return true; } } // End:0x1EA if(kSoldier1.GetRank() > kSoldier2.GetRank()) { return true; } // End:0x22F else { // End:0x22F if(kSoldier2.GetRank() > kSoldier1.GetRank()) { return false; } } // End:0x274 if(kSoldier1.GetNumMissions() > kSoldier2.GetNumMissions()) { return true; } // End:0x2B9 if(kSoldier1.GetNumKills() > kSoldier2.GetNumKills()) { return true; } // End:0x322 if(kSoldier1.m_kSoldier.iID < kSoldier2.m_kSoldier.iID) { return true; } return false; //return ReturnValue; } Who cares if the chosen one is on top of the list by default?Who cares if wounded soldiers are put on bottom of the list?Who cares if the PSI-trainees are in the bottom of the list? I think it would actually be more intuitive if they remained sorted by rank, missions and kills regardless of current status. Instead the below code could be inserted (or any critera which can be checked in the code and modified by the player): function bool OrderedHigher(XGStrategySoldier kSoldier1, XGStrategySoldier kSoldier2) { // End:0x3A if(kSoldier1.GetFirstName() == "*" && kSoldier2.GetFirstName() != "*") { return true; } // End:0x1EA if(kSoldier1.GetRank() > kSoldier2.GetRank()) { return true; } // End:0x22F else { // End:0x22F if(kSoldier2.GetRank() > kSoldier1.GetRank()) { return false; } } // End:0x274 if(kSoldier1.GetNumMissions() > kSoldier2.GetNumMissions()) { return true; } // End:0x2B9 if(kSoldier1.GetNumKills() > kSoldier2.GetNumKills()) { return true; } // End:0x322 if(kSoldier1.m_kSoldier.iID < kSoldier2.m_kSoldier.iID) { return true; } return false; //return ReturnValue; } The player would simply change first name to * for the soldiers he/she wants to bring along in addition to the ones already visible in the loadout-screen. If the player wants to bring less than maximum number of soldiers, he just removes the unwanted ones from the loadout screen before pressing launch. Link to comment Share on other sites More sharing options...
Amineri Posted July 20, 2013 Share Posted July 20, 2013 I've been doing some more thinking about this issue, and recently recalled that there is a tactical-based UI for selecting up to 8 soldiers. I know it's available in the "skirmish mode", which is only available via when the developer shell is unlocked. I think that the MP UI might also be suitable, although offhand I don't know how many squad members it supports (I don't play multiplayer :p) I've been thinking about this in the context of allowing more soldiers to be put on the dropship, but some of them would be "in reserve". This would allow for selection of a general-purpose team back at HQ, then selecting a more specialized subteam once the map is known. Additionally (if it's possible), would like to allow soldiers to withdraw from the field back to the skyranger, allowing a reserve soldier to take their place. Over the next few days (once I squash some more bugs in Long War) hopefully I'll be able to play around with it a bit and post up some screens showing the UI, presuming I can get it activated. Link to comment Share on other sites More sharing options...
Bertilsson Posted July 20, 2013 Share Posted July 20, 2013 I've been doing some more thinking about this issue, and recently recalled that there is a tactical-based UI for selecting up to 8 soldiers.Thinking about this one?http://hem.bredband.net/bertrich/XCOM/Temp/XCom_Developer_Shell_Tactical_Squad_Selection.pngIt is a available from the "start menu" in the game when Developer Shell is activated. It works excelent for testing with up to 8 soldiers as long as more than 6 spawn points are handled in XComGame.upk In theory it might be relatively easy to replace the normal squad selection screen with this one and make changes to the functionality of the buttons to mimic the normal loadout screen. Link to comment Share on other sites More sharing options...
Amineri Posted July 20, 2013 Share Posted July 20, 2013 In theory it might be relatively easy to replace the normal squad selection screen with this one and make changes to the functionality of the buttons to mimic the normal loadout screen. That's the one I was thinking of. Needs more testing / exploration, but I think that UI is implemented in the tactical game, not the strategy game. (i.e. in XComGame.upk, not XComStrategyGame.upk). This means that it can't be used in the squad select screen at base, because that code is a part of the strategy game. I base my guess about it being in tactical on the fact that the Second Wave options are all handled through the XComGame.upk as well, which leads me to believe that all of the opening screen UI stuff is as well. Link to comment Share on other sites More sharing options...
Amineri Posted July 20, 2013 Share Posted July 20, 2013 The good news is that I discovered where that single player loadout UI is defined, and can edit it. The bad news is that it is defined in XComShell.upk, and that there appears to be no access to the functions from XComGame.upk. I'm still not 100% sure how the GameplayToggles (in-code name for the Second Wave options) are set up to interact between the two, so it's definitely possible that I might have missed something. The upk class that implements the above screen is UISinglePlayerLoadout. There is a corresponding SWF file embedded into XComShell to support it, named SinglePlayerLoadoutD. I'm going to poke around at it a bit more but it doesn't look very promising at this point. Link to comment Share on other sites More sharing options...
XMarksTheSpot Posted July 20, 2013 Share Posted July 20, 2013 I'm going to poke around at it a bit more but it doesn't look very promising at this point.Maybe editing the original squad selection UI is still the best option?I've been sifting through the related ActionScript and UnrealScript classes, but haven't found what exactly limits the number of displayed unit boxes and how they're laid out, yet. I was able to reduce their number (by reducing the SKYRANGER_CAPACITY variable in the DGC settings) and modify their scale (via AS hexing), but making additional boxes appear has been out of reach so far - perhaps I'm looking in the wrong places :ermm: Yet perhaps a different alternative could be viable: instead of changing the number of visible unit boxes it might be possible to re-rig the outermost boxes (the ones that display the OTS-related hints) to serve a different function. The way I envision it these boxes would display left-/right-pointing arrows or 'next'/'prev' text labels and would be used to 'scroll' through the list of soldiers by manually invoking the UnloadSoldierFromSlot() and LoadSoldierIntoSlot() methods inside the XGFacility_Barracks class.Scrolling could happen in increments of four - imagine 4-person sub-squads (e.g. Team Alpha, Bravo and Charlie :cool:) and the OTS upgrades would be re-configured to increase the squad limit by the same increment (making it 4/8/12 instead of 4/5/6). Perhaps I'm dreaming a little too big here, but this would at least be visually more consistent than adding more unit boxes to the loadout screen without additional soldier pawns in the hangar scene to go with them.I suspect there are a quite a few changes to be made in various places, mainly XGChooseSquadUI, UISquadSelect and UISquadSelect_SquadList (to modify button behavior of the outermost boxes), but possibly also to XGFacility_Barracks and XGShip_Dropship (to properly track changes made to the soldier selection and to differentiate scrolling-related loading/unloading from standard behavior by clicking 'add unit'/'clear unit'). Anyone up for brainstorming this idea? :smile: Link to comment Share on other sites More sharing options...
Amineri Posted July 21, 2013 Share Posted July 21, 2013 I believe this was the earlier approach tried if you read back through the thread, which was made to almost work -- almost the same idea -- using the outer two boxes as "left" and "right" buttons instead of squad select. That could probably be made to work. As to getting more boxes, I suspect that it's a similar issue as I had with both the increased interceptor launch boxes and increased perk icon boxes. In both cases the locations are not created procedurally, but by creating a single larger sprite containing multiple subsprites. The original perk tree sprite defined 12 specific subsprites (the icon placeholders) in specific offset locations. To increase the count I had to rewrite the sprite (directly, in hex) to contains 27 sprites instead. For the interceptor launch UI the original sprite contained 4 individual launch window sprites. I had to redefine the sprite to contain 6 launch windows instead. The DefineSprite and PlaceObject2 commands aren't scripting commands, but actionscript primitives, so no loop or other control structures are allowed within them. The new DefineSprite definition for the Interceptor mod ended up looking like this : // multiship sprite defintion <DefineSprite id='226'> (old size -- 0x60 = 96 bytes) (new size -- 0x8C = 140 bytes) FF 09 8C 00 00 00 E2 00 01 00 <PlaceObject2 idref='225' name='ship0' depth='1' matrix='t7041,-1140'/> BF 06 10 00 00 00 26 42 00 E1 00 1C DC 0F 71 80 73 68 69 70 30 00 1C -- 14 bits: 0 11011100000011110111000110000000 = DC 0F 71 80 TX : 01101110000001 =0x1B81 = 7041 TY : 11101110001100 =0x3B8C = -1140 <PlaceObject2 idref='225' name='ship1' depth='14' matrix='t7041,1135'/> BF 06 10 00 00 00 26 35 00 E1 00 1C DC 08 8D E0 73 68 69 70 31 00 1C -- 14 bits: 0 11011100000010001000110111100000 = DC 08 8D E0 TX : 01101110000001 =0x1B81 = 7041 TY : 00010001101111 =0x46F = 1135 <PlaceObject2 idref='225' name='ship2' depth='27' matrix='t7041,3410'/> BF 06 10 00 00 00 26 28 00 E1 00 1C DC 09 AA 40 73 68 69 70 32 00 1C -- 14 bits: 0 11011100000010011010101001000000 = DC 09 AA 40 TX : 01101110000001 =0x1B81 = 7041 TY : 00110101010010 =0xD52 = 3410 <PlaceObject2 idref='225' name='ship3' depth='40' matrix='t7041,5685'/> BF 06 10 00 00 00 26 1B 00 E1 00 1C DC 0A C6 A0 73 68 69 70 33 00 1C -- 14 bits: 0 11011100000010101100011010100000 = DC 0A C6 A0 TX : 01101110000001 =0x1B81 = 7041 TY : 01011000110101 =0x1635 = 5685 <PlaceObject2 idref='225' name='ship4' depth='53' matrix='t7041,7960'/> BF 06 10 00 00 00 26 0E 00 E1 00 1C DC 0B E3 00 73 68 69 70 34 00 1C -- 14 bits: 0 11011100000010111110001100000000 = DC 0B E3 00 TX : 01101110000001 =0x1B81 = 7041 TY : 01111100011000 =0x1F18 = 7960 <PlaceObject2 idref='225' name='ship5' depth='66' matrix='t7041,10235'/> BF 06 10 00 00 00 26 01 00 E1 00 1E 6E 05 3F D8 73 68 69 70 35 00 1E -- 15 bits: 0 01101110000001010011111111011000 = 6E 05 3F D8 TX : 001101110000001 =0x1B81 = 7041 TY : 010011111111011 =0x27FB = 10235 <ShowFrame/> 40 00 00 00 I didn't have a tool that would decompile and recompile the sprite commands (the version of JPEXS I had didn't do it), so I had to decompile and re-compile these by hand. The trickiest part, however, was freeing up the bytes to add the extra 2 PlaceObject2 commands to add the 2 additional boxes. The sprite always contains 6 boxes, and cannot easily be made to contain more (without freeing up more bytes and redefining the sprite larger). To display fewer boxes some subelements of the sprite are set to _visible = false. The same situation with the perk tree, although that sprite has 27 PlaceObject2 commands. The original code did not allow for making the perk icons invisible, but that wasn't too difficult to add. So, it's likely that the UISquadSelect boxes are all part of a single sprite that would have to be re-defined larger. Link to comment Share on other sites More sharing options...
Bertilsson Posted July 21, 2013 Share Posted July 21, 2013 How about duplicating the existing sprite?I imagine that somwhere exists a declaration to put the whole thing on screen... and that sprite coordinates are relative or could be manipulated after creation? Link to comment Share on other sites More sharing options...
Amineri Posted July 21, 2013 Share Posted July 21, 2013 That's an option but the then the individual boxes have the same names. For the perk tree each icon has a unique string descriptor which is used to reference it in the actionscript code, and which is returned during the mouse callback (that's how the game figures out which icon the mouse is hovering over to display the perk description). Perk names are all formatted like "icon1_3" I suspect a similar system is in place for the UISquadselect boxes, with sprite names like "soldier_1", "soldier_2", etc. The actionscript typically string concats the loop identifier onto the base. For the perks it was "icon" + row + "_" + col, or something similar. I haven't looked at the UI Squadselect code, so maybe it's set up a little differently, though. ------------------------- I was poking around in to the possibility of disallowing changing difficulty in the middle of a tactical mission and re-purposing the change difficulty UI for selection of soldiers during tactical missions. To see how many boxes the UI supports I added a bunch of phantom difficulties, making 12 total. Here was the result : This was really just as simple as adding more lines to the XComGame.int localization file (side note -- this means that 2 more difficulty settings could be created rather easily). I had increased the number of lines to 12 in total, but only 6 total displayed, and the 6th was clipped. I think the space at the bottom is left blank to leave space for the second wave button and advanced options buttons (and for the ironman/ tutorial radio buttons) when new game is created. However, if the sprite could be stretched vertically there could easily be room made for more buttons. Alternatively / additionally if a scrollbar can be added things would open right up. This selection interface would be a lot less fancy than the UISquadSelect in the strategy game, as no preview of soldiers (nor re-equipping) would be possible. Instead of a single selection possible, a number up to the maximum allowed on the map could be selected ... presumable each would be filled and have an XCOM shield next to the name. The text box on the right side could contain essential soldier information, such as rank, name, missions, kills, stats, armor, weapons, and equipment. I think would need to change the text box to change as different soldier buttons are moused-over, instead of always display text associated with the "active" button (especially since more than one could be active) Link to comment Share on other sites More sharing options...
XMarksTheSpot Posted July 21, 2013 Share Posted July 21, 2013 The DefineSprite and PlaceObject2 commands aren't scripting commands, but actionscript primitives, so no loop or other control structures are allowed within them.Ah, intriguing, I haven't considered looking into the sprite definitions, so I was looking in the wrong places after all :wink:Thanks for the hint, I'll try tinkering with that, and maybe re-read some earlier posts, the scrolling solution still seems rather sound to me (visual consistency and all). Link to comment Share on other sites More sharing options...
Recommended Posts