Sandbox Skirmish - Player vs. AI campaign
- 
				toadfather
- Senior Corporal - Ju 87G 
- Posts: 78
- Joined: Tue Jul 23, 2024 2:35 pm
Sandbox Skirmish - Player vs. AI campaign
Another mod to share, this time it’s a sandbox AI campaign.  I noticed somebody on Steam had recently made a comment about wishing the game had something like this, so I gave it a go.  
With this campaign you choose the points, your units and the AI units to fight in a skirmish battle.
You both will have the same number of points regardless of difficulty, and you can balance the armies however you like.
Links below, or you can find the latest in gitlab under toadfather/sanctus_reach.
--------------------------------------------------
Sandbox AI: sandbox_ai_release_1.1
Main project: project home page
--------------------------------------------------------------
*Edit: Updated to version 1.1
			
			
									
						
										
						With this campaign you choose the points, your units and the AI units to fight in a skirmish battle.
You both will have the same number of points regardless of difficulty, and you can balance the armies however you like.
Links below, or you can find the latest in gitlab under toadfather/sanctus_reach.
--------------------------------------------------
Sandbox AI: sandbox_ai_release_1.1
Main project: project home page
--------------------------------------------------------------
*Edit: Updated to version 1.1
- 
				toadfather
- Senior Corporal - Ju 87G 
- Posts: 78
- Joined: Tue Jul 23, 2024 2:35 pm
Re: Sandbox Skirmish - Player vs. AI campaign
Updated to version 1.2.
Changes:
Sandbox AI: sandbox_ai_release_1.2.zip
			
			
									
						
										
						Changes:
- support for linked battles where units level up between skirmishes:
 --maintains cumulative score across skirmishes to determine the ultimate winner
- total annihilation mode - fight to the bitter end!
- optionally assign points to victory objectives
- support for optionally enforcing balanced armies:
 -- minimum base army (grunts)
 -- maximum giants (towering units) allowed in an army
Sandbox AI: sandbox_ai_release_1.2.zip
- 
				toadfather
- Senior Corporal - Ju 87G 
- Posts: 78
- Joined: Tue Jul 23, 2024 2:35 pm
Re: Sandbox Skirmish - Player vs. AI campaign
Updated to version 1.3
Now includes upgraded Daemons and Knights from Terrors of the Warp (used by permission and credit to A-Wal)!
Sandbox AI: sandbox_ai_release_1.3
Full release notes are provided in the download file.
			
			
									
						
										
						Now includes upgraded Daemons and Knights from Terrors of the Warp (used by permission and credit to A-Wal)!
