Jump to content

R&D XCOM Map Alterations


Amineri

Recommended Posts

Actually, as far as I can see, InitPlayers() function, which is called from inside Initing and Loading states of XGBattle, does call all the necessary alien init functions. And pods or individual aliens, created by random spawn, do show up immediately. BTW, game did crashed on briefing screen several times, when I messed up deployment code, so it is called during briefing in normal game.

But there are a lot of code, which is used for debug missions init. For example, when you create a mission from developer shell menu. And there are a lot of if-else "safety" code, which checks for proper initialization.

More on battle initialization

XGBattle state Initing calls for the functions

  • InitDescription()
  • InitLevel()
  • PostLevelLoaded()
  • InitPlayers()

XGBattle_SP.InitDescription() calls for XGBattleDesc.InitAlienLoadoutInfos(), which builds pods and loadouts.

 

XGBattle_SP.PostLevelLoaded() inits meld containers and capture points by calling InitMeldContainers() and InitCapturePoints() respectively.

 

XGBattle_SP.InitPlayers() calls for XComAlienPodManager.InitPods() and then for each player calls XGAIPlayer.LoadSquad().

XComAlienPodManager.InitPods() centers each pod location on tile, inits patrol routes (if pod has any), checks if pod is enabled and hides/shows pod body depending on current situation.

 

XGAIPlayer.LoadSquad() calls for XGAIPlayer.CreateSquad().

 

There are several places along this chain of function calls, where transfer data are checked and created if necessary: mission description, narrative moments, human squad...

 

Alien squad is created by XGAIPlayer.CreateSquad():

XComAlienPodManager.InitPlayer() is called, which initializes Overmind by calling XGOvermind.Init(). XGOvermind.Init() performs alien spawn initialization by calling for XGDeployAI.DeployPods(), which assigns a pod from transfer save to map pod "placeholders".

XComAlienPodManager.SpawnAllPodAliens() is then tries to spawn preplaced pods. If it fails, following code tries to create a random pods on any available pod "placeholder". If it fails too, function creates random individual aliens, randomly distributed throughout the map.

 

XComAlienPodManager.SpawnAllPodAliens() first tries to create pods from transfer save. If it fails, it calls for CheckAlienCounts() to try and build pods from info, embedded into XComAlienPod "placeholders". It analyzes all the info and creates pods, based on specialty, alien numbers and patrol routes: as many, as it can.

 

With so much "safety" spawns, I suspect this code will create an alien squad even on totally empty map. :)

 

 

 

Being able to add additional random pods (or replacing old pods with new randomized locations) will go a long way toward adding replayability to the maps.

I was thinking the same thing. :)

 

 

 

However what I'd also be interested in is a way to trigger aliens appearing during a mission, in a manner simlar to how the Mutons appear in the Slingshot Confounding Light mission. (I recognize that it's quite possible that the particle effects may be baked into the map instead of in a separate upk).

Yes, all the effects and dynamic spawns are embedded into the map package.

Link to comment
Share on other sites

  • Replies 473
  • Created
  • Last Reply

Top Posters In This Topic

Now, here is something you don't see every day. :smile:

 

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

 

24 procedural-generated alien pods! Looks scary. :smile: Textures aren't loaded because alien type is none. :smile: I got lazy and did some quick and dirty changes to see the result. :smile:

 

I haven't yet updated sorting procedure and placement logic, but I was able to generate a 5x5 uniform grid of 25 pods total.

 

I've run into same problems with borrowed variables, Amineri mentioned in New Modding Tools thread: sometimes they cause CTD and you can't understand why. For example, I borrowed 4 variables from XComMeldContainerActor.InitFromSpawnPoint function:

    local Vector vLocation;
    local int iTileX, iTileY, iTileZ;
Integers worked just fine, but vLocation caused CTD. But other Vector variable, borrowed from another function, worked perfectly.

 

Eventually, I was forced to construct this monstrosity:

kPod = Spawn(class'XComAlienPod',,, World().FindClosestValidLocation(World().GetPositionFromTileCoordinates(World().NumX/6 * iPod, World().NumY/6 * iTestPod, 0), false, false, true),,, true);
It (re)uses only local GetPossibleSpawns variables and works fine.
Link to comment
Share on other sites

That's a crazy number of alien pods, very nice work :)

 

 

I've run into same problems with borrowed variables, Amineri mentioned in New Modding Tools thread: sometimes they cause CTD and you can't understand why. For example, I borrowed 4 variables from XComMeldContainerActor.InitFromSpawnPoint function:

    local Vector vLocation;
    local int iTileX, iTileY, iTileZ;
Integers worked just fine, but vLocation caused CTD. But other Vector variable, borrowed from another function, worked perfectly.

 

I've also run into cases where there is no CTD, but the borrowed local variable just doesn't work right -- it "loses" it's assigned value while the function is running. Swapping to another local variable has usually resolved the issue.

 

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

 

Have you experimented with hooking this system up to the pod data sent over from the strategy game?

 

All of this data gets stored in XComAlienPodManager:

var array<TAlienSpawn> m_arrSpawnList;

Pods are drawn from this list one at a time in XComAlienPodManager.OvermindSpawn, which is partly where the increased alien pod size is implemented (as I'm sure you're aware :D )

 

The array appears to be initialized in XComAlienPodManager.InitPlayer via the line:

    kPlayer.m_kOvermindHandler.InitOvermind();
    kPlayer.m_kOvermindHandler.m_kOvermind.Init(m_arrSpawnList);

This Init function is found in XGOvermind :

