Change AISizeType in Lua

In this forum you will find and post information regarding the modding of Star Wars Battlefront 2. DO NOT POST MOD IDEAS/REQUESTS.

Moderator: Moderators

Post Reply
User avatar
Benoz
Corporal
Corporal
Posts: 140
Joined: Tue May 28, 2013 12:34 pm
Projects :: Clone Wars Era Mod Version 2
Games I'm Playing :: OldFront - EAFront
xbox live or psn: No gamertag set
Location: Germany

Change AISizeType in Lua

Post by Benoz »

Hello Community,

I have created different pathing for different AISizeTypes on my map and I want to spawn in units and determine their AISizeType and thus their pathing via LUA.

Now as ZoomV states in this post, AISizeType is a [InstanceProperty] and should be able to being modified in the LUA script.

My function basically looks like this:

Code: Select all

OnTimerElapse(
		function(timer)
		if enemyCount == 0 then
			enemyIndex = GetTeamMember(teamEnemy, enemyCount)
			SpawnCharacter(enemyIndex, GetPathPoint("Enemy1_spawn", 0))
			enemyUnit = GetCharacterUnit(enemyIndex)
			SetProperty(enemyUnit, "AISizeType", "Soldier")
			
			SetTimerValue(spawnEnemies, 2)
			StartTimer(spawnEnemies)
		end
		if enemyCount == 1 then
			enemyIndex = GetTeamMember(teamEnemy, enemyCount)
			SpawnCharacter(enemyIndex, GetPathPoint("Enemy2_spawn", 0))
			enemyUnit = GetCharacterUnit(enemyIndex)
			SetProperty(enemyUnit, "AISizeType", "Hover")

		end
		enemyCount = enemyCount + 1
		print("enemyCount", enemyCount)	
		end,
		spawnEnemies
	)
Spawning in the enemies works just fine. But changing the AISizeType does not work. Am I doing something wrong, or does that mean that this value cannot be changed in the LUA?

It would be an easy fix to spawn in different unit types that already have their AISizeType predefined in the ODF file. But in my case I want only one unit type, because the unit is also being used in other scripts.

Thanks for the help!

EDIT: I tried manipulating the MaxSpeed value in the function as a test, and it didn't work either. Am I addressing the units wrong? I saw in the Ambush script they are also using the value of GetCharacterUnit.
Sporadia
Corporal
Corporal
Posts: 151
Joined: Thu Jan 24, 2019 11:02 pm
Projects :: No Mod project currently
Games I'm Playing :: None
xbox live or psn: No gamertag set

Re: Change AISizeType in Lua

Post by Sporadia »

It looks like the functions are all using the correct arguments. ZoomV states in that post that they hadn't tested their idea, so it's anybody's guess whether "AISizeType" can be changed for a unit after it's been spawned. You could try using SetClassProperty immediately before and after you spawn the unit. It won't affect the units which are already spawned, but it will affect the other units which happen to spawn at the exact same time. And for SetClassProperty you would need to get the name of the unit's class as a string from somewhere, which might be difficult since GetCharacterClass returns a number. So you'd need to make a table or a function with all the unit names, where you put in the team number and class number (which is team specific) to get the class name. But if you want to achieve what ZoomV suggested about changing AISizeType on living characters when they move to different regions, I don't know if it's possible.

I would also add a warning about any OnTimerElapse which doesn't contain DestroyTimer. In one of the first lua heavy things I modded, I made a user script which was crashing several missions into the instant action playlist. And because it was several missions in, I didn't know how to get an error message into the debug log. (I was testing it in the main game to get the playlist). The crashing stopped when I destroyed my timers. I can't promise that it's the only change I made, or that it was the real cause of the crash, but I've always suspected that it was. It should be possible to reproduce this crash if it really is caused by undestroyed timers, if anyone does want to test it fully.