Sandbox AI: sandbox_ai_release_1.3
Full release notes are provided in the download file.
Re: Sandbox Skirmish - Player vs. AI campaign
Yea those previous ability files edits were a waste of time now I've fixed the leveling up function. Oh well.toadfather wrote: ↑Tue Aug 27, 2024 8:07 pmLol - well my friend you are keeping me hopping with these bug fixes. I saw your post(s) on steam as well, will reply when I get a chance. I'm also still tidying up a few sandbox army interface changes before I put out another patch.
Very nice force selection additions by the way.
"Fix initial startturn morale boost for Machine Spirit Ritual and Hull Reinforement. (A-Wal)" Huh? Were they not working before on the first turn? I thought I fixed that for the patch. Maybe I forgot to transfer that over to the mod and accidently caught it with the StartTurn edits. Hull reinforcement is HP. There's also a typo in reinforcement, missing c
The old spawn can be set to side 99 in UNITIDS, 412 413 553 554. Those models are now the nurgle and slaanesh spawn. Khorne uses the generic spawn model but with different skins.
I noticed I altered the upgraded astra knights speed in the squads file. I think when I was testing on a knights map to see how fast the chaos knights should move and I forgot to put the values back. Just change the 650s to 700s to make the the same as the standard knight.
There's a mistake in the daemon abilities file for upgraded tzeentch knights. Start1 should be Start2, Start2 should be Start3, etc, oops.
The knight's fear aura counts the furthest knight, not the closest. I had it backwards in my head because I'm an idiot. Counting the furthest is a lot easier because you can check if either axis is out by 6, then 5, 4 and so on. To get the closest you need to check both in relation to each other. It didn't matter for the campaign because you can only ever fight one. I thought I'd done a version that works but it doesn't if you're on the same x or y axis as the knight. I'll fix it tomorrow.
Re: Sandbox Skirmish - Player vs. AI campaign
Ignore me, it counts the axis of each knight individually. I was very tired last night. It does need a slight fix though. This needs to replace the second set of checks, a few lines after 'morale = 0;'. It just adds a morale variable check so now it actually does only count the closest knight.A_Wal_ wrote: ↑Thu Aug 29, 2024 10:57 pmThe knight's fear aura counts the furthest knight, not the closest. I had it backwards in my head because I'm an idiot. Counting the furthest is a lot easier because you can check if either axis is out by 6, then 5, 4 and so on. To get the closest you need to check both in relation to each other. It didn't matter for the campaign because you can only ever fight one. I thought I'd done a version that works but it doesn't if you're on the same x or y axis as the knight. I'll fix it tomorrow.
Code: Select all
	if (((i == GetUnitX(me)-6) || (i == GetUnitX(me)+6) || (j == GetUnitY(me)-6) || (j == GetUnitY(me)+6)) && (morale < 15))
	{
		morale = 15;
	}
	else if (((i == GetUnitX(me)-5) || (i == GetUnitX(me)+5) || (j == GetUnitY(me)-5) || (j == GetUnitY(me)+5)) && (morale < 30))
	{
		morale = 30;
	}
	else if (((i == GetUnitX(me)-4) || (i == GetUnitX(me)+4) || (j == GetUnitY(me)-4) || (j == GetUnitY(me)+4)) && (morale < 45))
	{
		morale = 45;
	}
	else if (((i == GetUnitX(me)-3) || (i == GetUnitX(me)+3) || (j == GetUnitY(me)-3) || (j == GetUnitY(me)+3)) && (morale < 60))
	{
		morale = 60;
	}
	else if (((i == GetUnitX(me)-2) || (i == GetUnitX(me)+2) || (j == GetUnitY(me)-2) || (j == GetUnitY(me)+2)) && (morale < 75))
	{
		morale = 75;
	}
	else
	{
		morale = 90;
	}Just a few suggestions...
The 'Giant' text still shows below units if giants are unlimited, maybe do the same thing you did with core units.
I'm not sure why you didn't include landraiders and shadowswords or did you want a unique classification separate from the super-heavies?
I really like that you can filter the force selection list but it's good to be able to see everything as well. Maybe you could start with the boxes (other than purchased units) ticked and filter it by unticking them. Maybe even add categories like artillery, fast attack, transport, elite etc. I'm not sure how easy that would be to do now you have the system in place.
Just my thoughts. Feel free to ignore me, it's your mod.
- 
				toadfather
