XCOM: ENEMY UNKNOWN
XComModBridge by AzXeus
XCOM - Enemy Unknown » Utilities
Added: 07/06/2017 - 10:51AM
Updated: 10/06/2017 - 12:25PM

1 Endorsements

1 Latest version

14 Unique D/Ls

29 Total D/Ls

1,972 Total Views

Uploaded by azxeus

Description

Last updated at 12:25, 10 Jun 2017 Uploaded at 10:51, 7 Jun 2017

Installation:
  1. put XComModBridge.u into CookedPCConsole folder
  2. use patchergui or upkutils to apply XComModBridge.txt patch
  3. open DefaultGame.ini and at the bottom create new section [XComGame.XComGameInfo] then under that the line: ModNames[0]=XComModBridge.ModBridge

Usage:

You can access ModBridge in any actor class (any class that extends actor down the line) by using the line XComGameInfo(WorldInfo.Game).Mods[0] any class that isn't an actor will have to use XComGameInfo(class'Engine'.static.GetCurrentWorldInfo().Game).Mods[0]

in hex(psuedocode) this looks like:
QUOTE
10 25 19 2E <Class.XComGameInfo> 19 01 <Engine.Actor.WorldInfo> [@] <Engine.WorldInfo.Game> 00 ( 01 <Engine.WorldInfo.Game> ) [@] <XComGameInfo.Mods> 00 ( 01 <XComGameInfo.Mods> )
or
QUOTE
10 25 19 2E <Class.XComGameInfo> 19 12 20 <Engine.Engine> [@] <Engine.Engine.GetCurrentWorldInfo.ReturnValue> 00 ( 1B <GetCurrentWorldInfo> 16 ) [@] <Engine.WorldInfo.Game> 00 ( 01 <Engine.WorldInfo.Game> ) [@] <XComGameInfo.Mods> 00 ( 01 <XComGameInfo.Mods> )




There are functions that are built into ModBridge that act as Variables which can be written to or accessed in the base upks from the game, this works because for functions the upk only needs a 'name' (text stored in the .upk file) reference rather full knowledge of the new script file:
QUOTE
19 ... ... [@] <NullRef> 00 ( 1B <StrValue0> 1F <%t "Sometext"> 16 )
the functions and their uses are as follows:
  • string StrValue0(optional string str, optional bool bForce)
  • string StrValue1(optional string str, optional bool bForce)
  • string StrValue2(optional string str, optional bool bForce)
  • int IntValue0(optional int I = -1, optional bool bForce)
  • int IntValue1(optional int I = -1, optional bool bForce)
  • int IntValue2(optional int I = -1, optional bool bForce)
  • array<string> arrStrings(optional array<string> arrStr, optional bool bForce)
  • array<int> arrInts(optional array<int> arrInt, optional bool bForce)

any function called without a parameter will return their previously stored value including the arrays which will look like arrInts()[2]; or
QUOTE
10 2C 02 1B <arrInts> 16
QUOTE
10 2C 02 19 ... ... [@] <NullRef> 00 ( 1B <arrInts> 16 )

if you give the first parameter that will be stored to return later, the bForce option to force the first parameter to be stored (useful if you want to make sure stored value is overwritten even with default values such as -1, 0, or "")



ModSorter:

There is also a System to access external scripts by name that are added into the XComMod system.
First off the Class which you want to add MUST extend XComMod.
you can use this by adding your package to the CookedPCConsole folder and in the defaultGame.ini add under the [XComGame.XComGameInfo] section a line ModNames[(>0)]=[Package].[Class] such as ModNames[1]=MyMod.MyClass

Note: don't use [0], make sure XComModBridge is always [0] else this will break some things.

To access your Script without knowing what number it is in ModNames list use the ModBridge function Mods:
  • XComMod Mods(string ModName, optional string funtName, optional string paras)


Then you have two options to access your functions, if functName is blank then the function will return your Mod and you will be able to access your functions directly, BUT the function MUST be called a 'name' that is already contained in the upk you are trying to access it from eg:

XComGameInfo(WorldInfo.Game).Mods[0].Mods("MyMod.MyClass").SoldierState("sometext", -3);
QUOTE
19 19 10 25 19 2E <XComGame.XComGameInfo> 19 01 <Engine.Actor.WorldInfo> [@] <Engine.WorldInfo.Game> 00 ( 01 <Engine.WorldInfo.Game> ) [@] <XComGameinfo.Mods> 00 ( 01 <XComGameInfo.Mods> ) [@] <NullRef> 00 ( 1B <Mods> 1F <%t "MyMod.MyClass"> 16 ) [@] <NullRef> 00 ( 1B <SoldierState> 1F <%t "sometext> 1D <%i -3> 16 )
If the function were called SoldierStateSort instead this would not work because the upk file doesn't know what that is.


The other option is the specify functName which will access the StartMatch() function of your mod class while storing functName and paras, you will want to add XComModBridge to your UDK project and set your StartMatch() function up something like this:

simulated function StartMatch()
{
    local string functionName;
    local string functParas;

    functionName = ModBridge(XComGameInfo(Outer).Mods[0]).functionName;
    functParas = ModBridge(XComGameInfo(Outer).Mods[0]).functParas;

    if(functionName == "TestFunct")
    {
        if(functparas != "")
        {
            TestFunct(functParas);
        }
        else
        {
            TestFunct();
        }
    }

}


This last feature was inspired by the mutator system that was previously utilised in XCOM modding to access external scripts enabled by WGhost (BIG thanks to her!) added here to bring systems together.


TO COME:

More indepth guides on how to create external script mods and utilising ModBridge.
Actual Mod hooks so that we don't have to edit the base upks in hex to load our mods.
TBC.