Jump to content

R&D to Increase Squad Size


Beknatok

Recommended Posts

I did a search for location and .location in XcomStrategyGame.upk and from what I can tell they use a lot of relative offsets and tons of different high level references for locations, especially rooms.

 

Vectors seems to be mostly used for camera handling and earth globe in mission controll room.

 

So I'm suspecting that m_kPawn.location is not a vector but something different. That is why we run into trouble whenever we treat it as a vector and I would guess move() and setLocation() runs into the same issue when attempting to modify the .location as if it was a vector.

 

But I'm usually not the most reliable source when it comes to these kind of things so it is just a theory :tongue:

 

Edit: Another theory is that they will eventually get a vector but we are trying to alter it before a ton of logic is applied to make that happen...

Edited by Bertilsson
Link to comment
Share on other sites

  • Replies 429
  • Created
  • Last Reply

Top Posters In This Topic

Hmm, calling Move() doesn't seem to have any effect, I'd like to try SetRelativeLocation() instead, but It doesn't seem to have a corresponding native function token.

The single instance of SetRelativeLocation() being used is inside XComEarthRadar.PlaceRadar() and it's referenced by a final function token (0xAC) followed by 4 more bytes and the familiar vect() construct: 1C A7 FD FF FF 23 ...

Copy-pasting this to replace the SetLocation()/Move() call in AddToLocation() doesn't seem to work, UE Explorer can't properly decompile the final function token and I suspect those 4 extra bytes have something to do with it - can anyone shed light on what these represent?

Link to comment
Share on other sites

I think you are talking about the "return value".

 

Breakdown and explanation from when I asked the infinite knowledge base (aka amineri) about that:

 

m_kSoldier.GetFirstName(): 19 01 FE 13 00 00 0A 00 EF 44 00 00 00 1B 22 0F 00 00 00 00 00 00 16

Context token: 19
m_kSoldier: 01 FE 13 00 00
memory size of next context: 0A 00
return value next context:EF 44 00 00
unknown (always 00) :00
GetFirstName(): 1B 22 0F 00 00 00 00 00 00
End of context token: 16
The memory size of a function with no parameters is 10, that's why the 0x0A.
The return value is a little trickier to look up, but can be found in the GetFirstName() properties, under return value. It's listed in decimal so you have convert it.
However, to change the first part of the context, m_kSoldier, you only have to change the 01 FE 13 00 00 to another variable or function.
---
Needless to say I allways try to find x.y and only replace x in order to not have to deal with the return value, but I did verify that you could find the value exactly where she said it would be :)
Link to comment
Share on other sites

Okay, to elaborate, NewRadar.SetRelativeLocation(vect(0.0, 0.0, 0.0)) inside XComEarthRadar.PlaceRadar() translates to:

19 00 85 1B 00 00 17 00 B4 FF FF FF 00 1C A7 FD FF FF 23 00 00 00 00 00 00 00 00 00 00 00 00 16
|| |------------| |---| |---------| || || |---------| || |---------------------------------| ||
 1        2         3        4       5  6      7       8                    9                10

 1  context token                6  final function token
 2  local variable               7  ??
 3  memory size next context     8  vector const token
 4  return val next context      9  x, y, z (4 bytes each)
 5  ??, always 00               10  end function token
 
 3 = 0x0017 = 23
 4 = 0xFFFFFFB4 =  -76
 7 = 0xFFFFFDA7 = -601

I do see a reference to 23 as memory size in UE Explorer's token view, but I'm not sure what to make of sections 4 and 7 :confused:

 

Edit: Ah, it's now dawning on me that I need to copy-paste the context part preceding the final function token, too :sweat: No need to wrap my head around understanding those sections in detail after all, hehe

Edit2: Alright, I got the game to accept the SetRelativeLocation() call without crashing, but as with Move() I can't see it having any effect :confused:

Edited by XMarksTheSpot
Link to comment
Share on other sites

Just for future referencing ....

 