- Senior Corporal - Ju 87G 
- Posts: 78
- Joined: Tue Jul 23, 2024 2:35 pm
Re: Sandbox Skirmish - Player vs. AI campaign
Well, I made use of them anyway while testing and they are still in the latest patch so they are being used. Now I'm in the process of using your latest InitAbility code in conjunction with the new abilities files to do the next run of testing. I've been working on allowing Side 1 to level up units so the hotseat match up is fair. Took me a bit to untangle and refactor but it now seems to be working. I have some actual games coming up soon so it will get more testing then, but for now it's good. I want to then do something similar for this mod to allow the AI to get random abilities when they level up as well. In actual gameplay it's not really a huge deal as many of the units are wiped out during each skirmish, but it could be fun to potentially build up a nemesis on the enemy side.
Yeah, I got tired of hunting through the list, especially when trying to compare standard to upgraded units. It's still not where I want it to be but I had to put it down and move on for now. Your feedback is appreciated though.
I think this was a one line fix, I'll check. I usually try to filter out trivial changes from release notes as they just create noise. I'll likely remove this bullet item.A_Wal_ wrote: ↑Thu Aug 29, 2024 10:57 pm "Fix initial startturn morale boost for Machine Spirit Ritual and Hull Reinforement. (A-Wal)" Huh? Were they not working before on the first turn? I thought I fixed that for the patch. Maybe I forgot to transfer that over to the mod and accidently caught it with the StartTurn edits. Hull reinforcement is HP. There's also a typo in reinforcement, missing c
Thanks, I'll check it out.
Ok - will check.A_Wal_ wrote: ↑Thu Aug 29, 2024 10:57 pm I noticed I altered the upgraded astra knights speed in the squads file. I think when I was testing on a knights map to see how fast the chaos knights should move and I forgot to put the values back. Just change the 650s to 700s to make the the same as the standard knight.
Ok, it's on the list to merge in.
And this.
That was on purpose. I didn't want to add too many filters and the (Giant) keyword was unobtrusive enough on the few units, and slightly beneficial.
Right. I actually started with super heavies (the code is still in there in fact), but ultimately decided to focus on the knights as they are the real hitters. This was motivated over time while playing with my buddy in hotseat and wanting to come up with a rule to keep the games interesting, rather than being forced into an arms race each skirmish that devolved into just butting heads with knights.
Side note - was meaning to ask - did you have interest or plans to add in Nurglings? They might be a cool addition, and since you were in daemon territory already thought I would see what your plans were.
Re: Sandbox Skirmish - Player vs. AI campaign
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.toadfather wrote: ↑Fri Aug 30, 2024 10:25 pmWell, I made use of them anyway while testing and they are still in the latest patch so they are being used. Now I'm in the process of using your latest InitAbility code in conjunction with the new abilities files to do the next run of testing. I've been working on allowing Side 1 to level up units so the hotseat match up is fair. Took me a bit to untangle and refactor but it now seems to be working. I have some actual games coming up soon so it will get more testing then, but for now it's good. I want to then do something similar for this mod to allow the AI to get random abilities when they level up as well. In actual gameplay it's not really a huge deal as many of the units are wiped out during each skirmish, but it could be fun to potentially build up a nemesis on the enemy side.
I was sure I included this in the patch so it should have always been in the campaign mod, I'll check. Maybe it wasn't in the mod to start with because the knights can't get the astra abilities when they level up so it wasn't needed.
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.
Re: Sandbox Skirmish - Player vs. AI campaign
Brain fart, the morale checks need to be separate or they mess up the else checks so the first set should be this.
And the second set should be this.I should have seen that straight away.
			
			
									
						
										
						Code: Select all
	if ((i == GetUnitX(me)-6) || (i == GetUnitX(me)+6) || (j == GetUnitY(me)-6) || (j == GetUnitY(me)+6))
	{
		if (morale > 85)
		{
			morale = 85;
		}
	}
	else if ((i == GetUnitX(me)-5) || (i == GetUnitX(me)+5) || (j == GetUnitY(me)-5) || (j == GetUnitY(me)+5))
	{
		if (morale > 70)
		{
			morale = 70;
		}
	}
	else if ((i == GetUnitX(me)-4) || (i == GetUnitX(me)+4) || (j == GetUnitY(me)-4) || (j == GetUnitY(me)+4))
	{
		if (morale > 55)
		{
			morale = 55;
		}
	}
	else if ((i == GetUnitX(me)-3) || (i == GetUnitX(me)+3) || (j == GetUnitY(me)-3) || (j == GetUnitY(me)+3))
	{
		if (morale > 40)
		{
			morale = 40;
		}
	}
	else if ((i == GetUnitX(me)-2) || (i == GetUnitX(me)+2) || (j == GetUnitY(me)-2) || (j == GetUnitY(me)+2))
	{
		if (morale > 25)
		{
			morale = 25;
		}
	}
	else if (morale > 10)
	{
		morale = 10;
	}Code: Select all
	if ((i == GetUnitX(me)-6) || (i == GetUnitX(me)+6) || (j == GetUnitY(me)-6) || (j == GetUnitY(me)+6))
	{
		if (morale < 15)
		{
			morale = 15;
		}
	}
	else if ((i == GetUnitX(me)-5) || (i == GetUnitX(me)+5) || (j == GetUnitY(me)-5) || (j == GetUnitY(me)+5))
	{
		if (morale < 30)
		{
			morale = 30;
		}
	}
	else if ((i == GetUnitX(me)-4) || (i == GetUnitX(me)+4) || (j == GetUnitY(me)-4) || (j == GetUnitY(me)+4))
	{
		if (morale < 45)
		{
			morale = 45;
		}
	}
	else if ((i == GetUnitX(me)-3) || (i == GetUnitX(me)+3) || (j == GetUnitY(me)-3) || (j == GetUnitY(me)+3))
	{
		if (morale < 60)
		{
			morale = 60;
		}
	}
	else if ((i == GetUnitX(me)-2) || (i == GetUnitX(me)+2) || (j == GetUnitY(me)-2) || (j == GetUnitY(me)+2))
	{
		if (morale < 75)
		{
			morale = 75;
		}
	}
	else
	{
		morale = 90;
	}- 
				toadfather