Edit: Test print("Value of enemyUnit:", enemyUnit) to check that it's userdata, not nil. Don't truncate enemyUnit because it will crash. (ie don't try ..enemyUnit)

And test the SetProperty() with something that definitely works like SetProperty(enemyUnit, "MaxHealth", "1e+37") should apply invincibility.

Also I've forgotten what GetEntityClass(enemyUnit) returns. That might return a string which would be great for SetClassProperty.
Last edited by Sporadia on Wed Jul 06, 2022 5:49 pm, edited 1 time in total.
User avatar
Benoz
Corporal
Corporal
Posts: 140
Joined: Tue May 28, 2013 12:34 pm
Projects :: Clone Wars Era Mod Version 2
Games I'm Playing :: OldFront - EAFront
xbox live or psn: No gamertag set
Location: Germany

Re: Change AISizeType in Lua

Post by Benoz »

When I change the script to SetClassProperty, both the AISizeType and MaxSpeed changes work. But then those changes affect all units of the same class. I stumbled across the following:
DarthD.U.C.K. wrote:...i discovered that you could put any ODF property under the [InstanceProperties] tag and they would become editable in ZE...
which should make it possible to modify AISizeType with SetProperty. Although when I set it under the [InstanceProperties] tag, the change doesn't apply. It seems as if this property is a [ClassProperties] and can only be changed with the SetClassProperty line.

Sporadia wrote:You could try using SetClassProperty immediately before and after you spawn the unit. It won't affect the units which are already spawned, but it will affect the other units which happen to spawn at the exact same time.
If this is true, that would fix my problem as I can delay the spawns for several seconds and then change the SetClassProperty for the newly spawned unit. But when I test this, the changes of SetClassProperty affect all units. This is the code:

Code: Select all

OnTimerElapse(
		function(timer)
		if enemyCount == 0 then
			enemyIndex = GetTeamMember(teamEnemy, enemyCount)
			SpawnCharacter(enemyIndex, GetPathPoint("teamEnemy2_spawn", 0))
			enemyUnit = GetCharacterUnit(enemyIndex)
			
			SetTimerValue(spawnEnemies, 5)
			StartTimer(spawnEnemies)
		end
		if enemyCount == 1 then
			enemyIndex = GetTeamMember(teamEnemy, enemyCount)
			SpawnCharacter(enemyIndex, GetPathPoint("teamEnemy3_spawn", 0))
			SetClassProperty("rep_inf_unit", "AISizeType", "Hover")
			enemyUnit = GetCharacterUnit(enemyIndex)
			
			DestroyTimer(spawnEnemies)
		end
		enemyCount = enemyCount + 1
		end,
		spawnEnemies
	)
I've set a delay of 5 seconds and change the AISizeType for the second spawned unit. the unit spawned during enemyCount == 0 still is affected by the change. How can that be? It might be worth noting that the team from which the function spawns the units only consists of one unit class.
Sporadia
Corporal
Corporal
Posts: 151
Joined: Thu Jan 24, 2019 11:02 pm
Projects :: No Mod project currently
Games I'm Playing :: None
xbox live or psn: No gamertag set

Re: Change AISizeType in Lua

Post by Sporadia »

I'm surprised by that result. From memory, if you did the same SetClassProperty with MaxHealth instead of AISizeType, it wouldn't affect the one spawned at enemy == 0. Try it in case I'm wrong, because it looks like AI just works different. Also, I don't know what the [InstanceProperties] tag is for, and I've always assumed that SetProperty and SetClassProperty worked on the same ODF parameters. The difference being that SetClassProperty works pre-spawn and SetProperty works post-spawn. And the other difference being the first argument each function takes. Have you tried SetProperty with the [ClassProperties] tag? (I ask, not fully understanding what it means).

Edit:
1) I've read up a bit more. I think it's a good idea to test SetProperty(enemyUnit, "AISizeType", "Hover") when "AISizeType" = "Medium" is under [Properties]. If you haven't tested that already. This would verify that SetProperty definitely can't be used. In your previous test, it might have been the [InstanceProperties] tag that broke "AISizeType". But I think it's more likely that "AISizeType" just can't be changed post-spawn.

2) I also want to know what's up with SetClassProperty. So test SetClassProperty("rep_unit", "MaxHealth", "1e+37") when "MaxHealth = 400" is under [Properties] like I said, to see if it behaves differently. I still expect that one will affect the second spawned unit, but not the first. I now think the difference is because MaxHealth is a proper instance property, as listed in the scripting system doc. (ie it still behaves like an instance property when you put it under the [Properties] tag)

3) Then finally, it's time to challenge the idea that any odf parameter becomes an instance property when you tag it as one. So test SetClassProperty("rep_unit", "AISizeType", "Hover") when "AISizeType" = "Medium" is under [InstanceProperties]. I'm actually getting the feeling that the instance properties tag is more for zeroeditor than it is for the actual game. But who knows, maybe this will actually work, or maybe it will break the "AISizeType" parameter completely. I'm avoiding "AISizeType = Soldier" because that's likely to be the default setting, and you need to test that the odf parameters are actually doing something.

I hypothesise that:
1) test one will spawn both units with "AISizeType" = "Medium", because the SetProperty will fail
2) test two will spawn the first unit with "MaxHealth" = "400", then spawn the second unit with infinite health, with no change to the health of the first unit. I hope that's caused by "MaxHealth" being an instance property.
2.1) If you do an "AISizeType" test with SetClassProperty and the [Properties] tag, the first unit will be spawned with "AISizeType" = "Medium", then both units would change to "AISizeType" = "Hover" before the second unit spawns. I think these are the conditions you've already tested so I haven't suggested that you test them again. Maybe it's because "AISizeType" isn't an instance property. I don't really know.
3) test three will spawn the first unit with "AISizeType" = "Medium", then spawn the second unit with "AISizeType" = "Hover", with no change applied to the first unit. Because this time "AISizeType" will be an instance property.
That's what I hope will happen.
If "AISizeType" breaks under [InstanceProperties], then test 3 will spawn both units with "AISizeType" = "Soldier".
If test 3 changes the "AISizeType" of both units to "Hover", then it's got nothing to do with instance properties. It's just how "AISizeType" behaves.
Any other behaviour would mean I've got something wrong.
Post Reply