Regular virtual function are specified using the format :

1B ## ## ## ## 00 00 00 00 <parameters> 16 

The four byte code at the beginning is the 'reference' for that virtual function. Most functions used in XCOM are virtual functions -- if there isn't a special modifier before the function in UE Explorer it's a virtual function.

 

However, some functions (rarely) are defined as final functions. In UE Explorer such functions will be preceded by the keyword 'final'. Some final functions also appear to be built into the Unreal Engine (using a final function instead of a single token). The functional difference (which I gleaned from reading in the UE reference website) is that final functions can never be overridden in a child class.

 

Final functions use a different format to invoke -- basically they skip the four 00 bytes present in a virtual function call.

1C ## ## ## ## <parameters> 16 

So the A7 FD FF FF in the above construction is the 'reference' for SetRelativeLocation. The reference is immediately followed by the parameters (in this case a single vector const) with the 0x16 value at the end to terminate the function (it terminates the function not the context).

 

So B4 FF FF FF is the return value reference for SetRelativeVectorLocation and A7 FD FF FF is the function reference itself.

Link to comment
Share on other sites

Edit2: Alright, I got the game to accept the SetRelativeLocation() call without crashing, but as with Move() I can't see it having any effect :confused:

 

I tested this:

    CreatePawn(SoldierState);
    // End:0x11C
    if(class'SeqEvent_HQUnits'.static.AddUnitToRoomSequence(HQLocToName(Loc), m_kPawn, SlotIdx))
    {
      m_kPawn.SetLocation(integerValue);
      return;
    }

It doesn't seem to make any difference at all what integers I put there, the game accepts all of them and then place all soldiers at the exact same spot, in mid-air in hangar instead of barracks.

 

Edit:

One simple explanation could be that m_kPawn has nothing to do with what happens in XComGame.upk after the AddUnitToRoomSequence call is made...

 

I think I will try and see what happens if I simply try UnitPawn.Move(vector) in SeqEvent_HQUnits.AddUnit later tonight or tomorrow. On the positive side It is probbly easy to make room for testing in that function by throwing out some of the else try to find an empty location-stuff.

On the negative side it will probably be much harder only moving the soldiers we want to in there, if test is successfull.

Edited by Bertilsson
Link to comment
Share on other sites

One random thought that occured to me when I thought about how X was able to unlock the camera controls... Since the base appears to be a fully modeled 3D environment, have you investigated how the camera coordinates are defined? The camera is zooming smoothly all over the base and so can't be using pre-defined points for everything.

 

However, there are a few particularly interesting points ... the XCOM memorial is a crazy zoomin point within the Commander's quarters (against the right-hand wall, I think). The Armoury is also defined as a particular zoom-to-point. In some cases the camera "jumps" to the location while in some it pans there, as I recall.

Link to comment
Share on other sites

The two following functions seems to indicate that positions in the base are ultimately handled via vector:

function FocusOnFacility(name RoomName)
{
  local Vector FacilityLocation;
  local XComHQ_RoomLocation RoomLoc;

  // End:0x71
  foreach AllActors(class'XComHQ_RoomLocation', RoomLoc)
  {
    // End:0x70
    if(RoomLoc.RoomName == RoomName)
    {
      FacilityLocation = RoomLoc.Location;  //99% sure this is a vector.
      // End:0x71
      break;
    }    
  }  
  StartRoomView('FreeMovement', 1.0);
  XComCamState_HQ_FreeMovement(CameraState).SetTargetFocus(FacilityLocation);
  //return;  
}
function Vector GetRoomLocation(int iRow, int iCol)
{
  local XComHQ_RoomLocation RoomLoc;
  local string tagtofind;

  tagtofind = (("R" $ string(iRow)) $ "_C") $ string(iCol + 1);
  // End:0x98
  foreach AllActors(class'XComHQ_RoomLocation', RoomLoc)
  {
    // End:0x97
    if(RoomLoc.Tag == name(tagtofind))
    {      
      return RoomLoc.Location; //99.9% sure this is a vector
    }    
  }  
  return vect(0.0, 0.0, 0.0);  //Well this one is a vector for sure :)
  //return ReturnValue;  
}