- Senior Corporal - Ju 87G 
- Posts: 78
- Joined: Tue Jul 23, 2024 2:35 pm
Re: Sandbox Skirmish - Player vs. AI campaign
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).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.
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);
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);
      }
    }
  }
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.
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)
Sounds good, look forward to what you have planned!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.
					Last edited by toadfather on Sun Sep 01, 2024 11:26 am, edited 1 time in total.
									
			
						
										
						- 
				toadfather
- Senior Corporal - Ju 87G 
- Posts: 78
- Joined: Tue Jul 23, 2024 2:35 pm
Re: Sandbox Skirmish - Player vs. AI campaign
No problem - will mergeA_Wal_ wrote: ↑Sat Aug 31, 2024 9:12 pm Brain fart, the morale checks need to be separate or they mess up the else checks so the first set should be this.And the second set should be this.Code: Select all
if ((i == GetUnitX(me)-6) || (i == GetUnitX(me)+6) || (j == GetUnitY(me)-6) || (j == GetUnitY(me)+6)) { if (morale > 85) { morale = 85; } } else if ((i == GetUnitX(me)-5) || (i == GetUnitX(me)+5) || (j == GetUnitY(me)-5) || (j == GetUnitY(me)+5)) { if (morale > 70) { morale = 70; } } else if ((i == GetUnitX(me)-4) || (i == GetUnitX(me)+4) || (j == GetUnitY(me)-4) || (j == GetUnitY(me)+4)) { if (morale > 55) { morale = 55; } } else if ((i == GetUnitX(me)-3) || (i == GetUnitX(me)+3) || (j == GetUnitY(me)-3) || (j == GetUnitY(me)+3)) { if (morale > 40) { morale = 40; } } else if ((i == GetUnitX(me)-2) || (i == GetUnitX(me)+2) || (j == GetUnitY(me)-2) || (j == GetUnitY(me)+2)) { if (morale > 25) { morale = 25; } } else if (morale > 10) { morale = 10; }I should have seen that straight away.Code: Select all
if ((i == GetUnitX(me)-6) || (i == GetUnitX(me)+6) || (j == GetUnitY(me)-6) || (j == GetUnitY(me)+6)) { if (morale < 15) { morale = 15; } } else if ((i == GetUnitX(me)-5) || (i == GetUnitX(me)+5) || (j == GetUnitY(me)-5) || (j == GetUnitY(me)+5)) { if (morale < 30) { morale = 30; } } else if ((i == GetUnitX(me)-4) || (i == GetUnitX(me)+4) || (j == GetUnitY(me)-4) || (j == GetUnitY(me)+4)) { if (morale < 45) { morale = 45; } } else if ((i == GetUnitX(me)-3) || (i == GetUnitX(me)+3) || (j == GetUnitY(me)-3) || (j == GetUnitY(me)+3)) { if (morale < 60) { morale = 60; } } else if ((i == GetUnitX(me)-2) || (i == GetUnitX(me)+2) || (j == GetUnitY(me)-2) || (j == GetUnitY(me)+2)) { if (morale < 75) { morale = 75; } } else { morale = 90; }
Re: Sandbox Skirmish - Player vs. AI campaign
Were you thinking of adding nurglings then? I think using edited models would be tricky, I know nothing about models. There's an OUTPUT.REZ file in the battle folder that I assume has them in. Did you mean shrunk down plaguebearers?
Edit:
			
			
									
						
										
						That's great info, it would have affected my next mod. I think I ran into that problem with unloading units and fixed it for the patch. It might have been specifically when a transport is destroyed, can't remember and it might not be the same bug.toadfather wrote: ↑Sun Sep 01, 2024 11:21 amWhich 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).
