Jump to content

Trying to make a "Big Head" mod - works ok in barracks but not in tactical


SpazmoJones

Recommended Posts

I think I know how to increase the size of just the head part - but there's a problem!

 

Using UE Explorer to view Engine.upk, we see that SkeletalMeshSocket is defined as follows (notice the RelativeScale variable):

class SkeletalMeshSocket extends Object
    native(SkeletalMesh)
    hidecategories(Object,Actor);

var() const editconst name SocketName;
var() const editconst name BoneName;
var() Vector RelativeLocation;
var() Rotator RelativeRotation;
var() Vector RelativeScale;
var() editoronly SkeletalMesh PreviewSkelMesh;
var() const editconst export editinline transient SkeletalMeshComponent PreviewSkelComp;
var() editoronly StaticMesh PreviewStaticMesh;
var() editoronly ParticleSystem PreviewParticleSystem;

defaultproperties
{
    RelativeScale=(X=1.0,Y=1.0,Z=1.0)
}

To scale just the head, I'm pretty sure the SkeletalMeshSocket object named 'Inv_Head' must have its RelativeScale value set.

The XComHumanPawn.OnHeadLoaded function would have to be changed as follows:

simulated function OnHeadLoaded(Object HeadArchetype)
{
    local MaterialInterface SkinMaterial;


    // End:0x22
    if(HeadContent == XComHeadContent(HeadArchetype))
    {
        return;
    }
    HeadContent = XComHeadContent(HeadArchetype);
    m_kHeadMeshComponent.SetSkeletalMesh(HeadContent.SkeletalMesh);
    m_kHeadMeshComponent.SetParentAnimComponent(Mesh);
    RestoreAnimSetsToDefault();
    UpdateAnimations();
    PostInitAnimTree(Mesh);
    m_kHeadMeshComponent.SetLightEnvironment(LightEnvironment);
    m_kHeadMeshComponent.SetShadowParent(Mesh);
    m_kHeadMeshComponent.bAllowApproximateOcclusion = false;
    SkinMaterial = HeadContent.SkeletalMesh.Materials[0];
    // End:0x1B3
    if(SkinMaterial != none)
    {
        m_kHeadMeshComponent.SetMaterial(0, SkinMaterial);
    }
    UpdateMeshMaterials(m_kHeadMeshComponent);
    Mesh.AppendSockets(m_kHeadMeshComponent.SkeletalMesh.Sockets, true);

//***********************************************************************
// set scaling here...?
Mesh.GetSocketByName('Inv_Head').RelativeScale = (2.0, 2.0, 2.0);
//***********************************************************************

    m_kHeadMeshComponent.PrestreamTextures(10.0, true);
    MarkAuxParametersAsDirty(m_bAuxParamNeedsPrimary, m_bAuxParamNeedsSecondary, m_bAuxParamUse3POutline);
    //return;    
}

Now the problem is that PatcherGUI returns a 'Bad object name: Engine.SkeletalMeshSocket.RelativeScale' when I try to reference the RelativeScale variable. It seems as if you can only reference objects/functions/variables that are actually used in the XComGame.upk file.

 

I think you can view the available Engine.upk objects by opening up XComGame.upk using UE Explorer, then viewing Objects->Dependencies->Engine. If you do this you'll see that the only object within SkeletalMeshSocket is SocketName.

 

RelativeScale isn't there, thus the 'bad object name' error.

 

Is there a way to access RelativeScale directly via address or something? If not, how do I get XComGame.upk to reference RelativeScale as a dependency?

 

Phew. :smile:

 

Edited by SpazmoJones
Link to comment
Share on other sites

Welcome to the club. :) One thing that works for sure: adding new names to namelist and referencing virtual functions with void return values. Everything else works weird.

 

Patcher has all the functionality to insert new export and import entries, but sometimes it doesn't work. Actually, it was most of the time for me. :)

 

Personally, I had no success adding new import references to script packages. I was able to add and use new export variable, but that was magic, because it worked for one place and didn't work for another and finally turned out to cause CTD under Linux/Mac.

 

What this means, basically, if you have something which is not referenced in upk - you're out of luck. You need to use either indirect access with means that are available or switch to mutators. Which can also be tricky. :)

 

There is a native method AttachComponent, which has relative scale as a parameter and is referenced in xcomgame.upk. This parameter is optional and might not appear in UEE decompiled scripts, but it is still there and you can use it. You can also try to edit HeadArchetype parameters, which is requested with PawnContentRequest. This one is probably somewhere in ini (?).

Link to comment
Share on other sites

Hey wghost - is it possible to add code to a function that has no script code attached?

 

In Engine.upk there's the AppendSockets function which is defined as:

// Export USkeletalMeshComponent::execAppendSockets(FFrame&, void* const)
native final function AppendSockets(out array<SkeletalMeshSocket> aSockets, bool bReplaceDuplicates);

The decompiler produces this:

 

UPK_FILE = Engine.upk
OBJECT = SkeletalMeshComponent.AppendSockets : AUTO
[REPLACEMENT_CODE]
/*(0x0000/0x0000)*/ 29
/*(0x0001/0x0001)*/ 8D 0C <None> <%u 83> <None> <%u 0> <None> <%u 0>

