Jump to content

R&D Dynamic Pod Placement


wghost81

Recommended Posts

Amineri, yes, I've noticed it too. On battleships, for example, pods are often placed out of ship area. Aliens are actually placed at closest valid tile, but pods location seems invalid, although it was validated with FindClosestValidLocation.
Link to comment
Share on other sites

  • Replies 60
  • Created
  • Last Reply

Top Posters In This Topic

 

 

Yes, seems Kismet events for Council missions affect only random Thinmen drop-downs. Not so sure about Final mission (Temple Ship), as I've seen spawn code inside Kismet. But anyway, Overmind manages preplaced pods only, so any dynamic Kismet pods should not be affected... theoretically. :smile:

 

A little OT, but is it your understanding that setting the DyanmicAliens[x] entries to none on the council mission maps (from Thin Men in most cases) will cause the engine to revert to the roaming pods that are rolled up in GetPossibleAliens ?

Link to comment
Share on other sites

johnnylump, can't say for sure, as I haven't looked into this matter. But yes, default values have to be defined somewhere: either inside Kismet script, or inside placement code. Edited by wghost81
Link to comment
Share on other sites

With much better instruments available than months ago :smile: I was able to test a lot of native functions of XComWorldData class. And seems, that I finally found the right combination.

 

With following changes to the current Random Pods mod version I'm not getting pods placed mid-air on my nightmare map Higway1 (I really start to hate this one... and URB_Bar too):

iTestPod = World().FindClosestValidLocation(World().GetPositionFromTileCoordinates(iPod[9] + Rand(iPod[7]), iPod[10] + Rand(iPod[8]), 0), false, false, true);
World().GetFloorTileForPosition(iTestPod, iPod[14], iPod[15], iPod[16], true);
iTestPod = World().GetPositionFromTileCoordinates(iPod[14], iPod[15], iPod[16]);
I will test it for a little more time and will also try to add true visibility check, instead of just spawning aliens 30+ tiles away from landing zone, to resolve a problem of aliens clustering on my second nightmare map Highway Fallen. Edited by wghost81
Link to comment
Share on other sites

