Jump to content

Randomising Enemy Unit Stats


lamaros

Recommended Posts

EladDv's method might be better in the end, but I'm going to see where i get with this.

 

My current knowledge problem is how to use the entries in the array to get the units estats. How do I take two values like follows:

 

EnemyRandomNCE[0]=AdvTrooperM1
EnemyStatRandom[0]=eStat_HP

And convert that to code that will effectively ask AdvTrooperM1.getBaseMaxStat(eStat_HP)

 

I've tried a few ways, converting to strings and whatnot, but I'm a bit too beginner for it it seems.

 

My awful code, to see where I'm going wrong.:

INI

EnemyRandomNCE[0]=AdvTrooperM1
EnemyRandomStatNCE[0]=eStat_HP
StatRandomAmountNCE[0]=1


Class

var config array<int> EnemyRandomNCE;
var config array<int> EnemyRandomStatNCE;
var config array<int> StatRandomAmountNCE;

//random enemy test

function RandomEnemyStats(XComGameState_Unit Unit)
{
		local array<int> RandomStats;
		local int n;
		local int currentStat;
		local bool endThis;
		local string getEnemyRandomNCE;
		local string getEnemyRandomStatNCE;

		do
			{
				endThis=false;
				getEnemyRandomNCE=string(EnemyRandomNCE[n]);
				getEnemyRandomStatNCE=string(EnemyRandomStatNCE[n]);
				for(n=0;n<10;n=n++)
				{		
					currentStat=(Rand((ABS(StatRandomAmountNCE[n]))+1));
					RandomStats.addItem((getEnemyRandomNCE.getBaseMaxStat(getEnemyRandomStatNCE))+currentStat);
				
				}
				
				getEnemyRandomNCE.setBaseMaxStat(getEnemyRandomStatNCE,RandomStats[n]);

				endThis=false;

			} Until(endThis==true);

}
Edited by lamaros
Link to comment
Share on other sites

A few things that immediately catch my attention

  • Do not prefix any variables with get, this makes them look like they are functions.
  • Try to do as little casts (type conversions) as you can get away with. (but I understand you are trying around, so maybe scratch that for now...)
  • Try to ask your self questions like: What type does this variable have? This might be helpfull to get you off the ground...

I'm not gonna lie: You still have some road ahead of you for this project.

 

If I understand correctly what you try to do, its modifying a units state. To do this you have to create a new GameState, add changes to that and finaly commit the new GameState. I suspect there is information about stuff like this in this forum.

 

This

[...] code that will effectively ask AdvTrooperM1.getBaseMaxStat(eStat_HP)

 

 

 

will not work, because AdvTrooperM1 is the name of the CharacterTemplate. The enginge uses it to create new XComGameState_Unit's. If you would change that, then all the troopers woold receive the same 'random' change in stats.

Edited by eXecator
Link to comment
Share on other sites

I do have a long way to go, that's true :), but a lot further along that yesterday when I was literally clueless.

 

Thanks for the pointers.

 

  • The variable names were just thrown in there for five seconds to see if it did anything, not a naming convention i'm going for.
  • Yeah, didn't want to do that either, was just seeing if it did anything.
  • I'm not entirely sure what you mean by 'type'.

 

Ok, so what I'm looking at is...

function OnCreation(X2CharacterTemplate CharTemplate)
{
    local int i;
    local ECharStatType StatType;

    m_CharTemplate = CharTemplate;
    m_TemplateName = CharTemplate.DataName;

    UnitSize = CharTemplate.UnitSize;
    UnitHeight = CharTemplate.UnitHeight;

    for (i = 0; i < eStat_MAX; ++i)
    {
        StatType = ECharStatType(i);
        CharacterStats[i].Type = StatType;
        SetBaseMaxStat( StatType, CharTemplate.CharacterBaseStats[i] );
        SetCurrentStat( StatType, GetMaxStat(StatType) );
    }

Which seems more the right track?

Link to comment
Share on other sites

So, logically speaking, I have to:

 

a) check the unit being created, and the stat being set

 

b) check that against my config arrays to see if that combination is included there

 

c) if so then if check how much to modify the template base stat by when setting it

 

d) then set the stats, and move onwards.

 

Does that seem correct?

Link to comment
Share on other sites

I'm not entirely sure what you mean by 'type'

 

 

 

You might know all of the following, but just in case... ;-)

 

A variable declaration consists of at least two things

  • a name, so we can talk about whatever-it-is
  • a type, so we know what kind of thing whatever-it-is is

in your case

string getEnemyRandomNCE;

