A_Wal_ wrote: ↑Sat Aug 31, 2024 8:09 am
Omg, I was literally just thinking about this exact thing! In Init I was going to add a level randomisier and use the new InitAbility function to give them random abilities. Are you talking about actually keeping track of they're xp for level ups and carrying them over to future matches? That's even better.
Randomizing the AI levels is a cool idea. Yeah, I'm planning to carrying the AI levels over with their abilities. Which reminds me, I ran into an intermittent bug when initializing units in StartTurn. Occasionally, and only on turn 0, GetUnitStatus() would always return 0 for the unit level, even if its starting level was higher (or lower).
Depending on the unit, this would cause the new InitAbility code to lock up. Elite_Warbiker is an example - its starting level is 3, so if the code thought it was level 1 it would try to load up the ability array for LEVEL2 and not find it. ability1 would then be set to 0, which would cause these calls to Rand to be negative values (or presumably internally converted to UINT_MAX by the API to keep it positive):
Code: Select all
ability2 = ability1; <---ability1 is 0
...
ability1 = Rand(0, ability2 -1); <--and ability2 -1 is now negative
ability2 = Rand(0, ability2 -2);
You can also force this problem by passing in a unit who is not a daemon and not max level but also has level gain abilities (gretchin).
Anyway, to work around this I made two changes, I reversed the call order in StartTurn of SetupStartAbilities(me, 0); and DoInitAbility(me); I'm pretty sure the base code should be calling in this order anyway as the unit needs to first be set to its current level (not the level that's read in from squads.csv).
Code: Select all
if (GetTurn() == 0 || GetTurn() == 1)
{
SetAttrib(me, "SquadName", GetTileData(GetUnitX(me), GetUnitY(me), 3));
SetupStartAbilities(me, 0);
}
else
{
SetupStartAbilities(me, 1);
}
if (GetSkirmishState() != 1)
{
if (GetTurn() == 0 || GetTurn() == 1)
{
if (GetUnitStatus(me) != 2)
{
DoInitAbility(me);
}
}
}
(I also needed to make a change for my mods to allow for both sides to setup their abilities)
The second was to place a guard to check for ability1 >= 2.
To be clear, this is an existing bug, and in the original InitAbility code, it does not lock up but ultimately instead just silently gives the unit a garbage ability of zero. If the unit is non-elite, it will just give the unit an ability for level 1, which for most standard units, would be simply wrong but it would be a valid ability. If this happened I'm sure it would be entirely unnoticed.
A_Wal_ wrote: ↑Thu Aug 29, 2024 10:57 pmI was sure I included this in the patch so it should have always been in the campaign mod...
It was. It looks like I merged the fix because I did not take the entire StartTurn from your campaign...
"I did a lot of tidying up too, which is good because it reminded me about a patch fix for campaigns when you deploy and get the first turn which you definitely don't want in your mod. Make sure you replace the two 'if ((((IsMultiplayer() == 1) || (GetSkirmishState() == 1)) && (GetTurn() == 1)) || (GetTurn() == 0))'s with 'if ((GetTurn() == 0)) || (GetTurn() == 1))' if you don't copy over the whole file."
(from the Terrors of the Warp thread)
A_Wal_ wrote: ↑Sat Aug 31, 2024 8:09 am
I was planning to add something for the demons but it wasn't nurglings. I was going to go in the other direction and add greater demons using the spawn and horror models and classing them as artillery. If I was going to add nurglings for nurgle I'd want something else for the other three, because of something else I've got coming it would be nice to keep the units even for each god. Maybe a spawn for tzeentch or the two horror types separated, use the skulltaker model for exalted bloodletters and I'm not sure for slaanesh. Maybe use one seeker model reskinned and call it a herald or something.
Sounds good, look forward to what you have planned!