BTW, I also experimented with randomizing Z level and it works just fine. Except, some cases (yes, you've guessed it: Highway1), where valid tiles indeed exist out of reachable area. Those are sectoids, placed on the roof of the building:

http://i.imgur.com/66YHDpp.jpg

 

Good news is — they teleport to the bridge in their turn. Bad news — they will teleport right behind player, as closest position seems to be the one, nearest to landing lone.

 

PS: one of the vanilla map points for this map is located mid-air, that's why players report aliens sometimes teleporting on top of the squad on this map.

Edited by wghost81
Link to comment
Share on other sites

I've used developer's console to test all the maps with new placing algorithm. So far, it looks much better than current mod version.

 

First: pods can be placed on the roofs now:

 

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

 

http://i.imgur.com/1zYSnHD.jpg

 

Second: bad pod placement happens rarely now. Alien Base, Battleship and Highway1 map placement is much better. Seems, there are some terrain elements on those maps, inaccessible, but valid for placement, so pods are sometimes placed there and warped to correct location at the start of their turn.

 

I was unable to check for path validity and actual visibility, as those operations depend on pawns and there are no pawns at the stage of determining spawn points. But I reduced no spawn radius to 30m (as I did for EU version). It can sometimes lead to pods activation in the very first turn, but it allows for better placement and VanDorn map finally looks good:

 

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

 

Here's PatchUPK code for the version I tested:

 

MOD_NAME=Random Alien Pods Mod
AUTHOR=wghost81 aka Wasteland Ghost
DESCRIPTION=Alien pods will spawn at random locations on maps.

Note: mod installs slowly! Please, don't touch anything and wait until the message
box appears.

Version info:
- Aliens should spawn out of squad and covert operative LOS.
- All pods, including Council missions pods, should patrol randomly.
- Commanders should spawn at random location inside UFO.
- Alien Base commander and Overseer will use their default spawn points.
- EXALT missions will actually have 3-4 pods on maps.
- Does not affect alien waves or drop-downs.

Known issues:
- Aliens may end up in weird places on some complex terrain (like Battleship),
  but they will be warped to nearby valid location in their turn anyway. It happens
  mostly with Cyberdiscs (and they still warp around in vanilla too).
- Aliens still tend to cluster near VanDorn on corresponding Council rescue mission.
  This map is just too small and narrow.
- Map loading time may increase.

ToDo:
- Meld on maps with no default Meld spawn points (+ existing spawn points randomization).
- Dynamic aliens drop-downs randomization.

Version: 2.0 for EW

Compatible with XCOM Enemy Within versions:
 - all

UPK_FILE=XComGame.upk

// enable Overmind for Council missions
OBJECT=XGOvermind.Enabled
REL_OFFSET=0x4C
BYTE=0xFF // replace 11 (council mission) with 255

// set all mission deployment flags to random
OBJECT=XGDeployAI.SetDeploymentFlags
REL_OFFSET=0x61
BYTE=0
REL_OFFSET=0xA6
BYTE=0

// convert iTestPod integer to vector
EXPORT_ENTRY=XGDeployAI.GetPossibleSpawns.iTestPod
OBJIDX=Core.StructProperty // Type
EXPAND_FUNCTION=XGDeployAI.GetPossibleSpawns.iTestPod:44
REL_OFFSET=40
OBJIDX=Core.Object.Vector // StructObjRef
    
// convert iPod variable to static array
OBJECT=XGDeployAI.GetPossibleSpawns.iPod
REL_OFFSET=0x10
BYTE=18 // array size

// convert XGDeployAI.GetPossibleSpawns.arrRemove dynamic array to structure
EXPORT_ENTRY=XGDeployAI.GetPossibleSpawns.arrRemove
OBJIDX=Core.StructProperty // Type
OBJECT=XGDeployAI.GetPossibleSpawns.arrRemove
REL_OFFSET=20
UNSIGNED=0 // set PropertyFlagsL to zero
REL_OFFSET=40
OBJIDX=Engine.Actor.TRect // StructObjRef

// rename and relink XGDeployAI.GetPossibleSpawns.arrRemove.arrRemove
EXPORT_ENTRY=XGDeployAI.GetPossibleSpawns.arrRemove.arrRemove
OBJIDX=Core.StructProperty // Type
REL_OFFSET=8
OBJIDX=XGDeployAI.GetPossibleSpawns
REL_OFFSET=12
NAMEIDX=kEndTile // new name
OBJECT=XGDeployAI.GetPossibleSpawns.kEndTile
REL_OFFSET=40
OBJIDX=XComWorldData.TTile // StructObjRef
// link new var to XGDeployAI.GetPossibleSpawns
OBJECT=XGDeployAI.GetPossibleSpawns.iTestPod
REL_OFFSET=12
OBJIDX=XGDeployAI.GetPossibleSpawns.kEndTile // NextRef

// rearrange function calls in XGOvermind.Init to calculate layout before alien pods deployment
OBJECT=XGOvermind.Init
[REPLACEMENT_CODE]
//if(class'XComEngine'.static.SyncRand(2, (string(Name) @ string(GetStateName())) @ string(GetFuncName())) == 0)
07 [@label1]
    9A
        12 20 <Class.XComEngine> 2C 00 <XComEngine.SyncRand.ReturnValue> 00 1C <XComEngine.SyncRand>
            2C 02
            A8
                A8
                    38 57 01 <Core.Object.Name>
                    38 57 61 1C 16 16
                    38 57 1C <Core.Object.GetFuncName> 16
                16
            16
        25
    16
    //ToggleDeflection();
    1B <ToggleDeflection> 16
[#label1]
//InitWaveSystem();
1B <InitWaveSystem> 16
//m_vEnemySpawn = BATTLE().GetHumanPlayer().GetSquad().GetPermanentMemberAt(0).GetLocation();
0F 01 <@m_vEnemySpawn>
    19 19 19 19
    1B <BATTLE> 16
    0A 00
    <XGBattle_SP.GetHumanPlayer.ReturnValue> 00 1B <GetHumanPlayer> 16
    0A 00
    <XGPlayer.GetSquad.ReturnValue> 00 1B <GetSquad> 16
    0B 00
    <XGSquad.GetPermanentMemberAt.ReturnValue> 00 1B <GetPermanentMemberAt> 25 16
    0A 00
    <XGUnitNativeBase.GetLocation.ReturnValue> 00 1B <GetLocation> 16
//m_kLayout = Spawn(class'XGLayout', self);
0F 01 <@m_kLayout> 1C <Engine.Actor.Spawn> 20 <Class.XGLayout> 17 4A 4A 4A 4A 4A 4A 16
//m_kLayout.BuildBounds();
19 01 <@m_kLayout> 0A 00 <NullRef> 00 1B <BuildBounds> 16
//m_kLayout.BuildLayout();
19 01 <@m_kLayout> 0A 00 <NullRef> 00 1B <BuildLayout> 16
//m_kDeploy = Spawn(class'XGDeployAI', self);
0F 01 <@m_kDeploy> 1C <Engine.Actor.Spawn> 20 <Class.XGDeployAI> 17 4A 4A 4A 4A 4A 4A 16
//arrSpawns = m_kDeploy.DeployPods(BattleDesc().m_kAlienSquad);
0F 48 <.arrSpawns>
    19
    01 <@m_kDeploy>
    29 00
    <XGDeployAI.DeployPods.ReturnValue> 00 1B <DeployPods>
        19
        1B <BattleDesc> 16
        09 00
        <XGBattleDesc.m_kAlienSquad> 00 01 <XGBattleDesc.m_kAlienSquad> 16
//if(BattleDesc().m_bIsTutorial && BattleDesc().m_bScripted)
07 [@label2]
    82
        19
        1B <BattleDesc> 16
        0A 00
        <XGBattleDesc.m_bIsTutorial> 00 2D 01 <XGBattleDesc.m_bIsTutorial>
        18 21 00
        19
        1B <BattleDesc> 16
        0A 00
        <XGBattleDesc.m_bScripted> 00 2D 01 <XGBattleDesc.m_bScripted> 16
    //arrSpawns.Length = 0;
    0F 36 48 <.arrSpawns> 25
[#label2]
//CalcMapDirection(arrSpawns);
1B <CalcMapDirection> 48 <.arrSpawns> 16
//m_arrSpawns = arrSpawns;
0F 01 <@m_arrSpawns> 48 <.arrSpawns>
//m_kEnemy = Spawn(class'XGEnemy', self);
0F 01 <@m_kEnemy> 1C <Engine.Actor.Spawn> 20 <Class.XGEnemy> 17 4A 4A 4A 4A 4A 4A 16
//m_kEnemy.Init();
19 01 <@m_kEnemy> 0A 00 <NullRef> 00 1B <Init> 16
//m_iTurnsSinceCall = 10;
0F 01 <@m_iTurnsSinceCall> 2C 0A
//return;
04 0B
//EOS
53

// random placement
OBJECT=XGDeployAI.GetPossibleSpawns:AUTO
// define aliases
ALIAS=numPods:1A 2C 00 00 <.iPod>       // num pods
ALIAS=numSecL:1A 2C 01 00 <.iPod>       // num sectors on the larger side
ALIAS=numSecS:1A 2C 02 00 <.iPod>       // num sectors on the smaller side
ALIAS=mapNumX:1A 2C 03 00 <.iPod>       // map X length in tiles
ALIAS=mapNumY:1A 2C 04 00 <.iPod>       // map Y length in tiles
ALIAS=mapNumZ:1A 2C 11 00 <.iPod>       // map Z length in tiles
ALIAS=stepX:1A 2C 05 00 <.iPod>         // X step in tiles
ALIAS=stepY:1A 2C 06 00 <.iPod>         // Y step in tiles
ALIAS=randX:1A 2C 07 00 <.iPod>         // X randomization interval in tiles
ALIAS=randY:1A 2C 08 00 <.iPod>         // Y randomization interval in tiles
ALIAS=startX:1A 2C 09 00 <.iPod>        // X start point in tiles
ALIAS=startY:1A 2C 0A 00 <.iPod>        // Y start point in tiles
ALIAS=pointFound:1A 2C 0B 00 <.iPod>    // found spawn point flag
ALIAS=commandFound:1A 2C 0C 00 <.iPod>  // found command point flag
ALIAS=UFOIdx:1A 2C 0D 00 <.iPod>        // UFO volume index
ALIAS=TileX:1A 2C 0E 00 <.iPod>
ALIAS=TileY:1A 2C 0F 00 <.iPod>
ALIAS=TileZ:1A 2C 10 00 <.iPod>
ALIAS=MissionType:19 1B <BattleDesc> 16 09 00 <XGBattleDesc.m_iMissionType> 00 01 <XGBattleDesc.m_iMissionType>
ALIAS=UFOType:19 1B <BattleDesc> 16 09 00 <XGBattleDesc.m_eUFOType> 00 01 <XGBattleDesc.m_eUFOType>
// write code
[REPLACEMENT_CODE]
//numPods = m_kSquad.arrPods.Length;
0F <!numPods> 36 35 <XGGameData.TAlienSquad.arrPods> <XGGameData.TAlienSquad> 00 00 01 <@m_kSquad>
//if (numPods < 5)
07 [@label1] 96 <!numPods> 2C 05 16
    //numSecL = 3;
    0F <!numSecL> 2C 03
    //numSecS = 2;
    0F <!numSecS> 2C 02
//goto (else)
06 [@label3]
[#label1]
//else if (numPods < 7)
07 [@label2] 96 <!numPods> 2C 07 16
    //numSecL = 3;
    0F <!numSecL> 2C 03
    //numSecS = 3;
    0F <!numSecS> 2C 03
//goto (else)
06 [@label3]
[#label2]
    //numSecL = 4;
    0F <!numSecL> 2C 04
    //numSecS = 3;
    0F <!numSecS> 2C 03
[#label3]
//mapNumX = World().NumX;
0F <!mapNumX> 19 1B <World> 16 09 00 <XComWorldData.NumX> 00 01 <XComWorldData.NumX>
//mapNumY = World().NumY;
0F <!mapNumY> 19 1B <World> 16 09 00 <XComWorldData.NumY> 00 01 <XComWorldData.NumY>
//mapNumZ = World().NumZ;
0F <!mapNumZ> 19 1B <World> 16 09 00 <XComWorldData.NumZ> 00 01 <XComWorldData.NumZ>
//if (mapNumX > mapNumY)
07 [@label4] 97 <!mapNumX> <!mapNumY> 16
    //stepX = mapNumX / numSecL;
    0F <!stepX> 91 <!mapNumX> <!numSecL> 16
    //stepY = mapNumY / numSecS;
    0F <!stepY> 91 <!mapNumY> <!numSecS> 16
//goto (else)
06 [@label5]
    [#label4]
    //stepX = mapNumX / numSecS;
    0F <!stepX> 91 <!mapNumX> <!numSecS> 16
    //stepY = mapNumY / numSecL;
    0F <!stepY> 91 <!mapNumY> <!numSecL> 16
[#label5]
//randX = (stepX * 3) / 4;
0F <!randX> 91 90 <!stepX> 2C 03 16 2C 04 16
//randY = (stepY * 3) / 4;
0F <!randY> 91 90 <!stepY> 2C 03 16 2C 04 16
//startX  = (stepX - randX) / 2;
0F <!startX> 91 93 <!stepX> <!randX> 16 2C 02 16
[#loopX]
//if (startX < mapNumX) // x loop
07 [@loopXend] 96 <!startX> <!mapNumX> 16
    //startY = (stepY - randY) / 2;
    0F <!startY> 91 93 <!stepY> <!randY> 16 2C 02 16
    [#loopY]
    //if (startY < mapNumY) // y loop
    07 [@loopYend] 96 <!startY> <!mapNumY> 16
        //pointFound = 0;
        0F <!pointFound> 2C 00
        [#loopFound]
        //if (pointFound < 10) // 10 attempts to find good spawn point
        07 [@loopFoundEnd] 96 <!pointFound> 2C 0A 16
            //++pointFound;
            A3 <!pointFound> 16
            //iTestPod = World().FindClosestValidLocation(World().GetPositionFromTileCoordinates(iPod[ 9] + Rand(randX),startY + Rand(randY), Rand(mapNumZ)),false, false, true);
            0F 00 <.iTestPod>
            19
            1B <World> 16 <%s115> <XComWorldData.FindClosestValidLocation.ReturnValue> 00 1B <FindClosestValidLocation>
                19
                1B <World> 16 <%s80> <XComWorldData.GetPositionFromTileCoordinates.ReturnValue> 00 1B <GetPositionFromTileCoordinates>
                    92 <!startX> A7 <!randX> 16 16
                    92 <!startY> A7 <!randY> 16 16
                    A7 <!mapNumZ> 16
                16
                28 28 27
            16
            //World().GetFloorTileForPosition(iTestPod, TileX, TileY, TileZ, true)
            19
            1B <World> 16 <%s56> <XComWorldData.GetFloorTileForPosition.ReturnValue> 00 1B <GetFloorTileForPosition>
                00 <.iTestPod>
                <!TileX>
                <!TileY>
                <!TileZ>
                27
            16
            //iTestPod = World().GetPositionFromTileCoordinates(TileX, TileY, TileZ)
            0F 00 <.iTestPod>
            19
            1B <World> 16 <%s46> <XComWorldData.GetPositionFromTileCoordinates.ReturnValue> 00 1B <GetPositionFromTileCoordinates>
                <!TileX>
                <!TileY>
                <!TileZ>
            16
            //if(VSizeSq(iTestPod - m_vPlayerSpawn) < 3686400.0) // far from player (30m)
            07 [@NotFarFromPlayer] B0 E4 D8 00 <.iTestPod> 01 <@m_vPlayerSpawn> 16 16 1E <%f3686400.0> 16
                //goto loop3
                06 [@loopFound]
            [#NotFarFromPlayer]
            //if(XGBattle_SPCovertOpsExtraction(BATTLE()) != none) // far from covert operative (30m)
            07 [@NotExtraction] 77 2E <Class.XGBattle_SPCovertOpsExtraction> 1B <BATTLE> 16 2A 16
                //if(VSizeSq(iTestPod - XGBattle_SPCovertOpsExtraction(BATTLE()).ChooseCovertOperativeSpawnPoint().Location) < 3686400.0)
                07 [@NotExtraction]
                B0
                    E4
                        D8
                            00 <.iTestPod>
                            19
                            19
                            2E <Class.XGBattle_SPCovertOpsExtraction>
                            1B <BATTLE> 16
                            0A 00
                            <XGBattle_SPCovertOpsExtraction.ChooseCovertOperativeSpawnPoint.ReturnValue> 00 1C <XGBattle_SPCovertOpsExtraction.ChooseCovertOperativeSpawnPoint> 16
                            09 00
                            <Engine.Actor.Location> 00 01 <Engine.Actor.Location>
                        16
                    16
                    1E <%f3686400.0>
                16
                    //goto loop3
                    06 [@loopFound]
            [#NotExtraction]
            //pointFound = 0; // found good spawn point
            0F <!pointFound> 2C 00
        [#loopFoundEnd]
        //if (pointFound == 0) // if found good spawn point
        07 [@pointNotFound] 9A <!pointFound> 2C 00 16
            //kPod = Spawn(class'XComAlienPod',,,iTestPod,,, true);
            0F 00 <.kPod> 1C <Engine.Actor.Spawn> 20 <Class.XComAlienPod> 4A 4A 00 <.iTestPod> 4A 4A 27 4A 16
            //kPod.Init();
            19 00 <.kPod> 0A 00 <NullRef> 00 1B <Init> 16
            //arrPods.AddItem(kPod);
            55 00 <.arrPods> 0A 00 00 <.kPod> 16
        [#pointNotFound]
        //startY += stepY;
        A1 <!startY> <!stepY> 16
        //goto loop2;
        06 [@loopY]
    [#loopYend]
    //startX += stepX;
    A1 <!startX> <!stepX> 16
    //goto loop1;
    06 [@loopX]
[#loopXend]
//if(BattleDesc().m_iMissionType == 8 || BattleDesc().m_iMissionType == 10 || BattleDesc().m_eUFOType == 9) // eMission_AlienBase || eMission_Final || eShip_UFOEthereal
07 [@notStoryMission]
    84
        84
            9A
                <!MissionType>
                2C 08
            16
            18 24 00
            9A
                <!MissionType>
                2C 0A
            16
        16
        18 28 00
        9A
            38 3A <!UFOType>
            38 3A 24 09
        16
    16
    //commandFound = 0;
    0F <!commandFound> 2C 00
//goto
06 [@missionCheckEnd]
[#notStoryMission]
//else if (BattleDesc().m_iMissionType == 3 || BattleDesc().m_iMissionType == 4) // eMission_Crash || eMission_LandedUFO
07 [@notUFOMission]
    84
        9A
            <!MissionType>
            2C 03
        16
        18 24 00
        9A
            <!MissionType>
            2C 04
        16
    16
    //UFOIdx = OVERMIND().m_kLayout.GetUFOVolumeIndex();
    0F <!UFOIdx>
    19
    19
    1B <OVERMIND> 16
    09 00
    <XGOvermind.m_kLayout> 00 01 <XGOvermind.m_kLayout>
    0A 00
    <XGLayout.GetUFOVolumeIndex.ReturnValue> 00 1B <GetUFOVolumeIndex> 16
    //arrRemove = OVERMIND().m_kLayout.GetBuildingByIndex(UFOIdx).rectBuilding;
    0F 00 <.arrRemove>
    35 <XGOvermindActor.TBuilding.rectBuilding> <XGOvermindActor.TBuilding> 00 00
    19
    19
    1B <OVERMIND> 16
    09 00
    <XGOvermind.m_kLayout> 00 01 <XGOvermind.m_kLayout>
    16 00
    <XGLayout.GetBuildingByIndex.ReturnValue> 00 1B <GetBuildingByIndex> <!UFOIdx> 16
    //arrRemove = ScaleRect(arrRemove, 0.75);
    0F 00 <.arrRemove> 1B <ScaleRect> 00 <.arrRemove> 1E <%f0.75> 16
    //iTestPod.X = arrRemove.fLeft + FRand() * RectWidth(arrRemove);
    0F 35 <Core.Object.Vector.X> <Core.Object.Vector> 00 00 00 <.iTestPod>
    AE
        35 <Engine.Actor.TRect.fLeft> <Engine.Actor.TRect> 00 01 00 <.arrRemove>
        AB
            C3 16
            1B <RectWidth> 00 <.arrRemove> 16
        16
    16
    //iTestPod.Y = arrRemove.fTop + FRand() * RectHeight(arrRemove);
    0F 35 <Core.Object.Vector.Y> <Core.Object.Vector> 00 00 00 <.iTestPod>
    AE
        35 <Engine.Actor.TRect.fTop> <Engine.Actor.TRect> 00 01 00 <.arrRemove>
        AB
            C3 16
            1B <RectHeight> 00 <.arrRemove> 16
        16
    16
    //iTestPod = World().FindClosestValidLocation(iTestPod, false, false, true);
    0F 00 <.iTestPod>
    19
    1B <World> 16
    20 00
    <XComWorldData.FindClosestValidLocation.ReturnValue> 00 1B <FindClosestValidLocation> 00 <.iTestPod> 28 28 27 16
    //World().GetFloorTileForPosition(iTestPod, TileX, TileY, TileZ, true)
    19
    1B <World> 16 <%s56> <XComWorldData.GetFloorTileForPosition.ReturnValue> 00 1B <GetFloorTileForPosition>
        00 <.iTestPod>
        <!TileX>
        <!TileY>
        <!TileZ>
        27
    16
    //iTestPod = World().GetPositionFromTileCoordinates(TileX, TileY, TileZ)
    0F 00 <.iTestPod>
    19
    1B <World> 16 <%s46> <XComWorldData.GetPositionFromTileCoordinates.ReturnValue> 00 1B <GetPositionFromTileCoordinates>
        <!TileX>
        <!TileY>
        <!TileZ>
    16
    //kPod = Spawn(class'XComAlienPod',,,iTestPod,,, true);
    0F 00 <.kPod> 1C <Engine.Actor.Spawn> 20 <Class.XComAlienPod> 4A 4A 00 <.iTestPod> 4A 4A 27 4A 16
    //kPod.Init();
    19 00 <.kPod> 0A 00 <NullRef> 00 1B <Init> 16
    //arrPods.AddItem(kPod);
    55 00 <.arrPods> 0A 00 00 <.kPod> 16
    //commandFound = 1;
    0F <!commandFound> 2C 01
//goto (else)
06 [@missionCheckEnd]
    [#notUFOMission]
    //commandFound = 1;
    0F <!commandFound> 2C 01
[#missionCheckEnd]
//if (commandFound == 0) // extract original commander pod from map
07 [@doNotExtract] 9A <!commandFound> 2C 00 16
    //foreach WorldInfo.AllActors(class'XComAlienPod', kPod)
    2F 19 01 <Engine.Actor.WorldInfo> 5A 00 <NullRef> 00 61 30 20 <Class.XComAlienPod> 00 <.kPod> 4A 16 [@IP]
        //if(kPod.bCommanderPod)
        07 [@IN] 19 00 <.kPod> 0A 00 <XComAlienPod.bCommanderPod> 00 2D 01 <XComAlienPod.bCommanderPod>
            //arrPods.AddItem(kPod);
            55 00 <.arrPods> 0A 00 00 <.kPod> 16
            //commandFound = 1;
            0F <!commandFound> 2C 01
    [#IN]
	//IN
    31
    [#IP]
	//IP
    30
[#doNotExtract]
//m_arrPossibleSpawns = arrPods;
0F 01 <@m_arrPossibleSpawns> 00 <.arrPods> 
//m_arrOriginalSpawns = m_arrPossibleSpawns;
0F 01 <@m_arrOriginalSpawns> 01 <@m_arrPossibleSpawns> 
//return;
04 0B
//EOS
53

// end of mod file

 

Link to comment
Share on other sites

Compared to the previous version it appears that only XGDeployAI.GetPossibleSpawns (and the iPod variable array size) have changed.

 

I converted to UPKmodder-style formatting for including into Long War beta 10.

 

Here's the UE Explorer decompiled code:

 

 

function GetPossibleSpawns()
{
    local XComAlienPod kPod;
    local array<XComAlienPod> arrPods;
    local TRect arrRemove;
    local int iPod[18];
    local protectedwrite Vector iTestPod;

    iPod[0] = m_kSquad.arrPods.Length;
    // End:0x5E
    if(iPod[0] < 5)
    {
        iPod[1] = 3;
        iPod[2] = 2;
    }
    // End:0xB0
    else
    {
        // End:0x92
        if(iPod[0] < 7)
        {
            iPod[1] = 3;
            iPod[2] = 3;
        }
        // End:0xB0
        else
        {
            iPod[1] = 4;
            iPod[2] = 3;
        }
    }
    iPod[3] = World().NumX;
    iPod[4] = World().NumY;
    iPod[17] = World().NumZ;
    // End:0x1A2
    if(iPod[3] > iPod[4])
    {
        iPod[5] = iPod[3] / iPod[1];
        iPod[6] = iPod[4] / iPod[2];
    }
    // End:0x1F0
    else
    {
        iPod[5] = iPod[3] / iPod[2];
        iPod[6] = iPod[4] / iPod[1];
    }
    iPod[7] = (iPod[5] * 3) / 4;
    iPod[8] = (iPod[6] * 3) / 4;
    iPod[9] = (iPod[5] - iPod[7]) / 2;
    J0x25D:
    // End:0x572 [Loop If]
    if(iPod[9] < iPod[3])
    {
        iPod[10] = (iPod[6] - iPod[8]) / 2;
        J0x2A5:
        // End:0x555 [Loop If]
        if(iPod[10] < iPod[4])
        {
            iPod[11] = 0;
            J0x2D1:
            // End:0x4C4 [Loop If]
            if(iPod[11] < 10)
            {
                ++ iPod[11];
                iTestPod = World().FindClosestValidLocation(World().GetPositionFromTileCoordinates(iPod[9] + Rand(iPod[7]), iPod[10] + Rand(iPod[8]), Rand(iPod[17])), false, false, true);
                World().GetFloorTileForPosition(iTestPod, iPod[14], iPod[15], iPod[16], true);
                iTestPod = World().GetPositionFromTileCoordinates(iPod[14], iPod[15], iPod[16]);
                // End:0x444
                if(VSizeSq(iTestPod - m_vPlayerSpawn) < 3686400.0)
                {
                    // [Loop Continue]
                    goto J0x2D1;
                }
                // End:0x4B5
                if(XGBattle_SPCovertOpsExtraction(BATTLE()) != none)
                {
                    // End:0x4B5
                    if(VSizeSq(iTestPod - XGBattle_SPCovertOpsExtraction(BATTLE()).ChooseCovertOperativeSpawnPoint().Location) < 3686400.0)
                    {
                        // [Loop Continue]
                        goto J0x2D1;
                    }
                }
                iPod[11] = 0;
            }
            // End:0x538
            if(iPod[11] == 0)
            {
                kPod = Spawn(class'XComAlienPod',,, iTestPod,,, true);
                kPod.Init();
                arrPods.AddItem(kPod);
            }
            iPod[10] += iPod[6];
            // [Loop Continue]
            goto J0x2A5;
        }
        iPod[9] += iPod[5];
        // [Loop Continue]
        goto J0x25D;
    }
    // End:0x5FE
    if(((BattleDesc().m_iMissionType == 8) || BattleDesc().m_iMissionType == 10) || BattleDesc().m_eUFOType == 9)
    {
        iPod[12] = 0;
    }
    // End:0x906
    else
    {
        // End:0x8F7
        if((BattleDesc().m_iMissionType == 3) || BattleDesc().m_iMissionType == 4)
        {
            iPod[13] = OVERMIND().m_kLayout.GetUFOVolumeIndex();
            arrRemove = OVERMIND().m_kLayout.GetBuildingByIndex(iPod[13]).rectBuilding;
            arrRemove = ScaleRect(arrRemove, 0.750);
            iTestPod.X = arrRemove.fLeft + (FRand() * (RectWidth(arrRemove)));
            iTestPod.Y = arrRemove.fTop + (FRand() * (RectHeight(arrRemove)));
            iTestPod = World().FindClosestValidLocation(iTestPod, false, false, true);
            World().GetFloorTileForPosition(iTestPod, iPod[14], iPod[15], iPod[16], true);
            iTestPod = World().GetPositionFromTileCoordinates(iPod[14], iPod[15], iPod[16]);
            kPod = Spawn(class'XComAlienPod',,, iTestPod,,, true);
            kPod.Init();
            arrPods.AddItem(kPod);
            iPod[12] = 1;
        }
        // End:0x906
        else
        {
            iPod[12] = 1;
        }
    }
    // End:0x990
    if(iPod[12] == 0)
    {
        // End:0x98F
        foreach WorldInfo.AllActors(class'XComAlienPod', kPod)
        {
            // End:0x98E
            if(kPod.bCommanderPod)
            {
                arrPods.AddItem(kPod);
                iPod[12] = 1;
            }            
        }        
    }
    m_arrPossibleSpawns = arrPods;
    m_arrOriginalSpawns = m_arrPossibleSpawns;
    return;                                                
} 

 

 

 

For those interested in such things (probably no one, but that's fine :) ), here's the GetPossibleSpawns UPKmodder file:

 

 

 

MODFILEVERSION=4
UPKFILE=XComGame.upk
GUID=1C 18 A1 1A 2B C3 34 4E 8B 2C 72 33 CD 16 7E 3E // XComGame_EW_patch3.upk
FUNCTION=GetPossibleSpawns@XGDeployAI
RESIZE=540

[BEFORE_HEX]
[HEADER]
C0 02 00 00 E0 01 00 00
[/HEADER]
[CODE]
2F 19 01 A6 F9 FF FF 30 00 00 00 00 00 00 61 30 20 32 42 00 00 00 73 BA 00 00 4A 16 45 00 
	//foreach WorldInfo.AllActors(class'XComAlienPod', kPod)

55 00 72 BA 00 00 0A 00 00 73 BA 00 00 16 
	//arrPods.AddItem(kPod)

31 
//
	
30

0f 00 70 BA 00 00 25 
	//iPod = 0

07 72 01 96 00 70 BA 00 00 36 00 72 BA 00 00 16 
	//if(iPod < arrPods.Length)

0F 00 73 BA 00 00 10 00 70 BA 00 00 00 72 BA 00 00 
	//kPod = arrPods[iPod]

07 EB 00 82 81 19 1B 25 63 00 00 00 00 00 00 16 0A 00 D7 BF 00 00 00 1B C6 29 00 00 00 00 00 00 16 16 18 23 00 F2 19 00 73 BA 00 00 0A 00 F6 3F 00 00 00 2D 01 F6 3F 00 00 28 16 16 
	//if(!OVERMIND().Enabled() && kPod.bUse == false)

55 00 71 BA 00 00 0A 00 00 73 BA 00 00 16 
	//arrRemove.AddItem(kPod)

06 64 01 
	//goto J0x164

07 13 01 F2 19 00 73 BA 00 00 0A 00 F6 3F 00 00 00 2D 01 F6 3F 00 00 28 16 
	//if(kPod.bUse == false)

06 64 01 
	//goto J0x164

07 64 01 81 19 00 73 BA 00 00 0B 00 56 40 00 00 00 1B 3E 45 00 00 00 00 00 00 25 16 16 
	//if(!kPod.IsInGroup(0))

55 01 34 BA 00 00 0A 00 00 73 BA 00 00 16 
	//m_arrBackupSpawns.AddItem(kPod)

55 00 71 BA 00 00 0A 00 00 73 BA 00 00 16 
	//arrRemove.AddItem(kPod)

A5 00 70 BA 00 00 16 
	//++ iPod

06 51 00 
	//goto J0x51

58 00 71 BA 00 00 00 73 BA 00 00 00 4A A0 01 
	//foreach arrRemove(kPod,)

56 00 72 BA 00 00 0A 00 00 73 BA 00 00 16 
	//arrPods.RemoveItem(kPod)

31
	//IN(1/1)
	
30
	//IP(1/1)
	
58 00 72 BA 00 00 00 73 BA 00 00 00 4A A9 02 
	//foreach arrPods(kPod,)

0F 00 6F BA 00 00 25 
	//iTestPod = 0

07 7F 02 96 00 6F BA 00 00 36 01 36 BA 00 00 16 
	//if(iTestPod < m_arrPossibleSpawns.Length)

07 71 02 B0 E4 D8 19 00 73 BA 00 00 09 00 94 F8 FF FF 00 01 94 F8 FF FF 01 32 BA 00 00 16 16 E4 D8 19 10 00 6F BA 00 00 01 36 BA 00 00 09 00 94 F8 FF FF 00 01 94 F8 FF FF 01 32 BA 00 00 16 16 16 
	//if(VSizeSq(kPod.Location - m_vPlayerSpawn) < VSizeSq(m_arrPossibleSpawns[iTestPod].Location - m_vPlayerSpawn))

57 01 36 BA 00 00 13 00 00 6F BA 00 00 00 73 BA 00 00 16 
	//m_arrPossibleSpawns.InsertItem(iTestPod, kPod)

0F 00 6F BA 00 00 1D FF FF FF FF 
	//iTestPod = -1

06 7F 02 
	//goto J0x27F

A5 00 6F BA 00 00 16 
	//++ iTestPod

06 C3 01 
	//goto J0x1C3

07 A8 02 9B 00 6F BA 00 00 1D FF FF FF FF 16 
	//if(iTestPod != -1)

55 01 36 BA 00 00 0A 00 00 73 BA 00 00 16 
	//m_arrPossibleSpawns.AddItem(kPod)

31
	IN(1/1)
	
30
	IP(1/1)
	
0F 01 35 BA 00 00 01 36 BA 00 00 
	//m_arrOriginalSpawns = m_arrPossibleSpawns

04 0B 
	//return

53 
//	
[/CODE]
[/BEFORE_HEX]



ALIAS=numPods:1A 2C 00 00 <.iPod>       // num pods
ALIAS=numSecL:1A 2C 01 00 <.iPod>       // num sectors on the larger side
ALIAS=numSecS:1A 2C 02 00 <.iPod>       // num sectors on the smaller side
ALIAS=mapNumX:1A 2C 03 00 <.iPod>       // map X length in tiles
ALIAS=mapNumY:1A 2C 04 00 <.iPod>       // map Y length in tiles
ALIAS=mapNumZ:1A 2C 11 00 <.iPod>       // map Z length in tiles
ALIAS=stepX:1A 2C 05 00 <.iPod>         // X step in tiles
ALIAS=stepY:1A 2C 06 00 <.iPod>         // Y step in tiles
ALIAS=randX:1A 2C 07 00 <.iPod>         // X randomization interval in tiles
ALIAS=randY:1A 2C 08 00 <.iPod>         // Y randomization interval in tiles
ALIAS=startX:1A 2C 09 00 <.iPod>        // X start point in tiles
ALIAS=startY:1A 2C 0A 00 <.iPod>        // Y start point in tiles
ALIAS=pointFound:1A 2C 0B 00 <.iPod>    // found spawn point flag
ALIAS=commandFound:1A 2C 0C 00 <.iPod>  // found command point flag
ALIAS=UFOIdx:1A 2C 0D 00 <.iPod>        // UFO volume index
ALIAS=TileX:1A 2C 0E 00 <.iPod>
ALIAS=TileY:1A 2C 0F 00 <.iPod>
ALIAS=TileZ:1A 2C 10 00 <.iPod>

[AFTER_HEX]
[HEADER]
C4 09 00 00 20 07 00 00
[/HEADER]
[CODE]
//numPods = m_kSquad.arrPods.Length
0F 1A 2C 00 00 70 BA 00 00 36 35 42 00 00 00 43 00 00 00 00 00 01 38 BA 00 00 

//if (numPods < 5)
07 5E 00 96 1A 2C 00 00 70 BA 00 00 2C 05 16 

    //numSecL = 3;
    0F 1A 2C 01 00 70 BA 00 00 2C 03

    //numSecS = 2;
    0F 1A 2C 02 00 70 BA 00 00 2C 02

//goto (else)
06 B0 00 

	//else if (numPods < 7)
	07 92 00 96 1A 2C 00 00 70 BA 00 00 2C 07 16

	    //numSecL = 3;
	    0F 1A 2C 01 00 70 BA 00 00 2C 03

	    //numSecS = 3;
	    0F 1A 2C 02 00 70 BA 00 00 2C 03

	//goto (else)
	06 B0 00

	    //numSecL = 4;
	    0F 1A 2C 01 00 70 BA 00 00 2C 04

	    //numSecS = 3;
	    0F 1A 2C 02 00 70 BA 00 00 2C 03

//mapNumX = World().NumX;
0F 1A 2C 03 00 70 BA 00 00 19 1B A1 7F 00 00 00 00 00 00 16 09 00 30 0D 00 00 00 01 30 0D 00 00 

//mapNumY = World().NumY;
0F 1A 2C 04 00 70 BA 00 00 19 1B A1 7F 00 00 00 00 00 00 16 09 00 2F 0D 00 00 00 01 2F 0D 00 00 

//mapNumZ = World().NumZ;
0F 1A 2C 11 00 70 BA 00 00 19 1B A1 7F 00 00 00 00 00 00 16 09 00 2E 0D 00 00 00 01 2E 0D 00 00 

//if (mapNumX > mapNumY)
07 A2 01 97 1A 2C 03 00 70 BA 00 00 1A 2C 04 00 70 BA 00 00 16 

	//stepX = mapNumX / numSecL;
	0F 1A 2C 05 00 70 BA 00 00 91 1A 2C 03 00 70 BA 00 00 1A 2C 01 00 70 BA 00 00 16 

	//stepY = mapNumY / numSecS;
	0F 1A 2C 06 00 70 BA 00 00 91 1A 2C 04 00 70 BA 00 00 1A 2C 02 00 70 BA 00 00 16 

//goto (else)
06 F0 01 

	//stepX = mapNumX / numSecS;
	0F 1A 2C 05 00 70 BA 00 00 91 1A 2C 03 00 70 BA 00 00 1A 2C 02 00 70 BA 00 00 16 

	//stepY = mapNumY / numSecL;
	0F 1A 2C 06 00 70 BA 00 00 91 1A 2C 04 00 70 BA 00 00 1A 2C 01 00 70 BA 00 00 16 

//randX = (stepX * 3) / 4;
0F 1A 2C 07 00 70 BA 00 00 91 90 1A 2C 05 00 70 BA 00 00 2C 03 16 2C 04 16 

//randY = (stepY * 3) / 4;
0F 1A 2C 08 00 70 BA 00 00 91 90 1A 2C 06 00 70 BA 00 00 2C 03 16 2C 04 16 

//startX  = (stepX - randX) / 2;
0F 1A 2C 09 00 70 BA 00 00 91 93 1A 2C 05 00 70 BA 00 00 1A 2C 07 00 70 BA 00 00 16 2C 02 16 

//if (startX < mapNumX) // x loop
07 72 05 96 1A 2C 09 00 70 BA 00 00 1A 2C 03 00 70 BA 00 00 16 

	//startY = (stepY - randY) / 2;
	0F 1A 2C 0A 00 70 BA 00 00 91 93 1A 2C 06 00 70 BA 00 00 1A 2C 08 00 70 BA 00 00 16 2C 02 16 

	//if (startY < mapNumY) // y loop
	07 55 05 96 1A 2C 0A 00 70 BA 00 00 1A 2C 04 00 70 BA 00 00 16 

		//pointFound = 0;
		0F 1A 2C 0B 00 70 BA 00 00 2C 00 

		//if (pointFound < 10) // 10 attempts to find good spawn point
		07 C4 04 96 1A 2C 0B 00 70 BA 00 00 2C 0A 16 

			//++pointFound;
			A3 1A 2C 0B 00 70 BA 00 00 16 

			//iTestPod = World().FindClosestValidLocation(World().GetPositionFromTileCoordinates(iPod[ 9] + Rand(randX),startY + Rand(randY), Rand(mapNumZ)),false, false, true);
			0F 00 6F BA 00 00 19 1B A1 7F 00 00 00 00 00 00 16 73 00 AC D2 00 00 00 1B 29 33 00 00 00 00 00 00 19 1B A1 7F 00 00 00 00 00 00 16 50 00 BC 0C 00 00 00 1B DD 3A 00 00 00 00 00 00 92 1A 2C 09 00 70 BA 00 00 A7 1A 2C 07 00 70 BA 00 00 16 16 92 1A 2C 0A 00 70 BA 00 00 A7 1A 2C 08 00 70 BA 00 00 16 16 A7 1A 2C 11 00 70 BA 00 00 16 16 28 28 27 16 

			//World().GetFloorTileForPosition(iTestPod, TileX, TileY, TileZ, true)
			19 1B A1 7F 00 00 00 00 00 00 16 38 00 C4 0C 00 00 00 1B E8 38 00 00 00 00 00 00 00 6F BA 00 00 1A 2C 0E 00 70 BA 00 00 1A 2C 0F 00 70 BA 00 00 1A 2C 10 00 70 BA 00 00 27 16 

			//iTestPod = World().GetPositionFromTileCoordinates(TileX, TileY, TileZ)
			0F 00 6F BA 00 00 19 1B A1 7F 00 00 00 00 00 00 16 2E 00 BC 0C 00 00 00 1B DD 3A 00 00 00 00 00 00 1A 2C 0E 00 70 BA 00 00 1A 2C 0F 00 70 BA 00 00 1A 2C 10 00 70 BA 00 00 16 

			//if(VSizeSq(iTestPod - m_vPlayerSpawn) < 3686400.0) // far from player (30m)  // 4A610000
			07 44 04 B0 E4 D8 00 6F BA 00 00 01 32 BA 00 00 16 16 1E 00 00 61 4A 16 

				//goto loop3  break
				06 D1 02

			//if(XGBattle_SPCovertOpsExtraction(BATTLE()) != none) // far from covert operative (30m)
			07 B5 04 77 2E 1F B4 00 00 1B 3C 08 00 00 00 00 00 00 16 2A 16 

				//if(VSizeSq(iTestPod - XGBattle_SPCovertOpsExtraction(BATTLE()).ChooseCovertOperativeSpawnPoint().Location) < 3686400.0)
				07 B5 04 B0 E4 D8 00 6F BA 00 00 19 19 2E 1F B4 00 00 1B 3C 08 00 00 00 00 00 00 16 0A 00 FF B3 00 00 00 1C 00 B4 00 00 16 09 00 94 F8 FF FF 00 01 94 F8 FF FF 16 16 1E 00 00 61 4A 16 

					//goto loop3   break
					06 D1 02 

			//pointFound = 0; // found good spawn point
			0F 1A 2C 0B 00 70 BA 00 00 2C 00 

		//if (pointFound == 0) // if found good spawn point
		07 38 05 9A 1A 2C 0B 00 70 BA 00 00 2C 00 16 

			//kPod = Spawn(class'XComAlienPod',,, iTestPod,,, true)
			0F 00 73 BA 00 00 1C 12 FC FF FF 20 32 42 00 00 4A 4A 00 6F BA 00 00 4A 4A 27 4A 16 

			//kPod.Init()
			19 00 73 BA 00 00 0A 00 00 00 00 00 00 1B 8D 41 00 00 00 00 00 00 16 

			//arrPods.AddItem(kPod)
			55 00 72 BA 00 00 0A 00 00 73 BA 00 00 16 

		//startY += stepY;
		A1 1A 2C 0A 00 70 BA 00 00 1A 2C 06 00 70 BA 00 00 16

		//while loop
		06 A5 02 

	//startX += stepX;
	A1 1A 2C 09 00 70 BA 00 00 1A 2C 05 00 70 BA 00 00 16

	//goto loop1;
	06 5D 02 

//if(((BattleDesc().m_iMissionType == 8) || BattleDesc().m_iMissionType == 10) || BattleDesc().m_eUFOType == 9) // eMission_AlienBase || eMission_Final || eShip_UFOEthereal
07 FE 05 84 84 9A 19 1B 3F 08 00 00 00 00 00 00 16 09 00 B2 B4 00 00 00 01 B2 B4 00 00 2C 08 16 18 24 00 9A 19 1B 3F 08 00 00 00 00 00 00 16 09 00 B2 B4 00 00 00 01 B2 B4 00 00 2C 0A 16 16 18 28 00 9A 38 3A 19 1B 3F 08 00 00 00 00 00 00 16 09 00 AF B4 00 00 00 01 AF B4 00 00 38 3A 24 09 16 16 

    //commandFound = 0;
    0F 1A 2C 0C 00 70 BA 00 00 2C 00

//else
06 06 09 //[@missionCheckEnd]

	//if((BattleDesc().m_iMissionType == 3) || BattleDesc().m_iMissionType == 4)   // eMission_Crash || eMission_LandedUFO
	07 F7 08 84 9A 19 1B 3F 08 00 00 00 00 00 00 16 09 00 B2 B4 00 00 00 01 B2 B4 00 00 2C 03 16 18 24 00 9A 19 1B 3F 08 00 00 00 00 00 00 16 09 00 B2 B4 00 00 00 01 B2 B4 00 00 2C 04 16 16 

	    //UFOIdx = OVERMIND().m_kLayout.GetUFOVolumeIndex();
		0F 1A 2C 0D 00 70 BA 00 00 19 19 1B 25 63 00 00 00 00 00 00 16 09 00 16 BF 00 00 00 01 16 BF 00 00 0A 00 AB BC 00 00 00 1B F2 3B 00 00 00 00 00 00 16 

	    //arrRemove = OVERMIND().m_kLayout.GetBuildingByIndex(UFOIdx).rectBuilding;
		0F 00 71 BA 00 00 35 90 AF 00 00 91 AF 00 00 00 00 19 19 1B 25 63 00 00 00 00 00 00 16 09 00 16 BF 00 00 00 01 16 BF 00 00 16 00 AE BC 00 00 00 1B CA 37 00 00 00 00 00 00 1A 2C 0D 00 70 BA 00 00 16 

		//arrRemove = ScaleRect(arrRemove, 0.750)
		0F 00 71 BA 00 00 1B 14 6B 00 00 00 00 00 00 00 71 BA 00 00 1E 00 00 40 3F 16 

		//iTestPod.X = arrRemove.fLeft + (FRand() * (RectWidth(arrRemove)))
		0F 35 0C FD FF FF 16 F9 FF FF 00 00 00 6F BA 00 00 AE 35 00 FD FF FF 0F F9 FF FF 00 01 00 71 BA 00 00 AB C3 16 1B 56 68 00 00 00 00 00 00 00 71 BA 00 00 16 16 16 

		//iTestPod.Y = arrRemove.fTop + (FRand() * (RectHeight(arrRemove)))
		0F 35 0B FD FF FF 16 F9 FF FF 00 00 00 6F BA 00 00 AE 35 FE FC FF FF 0F F9 FF FF 00 01 00 71 BA 00 00 AB C3 16 1B 50 68 00 00 00 00 00 00 00 71 BA 00 00 16 16 16 

		//iTestPod = World().FindClosestValidLocation(iTestPod, false, false, true)
		0F 00 6F BA 00 00 19 1B A1 7F 00 00 00 00 00 00 16 16 00 AC D2 00 00 00 1B 29 33 00 00 00 00 00 00 00 6F BA 00 00 28 28 27 16 

		//World().GetFloorTileForPosition(iTestPod, TileX, TileY, TileZ, true)
		19 1B A1 7F 00 00 00 00 00 00 16 38 00 C4 0C 00 00 00 1B E8 38 00 00 00 00 00 00 00 6F BA 00 00 1A 2C 0E 00 70 BA 00 00 1A 2C 0F 00 70 BA 00 00 1A 2C 10 00 70 BA 00 00 27 16 

		//iTestPod = World().GetPositionFromTileCoordinates(TileX, TileY, TileZ)
		0F 00 6F BA 00 00 19 1B A1 7F 00 00 00 00 00 00 16 2E 00 BC 0C 00 00 00 1B DD 3A 00 00 00 00 00 00 1A 2C 0E 00 70 BA 00 00 1A 2C 0F 00 70 BA 00 00 1A 2C 10 00 70 BA 00 00 16 

		//kPod = Spawn(class'XComAlienPod',,, iTestPod,,, true)
		0F 00 73 BA 00 00 1C 12 FC FF FF 20 32 42 00 00 4A 4A 00 6F BA 00 00 4A 4A 27 4A 16 

		//kPod.Init()
		19 00 73 BA 00 00 0A 00 00 00 00 00 00 1B 8D 41 00 00 00 00 00 00 16 

		//arrPods.AddItem(kPod)
		55 00 72 BA 00 00 0A 00 00 73 BA 00 00 16 

		//commandFound = 1;
		0F 1A 2C 0C 00 70 BA 00 00 2C 01

	//goto (else)
	06 06 09 //[@missionCheckEnd]

		//commandFound = 1;
		0F 1A 2C 0C 00 70 BA 00 00 2C 01

//if (commandFound == 0) // extract original commander pod from map
07 90 09 9A 1A 2C 0C 00 70 BA 00 00 2C 00 16 

	//foreach WorldInfo.AllActors(class'XComAlienPod', kPod)
	2F 19 01 A6 F9 FF FF 5A 00 00 00 00 00 00 61 30 20 32 42 00 00 00 73 BA 00 00 4A 16 8F 09 

		//if(kPod.bCommanderPod)
		07 8E 09 19 00 73 BA 00 00 0A 00 EC 3F 00 00 00 2D 01 EC 3F 00 00 

			//arrPods.AddItem(kPod)
			55 00 72 BA 00 00 0A 00 00 73 BA 00 00 16 

			//commandFound = 1;
			0F 1A 2C 0C 00 70 BA 00 00 2C 01 

		//IN
		31

		//IP
		30

//m_arrPossibleSpawns = arrPods
0F 01 36 BA 00 00 00 72 BA 00 00 

//m_arrOriginalSpawns = m_arrPossibleSpawns
0F 01 35 BA 00 00 01 36 BA 00 00 

//return;
04 0B 

//null ops
0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 

//EOS
53

[/CODE]
[/AFTER_HEX] 

 

 

Link to comment
Share on other sites

I was assembling a fix for LW beta 9a and noticed that iTestPod has 'protectedwrite' flag set, which is wrong. I can confirm it has this flag in beta 9a too. There's no such flag in Random Pods original code, so this must be a typo, which can potentially cause a problem. iTestPod flags should be all zero.
Link to comment
Share on other sites

Here's a PatcherGUI mod for LW beta 9a with random pods fixes:

 

UPK_FILE=XComGame.upk

OBJECT=XGDeployAI.GetPossibleSpawns.iTestPod
REL_OFFSET=24
UNSIGNED=0

OBJECT=XGDeployAI.GetPossibleSpawns.iPod
REL_OFFSET=0x10
BYTE=18

OBJECT=XGDeployAI.GetPossibleSpawns:AUTO
[BEFORE_HEX]
4C 08 00 00 08 06 00 00 0F 1A 2C 00 00 70 BA 00 00 36 35 42 00 00 00 43 00 00 00 00 00 01 38 BA 00 00 07 5E 00 96 1A 2C 00 00 70 BA 00 00 2C 05 16 0F 1A 2C 01 00 70 BA 00 00 2C 03 0F 1A 2C 02 00 70 BA 00 00 2C 02 06 B0 00 07 92 00 96 1A 2C 00 00 70 BA 00 00 2C 07 16 0F 1A 2C 01 00 70 BA 00 00 2C 03 0F 1A 2C 02 00 70 BA 00 00 2C 03 06 B0 00 0F 1A 2C 01 00 70 BA 00 00 2C 04 0F 1A 2C 02 00 70 BA 00 00 2C 03 0F 1A 2C 03 00 70 BA 00 00 19 1B A1 7F 00 00 00 00 00 00 16 09 00 30 0D 00 00 00 01 30 0D 00 00 0F 1A 2C 04 00 70 BA 00 00 19 1B A1 7F 00 00 00 00 00 00 16 09 00 2F 0D 00 00 00 01 2F 0D 00 00 07 76 01 97 1A 2C 03 00 70 BA 00 00 1A 2C 04 00 70 BA 00 00 16 0F 1A 2C 05 00 70 BA 00 00 91 1A 2C 03 00 70 BA 00 00 1A 2C 01 00 70 BA 00 00 16 0F 1A 2C 06 00 70 BA 00 00 91 1A 2C 04 00 70 BA 00 00 1A 2C 02 00 70 BA 00 00 16 06 C4 01 0F 1A 2C 05 00 70 BA 00 00 91 1A 2C 03 00 70 BA 00 00 1A 2C 02 00 70 BA 00 00 16 0F 1A 2C 06 00 70 BA 00 00 91 1A 2C 04 00 70 BA 00 00 1A 2C 01 00 70 BA 00 00 16 0F 1A 2C 07 00 70 BA 00 00 91 90 1A 2C 05 00 70 BA 00 00 2C 03 16 2C 04 16 0F 1A 2C 08 00 70 BA 00 00 91 90 1A 2C 06 00 70 BA 00 00 2C 03 16 2C 04 16 0F 1A 2C 09 00 70 BA 00 00 91 93 1A 2C 05 00 70 BA 00 00 1A 2C 07 00 70 BA 00 00 16 2C 02 16 07 A1 04 96 1A 2C 09 00 70 BA 00 00 1A 2C 03 00 70 BA 00 00 16 0F 1A 2C 0A 00 70 BA 00 00 91 93 1A 2C 06 00 70 BA 00 00 1A 2C 08 00 70 BA 00 00 16 2C 02 16 07 84 04 96 1A 2C 0A 00 70 BA 00 00 1A 2C 04 00 70 BA 00 00 16 0F 1A 2C 0B 00 70 BA 00 00 2C 00 07 F3 03 96 1A 2C 0B 00 70 BA 00 00 2C 0A 16 0F 00 6F BA 00 00 19 1B A1 7F 00 00 00 00 00 00 16 6A 00 AC D2 00 00 00 1B 29 33 00 00 00 00 00 00 19 1B A1 7F 00 00 00 00 00 00 16 47 00 BC 0C 00 00 00 1B DD 3A 00 00 00 00 00 00 92 1A 2C 09 00 70 BA 00 00 A7 1A 2C 07 00 70 BA 00 00 16 16 92 1A 2C 0A 00 70 BA 00 00 A7 1A 2C 08 00 70 BA 00 00 16 16 1D 00 00 00 00 16 28 28 27 16 A3 1A 2C 0B 00 70 BA 00 00 16 07 73 03 B0 E4 D8 00 6F BA 00 00 01 32 BA 00 00 16 16 1E 00 00 80 4A 16 06 A5 02 07 E4 03 77 2E 1F B4 00 00 1B 3C 08 00 00 00 00 00 00 16 2A 16 07 E4 03 B0 E4 D8 00 6F BA 00 00 19 19 2E 1F B4 00 00 1B 3C 08 00 00 00 00 00 00 16 0A 00 FF B3 00 00 00 1C 00 B4 00 00 16 09 00 94 F8 FF FF 00 01 94 F8 FF FF 16 16 1E 00 00 80 4A 16 06 A5 02 0F 1A 2C 0B 00 70 BA 00 00 2C 00 07 67 04 9A 1A 2C 0B 00 70 BA 00 00 2C 00 16 0F 00 73 BA 00 00 1C 12 FC FF FF 20 32 42 00 00 4A 4A 00 6F BA 00 00 4A 4A 27 4A 16 19 00 73 BA 00 00 0A 00 00 00 00 00 00 1B 8D 41 00 00 00 00 00 00 16 55 00 72 BA 00 00 0A 00 00 73 BA 00 00 16 A1 1A 2C 0A 00 70 BA 00 00 1A 2C 06 00 70 BA 00 00 16 06 79 02 A1 1A 2C 09 00 70 BA 00 00 1A 2C 05 00 70 BA 00 00 16 06 31 02 07 2D 05 84 84 9A 19 1B 3F 08 00 00 00 00 00 00 16 09 00 B2 B4 00 00 00 01 B2 B4 00 00 2C 08 16 18 24 00 9A 19 1B 3F 08 00 00 00 00 00 00 16 09 00 B2 B4 00 00 00 01 B2 B4 00 00 2C 0A 16 16 18 28 00 9A 38 3A 19 1B 3F 08 00 00 00 00 00 00 16 09 00 AF B4 00 00 00 01 AF B4 00 00 38 3A 24 09 16 16 0F 1A 2C 0C 00 70 BA 00 00 2C 00 06 99 07 07 8A 07 84 9A 19 1B 3F 08 00 00 00 00 00 00 16 09 00 B2 B4 00 00 00 01 B2 B4 00 00 2C 03 16 18 24 00 9A 19 1B 3F 08 00 00 00 00 00 00 16 09 00 B2 B4 00 00 00 01 B2 B4 00 00 2C 04 16 16 0F 1A 2C 0D 00 70 BA 00 00 19 19 1B 25 63 00 00 00 00 00 00 16 09 00 16 BF 00 00 00 01 16 BF 00 00 0A 00 AB BC 00 00 00 1B F2 3B 00 00 00 00 00 00 16 0F 00 71 BA 00 00 35 90 AF 00 00 91 AF 00 00 00 00 19 19 1B 25 63 00 00 00 00 00 00 16 09 00 16 BF 00 00 00 01 16 BF 00 00 16 00 AE BC 00 00 00 1B CA 37 00 00 00 00 00 00 1A 2C 0D 00 70 BA 00 00 16 0F 00 71 BA 00 00 1B 14 6B 00 00 00 00 00 00 00 71 BA 00 00 1E 00 00 40 3F 16 0F 35 0C FD FF FF 16 F9 FF FF 00 00 00 6F BA 00 00 AE 35 00 FD FF FF 0F F9 FF FF 00 01 00 71 BA 00 00 AB C3 16 1B 56 68 00 00 00 00 00 00 00 71 BA 00 00 16 16 16 0F 35 0B FD FF FF 16 F9 FF FF 00 00 00 6F BA 00 00 AE 35 FE FC FF FF 0F F9 FF FF 00 01 00 71 BA 00 00 AB C3 16 1B 50 68 00 00 00 00 00 00 00 71 BA 00 00 16 16 16 0F 00 6F BA 00 00 19 1B A1 7F 00 00 00 00 00 00 16 20 00 AC D2 00 00 00 1B 29 33 00 00 00 00 00 00 00 6F BA 00 00 28 28 27 16 0F 00 73 BA 00 00 1C 12 FC FF FF 20 32 42 00 00 4A 4A 00 6F BA 00 00 4A 4A 27 4A 16 19 00 73 BA 00 00 0A 00 00 00 00 00 00 1B 8D 41 00 00 00 00 00 00 16 55 00 72 BA 00 00 0A 00 00 73 BA 00 00 16 0F 1A 2C 0C 00 70 BA 00 00 2C 01 06 99 07 0F 1A 2C 0C 00 70 BA 00 00 2C 01 07 23 08 9A 1A 2C 0C 00 70 BA 00 00 2C 00 16 2F 19 01 A6 F9 FF FF 5A 00 00 00 00 00 00 61 30 20 32 42 00 00 00 73 BA 00 00 4A 16 22 08 07 21 08 19 00 73 BA 00 00 0A 00 EC 3F 00 00 00 2D 01 EC 3F 00 00 55 00 72 BA 00 00 0A 00 00 73 BA 00 00 16 0F 1A 2C 0C 00 70 BA 00 00 2C 01 31 30 0F 01 36 BA 00 00 00 72 BA 00 00 0F 01 35 BA 00 00 01 36 BA 00 00 04 0B 53
[AFTER_HEX]
C4 09 00 00 20 07 00 00
0F 1A 2C 00 00 70 BA 00 00 36 35 42 00 00 00 43 00 00 00 00 00 01 38 BA 00 00 
07 5E 00 96 1A 2C 00 00 70 BA 00 00 2C 05 16 
    0F 1A 2C 01 00 70 BA 00 00 2C 03
    0F 1A 2C 02 00 70 BA 00 00 2C 02
06 B0 00 
	07 92 00 96 1A 2C 00 00 70 BA 00 00 2C 07 16
	    0F 1A 2C 01 00 70 BA 00 00 2C 03
	    0F 1A 2C 02 00 70 BA 00 00 2C 03
	06 B0 00
	    0F 1A 2C 01 00 70 BA 00 00 2C 04
	    0F 1A 2C 02 00 70 BA 00 00 2C 03
0F 1A 2C 03 00 70 BA 00 00 19 1B A1 7F 00 00 00 00 00 00 16 09 00 30 0D 00 00 00 01 30 0D 00 00 
0F 1A 2C 04 00 70 BA 00 00 19 1B A1 7F 00 00 00 00 00 00 16 09 00 2F 0D 00 00 00 01 2F 0D 00 00 
0F 1A 2C 11 00 70 BA 00 00 19 1B A1 7F 00 00 00 00 00 00 16 09 00 2E 0D 00 00 00 01 2E 0D 00 00 
07 A2 01 97 1A 2C 03 00 70 BA 00 00 1A 2C 04 00 70 BA 00 00 16 
	0F 1A 2C 05 00 70 BA 00 00 91 1A 2C 03 00 70 BA 00 00 1A 2C 01 00 70 BA 00 00 16 
	0F 1A 2C 06 00 70 BA 00 00 91 1A 2C 04 00 70 BA 00 00 1A 2C 02 00 70 BA 00 00 16 
06 F0 01 
	0F 1A 2C 05 00 70 BA 00 00 91 1A 2C 03 00 70 BA 00 00 1A 2C 02 00 70 BA 00 00 16 
	0F 1A 2C 06 00 70 BA 00 00 91 1A 2C 04 00 70 BA 00 00 1A 2C 01 00 70 BA 00 00 16 
0F 1A 2C 07 00 70 BA 00 00 91 90 1A 2C 05 00 70 BA 00 00 2C 03 16 2C 04 16 
0F 1A 2C 08 00 70 BA 00 00 91 90 1A 2C 06 00 70 BA 00 00 2C 03 16 2C 04 16 
0F 1A 2C 09 00 70 BA 00 00 91 93 1A 2C 05 00 70 BA 00 00 1A 2C 07 00 70 BA 00 00 16 2C 02 16 
07 72 05 96 1A 2C 09 00 70 BA 00 00 1A 2C 03 00 70 BA 00 00 16 
	0F 1A 2C 0A 00 70 BA 00 00 91 93 1A 2C 06 00 70 BA 00 00 1A 2C 08 00 70 BA 00 00 16 2C 02 16 
	07 55 05 96 1A 2C 0A 00 70 BA 00 00 1A 2C 04 00 70 BA 00 00 16 
		0F 1A 2C 0B 00 70 BA 00 00 2C 00 
		07 C4 04 96 1A 2C 0B 00 70 BA 00 00 2C 0A 16 
			A3 1A 2C 0B 00 70 BA 00 00 16 
			0F 00 6F BA 00 00 19 1B A1 7F 00 00 00 00 00 00 16 73 00 AC D2 00 00 00 1B 29 33 00 00 00 00 00 00 19 1B A1 7F 00 00 00 00 00 00 16 50 00 BC 0C 00 00 00 1B DD 3A 00 00 00 00 00 00 92 1A 2C 09 00 70 BA 00 00 A7 1A 2C 07 00 70 BA 00 00 16 16 92 1A 2C 0A 00 70 BA 00 00 A7 1A 2C 08 00 70 BA 00 00 16 16 A7 1A 2C 11 00 70 BA 00 00 16 16 28 28 27 16 
			19 1B A1 7F 00 00 00 00 00 00 16 38 00 C4 0C 00 00 00 1B E8 38 00 00 00 00 00 00 00 6F BA 00 00 1A 2C 0E 00 70 BA 00 00 1A 2C 0F 00 70 BA 00 00 1A 2C 10 00 70 BA 00 00 27 16 
			0F 00 6F BA 00 00 19 1B A1 7F 00 00 00 00 00 00 16 2E 00 BC 0C 00 00 00 1B DD 3A 00 00 00 00 00 00 1A 2C 0E 00 70 BA 00 00 1A 2C 0F 00 70 BA 00 00 1A 2C 10 00 70 BA 00 00 16 
			07 44 04 B0 E4 D8 00 6F BA 00 00 01 32 BA 00 00 16 16 1E 00 00 61 4A 16 
				06 D1 02
			07 B5 04 77 2E 1F B4 00 00 1B 3C 08 00 00 00 00 00 00 16 2A 16 
				07 B5 04 B0 E4 D8 00 6F BA 00 00 19 19 2E 1F B4 00 00 1B 3C 08 00 00 00 00 00 00 16 0A 00 FF B3 00 00 00 1C 00 B4 00 00 16 09 00 94 F8 FF FF 00 01 94 F8 FF FF 16 16 1E 00 00 61 4A 16 
					06 D1 02 
			0F 1A 2C 0B 00 70 BA 00 00 2C 00 
		07 38 05 9A 1A 2C 0B 00 70 BA 00 00 2C 00 16 
			0F 00 73 BA 00 00 1C 12 FC FF FF 20 32 42 00 00 4A 4A 00 6F BA 00 00 4A 4A 27 4A 16 
			19 00 73 BA 00 00 0A 00 00 00 00 00 00 1B 8D 41 00 00 00 00 00 00 16 
			55 00 72 BA 00 00 0A 00 00 73 BA 00 00 16 
		A1 1A 2C 0A 00 70 BA 00 00 1A 2C 06 00 70 BA 00 00 16
		06 A5 02 
	A1 1A 2C 09 00 70 BA 00 00 1A 2C 05 00 70 BA 00 00 16
	06 5D 02 
07 FE 05 84 84 9A 19 1B 3F 08 00 00 00 00 00 00 16 09 00 B2 B4 00 00 00 01 B2 B4 00 00 2C 08 16 18 24 00 9A 19 1B 3F 08 00 00 00 00 00 00 16 09 00 B2 B4 00 00 00 01 B2 B4 00 00 2C 0A 16 16 18 28 00 9A 38 3A 19 1B 3F 08 00 00 00 00 00 00 16 09 00 AF B4 00 00 00 01 AF B4 00 00 38 3A 24 09 16 16 
    0F 1A 2C 0C 00 70 BA 00 00 2C 00
06 06 09
	07 F7 08 84 9A 19 1B 3F 08 00 00 00 00 00 00 16 09 00 B2 B4 00 00 00 01 B2 B4 00 00 2C 03 16 18 24 00 9A 19 1B 3F 08 00 00 00 00 00 00 16 09 00 B2 B4 00 00 00 01 B2 B4 00 00 2C 04 16 16 
		0F 1A 2C 0D 00 70 BA 00 00 19 19 1B 25 63 00 00 00 00 00 00 16 09 00 16 BF 00 00 00 01 16 BF 00 00 0A 00 AB BC 00 00 00 1B F2 3B 00 00 00 00 00 00 16 
		0F 00 71 BA 00 00 35 90 AF 00 00 91 AF 00 00 00 00 19 19 1B 25 63 00 00 00 00 00 00 16 09 00 16 BF 00 00 00 01 16 BF 00 00 16 00 AE BC 00 00 00 1B CA 37 00 00 00 00 00 00 1A 2C 0D 00 70 BA 00 00 16 
		0F 00 71 BA 00 00 1B 14 6B 00 00 00 00 00 00 00 71 BA 00 00 1E 00 00 40 3F 16 
		0F 35 0C FD FF FF 16 F9 FF FF 00 00 00 6F BA 00 00 AE 35 00 FD FF FF 0F F9 FF FF 00 01 00 71 BA 00 00 AB C3 16 1B 56 68 00 00 00 00 00 00 00 71 BA 00 00 16 16 16 
		0F 35 0B FD FF FF 16 F9 FF FF 00 00 00 6F BA 00 00 AE 35 FE FC FF FF 0F F9 FF FF 00 01 00 71 BA 00 00 AB C3 16 1B 50 68 00 00 00 00 00 00 00 71 BA 00 00 16 16 16 
		0F 00 6F BA 00 00 19 1B A1 7F 00 00 00 00 00 00 16 16 00 AC D2 00 00 00 1B 29 33 00 00 00 00 00 00 00 6F BA 00 00 28 28 27 16 
		19 1B A1 7F 00 00 00 00 00 00 16 38 00 C4 0C 00 00 00 1B E8 38 00 00 00 00 00 00 00 6F BA 00 00 1A 2C 0E 00 70 BA 00 00 1A 2C 0F 00 70 BA 00 00 1A 2C 10 00 70 BA 00 00 27 16 
		0F 00 6F BA 00 00 19 1B A1 7F 00 00 00 00 00 00 16 2E 00 BC 0C 00 00 00 1B DD 3A 00 00 00 00 00 00 1A 2C 0E 00 70 BA 00 00 1A 2C 0F 00 70 BA 00 00 1A 2C 10 00 70 BA 00 00 16 
		0F 00 73 BA 00 00 1C 12 FC FF FF 20 32 42 00 00 4A 4A 00 6F BA 00 00 4A 4A 27 4A 16 
		19 00 73 BA 00 00 0A 00 00 00 00 00 00 1B 8D 41 00 00 00 00 00 00 16 
		55 00 72 BA 00 00 0A 00 00 73 BA 00 00 16 
		0F 1A 2C 0C 00 70 BA 00 00 2C 01
	06 06 09
		0F 1A 2C 0C 00 70 BA 00 00 2C 01
07 90 09 9A 1A 2C 0C 00 70 BA 00 00 2C 00 16 
	2F 19 01 A6 F9 FF FF 5A 00 00 00 00 00 00 61 30 20 32 42 00 00 00 73 BA 00 00 4A 16 8F 09 
		07 8E 09 19 00 73 BA 00 00 0A 00 EC 3F 00 00 00 2D 01 EC 3F 00 00 
			55 00 72 BA 00 00 0A 00 00 73 BA 00 00 16 
			0F 1A 2C 0C 00 70 BA 00 00 2C 01 
		31
		30
0F 01 36 BA 00 00 00 72 BA 00 00 
0F 01 35 BA 00 00 01 36 BA 00 00 
04 0B 
0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 
53

 

Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.

×
×
  • Create New...