you say you want to talk about a string called getEnemyRandomNCE which is fine. Later on you try

getEnemyRandomNCE.getBaseMaxStat(...)

this should not work, unless the type 'string' offers a function getBaseMaxStat, which it (hopefully) doesn't.

 

This would work (allthough this will not help you...) if you did something like this.

class SomethingThatGetsStats extends object;

string function getBaseMaxStat(string something)
{
  return "here you go";
}

and had used this declaration

local SomethingThatGetsStats getEnemyRandomNCE;
Edited by eXecator
Link to comment
Share on other sites

Ok, so what I'm looking at is...
function OnCreation(X2CharacterTemplate CharTemplate)

 

 

 

If you could modify that function to include your modification logic, then you would be good to go. In fact this would be the cleanest way possible I think. Sadly that function resides in XComGameState_Unit which is a gamestate class and therefore native. So you can't.

 

That's the reason Eladdv202 wants to manipulate the values later on, in tactical.

 

If you however find a way to

 

check the unit being created, and the stat being set

 

 

 

than i guess that would be preferable.

Link to comment
Share on other sites

Can I do something like:

 

function RandomEnemyStats(XComGameState_Unit Unit)
{

if( (CharTemplate.CharacterGroupName == 'AdvTrooperM1') && (CharTemplate.CharacterStats.Type == 'eStat_HP')
{
Unit.SetBaseMaxStat( eStat_HP, blah blah)
}

}

 

Nevermind! :blush:

Edited by lamaros
Link to comment
Share on other sites

I think you should use

CharTemplate.DataName

to check for the template name and not the group name, which would be the same for all troopers (advanced, elite and such...).

 

Also, I dont get the intention behind

&& (CharTemplate.CharacterStats.Type == 'eStat_HP')

I think you wanna skip that.

 

Your main tasks now would be to

  • fill the CharTemplate variable from the Unit you receive
  • find a way to call your function with units you want to manipulate

 

As an additional point: The Unit.SetBaseMaxStat might work, or it wont. It either case it will not be the 'regular' way to do this. That would involve as I mentioned some posts ago, creating a new game state, containing the changes you make. But maybe you want to solve the above points first.

Edited by eXecator
Link to comment
Share on other sites

I think you should use

CharTemplate.DataName
to check for the template name and not the group name, which would be the same for all troopers (advanced, elite and such...).

 

Also, I dont get the intention behind

&& (CharTemplate.CharacterStats.Type == 'eStat_HP')
I think you wanna skip that.

 

Your main tasks now would be to

  • fill the CharTemplate variable from the Unit you receive
  • find a way to call your function with units you want to manipulate

As an additional point: The Unit.SetBaseMaxStat might work, or it wont. It either case it will not be the 'regular' way to do this. That would involve as I mentioned some posts ago, creating a new game state, containing the changes you make. But maybe you want to solve the above points first.

From my experience with NCE it's clear that this way of setting stats are working fine most (if not all) of the time.
Link to comment
Share on other sites

Hmm, so I'm obviously missing something. Soldiers are not units in the same way Advent Troopers are?


How come,



function RandomStats(XComGameState_Unit Soldier)
{Soldier.setBaseMaxStat(eStat_HP,randomVariable)}


seems to work, but



function RandomStats(XComGameState_Unit AdvTrooperM1)
{AdvTrooperM1.setBaseMaxStat(eStat_HP,randomVariable)}


doesn't?


I'm know I'm missing something here, but struggling to parse everything.


Also, going back to an earlier point,




class SomethingThatGetsStats extends object;

string function getBaseMaxStat(string something)
{
return "here you go";
}

local SomethingThatGetsStats getEnemyRandomNCE;


This gives the string SomethingThatGetsStats the function getBaseMaxStat, for with the string variable something?


So I want to use the function setBaseMaxStat to set the eStat_HP for Solder. Writing this out it works to say,



Soldier.setBaseMaxStat(eStat_HP,8)}


From my experience it seems that if I have this code,



function RandomStats(XComGameState_Unit Soldier)
{Soldier.setBaseMaxStat(eStat_HP,8)}


It will set soldier health to 8.


But, if I want to break that down in to variables,


local string UnitRandomType

local string UnitRandomStatType

local int UnitRandomStatValue


and then vary the setBaseMaxStat function based on those variables, I'd go somewhere like?



string function getBaseMaxStat(UnitRandomStatType,UnitRandomStatValue)
{
return "here you go";
}


Hmm that doesn't seem right. I've lost myself here..

Edited by lamaros
Link to comment
Share on other sites

  • Recently Browsing   0 members

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