Jump to content

R&D XCOM Map Alterations


Amineri

Recommended Posts

Just, please review the wiki articles for accuracy.

Yes, I intend to, after I find all the information, I'm looking for, and try some in-game experiments.

 

I do some minor editorial tweaking as I realize English is not your native language (though it's really very, very good).

Thanks. :smile: I don't mind editing. I realize I'm probably making all sorts of grammar mistakes. :smile:
Link to comment
Share on other sites

  • Replies 473
  • Created
  • Last Reply

Top Posters In This Topic

I am now investigating a possibility to place more pods on map. Theoretically it can be done via adding new objects, but I don't know if map package will permit it and if I can add a new entry into TheWorld.PersistentLevel object.

 

Another way to place more pods on map is to get location info from another object, for example, XComRadarArrayActor on EXALT maps, and place aliens around it. (Of course, we can place pods on any random location, but there is no guarantee they won't end up inside the rock somewhere or totally off map.)

 

Now about those spawn points. There are several classes, other than XGDeployAI, where WorldInfo on XComAlienPod is accessed. XComAlienPodManager uses it in several functions and I'm wondering will it beak AI if I'll try to place aliens on "wrong" positions.

Link to comment
Share on other sites

Actually the XComAlienPodManager dynamically creates additional spawn points.

 

Technically a single spawn point is a single tile position, and so is only valid for a single unit. So the six spawn points for the XCOM units (albeit multiple sets of six for the multiple possible PlayerStart positions).

 

XComAlienPodManager I've messed with when increasing the size of the alien pod. What it does is create additional spawn points in the 3x3 grid centered on the defined map spawn point, and then place the aliens in the newly created spawn point. For 2 aliens they are at 180º ends, while for 3 aliens they are at 120º. Hence things can start to get a bit crowded once more than 8 aliens are getting spawned. I'd experimented for a while with placing the first alien at the center point and the remaining aliens around the center point, which allows up to 9 aliens to be placed, completely filling out the 3x3 grid.

 

There is a bunch of code present to try and place aliens in "good" locations, including moving the point up and then snapping it to the floor. However when I tried to array aliens in a larger circle radius so extend beyond the 3x3 grid I started to have problems (in theory this should be okay, though).

 

-----------------

 

The remaining question I need to sort out is where the character stats are loaded for the dynamically placed aliens (for council missions, exalt waves, or the temple ship). I know that aliens spawned from the definitions in the strategy game (e.g. XGStrategyAI.DetermineAbductionSquad or XGStrategyAI.DetermineSpecialMissionSquad) are created in XComAlienPodManager.OvermindSpawn. I've added a call in there to a new helper function which helps to individualize aliens (create alien leaders and navigators), like :

        if(iNum < kPod.NumAliens)
        {
            kSpawnPt = kPod.GetSpawnPoint(iNum, vLoc, true);
            if(kSpawnPt != none)
            {
                kSpawnPt.SnapToGround(32.0);
                eAlienType = class'XGGameData'.static.MapCharacterToPawn(arrPodMembers[iNum]);
                bUseAltWeapon = (128 & kSpawn.kPod.eMainAltWeapon) != 0;
                kAlien = m_kPlayer.SpawnAlien(eAlienType, kSpawnPt,,,, bUseAltWeapon);
                if(kAlien != none)
                {
                    if(iNum == 0)
                    {
                        kAlien.DebugAnims(7 & kSpawn.kPod.eMainAltWeapon, none);
                    }

However this doesn't appear to be how dynamic alien stats are initialized, which makes it more difficult to "beef up" the alien stats for the final Temple Ship mission.

Link to comment
Share on other sites

You may notice that in the above code, the spawn point is retrieved separately for each alien placed :

            kSpawnPt = kPod.GetSpawnPoint(iNum, vLoc, true);

This function is in XComAlienPod.

 

XComAlienPod.GetSpawnPoint has a couple of branches. If the third (optional) parameter is left blank or is false, then the code uses CustomStartLocations (but only if the array has non-zero length). Code such as :

            vLoc_Out = XComTacticalGRI(WorldInfo.GRI).GetClosestValidLocation(vLoc_Out, none,, false);

is used liberally to try and ensure a valid spawn location.

 

If the 3rd parameter is true, then the "circle method" of generating additional spawn points around the center point is used:

        if(iAlien < NumAliens)
        {
            vLoc_Out = GetDistributedLocationAround(Location, iAlien, Rotation, true);
            kSpawnPoint = Spawn(class'XComSpawnPoint_Alien',,, vLoc_Out, rotator(Location - vLoc_Out),, true);
            return kSpawnPoint;
        }

The GetDistributedLocationAround selects a position in an adjacent tile (in the 3x3 grid surrounding the given spawn point location), and the next line spawns a new XComSpawnPoint_Alien at the designated location, and returns that spawn point to place the alien into.

 

A similar method was used to dynamically create additional generic spawn points near the existing six soldier spawn points in order to handle spawning more than six soldiers (without having to alter the mapfile).

Link to comment
Share on other sites

Actually, map package doesn't provide the info on individual spawn points. It provides only XComAlienPod info, which holds default properties on the whole "Spawn" and location is just one of those. XComAlienPod map objects serve as a "templates" for creating a pod of specified type at specified location. They deal with pod as a whole. BTW, there are NumAliens_Min and NumAliens_Max properties. They are used in PodManager too. I know they used to create test pods for controlled games, but I don't know if they're used somewhere else.

 

Council missions and EXALT missions use different dynamic aliens spawn methods. All EXALT maps, except HQ, use XComWaveSystem to add dynamic aliens in waves. Some of the alien stats are defined in map objects, and alien type is chosen randomly from the list of available aliens in current squad (see my posts in modding EXALT topic). XCOM HQ Assault map uses XComWaveSystem for alien waves deployment too and it is BIG.

 

Council missions and Temple Ship mission use triggers (zones on map or global events) to spawn a group of aliens. For example, there are a couple of SeqAct_AlienContent_Request and SeqAct_SpawnAlien objects in MainSequence of Temple Ship map package, in which alien type and some other properties are defined. I'm not quite sure how they work as I haven't looked into them yet.

 

So, my problem isn't in the XComSpawnPoint object, which doesn't hold very much data, but in the XComAlienPod object, which defines alien pod placement and some other properties, like patrolling routes, forced alien types, pod type, etc.

Edited by wghost81
Link to comment
Share on other sites

To me it looks like XComAlienPod can either contain a single Location (in which case all of the aliens in the pod are distributed around that location) :

 

OR

 

The XComAlienPod can contain a CustomStartLocations array, in which case the alien is placed at CustomStartLocations[iAlien].Location. The CustomStartLocations array is prototyped as a class variable in XComAlienPod as :

var() array<XComSpawnPoint> CustomStartLocations;

which is indeed a dynamic array of XComSpawnPoint's.

 

I'm not sure what exactly the () after the var tag that UE Explorer is diplaying means, but only some of the variables have that notation. Perhaps it's indicating which variables are supposed to be initialized from the mapfile?

Link to comment
Share on other sites

I'm not sure what exactly the () after the var tag that UE Explorer is diplaying means, but only some of the variables have that notation. Perhaps it's indicating which variables are supposed to be initialized from the mapfile?

No, it says, that those can be edited directly in Unreal Editor.

 

XComAlienPod is... a Pod. It literally is. I.e. pods are already placed on maps via XComAlienPod_X archetypes. They are not only locations, although in most cases only location info is used. Example:

 

 

0x000037AF (14255): XComAlienPod'TheWorld.PersistentLevel.XComAlienPod_2'
	TypeRef: 0xFFFFFF40 -> XComAlienPod
	ParentClassRef: 0x00000000 -> 
	OwnerRef: 0x00000770 -> PersistentLevel
	NameIdx: 0x00000E74 (Index) 0x00000003 (Numeric) -> XComAlienPod_2
	ArchetypeRef: 0x00000000 -> 
	ObjectFlagsH: 0x00000000
	ObjectFlagsL: 0x02070001
		0x00000001: Transactional
		0x00010000: LoadForClient
		0x00020000: LoadForServer
		0x00040000: LoadForEdit
		0x02000000: HasStack
	SerialSize: 0x00000166 (358)
	SerialOffset: 0x01D12B90
	ExportFlags: 0x00000000
	NetObjectCount: 0
	GUID: 00000000000000000000000000000000
	Unknown1: 0x00000000
UObject:
	PrevObjRef = 0xFFFFFF40 -> XComAlienPod
Can't deserialize stack: skipping!
UDefaultPropertiesList:
UDefaultProperty:
	NameIdx: 0x000009F8 (Index) 0x00000000 (Numeric) -> PodIndex
	TypeIdx: 0x000006BA (Index) 0x00000000 (Numeric) -> IntProperty
	PropertySize: 0x00000004
	ArrayIdx: 0x00000000
	Integer: 0x00000002 = 2
UDefaultProperty:
	NameIdx: 0x0000073A (Index) 0x00000000 (Numeric) -> LoopType
	TypeIdx: 0x000002D7 (Index) 0x00000000 (Numeric) -> ByteProperty
	PropertySize: 0x00000008
	ArrayIdx: 0x00000000
	InnerNameIdx: 0x000004F7 (Index) 0x00000000 (Numeric) -> EPathLoopType
	Name: 0x000009BD (Index) 0x00000000 (Numeric) = PATH_TYPE_FORWARD_BACKWARD_LOOP
UDefaultProperty:
	NameIdx: 0x000006FC (Index) 0x00000000 (Numeric) -> LightEnvironment
	TypeIdx: 0x000008FC (Index) 0x00000000 (Numeric) -> ObjectProperty
	PropertySize: 0x00000004
	ArrayIdx: 0x00000000
	Object: 0x000003D6 = DynamicLightEnvironmentComponent_3538
UDefaultProperty:
	NameIdx: 0x000008F2 (Index) 0x00000000 (Numeric) -> NumAliens_Min
	TypeIdx: 0x000006BA (Index) 0x00000000 (Numeric) -> IntProperty
	PropertySize: 0x00000004
	ArrayIdx: 0x00000000
	Integer: 0x00000003 = 3
UDefaultProperty:
	NameIdx: 0x000008F1 (Index) 0x00000000 (Numeric) -> NumAliens_Max
	TypeIdx: 0x000006BA (Index) 0x00000000 (Numeric) -> IntProperty
	PropertySize: 0x00000004
	ArrayIdx: 0x00000000
	Integer: 0x00000003 = 3
UDefaultProperty:
	NameIdx: 0x000009F9 (Index) 0x00000000 (Numeric) -> PodMesh
	TypeIdx: 0x000008FC (Index) 0x00000000 (Numeric) -> ObjectProperty
	PropertySize: 0x00000004
	ArrayIdx: 0x00000000
	Object: 0x00002FDD = StaticMeshComponent_371
UDefaultProperty:
	NameIdx: 0x000009BF (Index) 0x00000000 (Numeric) -> PathNodes
	TypeIdx: 0x0000017F (Index) 0x00000000 (Numeric) -> ArrayProperty
	PropertySize: 0x00000010
	ArrayIdx: 0x00000000
	NumElements = 0x00000003 = 3
	ArrayInnerType = None
	PathNodes[0]:
	Unsafe guess: It's an Integer: 0x00003799 = 14233 or a Reference: 0x00003799 -> XComAlienPathNode_0
	PathNodes[1]:
	Unsafe guess: It's an Integer: 0x000037A5 = 14245 or a Reference: 0x000037A5 -> XComAlienPathNode_2
	PathNodes[2]:
	Unsafe guess: It's an Integer: 0x0000379A = 14234 or a Reference: 0x0000379A -> XComAlienPathNode_1
UDefaultProperty:
	NameIdx: 0x00000309 (Index) 0x00000000 (Numeric) -> CenterpieceMesh
	TypeIdx: 0x000008FC (Index) 0x00000000 (Numeric) -> ObjectProperty
	PropertySize: 0x00000004
	ArrayIdx: 0x00000000
	Object: 0x00002FDE = StaticMeshComponent_372
UDefaultProperty:
	NameIdx: 0x0000071A (Index) 0x00000000 (Numeric) -> Location
	TypeIdx: 0x00000C54 (Index) 0x00000000 (Numeric) -> StructProperty
	PropertySize: 0x0000000C
	ArrayIdx: 0x00000000
	InnerNameIdx: 0x00000E19 (Index) 0x00000000 (Numeric) -> Vector
	Vector (X, Y, Z) = (0xC4164382, 0xC3D60B27, 0x43420622) = (-601.055, -428.087, 194.024)
UDefaultProperty:
	NameIdx: 0x00000D1B (Index) 0x00000000 (Numeric) -> Tag
	TypeIdx: 0x000008D1 (Index) 0x00000000 (Numeric) -> NameProperty
	PropertySize: 0x00000008
	ArrayIdx: 0x00000000
	Name: 0x00000E74 (Index) 0x00000000 (Numeric) = XComAlienPod
UDefaultProperty:
	NameIdx: 0x000008EA (Index) 0x00000000 (Numeric) -> None
Stream relative position (debug info): 0x00000166 (358)

 

Pre-placed pods usually describe some generic pod, so actual pod is spawned from kAlienSquad array. But you can set all the details inside a map object, i.e. embed a pod in a map directly. You can set pod type, pod main alien... all the info, which is set in a scripts, as every class property can be initialized in archetype.

 

I found, that XComAlienPod map info is used in XComAlienPodManager in functions:

LoadInit

InitPods

SelectSpecialtyPods

GenerateSpawnList

DebugLogAllPods

HasPodsInGroup

 

And in XGAIPlayer_Animal (for civilians): GetGoodCoverPoints_Civilian function.

 

I don't know will it break those functions if I'll try and place pods not via XComAlienPod defined in maps, but via XComAlienPod objects defined in scripts.

Edited by wghost81
Link to comment
Share on other sites

Two words on maps streaming in XCOM.

 

UDN info:

Content Streaming

Level Streaming

 

XCOM maps streaming

 

Some maps in XCOM have a very small size and very little info inside. That's because they're not actual maps, but packages which are streamed in when actual map is loaded.

 

In DefaultMaps.ini there is an array property StreamingMaps. For most of the maps it contains cinematic package link (CIN_DropshipIntros or CIN_FastropeIntros), but for some maps it contains another link. For example, for Pier Covert Extraction map name is "URB_PierA_Terror" (which is actual map package) and StreamingMaps array contains two entries: "CIN_DropshipIntros" and "URB_PierA_Terror_CovExt". First entry is a link to deployment cinematic package and second is a link to package with EXALT-related info only. It contains EXALT relays data, XComAlienPod data and WaveSystem data mostly. There is no PlayersStart info, so it must be taken from original package "URB_PierA_Terror". PierA is actually widely used map. :smile: It has three "full" variants for abductions and terror: URB_PierA, URB_PierA_Asian and URB_PierA_Terror. And other three variants, which are used in special missions and stream in additonal info:

URB_PierA with streamed URB_PierA_StreamB is used for "Assault on Pier".

URB_PierA with streamed URB_PierA_Stream is used for "Pier Rescue".

URB_PierA_Terror with streamed URB_PierA_Terror_CovExt is used for "Covert Extraction".

 

Now, I can't claim I understand Unreal Streaming, but it seems they use it for maps to load additional info and create special mission variants without a need to include full map with just a few alterations.

 

Interesting question is, how is streamed content used with original content? For example, if there is no PlayerStart info defined, it definitely is taken from the original package. But if there is one, it overrides original info, even if it has different numeric in Name Index. And most of all, I'm interested in how XComAlienPod info is used. For example, there are 4 pods in URB_PierA_Terror map and only 2 in URB_PierA_Terror_CovExt package. And it seems, only 2 streamed pods are "seen" by WorldInfo. How it gets overridden and can it be still accessed - those are a very good questions...

Edited by wghost81
Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.

×
×
  • Create New...