Ability2 at that point is the number of abilities on the array in the text file, so for 'LEVEL2 12 32 41 42 44 45' it would have a value of 6.toadfather wrote: ↑Sun Sep 01, 2024 11:21 amDepending 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);
Oh yea. That was a few days ago and I completely forgot, sorry. ((((IsMultiplayer() == 1) || (GetSkirmishState() == 1)) && (GetTurn() == 1)) || (GetTurn() == 0)) is in the patch because turn 1 is needed for player 2 upgraded units with those abilities in multiplayer and I think in some campaign missions the player gets turn 0 and turn 1 when you deploy and get the first turn.toadfather wrote: ↑Sun Sep 01, 2024 11:21 amIt 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)
Edit:
You already know that, you said it's checking the array and not finding anything because it's checking the wrong array because it's getting the wrong current level of the unit but only for upgraded units, is that right?
- 
				toadfather
- Senior Corporal - Ju 87G 
- Posts: 78
- Joined: Tue Jul 23, 2024 2:35 pm
Re: Sandbox Skirmish - Player vs. AI campaign
Exactly - lol. No new models, though I wish we could add some! I think I remember reading somewhere it was prohibited by GW license. But man, if we could the possibilities would be endless. I think we can freely add new terrain models though, which also would be fun to do.
Not only upgraded units, it could happen to any, but it won't cause a critical issue for most because non-upgraded units have data for all levels. In that case the unit will get abilities from the wrong level. Gretchin are a good unit to try and should trigger this behavior.
*EDIT: I dug into the details on this further; it's not the negative value passed into Rand that's causing an issue (Rand will return 0 in this case), it's just the fact that ability1 == 0; The code below then goes into an endless loop because i is chasing ability1 as it increases.
Code: Select all
        for (i = 0; i <= ability1; i++)
	{
		if (((HasAmmo(me) == 1) && (IsAmmo(me, GetArray(i, 0)) == 1)) || (a == GetArray(i, 0)) || (b == GetArray(i, 0)))
		{
			ability1 += 1;
		}
	}
That's cool - hope it helps. I've seen this with other API calls too, GetMapStyles for example. I'm thinking there might be a race condition in the engine where not all data files yet are loaded but the scripts begin to run, giving incorrect or empty results from certain API calls. Something to watch out for anyway.A_Wal_ wrote: ↑Sun Sep 01, 2024 12:22 pmThat's great info, it would have affected my next mod. I think I ran into that problem with unloading units and fixed it for the patch. It might have been specifically when a transport is destroyed, can't remember and it might not be the same bug.toadfather wrote: ↑Sun Sep 01, 2024 11:21 amWhich 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).
Re: Sandbox Skirmish - Player vs. AI campaign
I see, well it looks like you've fixed the problem so Ill just copy your work. Here have a reward https://www.mediafire.com/file/kauv2fjt ... s.zip/file
This adds a fear status effect to units in range and makes a few alterations to Helpers.
The upgraded errant and paladin need their levels changed to 3, 1 in the squads file if you haven't already done it. Levelling up to level 3 doesn't work in 1.3, presumably it will actually fail all 1,048,576 tries. That could take a while, it would be days on my laptop. It will still be quicker than the sodding toxic cloud delay! If you're using the new ability files all three upgraded knights should be level 3.
I changed the valkyrie full throttle sound to the skyclaw's.
			
			
									
						
										
						This adds a fear status effect to units in range and makes a few alterations to Helpers.