But trying to follow further only ends up in things like this:

class XComHQ_RoomLocation extends PointInSpace
  hidecategories(Navigation);

var() name RoomName;

defaultproperties
{
  begin object name=Sprite class=SpriteComponent
    ReplacementPrimitive=none
  object end
  // Reference: SpriteComponent'Default__XComHQ_RoomLocation.Sprite'
  VisualizeSprite=Sprite
  begin object name=Sprite class=SpriteComponent
    ReplacementPrimitive=none
  object end
  // Reference: SpriteComponent'Default__XComHQ_RoomLocation.Sprite'
  Components(0)=Sprite
  Components(1)=none
}

So basically everything in the base indeed seems to be 3D-modelled and using vectors for locations but only via reference to refeferene to reference somewhere we cannot see.

Edited by Bertilsson
Link to comment
Share on other sites

Trying to move HumanPawn or UnitPawn turned out to be fruitless.

Everything resulted in either no effect or the hanging out in mid air in the hangar syndrome.

 

However CineDummy is a different story...

  if(bAdded)
  {
    // End:0x318
    if(CineDummy != none)
    {
      HumanPawn = XComHumanPawn(InUnit);
      // End:0x24F
      if(HumanPawn != none)
      {
        HumanPawn.PrepForMatinee();
      }
      UnitPawn = XComUnitPawn(InUnit);
      UnitPawn.bSkipRotateToward = false;
      UnitPawn.SetBase(CineDummy);
      CineDummy.Move(vect(-96.0, -96.0, 0.0));
      UnitPawn.SetPhysics(7);
      UnitPawn.ResetIKTranslations();
      UpdateMatinee();
    }
  }