Is it possible to modify such a function using Patcher? I'd try it myself but I can't test this at the moment.

 

If it's possible I could modify this function to check for references to the 'head' socket and set the scaling directly.

Link to comment
Share on other sites

That's a native function, i.e. a function that is implemented in C++ instead of UnrealScript. You could probably remove the native modifier and turn it into a plain UnrealScript function, but you'd likely break it by severing its link to its C++ implementation that way. Theoretically you could re-implement the functionality in UnrealScript, but without knowing the C++ source this is rather futile.

Link to comment
Share on other sites

Yes, it's native and you will most probably break it by turning it into regular function. EW console enabler by Drakous79 used this method of making native function into non-native one, but there was just "return true" statement and nothing more. SkeletalMeshComponent.AppendSockets function looks like it is way more complicated, so I don't think this method applies here.

Link to comment
Share on other sites

First the bad news:

 

I eventually managed to hack a version that set the socket relative scale values but it didn't make any difference. I eventually realised that this would only scale components attached to the socket you set the scaling on. Because the head mesh isn't actually attached to any sockets this approach wont work.

 

The technique I used to access the .RelativeScale object (which isn't referenced by XComGame.upk) might be useful to somebody, so here's what I did:

 

I modified the Actor.TriggerGlobalEventClass function in Engine.upk as follows (this function is referenced by XComGame.upk):

 

UPK_FILE = Engine.upk
OBJECT = Actor.TriggerGlobalEventClass : AUTO
[REPLACEMENT_CODE]
/*(0x0000/0x0000)*/ 49 [@] ( 1D <%i -1> 15 ) 


// Check our magic number
07 [@notspecial] 9A 
  00 <.ActivateIndex> 
  1d <%i 123456> 
16 


//** do something special with the <.InInstigator> object here. It seems it can hold any object (not just an Actor)
  E7 1f <%t "Access everything in ENGINE.UPK here!"> 2A 16 // write to the launch.log file
  // my code that set the relativescale went here...
//**************************


[#notspecial]


/*(0x0009/0x0009)*/ 07 [@label_0x002D] 99 00 <.ActivateIndex> 25 16 
/*(0x0018/0x0014)*/  0F 10 25 00 <.ActivateIndices> 00 <.ActivateIndex> 
/*(0x002D/0x0021)*/ [#label_0x002D]
/*(0x002D/0x0021)*/ 0F 00 <.GameSeq> 19 01 <@WorldInfo> [@] <WorldInfo.GetGameSequence.ReturnValue> 00 ( 1C <WorldInfo.GetGameSequence> 16 ) 
/*(0x0056/0x003A)*/ 07 [@label_0x011E] 77 00 <.GameSeq> 2A 16 
/*(0x0065/0x0045)*/  19 00 <.GameSeq> [@] <NullRef> 00 ( 1C <Sequence.FindSeqObjectsByClass> 00 <.InEventClass> 27 00 <.EventsToActivate> 16 ) 
/*(0x0097/0x0063)*/  0F 00 <.I> 25 
/*(0x00A2/0x006A)*/  [#label_0x00A2]
/*(0x00A2/0x006A)*/  07 [@label_0x011E] 96 00 <.I> 36 00 <.EventsToActivate> 16 
/*(0x00BA/0x007A)*/  07 [@label_0x0110] 19 2E <Class.SequenceEvent> 10 00 <.I> 00 <.EventsToActivate> [@] <SequenceEvent.CheckActivate.ReturnValue> 00 ( 1C <SequenceEvent.CheckActivate> 17 00 <.InInstigator> 4A 00 <.ActivateIndices> 4A 16 ) 
/*(0x0104/0x00A8)*/  14 2D 00 <.bResult> 27 
/*(0x0110/0x00B0)*/  [#label_0x0110]
/*(0x0110/0x00B0)*/  A5 00 <.I> 16 
/*(0x011B/0x00B7)*/  06 [@label_0x00A2] 
/*(0x011E/0x00BA)*/ [#label_0x011E]


[#end]
/*(0x011E/0x00BA)*/ 04 2D 00 <.bResult> 
/*(0x0129/0x00C1)*/ 04 3A <.ReturnValue> 
/*(0x0133/0x00C7)*/ 53 

The idea is that you call it with a "magic number" parameter (in this case 123456) so you can do something with the passed object inside Engine.upk

 

So inside XComGame.upk you'd call it like this:

 

1B <TriggerGlobalEventClass> 20 <Class.SeqEvent_OnUnitChanged> 
  17 // self - Pass some sort of object here. Could be anything
  1d <%i 123456>
16 

Anyhow, that didn't help me with my big head problem. :smile:

 

Now for the good news:

 

The solution I eventually came up with was to simply scale the head mesh as I'd done before. The problem was that scaling the head made it hover above the body model due to everything being bigger. So I had to find a way to 'snap' the head mesh back into place. I modified the XComUnitPawn.Tick function to move the head mesh by the difference between the body's head bone position and the head mesh's head bone position, and it ACTUALLY WORKED. And I'm so happy now. :smile: :smile: :smile:

 

It's here: http://www.nexusmods.com/xcom/mods/600/

Edited by SpazmoJones
Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...