The upgraded errant and paladin need their levels changed to 3, 1 in the squads file if you haven't already done it. Levelling up to level 3 doesn't work in 1.3, presumably it will actually fail all 1,048,576 tries. That could take a while, it would be days on my laptop. It will still be quicker than the sodding toxic cloud delay! If you're using the new ability files all three upgraded knights should be level 3.
I changed the valkyrie full throttle sound to the skyclaw's.
Code: Select all
	if ((IsUnitType(me, "Valkyrie") == 1) || (IsUnitType(me, "Elite_Valkyrie") == 1))
	{
		PlaySFX((GetUnitX(me)*100)+50, (GetUnitY(me)*100)+50, FXRand(259,261));
	}
	else
	{
		PlaySFX((GetUnitX(me)*100)+50, (GetUnitY(me)*100)+50, FXRand(386,388));
	}- 
				toadfather
- Senior Corporal - Ju 87G 
- Posts: 78
- Joined: Tue Jul 23, 2024 2:35 pm
Re: Sandbox Skirmish - Player vs. AI campaign
When I was hunting down leveling bugs I changed things up a bit as I needed to isolate and test so I took your original code and ran with it - it's a bit different now but seems to do the trick. You may or may not want it, just a heads up.
Thanks, merged in.
Merged.
Ok - I had made the level change a while back to the errant and paladin so they're fine. With the new ability files I lowered the upgraded warden down to 3.
However, in the AbilityHelpers file, this code causes an endless loop with the upgraded paladin as it always returns true:
Code: Select all
FUNCTION IsAmmo(me, index)
{
  if ((IsUnitType(me, "Elite_KnightPaladin") == 1) || (IsUnitType(me, "Upgraded_KnightPaladin") == 1))
  {
    return 1;
  }
  ...
I recruited some volunteer guardsmen to check out the tzeentch knight aura of fear behavior, and reports from the field are the fear calculations are done without considering their base morale, so if there is enough of them around each other they can raise their own morale up past their base morale, which negates the fear effect somewhat.
In an actual game this will likely have little benefit as the battlefield is too dynamic and negative morale is already easy to get as they take damage or nearby allied units are destroyed, but they suggested I bring it up.
The first screenshot is the current code, the second is if base morale is considered in the calculation:
Re: Sandbox Skirmish - Player vs. AI campaign
Cheers, I'll go back through our conversations to make sure I haven't missed anything and compare our code when you release the next update.toadfather wrote: ↑Wed Sep 04, 2024 8:24 amWhen I was hunting down leveling bugs I changed things up a bit as I needed to isolate and test so I took your original code and ran with it - it's a bit different now but seems to do the trick. You may or may not want it, just a heads up.
Right. I don't think I even needed to put that there, I did thinking it was needed in CombatTools but I think IsAmmo ans HasAmmo are only used in AbilityHelpers.toadfather wrote: ↑Wed Sep 04, 2024 8:24 amHowever, in the AbilityHelpers file, this code causes an endless loop with the upgraded paladin as it always returns true:Code: Select all
FUNCTION IsAmmo(me, index) { if ((IsUnitType(me, "Elite_KnightPaladin") == 1) || (IsUnitType(me, "Upgraded_KnightPaladin") == 1)) { return 1; } ...
Because I counted before merging all the abilities from three level ups into one and forgot to recount. Good spot.toadfather wrote: ↑Wed Sep 04, 2024 8:24 amAlso, the new code reads in max 27 abilities, the Elite_Nobz_Slugga has 28 abilities.
Oh is the if morale > baseMorale then morale = baseMorale after the knight's stuff? ...Yep it is. I think it's as simple as moving it to before it, I'll check tomorrow. Yea the effect should definitely not got eaten away by going above base morale. Cheers for the info.toadfather wrote: ↑Wed Sep 04, 2024 8:24 amI recruited some volunteer guardsmen to check out the tzeentch knight aura of fear behavior, and reports from the field are the fear calculations are done without considering their base morale, so if there is enough of them around each other they can raise their own morale up past their base morale, which negates the fear effect somewhat.
In an actual game this will likely have little benefit as the battlefield is too dynamic and negative morale is already easy to get as they take damage or nearby allied units are destroyed, but they suggested I bring it up.
- 
				toadfather
- Senior Corporal - Ju 87G 
- Posts: 78
- Joined: Tue Jul 23, 2024 2:35 pm
Re: Sandbox Skirmish - Player vs. AI campaign
I ended up leaving it alone for now. After play testing in an actual game it seemed like his aura was pretty harsh, even with the small boost from surrounding troops. Although I did only use him once in an actual matchup against another player and he ultimately was taken out by another knight, but in the meanwhile he terrorized the battlefield. I'm going to give him some more play now that I have 1.4 buttoned up.A_Wal_ wrote: ↑Wed Sep 04, 2024 10:55 pmOh is the if morale > baseMorale then morale = baseMorale after the knight's stuff? ...Yep it is. I think it's as simple as moving it to before it, I'll check tomorrow. Yea the effect should definitely not got eaten away by going above base morale. Cheers for the info.toadfather wrote: ↑Wed Sep 04, 2024 8:24 amI recruited some volunteer guardsmen to check out the tzeentch knight aura of fear behavior, and reports from the field are the fear calculations are done without considering their base morale, so if there is enough of them around each other they can raise their own morale up past their base morale, which negates the fear effect somewhat.
In an actual game this will likely have little benefit as the battlefield is too dynamic and negative morale is already easy to get as they take damage or nearby allied units are destroyed, but they suggested I bring it up.
Liking all the new daemons btw.
Oh, that reminds me - was meaning to clarify, I wasn't really planning on adding nurglings, at least not any time soon, I have too many other things I need to do first. They're all yours if you have interest.
- 
				toadfather
- Senior Corporal - Ju 87G 
- Posts: 78
- Joined: Tue Jul 23, 2024 2:35 pm
Re: Sandbox Skirmish - Player vs. AI campaign
Updated to version 1.4
Full release notes are provided in the download files.
			
			
									
						
										
						- For both sides, units will keep XP, levels and new abilities gained from each battle. By selecting the "Legacy XP" option, you can also choose to keep XP from units that have been destroyed during the fight, allowing both armies to continue to evolve regardless of which side wins.
- Optional - Units can gain XP by participating and doing damage to the enemy rather than only a single unit gaining XP for getting in the final blow.
Full release notes are provided in the download files.
Re: Sandbox Skirmish - Player vs. AI campaign
The icon we're using for the slaanesh spawn will of the warp is also used for deamon rally, I'm changing mine to AbilitySlot_Domination which at the moment is slaanesh knight's so that's changing to AbilitySlot_EternalWarrior which is unused by any unit. I think it's actually the full version of the seneschal symbol so it's appropriate for a knight with three actions. I'm changing the fear aura one to AbilitySlot_MachineSpirit because that's not used anywhere else either.
 
 
			
			
									
						
										
						Somebody playtested the new units for in the campaign but not in multiplayer so I haven't really tested balance. One way to tone it down could be to apply the effect at the start of the enemy's turn giving units their own turn before it kicks in.toadfather wrote: ↑Tue Sep 10, 2024 9:40 pmI ended up leaving it alone for now. After play testing in an actual game it seemed like his aura was pretty harsh, even with the small boost from surrounding troops. Although I did only use him once in an actual matchup against another player and he ultimately was taken out by another knight, but in the meanwhile he terrorized the battlefield.
 
 Yea I'll be finishing patching the old mod before adding any new units. Maybe I'll add nurglings, separate the horrors and add a slaanesh herald, exalted bloodletters and greater demons after. I'll just take the blue horror's shield away, screamers don't get an energy shield so horrors can be the cut off point. I think that might be a mistake, I think all tzeentch demons get the ephemeral shield in the lore.toadfather wrote: ↑Tue Sep 10, 2024 9:40 pmOh, that reminds me - was meaning to clarify, I wasn't really planning on adding nurglings, at least not any time soon, I have too many other things I need to do first. They're all yours if you have interest.
That's nice. It always bothered me that you have to worry about which units to get the kill with.toadfather wrote: ↑Tue Sep 10, 2024 9:41 pm
- Optional - Units can gain XP by participating and doing damage to the enemy rather than only a single unit gaining XP for getting in the final blow.
- 
				toadfather
- Senior Corporal - Ju 87G 
- Posts: 78
- Joined: Tue Jul 23, 2024 2:35 pm
Re: Sandbox Skirmish - Player vs. AI campaign
Ok, I'll take a look and might do the same to keep them consistent. I did start creating new icons for some of the other abilities that were lacking their own. I might redo some of them again, especially Hit&Run as I have a different idea for that one. Ultimately though these are low priority given the finite amount of time I have for modding.A_Wal_ wrote: ↑Sat Sep 14, 2024 4:46 pm The icon we're using for the slaanesh spawn will of the warp is also used for deamon rally, I'm changing mine to AbilitySlot_Domination which at the moment is slaanesh knight's so that's changing to AbilitySlot_EternalWarrior which is unused by any unit. I think it's actually the full version of the seneschal symbol so it's appropriate for a knight with three actions. I'm changing the fear aura one to AbilitySlot_MachineSpirit because that's not used anywhere else either.
That's an idea. I guess I have a keen interest in this guy because I want to use him for my upcoming Night Lords mod. For the Night Lords, I made their "aura of terror" cause a 25 morale hit, then each round forward just cap the effected unit's base morale at Base - 25 so it won't eventually drain to zero. So it can potentially regain some morale, but it won't ever fully recover while under the influence of the aura.A_Wal_ wrote: ↑Sat Sep 14, 2024 4:46 pmSomebody playtested the new units for in the campaign but not in multiplayer so I haven't really tested balance. One way to tone it down could be to apply the effect at the start of the enemy's turn giving units their own turn before it kicks in.toadfather wrote: ↑Tue Sep 10, 2024 9:40 pmI ended up leaving it alone for now. After play testing in an actual game it seemed like his aura was pretty harsh, even with the small boost from surrounding troops. Although I did only use him once in an actual matchup against another player and he ultimately was taken out by another knight, but in the meanwhile he terrorized the battlefield.
I agree, and I've noticed others mention it several times in different threads. With that in mind I now split it out and made a dedicated mod that can be used by everyone globally rather than only in my other two mods. I'll create a new thread and post a link in a moment.A_Wal_ wrote: ↑Sat Sep 14, 2024 4:46 pmThat's nice. It always bothered me that you have to worry about which units to get the kill with.toadfather wrote: ↑Tue Sep 10, 2024 9:41 pm
- Optional - Units can gain XP by participating and doing damage to the enemy rather than only a single unit gaining XP for getting in the final blow.
Re: Sandbox Skirmish - Player vs. AI campaign
Some of the spawn have the wrong points cost. I must have got distracted half way through then thought it was done.  
 
It should be...
Spawn 120 Upg 150 (120%4)+120 = 150
Nurgle 140 Upg 175 (140%4)+140 = 175
Khorne 160 Upg 200 (160%4)+160 = 200
Slaanesh 180 Upg 225 (180%4)+180 = 225
			
			
									
						
										
						 
 It should be...
Spawn 120 Upg 150 (120%4)+120 = 150
Nurgle 140 Upg 175 (140%4)+140 = 175
Khorne 160 Upg 200 (160%4)+160 = 200
Slaanesh 180 Upg 225 (180%4)+180 = 225
 
					