Experiment code (make sure to make backup of original: XComGame.upk decimal offset 5061546
05 13 00 00 50 55 00 00 00 00 00 00 FF 12 00 00 00 00 00 00 00 00 00 00 05 13 00 00 00 00 00 00 22 00 00 00 8C 04 00 00 2E 03 00 00 C9 03 00 00 49 06 00 1D FF FF FF FF 15 14 2D 00 02 13 00 00 27 07 A7 01 82 99 00 04 13 00 00 25 16 18 15 00 96 00 04 13 00 00 01 F0 12 00 00 16 16 05 04 13 00 00 00 00 04 13 00 00 0A 6A 00 25 0F 01 FC 12 00 00 00 05 13 00 00 06 A4 01 0A 84 00 26 0F 01 FB 12 00 00 00 05 13 00 00 06 A4 01 0A 9F 00 2C 02 0F 01 FA 12 00 00 00 05 13 00 00 06 A4 01 0A BA 00 2C 03 0F 01 F9 12 00 00 00 05 13 00 00 06 A4 01 0A D5 00 2C 04 0F 01 F8 12 00 00 00 05 13 00 00 06 A4 01 0A F0 00 2C 05 0F 01 F7 12 00 00 00 05 13 00 00 06 A4 01 0A 0B 01 2C 06 0F 01 F6 12 00 00 00 05 13 00 00 06 A4 01 0A 26 01 2C 07 0F 01 F5 12 00 00 00 05 13 00 00 06 A4 01 0A 41 01 2C 08 0F 01 F4 12 00 00 00 05 13 00 00 06 A4 01 0A 5C 01 2C 09 0F 01 F3 12 00 00 00 05 13 00 00 06 A4 01 0A 77 01 2C 0A 0F 01 F2 12 00 00 00 05 13 00 00 06 A4 01 0A 92 01 2C 0B 0F 01 F1 12 00 00 00 05 13 00 00 06 A4 01 0A FF FF 14 2D 00 02 13 00 00 28 06 A4 01 06 E9 01 07 DD 01 82 72 01 FC 12 00 00 2A 16 18 0D 00 97 01 F0 12 00 00 25 16 16 0F 01 FC 12 00 00 00 05 13 00 00 06 E9 01 14 2D 00 02 13 00 00 28 07 18 03 2D 00 02 13 00 00 07 18 03 77 01 EF 12 00 00 2A 16 0F 00 00 13 00 00 2E B5 46 00 00 00 05 13 00 00 07 4F 02 77 00 00 13 00 00 2A 16 19 00 00 13 00 00 0A 00 00 00 00 00 00 1B 85 5A 00 00 00 00 00 00 16 0F 00 01 13 00 00 2E CF 37 00 00 00 05 13 00 00 14 19 00 01 13 00 00 0A 00 D1 35 00 00 00 2D 01 D1 35 00 00 28 19 00 01 13 00 00 0F 00 00 00 00 00 00 61 2A 01 EF 12 00 00 4A 4A 4A 16 19 01 EF 12 00 00 0C 00 A8 FF FF FF 00 61 0A 23 00 00 C0 C2 00 00 C0 C2 00 00 00 00 16 19 00 01 13 00 00 05 00 00 00 00 00 00 6F 82 24 07 16 19 00 01 13 00 00 0A 00 00 00 00 00 00 1B CD 5D 00 00 00 00 00 00 16 1B 4C 6E 00 00 00 00 00 00 16 04 2D 00 02 13 00 00 04 3A 03 13 00 00 53 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 00 00 00 02 40 02 00 75 02 00 00 00 00 00 00

Additional observations:

Off duty soldiers in the barracks are not assigned to any specific SlotIdx.

So it seems complete harmless to remove any code related to units assigned specifically to slot 6-11.

Vect(xHorizontal, zDepthfrombackground, yVertical)

Edited by Bertilsson
Link to comment
Share on other sites

One random thought that occured to me when I thought about how X was able to unlock the camera controls... Since the base appears to be a fully modeled 3D environment, have you investigated how the camera coordinates are defined? The camera is zooming smoothly all over the base and so can't be using pre-defined points for everything.

 

However, there are a few particularly interesting points ... the XCOM memorial is a crazy zoomin point within the Commander's quarters (against the right-hand wall, I think). The Armoury is also defined as a particular zoom-to-point. In some cases the camera "jumps" to the location while in some it pans there, as I recall.

Most of the high-level camera stuff is handled in the XComHQPresentationLayer class with various methods such as CAMLookAtFacility() and states governing which UI to display, what music to play, locking/unlocking camera controls and so on. This is where I unlocked the camera, adding a call to XComHeadquartersController(Owner).SetInputState('HQ_FreeMovement') somewhere inside State_ChooseSquad.

The actual camera controls are further delegated to functions of a XComHeadquartersCamera instance, referencing various XComCamState_HQ subclasses and the like. The actual camera targets seem to be actors placed throughout the base geometry and are probably not defined via UnrealScript. I suppose having some kind of level editor would be cool to investigate further :smile: Last I heard viewing stuff in the official UDK isn't possible, too bad.

 

Trying to move HumanPawn or UnitPawn turned out to be fruitless.

Everything resulted in either no effect or the hanging out in mid air in the hangar syndrome.

 

However CineDummy is a different story...

I don't think moving the CineDummy actor around is a viable solution as this serves as the base actor to which the soldier pawns are attached. That way you couldn't separate multiple pawns being attached to the same location :confused:

 

Additional observations:

Off duty soldiers in the barracks are not assigned to any specific SlotIdx.

So it seems complete harmless to remove any code related to units assigned specifically to slot 6-11.

From my observations the SlotIdx does play a role for the placement of off-duty soldiers. By hard-coding the AddUnit() call inside SeqEvent_HQUnits.AddUnitToRoomSequence() to use specific slot ids I could make all off-duty pawns appear in the corresponding locations. And there appear to be more than 6 different locations to choose from.

Edited by XMarksTheSpot
Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.

×
×
  • Create New...