function Init(out array<TAlienSpawn> arrSpawns)
{
    if(class'XComEngine'.static.SyncRand(2, (string(Name) @ string(GetStateName())) @ string(GetFuncName())) == 0)
    {
        ToggleDeflection();
    }
    InitWaveSystem();
    m_vEnemySpawn = BATTLE().GetHumanPlayer().GetSquad().GetPermanentMemberAt(0).GetLocation();
    m_kDeploy = Spawn(class'XGDeployAI', self);
    arrSpawns = m_kDeploy.DeployPods(BattleDesc().m_kAlienSquad);
    if(BattleDesc().m_bIsTutorial && BattleDesc().m_bScripted)
    {
        arrSpawns.Length = 0;
    }
    m_kLayout = Spawn(class'XGLayout', self);
    m_kLayout.BuildBounds();
    CalcMapDirection(arrSpawns);
    m_kLayout.BuildLayout();
    m_arrSpawns = arrSpawns;
    m_kEnemy = Spawn(class'XGEnemy', self);
    m_kEnemy.Init();
    m_iTurnsSinceCall = 10;
    //return;    
}

which seems to do a bunch of interesting things:

  1. init the wave system
  2. retrieves the alien squad info from XGBattleDesc and invoked DeployPods on them
Link to comment
Share on other sites

I'm sure I'm getting ahead of things, but I'd like to interject, in hooking this into the pod data, would be it be possible to initialize new random pod locations as roaming pod spawn points? There's some unused features in XGStrategyAI for a fourth pod type (#3), called roaming. This is in addition to soldier (all missions), secondary (terror, large UFOs and alien base assaults), and commander (UFOs only).

 

I've tried initializing roaming pods in missions, but the assigned aliens never appear.

 

Would be a way for modders to control the types of aliens appearing in the new spawns, differentiating them from the usual types, if desired.

Link to comment
Share on other sites

Amineri, I described and entire battle init procedure in an early posts in this thread. :wink: And Dubious made a wiki article about it. :wink: Yes, I am in fact initializing pods, which are used to generate m_arrSpawnList in m_kDeploy.DeployPods(BattleDesc().m_kAlienSquad). I did it as early as I could, to allow PodManager to handle all the conversion and init problems later and it woked just fine in an actual game.

 

johnnylump, actually, roaming aliens are used for ThinMen drops:

 

function DeployRoaming()
{
    KismetRoamingNumber(m_kSquad.iNumDynamicAliens);
    //return;    
}

function KismetRoamingNumber(int iNum)
{
    local array<SequenceObject> arrEvents;
    local SequenceObject kEvent;

    WorldInfo.GetGameSequence().FindSeqObjectsByClass(class'SeqEvent_RoamingAlienNumberSet', true, arrEvents);
    // End:0x91
    foreach arrEvents(kEvent,)
    {
        SeqEvent_RoamingAlienNumberSet(kEvent).iNumAliens = iNum;        
    }    
    TriggerGlobalEventClass(class'SeqEvent_RoamingAlienNumberSet', self);
    //return;    
}

 

 

The pods I've added are not complete pods, they are just placeholders, which can (and in fact are) be converted to any type from PodManager. DeployAI just selects random placeholders to be occupied by actual pods from AlienSquad array and PodManager then performs all the necessary conversion, alien spawns and AI initialization.

Link to comment
Share on other sites

Just as an aside (been looking into meld containers), the UI isn't designed to be able to handle both the meld timer and the EXALT special mission timer at the same time :

controllerRef.m_Pres.PopupDebugDialog("ERROR:", "Found CONTROL POINT and MELD CANNISTERS in same level. This is a UI violation!");
Link to comment
Share on other sites

We who? :smile:

 

Seems like it's relatively easy to randomize alien placement, meld and exalt radar arrays placement, starting location. It also seems possible to randomize dynamic alien drop points. Other map objects are not that easy to find and identify and to move dynamically without overlapping.

 

Basically, we won't be able to generate the whole new maps "on the fly".

 

BTW, I can't understand why Firaxis didn't used UE map streaming abilities to create semi-random maps like in the OG.

Link to comment
Share on other sites

BTW, I can't understand why Firaxis didn't used UE map streaming abilities to create semi-random maps like in the OG.

 

From my personal experience in modding maps on the OG it's just too time consuming if you really want to make something that doesn't look like a bunch of map blocks randomly joined together. It's like putting a 3D puzzle together when you're designing the terrain blocks, and the end result doesn't look as good visually as the EU maps, even if you add extra coding to give some variations (which is even more time consuming).

 

That said, I have no idea of how UE map streaming works.

 

There is also some few legacy code on XComStrategyGame.upk, XGWander class that seemed to indicate that at one point they wanted to fit the terrain in the maps to the actual terrain on Geoscape but it seems they dropped it:

enum eTerrainType
{
	eTerrain_None,
	eTerrain_WaterDeep,
	eTerrain_WaterShallow,
	eTerrain_Beach,
	eTerrain_Grass,
 	eTerrain_Hills,
	eTerrain_Mountains,
	eTerrain_MAX
};
Edited by Hobbes77
Link to comment
Share on other sites

We who? :smile:

 

Seems like it's relatively easy to randomize alien placement, meld and exalt radar arrays placement, starting location. It also seems possible to randomize dynamic alien drop points. Other map objects are not that easy to find and identify and to move dynamically without overlapping.

 

Basically, we won't be able to generate the whole new maps "on the fly".

 

BTW, I can't understand why Firaxis didn't used UE map streaming abilities to create semi-random maps like in the OG.

We being the community on this site :)

 

And that's a shame. I just can't wait until our community has another thing to make Firaxis feel silly when we mod in a feature they said was nearly impossible to add. But it seems like that's still a ways away.

Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.

×
×
  • Create New...